diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/Support')
78 files changed, 1829 insertions, 3173 deletions
diff --git a/contrib/llvm-project/llvm/lib/Support/AArch64TargetParser.cpp b/contrib/llvm-project/llvm/lib/Support/AArch64TargetParser.cpp index b5cd4af0eb3d..6f1d6d50eee2 100644 --- a/contrib/llvm-project/llvm/lib/Support/AArch64TargetParser.cpp +++ b/contrib/llvm-project/llvm/lib/Support/AArch64TargetParser.cpp @@ -213,51 +213,3 @@ AArch64::ArchKind AArch64::parseCPUArch(StringRef CPU) { } return ArchKind::INVALID; } - -// Parse a branch protection specification, which has the form -// standard | none | [bti,pac-ret[+b-key,+leaf]*] -// Returns true on success, with individual elements of the specification -// returned in `PBP`. Returns false in error, with `Err` containing -// an erroneous part of the spec. -bool AArch64::parseBranchProtection(StringRef Spec, ParsedBranchProtection &PBP, - StringRef &Err) { - PBP = {"none", "a_key", false}; - if (Spec == "none") - return true; // defaults are ok - - if (Spec == "standard") { - PBP.Scope = "non-leaf"; - PBP.BranchTargetEnforcement = true; - return true; - } - - SmallVector<StringRef, 4> Opts; - Spec.split(Opts, "+"); - for (int I = 0, E = Opts.size(); I != E; ++I) { - StringRef Opt = Opts[I].trim(); - if (Opt == "bti") { - PBP.BranchTargetEnforcement = true; - continue; - } - if (Opt == "pac-ret") { - PBP.Scope = "non-leaf"; - for (; I + 1 != E; ++I) { - StringRef PACOpt = Opts[I + 1].trim(); - if (PACOpt == "leaf") - PBP.Scope = "all"; - else if (PACOpt == "b-key") - PBP.Key = "b_key"; - else - break; - } - continue; - } - if (Opt == "") - Err = "<empty>"; - else - Err = Opt; - return false; - } - - return true; -} diff --git a/contrib/llvm-project/llvm/lib/Support/ABIBreak.cpp b/contrib/llvm-project/llvm/lib/Support/ABIBreak.cpp deleted file mode 100644 index 247b635e02b8..000000000000 --- a/contrib/llvm-project/llvm/lib/Support/ABIBreak.cpp +++ /dev/null @@ -1,24 +0,0 @@ -//===----- lib/Support/ABIBreak.cpp - EnableABIBreakingChecks -------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Config/abi-breaking.h" - -#ifndef _MSC_VER -namespace llvm { - -// One of these two variables will be referenced by a symbol defined in -// llvm-config.h. We provide a link-time (or load time for DSO) failure when -// there is a mismatch in the build configuration of the API client and LLVM. -#if LLVM_ENABLE_ABI_BREAKING_CHECKS -int EnableABIBreakingChecks; -#else -int DisableABIBreakingChecks; -#endif - -} // end namespace llvm -#endif diff --git a/contrib/llvm-project/llvm/lib/Support/AMDGPUMetadata.cpp b/contrib/llvm-project/llvm/lib/Support/AMDGPUMetadata.cpp index 4ea197a97389..5f8102299f47 100644 --- a/contrib/llvm-project/llvm/lib/Support/AMDGPUMetadata.cpp +++ b/contrib/llvm-project/llvm/lib/Support/AMDGPUMetadata.cpp @@ -62,7 +62,6 @@ struct ScalarEnumerationTraits<ValueKind> { YIO.enumCase(EN, "HiddenGlobalOffsetZ", ValueKind::HiddenGlobalOffsetZ); YIO.enumCase(EN, "HiddenNone", ValueKind::HiddenNone); YIO.enumCase(EN, "HiddenPrintfBuffer", ValueKind::HiddenPrintfBuffer); - YIO.enumCase(EN, "HiddenHostcallBuffer", ValueKind::HiddenHostcallBuffer); YIO.enumCase(EN, "HiddenDefaultQueue", ValueKind::HiddenDefaultQueue); YIO.enumCase(EN, "HiddenCompletionAction", ValueKind::HiddenCompletionAction); diff --git a/contrib/llvm-project/llvm/lib/Support/APFloat.cpp b/contrib/llvm-project/llvm/lib/Support/APFloat.cpp index 050c37baefb8..b79baf1834a7 100644 --- a/contrib/llvm-project/llvm/lib/Support/APFloat.cpp +++ b/contrib/llvm-project/llvm/lib/Support/APFloat.cpp @@ -20,7 +20,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Error.h" +#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <cstring> @@ -208,10 +208,6 @@ namespace llvm { /* A bunch of private, handy routines. */ -static inline Error createError(const Twine &Err) { - return make_error<StringError>(Err, inconvertibleErrorCode()); -} - static inline unsigned int partCountForBits(unsigned int bits) { @@ -230,8 +226,9 @@ decDigitValue(unsigned int c) If the exponent overflows, returns a large exponent with the appropriate sign. */ -static Expected<int> readExponent(StringRef::iterator begin, - StringRef::iterator end) { +static int +readExponent(StringRef::iterator begin, StringRef::iterator end) +{ bool isNegative; unsigned int absExponent; const unsigned int overlargeExponent = 24000; /* FIXME. */ @@ -245,28 +242,29 @@ static Expected<int> readExponent(StringRef::iterator begin, isNegative = (*p == '-'); if (*p == '-' || *p == '+') { p++; - if (p == end) - return createError("Exponent has no digits"); + assert(p != end && "Exponent has no digits"); } absExponent = decDigitValue(*p++); - if (absExponent >= 10U) - return createError("Invalid character in exponent"); + assert(absExponent < 10U && "Invalid character in exponent"); for (; p != end; ++p) { unsigned int value; value = decDigitValue(*p); - if (value >= 10U) - return createError("Invalid character in exponent"); + assert(value < 10U && "Invalid character in exponent"); - absExponent = absExponent * 10U + value; + 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 @@ -275,21 +273,20 @@ static Expected<int> readExponent(StringRef::iterator begin, /* This is ugly and needs cleaning up, but I don't immediately see how whilst remaining safe. */ -static Expected<int> totalExponent(StringRef::iterator p, - StringRef::iterator end, - int exponentAdjustment) { +static int +totalExponent(StringRef::iterator p, StringRef::iterator end, + int exponentAdjustment) +{ int unsignedExponent; bool negative, overflow; int exponent = 0; - if (p == end) - return createError("Exponent has no digits"); + assert(p != end && "Exponent has no digits"); negative = *p == '-'; if (*p == '-' || *p == '+') { p++; - if (p == end) - return createError("Exponent has no digits"); + assert(p != end && "Exponent has no digits"); } unsignedExponent = 0; @@ -298,8 +295,7 @@ static Expected<int> totalExponent(StringRef::iterator p, unsigned int value; value = decDigitValue(*p); - if (value >= 10U) - return createError("Invalid character in exponent"); + assert(value < 10U && "Invalid character in exponent"); unsignedExponent = unsignedExponent * 10 + value; if (unsignedExponent > 32767) { @@ -326,9 +322,10 @@ static Expected<int> totalExponent(StringRef::iterator p, return exponent; } -static Expected<StringRef::iterator> +static StringRef::iterator skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end, - StringRef::iterator *dot) { + StringRef::iterator *dot) +{ StringRef::iterator p = begin; *dot = end; while (p != end && *p == '0') @@ -337,8 +334,7 @@ skipLeadingZeroesAndAnyDot(StringRef::iterator begin, StringRef::iterator end, if (p != end && *p == '.') { *dot = p++; - if (end - begin == 1) - return createError("Significand has no digits"); + assert(end - begin != 1 && "Significand has no digits"); while (p != end && *p == '0') p++; @@ -367,14 +363,12 @@ struct decimalInfo { int normalizedExponent; }; -static Error interpretDecimal(StringRef::iterator begin, - StringRef::iterator end, decimalInfo *D) { +static void +interpretDecimal(StringRef::iterator begin, StringRef::iterator end, + decimalInfo *D) +{ StringRef::iterator dot = end; - - auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot); - if (!PtrOrErr) - return PtrOrErr.takeError(); - StringRef::iterator p = *PtrOrErr; + StringRef::iterator p = skipLeadingZeroesAndAnyDot (begin, end, &dot); D->firstSigDigit = p; D->exponent = 0; @@ -382,8 +376,7 @@ static Error interpretDecimal(StringRef::iterator begin, for (; p != end; ++p) { if (*p == '.') { - if (dot != end) - return createError("String contains multiple dots"); + assert(dot == end && "String contains multiple dots"); dot = p++; if (p == end) break; @@ -393,18 +386,12 @@ static Error interpretDecimal(StringRef::iterator begin, } if (p != end) { - if (*p != 'e' && *p != 'E') - return createError("Invalid character in significand"); - if (p == begin) - return createError("Significand has no digits"); - if (dot != end && p - begin == 1) - return createError("Significand has no digits"); + 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 */ - auto ExpOrErr = readExponent(p + 1, end); - if (!ExpOrErr) - return ExpOrErr.takeError(); - D->exponent = *ExpOrErr; + D->exponent = readExponent(p + 1, end); /* Implied decimal point? */ if (dot == end) @@ -430,15 +417,15 @@ static Error interpretDecimal(StringRef::iterator begin, } D->lastSigDigit = p; - return Error::success(); } /* Return the trailing fraction of a hexadecimal number. DIGITVALUE is the first hex digit of the fraction, P points to the next digit. */ -static Expected<lostFraction> +static lostFraction trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end, - unsigned int digitValue) { + unsigned int digitValue) +{ unsigned int hexDigit; /* If the first trailing digit isn't 0 or 8 we can work out the @@ -452,8 +439,7 @@ trailingHexadecimalFraction(StringRef::iterator p, StringRef::iterator end, while (p != end && (*p == '0' || *p == '.')) p++; - if (p == end) - return createError("Invalid trailing hexadecimal fraction!"); + assert(p != end && "Invalid trailing hexadecimal fraction!"); hexDigit = hexDigitValue(*p); @@ -992,7 +978,7 @@ IEEEFloat::integerPart IEEEFloat::subtractSignificand(const IEEEFloat &rhs, on to the full-precision result of the multiplication. Returns the lost fraction. */ lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, - IEEEFloat addend) { + const IEEEFloat *addend) { unsigned int omsb; // One, not zero, based MSB. unsigned int partsCount, newPartsCount, precision; integerPart *lhsSignificand; @@ -1036,7 +1022,7 @@ lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, // toward left by two bits, and adjust exponent accordingly. exponent += 2; - if (addend.isNonZero()) { + if (addend && addend->isNonZero()) { // The intermediate result of the multiplication has "2 * precision" // signicant bit; adjust the addend to be consistent with mul result. // @@ -1065,10 +1051,7 @@ lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, significand.parts = fullSignificand; semantics = &extendedSemantics; - // Make a copy so we can convert it to the extended semantics. - // Note that we cannot convert the addend directly, as the extendedSemantics - // is a local variable (which we take a reference to). - IEEEFloat extendedAddend(addend); + IEEEFloat extendedAddend(*addend); status = extendedAddend.convert(extendedSemantics, rmTowardZero, &ignored); assert(status == opOK); (void)status; @@ -1123,10 +1106,6 @@ lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs, return lost_fraction; } -lostFraction IEEEFloat::multiplySignificand(const IEEEFloat &rhs) { - return multiplySignificand(rhs, IEEEFloat(*semantics)); -} - /* Multiply the significands of LHS and RHS to DST. */ lostFraction IEEEFloat::divideSignificand(const IEEEFloat &rhs) { unsigned int bit, i, partsCount; @@ -1505,19 +1484,22 @@ lostFraction IEEEFloat::addOrSubtractSignificand(const IEEEFloat &rhs, /* Subtraction is more subtle than one might naively expect. */ if (subtract) { IEEEFloat temp_rhs(rhs); + bool reverse; - if (bits == 0) + if (bits == 0) { + reverse = compareAbsoluteValue(temp_rhs) == cmpLessThan; lost_fraction = lfExactlyZero; - else if (bits > 0) { + } 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; } - // Should we reverse the subtraction. - if (compareAbsoluteValue(temp_rhs) == cmpLessThan) { + if (reverse) { carry = temp_rhs.subtractSignificand (*this, lost_fraction != lfExactlyZero); copySignificand(temp_rhs); @@ -1732,7 +1714,7 @@ IEEEFloat::opStatus IEEEFloat::multiply(const IEEEFloat &rhs, fs = multiplySpecials(rhs); if (isFiniteNonZero()) { - lostFraction lost_fraction = multiplySignificand(rhs); + lostFraction lost_fraction = multiplySignificand(rhs, nullptr); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) fs = (opStatus) (fs | opInexact); @@ -1833,7 +1815,7 @@ IEEEFloat::opStatus IEEEFloat::fusedMultiplyAdd(const IEEEFloat &multiplicand, addend.isFinite()) { lostFraction lost_fraction; - lost_fraction = multiplySignificand(multiplicand, addend); + lost_fraction = multiplySignificand(multiplicand, &addend); fs = normalize(rounding_mode, lost_fraction); if (lost_fraction != lfExactlyZero) fs = (opStatus) (fs | opInexact); @@ -2320,7 +2302,7 @@ IEEEFloat::convertFromZeroExtendedInteger(const integerPart *parts, return convertFromUnsignedParts(api.getRawData(), partCount, rounding_mode); } -Expected<IEEEFloat::opStatus> +IEEEFloat::opStatus IEEEFloat::convertFromHexadecimalString(StringRef s, roundingMode rounding_mode) { lostFraction lost_fraction = lfExactlyZero; @@ -2338,18 +2320,14 @@ IEEEFloat::convertFromHexadecimalString(StringRef s, StringRef::iterator begin = s.begin(); StringRef::iterator end = s.end(); StringRef::iterator dot; - auto PtrOrErr = skipLeadingZeroesAndAnyDot(begin, end, &dot); - if (!PtrOrErr) - return PtrOrErr.takeError(); - StringRef::iterator p = *PtrOrErr; + StringRef::iterator p = skipLeadingZeroesAndAnyDot(begin, end, &dot); StringRef::iterator firstSignificantDigit = p; while (p != end) { integerPart hex_value; if (*p == '.') { - if (dot != end) - return createError("String contains multiple dots"); + assert(dot == end && "String contains multiple dots"); dot = p++; continue; } @@ -2366,23 +2344,16 @@ IEEEFloat::convertFromHexadecimalString(StringRef s, hex_value <<= bitPos % integerPartWidth; significand[bitPos / integerPartWidth] |= hex_value; } else if (!computedTrailingFraction) { - auto FractOrErr = trailingHexadecimalFraction(p, end, hex_value); - if (!FractOrErr) - return FractOrErr.takeError(); - lost_fraction = *FractOrErr; + lost_fraction = trailingHexadecimalFraction(p, end, hex_value); computedTrailingFraction = true; } } /* Hex floats require an exponent but not a hexadecimal point. */ - if (p == end) - return createError("Hex strings require an exponent"); - if (*p != 'p' && *p != 'P') - return createError("Invalid character in significand"); - if (p == begin) - return createError("Significand has no digits"); - if (dot != end && p - begin == 1) - return createError("Significand has no digits"); + 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) { @@ -2405,10 +2376,7 @@ IEEEFloat::convertFromHexadecimalString(StringRef s, expAdjustment -= partsCount * integerPartWidth; /* Adjust for the given exponent. */ - auto ExpOrErr = totalExponent(p + 1, end, expAdjustment); - if (!ExpOrErr) - return ExpOrErr.takeError(); - exponent = *ExpOrErr; + exponent = totalExponent(p + 1, end, expAdjustment); } return normalize(rounding_mode, lost_fraction); @@ -2456,7 +2424,7 @@ IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts, if (exp >= 0) { /* multiplySignificand leaves the precision-th bit set to 1. */ - calcLostFraction = decSig.multiplySignificand(pow5); + calcLostFraction = decSig.multiplySignificand(pow5, nullptr); powHUerr = powStatus != opOK; } else { calcLostFraction = decSig.divideSignificand(pow5); @@ -2499,15 +2467,14 @@ IEEEFloat::roundSignificandWithExponent(const integerPart *decSigParts, } } -Expected<IEEEFloat::opStatus> +IEEEFloat::opStatus IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) { decimalInfo D; opStatus fs; /* Scan the text. */ StringRef::iterator p = str.begin(); - if (Error Err = interpretDecimal(p, str.end(), &D)) - return std::move(Err); + 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 @@ -2590,10 +2557,7 @@ IEEEFloat::convertFromDecimalString(StringRef str, roundingMode rounding_mode) { } } decValue = decDigitValue(*p++); - if (decValue >= 10U) { - delete[] decSignificand; - return createError("Invalid character in significand"); - } + assert(decValue < 10U && "Invalid character in significand"); multiplier *= 10; val = val * 10 + decValue; /* The maximum number that can be multiplied by ten with any @@ -2644,10 +2608,9 @@ bool IEEEFloat::convertFromStringSpecials(StringRef str) { return false; } -Expected<IEEEFloat::opStatus> -IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) { - if (str.empty()) - return createError("Invalid string length"); +IEEEFloat::opStatus IEEEFloat::convertFromString(StringRef str, + roundingMode rounding_mode) { + assert(!str.empty() && "Invalid string length"); // Handle special cases. if (convertFromStringSpecials(str)) @@ -2660,13 +2623,11 @@ IEEEFloat::convertFromString(StringRef str, roundingMode rounding_mode) { if (*p == '-' || *p == '+') { p++; slen--; - if (!slen) - return createError("String has no digits"); + assert(slen && "String has no digits"); } if (slen >= 2 && p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) { - if (slen == 2) - return createError("Invalid string"); + assert(slen - 2 && "Invalid string"); return convertFromHexadecimalString(StringRef(p + 2, slen - 2), rounding_mode); } @@ -4354,8 +4315,8 @@ APInt DoubleAPFloat::bitcastToAPInt() const { return APInt(128, 2, Data); } -Expected<APFloat::opStatus> DoubleAPFloat::convertFromString(StringRef S, - roundingMode RM) { +APFloat::opStatus DoubleAPFloat::convertFromString(StringRef S, + roundingMode RM) { assert(Semantics == &semPPCDoubleDouble && "Unexpected Semantics"); APFloat Tmp(semPPCDoubleDoubleLegacy); auto Ret = Tmp.convertFromString(S, RM); @@ -4502,8 +4463,7 @@ APFloat::Storage::Storage(IEEEFloat F, const fltSemantics &Semantics) { llvm_unreachable("Unexpected semantics"); } -Expected<APFloat::opStatus> APFloat::convertFromString(StringRef Str, - roundingMode RM) { +APFloat::opStatus APFloat::convertFromString(StringRef Str, roundingMode RM) { APFLOAT_DISPATCH_ON_SEMANTICS(convertFromString(Str, RM)); } @@ -4517,9 +4477,7 @@ hash_code hash_value(const APFloat &Arg) { APFloat::APFloat(const fltSemantics &Semantics, StringRef S) : APFloat(Semantics) { - auto StatusOrErr = convertFromString(S, rmNearestTiesToEven); - assert(StatusOrErr && "Invalid floating point representation"); - consumeError(StatusOrErr.takeError()); + convertFromString(S, rmNearestTiesToEven); } APFloat::opStatus APFloat::convert(const fltSemantics &ToSemantics, diff --git a/contrib/llvm-project/llvm/lib/Support/APInt.cpp b/contrib/llvm-project/llvm/lib/Support/APInt.cpp index 9b9cd70078b3..43173311cd80 100644 --- a/contrib/llvm-project/llvm/lib/Support/APInt.cpp +++ b/contrib/llvm-project/llvm/lib/Support/APInt.cpp @@ -187,7 +187,7 @@ APInt& APInt::operator--() { return clearUnusedBits(); } -/// Adds the RHS APInt to this APInt. +/// Adds the RHS APint to this APInt. /// @returns this, after addition of RHS. /// Addition assignment operator. APInt& APInt::operator+=(const APInt& RHS) { @@ -401,33 +401,6 @@ void APInt::insertBits(const APInt &subBits, unsigned bitPosition) { } } -void APInt::insertBits(uint64_t subBits, unsigned bitPosition, unsigned numBits) { - uint64_t maskBits = maskTrailingOnes<uint64_t>(numBits); - subBits &= maskBits; - if (isSingleWord()) { - U.VAL &= ~(maskBits << bitPosition); - U.VAL |= subBits << bitPosition; - return; - } - - unsigned loBit = whichBit(bitPosition); - unsigned loWord = whichWord(bitPosition); - unsigned hiWord = whichWord(bitPosition + numBits - 1); - if (loWord == hiWord) { - U.pVal[loWord] &= ~(maskBits << loBit); - U.pVal[loWord] |= subBits << loBit; - return; - } - - static_assert(8 * sizeof(WordType) <= 64, "This code assumes only two words affected"); - unsigned wordBits = 8 * sizeof(WordType); - U.pVal[loWord] &= ~(maskBits << loBit); - U.pVal[loWord] |= subBits << loBit; - - U.pVal[hiWord] &= ~(maskBits >> (wordBits - loBit)); - U.pVal[hiWord] |= subBits >> (wordBits - loBit); -} - APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const { assert(numBits > 0 && "Can't extract zero bits"); assert(bitPosition < BitWidth && (numBits + bitPosition) <= BitWidth && @@ -465,31 +438,6 @@ APInt APInt::extractBits(unsigned numBits, unsigned bitPosition) const { return Result.clearUnusedBits(); } -uint64_t APInt::extractBitsAsZExtValue(unsigned numBits, - unsigned bitPosition) const { - assert(numBits > 0 && "Can't extract zero bits"); - assert(bitPosition < BitWidth && (numBits + bitPosition) <= BitWidth && - "Illegal bit extraction"); - assert(numBits <= 64 && "Illegal bit extraction"); - - uint64_t maskBits = maskTrailingOnes<uint64_t>(numBits); - if (isSingleWord()) - return (U.VAL >> bitPosition) & maskBits; - - unsigned loBit = whichBit(bitPosition); - unsigned loWord = whichWord(bitPosition); - unsigned hiWord = whichWord(bitPosition + numBits - 1); - if (loWord == hiWord) - return (U.pVal[loWord] >> loBit) & maskBits; - - static_assert(8 * sizeof(WordType) <= 64, "This code assumes only two words affected"); - unsigned wordBits = 8 * sizeof(WordType); - uint64_t retBits = U.pVal[loWord] >> loBit; - retBits |= U.pVal[hiWord] << (wordBits - loBit); - retBits &= maskBits; - return retBits; -} - unsigned APInt::getBitsNeeded(StringRef str, uint8_t radix) { assert(!str.empty() && "Invalid string length"); assert((radix == 10 || radix == 8 || radix == 16 || radix == 2 || @@ -884,31 +832,6 @@ APInt APInt::trunc(unsigned width) const { return Result; } -// Truncate to new width with unsigned saturation. -APInt APInt::truncUSat(unsigned width) const { - assert(width < BitWidth && "Invalid APInt Truncate request"); - assert(width && "Can't truncate to 0 bits"); - - // Can we just losslessly truncate it? - if (isIntN(width)) - return trunc(width); - // If not, then just return the new limit. - return APInt::getMaxValue(width); -} - -// Truncate to new width with signed saturation. -APInt APInt::truncSSat(unsigned width) const { - assert(width < BitWidth && "Invalid APInt Truncate request"); - assert(width && "Can't truncate to 0 bits"); - - // Can we just losslessly truncate it? - if (isSignedIntN(width)) - return trunc(width); - // If not, then just return the new limits. - return isNegative() ? APInt::getSignedMinValue(width) - : APInt::getSignedMaxValue(width); -} - // Sign extend to a new width. APInt APInt::sext(unsigned Width) const { assert(Width > BitWidth && "Invalid APInt SignExtend request"); @@ -2073,46 +1996,6 @@ APInt APInt::usub_sat(const APInt &RHS) const { return APInt(BitWidth, 0); } -APInt APInt::smul_sat(const APInt &RHS) const { - bool Overflow; - APInt Res = smul_ov(RHS, Overflow); - if (!Overflow) - return Res; - - // The result is negative if one and only one of inputs is negative. - bool ResIsNegative = isNegative() ^ RHS.isNegative(); - - return ResIsNegative ? APInt::getSignedMinValue(BitWidth) - : APInt::getSignedMaxValue(BitWidth); -} - -APInt APInt::umul_sat(const APInt &RHS) const { - bool Overflow; - APInt Res = umul_ov(RHS, Overflow); - if (!Overflow) - return Res; - - return APInt::getMaxValue(BitWidth); -} - -APInt APInt::sshl_sat(const APInt &RHS) const { - bool Overflow; - APInt Res = sshl_ov(RHS, Overflow); - if (!Overflow) - return Res; - - return isNegative() ? APInt::getSignedMinValue(BitWidth) - : APInt::getSignedMaxValue(BitWidth); -} - -APInt APInt::ushl_sat(const APInt &RHS) const { - bool Overflow; - APInt Res = ushl_ov(RHS, Overflow); - if (!Overflow) - return Res; - - return APInt::getMaxValue(BitWidth); -} void APInt::fromString(unsigned numbits, StringRef str, uint8_t radix) { // Check our assumptions here @@ -2855,7 +2738,7 @@ APInt llvm::APIntOps::RoundingSDiv(const APInt &A, const APInt &B, return Quo; return Quo + 1; } - // Currently sdiv rounds towards zero. + // Currently sdiv rounds twards zero. case APInt::Rounding::TOWARD_ZERO: return A.sdiv(B); } @@ -2998,7 +2881,7 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, APInt Q = SQ * SQ; bool InexactSQ = Q != D; // The calculated SQ may actually be greater than the exact (non-integer) - // value. If that's the case, decrement SQ to get a value that is lower. + // value. If that's the case, decremement SQ to get a value that is lower. if (Q.sgt(D)) SQ -= 1; @@ -3052,14 +2935,6 @@ llvm::APIntOps::SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, return X; } -Optional<unsigned> -llvm::APIntOps::GetMostSignificantDifferentBit(const APInt &A, const APInt &B) { - assert(A.getBitWidth() == B.getBitWidth() && "Must have the same bitwidth"); - if (A == B) - return llvm::None; - return A.getBitWidth() - ((A ^ B).countLeadingZeros() + 1); -} - /// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst /// with the integer held in IntVal. void llvm::StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, diff --git a/contrib/llvm-project/llvm/lib/Support/ARMAttributeParser.cpp b/contrib/llvm-project/llvm/lib/Support/ARMAttributeParser.cpp index 8a89f4c45fb9..df50fff720cd 100644 --- a/contrib/llvm-project/llvm/lib/Support/ARMAttributeParser.cpp +++ b/contrib/llvm-project/llvm/lib/Support/ARMAttributeParser.cpp @@ -73,9 +73,9 @@ ARMAttributeParser::DisplayRoutines[] = { uint64_t ARMAttributeParser::ParseInteger(const uint8_t *Data, uint32_t &Offset) { - unsigned DecodeLength; - uint64_t Value = decodeULEB128(Data + Offset, &DecodeLength); - Offset += DecodeLength; + unsigned Length; + uint64_t Value = decodeULEB128(Data + Offset, &Length); + Offset = Offset + Length; return Value; } @@ -587,9 +587,9 @@ void ARMAttributeParser::nodefaults(AttrType Tag, const uint8_t *Data, void ARMAttributeParser::ParseIndexList(const uint8_t *Data, uint32_t &Offset, SmallVectorImpl<uint8_t> &IndexList) { for (;;) { - unsigned DecodeLength; - uint64_t Value = decodeULEB128(Data + Offset, &DecodeLength); - Offset += DecodeLength; + unsigned Length; + uint64_t Value = decodeULEB128(Data + Offset, &Length); + Offset = Offset + Length; if (Value == 0) break; IndexList.push_back(Value); @@ -599,9 +599,9 @@ void ARMAttributeParser::ParseIndexList(const uint8_t *Data, uint32_t &Offset, void ARMAttributeParser::ParseAttributeList(const uint8_t *Data, uint32_t &Offset, uint32_t Length) { while (Offset < Length) { - unsigned DecodeLength; - uint64_t Tag = decodeULEB128(Data + Offset, &DecodeLength); - Offset += DecodeLength; + unsigned Length; + uint64_t Tag = decodeULEB128(Data + Offset, &Length); + Offset += Length; bool Handled = false; for (unsigned AHI = 0, AHE = array_lengthof(DisplayRoutines); diff --git a/contrib/llvm-project/llvm/lib/Support/ARMTargetParser.cpp b/contrib/llvm-project/llvm/lib/Support/ARMTargetParser.cpp index f2c22fd93c8b..a893991ebe70 100644 --- a/contrib/llvm-project/llvm/lib/Support/ARMTargetParser.cpp +++ b/contrib/llvm-project/llvm/lib/Support/ARMTargetParser.cpp @@ -174,7 +174,11 @@ bool ARM::getFPUFeatures(unsigned FPUKind, std::vector<StringRef> &Features) { // under FPURestriction::None, which is the only FPURestriction in // which they would be valid (since FPURestriction::SP doesn't // exist). + + {"+fpregs", "-fpregs", FPUVersion::VFPV2, FPURestriction::SP_D16}, {"+vfp2", "-vfp2", FPUVersion::VFPV2, FPURestriction::D16}, + {"+vfp2d16", "-vfp2d16", FPUVersion::VFPV2, FPURestriction::D16}, + {"+vfp2d16sp", "-vfp2d16sp", FPUVersion::VFPV2, FPURestriction::SP_D16}, {"+vfp2sp", "-vfp2sp", FPUVersion::VFPV2, FPURestriction::SP_D16}, {"+vfp3", "-vfp3", FPUVersion::VFPV3, FPURestriction::None}, {"+vfp3d16", "-vfp3d16", FPUVersion::VFPV3, FPURestriction::D16}, diff --git a/contrib/llvm-project/llvm/lib/Support/BinaryStreamReader.cpp b/contrib/llvm-project/llvm/lib/Support/BinaryStreamReader.cpp index a0434bdc6115..b17786593bde 100644 --- a/contrib/llvm-project/llvm/lib/Support/BinaryStreamReader.cpp +++ b/contrib/llvm-project/llvm/lib/Support/BinaryStreamReader.cpp @@ -139,10 +139,10 @@ Error BinaryStreamReader::readStreamRef(BinaryStreamRef &Ref, uint32_t Length) { return Error::success(); } -Error BinaryStreamReader::readSubstream(BinarySubstreamRef &Ref, - uint32_t Length) { - Ref.Offset = getOffset(); - return readStreamRef(Ref.StreamData, Length); +Error BinaryStreamReader::readSubstream(BinarySubstreamRef &Stream, + uint32_t Size) { + Stream.Offset = getOffset(); + return readStreamRef(Stream.StreamData, Size); } Error BinaryStreamReader::skip(uint32_t Amount) { diff --git a/contrib/llvm-project/llvm/lib/Support/CRC.cpp b/contrib/llvm-project/llvm/lib/Support/CRC.cpp index 2bc668beed32..fd98f3a24003 100644 --- a/contrib/llvm-project/llvm/lib/Support/CRC.cpp +++ b/contrib/llvm-project/llvm/lib/Support/CRC.cpp @@ -6,102 +6,63 @@ // //===----------------------------------------------------------------------===// // -// This file contains implementations of CRC functions. -// -// The implementation technique is the one mentioned in: -// D. V. Sarwate. 1988. Computation of cyclic redundancy checks via table -// look-up. Commun. ACM 31, 8 (August 1988) -// -// See also Ross N. Williams "A Painless Guide to CRC Error Detection -// Algorithms" (https://zlib.net/crc_v3.txt) or Hacker's Delight (2nd ed.) -// Chapter 14 (Figure 14-7 in particular) for how the algorithm works. +// This file implements llvm::crc32 function. // //===----------------------------------------------------------------------===// #include "llvm/Support/CRC.h" - -#include "llvm/ADT/ArrayRef.h" #include "llvm/Config/config.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Threading.h" +#include <array> using namespace llvm; -#if !LLVM_ENABLE_ZLIB +#if LLVM_ENABLE_ZLIB == 0 || !HAVE_ZLIB_H +using CRC32Table = std::array<uint32_t, 256>; + +static void initCRC32Table(CRC32Table *Tbl) { + auto Shuffle = [](uint32_t V) { + return (V & 1) ? (V >> 1) ^ 0xEDB88320U : V >> 1; + }; + + for (size_t I = 0; I < Tbl->size(); ++I) { + uint32_t V = Shuffle(I); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + V = Shuffle(V); + (*Tbl)[I] = Shuffle(V); + } +} -static const uint32_t CRCTable[256] = { - 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, - 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, - 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, - 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, - 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, - 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, - 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, - 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, - 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, - 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, - 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, - 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, - 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, - 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, - 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, - 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, - 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, - 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, - 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, - 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, - 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, - 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, - 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, - 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, - 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, - 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, - 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, - 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, - 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, - 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, - 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, - 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, - 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, - 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, - 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, - 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, - 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, - 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, - 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, - 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, - 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, - 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, - 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; +uint32_t llvm::crc32(uint32_t CRC, StringRef S) { + static llvm::once_flag InitFlag; + static CRC32Table Tbl; + llvm::call_once(InitFlag, initCRC32Table, &Tbl); -uint32_t llvm::crc32(uint32_t CRC, ArrayRef<uint8_t> Data) { + const uint8_t *P = reinterpret_cast<const uint8_t *>(S.data()); + size_t Len = S.size(); CRC ^= 0xFFFFFFFFU; - for (uint8_t Byte : Data) { - int TableIdx = (CRC ^ Byte) & 0xff; - CRC = CRCTable[TableIdx] ^ (CRC >> 8); + for (; Len >= 8; Len -= 8) { + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); } + while (Len--) + CRC = Tbl[(CRC ^ *P++) & 0xFF] ^ (CRC >> 8); return CRC ^ 0xFFFFFFFFU; } - #else - #include <zlib.h> -uint32_t llvm::crc32(uint32_t CRC, ArrayRef<uint8_t> Data) { - // Zlib's crc32() only takes a 32-bit length, so we have to iterate for larger - // sizes. One could use crc32_z() instead, but that's a recent (2017) addition - // and may not be available on all systems. - do { - ArrayRef<uint8_t> Slice = Data.take_front(UINT32_MAX); - CRC = ::crc32(CRC, (const Bytef *)Slice.data(), (uInt)Slice.size()); - Data = Data.drop_front(Slice.size()); - } while (Data.size() > 0); - return CRC; +uint32_t llvm::crc32(uint32_t CRC, StringRef S) { + return ::crc32(CRC, (const Bytef *)S.data(), S.size()); } - #endif - -uint32_t llvm::crc32(ArrayRef<uint8_t> Data) { return crc32(0, Data); } - -void JamCRC::update(ArrayRef<uint8_t> Data) { - CRC ^= 0xFFFFFFFFU; // Undo CRC-32 Init. - CRC = crc32(CRC, Data); - CRC ^= 0xFFFFFFFFU; // Undo CRC-32 XorOut. -} diff --git a/contrib/llvm-project/llvm/lib/Support/CachePruning.cpp b/contrib/llvm-project/llvm/lib/Support/CachePruning.cpp index 7a2f6c53435a..9813eec0e433 100644 --- a/contrib/llvm-project/llvm/lib/Support/CachePruning.cpp +++ b/contrib/llvm-project/llvm/lib/Support/CachePruning.cpp @@ -45,7 +45,7 @@ struct FileInfo { /// interval option. static void writeTimestampFile(StringRef TimestampFile) { std::error_code EC; - raw_fd_ostream Out(TimestampFile.str(), EC, sys::fs::OF_None); + raw_fd_ostream Out(TimestampFile.str(), EC, sys::fs::F_None); } static Expected<std::chrono::seconds> parseDuration(StringRef Duration) { diff --git a/contrib/llvm-project/llvm/lib/Support/CodeGenCoverage.cpp b/contrib/llvm-project/llvm/lib/Support/CodeGenCoverage.cpp index 2db4193ce382..f39eb7533b43 100644 --- a/contrib/llvm-project/llvm/lib/Support/CodeGenCoverage.cpp +++ b/contrib/llvm-project/llvm/lib/Support/CodeGenCoverage.cpp @@ -101,9 +101,9 @@ bool CodeGenCoverage::emit(StringRef CoveragePrefix, std::string CoverageFilename = (CoveragePrefix + Pid).str(); std::error_code EC; - sys::fs::OpenFlags OpenFlags = sys::fs::OF_Append; + sys::fs::OpenFlags OpenFlags = sys::fs::F_Append; std::unique_ptr<ToolOutputFile> CoverageFile = - std::make_unique<ToolOutputFile>(CoverageFilename, EC, OpenFlags); + llvm::make_unique<ToolOutputFile>(CoverageFilename, EC, OpenFlags); if (EC) return false; diff --git a/contrib/llvm-project/llvm/lib/Support/CommandLine.cpp b/contrib/llvm-project/llvm/lib/Support/CommandLine.cpp index cb73380ba383..25510fa58ff5 100644 --- a/contrib/llvm-project/llvm/lib/Support/CommandLine.cpp +++ b/contrib/llvm-project/llvm/lib/Support/CommandLine.cpp @@ -24,13 +24,11 @@ #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" #include "llvm/Support/ConvertUTF.h" #include "llvm/Support/Debug.h" -#include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -39,11 +37,9 @@ #include "llvm/Support/Path.h" #include "llvm/Support/Process.h" #include "llvm/Support/StringSaver.h" -#include "llvm/Support/VirtualFileSystem.h" #include "llvm/Support/raw_ostream.h" #include <cstdlib> #include <map> -#include <string> using namespace llvm; using namespace cl; @@ -57,8 +53,6 @@ namespace cl { template class basic_parser<bool>; template class basic_parser<boolOrDefault>; template class basic_parser<int>; -template class basic_parser<long>; -template class basic_parser<long long>; template class basic_parser<unsigned>; template class basic_parser<unsigned long>; template class basic_parser<unsigned long long>; @@ -84,8 +78,6 @@ void basic_parser_impl::anchor() {} void parser<bool>::anchor() {} void parser<boolOrDefault>::anchor() {} void parser<int>::anchor() {} -void parser<long>::anchor() {} -void parser<long long>::anchor() {} void parser<unsigned>::anchor() {} void parser<unsigned long>::anchor() {} void parser<unsigned long long>::anchor() {} @@ -96,26 +88,21 @@ void parser<char>::anchor() {} //===----------------------------------------------------------------------===// -const static size_t DefaultPad = 2; - -static StringRef ArgPrefix = "-"; -static StringRef ArgPrefixLong = "--"; +static StringRef ArgPrefix = " -"; +static StringRef ArgPrefixLong = " --"; static StringRef ArgHelpPrefix = " - "; -static size_t argPlusPrefixesSize(StringRef ArgName, size_t Pad = DefaultPad) { +static size_t argPlusPrefixesSize(StringRef ArgName) { size_t Len = ArgName.size(); if (Len == 1) - return Len + Pad + ArgPrefix.size() + ArgHelpPrefix.size(); - return Len + Pad + ArgPrefixLong.size() + ArgHelpPrefix.size(); + return Len + ArgPrefix.size() + ArgHelpPrefix.size(); + return Len + ArgPrefixLong.size() + ArgHelpPrefix.size(); } -static SmallString<8> argPrefix(StringRef ArgName, size_t Pad = DefaultPad) { - SmallString<8> Prefix; - for (size_t I = 0; I < Pad; ++I) { - Prefix.push_back(' '); - } - Prefix.append(ArgName.size() > 1 ? ArgPrefixLong : ArgPrefix); - return Prefix; +static StringRef argPrefix(StringRef ArgName) { + if (ArgName.size() == 1) + return ArgPrefix; + return ArgPrefixLong; } // Option predicates... @@ -132,14 +119,13 @@ namespace { class PrintArg { StringRef ArgName; - size_t Pad; public: - PrintArg(StringRef ArgName, size_t Pad = DefaultPad) : ArgName(ArgName), Pad(Pad) {} - friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg &); + PrintArg(StringRef ArgName) : ArgName(ArgName) {} + friend raw_ostream &operator<<(raw_ostream &OS, const PrintArg&); }; raw_ostream &operator<<(raw_ostream &OS, const PrintArg& Arg) { - OS << argPrefix(Arg.ArgName, Arg.Pad) << Arg.ArgName; + OS << argPrefix(Arg.ArgName) << Arg.ArgName; return OS; } @@ -187,7 +173,7 @@ public: // If we're adding this to all sub-commands, add it to the ones that have // already been registered. if (SC == &*AllSubCommands) { - for (auto *Sub : RegisteredSubCommands) { + for (const auto &Sub : RegisteredSubCommands) { if (SC == Sub) continue; addLiteralOption(Opt, Sub, Name); @@ -243,7 +229,7 @@ public: // If we're adding this to all sub-commands, add it to the ones that have // already been registered. if (SC == &*AllSubCommands) { - for (auto *Sub : RegisteredSubCommands) { + for (const auto &Sub : RegisteredSubCommands) { if (SC == Sub) continue; addOption(O, Sub); @@ -318,7 +304,7 @@ public: } bool hasOptions() const { - for (const auto *S : RegisteredSubCommands) { + for (const auto &S : RegisteredSubCommands) { if (hasOptions(*S)) return true; } @@ -706,7 +692,7 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName, return false; } -bool llvm::cl::ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { +static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) { int Dummy = i; return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy); } @@ -1051,16 +1037,14 @@ static bool hasUTF8ByteOrderMark(ArrayRef<char> S) { return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf'); } -// FName must be an absolute path. -static llvm::Error ExpandResponseFile( - StringRef FName, StringSaver &Saver, TokenizerCallback Tokenizer, - SmallVectorImpl<const char *> &NewArgv, bool MarkEOLs, bool RelativeNames, - llvm::vfs::FileSystem &FS) { - assert(sys::path::is_absolute(FName)); - llvm::ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = - FS.getBufferForFile(FName); +static bool ExpandResponseFile(StringRef FName, StringSaver &Saver, + TokenizerCallback Tokenizer, + SmallVectorImpl<const char *> &NewArgv, + bool MarkEOLs, bool RelativeNames) { + ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr = + MemoryBuffer::getFile(FName); if (!MemBufOrErr) - return llvm::errorCodeToError(MemBufOrErr.getError()); + return false; MemoryBuffer &MemBuf = *MemBufOrErr.get(); StringRef Str(MemBuf.getBufferStart(), MemBuf.getBufferSize()); @@ -1069,8 +1053,7 @@ static llvm::Error ExpandResponseFile( std::string UTF8Buf; if (hasUTF16ByteOrderMark(BufRef)) { if (!convertUTF16ToUTF8String(BufRef, UTF8Buf)) - return llvm::createStringError(std::errc::illegal_byte_sequence, - "Could not convert UTF16 to UTF8"); + return false; Str = StringRef(UTF8Buf); } // If we see UTF-8 BOM sequence at the beginning of a file, we shall remove @@ -1082,40 +1065,41 @@ static llvm::Error ExpandResponseFile( // Tokenize the contents into NewArgv. Tokenizer(Str, Saver, NewArgv, MarkEOLs); - if (!RelativeNames) - return Error::success(); - llvm::StringRef BasePath = llvm::sys::path::parent_path(FName); // If names of nested response files should be resolved relative to including // file, replace the included response file names with their full paths // obtained by required resolution. - for (auto &Arg : NewArgv) { - // Skip non-rsp file arguments. - if (!Arg || Arg[0] != '@') - continue; - - StringRef FileName(Arg + 1); - // Skip if non-relative. - if (!llvm::sys::path::is_relative(FileName)) - continue; + if (RelativeNames) + for (unsigned I = 0; I < NewArgv.size(); ++I) + if (NewArgv[I]) { + StringRef Arg = NewArgv[I]; + if (Arg.front() == '@') { + StringRef FileName = Arg.drop_front(); + if (llvm::sys::path::is_relative(FileName)) { + SmallString<128> ResponseFile; + ResponseFile.append(1, '@'); + if (llvm::sys::path::is_relative(FName)) { + SmallString<128> curr_dir; + llvm::sys::fs::current_path(curr_dir); + ResponseFile.append(curr_dir.str()); + } + llvm::sys::path::append( + ResponseFile, llvm::sys::path::parent_path(FName), FileName); + NewArgv[I] = Saver.save(ResponseFile.c_str()).data(); + } + } + } - SmallString<128> ResponseFile; - ResponseFile.push_back('@'); - ResponseFile.append(BasePath); - llvm::sys::path::append(ResponseFile, FileName); - Arg = Saver.save(ResponseFile.c_str()).data(); - } - return Error::success(); + return true; } /// 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, - bool RelativeNames, llvm::vfs::FileSystem &FS, - llvm::Optional<llvm::StringRef> CurrentDir) { + SmallVectorImpl<const char *> &Argv, + bool MarkEOLs, bool RelativeNames) { bool AllExpanded = true; struct ResponseFileRecord { - std::string File; + const char *File; size_t End; }; @@ -1149,31 +1133,8 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, } const char *FName = Arg + 1; - // Note that CurrentDir is only used for top-level rsp files, the rest will - // always have an absolute path deduced from the containing file. - SmallString<128> CurrDir; - if (llvm::sys::path::is_relative(FName)) { - if (!CurrentDir) - llvm::sys::fs::current_path(CurrDir); - else - CurrDir = *CurrentDir; - llvm::sys::path::append(CurrDir, FName); - FName = CurrDir.c_str(); - } - auto IsEquivalent = [FName, &FS](const ResponseFileRecord &RFile) { - llvm::ErrorOr<llvm::vfs::Status> LHS = FS.status(FName); - if (!LHS) { - // TODO: The error should be propagated up the stack. - llvm::consumeError(llvm::errorCodeToError(LHS.getError())); - return false; - } - llvm::ErrorOr<llvm::vfs::Status> RHS = FS.status(RFile.File); - if (!RHS) { - // TODO: The error should be propagated up the stack. - llvm::consumeError(llvm::errorCodeToError(RHS.getError())); - return false; - } - return LHS->equivalent(*RHS); + auto IsEquivalent = [FName](const ResponseFileRecord &RFile) { + return sys::fs::equivalent(RFile.File, FName); }; // Check for recursive response files. @@ -1188,13 +1149,10 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, // Replace this response file argument with the tokenization of its // contents. Nested response files are expanded in subsequent iterations. SmallVector<const char *, 0> ExpandedArgv; - if (llvm::Error Err = - ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs, - RelativeNames, FS)) { + if (!ExpandResponseFile(FName, Saver, Tokenizer, ExpandedArgv, MarkEOLs, + RelativeNames)) { // We couldn't read this file, so we leave it in the argument stream and // move on. - // TODO: The error should be propagated up the stack. - llvm::consumeError(std::move(Err)); AllExpanded = false; ++I; continue; @@ -1222,20 +1180,9 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer, bool cl::readConfigFile(StringRef CfgFile, StringSaver &Saver, SmallVectorImpl<const char *> &Argv) { - SmallString<128> AbsPath; - if (sys::path::is_relative(CfgFile)) { - llvm::sys::fs::current_path(AbsPath); - llvm::sys::path::append(AbsPath, CfgFile); - CfgFile = AbsPath.str(); - } - if (llvm::Error Err = - ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv, - /*MarkEOLs*/ false, /*RelativeNames*/ true, - *llvm::vfs::getRealFileSystem())) { - // TODO: The error should be propagated up the stack. - llvm::consumeError(std::move(Err)); + if (!ExpandResponseFile(CfgFile, Saver, cl::tokenizeConfigFile, Argv, + /*MarkEOLs*/ false, /*RelativeNames*/ true)) return false; - } return ExpandResponseFiles(Saver, cl::tokenizeConfigFile, Argv, /*MarkEOLs*/ false, /*RelativeNames*/ true); } @@ -1500,7 +1447,7 @@ bool CommandLineParser::ParseCommandLineOptions(int argc, if (NearestHandler) { // If we know a near match, report it as well. *Errs << ProgramName << ": Did you mean '" - << PrintArg(NearestHandlerString, 0) << "'?\n"; + << PrintArg(NearestHandlerString) << "'?\n"; } ErrorParsing = true; @@ -1654,7 +1601,7 @@ bool Option::error(const Twine &Message, StringRef ArgName, raw_ostream &Errs) { if (ArgName.empty()) Errs << HelpStr; // Be nice for positional arguments else - Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName, 0); + Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName); Errs << " option: " << Message << "\n"; return true; @@ -1810,24 +1757,6 @@ bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg, return false; } -// parser<long> implementation -// -bool parser<long>::parse(Option &O, StringRef ArgName, StringRef Arg, - long &Value) { - if (Arg.getAsInteger(0, Value)) - return O.error("'" + Arg + "' value invalid for long argument!"); - return false; -} - -// parser<long long> implementation -// -bool parser<long long>::parse(Option &O, StringRef ArgName, StringRef Arg, - long long &Value) { - if (Arg.getAsInteger(0, Value)) - return O.error("'" + Arg + "' value invalid for llong argument!"); - return false; -} - // parser<unsigned> implementation // bool parser<unsigned>::parse(Option &O, StringRef ArgName, StringRef Arg, @@ -2037,8 +1966,6 @@ void generic_parser_base::printGenericOptionDiff( PRINT_OPT_DIFF(bool) PRINT_OPT_DIFF(boolOrDefault) PRINT_OPT_DIFF(int) -PRINT_OPT_DIFF(long) -PRINT_OPT_DIFF(long long) PRINT_OPT_DIFF(unsigned) PRINT_OPT_DIFF(unsigned long) PRINT_OPT_DIFF(unsigned long long) @@ -2112,7 +2039,7 @@ static void sortOpts(StringMap<Option *> &OptMap, static void sortSubCommands(const SmallPtrSetImpl<SubCommand *> &SubMap, SmallVectorImpl<std::pair<const char *, SubCommand *>> &Subs) { - for (auto *S : SubMap) { + for (const auto &S : SubMap) { if (S->getName().empty()) continue; Subs.push_back(std::make_pair(S->getName().data(), S)); @@ -2436,28 +2363,6 @@ static VersionPrinterTy OverrideVersionPrinter = nullptr; static std::vector<VersionPrinterTy> *ExtraVersionPrinters = nullptr; -#if defined(__GNUC__) -// GCC and GCC-compatible compilers define __OPTIMIZE__ when optimizations are -// enabled. -# if defined(__OPTIMIZE__) -# define LLVM_IS_DEBUG_BUILD 0 -# else -# define LLVM_IS_DEBUG_BUILD 1 -# endif -#elif defined(_MSC_VER) -// MSVC doesn't have a predefined macro indicating if optimizations are enabled. -// Use _DEBUG instead. This macro actually corresponds to the choice between -// debug and release CRTs, but it is a reasonable proxy. -# if defined(_DEBUG) -# define LLVM_IS_DEBUG_BUILD 1 -# else -# define LLVM_IS_DEBUG_BUILD 0 -# endif -#else -// Otherwise, for an unknown compiler, assume this is an optimized build. -# define LLVM_IS_DEBUG_BUILD 0 -#endif - namespace { class VersionPrinter { public: @@ -2473,7 +2378,7 @@ public: OS << " " << LLVM_VERSION_INFO; #endif OS << "\n "; -#if LLVM_IS_DEBUG_BUILD +#ifndef __OPTIMIZE__ OS << "DEBUG build"; #else OS << "Optimized build"; diff --git a/contrib/llvm-project/llvm/lib/Support/Compression.cpp b/contrib/llvm-project/llvm/lib/Support/Compression.cpp index 4165a2740cd0..97d5ffaadf82 100644 --- a/contrib/llvm-project/llvm/lib/Support/Compression.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Compression.cpp @@ -17,13 +17,13 @@ #include "llvm/Support/Compiler.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" -#if LLVM_ENABLE_ZLIB +#if LLVM_ENABLE_ZLIB == 1 && HAVE_ZLIB_H #include <zlib.h> #endif using namespace llvm; -#if LLVM_ENABLE_ZLIB +#if LLVM_ENABLE_ZLIB == 1 && HAVE_LIBZ static Error createError(StringRef Err) { return make_error<StringError>(Err, inconvertibleErrorCode()); } diff --git a/contrib/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp b/contrib/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp index 356835609830..c2459256f8fe 100644 --- a/contrib/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp +++ b/contrib/llvm-project/llvm/lib/Support/CrashRecoveryContext.cpp @@ -10,14 +10,9 @@ #include "llvm/Config/llvm-config.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" -#include "llvm/Support/Signals.h" +#include "llvm/Support/Mutex.h" #include "llvm/Support/ThreadLocal.h" -#include <mutex> #include <setjmp.h> -#if LLVM_ON_UNIX -#include <sysexits.h> // EX_IOERR -#endif - using namespace llvm; namespace { @@ -38,11 +33,11 @@ struct CrashRecoveryContextImpl { ::jmp_buf JumpBuffer; volatile unsigned Failed : 1; unsigned SwitchedThread : 1; - unsigned ValidJumpBuffer : 1; public: - CrashRecoveryContextImpl(CrashRecoveryContext *CRC) noexcept - : CRC(CRC), Failed(false), SwitchedThread(false), ValidJumpBuffer(false) { + CrashRecoveryContextImpl(CrashRecoveryContext *CRC) : CRC(CRC), + Failed(false), + SwitchedThread(false) { Next = CurrentContext->get(); CurrentContext->set(this); } @@ -59,11 +54,7 @@ public: #endif } - // If the function ran by the CrashRecoveryContext crashes or fails, then - // 'RetCode' represents the returned error code, as if it was returned by a - // process. 'Context' represents the signal type on Unix; on Windows, it is - // the ExceptionContext. - void HandleCrash(int RetCode, uintptr_t Context) { + void HandleCrash() { // Eliminate the current context entry, to avoid re-entering in case the // cleanup code crashes. CurrentContext->set(Next); @@ -71,22 +62,16 @@ public: assert(!Failed && "Crash recovery context already failed!"); Failed = true; - if (CRC->DumpStackAndCleanupOnFailure) - sys::CleanupOnSignal(Context); - - CRC->RetCode = RetCode; + // FIXME: Stash the backtrace. // Jump back to the RunSafely we were called under. - if (ValidJumpBuffer) - longjmp(JumpBuffer, 1); - - // Otherwise let the caller decide of the outcome of the crash. Currently - // this occurs when using SEH on Windows with MSVC or clang-cl. + longjmp(JumpBuffer, 1); } }; + } -static ManagedStatic<std::mutex> gCrashRecoveryContextMutex; +static ManagedStatic<sys::Mutex> gCrashRecoveryContextMutex; static bool gCrashRecoveryEnabled = false; static ManagedStatic<sys::ThreadLocal<const CrashRecoveryContext>> @@ -131,7 +116,7 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() { } void CrashRecoveryContext::Enable() { - std::lock_guard<std::mutex> L(*gCrashRecoveryContextMutex); + sys::ScopedLock L(*gCrashRecoveryContextMutex); // FIXME: Shouldn't this be a refcount or something? if (gCrashRecoveryEnabled) return; @@ -140,7 +125,7 @@ void CrashRecoveryContext::Enable() { } void CrashRecoveryContext::Disable() { - std::lock_guard<std::mutex> L(*gCrashRecoveryContextMutex); + sys::ScopedLock L(*gCrashRecoveryContextMutex); if (!gCrashRecoveryEnabled) return; gCrashRecoveryEnabled = false; @@ -175,9 +160,6 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { } #if defined(_MSC_VER) - -#include <windows.h> // for GetExceptionInformation - // If _MSC_VER is defined, we must have SEH. Use it if it's available. It's way // better than VEH. Vectored exception handling catches all exceptions happening // on the thread with installed exception handlers, so it can interfere with @@ -189,47 +171,19 @@ CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) { static void installExceptionOrSignalHandlers() {} static void uninstallExceptionOrSignalHandlers() {} -// We need this function because the call to GetExceptionInformation() can only -// occur inside the __except evaluation block -static int ExceptionFilter(_EXCEPTION_POINTERS *Except) { - // 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; - } - - int RetCode = (int)Except->ExceptionRecord->ExceptionCode; - if ((RetCode & 0xF0000000) == 0xE0000000) - RetCode &= ~0xF0000000; // this crash was generated by sys::Process::Exit - - // Handle the crash - const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash( - RetCode, reinterpret_cast<uintptr_t>(Except)); - - return EXCEPTION_EXECUTE_HANDLER; -} - -#if defined(__clang__) && defined(_M_IX86) -// Work around PR44697. -__attribute__((optnone)) -#endif bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) { if (!gCrashRecoveryEnabled) { Fn(); return true; } - assert(!Impl && "Crash recovery context already initialized!"); - Impl = new CrashRecoveryContextImpl(this); + + bool Result = true; __try { Fn(); - } __except (ExceptionFilter(GetExceptionInformation())) { - return false; + } __except (1) { // Catch any exception. + Result = false; } - return true; + return Result; } #else // !_MSC_VER @@ -282,13 +236,8 @@ static LONG CALLBACK ExceptionHandler(PEXCEPTION_POINTERS ExceptionInfo) // TODO: We can capture the stack backtrace here and store it on the // implementation if we so choose. - int RetCode = (int)ExceptionInfo->ExceptionRecord->ExceptionCode; - if ((RetCode & 0xF0000000) == 0xE0000000) - RetCode &= ~0xF0000000; // this crash was generated by sys::Process::Exit - // Handle the crash - const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash( - RetCode, reinterpret_cast<uintptr_t>(ExceptionInfo)); + const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash(); // Note that we don't actually get here because HandleCrash calls // longjmp, which means the HandleCrash function never returns. @@ -331,7 +280,7 @@ static void uninstallExceptionOrSignalHandlers() { // crash recovery context, and install signal handlers to invoke HandleCrash on // the active object. // -// This implementation does not attempt to chain signal handlers in any +// 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. @@ -370,16 +319,8 @@ static void CrashRecoverySignalHandler(int Signal) { sigaddset(&SigMask, Signal); sigprocmask(SIG_UNBLOCK, &SigMask, nullptr); - // As per convention, -2 indicates a crash or timeout as opposed to failure to - // execute (see llvm/include/llvm/Support/Program.h) - int RetCode = -2; - - // Don't consider a broken pipe as a crash (see clang/lib/Driver/Driver.cpp) - if (Signal == SIGPIPE) - RetCode = EX_IOERR; - if (CRCI) - const_cast<CrashRecoveryContextImpl *>(CRCI)->HandleCrash(RetCode, Signal); + const_cast<CrashRecoveryContextImpl*>(CRCI)->HandleCrash(); } static void installExceptionOrSignalHandlers() { @@ -409,7 +350,6 @@ bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) { CrashRecoveryContextImpl *CRCI = new CrashRecoveryContextImpl(this); Impl = CRCI; - CRCI->ValidJumpBuffer = true; if (setjmp(CRCI->JumpBuffer) != 0) { return false; } @@ -421,19 +361,10 @@ bool CrashRecoveryContext::RunSafely(function_ref<void()> Fn) { #endif // !_MSC_VER -LLVM_ATTRIBUTE_NORETURN -void CrashRecoveryContext::HandleExit(int RetCode) { -#if defined(_WIN32) - // SEH and VEH - ::RaiseException(0xE0000000 | RetCode, 0, 0, NULL); -#else - // On Unix we don't need to raise an exception, we go directly to - // HandleCrash(), then longjmp will unwind the stack for us. - CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *)Impl; +void CrashRecoveryContext::HandleCrash() { + CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl; assert(CRCI && "Crash recovery context never initialized!"); - CRCI->HandleCrash(RetCode, 0 /*no sig num*/); -#endif - llvm_unreachable("Most likely setjmp wasn't called!"); + CRCI->HandleCrash(); } // FIXME: Portability. @@ -473,10 +404,7 @@ 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 == 0 - ? llvm::None - : llvm::Optional<unsigned>(RequestedStackSize)); + llvm_execute_on_thread(RunSafelyOnThread_Dispatch, &Info, RequestedStackSize); if (CrashRecoveryContextImpl *CRC = (CrashRecoveryContextImpl *)Impl) CRC->setSwitchedThread(); return Info.Result; diff --git a/contrib/llvm-project/llvm/lib/Support/DataExtractor.cpp b/contrib/llvm-project/llvm/lib/Support/DataExtractor.cpp index a98297cdb35f..673bbb4d06f4 100644 --- a/contrib/llvm-project/llvm/lib/Support/DataExtractor.cpp +++ b/contrib/llvm-project/llvm/lib/Support/DataExtractor.cpp @@ -7,137 +7,111 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/DataExtractor.h" -#include "llvm/Support/Errc.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/Host.h" -#include "llvm/Support/LEB128.h" #include "llvm/Support/SwapByteOrder.h" - +#include "llvm/Support/LEB128.h" using namespace llvm; -static void unexpectedEndReached(Error *E) { - if (E) - *E = createStringError(errc::illegal_byte_sequence, - "unexpected end of data"); -} - -static bool isError(Error *E) { return E && *E; } - template <typename T> -static T getU(uint64_t *offset_ptr, const DataExtractor *de, - bool isLittleEndian, const char *Data, llvm::Error *Err) { - ErrorAsOutParameter ErrAsOut(Err); +static T getU(uint32_t *offset_ptr, const DataExtractor *de, + bool isLittleEndian, const char *Data) { T val = 0; - if (isError(Err)) - return val; - - uint64_t offset = *offset_ptr; - if (!de->isValidOffsetForDataOfSize(offset, sizeof(T))) { - unexpectedEndReached(Err); - return val; + 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); } - 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(uint64_t *offset_ptr, T *dst, uint32_t count, - const DataExtractor *de, bool isLittleEndian, const char *Data, - llvm::Error *Err) { - ErrorAsOutParameter ErrAsOut(Err); - if (isError(Err)) - return nullptr; - - uint64_t offset = *offset_ptr; - - if (!de->isValidOffsetForDataOfSize(offset, sizeof(*dst) * count)) { - unexpectedEndReached(Err); - return nullptr; +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; } - 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, Err); - // 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(uint64_t *offset_ptr, llvm::Error *Err) const { - return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data(), Err); +uint8_t DataExtractor::getU8(uint32_t *offset_ptr) const { + return getU<uint8_t>(offset_ptr, this, IsLittleEndian, Data.data()); } uint8_t * -DataExtractor::getU8(uint64_t *offset_ptr, uint8_t *dst, uint32_t count) const { +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(), nullptr); + Data.data()); } -uint8_t *DataExtractor::getU8(Cursor &C, uint8_t *Dst, uint32_t Count) const { - return getUs<uint8_t>(&C.Offset, Dst, Count, this, IsLittleEndian, - Data.data(), &C.Err); -} -uint16_t DataExtractor::getU16(uint64_t *offset_ptr, llvm::Error *Err) const { - return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data(), Err); +uint16_t DataExtractor::getU16(uint32_t *offset_ptr) const { + return getU<uint16_t>(offset_ptr, this, IsLittleEndian, Data.data()); } -uint16_t *DataExtractor::getU16(uint64_t *offset_ptr, uint16_t *dst, +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(), nullptr); + Data.data()); } -uint32_t DataExtractor::getU24(uint64_t *offset_ptr) const { +uint32_t DataExtractor::getU24(uint32_t *offset_ptr) const { uint24_t ExtractedVal = - getU<uint24_t>(offset_ptr, this, IsLittleEndian, Data.data(), nullptr); + getU<uint24_t>(offset_ptr, this, IsLittleEndian, Data.data()); // The 3 bytes are in the correct byte order for the host. return ExtractedVal.getAsUint32(sys::IsLittleEndianHost); } -uint32_t DataExtractor::getU32(uint64_t *offset_ptr, llvm::Error *Err) const { - return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data(), Err); +uint32_t DataExtractor::getU32(uint32_t *offset_ptr) const { + return getU<uint32_t>(offset_ptr, this, IsLittleEndian, Data.data()); } -uint32_t *DataExtractor::getU32(uint64_t *offset_ptr, uint32_t *dst, +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(), nullptr); + Data.data()); } -uint64_t DataExtractor::getU64(uint64_t *offset_ptr, llvm::Error *Err) const { - return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data(), Err); +uint64_t DataExtractor::getU64(uint32_t *offset_ptr) const { + return getU<uint64_t>(offset_ptr, this, IsLittleEndian, Data.data()); } -uint64_t *DataExtractor::getU64(uint64_t *offset_ptr, uint64_t *dst, +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(), nullptr); + Data.data()); } -uint64_t DataExtractor::getUnsigned(uint64_t *offset_ptr, uint32_t byte_size, - llvm::Error *Err) const { +uint64_t +DataExtractor::getUnsigned(uint32_t *offset_ptr, uint32_t byte_size) const { switch (byte_size) { case 1: - return getU8(offset_ptr, Err); + return getU8(offset_ptr); case 2: - return getU16(offset_ptr, Err); + return getU16(offset_ptr); case 4: - return getU32(offset_ptr, Err); + return getU32(offset_ptr); case 8: - return getU64(offset_ptr, Err); + return getU64(offset_ptr); } llvm_unreachable("getUnsigned unhandled case!"); } int64_t -DataExtractor::getSigned(uint64_t *offset_ptr, uint32_t byte_size) const { +DataExtractor::getSigned(uint32_t *offset_ptr, uint32_t byte_size) const { switch (byte_size) { case 1: return (int8_t)getU8(offset_ptr); @@ -151,8 +125,8 @@ DataExtractor::getSigned(uint64_t *offset_ptr, uint32_t byte_size) const { llvm_unreachable("getSigned unhandled case!"); } -const char *DataExtractor::getCStr(uint64_t *offset_ptr) const { - uint64_t offset = *offset_ptr; +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; @@ -161,38 +135,31 @@ const char *DataExtractor::getCStr(uint64_t *offset_ptr) const { return nullptr; } -StringRef DataExtractor::getCStrRef(uint64_t *offset_ptr) const { - uint64_t Start = *offset_ptr; +StringRef DataExtractor::getCStrRef(uint32_t *OffsetPtr) const { + uint32_t Start = *OffsetPtr; StringRef::size_type Pos = Data.find('\0', Start); if (Pos != StringRef::npos) { - *offset_ptr = Pos + 1; + *OffsetPtr = Pos + 1; return StringRef(Data.data() + Start, Pos - Start); } return StringRef(); } -uint64_t DataExtractor::getULEB128(uint64_t *offset_ptr, - llvm::Error *Err) const { +uint64_t DataExtractor::getULEB128(uint32_t *offset_ptr) const { assert(*offset_ptr <= Data.size()); - ErrorAsOutParameter ErrAsOut(Err); - if (isError(Err)) - return 0; const char *error; unsigned bytes_read; uint64_t result = decodeULEB128( reinterpret_cast<const uint8_t *>(Data.data() + *offset_ptr), &bytes_read, reinterpret_cast<const uint8_t *>(Data.data() + Data.size()), &error); - if (error) { - if (Err) - *Err = createStringError(errc::illegal_byte_sequence, error); + if (error) return 0; - } *offset_ptr += bytes_read; return result; } -int64_t DataExtractor::getSLEB128(uint64_t *offset_ptr) const { +int64_t DataExtractor::getSLEB128(uint32_t *offset_ptr) const { assert(*offset_ptr <= Data.size()); const char *error; @@ -205,14 +172,3 @@ int64_t DataExtractor::getSLEB128(uint64_t *offset_ptr) const { *offset_ptr += bytes_read; return result; } - -void DataExtractor::skip(Cursor &C, uint64_t Length) const { - ErrorAsOutParameter ErrAsOut(&C.Err); - if (isError(&C.Err)) - return; - - if (isValidOffsetForDataOfSize(C.Offset, Length)) - C.Offset += Length; - else - unexpectedEndReached(&C.Err); -} diff --git a/contrib/llvm-project/llvm/lib/Support/DebugCounter.cpp b/contrib/llvm-project/llvm/lib/Support/DebugCounter.cpp index 1e3ec300964c..6598103658da 100644 --- a/contrib/llvm-project/llvm/lib/Support/DebugCounter.cpp +++ b/contrib/llvm-project/llvm/lib/Support/DebugCounter.cpp @@ -2,6 +2,7 @@ #include "llvm/Support/CommandLine.h" #include "llvm/Support/Format.h" #include "llvm/Support/ManagedStatic.h" +#include "llvm/Support/Options.h" using namespace llvm; diff --git a/contrib/llvm-project/llvm/lib/Support/Error.cpp b/contrib/llvm-project/llvm/lib/Support/Error.cpp index 315a11e967d1..72bc08af2ddb 100644 --- a/contrib/llvm-project/llvm/lib/Support/Error.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Error.cpp @@ -87,7 +87,7 @@ std::error_code FileError::convertToErrorCode() const { Error errorCodeToError(std::error_code EC) { if (!EC) return Error::success(); - return Error(std::make_unique<ECError>(ECError(EC))); + return Error(llvm::make_unique<ECError>(ECError(EC))); } std::error_code errorToErrorCode(Error Err) { @@ -103,10 +103,9 @@ std::error_code errorToErrorCode(Error Err) { #if LLVM_ENABLE_ABI_BREAKING_CHECKS void Error::fatalUncheckedError() const { dbgs() << "Program aborted due to an unhandled Error:\n"; - if (getPtr()) { + if (getPtr()) getPtr()->log(dbgs()); - dbgs() << "\n"; - }else + else dbgs() << "Error value was Success. (Note: Success values must still be " "checked prior to being destroyed).\n"; abort(); @@ -168,3 +167,18 @@ void LLVMDisposeErrorMessage(char *ErrMsg) { delete[] ErrMsg; } LLVMErrorTypeId LLVMGetStringErrorTypeId() { return reinterpret_cast<void *>(&StringError::ID); } + +#ifndef _MSC_VER +namespace llvm { + +// One of these two variables will be referenced by a symbol defined in +// llvm-config.h. We provide a link-time (or load time for DSO) failure when +// there is a mismatch in the build configuration of the API client and LLVM. +#if LLVM_ENABLE_ABI_BREAKING_CHECKS +int EnableABIBreakingChecks; +#else +int DisableABIBreakingChecks; +#endif + +} // end namespace llvm +#endif diff --git a/contrib/llvm-project/llvm/lib/Support/ErrorHandling.cpp b/contrib/llvm-project/llvm/lib/Support/ErrorHandling.cpp index a9463024c420..0f13f7a536f1 100644 --- a/contrib/llvm-project/llvm/lib/Support/ErrorHandling.cpp +++ b/contrib/llvm-project/llvm/lib/Support/ErrorHandling.cpp @@ -19,7 +19,6 @@ #include "llvm/Support/Debug.h" #include "llvm/Support/Errc.h" #include "llvm/Support/Error.h" -#include "llvm/Support/Process.h" #include "llvm/Support/Signals.h" #include "llvm/Support/Threading.h" #include "llvm/Support/WindowsError.h" @@ -123,7 +122,7 @@ void llvm::report_fatal_error(const Twine &Reason, bool GenCrashDiag) { // files registered with RemoveFileOnSignal. sys::RunInterruptHandlers(); - sys::Process::Exit(1); + exit(1); } void llvm::install_bad_alloc_error_handler(fatal_error_handler_t handler, diff --git a/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp b/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp index 2261ecc236c2..e0f17787bdf8 100644 --- a/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp +++ b/contrib/llvm-project/llvm/lib/Support/FileCheck.cpp @@ -14,26 +14,35 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FileCheck.h" -#include "FileCheckImpl.h" #include "llvm/ADT/StringSet.h" -#include "llvm/ADT/Twine.h" #include "llvm/Support/FormatVariadic.h" #include <cstdint> #include <list> +#include <map> #include <tuple> #include <utility> using namespace llvm; -Expected<uint64_t> NumericVariableUse::eval() const { - Optional<uint64_t> Value = Variable->getValue(); +void FileCheckNumericVariable::setValue(uint64_t NewValue) { + assert(!Value && "Overwriting numeric variable's value is not allowed"); + Value = NewValue; +} + +void FileCheckNumericVariable::clearValue() { + if (!Value) + return; + Value = None; +} + +Expected<uint64_t> FileCheckNumericVariableUse::eval() const { + Optional<uint64_t> Value = NumericVariable->getValue(); if (Value) return *Value; - - return make_error<UndefVarError>(Name); + return make_error<FileCheckUndefVarError>(Name); } -Expected<uint64_t> BinaryOperation::eval() const { +Expected<uint64_t> FileCheckASTBinop::eval() const { Expected<uint64_t> LeftOp = LeftOperand->eval(); Expected<uint64_t> RightOp = RightOperand->eval(); @@ -51,14 +60,14 @@ Expected<uint64_t> BinaryOperation::eval() const { return EvalBinop(*LeftOp, *RightOp); } -Expected<std::string> NumericSubstitution::getResult() const { - Expected<uint64_t> EvaluatedValue = ExpressionASTPointer->eval(); +Expected<std::string> FileCheckNumericSubstitution::getResult() const { + Expected<uint64_t> EvaluatedValue = ExpressionAST->eval(); if (!EvaluatedValue) return EvaluatedValue.takeError(); return utostr(*EvaluatedValue); } -Expected<std::string> StringSubstitution::getResult() const { +Expected<std::string> FileCheckStringSubstitution::getResult() const { // Look up the value and escape it so that we can put it into the regex. Expected<StringRef> VarVal = Context->getPatternVarValue(FromStr); if (!VarVal) @@ -66,12 +75,14 @@ Expected<std::string> StringSubstitution::getResult() const { return Regex::escape(*VarVal); } -bool Pattern::isValidVarNameStart(char C) { return C == '_' || isalpha(C); } +bool FileCheckPattern::isValidVarNameStart(char C) { + return C == '_' || isalpha(C); +} -Expected<Pattern::VariableProperties> -Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) { +Expected<FileCheckPattern::VariableProperties> +FileCheckPattern::parseVariable(StringRef &Str, const SourceMgr &SM) { if (Str.empty()) - return ErrorDiagnostic::get(SM, Str, "empty variable name"); + return FileCheckErrorDiagnostic::get(SM, Str, "empty variable name"); bool ParsedOneChar = false; unsigned I = 0; @@ -83,7 +94,7 @@ Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) { for (unsigned E = Str.size(); I != E; ++I) { if (!ParsedOneChar && !isValidVarNameStart(Str[I])) - return ErrorDiagnostic::get(SM, Str, "invalid variable name"); + return FileCheckErrorDiagnostic::get(SM, Str, "invalid variable name"); // Variable names are composed of alphanumeric characters and underscores. if (Str[I] != '_' && !isalnum(Str[I])) @@ -98,7 +109,7 @@ Pattern::parseVariable(StringRef &Str, const SourceMgr &SM) { // StringRef holding all characters considered as horizontal whitespaces by // FileCheck input canonicalization. -constexpr StringLiteral SpaceChars = " \t"; +StringRef SpaceChars = " \t"; // Parsing helper function that strips the first character in S and returns it. static char popFront(StringRef &S) { @@ -107,11 +118,12 @@ static char popFront(StringRef &S) { return C; } -char UndefVarError::ID = 0; -char ErrorDiagnostic::ID = 0; -char NotFoundError::ID = 0; +char FileCheckUndefVarError::ID = 0; +char FileCheckErrorDiagnostic::ID = 0; +char FileCheckNotFoundError::ID = 0; -Expected<NumericVariable *> Pattern::parseNumericVariableDefinition( +Expected<FileCheckNumericVariable *> +FileCheckPattern::parseNumericVariableDefinition( StringRef &Expr, FileCheckPatternContext *Context, Optional<size_t> LineNumber, const SourceMgr &SM) { Expected<VariableProperties> ParseVarResult = parseVariable(Expr, SM); @@ -120,22 +132,22 @@ Expected<NumericVariable *> Pattern::parseNumericVariableDefinition( StringRef Name = ParseVarResult->Name; if (ParseVarResult->IsPseudo) - return ErrorDiagnostic::get( + return FileCheckErrorDiagnostic::get( SM, Name, "definition of pseudo numeric variable unsupported"); // Detect collisions between string and numeric variables when the latter // is created later than the former. if (Context->DefinedVariableTable.find(Name) != Context->DefinedVariableTable.end()) - return ErrorDiagnostic::get( + return FileCheckErrorDiagnostic::get( SM, Name, "string variable with name '" + Name + "' already exists"); Expr = Expr.ltrim(SpaceChars); if (!Expr.empty()) - return ErrorDiagnostic::get( + return FileCheckErrorDiagnostic::get( SM, Expr, "unexpected characters after numeric variable name"); - NumericVariable *DefinedNumericVariable; + FileCheckNumericVariable *DefinedNumericVariable; auto VarTableIter = Context->GlobalNumericVariableTable.find(Name); if (VarTableIter != Context->GlobalNumericVariableTable.end()) DefinedNumericVariable = VarTableIter->second; @@ -145,11 +157,11 @@ Expected<NumericVariable *> Pattern::parseNumericVariableDefinition( return DefinedNumericVariable; } -Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse( - StringRef Name, bool IsPseudo, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM) { +Expected<std::unique_ptr<FileCheckNumericVariableUse>> +FileCheckPattern::parseNumericVariableUse(StringRef Name, bool IsPseudo, + const SourceMgr &SM) const { if (IsPseudo && !Name.equals("@LINE")) - return ErrorDiagnostic::get( + return FileCheckErrorDiagnostic::get( SM, Name, "invalid pseudo numeric variable '" + Name + "'"); // Numeric variable definitions and uses are parsed in the order in which @@ -161,7 +173,7 @@ Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse( // uses of undefined variables, whether string or numeric, are then diagnosed // in printSubstitutions() after failing to match. auto VarTableIter = Context->GlobalNumericVariableTable.find(Name); - NumericVariable *NumericVariable; + FileCheckNumericVariable *NumericVariable; if (VarTableIter != Context->GlobalNumericVariableTable.end()) NumericVariable = VarTableIter->second; else { @@ -171,25 +183,23 @@ Expected<std::unique_ptr<NumericVariableUse>> Pattern::parseNumericVariableUse( Optional<size_t> DefLineNumber = NumericVariable->getDefLineNumber(); if (DefLineNumber && LineNumber && *DefLineNumber == *LineNumber) - return ErrorDiagnostic::get( + return FileCheckErrorDiagnostic::get( SM, Name, - "numeric variable '" + Name + - "' defined earlier in the same CHECK directive"); + "numeric variable '" + Name + "' defined on the same line as used"); - return std::make_unique<NumericVariableUse>(Name, NumericVariable); + return llvm::make_unique<FileCheckNumericVariableUse>(Name, NumericVariable); } -Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand( - StringRef &Expr, AllowedOperand AO, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM) { +Expected<std::unique_ptr<FileCheckExpressionAST>> +FileCheckPattern::parseNumericOperand(StringRef &Expr, AllowedOperand AO, + const SourceMgr &SM) const { if (AO == AllowedOperand::LineVar || AO == AllowedOperand::Any) { // Try to parse as a numeric variable use. - Expected<Pattern::VariableProperties> ParseVarResult = + Expected<FileCheckPattern::VariableProperties> ParseVarResult = parseVariable(Expr, SM); if (ParseVarResult) return parseNumericVariableUse(ParseVarResult->Name, - ParseVarResult->IsPseudo, LineNumber, - Context, SM); + ParseVarResult->IsPseudo, SM); if (AO == AllowedOperand::LineVar) return ParseVarResult.takeError(); // Ignore the error and retry parsing as a literal. @@ -199,10 +209,10 @@ Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericOperand( // Otherwise, parse it as a literal. uint64_t LiteralValue; if (!Expr.consumeInteger(/*Radix=*/10, LiteralValue)) - return std::make_unique<ExpressionLiteral>(LiteralValue); + return llvm::make_unique<FileCheckExpressionLiteral>(LiteralValue); - return ErrorDiagnostic::get(SM, Expr, - "invalid operand format '" + Expr + "'"); + return FileCheckErrorDiagnostic::get(SM, Expr, + "invalid operand format '" + Expr + "'"); } static uint64_t add(uint64_t LeftOp, uint64_t RightOp) { @@ -213,10 +223,10 @@ static uint64_t sub(uint64_t LeftOp, uint64_t RightOp) { return LeftOp - RightOp; } -Expected<std::unique_ptr<ExpressionAST>> -Pattern::parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp, - bool IsLegacyLineExpr, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM) { +Expected<std::unique_ptr<FileCheckExpressionAST>> +FileCheckPattern::parseBinop(StringRef &Expr, + std::unique_ptr<FileCheckExpressionAST> LeftOp, + bool IsLegacyLineExpr, const SourceMgr &SM) const { Expr = Expr.ltrim(SpaceChars); if (Expr.empty()) return std::move(LeftOp); @@ -234,82 +244,82 @@ Pattern::parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp, EvalBinop = sub; break; default: - return ErrorDiagnostic::get( + return FileCheckErrorDiagnostic::get( SM, OpLoc, Twine("unsupported operation '") + Twine(Operator) + "'"); } // Parse right operand. Expr = Expr.ltrim(SpaceChars); if (Expr.empty()) - return ErrorDiagnostic::get(SM, Expr, "missing operand in expression"); + return FileCheckErrorDiagnostic::get(SM, Expr, + "missing operand in expression"); // The second operand in a legacy @LINE expression is always a literal. AllowedOperand AO = IsLegacyLineExpr ? AllowedOperand::Literal : AllowedOperand::Any; - Expected<std::unique_ptr<ExpressionAST>> RightOpResult = - parseNumericOperand(Expr, AO, LineNumber, Context, SM); + Expected<std::unique_ptr<FileCheckExpressionAST>> RightOpResult = + parseNumericOperand(Expr, AO, SM); if (!RightOpResult) return RightOpResult; Expr = Expr.ltrim(SpaceChars); - return std::make_unique<BinaryOperation>(EvalBinop, std::move(LeftOp), - std::move(*RightOpResult)); + return llvm::make_unique<FileCheckASTBinop>(EvalBinop, std::move(LeftOp), + std::move(*RightOpResult)); } -Expected<std::unique_ptr<ExpressionAST>> Pattern::parseNumericSubstitutionBlock( - StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable, - bool IsLegacyLineExpr, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM) { - std::unique_ptr<ExpressionAST> ExpressionASTPointer = nullptr; - StringRef DefExpr = StringRef(); +Expected<std::unique_ptr<FileCheckExpressionAST>> +FileCheckPattern::parseNumericSubstitutionBlock( + StringRef Expr, + Optional<FileCheckNumericVariable *> &DefinedNumericVariable, + bool IsLegacyLineExpr, const SourceMgr &SM) const { + // Parse the numeric variable definition. DefinedNumericVariable = None; - // Save variable definition expression if any. size_t DefEnd = Expr.find(':'); if (DefEnd != StringRef::npos) { - DefExpr = Expr.substr(0, DefEnd); - Expr = Expr.substr(DefEnd + 1); - } + StringRef DefExpr = Expr.substr(0, DefEnd); + StringRef UseExpr = Expr.substr(DefEnd + 1); - // Parse the expression itself. - Expr = Expr.ltrim(SpaceChars); - if (!Expr.empty()) { - // The first operand in a legacy @LINE expression is always the @LINE - // pseudo variable. - AllowedOperand AO = - IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any; - Expected<std::unique_ptr<ExpressionAST>> ParseResult = - parseNumericOperand(Expr, AO, LineNumber, Context, SM); - while (ParseResult && !Expr.empty()) { - ParseResult = parseBinop(Expr, std::move(*ParseResult), IsLegacyLineExpr, - LineNumber, Context, SM); - // Legacy @LINE expressions only allow 2 operands. - if (ParseResult && IsLegacyLineExpr && !Expr.empty()) - return ErrorDiagnostic::get( - SM, Expr, - "unexpected characters at end of expression '" + Expr + "'"); - } - if (!ParseResult) - return ParseResult; - ExpressionASTPointer = std::move(*ParseResult); - } + UseExpr = UseExpr.ltrim(SpaceChars); + if (!UseExpr.empty()) + return FileCheckErrorDiagnostic::get( + SM, UseExpr, + "unexpected string after variable definition: '" + UseExpr + "'"); - // Parse the numeric variable definition. - if (DefEnd != StringRef::npos) { DefExpr = DefExpr.ltrim(SpaceChars); - Expected<NumericVariable *> ParseResult = + Expected<FileCheckNumericVariable *> ParseResult = parseNumericVariableDefinition(DefExpr, Context, LineNumber, SM); - if (!ParseResult) return ParseResult.takeError(); DefinedNumericVariable = *ParseResult; + + return nullptr; } - return std::move(ExpressionASTPointer); + // Parse the expression itself. + Expr = Expr.ltrim(SpaceChars); + // The first operand in a legacy @LINE expression is always the @LINE pseudo + // variable. + AllowedOperand AO = + IsLegacyLineExpr ? AllowedOperand::LineVar : AllowedOperand::Any; + Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult = + parseNumericOperand(Expr, AO, SM); + while (ParseResult && !Expr.empty()) { + ParseResult = + parseBinop(Expr, std::move(*ParseResult), IsLegacyLineExpr, SM); + // Legacy @LINE expressions only allow 2 operands. + if (ParseResult && IsLegacyLineExpr && !Expr.empty()) + return FileCheckErrorDiagnostic::get( + SM, Expr, + "unexpected characters at end of expression '" + Expr + "'"); + } + if (!ParseResult) + return ParseResult; + return std::move(*ParseResult); } -bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, - SourceMgr &SM, const FileCheckRequest &Req) { +bool FileCheckPattern::parsePattern(StringRef PatternStr, StringRef Prefix, + SourceMgr &SM, + const FileCheckRequest &Req) { bool MatchFullLinesHere = Req.MatchFullLines && CheckTy != Check::CheckNot; - IgnoreCase = Req.IgnoreCase; PatternLoc = SMLoc::getFromPointer(PatternStr.data()); @@ -386,15 +396,14 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, continue; } - // String and numeric substitution blocks. Pattern substitution blocks come + // String and numeric substitution blocks. String substitution blocks come // in two forms: [[foo:.*]] and [[foo]]. The former matches .* (or some // other regex) and assigns it to the string variable 'foo'. The latter - // substitutes foo's value. Numeric substitution blocks recognize the same - // form as string ones, but start with a '#' sign after the double - // brackets. They also accept a combined form which sets a numeric variable - // to the evaluation of an expression. Both string and numeric variable - // names must satisfy the regular expression "[a-zA-Z_][0-9a-zA-Z_]*" to be - // valid, as this helps catch some common errors. + // substitutes foo's value. Numeric substitution blocks work the same way + // as string ones, but start with a '#' sign after the double brackets. + // Both string and numeric variable names must satisfy the regular + // expression "[a-zA-Z_][0-9a-zA-Z_]*" to be valid, as this helps catch + // some common errors. if (PatternStr.startswith("[[")) { StringRef UnparsedPatternStr = PatternStr.substr(2); // Find the closing bracket pair ending the match. End is going to be an @@ -415,7 +424,6 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, PatternStr = UnparsedPatternStr.substr(End + 2); bool IsDefinition = false; - bool SubstNeeded = false; // Whether the substitution block is a legacy use of @LINE with string // substitution block syntax. bool IsLegacyLineExpr = false; @@ -436,7 +444,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, // Get the name (e.g. "foo") and verify it is well formed. StringRef OrigMatchStr = MatchStr; - Expected<Pattern::VariableProperties> ParseVarResult = + Expected<FileCheckPattern::VariableProperties> ParseVarResult = parseVariable(MatchStr, SM); if (!ParseVarResult) { logAllUnhandledErrors(ParseVarResult.takeError(), errs()); @@ -446,7 +454,6 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, bool IsPseudo = ParseVarResult->IsPseudo; IsDefinition = (VarEndIdx != StringRef::npos); - SubstNeeded = !IsDefinition; if (IsDefinition) { if ((IsPseudo || !MatchStr.consume_front(":"))) { SM.PrintMessage(SMLoc::getFromPointer(Name.data()), @@ -476,66 +483,27 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, } // Parse numeric substitution block. - std::unique_ptr<ExpressionAST> ExpressionASTPointer; - Optional<NumericVariable *> DefinedNumericVariable; + std::unique_ptr<FileCheckExpressionAST> ExpressionAST; + Optional<FileCheckNumericVariable *> DefinedNumericVariable; if (IsNumBlock) { - Expected<std::unique_ptr<ExpressionAST>> ParseResult = + Expected<std::unique_ptr<FileCheckExpressionAST>> ParseResult = parseNumericSubstitutionBlock(MatchStr, DefinedNumericVariable, - IsLegacyLineExpr, LineNumber, Context, - SM); + IsLegacyLineExpr, SM); if (!ParseResult) { logAllUnhandledErrors(ParseResult.takeError(), errs()); return true; } - ExpressionASTPointer = std::move(*ParseResult); - SubstNeeded = ExpressionASTPointer != nullptr; + ExpressionAST = std::move(*ParseResult); if (DefinedNumericVariable) { IsDefinition = true; DefName = (*DefinedNumericVariable)->getName(); - } - if (SubstNeeded) + MatchRegexp = StringRef("[0-9]+"); + } else SubstStr = MatchStr; - else - MatchRegexp = "[0-9]+"; - } - - // Handle variable definition: [[<def>:(...)]] and [[#(...)<def>:(...)]]. - if (IsDefinition) { - RegExStr += '('; - ++SubstInsertIdx; - - if (IsNumBlock) { - NumericVariableMatch NumericVariableDefinition = { - *DefinedNumericVariable, CurParen}; - NumericVariableDefs[DefName] = NumericVariableDefinition; - // This store is done here rather than in match() to allow - // parseNumericVariableUse() to get the pointer to the class instance - // of the right variable definition corresponding to a given numeric - // variable use. - Context->GlobalNumericVariableTable[DefName] = - *DefinedNumericVariable; - } else { - VariableDefs[DefName] = CurParen; - // Mark string variable as defined to detect collisions between - // string and numeric variables in parseNumericVariableUse() and - // defineCmdlineVariables() when the latter is created later than the - // former. We cannot reuse GlobalVariableTable for this by populating - // it with an empty string since we would then lose the ability to - // detect the use of an undefined variable in match(). - Context->DefinedVariableTable[DefName] = true; - } - - ++CurParen; } - if (!MatchRegexp.empty() && AddRegExToRegEx(MatchRegexp, CurParen, SM)) - return true; - - if (IsDefinition) - RegExStr += ')'; - // Handle substitutions: [[foo]] and [[#<foo expr>]]. - if (SubstNeeded) { + if (!IsDefinition) { // Handle substitution of string variables that were defined earlier on // the same line by emitting a backreference. Expressions do not // support substituting a numeric variable defined on the same line. @@ -551,15 +519,44 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, } else { // Handle substitution of string variables ([[<var>]]) defined in // previous CHECK patterns, and substitution of expressions. - Substitution *Substitution = + FileCheckSubstitution *Substitution = IsNumBlock ? Context->makeNumericSubstitution( - SubstStr, std::move(ExpressionASTPointer), - SubstInsertIdx) + SubstStr, std::move(ExpressionAST), SubstInsertIdx) : Context->makeStringSubstitution(SubstStr, SubstInsertIdx); Substitutions.push_back(Substitution); } + continue; } + + // Handle variable definitions: [[<def>:(...)]] and + // [[#(...)<def>:(...)]]. + if (IsNumBlock) { + FileCheckNumericVariableMatch NumericVariableDefinition = { + *DefinedNumericVariable, CurParen}; + NumericVariableDefs[DefName] = NumericVariableDefinition; + // This store is done here rather than in match() to allow + // parseNumericVariableUse() to get the pointer to the class instance + // of the right variable definition corresponding to a given numeric + // variable use. + Context->GlobalNumericVariableTable[DefName] = *DefinedNumericVariable; + } else { + VariableDefs[DefName] = CurParen; + // Mark the string variable as defined to detect collisions between + // string and numeric variables in parseNumericVariableUse() and + // DefineCmdlineVariables() when the latter is created later than the + // former. We cannot reuse GlobalVariableTable for this by populating + // it with an empty string since we would then lose the ability to + // detect the use of an undefined variable in match(). + Context->DefinedVariableTable[DefName] = true; + } + RegExStr += '('; + ++CurParen; + + if (AddRegExToRegEx(MatchRegexp, CurParen, SM)) + return true; + + RegExStr += ')'; } // Handle fixed string matches. @@ -579,7 +576,7 @@ bool Pattern::parsePattern(StringRef PatternStr, StringRef Prefix, return false; } -bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) { +bool FileCheckPattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) { Regex R(RS); std::string Error; if (!R.isValid(Error)) { @@ -593,14 +590,14 @@ bool Pattern::AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM) { return false; } -void Pattern::AddBackrefToRegEx(unsigned BackrefNum) { +void FileCheckPattern::AddBackrefToRegEx(unsigned BackrefNum) { assert(BackrefNum >= 1 && BackrefNum <= 9 && "Invalid backref number"); std::string Backref = std::string("\\") + std::string(1, '0' + BackrefNum); RegExStr += Backref; } -Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen, - const SourceMgr &SM) const { +Expected<size_t> FileCheckPattern::match(StringRef Buffer, size_t &MatchLen, + const SourceMgr &SM) const { // If this is the EOF pattern, match it immediately. if (CheckTy == Check::CheckEOF) { MatchLen = 0; @@ -610,10 +607,9 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen, // If this is a fixed string pattern, just match it now. if (!FixedStr.empty()) { MatchLen = FixedStr.size(); - size_t Pos = - IgnoreCase ? Buffer.find_lower(FixedStr) : Buffer.find(FixedStr); + size_t Pos = Buffer.find(FixedStr); if (Pos == StringRef::npos) - return make_error<NotFoundError>(); + return make_error<FileCheckNotFoundError>(); return Pos; } @@ -635,8 +631,10 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen, for (const auto &Substitution : Substitutions) { // Substitute and check for failure (e.g. use of undefined variable). Expected<std::string> Value = Substitution->getResult(); - if (!Value) + if (!Value) { + Context->LineVariable->clearValue(); return Value.takeError(); + } // Plop it into the regex at the adjusted offset. TmpStr.insert(TmpStr.begin() + Substitution->getIndex() + InsertOffset, @@ -646,14 +644,12 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen, // Match the newly constructed regex. RegExToMatch = TmpStr; + Context->LineVariable->clearValue(); } SmallVector<StringRef, 4> MatchInfo; - unsigned int Flags = Regex::Newline; - if (IgnoreCase) - Flags |= Regex::IgnoreCase; - if (!Regex(RegExToMatch, Flags).match(Buffer, &MatchInfo)) - return make_error<NotFoundError>(); + if (!Regex(RegExToMatch, Regex::Newline).match(Buffer, &MatchInfo)) + return make_error<FileCheckNotFoundError>(); // Successful regex match. assert(!MatchInfo.empty() && "Didn't get any match"); @@ -668,18 +664,18 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen, // If this defines any numeric variables, remember their values. for (const auto &NumericVariableDef : NumericVariableDefs) { - const NumericVariableMatch &NumericVariableMatch = + const FileCheckNumericVariableMatch &NumericVariableMatch = NumericVariableDef.getValue(); unsigned CaptureParenGroup = NumericVariableMatch.CaptureParenGroup; assert(CaptureParenGroup < MatchInfo.size() && "Internal paren error"); - NumericVariable *DefinedNumericVariable = + FileCheckNumericVariable *DefinedNumericVariable = NumericVariableMatch.DefinedNumericVariable; StringRef MatchedValue = MatchInfo[CaptureParenGroup]; uint64_t Val; if (MatchedValue.getAsInteger(10, Val)) - return ErrorDiagnostic::get(SM, MatchedValue, - "Unable to represent numeric value"); + return FileCheckErrorDiagnostic::get(SM, MatchedValue, + "Unable to represent numeric value"); DefinedNumericVariable->setValue(Val); } @@ -691,7 +687,7 @@ Expected<size_t> Pattern::match(StringRef Buffer, size_t &MatchLen, return FullMatch.data() - Buffer.data() + MatchStartSkip; } -unsigned Pattern::computeMatchDistance(StringRef Buffer) const { +unsigned FileCheckPattern::computeMatchDistance(StringRef Buffer) const { // Just compute the number of matching characters. For regular expressions, we // just compare against the regex itself and hope for the best. // @@ -708,8 +704,8 @@ unsigned Pattern::computeMatchDistance(StringRef Buffer) const { return BufferPrefix.edit_distance(ExampleString); } -void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer, - SMRange MatchRange) const { +void FileCheckPattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer, + SMRange MatchRange) const { // Print what we know about substitutions. if (!Substitutions.empty()) { for (const auto &Substitution : Substitutions) { @@ -721,10 +717,11 @@ void Pattern::printSubstitutions(const SourceMgr &SM, StringRef Buffer, // variables it uses. if (!MatchedValue) { bool UndefSeen = false; - handleAllErrors(MatchedValue.takeError(), [](const NotFoundError &E) {}, + handleAllErrors(MatchedValue.takeError(), + [](const FileCheckNotFoundError &E) {}, // Handled in PrintNoMatch(). - [](const ErrorDiagnostic &E) {}, - [&](const UndefVarError &E) { + [](const FileCheckErrorDiagnostic &E) {}, + [&](const FileCheckUndefVarError &E) { if (!UndefSeen) { OS << "uses undefined variable(s):"; UndefSeen = true; @@ -767,8 +764,9 @@ static SMRange ProcessMatchResult(FileCheckDiag::MatchType MatchTy, return Range; } -void Pattern::printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, - std::vector<FileCheckDiag> *Diags) const { +void FileCheckPattern::printFuzzyMatch( + const SourceMgr &SM, StringRef Buffer, + std::vector<FileCheckDiag> *Diags) const { // Attempt to find the closest/best fuzzy match. Usually an error happens // because some string in the output didn't exactly match. In these cases, we // would like to show the user a best guess at what "should have" matched, to @@ -817,34 +815,36 @@ Expected<StringRef> FileCheckPatternContext::getPatternVarValue(StringRef VarName) { auto VarIter = GlobalVariableTable.find(VarName); if (VarIter == GlobalVariableTable.end()) - return make_error<UndefVarError>(VarName); + return make_error<FileCheckUndefVarError>(VarName); return VarIter->second; } template <class... Types> -NumericVariable *FileCheckPatternContext::makeNumericVariable(Types... args) { - NumericVariables.push_back(std::make_unique<NumericVariable>(args...)); +FileCheckNumericVariable * +FileCheckPatternContext::makeNumericVariable(Types... args) { + NumericVariables.push_back( + llvm::make_unique<FileCheckNumericVariable>(args...)); return NumericVariables.back().get(); } -Substitution * +FileCheckSubstitution * FileCheckPatternContext::makeStringSubstitution(StringRef VarName, size_t InsertIdx) { Substitutions.push_back( - std::make_unique<StringSubstitution>(this, VarName, InsertIdx)); + llvm::make_unique<FileCheckStringSubstitution>(this, VarName, InsertIdx)); return Substitutions.back().get(); } -Substitution *FileCheckPatternContext::makeNumericSubstitution( +FileCheckSubstitution *FileCheckPatternContext::makeNumericSubstitution( StringRef ExpressionStr, - std::unique_ptr<ExpressionAST> ExpressionASTPointer, size_t InsertIdx) { - Substitutions.push_back(std::make_unique<NumericSubstitution>( - this, ExpressionStr, std::move(ExpressionASTPointer), InsertIdx)); + std::unique_ptr<FileCheckExpressionAST> ExpressionAST, size_t InsertIdx) { + Substitutions.push_back(llvm::make_unique<FileCheckNumericSubstitution>( + this, ExpressionStr, std::move(ExpressionAST), InsertIdx)); return Substitutions.back().get(); } -size_t Pattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) { +size_t FileCheckPattern::FindRegexVarEnd(StringRef Str, SourceMgr &SM) { // Offset keeps track of the current offset within the input Str size_t Offset = 0; // [...] Nesting depth @@ -1108,24 +1108,18 @@ void FileCheckPatternContext::createLineVariable() { GlobalNumericVariableTable[LineName] = LineVariable; } -FileCheck::FileCheck(FileCheckRequest Req) - : Req(Req), PatternContext(std::make_unique<FileCheckPatternContext>()), - CheckStrings(std::make_unique<std::vector<FileCheckString>>()) {} - -FileCheck::~FileCheck() = default; - -bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer, - Regex &PrefixRE) { +bool FileCheck::ReadCheckFile(SourceMgr &SM, StringRef Buffer, Regex &PrefixRE, + std::vector<FileCheckString> &CheckStrings) { Error DefineError = - PatternContext->defineCmdlineVariables(Req.GlobalDefines, SM); + PatternContext.defineCmdlineVariables(Req.GlobalDefines, SM); if (DefineError) { logAllUnhandledErrors(std::move(DefineError), errs()); return true; } - PatternContext->createLineVariable(); + PatternContext.createLineVariable(); - std::vector<Pattern> ImplicitNegativeChecks; + std::vector<FileCheckPattern> ImplicitNegativeChecks; for (const auto &PatternString : Req.ImplicitCheckNot) { // Create a buffer with fake command line content in order to display the // command line option responsible for the specific implicit CHECK-NOT. @@ -1139,12 +1133,12 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer, SM.AddNewSourceBuffer(std::move(CmdLine), SMLoc()); ImplicitNegativeChecks.push_back( - Pattern(Check::CheckNot, PatternContext.get())); + FileCheckPattern(Check::CheckNot, &PatternContext)); ImplicitNegativeChecks.back().parsePattern(PatternInBuffer, "IMPLICIT-CHECK", SM, Req); } - std::vector<Pattern> DagNotMatches = ImplicitNegativeChecks; + std::vector<FileCheckPattern> DagNotMatches = ImplicitNegativeChecks; // LineNumber keeps track of the line on which CheckPrefix instances are // found. @@ -1202,7 +1196,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer, SMLoc PatternLoc = SMLoc::getFromPointer(Buffer.data()); // Parse the pattern. - Pattern P(CheckTy, PatternContext.get(), LineNumber); + FileCheckPattern P(CheckTy, &PatternContext, LineNumber); if (P.parsePattern(Buffer.substr(0, EOL), UsedPrefix, SM, Req)) return true; @@ -1220,7 +1214,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer, // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them. if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame || CheckTy == Check::CheckEmpty) && - CheckStrings->empty()) { + CheckStrings.empty()) { StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME"; @@ -1238,21 +1232,21 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer, } // Okay, add the string we captured to the output vector and move on. - CheckStrings->emplace_back(P, UsedPrefix, PatternLoc); - std::swap(DagNotMatches, CheckStrings->back().DagNotStrings); + CheckStrings.emplace_back(P, UsedPrefix, PatternLoc); + std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); DagNotMatches = ImplicitNegativeChecks; } // Add an EOF pattern for any trailing CHECK-DAG/-NOTs, and use the first // prefix as a filler for the error message. if (!DagNotMatches.empty()) { - CheckStrings->emplace_back( - Pattern(Check::CheckEOF, PatternContext.get(), LineNumber + 1), + CheckStrings.emplace_back( + FileCheckPattern(Check::CheckEOF, &PatternContext, LineNumber + 1), *Req.CheckPrefixes.begin(), SMLoc::getFromPointer(Buffer.data())); - std::swap(DagNotMatches, CheckStrings->back().DagNotStrings); + std::swap(DagNotMatches, CheckStrings.back().DagNotStrings); } - if (CheckStrings->empty()) { + if (CheckStrings.empty()) { errs() << "error: no check strings found with prefix" << (Req.CheckPrefixes.size() > 1 ? "es " : " "); auto I = Req.CheckPrefixes.begin(); @@ -1272,7 +1266,7 @@ bool FileCheck::readCheckFile(SourceMgr &SM, StringRef Buffer, } static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, - StringRef Prefix, SMLoc Loc, const Pattern &Pat, + StringRef Prefix, SMLoc Loc, const FileCheckPattern &Pat, int MatchedCount, StringRef Buffer, size_t MatchPos, size_t MatchLen, const FileCheckRequest &Req, std::vector<FileCheckDiag> *Diags) { @@ -1318,10 +1312,10 @@ static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, } static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, - StringRef Prefix, SMLoc Loc, const Pattern &Pat, - int MatchedCount, StringRef Buffer, - bool VerboseVerbose, std::vector<FileCheckDiag> *Diags, - Error MatchErrors) { + StringRef Prefix, SMLoc Loc, + const FileCheckPattern &Pat, int MatchedCount, + StringRef Buffer, bool VerboseVerbose, + std::vector<FileCheckDiag> *Diags, Error MatchErrors) { assert(MatchErrors && "Called on successful match"); bool PrintDiag = true; if (!ExpectedMatch) { @@ -1347,8 +1341,9 @@ static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, return; } - MatchErrors = handleErrors(std::move(MatchErrors), - [](const ErrorDiagnostic &E) { E.log(errs()); }); + MatchErrors = + handleErrors(std::move(MatchErrors), + [](const FileCheckErrorDiagnostic &E) { E.log(errs()); }); // No problem matching the string per se. if (!MatchErrors) @@ -1412,7 +1407,7 @@ size_t FileCheckString::Check(const SourceMgr &SM, StringRef Buffer, FileCheckRequest &Req, std::vector<FileCheckDiag> *Diags) const { size_t LastPos = 0; - std::vector<const Pattern *> NotStrings; + std::vector<const FileCheckPattern *> NotStrings; // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL // bounds; we have not processed variable definitions within the bounded block @@ -1550,11 +1545,11 @@ bool FileCheckString::CheckSame(const SourceMgr &SM, StringRef Buffer) const { return false; } -bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer, - const std::vector<const Pattern *> &NotStrings, - const FileCheckRequest &Req, - std::vector<FileCheckDiag> *Diags) const { - for (const Pattern *Pat : NotStrings) { +bool FileCheckString::CheckNot( + const SourceMgr &SM, StringRef Buffer, + const std::vector<const FileCheckPattern *> &NotStrings, + const FileCheckRequest &Req, std::vector<FileCheckDiag> *Diags) const { + for (const FileCheckPattern *Pat : NotStrings) { assert((Pat->getCheckTy() == Check::CheckNot) && "Expect CHECK-NOT!"); size_t MatchLen = 0; @@ -1576,10 +1571,11 @@ bool FileCheckString::CheckNot(const SourceMgr &SM, StringRef Buffer, return false; } -size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, - std::vector<const Pattern *> &NotStrings, - const FileCheckRequest &Req, - std::vector<FileCheckDiag> *Diags) const { +size_t +FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, + std::vector<const FileCheckPattern *> &NotStrings, + const FileCheckRequest &Req, + std::vector<FileCheckDiag> *Diags) const { if (DagNotStrings.empty()) return 0; @@ -1599,7 +1595,7 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, // group, so we don't use a range-based for loop here. for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end(); PatItr != PatEnd; ++PatItr) { - const Pattern &Pat = *PatItr; + const FileCheckPattern &Pat = *PatItr; assert((Pat.getCheckTy() == Check::CheckDAG || Pat.getCheckTy() == Check::CheckNot) && "Invalid CHECK-DAG or CHECK-NOT!"); @@ -1708,7 +1704,7 @@ size_t FileCheckString::CheckDag(const SourceMgr &SM, StringRef Buffer, // A check prefix must contain only alphanumeric, hyphens and underscores. static bool ValidateCheckPrefix(StringRef CheckPrefix) { - static const Regex Validator("^[a-zA-Z0-9_-]*$"); + Regex Validator("^[a-zA-Z0-9_-]*$"); return Validator.match(CheckPrefix); } @@ -1763,32 +1759,11 @@ Error FileCheckPatternContext::defineCmdlineVariables( unsigned I = 0; Error Errs = Error::success(); std::string CmdlineDefsDiag; - SmallVector<std::pair<size_t, size_t>, 4> CmdlineDefsIndices; - for (StringRef CmdlineDef : CmdlineDefines) { - std::string DefPrefix = ("Global define #" + Twine(++I) + ": ").str(); - size_t EqIdx = CmdlineDef.find('='); - if (EqIdx == StringRef::npos) { - CmdlineDefsIndices.push_back(std::make_pair(CmdlineDefsDiag.size(), 0)); - continue; - } - // Numeric variable definition. - if (CmdlineDef[0] == '#') { - // Append a copy of the command-line definition adapted to use the same - // format as in the input file to be able to reuse - // parseNumericSubstitutionBlock. - CmdlineDefsDiag += (DefPrefix + CmdlineDef + " (parsed as: [[").str(); - std::string SubstitutionStr = CmdlineDef; - SubstitutionStr[EqIdx] = ':'; - CmdlineDefsIndices.push_back( - std::make_pair(CmdlineDefsDiag.size(), SubstitutionStr.size())); - CmdlineDefsDiag += (SubstitutionStr + Twine("]])\n")).str(); - } else { - CmdlineDefsDiag += DefPrefix; - CmdlineDefsIndices.push_back( - std::make_pair(CmdlineDefsDiag.size(), CmdlineDef.size())); - CmdlineDefsDiag += (CmdlineDef + "\n").str(); - } - } + StringRef Prefix1 = "Global define #"; + StringRef Prefix2 = ": "; + for (StringRef CmdlineDef : CmdlineDefines) + CmdlineDefsDiag += + (Prefix1 + Twine(++I) + Prefix2 + CmdlineDef + "\n").str(); // Create a buffer with fake command line content in order to display // parsing diagnostic with location information and point to the @@ -1798,55 +1773,55 @@ Error FileCheckPatternContext::defineCmdlineVariables( StringRef CmdlineDefsDiagRef = CmdLineDefsDiagBuffer->getBuffer(); SM.AddNewSourceBuffer(std::move(CmdLineDefsDiagBuffer), SMLoc()); - for (std::pair<size_t, size_t> CmdlineDefIndices : CmdlineDefsIndices) { - StringRef CmdlineDef = CmdlineDefsDiagRef.substr(CmdlineDefIndices.first, - CmdlineDefIndices.second); - if (CmdlineDef.empty()) { + SmallVector<StringRef, 4> CmdlineDefsDiagVec; + CmdlineDefsDiagRef.split(CmdlineDefsDiagVec, '\n', -1 /*MaxSplit*/, + false /*KeepEmpty*/); + for (StringRef CmdlineDefDiag : CmdlineDefsDiagVec) { + unsigned DefStart = CmdlineDefDiag.find(Prefix2) + Prefix2.size(); + StringRef CmdlineDef = CmdlineDefDiag.substr(DefStart); + size_t EqIdx = CmdlineDef.find('='); + if (EqIdx == StringRef::npos) { Errs = joinErrors( std::move(Errs), - ErrorDiagnostic::get(SM, CmdlineDef, - "missing equal sign in global definition")); + FileCheckErrorDiagnostic::get( + SM, CmdlineDef, "missing equal sign in global definition")); continue; } // Numeric variable definition. if (CmdlineDef[0] == '#') { - // Now parse the definition both to check that the syntax is correct and - // to create the necessary class instance. - StringRef CmdlineDefExpr = CmdlineDef.substr(1); - Optional<NumericVariable *> DefinedNumericVariable; - Expected<std::unique_ptr<ExpressionAST>> ExpressionASTResult = - Pattern::parseNumericSubstitutionBlock( - CmdlineDefExpr, DefinedNumericVariable, false, None, this, SM); - if (!ExpressionASTResult) { - Errs = joinErrors(std::move(Errs), ExpressionASTResult.takeError()); + StringRef CmdlineName = CmdlineDef.substr(1, EqIdx - 1); + Expected<FileCheckNumericVariable *> ParseResult = + FileCheckPattern::parseNumericVariableDefinition(CmdlineName, this, + None, SM); + if (!ParseResult) { + Errs = joinErrors(std::move(Errs), ParseResult.takeError()); continue; } - std::unique_ptr<ExpressionAST> ExpressionASTPointer = - std::move(*ExpressionASTResult); - // Now evaluate the expression whose value this variable should be set - // to, since the expression of a command-line variable definition should - // only use variables defined earlier on the command-line. If not, this - // is an error and we report it. - Expected<uint64_t> Value = ExpressionASTPointer->eval(); - if (!Value) { - Errs = joinErrors(std::move(Errs), Value.takeError()); + + StringRef CmdlineVal = CmdlineDef.substr(EqIdx + 1); + uint64_t Val; + if (CmdlineVal.getAsInteger(10, Val)) { + Errs = joinErrors(std::move(Errs), + FileCheckErrorDiagnostic::get( + SM, CmdlineVal, + "invalid value in numeric variable definition '" + + CmdlineVal + "'")); continue; } - - assert(DefinedNumericVariable && "No variable defined"); - (*DefinedNumericVariable)->setValue(*Value); + FileCheckNumericVariable *DefinedNumericVariable = *ParseResult; + DefinedNumericVariable->setValue(Val); // Record this variable definition. - GlobalNumericVariableTable[(*DefinedNumericVariable)->getName()] = - *DefinedNumericVariable; + GlobalNumericVariableTable[DefinedNumericVariable->getName()] = + DefinedNumericVariable; } else { // String variable definition. std::pair<StringRef, StringRef> CmdlineNameVal = CmdlineDef.split('='); StringRef CmdlineName = CmdlineNameVal.first; StringRef OrigCmdlineName = CmdlineName; - Expected<Pattern::VariableProperties> ParseVarResult = - Pattern::parseVariable(CmdlineName, SM); + Expected<FileCheckPattern::VariableProperties> ParseVarResult = + FileCheckPattern::parseVariable(CmdlineName, SM); if (!ParseVarResult) { Errs = joinErrors(std::move(Errs), ParseVarResult.takeError()); continue; @@ -1856,7 +1831,7 @@ Error FileCheckPatternContext::defineCmdlineVariables( // "FOO+2" in a "FOO+2=10" definition. if (ParseVarResult->IsPseudo || !CmdlineName.empty()) { Errs = joinErrors(std::move(Errs), - ErrorDiagnostic::get( + FileCheckErrorDiagnostic::get( SM, OrigCmdlineName, "invalid name in string variable definition '" + OrigCmdlineName + "'")); @@ -1868,15 +1843,15 @@ Error FileCheckPatternContext::defineCmdlineVariables( // is created later than the latter. if (GlobalNumericVariableTable.find(Name) != GlobalNumericVariableTable.end()) { - Errs = joinErrors(std::move(Errs), - ErrorDiagnostic::get(SM, Name, + Errs = joinErrors(std::move(Errs), FileCheckErrorDiagnostic::get( + SM, Name, "numeric variable with name '" + Name + "' already exists")); continue; } GlobalVariableTable.insert(CmdlineNameVal); // Mark the string variable as defined to detect collisions between - // string and numeric variables in defineCmdlineVariables when the latter + // string and numeric variables in DefineCmdlineVariables when the latter // is created later than the former. We cannot reuse GlobalVariableTable // for this by populating it with an empty string since we would then // lose the ability to detect the use of an undefined variable in @@ -1912,17 +1887,18 @@ void FileCheckPatternContext::clearLocalVars() { GlobalNumericVariableTable.erase(Var); } -bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer, +bool FileCheck::CheckInput(SourceMgr &SM, StringRef Buffer, + ArrayRef<FileCheckString> CheckStrings, std::vector<FileCheckDiag> *Diags) { bool ChecksFailed = false; - unsigned i = 0, j = 0, e = CheckStrings->size(); + unsigned i = 0, j = 0, e = CheckStrings.size(); while (true) { StringRef CheckRegion; if (j == e) { CheckRegion = Buffer; } else { - const FileCheckString &CheckLabelStr = (*CheckStrings)[j]; + const FileCheckString &CheckLabelStr = CheckStrings[j]; if (CheckLabelStr.Pat.getCheckTy() != Check::CheckLabel) { ++j; continue; @@ -1945,10 +1921,10 @@ bool FileCheck::checkInput(SourceMgr &SM, StringRef Buffer, // CHECK-LABEL and it would clear variables defined on the command-line // before they get used. if (i != 0 && Req.EnableVarScope) - PatternContext->clearLocalVars(); + PatternContext.clearLocalVars(); for (; i != j; ++i) { - const FileCheckString &CheckStr = (*CheckStrings)[i]; + const FileCheckString &CheckStr = CheckStrings[i]; // Check each string within the scanned region, including a second check // of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG) diff --git a/contrib/llvm-project/llvm/lib/Support/FileCheckImpl.h b/contrib/llvm-project/llvm/lib/Support/FileCheckImpl.h deleted file mode 100644 index dc07d22aefd8..000000000000 --- a/contrib/llvm-project/llvm/lib/Support/FileCheckImpl.h +++ /dev/null @@ -1,613 +0,0 @@ -//===-- FileCheckImpl.h - Private FileCheck Interface ------------*- C++ -*-==// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// -// -// This file defines the private interfaces of FileCheck. Its purpose is to -// allow unit testing of FileCheck and to separate the interface from the -// implementation. It is only meant to be used by FileCheck. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_LIB_SUPPORT_FILECHECKIMPL_H -#define LLVM_LIB_SUPPORT_FILECHECKIMPL_H - -#include "llvm/ADT/Optional.h" -#include "llvm/ADT/StringMap.h" -#include "llvm/ADT/StringRef.h" -#include "llvm/Support/Error.h" -#include "llvm/Support/SourceMgr.h" -#include <map> -#include <string> -#include <vector> - -namespace llvm { - -//===----------------------------------------------------------------------===// -// Numeric substitution handling code. -//===----------------------------------------------------------------------===// - -/// Base class representing the AST of a given expression. -class ExpressionAST { -public: - virtual ~ExpressionAST() = default; - - /// Evaluates and \returns the value of the expression represented by this - /// AST or an error if evaluation fails. - virtual Expected<uint64_t> eval() const = 0; -}; - -/// Class representing an unsigned literal in the AST of an expression. -class ExpressionLiteral : public ExpressionAST { -private: - /// Actual value of the literal. - uint64_t Value; - -public: - /// Constructs a literal with the specified value. - ExpressionLiteral(uint64_t Val) : Value(Val) {} - - /// \returns the literal's value. - Expected<uint64_t> eval() const override { return Value; } -}; - -/// Class to represent an undefined variable error, which quotes that -/// variable's name when printed. -class UndefVarError : public ErrorInfo<UndefVarError> { -private: - StringRef VarName; - -public: - static char ID; - - UndefVarError(StringRef VarName) : VarName(VarName) {} - - StringRef getVarName() const { return VarName; } - - std::error_code convertToErrorCode() const override { - return inconvertibleErrorCode(); - } - - /// Print name of variable associated with this error. - void log(raw_ostream &OS) const override { - OS << "\""; - OS.write_escaped(VarName) << "\""; - } -}; - -/// Class representing a numeric variable and its associated current value. -class NumericVariable { -private: - /// Name of the numeric variable. - StringRef Name; - - /// Value of numeric variable, if defined, or None otherwise. - Optional<uint64_t> Value; - - /// Line number where this variable is defined, or None if defined before - /// input is parsed. Used to determine whether a variable is defined on the - /// same line as a given use. - Optional<size_t> DefLineNumber; - -public: - /// Constructor for a variable \p Name defined at line \p DefLineNumber or - /// defined before input is parsed if \p DefLineNumber is None. - explicit NumericVariable(StringRef Name, - Optional<size_t> DefLineNumber = None) - : Name(Name), DefLineNumber(DefLineNumber) {} - - /// \returns name of this numeric variable. - StringRef getName() const { return Name; } - - /// \returns this variable's value. - Optional<uint64_t> getValue() const { return Value; } - - /// Sets value of this numeric variable to \p NewValue. - void setValue(uint64_t NewValue) { Value = NewValue; } - - /// Clears value of this numeric variable, regardless of whether it is - /// currently defined or not. - void clearValue() { Value = None; } - - /// \returns the line number where this variable is defined, if any, or None - /// if defined before input is parsed. - Optional<size_t> getDefLineNumber() const { return DefLineNumber; } -}; - -/// Class representing the use of a numeric variable in the AST of an -/// expression. -class NumericVariableUse : public ExpressionAST { -private: - /// Name of the numeric variable. - StringRef Name; - - /// Pointer to the class instance for the variable this use is about. - NumericVariable *Variable; - -public: - NumericVariableUse(StringRef Name, NumericVariable *Variable) - : Name(Name), Variable(Variable) {} - - /// \returns the value of the variable referenced by this instance. - Expected<uint64_t> eval() const override; -}; - -/// Type of functions evaluating a given binary operation. -using binop_eval_t = uint64_t (*)(uint64_t, uint64_t); - -/// Class representing a single binary operation in the AST of an expression. -class BinaryOperation : public ExpressionAST { -private: - /// Left operand. - std::unique_ptr<ExpressionAST> LeftOperand; - - /// Right operand. - std::unique_ptr<ExpressionAST> RightOperand; - - /// Pointer to function that can evaluate this binary operation. - binop_eval_t EvalBinop; - -public: - BinaryOperation(binop_eval_t EvalBinop, std::unique_ptr<ExpressionAST> LeftOp, - std::unique_ptr<ExpressionAST> RightOp) - : EvalBinop(EvalBinop) { - LeftOperand = std::move(LeftOp); - RightOperand = std::move(RightOp); - } - - /// Evaluates the value of the binary operation represented by this AST, - /// using EvalBinop on the result of recursively evaluating the operands. - /// \returns the expression value or an error if an undefined numeric - /// variable is used in one of the operands. - Expected<uint64_t> eval() const override; -}; - -class FileCheckPatternContext; - -/// Class representing a substitution to perform in the RegExStr string. -class Substitution { -protected: - /// Pointer to a class instance holding, among other things, the table with - /// the values of live string variables at the start of any given CHECK line. - /// Used for substituting string variables with the text they were defined - /// as. Expressions are linked to the numeric variables they use at - /// parse time and directly access the value of the numeric variable to - /// evaluate their value. - FileCheckPatternContext *Context; - - /// The string that needs to be substituted for something else. For a - /// string variable this is its name, otherwise this is the whole expression. - StringRef FromStr; - - // Index in RegExStr of where to do the substitution. - size_t InsertIdx; - -public: - Substitution(FileCheckPatternContext *Context, StringRef VarName, - size_t InsertIdx) - : Context(Context), FromStr(VarName), InsertIdx(InsertIdx) {} - - virtual ~Substitution() = default; - - /// \returns the string to be substituted for something else. - StringRef getFromString() const { return FromStr; } - - /// \returns the index where the substitution is to be performed in RegExStr. - size_t getIndex() const { return InsertIdx; } - - /// \returns a string containing the result of the substitution represented - /// by this class instance or an error if substitution failed. - virtual Expected<std::string> getResult() const = 0; -}; - -class StringSubstitution : public Substitution { -public: - StringSubstitution(FileCheckPatternContext *Context, StringRef VarName, - size_t InsertIdx) - : Substitution(Context, VarName, InsertIdx) {} - - /// \returns the text that the string variable in this substitution matched - /// when defined, or an error if the variable is undefined. - Expected<std::string> getResult() const override; -}; - -class NumericSubstitution : public Substitution { -private: - /// Pointer to the class representing the expression whose value is to be - /// substituted. - std::unique_ptr<ExpressionAST> ExpressionASTPointer; - -public: - NumericSubstitution(FileCheckPatternContext *Context, StringRef Expr, - std::unique_ptr<ExpressionAST> ExprAST, size_t InsertIdx) - : Substitution(Context, Expr, InsertIdx) { - ExpressionASTPointer = std::move(ExprAST); - } - - /// \returns a string containing the result of evaluating the expression in - /// this substitution, or an error if evaluation failed. - Expected<std::string> getResult() const override; -}; - -//===----------------------------------------------------------------------===// -// Pattern handling code. -//===----------------------------------------------------------------------===// - -struct FileCheckDiag; - -/// Class holding the Pattern global state, shared by all patterns: tables -/// holding values of variables and whether they are defined or not at any -/// given time in the matching process. -class FileCheckPatternContext { - friend class Pattern; - -private: - /// When matching a given pattern, this holds the value of all the string - /// variables defined in previous patterns. In a pattern, only the last - /// definition for a given variable is recorded in this table. - /// Back-references are used for uses after any the other definition. - StringMap<StringRef> GlobalVariableTable; - - /// Map of all string variables defined so far. Used at parse time to detect - /// a name conflict between a numeric variable and a string variable when - /// the former is defined on a later line than the latter. - StringMap<bool> DefinedVariableTable; - - /// When matching a given pattern, this holds the pointers to the classes - /// representing the numeric variables defined in previous patterns. When - /// matching a pattern all definitions for that pattern are recorded in the - /// NumericVariableDefs table in the Pattern instance of that pattern. - StringMap<NumericVariable *> GlobalNumericVariableTable; - - /// Pointer to the class instance representing the @LINE pseudo variable for - /// easily updating its value. - NumericVariable *LineVariable = nullptr; - - /// Vector holding pointers to all parsed numeric variables. Used to - /// automatically free them once they are guaranteed to no longer be used. - std::vector<std::unique_ptr<NumericVariable>> NumericVariables; - - /// Vector holding pointers to all substitutions. Used to automatically free - /// them once they are guaranteed to no longer be used. - std::vector<std::unique_ptr<Substitution>> Substitutions; - -public: - /// \returns the value of string variable \p VarName or an error if no such - /// variable has been defined. - Expected<StringRef> getPatternVarValue(StringRef VarName); - - /// Defines string and numeric variables from definitions given on the - /// command line, passed as a vector of [#]VAR=VAL strings in - /// \p CmdlineDefines. \returns an error list containing diagnostics against - /// \p SM for all definition parsing failures, if any, or Success otherwise. - Error defineCmdlineVariables(std::vector<std::string> &CmdlineDefines, - SourceMgr &SM); - - /// Create @LINE pseudo variable. Value is set when pattern are being - /// matched. - void createLineVariable(); - - /// Undefines local variables (variables whose name does not start with a '$' - /// sign), i.e. removes them from GlobalVariableTable and from - /// GlobalNumericVariableTable and also clears the value of numeric - /// variables. - void clearLocalVars(); - -private: - /// Makes a new numeric variable and registers it for destruction when the - /// context is destroyed. - template <class... Types> NumericVariable *makeNumericVariable(Types... args); - - /// Makes a new string substitution and registers it for destruction when the - /// context is destroyed. - Substitution *makeStringSubstitution(StringRef VarName, size_t InsertIdx); - - /// Makes a new numeric substitution and registers it for destruction when - /// the context is destroyed. - Substitution * - makeNumericSubstitution(StringRef ExpressionStr, - std::unique_ptr<ExpressionAST> ExpressionAST, - size_t InsertIdx); -}; - -/// Class to represent an error holding a diagnostic with location information -/// used when printing it. -class ErrorDiagnostic : public ErrorInfo<ErrorDiagnostic> { -private: - SMDiagnostic Diagnostic; - -public: - static char ID; - - ErrorDiagnostic(SMDiagnostic &&Diag) : Diagnostic(Diag) {} - - std::error_code convertToErrorCode() const override { - return inconvertibleErrorCode(); - } - - /// Print diagnostic associated with this error when printing the error. - void log(raw_ostream &OS) const override { Diagnostic.print(nullptr, OS); } - - static Error get(const SourceMgr &SM, SMLoc Loc, const Twine &ErrMsg) { - return make_error<ErrorDiagnostic>( - SM.GetMessage(Loc, SourceMgr::DK_Error, ErrMsg)); - } - - static Error get(const SourceMgr &SM, StringRef Buffer, const Twine &ErrMsg) { - return get(SM, SMLoc::getFromPointer(Buffer.data()), ErrMsg); - } -}; - -class NotFoundError : public ErrorInfo<NotFoundError> { -public: - static char ID; - - std::error_code convertToErrorCode() const override { - return inconvertibleErrorCode(); - } - - /// Print diagnostic associated with this error when printing the error. - void log(raw_ostream &OS) const override { - OS << "String not found in input"; - } -}; - -class Pattern { - SMLoc PatternLoc; - - /// A fixed string to match as the pattern or empty if this pattern requires - /// a regex match. - StringRef FixedStr; - - /// A regex string to match as the pattern or empty if this pattern requires - /// a fixed string to match. - std::string RegExStr; - - /// Entries in this vector represent a substitution of a string variable or - /// an expression in the RegExStr regex at match time. For example, in the - /// case of a CHECK directive with the pattern "foo[[bar]]baz[[#N+1]]", - /// RegExStr will contain "foobaz" and we'll get two entries in this vector - /// that tells us to insert the value of string variable "bar" at offset 3 - /// and the value of expression "N+1" at offset 6. - std::vector<Substitution *> Substitutions; - - /// Maps names of string variables defined in a pattern to the number of - /// their parenthesis group in RegExStr capturing their last definition. - /// - /// E.g. for the pattern "foo[[bar:.*]]baz([[bar]][[QUUX]][[bar:.*]])", - /// RegExStr will be "foo(.*)baz(\1<quux value>(.*))" where <quux value> is - /// the value captured for QUUX on the earlier line where it was defined, and - /// VariableDefs will map "bar" to the third parenthesis group which captures - /// the second definition of "bar". - /// - /// Note: uses std::map rather than StringMap to be able to get the key when - /// iterating over values. - std::map<StringRef, unsigned> VariableDefs; - - /// Structure representing the definition of a numeric variable in a pattern. - /// It holds the pointer to the class representing the numeric variable whose - /// value is being defined and the number of the parenthesis group in - /// RegExStr to capture that value. - struct NumericVariableMatch { - /// Pointer to class representing the numeric variable whose value is being - /// defined. - NumericVariable *DefinedNumericVariable; - - /// Number of the parenthesis group in RegExStr that captures the value of - /// this numeric variable definition. - unsigned CaptureParenGroup; - }; - - /// Holds the number of the parenthesis group in RegExStr and pointer to the - /// corresponding NumericVariable class instance of all numeric variable - /// definitions. Used to set the matched value of all those variables. - StringMap<NumericVariableMatch> NumericVariableDefs; - - /// Pointer to a class instance holding the global state shared by all - /// patterns: - /// - separate tables with the values of live string and numeric variables - /// respectively at the start of any given CHECK line; - /// - table holding whether a string variable has been defined at any given - /// point during the parsing phase. - FileCheckPatternContext *Context; - - Check::FileCheckType CheckTy; - - /// Line number for this CHECK pattern or None if it is an implicit pattern. - /// Used to determine whether a variable definition is made on an earlier - /// line to the one with this CHECK. - Optional<size_t> LineNumber; - - /// Ignore case while matching if set to true. - bool IgnoreCase = false; - -public: - Pattern(Check::FileCheckType Ty, FileCheckPatternContext *Context, - Optional<size_t> Line = None) - : Context(Context), CheckTy(Ty), LineNumber(Line) {} - - /// \returns the location in source code. - SMLoc getLoc() const { return PatternLoc; } - - /// \returns the pointer to the global state for all patterns in this - /// FileCheck instance. - FileCheckPatternContext *getContext() const { return Context; } - - /// \returns whether \p C is a valid first character for a variable name. - static bool isValidVarNameStart(char C); - - /// Parsing information about a variable. - struct VariableProperties { - StringRef Name; - bool IsPseudo; - }; - - /// Parses the string at the start of \p Str for a variable name. \returns - /// a VariableProperties structure holding the variable name and whether it - /// is the name of a pseudo variable, or an error holding a diagnostic - /// against \p SM if parsing fail. If parsing was successful, also strips - /// \p Str from the variable name. - static Expected<VariableProperties> parseVariable(StringRef &Str, - const SourceMgr &SM); - /// Parses \p Expr for a numeric substitution block at line \p LineNumber, - /// or before input is parsed if \p LineNumber is None. Parameter - /// \p IsLegacyLineExpr indicates whether \p Expr should be a legacy @LINE - /// expression and \p Context points to the class instance holding the live - /// string and numeric variables. \returns a pointer to the class instance - /// representing the AST of the expression whose value must be substitued, or - /// an error holding a diagnostic against \p SM if parsing fails. If - /// substitution was successful, sets \p DefinedNumericVariable to point to - /// the class representing the numeric variable defined in this numeric - /// substitution block, or None if this block does not define any variable. - static Expected<std::unique_ptr<ExpressionAST>> parseNumericSubstitutionBlock( - StringRef Expr, Optional<NumericVariable *> &DefinedNumericVariable, - bool IsLegacyLineExpr, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM); - /// Parses the pattern in \p PatternStr and initializes this Pattern instance - /// accordingly. - /// - /// \p Prefix provides which prefix is being matched, \p Req describes the - /// global options that influence the parsing such as whitespace - /// canonicalization, \p SM provides the SourceMgr used for error reports. - /// \returns true in case of an error, false otherwise. - bool parsePattern(StringRef PatternStr, StringRef Prefix, SourceMgr &SM, - const FileCheckRequest &Req); - /// Matches the pattern string against the input buffer \p Buffer - /// - /// \returns the position that is matched or an error indicating why matching - /// failed. If there is a match, updates \p MatchLen with the size of the - /// matched string. - /// - /// The GlobalVariableTable StringMap in the FileCheckPatternContext class - /// instance provides the current values of FileCheck string variables and is - /// updated if this match defines new values. Likewise, the - /// GlobalNumericVariableTable StringMap in the same class provides the - /// current values of FileCheck numeric variables and is updated if this - /// match defines new numeric values. - Expected<size_t> match(StringRef Buffer, size_t &MatchLen, - const SourceMgr &SM) const; - /// Prints the value of successful substitutions or the name of the undefined - /// string or numeric variables preventing a successful substitution. - void printSubstitutions(const SourceMgr &SM, StringRef Buffer, - SMRange MatchRange = None) const; - void printFuzzyMatch(const SourceMgr &SM, StringRef Buffer, - std::vector<FileCheckDiag> *Diags) const; - - bool hasVariable() const { - return !(Substitutions.empty() && VariableDefs.empty()); - } - - Check::FileCheckType getCheckTy() const { return CheckTy; } - - int getCount() const { return CheckTy.getCount(); } - -private: - bool AddRegExToRegEx(StringRef RS, unsigned &CurParen, SourceMgr &SM); - void AddBackrefToRegEx(unsigned BackrefNum); - /// Computes an arbitrary estimate for the quality of matching this pattern - /// at the start of \p Buffer; a distance of zero should correspond to a - /// perfect match. - unsigned computeMatchDistance(StringRef Buffer) const; - /// Finds the closing sequence of a regex variable usage or definition. - /// - /// \p Str has to point in the beginning of the definition (right after the - /// opening sequence). \p SM holds the SourceMgr used for error reporting. - /// \returns the offset of the closing sequence within Str, or npos if it - /// was not found. - static size_t FindRegexVarEnd(StringRef Str, SourceMgr &SM); - - /// Parses \p Expr for the name of a numeric variable to be defined at line - /// \p LineNumber, or before input is parsed if \p LineNumber is None. - /// \returns a pointer to the class instance representing that variable, - /// creating it if needed, or an error holding a diagnostic against \p SM - /// should defining such a variable be invalid. - static Expected<NumericVariable *> parseNumericVariableDefinition( - StringRef &Expr, FileCheckPatternContext *Context, - Optional<size_t> LineNumber, const SourceMgr &SM); - /// Parses \p Name as a (pseudo if \p IsPseudo is true) numeric variable use - /// at line \p LineNumber, or before input is parsed if \p LineNumber is - /// None. Parameter \p Context points to the class instance holding the live - /// string and numeric variables. \returns the pointer to the class instance - /// representing that variable if successful, or an error holding a - /// diagnostic against \p SM otherwise. - static Expected<std::unique_ptr<NumericVariableUse>> parseNumericVariableUse( - StringRef Name, bool IsPseudo, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM); - enum class AllowedOperand { LineVar, Literal, Any }; - /// Parses \p Expr for use of a numeric operand at line \p LineNumber, or - /// before input is parsed if \p LineNumber is None. Accepts both literal - /// values and numeric variables, depending on the value of \p AO. Parameter - /// \p Context points to the class instance holding the live string and - /// numeric variables. \returns the class representing that operand in the - /// AST of the expression or an error holding a diagnostic against \p SM - /// otherwise. - static Expected<std::unique_ptr<ExpressionAST>> - parseNumericOperand(StringRef &Expr, AllowedOperand AO, - Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM); - /// Parses \p Expr for a binary operation at line \p LineNumber, or before - /// input is parsed if \p LineNumber is None. The left operand of this binary - /// operation is given in \p LeftOp and \p IsLegacyLineExpr indicates whether - /// we are parsing a legacy @LINE expression. Parameter \p Context points to - /// the class instance holding the live string and numeric variables. - /// \returns the class representing the binary operation in the AST of the - /// expression, or an error holding a diagnostic against \p SM otherwise. - static Expected<std::unique_ptr<ExpressionAST>> - parseBinop(StringRef &Expr, std::unique_ptr<ExpressionAST> LeftOp, - bool IsLegacyLineExpr, Optional<size_t> LineNumber, - FileCheckPatternContext *Context, const SourceMgr &SM); -}; - -//===----------------------------------------------------------------------===// -// Check Strings. -//===----------------------------------------------------------------------===// - -/// A check that we found in the input file. -struct FileCheckString { - /// The pattern to match. - Pattern Pat; - - /// Which prefix name this check matched. - StringRef Prefix; - - /// The location in the match file that the check string was specified. - SMLoc Loc; - - /// All of the strings that are disallowed from occurring between this match - /// string and the previous one (or start of file). - std::vector<Pattern> DagNotStrings; - - FileCheckString(const Pattern &P, StringRef S, SMLoc L) - : Pat(P), Prefix(S), Loc(L) {} - - /// Matches check string and its "not strings" and/or "dag strings". - size_t Check(const SourceMgr &SM, StringRef Buffer, bool IsLabelScanMode, - size_t &MatchLen, FileCheckRequest &Req, - std::vector<FileCheckDiag> *Diags) const; - - /// Verifies that there is a single line in the given \p Buffer. Errors are - /// reported against \p SM. - bool CheckNext(const SourceMgr &SM, StringRef Buffer) const; - /// Verifies that there is no newline in the given \p Buffer. Errors are - /// reported against \p SM. - bool CheckSame(const SourceMgr &SM, StringRef Buffer) const; - /// Verifies that none of the strings in \p NotStrings are found in the given - /// \p Buffer. Errors are reported against \p SM and diagnostics recorded in - /// \p Diags according to the verbosity level set in \p Req. - bool CheckNot(const SourceMgr &SM, StringRef Buffer, - const std::vector<const Pattern *> &NotStrings, - const FileCheckRequest &Req, - std::vector<FileCheckDiag> *Diags) const; - /// Matches "dag strings" and their mixed "not strings". - size_t CheckDag(const SourceMgr &SM, StringRef Buffer, - std::vector<const Pattern *> &NotStrings, - const FileCheckRequest &Req, - std::vector<FileCheckDiag> *Diags) const; -}; - -} // namespace llvm - -#endif diff --git a/contrib/llvm-project/llvm/lib/Support/FileCollector.cpp b/contrib/llvm-project/llvm/lib/Support/FileCollector.cpp deleted file mode 100644 index 47fca6413722..000000000000 --- a/contrib/llvm-project/llvm/lib/Support/FileCollector.cpp +++ /dev/null @@ -1,268 +0,0 @@ -//===-- FileCollector.cpp ---------------------------------------*- C++ -*-===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "llvm/Support/FileCollector.h" -#include "llvm/ADT/SmallString.h" -#include "llvm/Support/FileSystem.h" -#include "llvm/Support/Path.h" -#include "llvm/Support/Process.h" - -using namespace llvm; - -static bool isCaseSensitivePath(StringRef Path) { - SmallString<256> TmpDest = Path, UpperDest, RealDest; - - // Remove component traversals, links, etc. - if (!sys::fs::real_path(Path, TmpDest)) - return true; // Current default value in vfs.yaml - Path = TmpDest; - - // Change path to all upper case and ask for its real path, if the latter - // exists and is equal to path, it's not case sensitive. Default to case - // sensitive in the absence of real_path, since this is the YAMLVFSWriter - // default. - UpperDest = Path.upper(); - if (sys::fs::real_path(UpperDest, RealDest) && Path.equals(RealDest)) - return false; - return true; -} - -FileCollector::FileCollector(std::string Root, std::string OverlayRoot) - : Root(std::move(Root)), OverlayRoot(std::move(OverlayRoot)) { - sys::fs::create_directories(this->Root, true); -} - -bool FileCollector::getRealPath(StringRef SrcPath, - SmallVectorImpl<char> &Result) { - SmallString<256> RealPath; - StringRef FileName = sys::path::filename(SrcPath); - std::string Directory = sys::path::parent_path(SrcPath).str(); - auto DirWithSymlink = SymlinkMap.find(Directory); - - // Use real_path to fix any symbolic link component present in a path. - // Computing the real path is expensive, cache the search through the parent - // path Directory. - if (DirWithSymlink == SymlinkMap.end()) { - auto EC = sys::fs::real_path(Directory, RealPath); - if (EC) - return false; - SymlinkMap[Directory] = RealPath.str(); - } else { - RealPath = DirWithSymlink->second; - } - - sys::path::append(RealPath, FileName); - Result.swap(RealPath); - return true; -} - -void FileCollector::addFile(const Twine &file) { - std::lock_guard<std::mutex> lock(Mutex); - std::string FileStr = file.str(); - if (markAsSeen(FileStr)) - addFileImpl(FileStr); -} - -void FileCollector::addFileImpl(StringRef SrcPath) { - // We need an absolute src path to append to the root. - SmallString<256> AbsoluteSrc = SrcPath; - sys::fs::make_absolute(AbsoluteSrc); - - // Canonicalize src to a native path to avoid mixed separator styles. - sys::path::native(AbsoluteSrc); - - // Remove redundant leading "./" pieces and consecutive separators. - AbsoluteSrc = sys::path::remove_leading_dotslash(AbsoluteSrc); - - // Canonicalize the source path by removing "..", "." components. - SmallString<256> VirtualPath = AbsoluteSrc; - sys::path::remove_dots(VirtualPath, /*remove_dot_dot=*/true); - - // If a ".." component is present after a symlink component, remove_dots may - // lead to the wrong real destination path. Let the source be canonicalized - // like that but make sure we always use the real path for the destination. - SmallString<256> CopyFrom; - if (!getRealPath(AbsoluteSrc, CopyFrom)) - CopyFrom = VirtualPath; - - SmallString<256> DstPath = StringRef(Root); - sys::path::append(DstPath, sys::path::relative_path(CopyFrom)); - - // Always map a canonical src path to its real path into the YAML, by doing - // this we map different virtual src paths to the same entry in the VFS - // overlay, which is a way to emulate symlink inside the VFS; this is also - // needed for correctness, not doing that can lead to module redefinition - // errors. - addFileToMapping(VirtualPath, DstPath); -} - -/// Set the access and modification time for the given file from the given -/// status object. -static std::error_code -copyAccessAndModificationTime(StringRef Filename, - const sys::fs::file_status &Stat) { - int FD; - - if (auto EC = - sys::fs::openFileForWrite(Filename, FD, sys::fs::CD_OpenExisting)) - return EC; - - if (auto EC = sys::fs::setLastAccessAndModificationTime( - FD, Stat.getLastAccessedTime(), Stat.getLastModificationTime())) - return EC; - - if (auto EC = sys::Process::SafelyCloseFileDescriptor(FD)) - return EC; - - return {}; -} - -std::error_code FileCollector::copyFiles(bool StopOnError) { - for (auto &entry : VFSWriter.getMappings()) { - // Create directory tree. - if (std::error_code EC = - sys::fs::create_directories(sys::path::parent_path(entry.RPath), - /*IgnoreExisting=*/true)) { - if (StopOnError) - return EC; - } - - // Get the status of the original file/directory. - sys::fs::file_status Stat; - if (std::error_code EC = sys::fs::status(entry.VPath, Stat)) { - if (StopOnError) - return EC; - continue; - } - - if (Stat.type() == sys::fs::file_type::directory_file) { - // Construct a directory when it's just a directory entry. - if (std::error_code EC = - sys::fs::create_directories(entry.RPath, - /*IgnoreExisting=*/true)) { - if (StopOnError) - return EC; - } - continue; - } - - // Copy file over. - if (std::error_code EC = sys::fs::copy_file(entry.VPath, entry.RPath)) { - if (StopOnError) - return EC; - } - - // Copy over permissions. - if (auto perms = sys::fs::getPermissions(entry.VPath)) { - if (std::error_code EC = sys::fs::setPermissions(entry.RPath, *perms)) { - if (StopOnError) - return EC; - } - } - - // Copy over modification time. - copyAccessAndModificationTime(entry.RPath, Stat); - } - return {}; -} - -std::error_code FileCollector::writeMapping(StringRef mapping_file) { - std::lock_guard<std::mutex> lock(Mutex); - - VFSWriter.setOverlayDir(OverlayRoot); - VFSWriter.setCaseSensitivity(isCaseSensitivePath(OverlayRoot)); - VFSWriter.setUseExternalNames(false); - - std::error_code EC; - raw_fd_ostream os(mapping_file, EC, sys::fs::OF_Text); - if (EC) - return EC; - - VFSWriter.write(os); - - return {}; -} - -namespace { - -class FileCollectorFileSystem : public vfs::FileSystem { -public: - explicit FileCollectorFileSystem(IntrusiveRefCntPtr<vfs::FileSystem> FS, - std::shared_ptr<FileCollector> Collector) - : FS(std::move(FS)), Collector(std::move(Collector)) {} - - llvm::ErrorOr<llvm::vfs::Status> status(const Twine &Path) override { - auto Result = FS->status(Path); - if (Result && Result->exists()) - Collector->addFile(Path); - return Result; - } - - llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>> - openFileForRead(const Twine &Path) override { - auto Result = FS->openFileForRead(Path); - if (Result && *Result) - Collector->addFile(Path); - return Result; - } - - llvm::vfs::directory_iterator dir_begin(const llvm::Twine &Dir, - std::error_code &EC) override { - auto It = FS->dir_begin(Dir, EC); - if (EC) - return It; - // Collect everything that's listed in case the user needs it. - Collector->addFile(Dir); - for (; !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) { - if (It->type() == sys::fs::file_type::regular_file || - It->type() == sys::fs::file_type::directory_file || - It->type() == sys::fs::file_type::symlink_file) { - Collector->addFile(It->path()); - } - } - if (EC) - return It; - // Return a new iterator. - return FS->dir_begin(Dir, EC); - } - - std::error_code getRealPath(const Twine &Path, - SmallVectorImpl<char> &Output) const override { - auto EC = FS->getRealPath(Path, Output); - if (!EC) { - Collector->addFile(Path); - if (Output.size() > 0) - Collector->addFile(Output); - } - return EC; - } - - std::error_code isLocal(const Twine &Path, bool &Result) override { - return FS->isLocal(Path, Result); - } - - llvm::ErrorOr<std::string> getCurrentWorkingDirectory() const override { - return FS->getCurrentWorkingDirectory(); - } - - std::error_code setCurrentWorkingDirectory(const llvm::Twine &Path) override { - return FS->setCurrentWorkingDirectory(Path); - } - -private: - IntrusiveRefCntPtr<vfs::FileSystem> FS; - std::shared_ptr<FileCollector> Collector; -}; - -} // end anonymous namespace - -IntrusiveRefCntPtr<vfs::FileSystem> -FileCollector::createCollectorVFS(IntrusiveRefCntPtr<vfs::FileSystem> BaseFS, - std::shared_ptr<FileCollector> Collector) { - return new FileCollectorFileSystem(std::move(BaseFS), std::move(Collector)); -} diff --git a/contrib/llvm-project/llvm/lib/Support/FileOutputBuffer.cpp b/contrib/llvm-project/llvm/lib/Support/FileOutputBuffer.cpp index 0a5306f684d4..3d6b569f2993 100644 --- a/contrib/llvm-project/llvm/lib/Support/FileOutputBuffer.cpp +++ b/contrib/llvm-project/llvm/lib/Support/FileOutputBuffer.cpp @@ -121,7 +121,7 @@ createInMemoryBuffer(StringRef Path, size_t Size, unsigned Mode) { Size, nullptr, sys::Memory::MF_READ | sys::Memory::MF_WRITE, EC); if (EC) return errorCodeToError(EC); - return std::make_unique<InMemoryBuffer>(Path, MB, Size, Mode); + return llvm::make_unique<InMemoryBuffer>(Path, MB, Size, Mode); } static Expected<std::unique_ptr<FileOutputBuffer>> @@ -146,7 +146,7 @@ createOnDiskBuffer(StringRef Path, size_t Size, unsigned Mode) { // Mmap it. std::error_code EC; - auto MappedFile = std::make_unique<fs::mapped_file_region>( + auto MappedFile = llvm::make_unique<fs::mapped_file_region>( fs::convertFDToNativeFile(File.FD), fs::mapped_file_region::readwrite, Size, 0, EC); @@ -157,7 +157,7 @@ createOnDiskBuffer(StringRef Path, size_t Size, unsigned Mode) { return createInMemoryBuffer(Path, Size, Mode); } - return std::make_unique<OnDiskBuffer>(Path, std::move(File), + return llvm::make_unique<OnDiskBuffer>(Path, std::move(File), std::move(MappedFile)); } @@ -189,10 +189,7 @@ FileOutputBuffer::create(StringRef Path, size_t Size, unsigned Flags) { case fs::file_type::regular_file: case fs::file_type::file_not_found: case fs::file_type::status_error: - if (Flags & F_no_mmap) - return createInMemoryBuffer(Path, Size, Mode); - else - return createOnDiskBuffer(Path, Size, Mode); + return createOnDiskBuffer(Path, Size, Mode); default: return createInMemoryBuffer(Path, Size, Mode); } diff --git a/contrib/llvm-project/llvm/lib/Support/FileUtilities.cpp b/contrib/llvm-project/llvm/lib/Support/FileUtilities.cpp index d11fbb54dc0d..62eb7bfda195 100644 --- a/contrib/llvm-project/llvm/lib/Support/FileUtilities.cpp +++ b/contrib/llvm-project/llvm/lib/Support/FileUtilities.cpp @@ -12,12 +12,9 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/FileUtilities.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" -#include "llvm/Support/Error.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include <cctype> #include <cmath> @@ -267,66 +264,3 @@ int llvm::DiffFilesWithTolerance(StringRef NameA, return CompareFailed; } - -void llvm::AtomicFileWriteError::log(raw_ostream &OS) const { - OS << "atomic_write_error: "; - switch (Error) { - case atomic_write_error::failed_to_create_uniq_file: - OS << "failed_to_create_uniq_file"; - return; - case atomic_write_error::output_stream_error: - OS << "output_stream_error"; - return; - case atomic_write_error::failed_to_rename_temp_file: - OS << "failed_to_rename_temp_file"; - return; - } - llvm_unreachable("unknown atomic_write_error value in " - "failed_to_rename_temp_file::log()"); -} - -llvm::Error llvm::writeFileAtomically(StringRef TempPathModel, - StringRef FinalPath, StringRef Buffer) { - return writeFileAtomically(TempPathModel, FinalPath, - [&Buffer](llvm::raw_ostream &OS) { - OS.write(Buffer.data(), Buffer.size()); - return llvm::Error::success(); - }); -} - -llvm::Error llvm::writeFileAtomically( - StringRef TempPathModel, StringRef FinalPath, - std::function<llvm::Error(llvm::raw_ostream &)> Writer) { - SmallString<128> GeneratedUniqPath; - int TempFD; - if (sys::fs::createUniqueFile(TempPathModel.str(), TempFD, - GeneratedUniqPath)) { - return llvm::make_error<AtomicFileWriteError>( - atomic_write_error::failed_to_create_uniq_file); - } - llvm::FileRemover RemoveTmpFileOnFail(GeneratedUniqPath); - - raw_fd_ostream OS(TempFD, /*shouldClose=*/true); - if (llvm::Error Err = Writer(OS)) { - return Err; - } - - OS.close(); - if (OS.has_error()) { - OS.clear_error(); - return llvm::make_error<AtomicFileWriteError>( - atomic_write_error::output_stream_error); - } - - if (const std::error_code Error = - sys::fs::rename(/*from=*/GeneratedUniqPath.c_str(), - /*to=*/FinalPath.str().c_str())) { - return llvm::make_error<AtomicFileWriteError>( - atomic_write_error::failed_to_rename_temp_file); - } - - RemoveTmpFileOnFail.releaseFile(); - return Error::success(); -} - -char llvm::AtomicFileWriteError::ID; diff --git a/contrib/llvm-project/llvm/lib/Support/GlobPattern.cpp b/contrib/llvm-project/llvm/lib/Support/GlobPattern.cpp index 8dae6941ec77..6011be86d77f 100644 --- a/contrib/llvm-project/llvm/lib/Support/GlobPattern.cpp +++ b/contrib/llvm-project/llvm/lib/Support/GlobPattern.cpp @@ -19,7 +19,7 @@ using namespace llvm; static bool hasWildcard(StringRef S) { - return S.find_first_of("?*[\\") != StringRef::npos; + return S.find_first_of("?*[") != StringRef::npos; } // Expands character ranges and returns a bitmap. @@ -60,9 +60,8 @@ static Expected<BitVector> expand(StringRef S, StringRef Original) { } // This is a scanner for the glob pattern. -// A glob pattern token is one of "*", "?", "\", "[<chars>]", "[^<chars>]" -// (which is a negative form of "[<chars>]"), "[!<chars>]" (which is -// equivalent to "[^<chars>]"), or a non-meta character. +// A glob pattern token is one of "*", "?", "[<chars>]", "[^<chars>]" +// (which is a negative form of "[<chars>]"), or a non-meta character. // This function returns the first token in S. static Expected<BitVector> scan(StringRef &S, StringRef Original) { switch (S[0]) { @@ -75,16 +74,14 @@ static Expected<BitVector> scan(StringRef &S, StringRef Original) { S = S.substr(1); return BitVector(256, true); case '[': { - // ']' is allowed as the first character of a character class. '[]' is - // invalid. So, just skip the first character. - size_t End = S.find(']', 2); + size_t End = S.find(']', 1); if (End == StringRef::npos) return make_error<StringError>("invalid glob pattern: " + Original, errc::invalid_argument); StringRef Chars = S.substr(1, End - 1); S = S.substr(End + 1); - if (Chars.startswith("^") || Chars.startswith("!")) { + if (Chars.startswith("^")) { Expected<BitVector> BV = expand(Chars.substr(1), Original); if (!BV) return BV.takeError(); @@ -92,11 +89,6 @@ static Expected<BitVector> scan(StringRef &S, StringRef Original) { } return expand(Chars, Original); } - case '\\': - // Eat this character and fall through below to treat it like a non-meta - // character. - S = S.substr(1); - LLVM_FALLTHROUGH; default: BitVector BV(256, false); BV[(uint8_t)S[0]] = true; @@ -115,9 +107,8 @@ Expected<GlobPattern> GlobPattern::create(StringRef S) { return Pat; } - // S is something like "foo*", and the "* is not escaped. We can use - // startswith(). - if (S.endswith("*") && !S.endswith("\\*") && !hasWildcard(S.drop_back())) { + // S is something like "foo*". We can use startswith(). + if (S.endswith("*") && !hasWildcard(S.drop_back())) { Pat.Prefix = S.drop_back(); return Pat; } diff --git a/contrib/llvm-project/llvm/lib/Support/Host.cpp b/contrib/llvm-project/llvm/lib/Support/Host.cpp index ef38c1c09413..d491912bdc0c 100644 --- a/contrib/llvm-project/llvm/lib/Support/Host.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Host.cpp @@ -35,7 +35,7 @@ #ifdef _MSC_VER #include <intrin.h> #endif -#if defined(__APPLE__) && (!defined(__x86_64__)) +#if defined(__APPLE__) && (defined(__ppc__) || defined(__powerpc__)) #include <mach/host_info.h> #include <mach/mach.h> #include <mach/mach_host.h> @@ -140,9 +140,6 @@ StringRef sys::detail::getHostCPUNameForPowerPC(StringRef ProcCpuinfoContent) { .Case("POWER8E", "pwr8") .Case("POWER8NVL", "pwr8") .Case("POWER9", "pwr9") - // FIXME: If we get a simulator or machine with the capabilities of - // mcpu=future, we should revisit this and add the name reported by the - // simulator/machine. .Default(generic); } @@ -268,12 +265,14 @@ StringRef sys::detail::getHostCPUNameForARM(StringRef ProcCpuinfoContent) { unsigned Exynos = (Variant << 12) | Part; switch (Exynos) { default: - // Default by falling through to Exynos M3. + // Default by falling through to Exynos M1. LLVM_FALLTHROUGH; - case 0x1002: - return "exynos-m3"; - case 0x1003: - return "exynos-m4"; + + case 0x1001: + return "exynos-m1"; + + case 0x4001: + return "exynos-m2"; } } @@ -317,7 +316,7 @@ StringRef sys::detail::getHostCPUNameForS390x(StringRef ProcCpuinfoContent) { unsigned int Id; if (!Lines[I].drop_front(Pos).getAsInteger(10, Id)) { if (Id >= 8561 && HaveVectorSupport) - return "z15"; + return "arch13"; if (Id >= 3906 && HaveVectorSupport) return "z14"; if (Id >= 2964 && HaveVectorSupport) @@ -681,7 +680,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, // Skylake Xeon: case 0x55: *Type = X86::INTEL_COREI7; - if (Features2 & (1 << (X86::FEATURE_AVX512BF16 - 32))) + if (Features3 & (1 << (X86::FEATURE_AVX512BF16 - 64))) *Subtype = X86::INTEL_COREI7_COOPERLAKE; // "cooperlake" else if (Features2 & (1 << (X86::FEATURE_AVX512VNNI - 32))) *Subtype = X86::INTEL_COREI7_CASCADELAKE; // "cascadelake" @@ -747,13 +746,6 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, break; default: // Unknown family 6 CPU, try to guess. - // TODO detect tigerlake host - if (Features3 & (1 << (X86::FEATURE_AVX512VP2INTERSECT - 64))) { - *Type = X86::INTEL_COREI7; - *Subtype = X86::INTEL_COREI7_TIGERLAKE; - break; - } - if (Features & (1 << X86::FEATURE_AVX512VBMI2)) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_ICELAKE_CLIENT; @@ -766,7 +758,7 @@ getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, break; } - if (Features2 & (1 << (X86::FEATURE_AVX512BF16 - 32))) { + if (Features3 & (1 << (X86::FEATURE_AVX512BF16 - 64))) { *Type = X86::INTEL_COREI7; *Subtype = X86::INTEL_COREI7_COOPERLAKE; break; @@ -962,9 +954,9 @@ static void getAMDProcessorTypeAndSubtype(unsigned Family, unsigned Model, break; // "btver2" case 23: *Type = X86::AMDFAM17H; - if ((Model >= 0x30 && Model <= 0x3f) || Model == 0x71) { + if (Model >= 0x30 && Model <= 0x3f) { *Subtype = X86::AMDFAM17H_ZNVER2; - break; // "znver2"; 30h-3fh, 71h: Zen2 + break; // "znver2"; 30h-3fh: Zen2 } if (Model <= 0x0f) { *Subtype = X86::AMDFAM17H_ZNVER1; @@ -1030,15 +1022,7 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, const unsigned AVXBits = (1 << 27) | (1 << 28); bool HasAVX = ((ECX & AVXBits) == AVXBits) && !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6); -#if defined(__APPLE__) - // Darwin lazily saves the AVX512 context on first use: trust that the OS will - // save the AVX512 context if we use AVX512 instructions, even the bit is not - // set right now. - bool HasAVX512Save = true; -#else - // AVX512 requires additional context to be saved by the OS. bool HasAVX512Save = HasAVX && ((EAX & 0xe0) == 0xe0); -#endif if (HasAVX) setFeature(X86::FEATURE_AVX); @@ -1050,7 +1034,7 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(X86::FEATURE_BMI); if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) setFeature(X86::FEATURE_AVX2); - if (HasLeaf7 && ((EBX >> 8) & 1)) + if (HasLeaf7 && ((EBX >> 9) & 1)) setFeature(X86::FEATURE_BMI2); if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX512F); @@ -1094,13 +1078,6 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(X86::FEATURE_AVX5124VNNIW); if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) setFeature(X86::FEATURE_AVX5124FMAPS); - if (HasLeaf7 && ((EDX >> 8) & 1) && HasAVX512Save) - setFeature(X86::FEATURE_AVX512VP2INTERSECT); - - bool HasLeaf7Subleaf1 = - MaxLeaf >= 7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); - if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) - setFeature(X86::FEATURE_AVX512BF16); unsigned MaxExtLevel; getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); @@ -1231,33 +1208,6 @@ StringRef sys::getHostCPUName() { StringRef Content = P ? P->getBuffer() : ""; return detail::getHostCPUNameForS390x(Content); } -#elif defined(__APPLE__) && defined(__aarch64__) -StringRef sys::getHostCPUName() { - return "cyclone"; -} -#elif defined(__APPLE__) && defined(__arm__) -StringRef sys::getHostCPUName() { - host_basic_info_data_t hostInfo; - mach_msg_type_number_t infoCount; - - infoCount = HOST_BASIC_INFO_COUNT; - mach_port_t hostPort = mach_host_self(); - host_info(hostPort, HOST_BASIC_INFO, (host_info_t)&hostInfo, - &infoCount); - mach_port_deallocate(mach_task_self(), hostPort); - - if (hostInfo.cpu_type != CPU_TYPE_ARM) { - assert(false && "CPUType not equal to ARM should not be possible on ARM"); - return "generic"; - } - switch (hostInfo.cpu_subtype) { - case CPU_SUBTYPE_ARM_V7S: - return "swift"; - default:; - } - - return "generic"; -} #else StringRef sys::getHostCPUName() { return "generic"; } #endif @@ -1375,15 +1325,8 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { // switch, then we have full AVX support. bool HasAVXSave = ((ECX >> 27) & 1) && ((ECX >> 28) & 1) && !getX86XCR0(&EAX, &EDX) && ((EAX & 0x6) == 0x6); -#if defined(__APPLE__) - // Darwin lazily saves the AVX512 context on first use: trust that the OS will - // save the AVX512 context if we use AVX512 instructions, even the bit is not - // set right now. - bool HasAVX512Save = true; -#else // AVX512 requires additional context to be saved by the OS. bool HasAVX512Save = HasAVXSave && ((EAX & 0xe0) == 0xe0); -#endif Features["avx"] = HasAVXSave; Features["fma"] = ((ECX >> 12) & 1) && HasAVXSave; @@ -1426,6 +1369,7 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { Features["bmi2"] = HasLeaf7 && ((EBX >> 8) & 1); Features["invpcid"] = HasLeaf7 && ((EBX >> 10) & 1); Features["rtm"] = HasLeaf7 && ((EBX >> 11) & 1); + Features["mpx"] = HasLeaf7 && ((EBX >> 14) & 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; @@ -1555,17 +1499,6 @@ bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return true; } -#elif defined(_WIN32) && (defined(__aarch64__) || defined(_M_ARM64)) -bool sys::getHostCPUFeatures(StringMap<bool> &Features) { - if (IsProcessorFeaturePresent(PF_ARM_NEON_INSTRUCTIONS_AVAILABLE)) - Features["neon"] = true; - if (IsProcessorFeaturePresent(PF_ARM_V8_CRC32_INSTRUCTIONS_AVAILABLE)) - Features["crc"] = true; - if (IsProcessorFeaturePresent(PF_ARM_V8_CRYPTO_INSTRUCTIONS_AVAILABLE)) - Features["crypto"] = true; - - return true; -} #else bool sys::getHostCPUFeatures(StringMap<bool> &Features) { return false; } #endif diff --git a/contrib/llvm-project/llvm/lib/Support/InitLLVM.cpp b/contrib/llvm-project/llvm/lib/Support/InitLLVM.cpp index bb9b569d2de6..0d7d7fcc8cb6 100644 --- a/contrib/llvm-project/llvm/lib/Support/InitLLVM.cpp +++ b/contrib/llvm-project/llvm/lib/Support/InitLLVM.cpp @@ -21,11 +21,7 @@ using namespace llvm; using namespace llvm::sys; -InitLLVM::InitLLVM(int &Argc, const char **&Argv, - bool InstallPipeSignalExitHandler) - : StackPrinter(Argc, Argv) { - if (InstallPipeSignalExitHandler) - sys::SetOneShotPipeSignalFunction(sys::DefaultOneShotPipeSignalHandler); +InitLLVM::InitLLVM(int &Argc, const char **&Argv) : StackPrinter(Argc, Argv) { sys::PrintStackTraceOnErrorSignal(Argv[0]); install_out_of_memory_new_handler(); diff --git a/contrib/llvm-project/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp b/contrib/llvm-project/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp index bbc06d186fba..da6514f7170b 100644 --- a/contrib/llvm-project/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp +++ b/contrib/llvm-project/llvm/lib/Support/ItaniumManglingCanonicalizer.cpp @@ -36,6 +36,17 @@ struct FoldingSetNodeIDBuilder { operator()(T V) { ID.AddInteger((unsigned long long)V); } + void operator()(itanium_demangle::NodeOrString NS) { + if (NS.isNode()) { + ID.AddInteger(0); + (*this)(NS.asNode()); + } else if (NS.isString()) { + ID.AddInteger(1); + (*this)(NS.asString()); + } else { + ID.AddInteger(2); + } + } void operator()(itanium_demangle::NodeArray A) { ID.AddInteger(A.size()); for (const Node *N : A) @@ -296,32 +307,16 @@ ItaniumManglingCanonicalizer::addEquivalence(FragmentKind Kind, StringRef First, return EquivalenceError::Success; } -static ItaniumManglingCanonicalizer::Key -parseMaybeMangledName(CanonicalizingDemangler &Demangler, StringRef Mangling, - bool CreateNewNodes) { - Demangler.ASTAllocator.setCreateNewNodes(CreateNewNodes); - Demangler.reset(Mangling.begin(), Mangling.end()); - // Attempt demangling only for names that look like C++ mangled names. - // Otherwise, treat them as extern "C" names. We permit the latter to - // be remapped by (eg) - // encoding 6memcpy 7memmove - // consistent with how they are encoded as local-names inside a C++ mangling. - Node *N; - if (Mangling.startswith("_Z") || Mangling.startswith("__Z") || - Mangling.startswith("___Z") || Mangling.startswith("____Z")) - N = Demangler.parse(); - else - N = Demangler.make<itanium_demangle::NameType>( - StringView(Mangling.data(), Mangling.size())); - return reinterpret_cast<ItaniumManglingCanonicalizer::Key>(N); -} - ItaniumManglingCanonicalizer::Key ItaniumManglingCanonicalizer::canonicalize(StringRef Mangling) { - return parseMaybeMangledName(P->Demangler, Mangling, true); + P->Demangler.ASTAllocator.setCreateNewNodes(true); + P->Demangler.reset(Mangling.begin(), Mangling.end()); + return reinterpret_cast<Key>(P->Demangler.parse()); } ItaniumManglingCanonicalizer::Key ItaniumManglingCanonicalizer::lookup(StringRef Mangling) { - return parseMaybeMangledName(P->Demangler, Mangling, false); + P->Demangler.ASTAllocator.setCreateNewNodes(false); + P->Demangler.reset(Mangling.begin(), Mangling.end()); + return reinterpret_cast<Key>(P->Demangler.parse()); } diff --git a/contrib/llvm-project/llvm/lib/Support/JSON.cpp b/contrib/llvm-project/llvm/lib/Support/JSON.cpp index 16b1d11efd08..95e5ed654277 100644 --- a/contrib/llvm-project/llvm/lib/Support/JSON.cpp +++ b/contrib/llvm-project/llvm/lib/Support/JSON.cpp @@ -502,7 +502,7 @@ bool Parser::parseError(const char *Msg) { } } Err.emplace( - std::make_unique<ParseError>(Msg, Line, P - StartOfLine, P - Start)); + llvm::make_unique<ParseError>(Msg, Line, P - StartOfLine, P - Start)); return false; } } // namespace diff --git a/contrib/llvm-project/llvm/lib/Support/JamCRC.cpp b/contrib/llvm-project/llvm/lib/Support/JamCRC.cpp new file mode 100644 index 000000000000..e043a3c33c28 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/JamCRC.cpp @@ -0,0 +1,96 @@ +//===-- JamCRC.cpp - Cyclic Redundancy Check --------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file contains an implementation of JamCRC. +// +//===----------------------------------------------------------------------===// +// +// The implementation technique is the one mentioned in: +// D. V. Sarwate. 1988. Computation of cyclic redundancy checks via table +// look-up. Commun. ACM 31, 8 (August 1988) +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/JamCRC.h" +#include "llvm/ADT/ArrayRef.h" + +using namespace llvm; + +static const uint32_t CRCTable[256] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, + 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, + 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, + 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, + 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, + 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, + 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, + 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, + 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, + 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, + 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, + 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, + 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, + 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, + 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, + 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, + 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, + 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, + 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, + 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, + 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, + 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, + 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, + 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, + 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, + 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, + 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, + 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, + 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, + 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, + 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, + 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, + 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d +}; + +void JamCRC::update(ArrayRef<char> Data) { + for (char Byte : Data) { + int TableIdx = (CRC ^ Byte) & 0xff; + CRC = CRCTable[TableIdx] ^ (CRC >> 8); + } +} diff --git a/contrib/llvm-project/llvm/lib/Support/KnownBits.cpp b/contrib/llvm-project/llvm/lib/Support/KnownBits.cpp index 8f3f4aa8caea..a6c591fca312 100644 --- a/contrib/llvm-project/llvm/lib/Support/KnownBits.cpp +++ b/contrib/llvm-project/llvm/lib/Support/KnownBits.cpp @@ -21,8 +21,8 @@ static KnownBits computeForAddCarry( assert(!(CarryZero && CarryOne) && "Carry can't be zero and one at the same time"); - APInt PossibleSumZero = LHS.getMaxValue() + RHS.getMaxValue() + !CarryZero; - APInt PossibleSumOne = LHS.getMinValue() + RHS.getMinValue() + CarryOne; + APInt PossibleSumZero = ~LHS.Zero + ~RHS.Zero + !CarryZero; + APInt PossibleSumOne = LHS.One + RHS.One + CarryOne; // Compute known bits of the carry. APInt CarryKnownZero = ~(PossibleSumZero ^ LHS.Zero ^ RHS.Zero); diff --git a/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp b/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp index 5c6508c3b007..10181192afbd 100644 --- a/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp +++ b/contrib/llvm-project/llvm/lib/Support/LockFileManager.cpp @@ -290,8 +290,7 @@ LockFileManager::~LockFileManager() { sys::DontRemoveFileOnSignal(UniqueLockFileName); } -LockFileManager::WaitForUnlockResult -LockFileManager::waitForUnlock(const unsigned MaxSeconds) { +LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() { if (getState() != LFS_Shared) return Res_Success; @@ -302,6 +301,9 @@ LockFileManager::waitForUnlock(const unsigned MaxSeconds) { Interval.tv_sec = 0; Interval.tv_nsec = 1000000; #endif + // Don't wait more than 40s per iteration. Total timeout for the file + // to appear is ~1.5 minutes. + const unsigned MaxSeconds = 40; do { // Sleep for the designated interval, to allow the owning process time to // finish up and remove the lock file. diff --git a/contrib/llvm-project/llvm/lib/Support/ManagedStatic.cpp b/contrib/llvm-project/llvm/lib/Support/ManagedStatic.cpp index 053493f72fb5..28ceb1a70e42 100644 --- a/contrib/llvm-project/llvm/lib/Support/ManagedStatic.cpp +++ b/contrib/llvm-project/llvm/lib/Support/ManagedStatic.cpp @@ -12,20 +12,21 @@ #include "llvm/Support/ManagedStatic.h" #include "llvm/Config/config.h" +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" #include "llvm/Support/Threading.h" #include <cassert> -#include <mutex> using namespace llvm; static const ManagedStaticBase *StaticList = nullptr; -static std::recursive_mutex *ManagedStaticMutex = nullptr; +static sys::Mutex *ManagedStaticMutex = nullptr; static llvm::once_flag mutex_init_flag; static void initializeMutex() { - ManagedStaticMutex = new std::recursive_mutex(); + ManagedStaticMutex = new sys::Mutex(); } -static std::recursive_mutex *getManagedStaticMutex() { +static sys::Mutex* getManagedStaticMutex() { llvm::call_once(mutex_init_flag, initializeMutex); return ManagedStaticMutex; } @@ -34,7 +35,7 @@ void ManagedStaticBase::RegisterManagedStatic(void *(*Creator)(), void (*Deleter)(void*)) const { assert(Creator); if (llvm_is_multithreaded()) { - std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex()); + MutexGuard Lock(*getManagedStaticMutex()); if (!Ptr.load(std::memory_order_relaxed)) { void *Tmp = Creator(); @@ -76,7 +77,7 @@ void ManagedStaticBase::destroy() const { /// llvm_shutdown - Deallocate and destroy all ManagedStatic variables. void llvm::llvm_shutdown() { - std::lock_guard<std::recursive_mutex> Lock(*getManagedStaticMutex()); + MutexGuard Lock(*getManagedStaticMutex()); while (StaticList) StaticList->destroy(); diff --git a/contrib/llvm-project/llvm/lib/Support/MemoryBuffer.cpp b/contrib/llvm-project/llvm/lib/Support/MemoryBuffer.cpp index e4027ca7bbfd..d0e5bb154c1a 100644 --- a/contrib/llvm-project/llvm/lib/Support/MemoryBuffer.cpp +++ b/contrib/llvm-project/llvm/lib/Support/MemoryBuffer.cpp @@ -211,17 +211,15 @@ static ErrorOr<std::unique_ptr<WritableMemoryBuffer>> getMemoryBufferForStream(sys::fs::file_t FD, const Twine &BufferName) { const ssize_t ChunkSize = 4096*4; SmallString<ChunkSize> Buffer; + size_t ReadBytes; // Read into Buffer until we hit EOF. - for (;;) { + do { Buffer.reserve(Buffer.size() + ChunkSize); - Expected<size_t> ReadBytes = sys::fs::readNativeFile( - FD, makeMutableArrayRef(Buffer.end(), ChunkSize)); - if (!ReadBytes) - return errorToErrorCode(ReadBytes.takeError()); - if (*ReadBytes == 0) - break; - Buffer.set_size(Buffer.size() + *ReadBytes); - } + if (auto EC = sys::fs::readNativeFile( + FD, makeMutableArrayRef(Buffer.end(), ChunkSize), &ReadBytes)) + return EC; + Buffer.set_size(Buffer.size() + ReadBytes); + } while (ReadBytes != 0); return getMemBufferCopyImpl(Buffer, BufferName); } @@ -460,20 +458,7 @@ getOpenFileImpl(sys::fs::file_t FD, const Twine &Filename, uint64_t FileSize, return make_error_code(errc::not_enough_memory); } - // Read until EOF, zero-initialize the rest. - MutableArrayRef<char> ToRead = Buf->getBuffer(); - while (!ToRead.empty()) { - Expected<size_t> ReadBytes = - sys::fs::readNativeFileSlice(FD, ToRead, Offset); - if (!ReadBytes) - return errorToErrorCode(ReadBytes.takeError()); - if (*ReadBytes == 0) { - std::memset(ToRead.data(), 0, ToRead.size()); - break; - } - ToRead = ToRead.drop_front(*ReadBytes); - Offset += *ReadBytes; - } + sys::fs::readNativeFileSlice(FD, Buf->getBuffer(), Offset); return std::move(Buf); } diff --git a/contrib/llvm-project/llvm/lib/Support/Mutex.cpp b/contrib/llvm-project/llvm/lib/Support/Mutex.cpp new file mode 100644 index 000000000000..69b7b8126ab1 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Mutex.cpp @@ -0,0 +1,123 @@ +//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the llvm::sys::Mutex class. +// +//===----------------------------------------------------------------------===// + +#include "llvm/Support/Mutex.h" +#include "llvm/Config/config.h" +#include "llvm/Support/ErrorHandling.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*>(safe_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; +} + +} + +#elif defined(LLVM_ON_UNIX) +#include "Unix/Mutex.inc" +#elif defined( _WIN32) +#include "Windows/Mutex.inc" +#else +#warning Neither LLVM_ON_UNIX nor _WIN32 was set in Support/Mutex.cpp +#endif +#endif diff --git a/contrib/llvm-project/llvm/lib/Support/Options.cpp b/contrib/llvm-project/llvm/lib/Support/Options.cpp new file mode 100644 index 000000000000..770b7381c20e --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Options.cpp @@ -0,0 +1,32 @@ +//===- llvm/Support/Options.cpp - Debug options support ---------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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-project/llvm/lib/Support/Parallel.cpp b/contrib/llvm-project/llvm/lib/Support/Parallel.cpp index 523665d14b02..621bccbf2a4c 100644 --- a/contrib/llvm-project/llvm/lib/Support/Parallel.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Parallel.cpp @@ -8,17 +8,14 @@ #include "llvm/Support/Parallel.h" #include "llvm/Config/llvm-config.h" -#include "llvm/Support/ManagedStatic.h" #if LLVM_ENABLE_THREADS #include "llvm/Support/Threading.h" #include <atomic> -#include <future> #include <stack> #include <thread> -#include <vector> namespace llvm { namespace parallel { @@ -35,57 +32,62 @@ public: static Executor *getDefaultExecutor(); }; +#if defined(_MSC_VER) +/// An Executor that runs tasks via ConcRT. +class ConcRTExecutor : public Executor { + struct Taskish { + Taskish(std::function<void()> Task) : Task(Task) {} + + std::function<void()> Task; + + static void run(void *P) { + Taskish *Self = static_cast<Taskish *>(P); + Self->Task(); + concurrency::Free(Self); + } + }; + +public: + virtual void add(std::function<void()> F) { + Concurrency::CurrentScheduler::ScheduleTask( + Taskish::run, new (concurrency::Alloc(sizeof(Taskish))) Taskish(F)); + } +}; + +Executor *Executor::getDefaultExecutor() { + static ConcRTExecutor exec; + return &exec; +} + +#else /// An implementation of an Executor that runs closures on a thread pool /// in filo order. class ThreadPoolExecutor : public Executor { public: - explicit ThreadPoolExecutor(unsigned ThreadCount = hardware_concurrency()) { + explicit ThreadPoolExecutor(unsigned ThreadCount = hardware_concurrency()) + : Done(ThreadCount) { // Spawn all but one of the threads in another thread as spawning threads // can take a while. - Threads.reserve(ThreadCount); - Threads.resize(1); - std::lock_guard<std::mutex> Lock(Mutex); - Threads[0] = std::thread([&, ThreadCount] { - for (unsigned i = 1; i < ThreadCount; ++i) { - Threads.emplace_back([=] { work(); }); - if (Stop) - break; + std::thread([&, ThreadCount] { + for (size_t i = 1; i < ThreadCount; ++i) { + std::thread([=] { work(); }).detach(); } - ThreadsCreated.set_value(); work(); - }); - } - - void stop() { - { - std::lock_guard<std::mutex> Lock(Mutex); - if (Stop) - return; - Stop = true; - } - Cond.notify_all(); - ThreadsCreated.get_future().wait(); + }).detach(); } ~ThreadPoolExecutor() override { - stop(); - std::thread::id CurrentThreadId = std::this_thread::get_id(); - for (std::thread &T : Threads) - if (T.get_id() == CurrentThreadId) - T.detach(); - else - T.join(); + std::unique_lock<std::mutex> Lock(Mutex); + Stop = true; + Lock.unlock(); + Cond.notify_all(); + // Wait for ~Latch. } - struct Deleter { - static void call(void *Ptr) { ((ThreadPoolExecutor *)Ptr)->stop(); } - }; - void add(std::function<void()> F) override { - { - std::lock_guard<std::mutex> Lock(Mutex); - WorkStack.push(F); - } + std::unique_lock<std::mutex> Lock(Mutex); + WorkStack.push(F); + Lock.unlock(); Cond.notify_one(); } @@ -101,41 +103,22 @@ private: Lock.unlock(); Task(); } + Done.dec(); } std::atomic<bool> Stop{false}; std::stack<std::function<void()>> WorkStack; std::mutex Mutex; std::condition_variable Cond; - std::promise<void> ThreadsCreated; - std::vector<std::thread> Threads; + parallel::detail::Latch Done; }; Executor *Executor::getDefaultExecutor() { - // The ManagedStatic enables the ThreadPoolExecutor to be stopped via - // llvm_shutdown() which allows a "clean" fast exit, e.g. via _exit(). This - // stops the thread pool and waits for any worker thread creation to complete - // but does not wait for the threads to finish. The wait for worker thread - // creation to complete is important as it prevents intermittent crashes on - // Windows due to a race condition between thread creation and process exit. - // - // The ThreadPoolExecutor will only be destroyed when the static unique_ptr to - // it is destroyed, i.e. in a normal full exit. The ThreadPoolExecutor - // destructor ensures it has been stopped and waits for worker threads to - // finish. The wait is important as it prevents intermittent crashes on - // Windows when the process is doing a full exit. - // - // The Windows crashes appear to only occur with the MSVC static runtimes and - // are more frequent with the debug static runtime. - // - // This also prevents intermittent deadlocks on exit with the MinGW runtime. - static ManagedStatic<ThreadPoolExecutor, object_creator<ThreadPoolExecutor>, - ThreadPoolExecutor::Deleter> - ManagedExec; - static std::unique_ptr<ThreadPoolExecutor> Exec(&(*ManagedExec)); - return Exec.get(); + static ThreadPoolExecutor exec; + return &exec; +} +#endif } -} // namespace static std::atomic<int> TaskGroupInstances; diff --git a/contrib/llvm-project/llvm/lib/Support/Path.cpp b/contrib/llvm-project/llvm/lib/Support/Path.cpp index 3c9a08cb4077..c49260125dba 100644 --- a/contrib/llvm-project/llvm/lib/Support/Path.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Path.cpp @@ -496,50 +496,27 @@ void replace_extension(SmallVectorImpl<char> &path, const Twine &extension, path.append(ext.begin(), ext.end()); } -bool replace_path_prefix(SmallVectorImpl<char> &Path, +void replace_path_prefix(SmallVectorImpl<char> &Path, const StringRef &OldPrefix, const StringRef &NewPrefix, - Style style, bool strict) { + Style style) { if (OldPrefix.empty() && NewPrefix.empty()) - return false; + return; StringRef OrigPath(Path.begin(), Path.size()); - StringRef OldPrefixDir; - - if (!strict && OldPrefix.size() > OrigPath.size()) - return false; - - // Ensure OldPrefixDir does not have a trailing separator. - if (!OldPrefix.empty() && is_separator(OldPrefix.back())) - OldPrefixDir = parent_path(OldPrefix, style); - else - OldPrefixDir = OldPrefix; - - if (!OrigPath.startswith(OldPrefixDir)) - return false; - - if (OrigPath.size() > OldPrefixDir.size()) - if (!is_separator(OrigPath[OldPrefixDir.size()], style) && strict) - return false; + if (!OrigPath.startswith(OldPrefix)) + return; // If prefixes have the same size we can simply copy the new one over. - if (OldPrefixDir.size() == NewPrefix.size() && !strict) { + if (OldPrefix.size() == NewPrefix.size()) { llvm::copy(NewPrefix, Path.begin()); - return true; + return; } - StringRef RelPath = OrigPath.substr(OldPrefixDir.size()); + StringRef RelPath = OrigPath.substr(OldPrefix.size()); SmallString<256> NewPath; path::append(NewPath, style, NewPrefix); - if (!RelPath.empty()) { - if (!is_separator(RelPath[0], style) || !strict) - path::append(NewPath, style, RelPath); - else - path::append(NewPath, style, relative_path(RelPath, style)); - } - + path::append(NewPath, style, RelPath); Path.swap(NewPath); - - return true; } void native(const Twine &path, SmallVectorImpl<char> &result, Style style) { @@ -878,11 +855,11 @@ void make_absolute(const Twine ¤t_directory, StringRef p(path.data(), path.size()); bool rootDirectory = path::has_root_directory(p); - bool rootName = path::has_root_name(p); + bool rootName = + (real_style(Style::native) != Style::windows) || path::has_root_name(p); // Already absolute. - if ((rootName || real_style(Style::native) != Style::windows) && - rootDirectory) + if (rootName && rootDirectory) return; // All of the following conditions will need the current directory. diff --git a/contrib/llvm-project/llvm/lib/Support/PrettyStackTrace.cpp b/contrib/llvm-project/llvm/lib/Support/PrettyStackTrace.cpp index bfb238cc8539..aec00baec0e3 100644 --- a/contrib/llvm-project/llvm/lib/Support/PrettyStackTrace.cpp +++ b/contrib/llvm-project/llvm/lib/Support/PrettyStackTrace.cpp @@ -121,63 +121,31 @@ extern "C" const char *__crashreporter_info__ asm(".desc ___crashreporter_info__, 0x10"); #endif -static void setCrashLogMessage(const char *msg) LLVM_ATTRIBUTE_UNUSED; -static void setCrashLogMessage(const char *msg) { -#ifdef HAVE_CRASHREPORTERCLIENT_H - (void)CRSetCrashLogMessage(msg); -#elif HAVE_CRASHREPORTER_INFO - __crashreporter_info__ = msg; -#endif - // Don't reorder subsequent operations: whatever comes after might crash and - // we want the system crash handling to see the message we just set. - std::atomic_signal_fence(std::memory_order_seq_cst); -} - -#ifdef __APPLE__ -using CrashHandlerString = SmallString<2048>; -using CrashHandlerStringStorage = - std::aligned_storage<sizeof(CrashHandlerString), - alignof(CrashHandlerString)>::type; -static CrashHandlerStringStorage crashHandlerStringStorage; -#endif - -/// This callback is run if a fatal signal is delivered to the process, it -/// prints the pretty stack trace. +/// 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 - // Emit the crash stack trace to a SmallString, put it where the system crash - // handling will find it, and also send it to stderr. - // - // The SmallString is fairly large in the hope that we don't allocate (we're - // handling a fatal signal, something is already pretty wrong, allocation - // might not work). Further, we don't use a magic static in case that's also - // borked. We leak any allocation that does occur because the program is about - // to die anyways. This is technically racy if we were handling two fatal - // signals, however if we're in that situation a race is the least of our - // worries. - auto &crashHandlerString = - *new (&crashHandlerStringStorage) CrashHandlerString; - - // If we crash while trying to print the stack trace, we still want the system - // crash handling to have some partial information. That'll work out as long - // as the SmallString doesn't allocate. If it does allocate then the system - // crash handling will see some garbage because the inline buffer now contains - // a pointer. - setCrashLogMessage(crashHandlerString.c_str()); - + // 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(crashHandlerString); + raw_svector_ostream Stream(TmpStr); PrintCurStackTrace(Stream); } - if (!crashHandlerString.empty()) { - setCrashLogMessage(crashHandlerString.c_str()); - errs() << crashHandlerString.str(); - } else - setCrashLogMessage("No crash information."); + if (!TmpStr.empty()) { +#ifdef HAVE_CRASHREPORTERCLIENT_H + // Cast to void to avoid warning. + (void)CRSetCrashLogMessage(TmpStr.c_str()); +#elif HAVE_CRASHREPORTER_INFO + __crashreporter_info__ = strdup(TmpStr.c_str()); +#endif + errs() << TmpStr.str(); + } + #endif } diff --git a/contrib/llvm-project/llvm/lib/Support/Process.cpp b/contrib/llvm-project/llvm/lib/Support/Process.cpp index 509512f643d3..5b6471008159 100644 --- a/contrib/llvm-project/llvm/lib/Support/Process.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Process.cpp @@ -13,9 +13,8 @@ #include "llvm/Support/Process.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringExtras.h" -#include "llvm/Config/config.h" #include "llvm/Config/llvm-config.h" -#include "llvm/Support/CrashRecoveryContext.h" +#include "llvm/Config/config.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/Program.h" @@ -89,13 +88,6 @@ static bool coreFilesPrevented = !LLVM_ENABLE_CRASH_DUMPS; bool Process::AreCoreFilesPrevented() { return coreFilesPrevented; } -LLVM_ATTRIBUTE_NORETURN -void Process::Exit(int RetCode) { - if (CrashRecoveryContext *CRC = CrashRecoveryContext::GetCurrent()) - CRC->HandleExit(RetCode); - ::exit(RetCode); -} - // Include the platform-specific parts of this class. #ifdef LLVM_ON_UNIX #include "Unix/Process.inc" diff --git a/contrib/llvm-project/llvm/lib/Support/RWMutex.cpp b/contrib/llvm-project/llvm/lib/Support/RWMutex.cpp index 5accf73e5f94..7ce856b716c6 100644 --- a/contrib/llvm-project/llvm/lib/Support/RWMutex.cpp +++ b/contrib/llvm-project/llvm/lib/Support/RWMutex.cpp @@ -14,20 +14,24 @@ #include "llvm/Support/RWMutex.h" #include "llvm/Config/config.h" -#if defined(LLVM_USE_RW_MUTEX_IMPL) -using namespace llvm; -using namespace sys; +//===----------------------------------------------------------------------===// +//=== 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 +using namespace llvm; +using namespace sys; + RWMutexImpl::RWMutexImpl() = default; RWMutexImpl::~RWMutexImpl() = default; -bool RWMutexImpl::lock_shared() { return true; } -bool RWMutexImpl::unlock_shared() { return true; } -bool RWMutexImpl::lock() { return true; } -bool RWMutexImpl::unlock() { return true; } +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 @@ -37,6 +41,9 @@ bool RWMutexImpl::unlock() { return true; } #include <cstdlib> #include <pthread.h> +using namespace llvm; +using namespace sys; + // Construct a RWMutex using pthread calls RWMutexImpl::RWMutexImpl() { @@ -68,7 +75,7 @@ RWMutexImpl::~RWMutexImpl() } bool -RWMutexImpl::lock_shared() +RWMutexImpl::reader_acquire() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); @@ -78,7 +85,7 @@ RWMutexImpl::lock_shared() } bool -RWMutexImpl::unlock_shared() +RWMutexImpl::reader_release() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); @@ -88,7 +95,7 @@ RWMutexImpl::unlock_shared() } bool -RWMutexImpl::lock() +RWMutexImpl::writer_acquire() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); @@ -98,7 +105,7 @@ RWMutexImpl::lock() } bool -RWMutexImpl::unlock() +RWMutexImpl::writer_release() { pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); assert(rwlock != nullptr); @@ -107,30 +114,11 @@ RWMutexImpl::unlock() return errorcode == 0; } +#elif defined(LLVM_ON_UNIX) +#include "Unix/RWMutex.inc" +#elif defined( _WIN32) +#include "Windows/RWMutex.inc" #else - -RWMutexImpl::RWMutexImpl() : data_(new MutexImpl(false)) { } - -RWMutexImpl::~RWMutexImpl() { - delete static_cast<MutexImpl *>(data_); -} - -bool RWMutexImpl::lock_shared() { - return static_cast<MutexImpl *>(data_)->acquire(); -} - -bool RWMutexImpl::unlock_shared() { - return static_cast<MutexImpl *>(data_)->release(); -} - -bool RWMutexImpl::lock() { - return static_cast<MutexImpl *>(data_)->acquire(); -} - -bool RWMutexImpl::unlock() { - return static_cast<MutexImpl *>(data_)->release(); -} - -#endif +#warning Neither LLVM_ON_UNIX nor _WIN32 was set in Support/Mutex.cpp #endif #endif diff --git a/contrib/llvm-project/llvm/lib/Support/Regex.cpp b/contrib/llvm-project/llvm/lib/Support/Regex.cpp index 8da345d4f140..4c1b07038024 100644 --- a/contrib/llvm-project/llvm/lib/Support/Regex.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Regex.cpp @@ -52,24 +52,14 @@ Regex::~Regex() { } } -namespace { +bool Regex::isValid(std::string &Error) const { + if (!error) + return true; -/// Utility to convert a regex error code into a human-readable string. -void RegexErrorToString(int error, struct llvm_regex *preg, - std::string &Error) { size_t len = llvm_regerror(error, preg, nullptr, 0); Error.resize(len - 1); llvm_regerror(error, preg, &Error[0], len); -} - -} // namespace - -bool Regex::isValid(std::string &Error) const { - if (!error) - return true; - - RegexErrorToString(error, preg, Error); return false; } @@ -79,14 +69,8 @@ unsigned Regex::getNumMatches() const { return preg->re_nsub; } -bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches, - std::string *Error) const { - // Reset error, if given. - if (Error && !Error->empty()) - *Error = ""; - - // Check if the regex itself didn't successfully compile. - if (Error ? !isValid(*Error) : !isValid()) +bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){ + if (error) return false; unsigned nmatch = Matches ? preg->re_nsub+1 : 0; @@ -99,13 +83,11 @@ bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches, int rc = llvm_regexec(preg, String.data(), nmatch, pm.data(), REG_STARTEND); - // Failure to match is not an error, it's just a normal return value. - // Any other error code is considered abnormal, and is logged in the Error. if (rc == REG_NOMATCH) return false; if (rc != 0) { - if (Error) - RegexErrorToString(error, preg, *Error); + // regexec can fail due to invalid pattern or running out of memory. + error = rc; return false; } @@ -130,11 +112,14 @@ bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches, } std::string Regex::sub(StringRef Repl, StringRef String, - std::string *Error) const { + 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, Error)) + if (!match(String, &Matches)) return String; // Otherwise splice in the replacement string, starting with the prefix before diff --git a/contrib/llvm-project/llvm/lib/Support/SHA1.cpp b/contrib/llvm-project/llvm/lib/Support/SHA1.cpp index a98ca41a3354..47a5f07fbe7b 100644 --- a/contrib/llvm-project/llvm/lib/Support/SHA1.cpp +++ b/contrib/llvm-project/llvm/lib/Support/SHA1.cpp @@ -16,7 +16,6 @@ #include "llvm/Support/SHA1.h" #include "llvm/ADT/ArrayRef.h" -#include "llvm/Support/Endian.h" #include "llvm/Support/Host.h" using namespace llvm; @@ -27,45 +26,45 @@ using namespace llvm; #define SHA_BIG_ENDIAN #endif -static inline uint32_t rol(uint32_t Number, int Bits) { +static uint32_t rol(uint32_t Number, int Bits) { return (Number << Bits) | (Number >> (32 - Bits)); } -static inline uint32_t blk0(uint32_t *Buf, int I) { return Buf[I]; } +static uint32_t blk0(uint32_t *Buf, int I) { return Buf[I]; } -static inline uint32_t blk(uint32_t *Buf, int I) { +static uint32_t blk(uint32_t *Buf, int I) { Buf[I & 15] = rol(Buf[(I + 13) & 15] ^ Buf[(I + 8) & 15] ^ Buf[(I + 2) & 15] ^ Buf[I & 15], 1); return Buf[I & 15]; } -static inline void r0(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, - uint32_t &E, int I, uint32_t *Buf) { +static void r0(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, + int I, uint32_t *Buf) { E += ((B & (C ^ D)) ^ D) + blk0(Buf, I) + 0x5A827999 + rol(A, 5); B = rol(B, 30); } -static inline void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, - uint32_t &E, int I, uint32_t *Buf) { +static void r1(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, + int I, uint32_t *Buf) { E += ((B & (C ^ D)) ^ D) + blk(Buf, I) + 0x5A827999 + rol(A, 5); B = rol(B, 30); } -static inline void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, - uint32_t &E, int I, uint32_t *Buf) { +static void r2(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, + int I, uint32_t *Buf) { E += (B ^ C ^ D) + blk(Buf, I) + 0x6ED9EBA1 + rol(A, 5); B = rol(B, 30); } -static inline void r3(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, - uint32_t &E, int I, uint32_t *Buf) { +static void r3(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, + int I, uint32_t *Buf) { E += (((B | C) & D) | (B & C)) + blk(Buf, I) + 0x8F1BBCDC + rol(A, 5); B = rol(B, 30); } -static inline void r4(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, - uint32_t &E, int I, uint32_t *Buf) { +static void r4(uint32_t &A, uint32_t &B, uint32_t &C, uint32_t &D, uint32_t &E, + int I, uint32_t *Buf) { E += (B ^ C ^ D) + blk(Buf, I) + 0xCA62C1D6 + rol(A, 5); B = rol(B, 30); } @@ -211,31 +210,8 @@ void SHA1::writebyte(uint8_t Data) { } void SHA1::update(ArrayRef<uint8_t> Data) { - InternalState.ByteCount += Data.size(); - - // Finish the current block. - if (InternalState.BufferOffset > 0) { - const size_t Remainder = std::min<size_t>( - Data.size(), BLOCK_LENGTH - InternalState.BufferOffset); - for (size_t I = 0; I < Remainder; ++I) - addUncounted(Data[I]); - Data = Data.drop_front(Remainder); - } - - // Fast buffer filling for large inputs. - while (Data.size() >= BLOCK_LENGTH) { - assert(InternalState.BufferOffset == 0); - assert(BLOCK_LENGTH % 4 == 0); - constexpr size_t BLOCK_LENGTH_32 = BLOCK_LENGTH / 4; - for (size_t I = 0; I < BLOCK_LENGTH_32; ++I) - InternalState.Buffer.L[I] = support::endian::read32be(&Data[I * 4]); - hashBlock(); - Data = Data.drop_front(BLOCK_LENGTH); - } - - // Finish the remainder. - for (uint8_t C : Data) - addUncounted(C); + for (auto &C : Data) + writebyte(C); } void SHA1::pad() { diff --git a/contrib/llvm-project/llvm/lib/Support/Signals.cpp b/contrib/llvm-project/llvm/lib/Support/Signals.cpp index add6fde0eb5e..173a07f009d2 100644 --- a/contrib/llvm-project/llvm/lib/Support/Signals.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Signals.cpp @@ -15,19 +15,19 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" #include "llvm/Config/llvm-config.h" -#include "llvm/Support/CommandLine.h" #include "llvm/Support/ErrorOr.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/FileUtilities.h" #include "llvm/Support/Format.h" -#include "llvm/Support/FormatAdapters.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/FormatAdapters.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/Program.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/Options.h" #include <vector> //===----------------------------------------------------------------------===// diff --git a/contrib/llvm-project/llvm/lib/Support/Signposts.cpp b/contrib/llvm-project/llvm/lib/Support/Signposts.cpp index aa159e1da2ae..d456f41d2fa6 100644 --- a/contrib/llvm-project/llvm/lib/Support/Signposts.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Signposts.cpp @@ -78,8 +78,6 @@ public: #if LLVM_SUPPORT_XCODE_SIGNPOSTS #define HAVE_ANY_SIGNPOST_IMPL 1 -#else -#define HAVE_ANY_SIGNPOST_IMPL 0 #endif SignpostEmitter::SignpostEmitter() { diff --git a/contrib/llvm-project/llvm/lib/Support/SpecialCaseList.cpp b/contrib/llvm-project/llvm/lib/Support/SpecialCaseList.cpp index d1ff44cefb08..96e09f9552bb 100644 --- a/contrib/llvm-project/llvm/lib/Support/SpecialCaseList.cpp +++ b/contrib/llvm-project/llvm/lib/Support/SpecialCaseList.cpp @@ -18,7 +18,6 @@ #include "llvm/ADT/StringExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Regex.h" -#include "llvm/Support/VirtualFileSystem.h" #include <string> #include <system_error> #include <utility> @@ -54,7 +53,7 @@ bool SpecialCaseList::Matcher::insert(std::string Regexp, return false; RegExes.emplace_back( - std::make_pair(std::make_unique<Regex>(std::move(CheckRE)), LineNumber)); + std::make_pair(make_unique<Regex>(std::move(CheckRE)), LineNumber)); return true; } @@ -72,9 +71,9 @@ unsigned SpecialCaseList::Matcher::match(StringRef Query) const { std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const std::vector<std::string> &Paths, - llvm::vfs::FileSystem &FS, std::string &Error) { + std::string &Error) { std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList()); - if (SCL->createInternal(Paths, FS, Error)) + if (SCL->createInternal(Paths, Error)) return SCL; return nullptr; } @@ -88,20 +87,19 @@ std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB, } std::unique_ptr<SpecialCaseList> -SpecialCaseList::createOrDie(const std::vector<std::string> &Paths, - llvm::vfs::FileSystem &FS) { +SpecialCaseList::createOrDie(const std::vector<std::string> &Paths) { std::string Error; - if (auto SCL = create(Paths, FS, Error)) + if (auto SCL = create(Paths, Error)) return SCL; report_fatal_error(Error); } bool SpecialCaseList::createInternal(const std::vector<std::string> &Paths, - vfs::FileSystem &VFS, std::string &Error) { + std::string &Error) { StringMap<size_t> Sections; for (const auto &Path : Paths) { ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr = - VFS.getBufferForFile(Path); + MemoryBuffer::getFile(Path); if (std::error_code EC = FileOrErr.getError()) { Error = (Twine("can't open file '") + Path + "': " + EC.message()).str(); return false; @@ -177,7 +175,7 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, // Create this section if it has not been seen before. if (SectionsMap.find(Section) == SectionsMap.end()) { - std::unique_ptr<Matcher> M = std::make_unique<Matcher>(); + std::unique_ptr<Matcher> M = make_unique<Matcher>(); std::string REError; if (!M->insert(Section, LineNo, REError)) { Error = (Twine("malformed section ") + Section + ": '" + REError).str(); diff --git a/contrib/llvm-project/llvm/lib/Support/Statistic.cpp b/contrib/llvm-project/llvm/lib/Support/Statistic.cpp index 25f13871e2e4..e4f0535d21aa 100644 --- a/contrib/llvm-project/llvm/lib/Support/Statistic.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Statistic.cpp @@ -38,7 +38,7 @@ using namespace llvm; /// -stats - Command line option to cause transformations to emit stats about /// what they did. /// -static cl::opt<bool> EnableStats( +static cl::opt<bool> Stats( "stats", cl::desc("Enable statistics output from program (available with Asserts)"), cl::Hidden); @@ -57,7 +57,7 @@ namespace { /// This class is also used to look up statistic values from applications that /// use LLVM. class StatisticInfo { - std::vector<TrackingStatistic *> Stats; + std::vector<Statistic*> Stats; friend void llvm::PrintStatistics(); friend void llvm::PrintStatistics(raw_ostream &OS); @@ -66,12 +66,14 @@ class StatisticInfo { /// Sort statistics by debugtype,name,description. void sort(); public: - using const_iterator = std::vector<TrackingStatistic *>::const_iterator; + using const_iterator = std::vector<Statistic *>::const_iterator; StatisticInfo(); ~StatisticInfo(); - void addStatistic(TrackingStatistic *S) { Stats.push_back(S); } + void addStatistic(Statistic *S) { + Stats.push_back(S); + } const_iterator begin() const { return Stats.begin(); } const_iterator end() const { return Stats.end(); } @@ -88,7 +90,7 @@ static ManagedStatic<sys::SmartMutex<true> > StatLock; /// RegisterStatistic - The first time a statistic is bumped, this method is /// called. -void TrackingStatistic::RegisterStatistic() { +void Statistic::RegisterStatistic() { // If stats are enabled, inform StatInfo that this statistic should be // printed. // llvm_shutdown calls destructors while holding the ManagedStatic mutex. @@ -104,7 +106,7 @@ void TrackingStatistic::RegisterStatistic() { // Check Initialized again after acquiring the lock. if (Initialized.load(std::memory_order_relaxed)) return; - if (EnableStats || Enabled) + if (Stats || Enabled) SI.addStatistic(this); // Remember we have been registered. @@ -119,30 +121,29 @@ StatisticInfo::StatisticInfo() { // Print information when destroyed, iff command line option is specified. StatisticInfo::~StatisticInfo() { - if (EnableStats || PrintOnExit) + if (::Stats || PrintOnExit) llvm::PrintStatistics(); } -void llvm::EnableStatistics(bool DoPrintOnExit) { +void llvm::EnableStatistics(bool PrintOnExit) { Enabled = true; - PrintOnExit = DoPrintOnExit; + ::PrintOnExit = PrintOnExit; } bool llvm::AreStatisticsEnabled() { - return Enabled || EnableStats; + return Enabled || Stats; } void StatisticInfo::sort() { - llvm::stable_sort( - Stats, [](const TrackingStatistic *LHS, const TrackingStatistic *RHS) { - if (int Cmp = std::strcmp(LHS->getDebugType(), RHS->getDebugType())) - return Cmp < 0; + llvm::stable_sort(Stats, [](const Statistic *LHS, const Statistic *RHS) { + if (int Cmp = std::strcmp(LHS->getDebugType(), RHS->getDebugType())) + return Cmp < 0; - if (int Cmp = std::strcmp(LHS->getName(), RHS->getName())) - return Cmp < 0; + if (int Cmp = std::strcmp(LHS->getName(), RHS->getName())) + return Cmp < 0; - return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0; - }); + return std::strcmp(LHS->getDesc(), RHS->getDesc()) < 0; + }); } void StatisticInfo::reset() { @@ -206,7 +207,7 @@ void llvm::PrintStatisticsJSON(raw_ostream &OS) { // Print all of the statistics. OS << "{\n"; const char *delim = ""; - for (const TrackingStatistic *Stat : Stats.Stats) { + for (const Statistic *Stat : Stats.Stats) { OS << delim; assert(yaml::needsQuotes(Stat->getDebugType()) == yaml::QuotingType::None && "Statistic group/type name is simple."); @@ -242,7 +243,7 @@ void llvm::PrintStatistics() { // 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 (EnableStats) { + if (Stats) { // Get the stream to write to. std::unique_ptr<raw_ostream> OutStream = CreateInfoOutputFile(); (*OutStream) << "Statistics are disabled. " diff --git a/contrib/llvm-project/llvm/lib/Support/StringExtras.cpp b/contrib/llvm-project/llvm/lib/Support/StringExtras.cpp index af8dd463e125..bf28b2be5657 100644 --- a/contrib/llvm-project/llvm/lib/Support/StringExtras.cpp +++ b/contrib/llvm-project/llvm/lib/Support/StringExtras.cpp @@ -60,9 +60,7 @@ void llvm::SplitString(StringRef Source, void llvm::printEscapedString(StringRef Name, raw_ostream &Out) { for (unsigned i = 0, e = Name.size(); i != e; ++i) { unsigned char C = Name[i]; - if (C == '\\') - Out << '\\' << C; - else if (isPrint(C) && C != '"') + if (isPrint(C) && C != '\\' && C != '"') Out << C; else Out << '\\' << hexdigit(C >> 4) << hexdigit(C & 0x0F); diff --git a/contrib/llvm-project/llvm/lib/Support/StringRef.cpp b/contrib/llvm-project/llvm/lib/Support/StringRef.cpp index 104482de4ad7..4bafc4ec7181 100644 --- a/contrib/llvm-project/llvm/lib/Support/StringRef.cpp +++ b/contrib/llvm-project/llvm/lib/Support/StringRef.cpp @@ -12,7 +12,6 @@ #include "llvm/ADT/Hashing.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/edit_distance.h" -#include "llvm/Support/Error.h" #include <bitset> using namespace llvm; @@ -373,16 +372,11 @@ void StringRef::split(SmallVectorImpl<StringRef> &A, char Separator, size_t StringRef::count(StringRef Str) const { size_t Count = 0; size_t N = Str.size(); - if (!N || N > Length) + if (N > Length) return 0; - for (size_t i = 0, e = Length - N + 1; i < e;) { - if (substr(i, N).equals(Str)) { + for (size_t i = 0, e = Length - N + 1; i != e; ++i) + if (substr(i, N).equals(Str)) ++Count; - i += N; - } - else - ++i; - } return Count; } @@ -588,11 +582,8 @@ bool StringRef::getAsInteger(unsigned Radix, APInt &Result) const { bool StringRef::getAsDouble(double &Result, bool AllowInexact) const { APFloat F(0.0); - auto StatusOrErr = F.convertFromString(*this, APFloat::rmNearestTiesToEven); - if (errorToBool(StatusOrErr.takeError())) - return true; - - APFloat::opStatus Status = *StatusOrErr; + APFloat::opStatus Status = + F.convertFromString(*this, APFloat::rmNearestTiesToEven); if (Status != APFloat::opOK) { if (!AllowInexact || !(Status & APFloat::opInexact)) return true; diff --git a/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp b/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp index 84ead58b98cd..d213b9a8c6af 100644 --- a/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp +++ b/contrib/llvm-project/llvm/lib/Support/TargetParser.cpp @@ -132,7 +132,7 @@ StringRef llvm::AMDGPU::getArchNameR600(GPUKind AK) { } AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) { - for (const auto &C : AMDGCNGPUs) { + for (const auto C : AMDGCNGPUs) { if (CPU == C.Name) return C.Kind; } @@ -141,7 +141,7 @@ AMDGPU::GPUKind llvm::AMDGPU::parseArchAMDGCN(StringRef CPU) { } AMDGPU::GPUKind llvm::AMDGPU::parseArchR600(StringRef CPU) { - for (const auto &C : R600GPUs) { + for (const auto C : R600GPUs) { if (CPU == C.Name) return C.Kind; } @@ -163,12 +163,12 @@ unsigned AMDGPU::getArchAttrR600(GPUKind AK) { void AMDGPU::fillValidArchListAMDGCN(SmallVectorImpl<StringRef> &Values) { // XXX: Should this only report unique canonical names? - for (const auto &C : AMDGCNGPUs) + for (const auto C : AMDGCNGPUs) Values.push_back(C.Name); } void AMDGPU::fillValidArchListR600(SmallVectorImpl<StringRef> &Values) { - for (const auto &C : R600GPUs) + for (const auto C : R600GPUs) Values.push_back(C.Name); } diff --git a/contrib/llvm-project/llvm/lib/Support/Threading.cpp b/contrib/llvm-project/llvm/lib/Support/Threading.cpp index 48750cef5ec2..e5899a60f4db 100644 --- a/contrib/llvm-project/llvm/lib/Support/Threading.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Threading.cpp @@ -12,7 +12,6 @@ //===----------------------------------------------------------------------===// #include "llvm/Support/Threading.h" -#include "llvm/ADT/Optional.h" #include "llvm/Config/config.h" #include "llvm/Support/Host.h" @@ -40,8 +39,8 @@ bool llvm::llvm_is_multithreaded() { (!defined(_WIN32) && !defined(HAVE_PTHREAD_H)) // Support for non-Win32, non-pthread implementation. void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData, - llvm::Optional<unsigned> StackSizeInBytes) { - (void)StackSizeInBytes; + unsigned RequestedStackSize) { + (void)RequestedStackSize; Fn(UserData); } @@ -57,25 +56,6 @@ void llvm::set_thread_name(const Twine &Name) {} void llvm::get_thread_name(SmallVectorImpl<char> &Name) { Name.clear(); } -#if LLVM_ENABLE_THREADS == 0 -void llvm::llvm_execute_on_thread_async( - llvm::unique_function<void()> Func, - llvm::Optional<unsigned> StackSizeInBytes) { - (void)Func; - (void)StackSizeInBytes; - report_fatal_error("Spawning a detached thread doesn't make sense with no " - "threading support"); -} -#else -// Support for non-Win32, non-pthread implementation. -void llvm::llvm_execute_on_thread_async( - llvm::unique_function<void()> Func, - llvm::Optional<unsigned> StackSizeInBytes) { - (void)StackSizeInBytes; - std::thread(std::move(Func)).detach(); -} -#endif - #else #include <thread> @@ -104,17 +84,6 @@ unsigned llvm::hardware_concurrency() { return 1; } -namespace { -struct SyncThreadInfo { - void (*UserFn)(void *); - void *UserData; -}; - -using AsyncThreadInfo = llvm::unique_function<void()>; - -enum class JoiningPolicy { Join, Detach }; -} // namespace - // Include the platform-specific parts of this class. #ifdef LLVM_ON_UNIX #include "Unix/Threading.inc" @@ -123,20 +92,4 @@ enum class JoiningPolicy { Join, Detach }; #include "Windows/Threading.inc" #endif -void llvm::llvm_execute_on_thread(void (*Fn)(void *), void *UserData, - llvm::Optional<unsigned> StackSizeInBytes) { - - SyncThreadInfo Info = {Fn, UserData}; - llvm_execute_on_thread_impl(threadFuncSync, &Info, StackSizeInBytes, - JoiningPolicy::Join); -} - -void llvm::llvm_execute_on_thread_async( - llvm::unique_function<void()> Func, - llvm::Optional<unsigned> StackSizeInBytes) { - llvm_execute_on_thread_impl(&threadFuncAsync, - new AsyncThreadInfo(std::move(Func)), - StackSizeInBytes, JoiningPolicy::Detach); -} - #endif diff --git a/contrib/llvm-project/llvm/lib/Support/TimeProfiler.cpp b/contrib/llvm-project/llvm/lib/Support/TimeProfiler.cpp index a7c85509064e..bc2340815645 100644 --- a/contrib/llvm-project/llvm/lib/Support/TimeProfiler.cpp +++ b/contrib/llvm-project/llvm/lib/Support/TimeProfiler.cpp @@ -13,8 +13,8 @@ #include "llvm/Support/TimeProfiler.h" #include "llvm/ADT/StringMap.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileSystem.h" #include "llvm/Support/JSON.h" -#include "llvm/Support/Path.h" #include <cassert> #include <chrono> #include <string> @@ -24,67 +24,48 @@ using namespace std::chrono; namespace llvm { +static cl::opt<unsigned> TimeTraceGranularity( + "time-trace-granularity", + cl::desc( + "Minimum time granularity (in microseconds) traced by time profiler"), + cl::init(500)); + TimeTraceProfiler *TimeTraceProfilerInstance = nullptr; typedef duration<steady_clock::rep, steady_clock::period> DurationType; -typedef time_point<steady_clock> TimePointType; typedef std::pair<size_t, DurationType> CountAndDurationType; typedef std::pair<std::string, CountAndDurationType> NameAndCountAndDurationType; struct Entry { - const TimePointType Start; - TimePointType End; - const std::string Name; - const std::string Detail; - - Entry(TimePointType &&S, TimePointType &&E, std::string &&N, std::string &&Dt) - : Start(std::move(S)), End(std::move(E)), Name(std::move(N)), - Detail(std::move(Dt)) {} - - // Calculate timings for FlameGraph. Cast time points to microsecond precision - // rather than casting duration. This avoid truncation issues causing inner - // scopes overruning outer scopes. - steady_clock::rep getFlameGraphStartUs(TimePointType StartTime) const { - return (time_point_cast<microseconds>(Start) - - time_point_cast<microseconds>(StartTime)) - .count(); - } - - steady_clock::rep getFlameGraphDurUs() const { - return (time_point_cast<microseconds>(End) - - time_point_cast<microseconds>(Start)) - .count(); - } + time_point<steady_clock> Start; + DurationType Duration; + std::string Name; + std::string Detail; + + Entry(time_point<steady_clock> &&S, DurationType &&D, std::string &&N, + std::string &&Dt) + : Start(std::move(S)), Duration(std::move(D)), Name(std::move(N)), + Detail(std::move(Dt)){}; }; struct TimeTraceProfiler { - TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "") - : StartTime(steady_clock::now()), ProcName(ProcName), - TimeTraceGranularity(TimeTraceGranularity) {} + TimeTraceProfiler() { + StartTime = steady_clock::now(); + } void begin(std::string Name, llvm::function_ref<std::string()> Detail) { - Stack.emplace_back(steady_clock::now(), TimePointType(), std::move(Name), + Stack.emplace_back(steady_clock::now(), DurationType{}, std::move(Name), Detail()); } void end() { assert(!Stack.empty() && "Must call begin() first"); auto &E = Stack.back(); - E.End = steady_clock::now(); - - // Check that end times monotonically increase. - assert((Entries.empty() || - (E.getFlameGraphStartUs(StartTime) + E.getFlameGraphDurUs() >= - Entries.back().getFlameGraphStartUs(StartTime) + - Entries.back().getFlameGraphDurUs())) && - "TimeProfiler scope ended earlier than previous scope"); + E.Duration = steady_clock::now() - E.Start; - // Calculate duration at full precision for overall counts. - DurationType Duration = E.End - E.Start; - - // Only include sections longer or equal to TimeTraceGranularity msec. - if (duration_cast<microseconds>(Duration).count() >= TimeTraceGranularity) + // Only include sections longer than TimeTraceGranularity msec. + if (duration_cast<microseconds>(E.Duration).count() > TimeTraceGranularity) Entries.emplace_back(E); // Track total time taken by each "name", but only the topmost levels of @@ -97,7 +78,7 @@ struct TimeTraceProfiler { }) == Stack.rend()) { auto &CountAndTotal = CountAndTotalPerName[E.Name]; CountAndTotal.first++; - CountAndTotal.second += Duration; + CountAndTotal.second += E.Duration; } Stack.pop_back(); @@ -113,8 +94,8 @@ struct TimeTraceProfiler { // Emit all events for the main flame graph. for (const auto &E : Entries) { - auto StartUs = E.getFlameGraphStartUs(StartTime); - auto DurUs = E.getFlameGraphDurUs(); + auto StartUs = duration_cast<microseconds>(E.Start - StartTime).count(); + auto DurUs = duration_cast<microseconds>(E.Duration).count(); J.object([&]{ J.attribute("pid", 1); @@ -123,9 +104,7 @@ struct TimeTraceProfiler { J.attribute("ts", StartUs); J.attribute("dur", DurUs); J.attribute("name", E.Name); - if (!E.Detail.empty()) { - J.attributeObject("args", [&] { J.attribute("detail", E.Detail); }); - } + J.attributeObject("args", [&] { J.attribute("detail", E.Detail); }); }); } @@ -170,7 +149,7 @@ struct TimeTraceProfiler { J.attribute("ts", 0); J.attribute("ph", "M"); J.attribute("name", "process_name"); - J.attributeObject("args", [&] { J.attribute("name", ProcName); }); + J.attributeObject("args", [&] { J.attribute("name", "clang"); }); }); J.arrayEnd(); @@ -181,19 +160,13 @@ struct TimeTraceProfiler { SmallVector<Entry, 16> Stack; SmallVector<Entry, 128> Entries; StringMap<CountAndDurationType> CountAndTotalPerName; - const TimePointType StartTime; - const std::string ProcName; - - // Minimum time granularity (in microseconds) - const unsigned TimeTraceGranularity; + time_point<steady_clock> StartTime; }; -void timeTraceProfilerInitialize(unsigned TimeTraceGranularity, - StringRef ProcName) { +void timeTraceProfilerInitialize() { assert(TimeTraceProfilerInstance == nullptr && "Profiler should not be initialized"); - TimeTraceProfilerInstance = new TimeTraceProfiler( - TimeTraceGranularity, llvm::sys::path::filename(ProcName)); + TimeTraceProfilerInstance = new TimeTraceProfiler(); } void timeTraceProfilerCleanup() { diff --git a/contrib/llvm-project/llvm/lib/Support/Timer.cpp b/contrib/llvm-project/llvm/lib/Support/Timer.cpp index 613d2eaae6d3..2a7ff1eaaf63 100644 --- a/contrib/llvm-project/llvm/lib/Support/Timer.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Timer.cpp @@ -58,23 +58,23 @@ namespace { std::unique_ptr<raw_fd_ostream> llvm::CreateInfoOutputFile() { const std::string &OutputFilename = getLibSupportInfoOutputFilename(); if (OutputFilename.empty()) - return std::make_unique<raw_fd_ostream>(2, false); // stderr. + return llvm::make_unique<raw_fd_ostream>(2, false); // stderr. if (OutputFilename == "-") - return std::make_unique<raw_fd_ostream>(1, false); // stdout. + return llvm::make_unique<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; - auto Result = std::make_unique<raw_fd_ostream>( - OutputFilename, EC, sys::fs::OF_Append | sys::fs::OF_Text); + auto Result = llvm::make_unique<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"; - return std::make_unique<raw_fd_ostream>(2, false); // stderr. + return llvm::make_unique<raw_fd_ostream>(2, false); // stderr. } namespace { @@ -91,15 +91,14 @@ static TimerGroup *getDefaultTimerGroup() { return &*DefaultTimerGroup; } // Timer Implementation //===----------------------------------------------------------------------===// -void Timer::init(StringRef TimerName, StringRef TimerDescription) { - init(TimerName, TimerDescription, *getDefaultTimerGroup()); +void Timer::init(StringRef Name, StringRef Description) { + init(Name, Description, *getDefaultTimerGroup()); } -void Timer::init(StringRef TimerName, StringRef TimerDescription, - TimerGroup &tg) { +void Timer::init(StringRef Name, StringRef Description, TimerGroup &tg) { assert(!TG && "Timer already initialized"); - Name.assign(TimerName.begin(), TimerName.end()); - Description.assign(TimerDescription.begin(), TimerDescription.end()); + this->Name.assign(Name.begin(), Name.end()); + this->Description.assign(Description.begin(), Description.end()); Running = Triggered = false; TG = &tg; TG->addTimer(*this); diff --git a/contrib/llvm-project/llvm/lib/Support/Triple.cpp b/contrib/llvm-project/llvm/lib/Support/Triple.cpp index 2c480c1094a5..18b013e1df3f 100644 --- a/contrib/llvm-project/llvm/lib/Support/Triple.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Triple.cpp @@ -21,56 +21,55 @@ StringRef Triple::getArchTypeName(ArchType Kind) { case UnknownArch: return "unknown"; case aarch64: return "aarch64"; - case aarch64_32: return "aarch64_32"; case aarch64_be: return "aarch64_be"; - case amdgcn: return "amdgcn"; - case amdil64: return "amdil64"; - case amdil: return "amdil"; - case arc: return "arc"; + case aarch64_32: return "aarch64_32"; case arm: return "arm"; case armeb: return "armeb"; + case arc: return "arc"; case avr: return "avr"; - case bpfeb: return "bpfeb"; case bpfel: return "bpfel"; + case bpfeb: return "bpfeb"; case hexagon: return "hexagon"; - case hsail64: return "hsail64"; - case hsail: return "hsail"; - case kalimba: return "kalimba"; - case lanai: return "lanai"; - case le32: return "le32"; - case le64: return "le64"; - case mips64: return "mips64"; - case mips64el: return "mips64el"; case mips: return "mips"; case mipsel: return "mipsel"; + case mips64: return "mips64"; + case mips64el: return "mips64el"; case msp430: return "msp430"; - case nvptx64: return "nvptx64"; - case nvptx: return "nvptx"; case ppc64: return "powerpc64"; case ppc64le: return "powerpc64le"; case ppc: return "powerpc"; case r600: return "r600"; - case renderscript32: return "renderscript32"; - case renderscript64: return "renderscript64"; + case amdgcn: return "amdgcn"; case riscv32: return "riscv32"; case riscv64: return "riscv64"; - case shave: return "shave"; case sparc: return "sparc"; - case sparcel: return "sparcel"; case sparcv9: return "sparcv9"; - case spir64: return "spir64"; - case spir: return "spir"; + case sparcel: return "sparcel"; case systemz: return "s390x"; case tce: return "tce"; case tcele: return "tcele"; case thumb: return "thumb"; case thumbeb: return "thumbeb"; - case ve: return "ve"; - case wasm32: return "wasm32"; - case wasm64: return "wasm64"; 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 lanai: return "lanai"; + case shave: return "shave"; + case wasm32: return "wasm32"; + case wasm64: return "wasm64"; + case renderscript32: return "renderscript32"; + case renderscript64: return "renderscript64"; } llvm_unreachable("Invalid ArchType!"); @@ -145,8 +144,6 @@ StringRef Triple::getArchTypePrefix(ArchType Kind) { case riscv32: case riscv64: return "riscv"; - - case ve: return "ve"; } } @@ -154,22 +151,22 @@ StringRef Triple::getVendorTypeName(VendorType Kind) { switch (Kind) { case UnknownVendor: return "unknown"; - case AMD: return "amd"; case Apple: return "apple"; + case PC: return "pc"; + case SCEI: return "scei"; case BGP: return "bgp"; case BGQ: return "bgq"; - case CSR: return "csr"; case Freescale: return "fsl"; case IBM: return "ibm"; case ImaginationTechnologies: return "img"; - case Mesa: return "mesa"; case MipsTechnologies: return "mti"; - case Myriad: return "myriad"; case NVIDIA: return "nvidia"; - case OpenEmbedded: return "oe"; - case PC: return "pc"; - case SCEI: return "scei"; + case CSR: return "csr"; + case Myriad: return "myriad"; + case AMD: return "amd"; + case Mesa: return "mesa"; case SUSE: return "suse"; + case OpenEmbedded: return "oe"; } llvm_unreachable("Invalid VendorType!"); @@ -179,41 +176,41 @@ StringRef Triple::getOSTypeName(OSType Kind) { switch (Kind) { case UnknownOS: return "unknown"; - case AIX: return "aix"; - case AMDHSA: return "amdhsa"; - case AMDPAL: return "amdpal"; case Ananas: return "ananas"; - case CNK: return "cnk"; - case CUDA: return "cuda"; case CloudABI: return "cloudabi"; - case Contiki: return "contiki"; case Darwin: return "darwin"; case DragonFly: return "dragonfly"; - case ELFIAMCU: return "elfiamcu"; - case Emscripten: return "emscripten"; case FreeBSD: return "freebsd"; case Fuchsia: return "fuchsia"; - case Haiku: return "haiku"; - case HermitCore: return "hermit"; - case Hurd: return "hurd"; case IOS: return "ios"; case KFreeBSD: return "kfreebsd"; case Linux: return "linux"; case Lv2: return "lv2"; case MacOSX: return "macosx"; - case Mesa3D: return "mesa3d"; - case Minix: return "minix"; - case NVCL: return "nvcl"; - case NaCl: return "nacl"; case NetBSD: return "netbsd"; case OpenBSD: return "openbsd"; - case PS4: return "ps4"; - case RTEMS: return "rtems"; 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 AIX: return "aix"; + case CUDA: return "cuda"; + case NVCL: return "nvcl"; + case AMDHSA: return "amdhsa"; + case PS4: return "ps4"; + case ELFIAMCU: return "elfiamcu"; case TvOS: return "tvos"; - case WASI: return "wasi"; case WatchOS: return "watchos"; - case Win32: return "windows"; + case Mesa3D: return "mesa3d"; + case Contiki: return "contiki"; + case AMDPAL: return "amdpal"; + case HermitCore: return "hermit"; + case Hurd: return "hurd"; + case WASI: return "wasi"; + case Emscripten: return "emscripten"; } llvm_unreachable("Invalid OSType"); @@ -222,25 +219,27 @@ StringRef Triple::getOSTypeName(OSType Kind) { StringRef Triple::getEnvironmentTypeName(EnvironmentType Kind) { switch (Kind) { case UnknownEnvironment: return "unknown"; - case Android: return "android"; - case CODE16: return "code16"; - case CoreCLR: return "coreclr"; - case Cygnus: return "cygnus"; - case EABI: return "eabi"; - case EABIHF: return "eabihf"; case GNU: return "gnu"; - case GNUABI64: return "gnuabi64"; case GNUABIN32: return "gnuabin32"; - case GNUEABI: return "gnueabi"; + case GNUABI64: return "gnuabi64"; case GNUEABIHF: return "gnueabihf"; + case GNUEABI: return "gnueabi"; case GNUX32: return "gnux32"; - case Itanium: return "itanium"; - case MSVC: return "msvc"; - case MacABI: return "macabi"; + case CODE16: return "code16"; + case EABI: return "eabi"; + case EABIHF: return "eabihf"; + case ELFv1: return "elfv1"; + case ELFv2: return "elfv2"; + case Android: return "android"; case Musl: return "musl"; case MuslEABI: return "musleabi"; case MuslEABIHF: return "musleabihf"; + case MSVC: return "msvc"; + case Itanium: return "itanium"; + case Cygnus: return "cygnus"; + case CoreCLR: return "coreclr"; case Simulator: return "simulator"; + case MacABI: return "macabi"; } llvm_unreachable("Invalid EnvironmentType!"); @@ -316,7 +315,6 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) { .Case("wasm64", wasm64) .Case("renderscript32", renderscript32) .Case("renderscript64", renderscript64) - .Case("ve", ve) .Default(UnknownArch); } @@ -440,12 +438,11 @@ static Triple::ArchType parseArch(StringRef ArchName) { .Case("spir64", Triple::spir64) .StartsWith("kalimba", Triple::kalimba) .Case("lanai", Triple::lanai) - .Case("renderscript32", Triple::renderscript32) - .Case("renderscript64", Triple::renderscript64) .Case("shave", Triple::shave) - .Case("ve", Triple::ve) .Case("wasm32", Triple::wasm32) .Case("wasm64", Triple::wasm64) + .Case("renderscript32", Triple::renderscript32) + .Case("renderscript64", Triple::renderscript64) .Default(Triple::UnknownArch); // Some architectures require special parsing logic just to compute the @@ -527,6 +524,8 @@ static Triple::EnvironmentType parseEnvironment(StringRef EnvironmentName) { return StringSwitch<Triple::EnvironmentType>(EnvironmentName) .StartsWith("eabihf", Triple::EABIHF) .StartsWith("eabi", Triple::EABI) + .StartsWith("elfv1", Triple::ELFv1) + .StartsWith("elfv2", Triple::ELFv2) .StartsWith("gnuabin32", Triple::GNUABIN32) .StartsWith("gnuabi64", Triple::GNUABI64) .StartsWith("gnueabihf", Triple::GNUEABIHF) @@ -641,10 +640,10 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) { static StringRef getObjectFormatTypeName(Triple::ObjectFormatType Kind) { switch (Kind) { case Triple::UnknownObjectFormat: return ""; - case Triple::COFF: return "coff"; - case Triple::ELF: return "elf"; + case Triple::COFF: return "coff"; + case Triple::ELF: return "elf"; case Triple::MachO: return "macho"; - case Triple::Wasm: return "wasm"; + case Triple::Wasm: return "wasm"; case Triple::XCOFF: return "xcoff"; } llvm_unreachable("unknown object format type"); @@ -666,28 +665,28 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { return Triple::ELF; case Triple::aarch64_be: + case Triple::arc: case Triple::amdgcn: - case Triple::amdil64: case Triple::amdil: - case Triple::arc: + case Triple::amdil64: case Triple::armeb: case Triple::avr: case Triple::bpfeb: case Triple::bpfel: case Triple::hexagon: - case Triple::hsail64: + case Triple::lanai: case Triple::hsail: + case Triple::hsail64: case Triple::kalimba: - case Triple::lanai: case Triple::le32: case Triple::le64: + case Triple::mips: case Triple::mips64: case Triple::mips64el: - case Triple::mips: case Triple::mipsel: case Triple::msp430: - case Triple::nvptx64: case Triple::nvptx: + case Triple::nvptx64: case Triple::ppc64le: case Triple::r600: case Triple::renderscript32: @@ -698,18 +697,17 @@ static Triple::ObjectFormatType getDefaultFormat(const Triple &T) { case Triple::sparc: case Triple::sparcel: case Triple::sparcv9: - case Triple::spir64: case Triple::spir: + case Triple::spir64: case Triple::systemz: case Triple::tce: case Triple::tcele: case Triple::thumbeb: - case Triple::ve: case Triple::xcore: return Triple::ELF; - case Triple::ppc64: case Triple::ppc: + case Triple::ppc64: if (T.isOSDarwin()) return Triple::MachO; else if (T.isOSAIX()) @@ -1240,56 +1238,55 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) { return 16; case llvm::Triple::aarch64_32: - case llvm::Triple::amdil: case llvm::Triple::arc: case llvm::Triple::arm: case llvm::Triple::armeb: case llvm::Triple::hexagon: - case llvm::Triple::hsail: - case llvm::Triple::kalimba: - case llvm::Triple::lanai: 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::renderscript32: case llvm::Triple::riscv32: - case llvm::Triple::shave: case llvm::Triple::sparc: case llvm::Triple::sparcel: - case llvm::Triple::spir: case llvm::Triple::tce: case llvm::Triple::tcele: case llvm::Triple::thumb: case llvm::Triple::thumbeb: - case llvm::Triple::wasm32: 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::lanai: + case llvm::Triple::shave: + case llvm::Triple::wasm32: + case llvm::Triple::renderscript32: return 32; case llvm::Triple::aarch64: case llvm::Triple::aarch64_be: case llvm::Triple::amdgcn: - case llvm::Triple::amdil64: - case llvm::Triple::bpfeb: case llvm::Triple::bpfel: - case llvm::Triple::hsail64: + 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::renderscript64: case llvm::Triple::riscv64: case llvm::Triple::sparcv9: - case llvm::Triple::spir64: case llvm::Triple::systemz: - case llvm::Triple::ve: - case llvm::Triple::wasm64: case llvm::Triple::x86_64: + case llvm::Triple::amdil64: + case llvm::Triple::hsail64: + case llvm::Triple::spir64: + case llvm::Triple::wasm64: + case llvm::Triple::renderscript64: return 64; } llvm_unreachable("Invalid architecture value"); @@ -1313,61 +1310,60 @@ Triple Triple::get32BitArchVariant() const { case Triple::UnknownArch: case Triple::amdgcn: case Triple::avr: - case Triple::bpfeb: case Triple::bpfel: + case Triple::bpfeb: case Triple::msp430: - case Triple::ppc64le: case Triple::systemz: - case Triple::ve: + case Triple::ppc64le: T.setArch(UnknownArch); break; case Triple::aarch64_32: case Triple::amdil: + case Triple::hsail: + case Triple::spir: case Triple::arc: case Triple::arm: case Triple::armeb: case Triple::hexagon: - case Triple::hsail: case Triple::kalimba: - case Triple::lanai: case Triple::le32: case Triple::mips: case Triple::mipsel: case Triple::nvptx: case Triple::ppc: case Triple::r600: - case Triple::renderscript32: case Triple::riscv32: - case Triple::shave: case Triple::sparc: case Triple::sparcel: - case Triple::spir: case Triple::tce: case Triple::tcele: case Triple::thumb: case Triple::thumbeb: - case Triple::wasm32: case Triple::x86: case Triple::xcore: + case Triple::lanai: + case Triple::shave: + case Triple::wasm32: + case Triple::renderscript32: // Already 32-bit. break; case Triple::aarch64: T.setArch(Triple::arm); break; case Triple::aarch64_be: T.setArch(Triple::armeb); break; - case Triple::amdil64: T.setArch(Triple::amdil); break; - case Triple::hsail64: T.setArch(Triple::hsail); 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::renderscript64: T.setArch(Triple::renderscript32); break; - case Triple::riscv64: T.setArch(Triple::riscv32); break; case Triple::sparcv9: T.setArch(Triple::sparc); break; + case Triple::riscv64: T.setArch(Triple::riscv32); 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; case Triple::wasm64: T.setArch(Triple::wasm32); break; - case Triple::x86_64: T.setArch(Triple::x86); break; + case Triple::renderscript64: T.setArch(Triple::renderscript32); break; } return T; } @@ -1383,56 +1379,55 @@ Triple Triple::get64BitArchVariant() const { case Triple::lanai: case Triple::msp430: case Triple::r600: - case Triple::shave: - case Triple::sparcel: case Triple::tce: case Triple::tcele: case Triple::xcore: + case Triple::sparcel: + case Triple::shave: T.setArch(UnknownArch); break; case Triple::aarch64: case Triple::aarch64_be: - case Triple::amdgcn: - case Triple::amdil64: - case Triple::bpfeb: case Triple::bpfel: - case Triple::hsail64: + 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::renderscript64: case Triple::riscv64: case Triple::sparcv9: - case Triple::spir64: case Triple::systemz: - case Triple::ve: - case Triple::wasm64: case Triple::x86_64: + case Triple::wasm64: + case Triple::renderscript64: // Already 64-bit. break; case Triple::aarch64_32: T.setArch(Triple::aarch64); break; - case Triple::amdil: T.setArch(Triple::amdil64); break; case Triple::arm: T.setArch(Triple::aarch64); break; case Triple::armeb: T.setArch(Triple::aarch64_be); break; - case Triple::hsail: T.setArch(Triple::hsail64); 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::renderscript32: T.setArch(Triple::renderscript64); break; - case Triple::riscv32: T.setArch(Triple::riscv64); break; case Triple::sparc: T.setArch(Triple::sparcv9); break; + case Triple::riscv32: T.setArch(Triple::riscv64); 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; case Triple::thumb: T.setArch(Triple::aarch64); break; case Triple::thumbeb: T.setArch(Triple::aarch64_be); break; case Triple::wasm32: T.setArch(Triple::wasm64); break; - case Triple::x86: T.setArch(Triple::x86_64); break; + case Triple::renderscript32: T.setArch(Triple::renderscript64); break; } return T; } @@ -1458,8 +1453,6 @@ Triple Triple::getBigEndianArchVariant() const { case Triple::nvptx64: case Triple::nvptx: case Triple::r600: - case Triple::renderscript32: - case Triple::renderscript64: case Triple::riscv32: case Triple::riscv64: case Triple::shave: @@ -1470,7 +1463,8 @@ Triple Triple::getBigEndianArchVariant() const { case Triple::x86: case Triple::x86_64: case Triple::xcore: - case Triple::ve: + case Triple::renderscript32: + case Triple::renderscript64: // ARM is intentionally unsupported here, changing the architecture would // drop any arch suffixes. @@ -1479,13 +1473,13 @@ Triple Triple::getBigEndianArchVariant() const { T.setArch(UnknownArch); break; + case Triple::tcele: T.setArch(Triple::tce); break; case Triple::aarch64: T.setArch(Triple::aarch64_be); break; case Triple::bpfel: T.setArch(Triple::bpfeb); break; case Triple::mips64el:T.setArch(Triple::mips64); break; case Triple::mipsel: T.setArch(Triple::mips); break; case Triple::ppc64le: T.setArch(Triple::ppc64); break; case Triple::sparcel: T.setArch(Triple::sparc); break; - case Triple::tcele: T.setArch(Triple::tce); break; default: llvm_unreachable("getBigEndianArchVariant: unknown triple."); } @@ -1511,13 +1505,13 @@ Triple Triple::getLittleEndianArchVariant() const { T.setArch(UnknownArch); break; + case Triple::tce: T.setArch(Triple::tcele); break; case Triple::aarch64_be: T.setArch(Triple::aarch64); break; case Triple::bpfeb: T.setArch(Triple::bpfel); break; case Triple::mips64: T.setArch(Triple::mips64el); break; case Triple::mips: T.setArch(Triple::mipsel); break; case Triple::ppc64: T.setArch(Triple::ppc64le); break; case Triple::sparc: T.setArch(Triple::sparcel); break; - case Triple::tce: T.setArch(Triple::tcele); break; default: llvm_unreachable("getLittleEndianArchVariant: unknown triple."); } @@ -1547,22 +1541,21 @@ bool Triple::isLittleEndian() const { case Triple::nvptx: case Triple::ppc64le: case Triple::r600: - case Triple::renderscript32: - case Triple::renderscript64: case Triple::riscv32: case Triple::riscv64: case Triple::shave: case Triple::sparcel: case Triple::spir64: case Triple::spir: - case Triple::tcele: case Triple::thumb: - case Triple::ve: case Triple::wasm32: case Triple::wasm64: case Triple::x86: case Triple::x86_64: case Triple::xcore: + case Triple::tcele: + case Triple::renderscript32: + case Triple::renderscript64: return true; default: return false; @@ -1617,10 +1610,10 @@ StringRef Triple::getARMCPUForArch(StringRef MArch) const { case llvm::Triple::Win32: // FIXME: this is invalid for WindowsCE return "cortex-a9"; - case llvm::Triple::IOS: case llvm::Triple::MacOSX: - case llvm::Triple::TvOS: + case llvm::Triple::IOS: case llvm::Triple::WatchOS: + case llvm::Triple::TvOS: if (MArch == "v7k") return "cortex-a7"; break; @@ -1640,10 +1633,10 @@ StringRef Triple::getARMCPUForArch(StringRef MArch) const { switch (getOS()) { case llvm::Triple::NetBSD: switch (getEnvironment()) { - case llvm::Triple::EABI: - case llvm::Triple::EABIHF: - case llvm::Triple::GNUEABI: case llvm::Triple::GNUEABIHF: + case llvm::Triple::GNUEABI: + case llvm::Triple::EABIHF: + case llvm::Triple::EABI: return "arm926ej-s"; default: return "strongarm"; diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc index 79b1759359e1..a0927da50e48 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Memory.inc @@ -42,7 +42,9 @@ extern "C" void sys_icache_invalidate(const void *Addr, size_t len); extern "C" void __clear_cache(void *, void*); #endif -static int getPosixProtectionFlags(unsigned Flags) { +namespace { + +int getPosixProtectionFlags(unsigned Flags) { switch (Flags & llvm::sys::Memory::MF_RWE_MASK) { case llvm::sys::Memory::MF_READ: return PROT_READ; @@ -74,6 +76,8 @@ static int getPosixProtectionFlags(unsigned Flags) { return PROT_NONE; } +} // anonymous namespace + namespace llvm { namespace sys { @@ -172,7 +176,7 @@ Memory::releaseMappedMemory(MemoryBlock &M) { std::error_code Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { - static const Align PageSize = Align(Process::getPageSizeEstimate()); + static const size_t PageSize = Process::getPageSizeEstimate(); if (M.Address == nullptr || M.AllocatedSize == 0) return std::error_code(); @@ -180,8 +184,8 @@ Memory::protectMappedMemory(const MemoryBlock &M, unsigned Flags) { return std::error_code(EINVAL, std::generic_category()); int Protect = getPosixProtectionFlags(Flags); - uintptr_t Start = alignAddr((const uint8_t *)M.Address - PageSize.value() + 1, PageSize); - uintptr_t End = alignAddr((const uint8_t *)M.Address + M.AllocatedSize, PageSize); + uintptr_t Start = alignAddr((uint8_t *)M.Address - PageSize + 1, PageSize); + uintptr_t End = alignAddr((uint8_t *)M.Address + M.AllocatedSize, PageSize); bool InvalidateCache = (Flags & MF_EXEC); diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc new file mode 100644 index 000000000000..2c982b38d6ff --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Mutex.inc @@ -0,0 +1,42 @@ +//===- llvm/Support/Unix/Mutex.inc - Unix Mutex Implementation ---*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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-project/llvm/lib/Support/Unix/Path.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc index 2a03dc682bce..a64ef8a6da3a 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Path.inc @@ -201,8 +201,8 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { if (elf_aux_info(AT_EXECPATH, exe_path, sizeof(exe_path)) == 0) return exe_path; #else - // elf_aux_info(AT_EXECPATH, ... is not available in all supported versions, - // fall back to finding the ELF auxiliary vectors after the process's + // elf_aux_info(AT_EXECPATH, ... is not available on older FreeBSD. Fall + // back to finding the ELF auxiliary vectors after the processes's // environment. char **p = ::environ; while (*p++ != 0) @@ -221,12 +221,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { // Fall back to argv[0] if auxiliary vectors are not available. if (getprogpath(exe_path, argv0) != NULL) return exe_path; -#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__minix) || \ +#elif defined(__NetBSD__) || defined(__OpenBSD__) || defined(__minix) || \ defined(__DragonFly__) || defined(__FreeBSD_kernel__) || defined(_AIX) - const char *curproc = "/proc/curproc/file"; + StringRef curproc("/proc/curproc/file"); char exe_path[PATH_MAX]; if (sys::fs::exists(curproc)) { - ssize_t len = readlink(curproc, exe_path, sizeof(exe_path)); + ssize_t len = readlink(curproc.str().c_str(), exe_path, sizeof(exe_path)); if (len > 0) { // Null terminate the string for realpath. readlink never null // terminates its output. @@ -238,12 +238,12 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) { // If we don't have procfs mounted, fall back to argv[0] if (getprogpath(exe_path, argv0) != NULL) return exe_path; -#elif defined(__linux__) || defined(__CYGWIN__) || defined(__gnu_hurd__) +#elif defined(__linux__) || defined(__CYGWIN__) char exe_path[MAXPATHLEN]; - const char *aPath = "/proc/self/exe"; + 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, exe_path, sizeof(exe_path)); + ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path)); if (len < 0) return ""; @@ -478,7 +478,7 @@ static bool is_local_impl(struct STATVFS &Vfs) { std::unique_ptr<char[]> Buf; int Tries = 3; while (Tries--) { - Buf = std::make_unique<char[]>(BufSize); + Buf = llvm::make_unique<char[]>(BufSize); Ret = mntctl(MCTL_QUERY, BufSize, Buf.get()); if (Ret != 0) break; @@ -868,10 +868,7 @@ std::error_code detail::directory_iterator_destruct(detail::DirIterState &it) { static file_type direntType(dirent* Entry) { // Most platforms provide the file type in the dirent: Linux/BSD/Mac. // The DTTOIF macro lets us reuse our status -> type conversion. - // Note that while glibc provides a macro to see if this is supported, - // _DIRENT_HAVE_D_TYPE, it's not defined on BSD/Mac, so we test for the - // d_type-to-mode_t conversion macro instead. -#if defined(DTTOIF) +#if defined(_DIRENT_HAVE_D_TYPE) && defined(DTTOIF) return typeForMode(DTTOIF(Entry->d_type)); #else // Other platforms such as Solaris require a stat() to get the type. @@ -922,9 +919,9 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, else if (Access == (FA_Read | FA_Write)) Result |= O_RDWR; - // This is for compatibility with old code that assumed OF_Append implied + // This is for compatibility with old code that assumed F_Append implied // would open an existing file. See Windows/Path.inc for a longer comment. - if (Flags & OF_Append) + if (Flags & F_Append) Disp = CD_OpenAlways; if (Disp == CD_CreateNew) { @@ -939,7 +936,7 @@ static int nativeOpenFlags(CreationDisposition Disp, OpenFlags Flags, // Nothing special, just don't add O_CREAT and we get these semantics. } - if (Flags & OF_Append) + if (Flags & F_Append) Result |= O_APPEND; #ifdef O_CLOEXEC @@ -1034,28 +1031,44 @@ file_t getStdinHandle() { return 0; } file_t getStdoutHandle() { return 1; } file_t getStderrHandle() { return 2; } -Expected<size_t> readNativeFile(file_t FD, MutableArrayRef<char> Buf) { - ssize_t NumRead = - sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); - if (ssize_t(NumRead) == -1) - return errorCodeToError(std::error_code(errno, std::generic_category())); - return NumRead; +std::error_code readNativeFile(file_t FD, MutableArrayRef<char> Buf, + size_t *BytesRead) { + *BytesRead = sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); + if (ssize_t(*BytesRead) == -1) + return std::error_code(errno, std::generic_category()); + return std::error_code(); } -Expected<size_t> readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf, - uint64_t Offset) { +std::error_code readNativeFileSlice(file_t FD, MutableArrayRef<char> Buf, + size_t Offset) { + char *BufPtr = Buf.data(); + size_t BytesLeft = Buf.size(); + +#ifndef HAVE_PREAD + // If we don't have pread, seek to Offset. + if (lseek(FD, Offset, SEEK_SET) == -1) + return std::error_code(errno, std::generic_category()); +#endif + + while (BytesLeft) { #ifdef HAVE_PREAD - ssize_t NumRead = - sys::RetryAfterSignal(-1, ::pread, FD, Buf.data(), Buf.size(), Offset); + ssize_t NumRead = sys::RetryAfterSignal(-1, ::pread, FD, BufPtr, BytesLeft, + Buf.size() - BytesLeft + Offset); #else - if (lseek(FD, Offset, SEEK_SET) == -1) - return errorCodeToError(std::error_code(errno, std::generic_category())); - ssize_t NumRead = - sys::RetryAfterSignal(-1, ::read, FD, Buf.data(), Buf.size()); + ssize_t NumRead = sys::RetryAfterSignal(-1, ::read, FD, BufPtr, BytesLeft); #endif - if (NumRead == -1) - return errorCodeToError(std::error_code(errno, std::generic_category())); - return NumRead; + if (NumRead == -1) { + // 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::error_code(); } std::error_code closeFile(file_t &F) { diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc index dfe81d7e2833..4115ee396582 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Process.inc @@ -15,7 +15,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/Config/config.h" #include "llvm/Support/ManagedStatic.h" -#include <mutex> +#include "llvm/Support/Mutex.h" +#include "llvm/Support/MutexGuard.h" #if HAVE_FCNTL_H #include <fcntl.h> #endif @@ -326,13 +327,13 @@ extern "C" int tigetnum(char *capname); #endif #ifdef HAVE_TERMINFO -static ManagedStatic<std::mutex> TermColorMutex; +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. - std::lock_guard<std::mutex> G(*TermColorMutex); + MutexGuard G(*TermColorMutex); int errret = 0; if (setupterm(nullptr, fd, &errret) != 0) diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc index 520685a0e987..c4123a64046f 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Program.inc @@ -136,7 +136,7 @@ static bool RedirectIO_PS(const std::string *Path, int FD, std::string *ErrMsg, if (int Err = posix_spawn_file_actions_addopen( FileActions, FD, File, FD == 0 ? O_RDONLY : O_WRONLY | O_CREAT, 0666)) - return MakeErrMsg(ErrMsg, "Cannot posix_spawn_file_actions_addopen", Err); + return MakeErrMsg(ErrMsg, "Cannot dup2", Err); return false; } #endif @@ -444,7 +444,7 @@ 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::OF_Text); + llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::OpenFlags::F_Text); if (EC) return EC; diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc b/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc new file mode 100644 index 000000000000..8b47dfa0f85c --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Unix/RWMutex.inc @@ -0,0 +1,50 @@ +//= llvm/Support/Unix/RWMutex.inc - Unix Reader/Writer Mutual Exclusion Lock =// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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-project/llvm/lib/Support/Unix/Signals.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc index f68374d29f02..634c16aa36c7 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Signals.inc @@ -43,6 +43,7 @@ #include "llvm/Support/Mutex.h" #include "llvm/Support/Program.h" #include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/UniqueLock.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <string> @@ -88,9 +89,6 @@ static std::atomic<SignalHandlerFunctionType> InterruptFunction = ATOMIC_VAR_INIT(nullptr); static std::atomic<SignalHandlerFunctionType> InfoSignalFunction = ATOMIC_VAR_INIT(nullptr); -/// The function to call on SIGPIPE (one-time use only). -static std::atomic<SignalHandlerFunctionType> OneShotPipeSignalFunction = - ATOMIC_VAR_INIT(nullptr); namespace { /// Signal-safe removal of files. @@ -209,7 +207,7 @@ static StringRef Argv0; /// 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, SIGTERM, SIGUSR2 + SIGHUP, SIGINT, SIGPIPE, SIGTERM, SIGUSR2 }; /// Signals that represent that we have a bug, and our prompt termination has @@ -240,7 +238,7 @@ static const int InfoSigs[] = { static const size_t NumSigs = array_lengthof(IntSigs) + array_lengthof(KillSigs) + - array_lengthof(InfoSigs) + 1 /* SIGPIPE */; + array_lengthof(InfoSigs); static std::atomic<unsigned> NumRegisteredSignals = ATOMIC_VAR_INIT(0); @@ -325,8 +323,6 @@ static void RegisterHandlers() { // Not signal-safe. registerHandler(S, SignalKind::IsKill); for (auto S : KillSigs) registerHandler(S, SignalKind::IsKill); - if (OneShotPipeSignalFunction) - registerHandler(SIGPIPE, SignalKind::IsKill); for (auto S : InfoSigs) registerHandler(S, SignalKind::IsInfo); } @@ -345,22 +341,6 @@ static void RemoveFilesToRemove() { FileToRemoveList::removeAllFiles(FilesToRemove); } -void sys::CleanupOnSignal(uintptr_t Context) { - int Sig = (int)Context; - - if (llvm::is_contained(InfoSigs, Sig)) { - InfoSignalHandler(Sig); - return; - } - - RemoveFilesToRemove(); - - if (llvm::is_contained(IntSigs, Sig) || Sig == SIGPIPE) - return; - - llvm::sys::RunSignalHandlers(); -} - // The signal handler that runs. static RETSIGTYPE SignalHandler(int Sig) { // Restore the signal behavior to default, so that the program actually @@ -377,16 +357,15 @@ static RETSIGTYPE SignalHandler(int Sig) { { RemoveFilesToRemove(); - if (Sig == SIGPIPE) - if (auto OldOneShotPipeFunction = - OneShotPipeSignalFunction.exchange(nullptr)) - return OldOneShotPipeFunction(); - if (std::find(std::begin(IntSigs), std::end(IntSigs), Sig) != std::end(IntSigs)) { if (auto OldInterruptFunction = InterruptFunction.exchange(nullptr)) return OldInterruptFunction(); + // Send a special return code that drivers can check for, from sysexits.h. + if (Sig == SIGPIPE) + exit(EX_IOERR); + raise(Sig); // Execute the default handler. return; } @@ -425,16 +404,6 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) { RegisterHandlers(); } -void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { - OneShotPipeSignalFunction.exchange(Handler); - RegisterHandlers(); -} - -void llvm::sys::DefaultOneShotPipeSignalHandler() { - // Send a special return code that drivers can check for, from sysexits.h. - exit(EX_IOERR); -} - // The public API bool llvm::sys::RemoveFileOnSignal(StringRef Filename, std::string* ErrMsg) { diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc index afb887fc1096..ed9a96563055 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Threading.inc @@ -10,8 +10,6 @@ // //===----------------------------------------------------------------------===// -#include "Unix.h" -#include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/Twine.h" @@ -42,56 +40,47 @@ #include <unistd.h> // For syscall() #endif -static void *threadFuncSync(void *Arg) { - SyncThreadInfo *TI = static_cast<SyncThreadInfo *>(Arg); - TI->UserFn(TI->UserData); - return nullptr; +namespace { + struct ThreadInfo { + void(*UserFn)(void *); + void *UserData; + }; } -static void *threadFuncAsync(void *Arg) { - std::unique_ptr<AsyncThreadInfo> Info(static_cast<AsyncThreadInfo *>(Arg)); - (*Info)(); +static void *ExecuteOnThread_Dispatch(void *Arg) { + ThreadInfo *TI = reinterpret_cast<ThreadInfo*>(Arg); + TI->UserFn(TI->UserData); return nullptr; } -static void -llvm_execute_on_thread_impl(void *(*ThreadFunc)(void *), void *Arg, - llvm::Optional<unsigned> StackSizeInBytes, - JoiningPolicy JP) { - int errnum; - - // Construct the attributes object. +void llvm::llvm_execute_on_thread(void(*Fn)(void*), void *UserData, + unsigned RequestedStackSize) { + ThreadInfo Info = { Fn, UserData }; pthread_attr_t Attr; - if ((errnum = ::pthread_attr_init(&Attr)) != 0) { - ReportErrnumFatal("pthread_attr_init failed", errnum); - } + pthread_t Thread; - auto AttrGuard = llvm::make_scope_exit([&] { - if ((errnum = ::pthread_attr_destroy(&Attr)) != 0) { - ReportErrnumFatal("pthread_attr_destroy failed", errnum); - } - }); + // Construct the attributes object. + if (::pthread_attr_init(&Attr) != 0) + return; // Set the requested stack size, if given. - if (StackSizeInBytes) { - if ((errnum = ::pthread_attr_setstacksize(&Attr, *StackSizeInBytes)) != 0) { - ReportErrnumFatal("pthread_attr_setstacksize failed", errnum); - } + if (RequestedStackSize != 0) { + if (::pthread_attr_setstacksize(&Attr, RequestedStackSize) != 0) + goto error; } // Construct and execute the thread. - pthread_t Thread; - if ((errnum = ::pthread_create(&Thread, &Attr, ThreadFunc, Arg)) != 0) - ReportErrnumFatal("pthread_create failed", errnum); + if (::pthread_create(&Thread, &Attr, ExecuteOnThread_Dispatch, &Info) != 0) + goto error; - if (JP == JoiningPolicy::Join) { - // Wait for the thread - if ((errnum = ::pthread_join(Thread, nullptr)) != 0) { - ReportErrnumFatal("pthread_join failed", errnum); - } - } + // Wait for the thread and clean up. + ::pthread_join(Thread, nullptr); + +error: + ::pthread_attr_destroy(&Attr); } + uint64_t llvm::get_threadid() { #if defined(__APPLE__) // Calling "mach_thread_self()" bumps the reference count on the thread diff --git a/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h b/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h index 1fc9a414f749..86309b0567f5 100644 --- a/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h +++ b/contrib/llvm-project/llvm/lib/Support/Unix/Unix.h @@ -21,7 +21,6 @@ #include "llvm/Config/config.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Errno.h" -#include "llvm/Support/ErrorHandling.h" #include <algorithm> #include <assert.h> #include <cerrno> @@ -70,14 +69,6 @@ static inline bool MakeErrMsg( return true; } -// Include StrError(errnum) in a fatal error message. -LLVM_ATTRIBUTE_NORETURN static inline void ReportErrnumFatal(const char *Msg, - int errnum) { - std::string ErrMsg; - MakeErrMsg(&ErrMsg, Msg, errnum); - llvm::report_fatal_error(ErrMsg); -} - namespace llvm { namespace sys { diff --git a/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp b/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp index edd4234fe501..5d3480e97148 100644 --- a/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp +++ b/contrib/llvm-project/llvm/lib/Support/VirtualFileSystem.cpp @@ -176,9 +176,9 @@ class RealFile : public File { Status S; std::string RealName; - RealFile(file_t RawFD, StringRef NewName, StringRef NewRealPathName) - : FD(RawFD), S(NewName, {}, {}, {}, {}, {}, - llvm::sys::fs::file_type::status_error, {}), + RealFile(file_t FD, StringRef NewName, StringRef NewRealPathName) + : FD(FD), S(NewName, {}, {}, {}, {}, {}, + llvm::sys::fs::file_type::status_error, {}), RealName(NewRealPathName.str()) { assert(FD != kInvalidFile && "Invalid or inactive file descriptor"); } @@ -349,7 +349,7 @@ IntrusiveRefCntPtr<FileSystem> vfs::getRealFileSystem() { } std::unique_ptr<FileSystem> vfs::createPhysicalFileSystem() { - return std::make_unique<RealFileSystem>(false); + return llvm::make_unique<RealFileSystem>(false); } namespace { @@ -754,7 +754,7 @@ bool InMemoryFileSystem::addFile(const Twine &P, time_t ModificationTime, ResolvedUser, ResolvedGroup, 0, sys::fs::file_type::directory_file, NewDirectoryPerms); Dir = cast<detail::InMemoryDirectory>(Dir->addChild( - Name, std::make_unique<detail::InMemoryDirectory>(std::move(Stat)))); + Name, llvm::make_unique<detail::InMemoryDirectory>(std::move(Stat)))); continue; } @@ -894,7 +894,7 @@ class InMemoryDirIterator : public llvm::vfs::detail::DirIterImpl { if (I != E) { SmallString<256> Path(RequestedDirName); llvm::sys::path::append(Path, I->second->getFileName()); - sys::fs::file_type Type = sys::fs::file_type::type_unknown; + sys::fs::file_type Type; switch (I->second->getKind()) { case detail::IME_File: case detail::IME_HardLink: @@ -989,16 +989,6 @@ std::error_code InMemoryFileSystem::isLocal(const Twine &Path, bool &Result) { // RedirectingFileSystem implementation //===-----------------------------------------------------------------------===/ -RedirectingFileSystem::RedirectingFileSystem(IntrusiveRefCntPtr<FileSystem> FS) - : ExternalFS(std::move(FS)) { - if (ExternalFS) - if (auto ExternalWorkingDirectory = - ExternalFS->getCurrentWorkingDirectory()) { - WorkingDirectory = *ExternalWorkingDirectory; - ExternalFSValidWD = true; - } -} - // FIXME: reuse implementation common with OverlayFSDirIterImpl as these // iterators are conceptually similar. class llvm::vfs::VFSFromYamlDirIterImpl @@ -1045,27 +1035,12 @@ public: llvm::ErrorOr<std::string> RedirectingFileSystem::getCurrentWorkingDirectory() const { - return WorkingDirectory; + return ExternalFS->getCurrentWorkingDirectory(); } std::error_code RedirectingFileSystem::setCurrentWorkingDirectory(const Twine &Path) { - // Don't change the working directory if the path doesn't exist. - if (!exists(Path)) - return errc::no_such_file_or_directory; - - // Always change the external FS but ignore its result. - if (ExternalFS) { - auto EC = ExternalFS->setCurrentWorkingDirectory(Path); - ExternalFSValidWD = !static_cast<bool>(EC); - } - - SmallString<128> AbsolutePath; - Path.toVector(AbsolutePath); - if (std::error_code EC = makeAbsolute(AbsolutePath)) - return EC; - WorkingDirectory = AbsolutePath.str(); - return {}; + return ExternalFS->setCurrentWorkingDirectory(Path); } std::error_code RedirectingFileSystem::isLocal(const Twine &Path, @@ -1073,25 +1048,12 @@ std::error_code RedirectingFileSystem::isLocal(const Twine &Path, return ExternalFS->isLocal(Path, Result); } -std::error_code RedirectingFileSystem::makeAbsolute(SmallVectorImpl<char> &Path) const { - if (llvm::sys::path::is_absolute(Path, llvm::sys::path::Style::posix) || - llvm::sys::path::is_absolute(Path, llvm::sys::path::Style::windows)) - return {}; - - auto WorkingDir = getCurrentWorkingDirectory(); - if (!WorkingDir) - return WorkingDir.getError(); - - llvm::sys::fs::make_absolute(WorkingDir.get(), Path); - return {}; -} - directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, std::error_code &EC) { ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Dir); if (!E) { EC = E.getError(); - if (shouldUseExternalFS() && EC == errc::no_such_file_or_directory) + if (IsFallthrough && EC == errc::no_such_file_or_directory) return ExternalFS->dir_begin(Dir, EC); return {}; } @@ -1109,7 +1071,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir, auto *D = cast<RedirectingFileSystem::RedirectingDirectoryEntry>(*E); return directory_iterator(std::make_shared<VFSFromYamlDirIterImpl>( Dir, D->contents_begin(), D->contents_end(), - /*IterateExternalFS=*/shouldUseExternalFS(), *ExternalFS, EC)); + /*IterateExternalFS=*/IsFallthrough, *ExternalFS, EC)); } void RedirectingFileSystem::setExternalContentsPrefixDir(StringRef PrefixDir) { @@ -1120,19 +1082,20 @@ StringRef RedirectingFileSystem::getExternalContentsPrefixDir() const { return ExternalContentsPrefixDir; } -void RedirectingFileSystem::dump(raw_ostream &OS) const { +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) +LLVM_DUMP_METHOD void RedirectingFileSystem::dump() const { for (const auto &Root : Roots) - dumpEntry(OS, Root.get()); + dumpEntry(Root.get()); } -void RedirectingFileSystem::dumpEntry(raw_ostream &OS, - RedirectingFileSystem::Entry *E, - int NumSpaces) const { +LLVM_DUMP_METHOD void +RedirectingFileSystem::dumpEntry(RedirectingFileSystem::Entry *E, + int NumSpaces) const { StringRef Name = E->getName(); for (int i = 0, e = NumSpaces; i < e; ++i) - OS << " "; - OS << "'" << Name.str().c_str() << "'" - << "\n"; + dbgs() << " "; + dbgs() << "'" << Name.str().c_str() << "'" + << "\n"; if (E->getKind() == RedirectingFileSystem::EK_Directory) { auto *DE = dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>(E); @@ -1140,12 +1103,9 @@ void RedirectingFileSystem::dumpEntry(raw_ostream &OS, for (std::unique_ptr<Entry> &SubEntry : llvm::make_range(DE->contents_begin(), DE->contents_end())) - dumpEntry(OS, SubEntry.get(), NumSpaces + 2); + dumpEntry(SubEntry.get(), NumSpaces + 2); } } - -#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) -LLVM_DUMP_METHOD void RedirectingFileSystem::dump() const { dump(dbgs()); } #endif /// A helper class to hold the common YAML parsing state. @@ -1249,7 +1209,7 @@ class llvm::vfs::RedirectingFileSystemParser { // ... or create a new one std::unique_ptr<RedirectingFileSystem::Entry> E = - std::make_unique<RedirectingFileSystem::RedirectingDirectoryEntry>( + llvm::make_unique<RedirectingFileSystem::RedirectingDirectoryEntry>( Name, Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), 0, 0, 0, file_type::directory_file, sys::fs::all_all)); @@ -1261,7 +1221,7 @@ class llvm::vfs::RedirectingFileSystemParser { } auto *DE = - cast<RedirectingFileSystem::RedirectingDirectoryEntry>(ParentEntry); + dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>(ParentEntry); DE->addContent(std::move(E)); return DE->getLastContent(); } @@ -1272,7 +1232,9 @@ class llvm::vfs::RedirectingFileSystemParser { StringRef Name = SrcE->getName(); switch (SrcE->getKind()) { case RedirectingFileSystem::EK_Directory: { - auto *DE = cast<RedirectingFileSystem::RedirectingDirectoryEntry>(SrcE); + auto *DE = + dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>(SrcE); + assert(DE && "Must be a directory"); // Empty directories could be present in the YAML as a way to // describe a file for a current directory after some of its subdir // is parsed. This only leads to redundant walks, ignore it. @@ -1284,12 +1246,13 @@ class llvm::vfs::RedirectingFileSystemParser { break; } case RedirectingFileSystem::EK_File: { + auto *FE = dyn_cast<RedirectingFileSystem::RedirectingFileEntry>(SrcE); + assert(FE && "Must be a file"); assert(NewParentE && "Parent entry must exist"); - auto *FE = cast<RedirectingFileSystem::RedirectingFileEntry>(SrcE); - auto *DE = - cast<RedirectingFileSystem::RedirectingDirectoryEntry>(NewParentE); + auto *DE = dyn_cast<RedirectingFileSystem::RedirectingDirectoryEntry>( + NewParentE); DE->addContent( - std::make_unique<RedirectingFileSystem::RedirectingFileEntry>( + llvm::make_unique<RedirectingFileSystem::RedirectingFileEntry>( Name, FE->getExternalContentsPath(), FE->getUseName())); break; } @@ -1441,41 +1404,31 @@ class llvm::vfs::RedirectingFileSystemParser { return nullptr; } - sys::path::Style path_style = sys::path::Style::native; - if (IsRootEntry) { - // VFS root entries may be in either Posix or Windows style. Figure out - // which style we have, and use it consistently. - if (sys::path::is_absolute(Name, sys::path::Style::posix)) { - path_style = sys::path::Style::posix; - } else if (sys::path::is_absolute(Name, sys::path::Style::windows)) { - path_style = sys::path::Style::windows; - } else { - assert(NameValueNode && "Name presence should be checked earlier"); - error(NameValueNode, - "entry with relative path at the root level is not discoverable"); - return nullptr; - } + if (IsRootEntry && !sys::path::is_absolute(Name)) { + assert(NameValueNode && "Name presence should be checked earlier"); + error(NameValueNode, + "entry with relative path at the root level is not discoverable"); + return nullptr; } // Remove trailing slash(es), being careful not to remove the root path StringRef Trimmed(Name); - size_t RootPathLen = sys::path::root_path(Trimmed, path_style).size(); + size_t RootPathLen = sys::path::root_path(Trimmed).size(); while (Trimmed.size() > RootPathLen && - sys::path::is_separator(Trimmed.back(), path_style)) + sys::path::is_separator(Trimmed.back())) Trimmed = Trimmed.slice(0, Trimmed.size() - 1); - // Get the last component - StringRef LastComponent = sys::path::filename(Trimmed, path_style); + StringRef LastComponent = sys::path::filename(Trimmed); std::unique_ptr<RedirectingFileSystem::Entry> Result; switch (Kind) { case RedirectingFileSystem::EK_File: - Result = std::make_unique<RedirectingFileSystem::RedirectingFileEntry>( + Result = llvm::make_unique<RedirectingFileSystem::RedirectingFileEntry>( LastComponent, std::move(ExternalContentsPath), UseExternalName); break; case RedirectingFileSystem::EK_Directory: Result = - std::make_unique<RedirectingFileSystem::RedirectingDirectoryEntry>( + llvm::make_unique<RedirectingFileSystem::RedirectingDirectoryEntry>( LastComponent, std::move(EntryArrayContents), Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), 0, 0, 0, @@ -1483,18 +1436,18 @@ class llvm::vfs::RedirectingFileSystemParser { break; } - StringRef Parent = sys::path::parent_path(Trimmed, path_style); + StringRef Parent = sys::path::parent_path(Trimmed); if (Parent.empty()) return Result; // if 'name' contains multiple components, create implicit directory entries - for (sys::path::reverse_iterator I = sys::path::rbegin(Parent, path_style), + for (sys::path::reverse_iterator I = sys::path::rbegin(Parent), E = sys::path::rend(Parent); I != E; ++I) { std::vector<std::unique_ptr<RedirectingFileSystem::Entry>> Entries; Entries.push_back(std::move(Result)); Result = - std::make_unique<RedirectingFileSystem::RedirectingDirectoryEntry>( + llvm::make_unique<RedirectingFileSystem::RedirectingDirectoryEntry>( *I, std::move(Entries), Status("", getNextVirtualUniqueID(), std::chrono::system_clock::now(), 0, 0, 0, @@ -1620,7 +1573,7 @@ RedirectingFileSystem::create(std::unique_ptr<MemoryBuffer> Buffer, RedirectingFileSystemParser P(Stream); std::unique_ptr<RedirectingFileSystem> FS( - new RedirectingFileSystem(ExternalFS)); + new RedirectingFileSystem(std::move(ExternalFS))); if (!YAMLFilePath.empty()) { // Use the YAML path from -ivfsoverlay to compute the dir to be prefixed @@ -1694,7 +1647,9 @@ RedirectingFileSystem::lookupPath(sys::path::const_iterator Start, // Forward the search to the next component in case this is an empty one. if (!FromName.empty()) { - if (!pathComponentMatches(*Start, FromName)) + if (CaseSensitive ? !Start->equals(FromName) + : !Start->equals_lower(FromName)) + // failure to match return make_error_code(llvm::errc::no_such_file_or_directory); ++Start; @@ -1716,7 +1671,6 @@ RedirectingFileSystem::lookupPath(sys::path::const_iterator Start, if (Result || Result.getError() != llvm::errc::no_such_file_or_directory) return Result; } - return make_error_code(llvm::errc::no_such_file_or_directory); } @@ -1748,7 +1702,7 @@ ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path, ErrorOr<Status> RedirectingFileSystem::status(const Twine &Path) { ErrorOr<RedirectingFileSystem::Entry *> Result = lookupPath(Path); if (!Result) { - if (shouldUseExternalFS() && + if (IsFallthrough && Result.getError() == llvm::errc::no_such_file_or_directory) { return ExternalFS->status(Path); } @@ -1786,7 +1740,7 @@ ErrorOr<std::unique_ptr<File>> RedirectingFileSystem::openFileForRead(const Twine &Path) { ErrorOr<RedirectingFileSystem::Entry *> E = lookupPath(Path); if (!E) { - if (shouldUseExternalFS() && + if (IsFallthrough && E.getError() == llvm::errc::no_such_file_or_directory) { return ExternalFS->openFileForRead(Path); } @@ -1809,7 +1763,7 @@ RedirectingFileSystem::openFileForRead(const Twine &Path) { Status S = getRedirectedFileStatus(Path, F->useExternalName(UseExternalNames), *ExternalStatus); return std::unique_ptr<File>( - std::make_unique<FileWithFixedStatus>(std::move(*Result), S)); + llvm::make_unique<FileWithFixedStatus>(std::move(*Result), S)); } std::error_code @@ -1817,7 +1771,7 @@ RedirectingFileSystem::getRealPath(const Twine &Path, SmallVectorImpl<char> &Output) const { ErrorOr<RedirectingFileSystem::Entry *> Result = lookupPath(Path); if (!Result) { - if (shouldUseExternalFS() && + if (IsFallthrough && Result.getError() == llvm::errc::no_such_file_or_directory) { return ExternalFS->getRealPath(Path, Output); } @@ -1830,8 +1784,8 @@ RedirectingFileSystem::getRealPath(const Twine &Path, } // Even if there is a directory entry, fall back to ExternalFS if allowed, // because directories don't have a single external contents path. - return shouldUseExternalFS() ? ExternalFS->getRealPath(Path, Output) - : llvm::errc::invalid_argument; + return IsFallthrough ? ExternalFS->getRealPath(Path, Output) + : llvm::errc::invalid_argument; } IntrusiveRefCntPtr<FileSystem> @@ -2095,7 +2049,7 @@ std::error_code VFSFromYamlDirIterImpl::incrementContent(bool IsFirstTime) { while (Current != End) { SmallString<128> PathStr(Dir); llvm::sys::path::append(PathStr, (*Current)->getName()); - sys::fs::file_type Type = sys::fs::file_type::type_unknown; + sys::fs::file_type Type; switch ((*Current)->getKind()) { case RedirectingFileSystem::EK_Directory: Type = sys::fs::file_type::directory_file; diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Memory.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Memory.inc index c5566f9910a5..a67f9c7d0f35 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/Memory.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Memory.inc @@ -19,7 +19,9 @@ // The Windows.h header must be the last one included. #include "WindowsSupport.h" -static DWORD getWindowsProtectionFlags(unsigned Flags) { +namespace { + +DWORD getWindowsProtectionFlags(unsigned Flags) { switch (Flags & llvm::sys::Memory::MF_RWE_MASK) { // Contrary to what you might expect, the Windows page protection flags // are not a bitwise combination of RWX values @@ -48,7 +50,7 @@ static DWORD getWindowsProtectionFlags(unsigned Flags) { // 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. -static size_t getAllocationGranularity() { +size_t getAllocationGranularity() { SYSTEM_INFO Info; ::GetSystemInfo(&Info); if (Info.dwPageSize > Info.dwAllocationGranularity) @@ -89,6 +91,8 @@ static size_t enableProcessLargePages() { return 0; } +} // namespace + namespace llvm { namespace sys { diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Mutex.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Mutex.inc new file mode 100644 index 000000000000..b55b14febf2c --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Mutex.inc @@ -0,0 +1,56 @@ +//===- llvm/Support/Win32/Mutex.inc - Win32 Mutex Implementation -*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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 { + +sys::MutexImpl::MutexImpl(bool /*recursive*/) +{ + data_ = new CRITICAL_SECTION; + InitializeCriticalSection((LPCRITICAL_SECTION)data_); +} + +sys::MutexImpl::~MutexImpl() +{ + DeleteCriticalSection((LPCRITICAL_SECTION)data_); + delete (LPCRITICAL_SECTION)data_; + data_ = 0; +} + +bool +sys::MutexImpl::acquire() +{ + EnterCriticalSection((LPCRITICAL_SECTION)data_); + return true; +} + +bool +sys::MutexImpl::release() +{ + LeaveCriticalSection((LPCRITICAL_SECTION)data_); + return true; +} + +bool +sys::MutexImpl::tryacquire() +{ + return TryEnterCriticalSection((LPCRITICAL_SECTION)data_); +} + +} diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Path.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Path.inc index c3b13abef5de..5704930aeecc 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/Path.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Path.inc @@ -371,19 +371,13 @@ static std::error_code realPathFromHandle(HANDLE H, if (std::error_code EC = realPathFromHandle(H, Buffer)) return EC; - // Strip the \\?\ prefix. We don't want it ending up in output, and such - // paths don't get canonicalized by file APIs. - wchar_t *Data = Buffer.data(); + const wchar_t *Data = Buffer.data(); DWORD CountChars = Buffer.size(); - if (CountChars >= 8 && ::memcmp(Data, L"\\\\?\\UNC\\", 16) == 0) { - // Convert \\?\UNC\foo\bar to \\foo\bar - CountChars -= 6; - Data += 6; - Data[0] = '\\'; - } else if (CountChars >= 4 && ::memcmp(Data, L"\\\\?\\", 8) == 0) { - // Convert \\?\c:\foo to c:\foo - CountChars -= 4; - Data += 4; + if (CountChars >= 4) { + if (0 == ::memcmp(Data, L"\\\\?\\", 8)) { + CountChars -= 4; + Data += 4; + } } // Convert the result from UTF-16 to UTF-8. @@ -1223,34 +1217,57 @@ file_t getStdinHandle() { return ::GetStdHandle(STD_INPUT_HANDLE); } file_t getStdoutHandle() { return ::GetStdHandle(STD_OUTPUT_HANDLE); } file_t getStderrHandle() { return ::GetStdHandle(STD_ERROR_HANDLE); } -Expected<size_t> readNativeFileImpl(file_t FileHandle, - MutableArrayRef<char> Buf, - OVERLAPPED *Overlap) { +std::error_code readNativeFileImpl(file_t FileHandle, char *BufPtr, size_t BytesToRead, + size_t *BytesRead, OVERLAPPED *Overlap) { // ReadFile can only read 2GB at a time. The caller should check the number of // bytes and read in a loop until termination. - DWORD BytesToRead = - std::min(size_t(std::numeric_limits<DWORD>::max()), Buf.size()); - DWORD BytesRead = 0; - if (::ReadFile(FileHandle, Buf.data(), BytesToRead, &BytesRead, Overlap)) - return BytesRead; - DWORD Err = ::GetLastError(); - // EOF is not an error. - if (Err == ERROR_BROKEN_PIPE || Err == ERROR_HANDLE_EOF) - return BytesRead; - return errorCodeToError(mapWindowsError(Err)); -} - -Expected<size_t> readNativeFile(file_t FileHandle, MutableArrayRef<char> Buf) { - return readNativeFileImpl(FileHandle, Buf, /*Overlap=*/nullptr); -} - -Expected<size_t> readNativeFileSlice(file_t FileHandle, - MutableArrayRef<char> Buf, - uint64_t Offset) { - OVERLAPPED Overlapped = {}; - Overlapped.Offset = uint32_t(Offset); - Overlapped.OffsetHigh = uint32_t(Offset >> 32); - return readNativeFileImpl(FileHandle, Buf, &Overlapped); + DWORD BytesToRead32 = + std::min(size_t(std::numeric_limits<DWORD>::max()), BytesToRead); + DWORD BytesRead32 = 0; + bool Success = + ::ReadFile(FileHandle, BufPtr, BytesToRead32, &BytesRead32, Overlap); + *BytesRead = BytesRead32; + if (!Success) { + DWORD Err = ::GetLastError(); + // Pipe EOF is not an error. + if (Err == ERROR_BROKEN_PIPE) + return std::error_code(); + return mapWindowsError(Err); + } + return std::error_code(); +} + +std::error_code readNativeFile(file_t FileHandle, MutableArrayRef<char> Buf, + size_t *BytesRead) { + return readNativeFileImpl(FileHandle, Buf.data(), Buf.size(), BytesRead, + /*Overlap=*/nullptr); +} + +std::error_code readNativeFileSlice(file_t FileHandle, + MutableArrayRef<char> Buf, size_t Offset) { + char *BufPtr = Buf.data(); + size_t BytesLeft = Buf.size(); + + while (BytesLeft) { + uint64_t CurOff = Buf.size() - BytesLeft + Offset; + OVERLAPPED Overlapped = {}; + Overlapped.Offset = uint32_t(CurOff); + Overlapped.OffsetHigh = uint32_t(uint64_t(CurOff) >> 32); + + size_t BytesRead = 0; + if (auto EC = readNativeFileImpl(FileHandle, BufPtr, BytesLeft, &BytesRead, + &Overlapped)) + return EC; + + // Once we reach EOF, zero the remaining bytes in the buffer. + if (BytesRead == 0) { + memset(BufPtr, 0, BytesLeft); + break; + } + BytesLeft -= BytesRead; + BufPtr += BytesRead; + } + return std::error_code(); } std::error_code closeFile(file_t &F) { diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Process.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Process.inc index 3526e3dee6fa..4b91f9f7fc66 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/Process.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Process.inc @@ -439,6 +439,13 @@ const char *Process::ResetColor() { return 0; } +// Include GetLastError() in a fatal error message. +static void ReportLastErrorFatal(const char *Msg) { + std::string ErrMsg; + MakeErrMsg(&ErrMsg, Msg); + report_fatal_error(ErrMsg); +} + unsigned Process::GetRandomNumber() { HCRYPTPROV HCPC; if (!::CryptAcquireContextW(&HCPC, NULL, NULL, PROV_RSA_FULL, diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Program.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Program.inc index a1482bf17c60..0f54e59ee55b 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/Program.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Program.inc @@ -197,7 +197,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, // 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 (StringRef E : *Env) { + for (const auto E : *Env) { SmallVector<wchar_t, MAX_PATH> EnvString; if (std::error_code ec = windows::UTF8ToUTF16(E, EnvString)) { SetLastError(ec.value()); @@ -470,7 +470,7 @@ 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::OF_Text); + llvm::raw_fd_ostream OS(FileName, EC, llvm::sys::fs::F_Text); if (EC) return EC; diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/RWMutex.inc b/contrib/llvm-project/llvm/lib/Support/Windows/RWMutex.inc new file mode 100644 index 000000000000..8df9bc394160 --- /dev/null +++ b/contrib/llvm-project/llvm/lib/Support/Windows/RWMutex.inc @@ -0,0 +1,128 @@ +//= llvm/Support/Win32/Mutex.inc - Win32 Reader/Writer Mutual Exclusion Lock =// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// 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 { + +// 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; +} + +sys::RWMutexImpl::RWMutexImpl() { + if (loadSRW()) { + data_ = safe_calloc(1, sizeof(SRWLOCK)); + fpInitializeSRWLock(static_cast<PSRWLOCK>(data_)); + } else { + data_ = safe_calloc(1, sizeof(CRITICAL_SECTION)); + InitializeCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); + } +} + +sys::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 sys::RWMutexImpl::reader_acquire() { + if (sHasSRW) { + fpAcquireSRWLockShared(static_cast<PSRWLOCK>(data_)); + } else { + EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); + } + return true; +} + +bool sys::RWMutexImpl::reader_release() { + if (sHasSRW) { + fpReleaseSRWLockShared(static_cast<PSRWLOCK>(data_)); + } else { + LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); + } + return true; +} + +bool sys::RWMutexImpl::writer_acquire() { + if (sHasSRW) { + fpAcquireSRWLockExclusive(static_cast<PSRWLOCK>(data_)); + } else { + EnterCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); + } + return true; +} + +bool sys::RWMutexImpl::writer_release() { + if (sHasSRW) { + fpReleaseSRWLockExclusive(static_cast<PSRWLOCK>(data_)); + } else { + LeaveCriticalSection(static_cast<LPCRITICAL_SECTION>(data_)); + } + return true; +} + + +} diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Signals.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Signals.inc index 09e19ae41f1a..6a820ef22b1e 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/Signals.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Signals.inc @@ -521,13 +521,10 @@ void sys::PrintStackTraceOnErrorSignal(StringRef Argv0, extern "C" VOID WINAPI RtlCaptureContext(PCONTEXT ContextRecord); #endif -static void LocalPrintStackTrace(raw_ostream &OS, PCONTEXT C) { - STACKFRAME64 StackFrame{}; - CONTEXT Context{}; - if (!C) { - ::RtlCaptureContext(&Context); - C = &Context; - } +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; @@ -549,12 +546,9 @@ static void LocalPrintStackTrace(raw_ostream &OS, PCONTEXT C) { StackFrame.AddrStack.Mode = AddrModeFlat; StackFrame.AddrFrame.Mode = AddrModeFlat; PrintStackTraceForThread(OS, GetCurrentProcess(), GetCurrentThread(), - StackFrame, C); + StackFrame, &Context); } -void llvm::sys::PrintStackTrace(raw_ostream &OS) { - LocalPrintStackTrace(OS, nullptr); -} void llvm::sys::SetInterruptFunction(void (*IF)()) { RegisterHandler(); @@ -566,13 +560,6 @@ void llvm::sys::SetInfoSignalFunction(void (*Handler)()) { // Unimplemented. } -void llvm::sys::SetOneShotPipeSignalFunction(void (*Handler)()) { - // Unimplemented. -} - -void llvm::sys::DefaultOneShotPipeSignalHandler() { - // Unimplemented. -} /// 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 @@ -798,10 +785,6 @@ WriteWindowsDumpFile(PMINIDUMP_EXCEPTION_INFORMATION ExceptionInfo) { return std::error_code(); } -void sys::CleanupOnSignal(uintptr_t Context) { - LLVMUnhandledExceptionFilter((LPEXCEPTION_POINTERS)Context); -} - static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { Cleanup(); @@ -820,15 +803,42 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) { << "\n"; } - // Stack unwinding appears to modify the context. Copy it to preserve the - // caller's context. - CONTEXT ContextCopy; - if (ep) - memcpy(&ContextCopy, ep->ContextRecord, sizeof(ContextCopy)); + // 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; +#elif defined(_M_ARM64) || defined(_M_ARM) + StackFrame.AddrPC.Offset = ep->ContextRecord->Pc; + StackFrame.AddrPC.Mode = AddrModeFlat; + StackFrame.AddrStack.Offset = ep->ContextRecord->Sp; + StackFrame.AddrStack.Mode = AddrModeFlat; +#if defined(_M_ARM64) + StackFrame.AddrFrame.Offset = ep->ContextRecord->Fp; +#else + StackFrame.AddrFrame.Offset = ep->ContextRecord->R11; +#endif + StackFrame.AddrFrame.Mode = AddrModeFlat; +#endif - LocalPrintStackTrace(llvm::errs(), ep ? &ContextCopy : nullptr); + HANDLE hProcess = GetCurrentProcess(); + HANDLE hThread = GetCurrentThread(); + PrintStackTraceForThread(llvm::errs(), hProcess, hThread, StackFrame, + ep->ContextRecord); - return EXCEPTION_EXECUTE_HANDLER; + _exit(ep->ExceptionRecord->ExceptionCode); } static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) { diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/Threading.inc b/contrib/llvm-project/llvm/lib/Support/Windows/Threading.inc index 9456efa686ff..96649472cc90 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/Threading.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/Threading.inc @@ -21,36 +21,36 @@ #undef MemoryFence #endif -static unsigned __stdcall threadFuncSync(void *Arg) { - SyncThreadInfo *TI = static_cast<SyncThreadInfo *>(Arg); - TI->UserFn(TI->UserData); - return 0; +namespace { + struct ThreadInfo { + void(*func)(void*); + void *param; + }; } -static unsigned __stdcall threadFuncAsync(void *Arg) { - std::unique_ptr<AsyncThreadInfo> Info(static_cast<AsyncThreadInfo *>(Arg)); - (*Info)(); +static unsigned __stdcall ThreadCallback(void *param) { + struct ThreadInfo *info = reinterpret_cast<struct ThreadInfo *>(param); + info->func(info->param); + return 0; } -static void -llvm_execute_on_thread_impl(unsigned (__stdcall *ThreadFunc)(void *), void *Arg, - llvm::Optional<unsigned> StackSizeInBytes, - JoiningPolicy JP) { - HANDLE hThread = (HANDLE)::_beginthreadex( - NULL, StackSizeInBytes.getValueOr(0), ThreadFunc, Arg, 0, NULL); - - if (!hThread) { - ReportLastErrorFatal("_beginthreadex failed"); - } - - if (JP == JoiningPolicy::Join) { - if (::WaitForSingleObject(hThread, INFINITE) == WAIT_FAILED) { - ReportLastErrorFatal("WaitForSingleObject failed"); - } - } - if (::CloseHandle(hThread) == FALSE) { - ReportLastErrorFatal("CloseHandle failed"); +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, + ¶m, 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); } } diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/WindowsSupport.h b/contrib/llvm-project/llvm/lib/Support/Windows/WindowsSupport.h index bb7e79b86018..fed9b2f462ef 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/WindowsSupport.h +++ b/contrib/llvm-project/llvm/lib/Support/Windows/WindowsSupport.h @@ -38,10 +38,8 @@ #include "llvm/ADT/StringRef.h" #include "llvm/ADT/Twine.h" #include "llvm/Config/config.h" // Get build system configuration settings -#include "llvm/Support/Allocator.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/Compiler.h" -#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/VersionTuple.h" #include <cassert> #include <string> @@ -67,13 +65,6 @@ llvm::VersionTuple GetWindowsOSVersion(); bool MakeErrMsg(std::string *ErrMsg, const std::string &prefix); -// Include GetLastError() in a fatal error message. -LLVM_ATTRIBUTE_NORETURN inline void ReportLastErrorFatal(const char *Msg) { - std::string ErrMsg; - MakeErrMsg(&ErrMsg, Msg); - llvm::report_fatal_error(ErrMsg); -} - template <typename HandleTraits> class ScopedHandle { typedef typename HandleTraits::handle_type handle_type; diff --git a/contrib/llvm-project/llvm/lib/Support/Windows/explicit_symbols.inc b/contrib/llvm-project/llvm/lib/Support/Windows/explicit_symbols.inc index 0a4fda1d4e8c..bbbf7ea6a777 100644 --- a/contrib/llvm-project/llvm/lib/Support/Windows/explicit_symbols.inc +++ b/contrib/llvm-project/llvm/lib/Support/Windows/explicit_symbols.inc @@ -90,6 +90,12 @@ 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 diff --git a/contrib/llvm-project/llvm/lib/Support/YAMLParser.cpp b/contrib/llvm-project/llvm/lib/Support/YAMLParser.cpp index d17e7b227f4a..9b2fe9c4418a 100644 --- a/contrib/llvm-project/llvm/lib/Support/YAMLParser.cpp +++ b/contrib/llvm-project/llvm/lib/Support/YAMLParser.cpp @@ -178,10 +178,10 @@ namespace { /// others) before the SimpleKey's Tok. struct SimpleKey { TokenQueueT::iterator Tok; - unsigned Column = 0; - unsigned Line = 0; - unsigned FlowLevel = 0; - bool IsRequired = false; + unsigned Column; + unsigned Line; + unsigned FlowLevel; + bool IsRequired; bool operator ==(const SimpleKey &Other) { return Tok == Other.Tok; @@ -789,7 +789,6 @@ Token &Scanner::peekNext() { if (TokenQueue.empty() || NeedMore) { if (!fetchMoreTokens()) { TokenQueue.clear(); - SimpleKeys.clear(); TokenQueue.push_back(Token()); return TokenQueue.front(); } @@ -933,16 +932,12 @@ void Scanner::scan_ns_uri_char() { } bool Scanner::consume(uint32_t Expected) { - if (Expected >= 0x80) { - setError("Cannot consume non-ascii characters"); - return false; - } + if (Expected >= 0x80) + report_fatal_error("Not dealing with this yet"); if (Current == End) return false; - if (uint8_t(*Current) >= 0x80) { - setError("Cannot consume non-ascii characters"); - return false; - } + if (uint8_t(*Current) >= 0x80) + report_fatal_error("Not dealing with this yet"); if (uint8_t(*Current) == Expected) { ++Current; ++Column; @@ -1232,10 +1227,7 @@ bool Scanner::scanValue() { if (i == SK.Tok) break; } - if (i == e) { - Failed = true; - return false; - } + assert(i != e && "SimpleKey not in token queue!"); i = TokenQueue.insert(i, T); // We may also need to add a Block-Mapping-Start token. @@ -1780,11 +1772,10 @@ Stream::~Stream() = default; bool Stream::failed() { return scanner->failed(); } void Stream::printError(Node *N, const Twine &Msg) { - SMRange Range = N ? N->getSourceRange() : SMRange(); - scanner->printError( Range.Start + scanner->printError( N->getSourceRange().Start , SourceMgr::DK_Error , Msg - , Range); + , N->getSourceRange()); } document_iterator Stream::begin() { @@ -1943,18 +1934,15 @@ StringRef ScalarNode::unescapeDoubleQuoted( StringRef UnquotedValue UnquotedValue = UnquotedValue.substr(1); break; default: - if (UnquotedValue.size() == 1) { - Token T; - T.Range = StringRef(UnquotedValue.begin(), 1); - setError("Unrecognized escape code", T); - return ""; - } + 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); + setError("Unrecognized escape code!", T); return ""; } case '\r': @@ -2090,14 +2078,7 @@ Node *KeyValueNode::getKey() { Node *KeyValueNode::getValue() { if (Value) return Value; - - if (Node* Key = getKey()) - Key->skip(); - else { - setError("Null key in Key Value.", peekNext()); - return Value = new (getAllocator()) NullNode(Doc); - } - + getKey()->skip(); if (failed()) return Value = new (getAllocator()) NullNode(Doc); @@ -2288,8 +2269,8 @@ Document::Document(Stream &S) : stream(S), Root(nullptr) { bool Document::skip() { if (stream.scanner->failed()) return false; - if (!Root && !getRoot()) - return false; + if (!Root) + getRoot(); Root->skip(); Token &T = peekNext(); if (T.Kind == Token::TK_StreamEnd) @@ -2413,15 +2394,6 @@ parse_property: // TODO: Properly handle tags. "[!!str ]" should resolve to !!str "", not // !!null null. return new (NodeAllocator) NullNode(stream.CurrentDoc); - case Token::TK_FlowMappingEnd: - case Token::TK_FlowSequenceEnd: - case Token::TK_FlowEntry: { - if (Root && (isa<MappingNode>(Root) || isa<SequenceNode>(Root))) - return new (NodeAllocator) NullNode(stream.CurrentDoc); - - setError("Unexpected token", T); - return nullptr; - } case Token::TK_Error: return nullptr; } diff --git a/contrib/llvm-project/llvm/lib/Support/YAMLTraits.cpp b/contrib/llvm-project/llvm/lib/Support/YAMLTraits.cpp index 5f0cedc71829..09eb36943de9 100644 --- a/contrib/llvm-project/llvm/lib/Support/YAMLTraits.cpp +++ b/contrib/llvm-project/llvm/lib/Support/YAMLTraits.cpp @@ -40,7 +40,7 @@ IO::IO(void *Context) : Ctxt(Context) {} IO::~IO() = default; -void *IO::getContext() const { +void *IO::getContext() { return Ctxt; } @@ -79,7 +79,7 @@ void Input::ScalarHNode::anchor() {} void Input::MapHNode::anchor() {} void Input::SequenceHNode::anchor() {} -bool Input::outputting() const { +bool Input::outputting() { return false; } @@ -87,6 +87,7 @@ 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; } @@ -376,12 +377,12 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) { // Copy string to permanent storage KeyStr = StringStorage.str().copy(StringAllocator); } - return std::make_unique<ScalarHNode>(N, KeyStr); + return llvm::make_unique<ScalarHNode>(N, KeyStr); } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) { StringRef ValueCopy = BSN->getValue().copy(StringAllocator); - return std::make_unique<ScalarHNode>(N, ValueCopy); + return llvm::make_unique<ScalarHNode>(N, ValueCopy); } else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) { - auto SQHNode = std::make_unique<SequenceHNode>(N); + auto SQHNode = llvm::make_unique<SequenceHNode>(N); for (Node &SN : *SQ) { auto Entry = createHNodes(&SN); if (EC) @@ -390,10 +391,10 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) { } return std::move(SQHNode); } else if (MappingNode *Map = dyn_cast<MappingNode>(N)) { - auto mapHNode = std::make_unique<MapHNode>(N); + auto mapHNode = llvm::make_unique<MapHNode>(N); for (KeyValueNode &KVN : *Map) { Node *KeyNode = KVN.getKey(); - ScalarNode *Key = dyn_cast_or_null<ScalarNode>(KeyNode); + ScalarNode *Key = dyn_cast<ScalarNode>(KeyNode); Node *Value = KVN.getValue(); if (!Key || !Value) { if (!Key) @@ -415,7 +416,7 @@ std::unique_ptr<Input::HNode> Input::createHNodes(Node *N) { } return std::move(mapHNode); } else if (isa<NullNode>(N)) { - return std::make_unique<EmptyHNode>(N); + return llvm::make_unique<EmptyHNode>(N); } else { setError(N, "unknown node kind"); return nullptr; @@ -439,7 +440,7 @@ Output::Output(raw_ostream &yout, void *context, int WrapColumn) Output::~Output() = default; -bool Output::outputting() const { +bool Output::outputting() { return true; } diff --git a/contrib/llvm-project/llvm/lib/Support/Z3Solver.cpp b/contrib/llvm-project/llvm/lib/Support/Z3Solver.cpp index a83d0f441a4b..f1a6fdf87cf2 100644 --- a/contrib/llvm-project/llvm/lib/Support/Z3Solver.cpp +++ b/contrib/llvm-project/llvm/lib/Support/Z3Solver.cpp @@ -886,7 +886,7 @@ public: llvm::SMTSolverRef llvm::CreateZ3Solver() { #if LLVM_WITH_Z3 - return std::make_unique<Z3Solver>(); + return llvm::make_unique<Z3Solver>(); #else llvm::report_fatal_error("LLVM was not compiled with Z3 support, rebuild " "with -DLLVM_ENABLE_Z3_SOLVER=ON", diff --git a/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp b/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp index 4bb315f824af..2baccaa0cbd7 100644 --- a/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp +++ b/contrib/llvm-project/llvm/lib/Support/raw_ostream.cpp @@ -65,24 +65,13 @@ using namespace llvm; -const raw_ostream::Colors raw_ostream::BLACK; -const raw_ostream::Colors raw_ostream::RED; -const raw_ostream::Colors raw_ostream::GREEN; -const raw_ostream::Colors raw_ostream::YELLOW; -const raw_ostream::Colors raw_ostream::BLUE; -const raw_ostream::Colors raw_ostream::MAGENTA; -const raw_ostream::Colors raw_ostream::CYAN; -const raw_ostream::Colors raw_ostream::WHITE; -const raw_ostream::Colors raw_ostream::SAVEDCOLOR; -const raw_ostream::Colors raw_ostream::RESET; - 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 == BufferKind::InternalBuffer) + if (BufferMode == InternalBuffer) delete [] OutBufStart; } @@ -102,14 +91,14 @@ void raw_ostream::SetBuffered() { void raw_ostream::SetBufferAndMode(char *BufferStart, size_t Size, BufferKind Mode) { - assert(((Mode == BufferKind::Unbuffered && !BufferStart && Size == 0) || - (Mode != BufferKind::Unbuffered && BufferStart && Size != 0)) && + 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 == BufferKind::InternalBuffer) + if (BufferMode == InternalBuffer) delete [] OutBufStart; OutBufStart = BufferStart; OutBufEnd = OutBufStart+Size; @@ -144,14 +133,6 @@ raw_ostream &raw_ostream::write_hex(unsigned long long N) { return *this; } -raw_ostream &raw_ostream::operator<<(Colors C) { - if (C == Colors::RESET) - resetColor(); - else - changeColor(C); - return *this; -} - raw_ostream &raw_ostream::write_uuid(const uuid_t UUID) { for (int Idx = 0; Idx < 16; ++Idx) { *this << format("%02" PRIX32, UUID[Idx]); @@ -223,7 +204,7 @@ 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 == BufferKind::Unbuffered) { + if (BufferMode == Unbuffered) { write_impl(reinterpret_cast<char*>(&C), 1); return *this; } @@ -243,7 +224,7 @@ 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 == BufferKind::Unbuffered) { + if (BufferMode == Unbuffered) { write_impl(Ptr, Size); return *this; } @@ -803,15 +784,11 @@ size_t raw_fd_ostream::preferred_buffer_size() const { raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold, bool bg) { - if (!ColorEnabled) - return *this; - if (sys::Process::ColorNeedsFlush()) flush(); const char *colorcode = - (colors == SAVEDCOLOR) - ? sys::Process::OutputBold(bg) - : sys::Process::OutputColor(static_cast<char>(colors), bold, bg); + (colors == SAVEDCOLOR) ? sys::Process::OutputBold(bg) + : sys::Process::OutputColor(colors, bold, bg); if (colorcode) { size_t len = strlen(colorcode); write(colorcode, len); @@ -822,9 +799,6 @@ raw_ostream &raw_fd_ostream::changeColor(enum Colors colors, bool bold, } raw_ostream &raw_fd_ostream::resetColor() { - if (!ColorEnabled) - return *this; - if (sys::Process::ColorNeedsFlush()) flush(); const char *colorcode = sys::Process::ResetColor(); @@ -838,9 +812,6 @@ raw_ostream &raw_fd_ostream::resetColor() { } raw_ostream &raw_fd_ostream::reverseColor() { - if (!ColorEnabled) - return *this; - if (sys::Process::ColorNeedsFlush()) flush(); const char *colorcode = sys::Process::OutputReverse(); @@ -872,7 +843,7 @@ void raw_fd_ostream::anchor() {} raw_ostream &llvm::outs() { // Set buffer settings to model stdout behavior. std::error_code EC; - static raw_fd_ostream S("-", EC, sys::fs::OF_None); + static raw_fd_ostream S("-", EC, sys::fs::F_None); assert(!EC); return S; } diff --git a/contrib/llvm-project/llvm/lib/Support/regcomp.c b/contrib/llvm-project/llvm/lib/Support/regcomp.c index ee2a1d87a267..12669ab75d1a 100644 --- a/contrib/llvm-project/llvm/lib/Support/regcomp.c +++ b/contrib/llvm-project/llvm/lib/Support/regcomp.c @@ -48,7 +48,6 @@ #include "regex2.h" #include "llvm/Config/config.h" -#include "llvm/Support/Compiler.h" /* character-class table */ static struct cclass { @@ -538,7 +537,7 @@ p_ere_exp(struct parse *p) break; case '{': /* okay as ordinary except if digit follows */ REQUIRE(!MORE() || !isdigit((uch)PEEK()), REG_BADRPT); - LLVM_FALLTHROUGH; + /* FALLTHROUGH */ default: ordinary(p, c); break; @@ -734,7 +733,7 @@ p_simp_re(struct parse *p, break; case '*': REQUIRE(starordinary, REG_BADRPT); - LLVM_FALLTHROUGH; + /* FALLTHROUGH */ default: ordinary(p, (char)c); break; @@ -1636,7 +1635,7 @@ findmust(struct parse *p, struct re_guts *g) return; } } while (OP(s) != O_QUEST && OP(s) != O_CH); - LLVM_FALLTHROUGH; + /* fallthrough */ default: /* things that break a sequence */ if (newlen > g->mlen) { /* ends one */ start = newstart; |
