summaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-05-02 19:34:44 +0000
committerdim <dim@FreeBSD.org>2011-05-02 19:34:44 +0000
commit2b066988909948dc3d53d01760bc2d71d32f3feb (patch)
treefc5f365fb9035b2d0c622bbf06c9bbe8627d7279 /lib/Support
parentc80ac9d286b8fcc6d1ee5d76048134cf80aa9edc (diff)
downloadFreeBSD-src-2b066988909948dc3d53d01760bc2d71d32f3feb.zip
FreeBSD-src-2b066988909948dc3d53d01760bc2d71d32f3feb.tar.gz
Vendor import of llvm trunk r130700:
http://llvm.org/svn/llvm-project/llvm/trunk@130700
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp57
-rw-r--r--lib/Support/APInt.cpp16
-rw-r--r--lib/Support/Allocator.cpp8
-rw-r--r--lib/Support/CommandLine.cpp193
-rw-r--r--lib/Support/CrashRecoveryContext.cpp51
-rw-r--r--lib/Support/Dwarf.cpp5
-rw-r--r--lib/Support/ErrorHandling.cpp1
-rw-r--r--lib/Support/FileUtilities.cpp2
-rw-r--r--lib/Support/FoldingSet.cpp5
-rw-r--r--lib/Support/Host.cpp2
-rw-r--r--lib/Support/MemoryBuffer.cpp142
-rw-r--r--lib/Support/Path.cpp28
-rw-r--r--lib/Support/PrettyStackTrace.cpp2
-rw-r--r--lib/Support/Regex.cpp2
-rw-r--r--lib/Support/Signals.cpp2
-rw-r--r--lib/Support/SmallPtrSet.cpp15
-rw-r--r--lib/Support/Statistic.cpp4
-rw-r--r--lib/Support/StringMap.cpp17
-rw-r--r--lib/Support/StringRef.cpp4
-rw-r--r--lib/Support/Triple.cpp112
-rw-r--r--lib/Support/Unix/Host.inc5
-rw-r--r--lib/Support/Unix/Memory.inc2
-rw-r--r--lib/Support/Unix/Path.inc6
-rw-r--r--lib/Support/Unix/Program.inc20
-rw-r--r--lib/Support/Unix/Signals.inc8
-rw-r--r--lib/Support/Windows/DynamicLibrary.inc33
-rw-r--r--lib/Support/Windows/Path.inc16
-rw-r--r--lib/Support/Windows/PathV2.inc11
-rw-r--r--lib/Support/raw_ostream.cpp64
-rw-r--r--lib/Support/regcomp.c2
30 files changed, 615 insertions, 220 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index e765ba0..c3169ac 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -726,7 +726,7 @@ APFloat::bitwiseIsEqual(const APFloat &rhs) const {
}
APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
-{
+ : exponent2(0), sign2(0) {
assertArithmeticOK(ourSemantics);
initialize(&ourSemantics);
sign = 0;
@@ -736,14 +736,15 @@ APFloat::APFloat(const fltSemantics &ourSemantics, integerPart value)
normalize(rmNearestTiesToEven, lfExactlyZero);
}
-APFloat::APFloat(const fltSemantics &ourSemantics) {
+APFloat::APFloat(const fltSemantics &ourSemantics) : exponent2(0), sign2(0) {
assertArithmeticOK(ourSemantics);
initialize(&ourSemantics);
category = fcZero;
sign = false;
}
-APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
+APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag)
+ : exponent2(0), sign2(0) {
assertArithmeticOK(ourSemantics);
// Allocates storage if necessary but does not initialize it.
initialize(&ourSemantics);
@@ -751,7 +752,7 @@ APFloat::APFloat(const fltSemantics &ourSemantics, uninitializedTag tag) {
APFloat::APFloat(const fltSemantics &ourSemantics,
fltCategory ourCategory, bool negative)
-{
+ : exponent2(0), sign2(0) {
assertArithmeticOK(ourSemantics);
initialize(&ourSemantics);
category = ourCategory;
@@ -763,14 +764,13 @@ APFloat::APFloat(const fltSemantics &ourSemantics,
}
APFloat::APFloat(const fltSemantics &ourSemantics, StringRef text)
-{
+ : exponent2(0), sign2(0) {
assertArithmeticOK(ourSemantics);
initialize(&ourSemantics);
convertFromString(text, rmNearestTiesToEven);
}
-APFloat::APFloat(const APFloat &rhs)
-{
+APFloat::APFloat(const APFloat &rhs) : exponent2(0), sign2(0) {
initialize(rhs.semantics);
assign(rhs);
}
@@ -3257,18 +3257,15 @@ APFloat APFloat::getSmallestNormalized(const fltSemantics &Sem, bool Negative) {
return Val;
}
-APFloat::APFloat(const APInt& api, bool isIEEE)
-{
+APFloat::APFloat(const APInt& api, bool isIEEE) : exponent2(0), sign2(0) {
initFromAPInt(api, isIEEE);
}
-APFloat::APFloat(float f)
-{
+APFloat::APFloat(float f) : exponent2(0), sign2(0) {
initFromAPInt(APInt::floatToBits(f));
}
-APFloat::APFloat(double d)
-{
+APFloat::APFloat(double d) : exponent2(0), sign2(0) {
initFromAPInt(APInt::doubleToBits(d));
}
@@ -3565,3 +3562,37 @@ void APFloat::toString(SmallVectorImpl<char> &Str,
for (; I != NDigits; ++I)
Str.push_back(buffer[NDigits-I-1]);
}
+
+bool APFloat::getExactInverse(APFloat *inv) const {
+ // We can only guarantee the existence of an exact inverse for IEEE floats.
+ if (semantics != &IEEEhalf && semantics != &IEEEsingle &&
+ semantics != &IEEEdouble && semantics != &IEEEquad)
+ return false;
+
+ // Special floats and denormals have no exact inverse.
+ if (category != fcNormal)
+ return false;
+
+ // Check that the number is a power of two by making sure that only the
+ // integer bit is set in the significand.
+ if (significandLSB() != semantics->precision - 1)
+ return false;
+
+ // Get the inverse.
+ APFloat reciprocal(*semantics, 1ULL);
+ if (reciprocal.divide(*this, rmNearestTiesToEven) != opOK)
+ return false;
+
+ // Avoid multiplication with a denormal, it is not safe on all platforms and
+ // may be slower than a normal division.
+ if (reciprocal.significandMSB() + 1 < reciprocal.semantics->precision)
+ return false;
+
+ assert(reciprocal.category == fcNormal &&
+ reciprocal.significandLSB() == reciprocal.semantics->precision - 1);
+
+ if (inv)
+ *inv = reciprocal;
+
+ return true;
+}
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index 08f36d2..23a22ac 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -1517,13 +1517,15 @@ APInt::ms APInt::magic() const {
/// division by a constant as a sequence of multiplies, adds and shifts.
/// Requires that the divisor not be 0. Taken from "Hacker's Delight", Henry
/// S. Warren, Jr., chapter 10.
-APInt::mu APInt::magicu() const {
+/// LeadingZeros can be used to simplify the calculation if the upper bits
+/// of the divided value are known zero.
+APInt::mu APInt::magicu(unsigned LeadingZeros) const {
const APInt& d = *this;
unsigned p;
APInt nc, delta, q1, r1, q2, r2;
struct mu magu;
magu.a = 0; // initialize "add" indicator
- APInt allOnes = APInt::getAllOnesValue(d.getBitWidth());
+ APInt allOnes = APInt::getAllOnesValue(d.getBitWidth()).lshr(LeadingZeros);
APInt signedMin = APInt::getSignedMinValue(d.getBitWidth());
APInt signedMax = APInt::getSignedMaxValue(d.getBitWidth());
@@ -2076,6 +2078,16 @@ APInt APInt::smul_ov(const APInt &RHS, bool &Overflow) const {
return Res;
}
+APInt APInt::umul_ov(const APInt &RHS, bool &Overflow) const {
+ APInt Res = *this * RHS;
+
+ if (*this != 0 && RHS != 0)
+ Overflow = Res.udiv(RHS) != *this || Res.udiv(*this) != RHS;
+ else
+ Overflow = false;
+ return Res;
+}
+
APInt APInt::sshl_ov(unsigned ShAmt, bool &Overflow) const {
Overflow = ShAmt >= getBitWidth();
if (Overflow)
diff --git a/lib/Support/Allocator.cpp b/lib/Support/Allocator.cpp
index 5e27df6..215b0f2 100644
--- a/lib/Support/Allocator.cpp
+++ b/lib/Support/Allocator.cpp
@@ -136,6 +136,14 @@ unsigned BumpPtrAllocator::GetNumSlabs() const {
return NumSlabs;
}
+size_t BumpPtrAllocator::getTotalMemory() const {
+ size_t TotalMemory = 0;
+ for (MemSlab *Slab = CurSlab; Slab != 0; Slab = Slab->NextPtr) {
+ TotalMemory += Slab->Size;
+ }
+ return TotalMemory;
+}
+
void BumpPtrAllocator::PrintStats() const {
unsigned NumSlabs = 0;
size_t TotalMemory = 0;
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 7e74499..7f1c0d3 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -186,12 +186,14 @@ static Option *LookupOption(StringRef &Arg, StringRef &Value,
/// have already been stripped.
static Option *LookupNearestOption(StringRef Arg,
const StringMap<Option*> &OptionsMap,
- const char *&NearestString) {
+ std::string &NearestString) {
// Reject all dashes.
if (Arg.empty()) return 0;
// Split on any equal sign.
- StringRef LHS = Arg.split('=').first;
+ std::pair<StringRef, StringRef> SplitArg = Arg.split('=');
+ StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.
+ StringRef &RHS = SplitArg.second;
// Find the closest match.
Option *Best = 0;
@@ -204,14 +206,19 @@ static Option *LookupNearestOption(StringRef Arg,
if (O->ArgStr[0])
OptionNames.push_back(O->ArgStr);
+ bool PermitValue = O->getValueExpectedFlag() != cl::ValueDisallowed;
+ StringRef Flag = PermitValue ? LHS : Arg;
for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
StringRef Name = OptionNames[i];
unsigned Distance = StringRef(Name).edit_distance(
- Arg, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
+ Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
if (!Best || Distance < BestDistance) {
Best = O;
- NearestString = OptionNames[i];
BestDistance = Distance;
+ if (RHS.empty() || !PermitValue)
+ NearestString = OptionNames[i];
+ else
+ NearestString = std::string(OptionNames[i]) + "=" + RHS.str();
}
}
}
@@ -611,7 +618,7 @@ void cl::ParseCommandLineOptions(int argc, char **argv,
for (int i = 1; i < argc; ++i) {
Option *Handler = 0;
Option *NearestHandler = 0;
- const char *NearestHandlerString = 0;
+ std::string NearestHandlerString;
StringRef Value;
StringRef ArgName = "";
@@ -908,8 +915,6 @@ void alias::printOptionInfo(size_t GlobalWidth) const {
errs().indent(GlobalWidth-L-6) << " - " << HelpStr << "\n";
}
-
-
//===----------------------------------------------------------------------===//
// Parser Implementation code...
//
@@ -939,7 +944,11 @@ void basic_parser_impl::printOptionInfo(const Option &O,
outs().indent(GlobalWidth-getOptionWidth(O)) << " - " << O.HelpStr << '\n';
}
-
+void basic_parser_impl::printOptionName(const Option &O,
+ size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+ outs().indent(GlobalWidth-std::strlen(O.ArgStr));
+}
// parser<bool> implementation
@@ -1083,6 +1092,89 @@ void generic_parser_base::printOptionInfo(const Option &O,
}
}
+static const size_t MaxOptWidth = 8; // arbitrary spacing for printOptionDiff
+
+// printGenericOptionDiff - Print the value of this option and it's default.
+//
+// "Generic" options have each value mapped to a name.
+void generic_parser_base::
+printGenericOptionDiff(const Option &O, const GenericOptionValue &Value,
+ const GenericOptionValue &Default,
+ size_t GlobalWidth) const {
+ outs() << " -" << O.ArgStr;
+ outs().indent(GlobalWidth-std::strlen(O.ArgStr));
+
+ unsigned NumOpts = getNumOptions();
+ for (unsigned i = 0; i != NumOpts; ++i) {
+ if (Value.compare(getOptionValue(i)))
+ continue;
+
+ outs() << "= " << getOption(i);
+ size_t L = std::strlen(getOption(i));
+ size_t NumSpaces = MaxOptWidth > L ? MaxOptWidth - L : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ for (unsigned j = 0; j != NumOpts; ++j) {
+ if (Default.compare(getOptionValue(j)))
+ continue;
+ outs() << getOption(j);
+ break;
+ }
+ outs() << ")\n";
+ return;
+ }
+ outs() << "= *unknown option value*\n";
+}
+
+// printOptionDiff - Specializations for printing basic value types.
+//
+#define PRINT_OPT_DIFF(T) \
+ void parser<T>:: \
+ printOptionDiff(const Option &O, T V, OptionValue<T> D, \
+ size_t GlobalWidth) const { \
+ printOptionName(O, GlobalWidth); \
+ std::string Str; \
+ { \
+ raw_string_ostream SS(Str); \
+ SS << V; \
+ } \
+ outs() << "= " << Str; \
+ size_t NumSpaces = MaxOptWidth > Str.size() ? MaxOptWidth - Str.size() : 0;\
+ outs().indent(NumSpaces) << " (default: "; \
+ if (D.hasValue()) \
+ outs() << D.getValue(); \
+ else \
+ outs() << "*no default*"; \
+ outs() << ")\n"; \
+ } \
+
+PRINT_OPT_DIFF(bool)
+PRINT_OPT_DIFF(boolOrDefault)
+PRINT_OPT_DIFF(int)
+PRINT_OPT_DIFF(unsigned)
+PRINT_OPT_DIFF(double)
+PRINT_OPT_DIFF(float)
+PRINT_OPT_DIFF(char)
+
+void parser<std::string>::
+printOptionDiff(const Option &O, StringRef V, OptionValue<std::string> D,
+ size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= " << V;
+ size_t NumSpaces = MaxOptWidth > V.size() ? MaxOptWidth - V.size() : 0;
+ outs().indent(NumSpaces) << " (default: ";
+ if (D.hasValue())
+ outs() << D.getValue();
+ else
+ outs() << "*no default*";
+ outs() << ")\n";
+}
+
+// Print a placeholder for options that don't yet support printOptionDiff().
+void basic_parser_impl::
+printOptionNoValue(const Option &O, size_t GlobalWidth) const {
+ printOptionName(O, GlobalWidth);
+ outs() << "= *cannot print option value*\n";
+}
//===----------------------------------------------------------------------===//
// -help and -help-hidden option implementation
@@ -1094,6 +1186,35 @@ static int OptNameCompare(const void *LHS, const void *RHS) {
return strcmp(((pair_ty*)LHS)->first, ((pair_ty*)RHS)->first);
}
+// Copy Options into a vector so we can sort them as we like.
+static void
+sortOpts(StringMap<Option*> &OptMap,
+ SmallVectorImpl< std::pair<const char *, Option*> > &Opts,
+ bool ShowHidden) {
+ SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection.
+
+ for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end();
+ I != E; ++I) {
+ // Ignore really-hidden options.
+ if (I->second->getOptionHiddenFlag() == ReallyHidden)
+ continue;
+
+ // Unless showhidden is set, ignore hidden flags.
+ if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
+ continue;
+
+ // If we've already seen this option, don't add it to the list again.
+ if (!OptionSet.insert(I->second))
+ continue;
+
+ Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(),
+ I->second));
+ }
+
+ // Sort the options list alphabetically.
+ qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare);
+}
+
namespace {
class HelpPrinter {
@@ -1115,30 +1236,8 @@ public:
StringMap<Option*> OptMap;
GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
- // Copy Options into a vector so we can sort them as we like.
SmallVector<std::pair<const char *, Option*>, 128> Opts;
- SmallPtrSet<Option*, 128> OptionSet; // Duplicate option detection.
-
- for (StringMap<Option*>::iterator I = OptMap.begin(), E = OptMap.end();
- I != E; ++I) {
- // Ignore really-hidden options.
- if (I->second->getOptionHiddenFlag() == ReallyHidden)
- continue;
-
- // Unless showhidden is set, ignore hidden flags.
- if (I->second->getOptionHiddenFlag() == Hidden && !ShowHidden)
- continue;
-
- // If we've already seen this option, don't add it to the list again.
- if (!OptionSet.insert(I->second))
- continue;
-
- Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(),
- I->second));
- }
-
- // Sort the options list alphabetically.
- qsort(Opts.data(), Opts.size(), sizeof(Opts[0]), OptNameCompare);
+ sortOpts(OptMap, Opts, ShowHidden);
if (ProgramOverview)
outs() << "OVERVIEW: " << ProgramOverview << "\n";
@@ -1197,6 +1296,38 @@ static cl::opt<HelpPrinter, true, parser<bool> >
HHOp("help-hidden", cl::desc("Display all available options"),
cl::location(HiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+static cl::opt<bool>
+PrintOptions("print-options",
+ cl::desc("Print non-default options after command line parsing"),
+ cl::Hidden, cl::init(false));
+
+static cl::opt<bool>
+PrintAllOptions("print-all-options",
+ cl::desc("Print all option values after command line parsing"),
+ cl::Hidden, cl::init(false));
+
+// Print the value of each option.
+void cl::PrintOptionValues() {
+ if (!PrintOptions && !PrintAllOptions) return;
+
+ // Get all the options.
+ SmallVector<Option*, 4> PositionalOpts;
+ SmallVector<Option*, 4> SinkOpts;
+ StringMap<Option*> OptMap;
+ GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
+
+ SmallVector<std::pair<const char *, Option*>, 128> Opts;
+ sortOpts(OptMap, Opts, /*ShowHidden*/true);
+
+ // Compute the maximum argument length...
+ size_t MaxArgLen = 0;
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ MaxArgLen = std::max(MaxArgLen, Opts[i].second->getOptionWidth());
+
+ for (size_t i = 0, e = Opts.size(); i != e; ++i)
+ Opts[i].second->printOptionValue(MaxArgLen, PrintAllOptions);
+}
+
static void (*OverrideVersionPrinter)() = 0;
static int TargetArraySortFn(const void *LHS, const void *RHS) {
diff --git a/lib/Support/CrashRecoveryContext.cpp b/lib/Support/CrashRecoveryContext.cpp
index bf8ca3f..899c389 100644
--- a/lib/Support/CrashRecoveryContext.cpp
+++ b/lib/Support/CrashRecoveryContext.cpp
@@ -57,12 +57,36 @@ public:
static sys::Mutex gCrashRecoveryContexMutex;
static bool gCrashRecoveryEnabled = false;
+static sys::ThreadLocal<const CrashRecoveryContextCleanup>
+ tlIsRecoveringFromCrash;
+
+CrashRecoveryContextCleanup::~CrashRecoveryContextCleanup() {}
+
CrashRecoveryContext::~CrashRecoveryContext() {
+ // Reclaim registered resources.
+ CrashRecoveryContextCleanup *i = head;
+ tlIsRecoveringFromCrash.set(head);
+ while (i) {
+ CrashRecoveryContextCleanup *tmp = i;
+ i = tmp->next;
+ tmp->cleanupFired = true;
+ tmp->recoverResources();
+ delete tmp;
+ }
+ tlIsRecoveringFromCrash.erase();
+
CrashRecoveryContextImpl *CRCI = (CrashRecoveryContextImpl *) Impl;
delete CRCI;
}
+bool CrashRecoveryContext::isRecoveringFromCrash() {
+ return tlIsRecoveringFromCrash.get() != 0;
+}
+
CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
+ if (!gCrashRecoveryEnabled)
+ return 0;
+
const CrashRecoveryContextImpl *CRCI = CurrentContext.get();
if (!CRCI)
return 0;
@@ -70,6 +94,33 @@ CrashRecoveryContext *CrashRecoveryContext::GetCurrent() {
return CRCI->CRC;
}
+void CrashRecoveryContext::registerCleanup(CrashRecoveryContextCleanup *cleanup)
+{
+ if (!cleanup)
+ return;
+ if (head)
+ head->prev = cleanup;
+ cleanup->next = head;
+ head = cleanup;
+}
+
+void
+CrashRecoveryContext::unregisterCleanup(CrashRecoveryContextCleanup *cleanup) {
+ if (!cleanup)
+ return;
+ if (cleanup == head) {
+ head = cleanup->next;
+ if (head)
+ head->prev = 0;
+ }
+ else {
+ cleanup->prev->next = cleanup->next;
+ if (cleanup->next)
+ cleanup->next->prev = cleanup->prev;
+ }
+ delete cleanup;
+}
+
#ifdef LLVM_ON_WIN32
// FIXME: No real Win32 implementation currently.
diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp
index 9799ef5..74a9fda 100644
--- a/lib/Support/Dwarf.cpp
+++ b/lib/Support/Dwarf.cpp
@@ -203,6 +203,10 @@ const char *llvm::dwarf::AttributeString(unsigned Attribute) {
case DW_AT_APPLE_major_runtime_vers: return "DW_AT_APPLE_major_runtime_vers";
case DW_AT_APPLE_runtime_class: return "DW_AT_APPLE_runtime_class";
case DW_AT_APPLE_omit_frame_ptr: return "DW_AT_APPLE_omit_frame_ptr";
+ case DW_AT_APPLE_property_name: return "DW_AT_APPLE_property_name";
+ case DW_AT_APPLE_property_getter: return "DW_AT_APPLE_property_getter";
+ case DW_AT_APPLE_property_setter: return "DW_AT_APPLE_property_setter";
+ case DW_AT_APPLE_property_attribute: return "DW_AT_APPLE_property_attribute";
}
return 0;
}
@@ -391,6 +395,7 @@ const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) {
case DW_OP_call_ref: return "DW_OP_call_ref";
case DW_OP_form_tls_address: return "DW_OP_form_tls_address";
case DW_OP_call_frame_cfa: return "DW_OP_call_frame_cfa";
+ case DW_OP_bit_piece: return "DW_OP_bit_piece";
case DW_OP_lo_user: return "DW_OP_lo_user";
case DW_OP_hi_user: return "DW_OP_hi_user";
}
diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp
index 3579546..e6cc57d 100644
--- a/lib/Support/ErrorHandling.cpp
+++ b/lib/Support/ErrorHandling.cpp
@@ -32,7 +32,6 @@
#endif
using namespace llvm;
-using namespace std;
static fatal_error_handler_t ErrorHandler = 0;
static void *ErrorHandlerUserData = 0;
diff --git a/lib/Support/FileUtilities.cpp b/lib/Support/FileUtilities.cpp
index 5dbabee..4c8c0c6 100644
--- a/lib/Support/FileUtilities.cpp
+++ b/lib/Support/FileUtilities.cpp
@@ -198,7 +198,7 @@ int llvm::DiffFilesWithTolerance(const sys::PathWithStatus &FileA,
return 1;
}
- // Now its safe to mmap the files into memory becasue both files
+ // Now its safe to mmap the files into memory because both files
// have a non-zero size.
error_code ec;
OwningPtr<MemoryBuffer> F1;
diff --git a/lib/Support/FoldingSet.cpp b/lib/Support/FoldingSet.cpp
index a4f80a9..d2e35b8 100644
--- a/lib/Support/FoldingSet.cpp
+++ b/lib/Support/FoldingSet.cpp
@@ -147,6 +147,11 @@ void FoldingSetNodeID::AddString(StringRef String) {
Bits.push_back(V);
}
+// AddNodeID - Adds the Bit data of another ID to *this.
+void FoldingSetNodeID::AddNodeID(const FoldingSetNodeID &ID) {
+ Bits.append(ID.Bits.begin(), ID.Bits.end());
+}
+
/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to
/// lookup the node in the FoldingSetImpl.
unsigned FoldingSetNodeID::ComputeHash() const {
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp
index 4dacf96..911c64a 100644
--- a/lib/Support/Host.cpp
+++ b/lib/Support/Host.cpp
@@ -214,6 +214,8 @@ std::string sys::getHostCPUName() {
// As found in a Summer 2010 model iMac.
case 37: // Intel Core i7, laptop version.
return "corei7";
+ case 42: // SandyBridge
+ return "sandybridge";
case 28: // Intel Atom processor. All processors are manufactured using
// the 45 nm process
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index a0c650d..e2b5b7a 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -46,8 +46,10 @@ MemoryBuffer::~MemoryBuffer() { }
/// init - Initialize this MemoryBuffer as a reference to externally allocated
/// memory, memory that we know is already null terminated.
-void MemoryBuffer::init(const char *BufStart, const char *BufEnd) {
- assert(BufEnd[0] == 0 && "Buffer is not null terminated!");
+void MemoryBuffer::init(const char *BufStart, const char *BufEnd,
+ bool RequiresNullTerminator) {
+ assert((!RequiresNullTerminator || BufEnd[0] == 0) &&
+ "Buffer is not null terminated!");
BufferStart = BufStart;
BufferEnd = BufEnd;
}
@@ -65,32 +67,39 @@ static void CopyStringRef(char *Memory, StringRef Data) {
/// GetNamedBuffer - Allocates a new MemoryBuffer with Name copied after it.
template <typename T>
-static T* GetNamedBuffer(StringRef Buffer, StringRef Name) {
+static T* GetNamedBuffer(StringRef Buffer, StringRef Name,
+ bool RequiresNullTerminator) {
char *Mem = static_cast<char*>(operator new(sizeof(T) + Name.size() + 1));
CopyStringRef(Mem + sizeof(T), Name);
- return new (Mem) T(Buffer);
+ return new (Mem) T(Buffer, RequiresNullTerminator);
}
namespace {
/// MemoryBufferMem - Named MemoryBuffer pointing to a block of memory.
class MemoryBufferMem : public MemoryBuffer {
public:
- MemoryBufferMem(StringRef InputData) {
- init(InputData.begin(), InputData.end());
+ MemoryBufferMem(StringRef InputData, bool RequiresNullTerminator) {
+ init(InputData.begin(), InputData.end(), RequiresNullTerminator);
}
virtual const char *getBufferIdentifier() const {
// The name is stored after the class itself.
return reinterpret_cast<const char*>(this + 1);
}
+
+ virtual BufferKind getBufferKind() const {
+ return MemoryBuffer_Malloc;
+ }
};
}
/// getMemBuffer - Open the specified memory range as a MemoryBuffer. Note
/// that EndPtr[0] must be a null byte and be accessible!
MemoryBuffer *MemoryBuffer::getMemBuffer(StringRef InputData,
- StringRef BufferName) {
- return GetNamedBuffer<MemoryBufferMem>(InputData, BufferName);
+ StringRef BufferName,
+ bool RequiresNullTerminator) {
+ return GetNamedBuffer<MemoryBufferMem>(InputData, BufferName,
+ RequiresNullTerminator);
}
/// getMemBufferCopy - Open the specified memory range as a MemoryBuffer,
@@ -127,7 +136,7 @@ MemoryBuffer *MemoryBuffer::getNewUninitMemBuffer(size_t Size,
char *Buf = Mem + AlignedStringLen;
Buf[Size] = 0; // Null terminate buffer.
- return new (Mem) MemoryBufferMem(StringRef(Buf, Size));
+ return new (Mem) MemoryBufferMem(StringRef(Buf, Size), true);
}
/// getNewMemBuffer - Allocate a new MemoryBuffer of the specified size that
@@ -172,26 +181,41 @@ namespace {
/// sys::Path::UnMapFilePages method.
class MemoryBufferMMapFile : public MemoryBufferMem {
public:
- MemoryBufferMMapFile(StringRef Buffer)
- : MemoryBufferMem(Buffer) { }
+ MemoryBufferMMapFile(StringRef Buffer, bool RequiresNullTerminator)
+ : MemoryBufferMem(Buffer, RequiresNullTerminator) { }
~MemoryBufferMMapFile() {
- sys::Path::UnMapFilePages(getBufferStart(), getBufferSize());
+ static int PageSize = sys::Process::GetPageSize();
+
+ uintptr_t Start = reinterpret_cast<uintptr_t>(getBufferStart());
+ size_t Size = getBufferSize();
+ uintptr_t RealStart = Start & ~(PageSize - 1);
+ size_t RealSize = Size + (Start - RealStart);
+
+ sys::Path::UnMapFilePages(reinterpret_cast<const char*>(RealStart),
+ RealSize);
+ }
+
+ virtual BufferKind getBufferKind() const {
+ return MemoryBuffer_MMap;
}
};
}
error_code MemoryBuffer::getFile(StringRef Filename,
OwningPtr<MemoryBuffer> &result,
- int64_t FileSize) {
+ int64_t FileSize,
+ bool RequiresNullTerminator) {
// Ensure the path is null terminated.
SmallString<256> PathBuf(Filename.begin(), Filename.end());
- return MemoryBuffer::getFile(PathBuf.c_str(), result, FileSize);
+ return MemoryBuffer::getFile(PathBuf.c_str(), result, FileSize,
+ RequiresNullTerminator);
}
error_code MemoryBuffer::getFile(const char *Filename,
OwningPtr<MemoryBuffer> &result,
- int64_t FileSize) {
+ int64_t FileSize,
+ bool RequiresNullTerminator) {
int OpenFlags = O_RDONLY;
#ifdef O_BINARY
OpenFlags |= O_BINARY; // Open input file in binary mode on win32.
@@ -200,17 +224,32 @@ error_code MemoryBuffer::getFile(const char *Filename,
if (FD == -1) {
return error_code(errno, posix_category());
}
- error_code ret = getOpenFile(FD, Filename, result, FileSize);
+ error_code ret = getOpenFile(FD, Filename, result, FileSize, FileSize,
+ 0, RequiresNullTerminator);
close(FD);
return ret;
}
-error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
- OwningPtr<MemoryBuffer> &result,
- int64_t FileSize) {
+static bool shouldUseMmap(int FD,
+ size_t FileSize,
+ size_t MapSize,
+ off_t Offset,
+ bool RequiresNullTerminator,
+ int PageSize) {
+ // We don't use mmap for small files because this can severely fragment our
+ // address space.
+ if (MapSize < 4096*4)
+ return false;
+
+ if (!RequiresNullTerminator)
+ return true;
+
+
// If we don't know the file size, use fstat to find out. fstat on an open
// file descriptor is cheaper than stat on a random path.
- if (FileSize == -1) {
+ // FIXME: this chunk of code is duplicated, but it avoids a fstat when
+ // RequiresNullTerminator = false and MapSize != -1.
+ if (FileSize == size_t(-1)) {
struct stat FileInfo;
// TODO: This should use fstat64 when available.
if (fstat(FD, &FileInfo) == -1) {
@@ -219,23 +258,59 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
FileSize = FileInfo.st_size;
}
+ // If we need a null terminator and the end of the map is inside the file,
+ // we cannot use mmap.
+ size_t End = Offset + MapSize;
+ assert(End <= FileSize);
+ if (End != FileSize)
+ return false;
- // If the file is large, try to use mmap to read it in. We don't use mmap
- // for small files, because this can severely fragment our address space. Also
- // don't try to map files that are exactly a multiple of the system page size,
- // as the file would not have the required null terminator.
- //
- // FIXME: Can we just mmap an extra page in the latter case?
- if (FileSize >= 4096*4 &&
- (FileSize & (sys::Process::GetPageSize()-1)) != 0) {
- if (const char *Pages = sys::Path::MapInFilePages(FD, FileSize)) {
+ // Don't try to map files that are exactly a multiple of the system page size
+ // if we need a null terminator.
+ if ((FileSize & (PageSize -1)) == 0)
+ return false;
+
+ return true;
+}
+
+error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
+ OwningPtr<MemoryBuffer> &result,
+ size_t FileSize, size_t MapSize,
+ off_t Offset,
+ bool RequiresNullTerminator) {
+ static int PageSize = sys::Process::GetPageSize();
+
+ // Default is to map the full file.
+ if (MapSize == size_t(-1)) {
+ // If we don't know the file size, use fstat to find out. fstat on an open
+ // file descriptor is cheaper than stat on a random path.
+ if (FileSize == size_t(-1)) {
+ struct stat FileInfo;
+ // TODO: This should use fstat64 when available.
+ if (fstat(FD, &FileInfo) == -1) {
+ return error_code(errno, posix_category());
+ }
+ FileSize = FileInfo.st_size;
+ }
+ MapSize = FileSize;
+ }
+
+ if (shouldUseMmap(FD, FileSize, MapSize, Offset, RequiresNullTerminator,
+ PageSize)) {
+ off_t RealMapOffset = Offset & ~(PageSize - 1);
+ off_t Delta = Offset - RealMapOffset;
+ size_t RealMapSize = MapSize + Delta;
+
+ if (const char *Pages = sys::Path::MapInFilePages(FD,
+ RealMapSize,
+ RealMapOffset)) {
result.reset(GetNamedBuffer<MemoryBufferMMapFile>(
- StringRef(Pages, FileSize), Filename));
+ StringRef(Pages + Delta, MapSize), Filename, RequiresNullTerminator));
return success;
}
}
- MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(FileSize, Filename);
+ MemoryBuffer *Buf = MemoryBuffer::getNewUninitMemBuffer(MapSize, Filename);
if (!Buf) {
// Failed to create a buffer. The only way it can fail is if
// new(std::nothrow) returns 0.
@@ -245,7 +320,10 @@ error_code MemoryBuffer::getOpenFile(int FD, const char *Filename,
OwningPtr<MemoryBuffer> SB(Buf);
char *BufPtr = const_cast<char*>(SB->getBufferStart());
- size_t BytesLeft = FileSize;
+ size_t BytesLeft = MapSize;
+ if (lseek(FD, Offset, SEEK_SET) == -1)
+ return error_code(errno, posix_category());
+
while (BytesLeft) {
ssize_t NumRead = ::read(FD, BufPtr, BytesLeft);
if (NumRead == -1) {
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index e5e875b..8fbaf2d 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -15,11 +15,15 @@
#include "llvm/Support/FileSystem.h"
#include "llvm/Config/config.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Endian.h"
#include <cassert>
#include <cstring>
#include <ostream>
using namespace llvm;
using namespace sys;
+namespace {
+using support::ulittle32_t;
+}
//===----------------------------------------------------------------------===//
//=== WARNING: Implementation here must contain only TRULY operating system
@@ -88,15 +92,21 @@ sys::IdentifyFileType(const char *magic, unsigned length) {
}
break;
+ // The two magic numbers for mach-o are:
+ // 0xfeedface - 32-bit mach-o
+ // 0xfeedfacf - 64-bit mach-o
case 0xFE:
- case 0xCE: {
+ case 0xCE:
+ case 0xCF: {
uint16_t type = 0;
if (magic[0] == char(0xFE) && magic[1] == char(0xED) &&
- magic[2] == char(0xFA) && magic[3] == char(0xCE)) {
+ magic[2] == char(0xFA) &&
+ (magic[3] == char(0xCE) || magic[3] == char(0xCF))) {
/* Native endian */
if (length >= 16) type = magic[14] << 8 | magic[15];
- } else if (magic[0] == char(0xCE) && magic[1] == char(0xFA) &&
- magic[2] == char(0xED) && magic[3] == char(0xFE)) {
+ } else if ((magic[0] == char(0xCE) || magic[0] == char(0xCF)) &&
+ magic[1] == char(0xFA) && magic[2] == char(0xED) &&
+ magic[3] == char(0xFE)) {
/* Reverse endian */
if (length >= 14) type = magic[13] << 8 | magic[12];
}
@@ -129,6 +139,16 @@ sys::IdentifyFileType(const char *magic, unsigned length) {
if (magic[1] == 0x02)
return COFF_FileType;
break;
+
+ case 0x4d: // Possible MS-DOS stub on Windows PE file
+ if (magic[1] == 0x5a) {
+ uint32_t off = *reinterpret_cast<const ulittle32_t *>(magic + 0x3c);
+ // PE/COFF file, either EXE or DLL.
+ if (off < length && memcmp(magic + off, "PE\0\0",4) == 0)
+ return COFF_FileType;
+ }
+ break;
+
case 0x64: // x86-64 Windows.
if (magic[1] == char(0x86))
return COFF_FileType;
diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp
index a9f4709..082b701 100644
--- a/lib/Support/PrettyStackTrace.cpp
+++ b/lib/Support/PrettyStackTrace.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
-// Unix signals occuring while your program is running.
+// Unix signals occurring while your program is running.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Support/Regex.cpp b/lib/Support/Regex.cpp
index 309ffb0..d293da0 100644
--- a/lib/Support/Regex.cpp
+++ b/lib/Support/Regex.cpp
@@ -82,7 +82,7 @@ bool Regex::match(StringRef String, SmallVectorImpl<StringRef> *Matches){
Matches->push_back(StringRef());
continue;
}
- assert(pm[i].rm_eo > pm[i].rm_so);
+ assert(pm[i].rm_eo >= pm[i].rm_so);
Matches->push_back(StringRef(String.data()+pm[i].rm_so,
pm[i].rm_eo-pm[i].rm_so));
}
diff --git a/lib/Support/Signals.cpp b/lib/Support/Signals.cpp
index a3af37d..a117893 100644
--- a/lib/Support/Signals.cpp
+++ b/lib/Support/Signals.cpp
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
-// Unix signals occuring while your program is running.
+// Unix signals occurring while your program is running.
//
//===----------------------------------------------------------------------===//
diff --git a/lib/Support/SmallPtrSet.cpp b/lib/Support/SmallPtrSet.cpp
index 504e649..997ce0b 100644
--- a/lib/Support/SmallPtrSet.cpp
+++ b/lib/Support/SmallPtrSet.cpp
@@ -52,10 +52,14 @@ bool SmallPtrSetImpl::insert_imp(const void * Ptr) {
// Otherwise, hit the big set case, which will call grow.
}
- // If more than 3/4 of the array is full, grow.
- if (NumElements*4 >= CurArraySize*3 ||
- CurArraySize-(NumElements+NumTombstones) < CurArraySize/8)
- Grow();
+ if (NumElements*4 >= CurArraySize*3) {
+ // If more than 3/4 of the array is full, grow.
+ Grow(CurArraySize < 64 ? 128 : CurArraySize*2);
+ } else if (CurArraySize-(NumElements+NumTombstones) < CurArraySize/8) {
+ // If fewer of 1/8 of the array is empty (meaning that many are filled with
+ // tombstones), rehash.
+ Grow(CurArraySize);
+ }
// Okay, we know we have space. Find a hash bucket.
const void **Bucket = const_cast<const void**>(FindBucketFor(Ptr));
@@ -125,10 +129,9 @@ const void * const *SmallPtrSetImpl::FindBucketFor(const void *Ptr) const {
/// Grow - Allocate a larger backing store for the buckets and move it over.
///
-void SmallPtrSetImpl::Grow() {
+void SmallPtrSetImpl::Grow(unsigned NewSize) {
// Allocate at twice as many buckets, but at least 128.
unsigned OldSize = CurArraySize;
- unsigned NewSize = OldSize < 64 ? 128 : OldSize*2;
const void **OldBuckets = CurArray;
bool WasSmall = isSmall();
diff --git a/lib/Support/Statistic.cpp b/lib/Support/Statistic.cpp
index f0ed626..1e733d9 100644
--- a/lib/Support/Statistic.cpp
+++ b/lib/Support/Statistic.cpp
@@ -101,6 +101,10 @@ void llvm::EnableStatistics() {
Enabled.setValue(true);
}
+bool llvm::AreStatisticsEnabled() {
+ return Enabled;
+}
+
void llvm::PrintStatistics(raw_ostream &OS) {
StatisticInfo &Stats = *StatInfo;
diff --git a/lib/Support/StringMap.cpp b/lib/Support/StringMap.cpp
index 90ec299..a1ac512 100644
--- a/lib/Support/StringMap.cpp
+++ b/lib/Support/StringMap.cpp
@@ -169,6 +169,8 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
TheTable[Bucket].Item = getTombstoneVal();
--NumItems;
++NumTombstones;
+ assert(NumItems + NumTombstones <= NumBuckets);
+
return Result;
}
@@ -177,7 +179,19 @@ StringMapEntryBase *StringMapImpl::RemoveKey(StringRef Key) {
/// RehashTable - Grow the table, redistributing values into the buckets with
/// the appropriate mod-of-hashtable-size.
void StringMapImpl::RehashTable() {
- unsigned NewSize = NumBuckets*2;
+ unsigned NewSize;
+
+ // If the hash table is now more than 3/4 full, or if fewer than 1/8 of
+ // the buckets are empty (meaning that many are filled with tombstones),
+ // grow/rehash the table.
+ if (NumItems*4 > NumBuckets*3) {
+ NewSize = NumBuckets*2;
+ } else if (NumBuckets-(NumItems+NumTombstones) < NumBuckets/8) {
+ NewSize = NumBuckets;
+ } else {
+ return;
+ }
+
// Allocate one extra bucket which will always be non-empty. This allows the
// iterators to stop at end.
ItemBucket *NewTableArray =(ItemBucket*)calloc(NewSize+1, sizeof(ItemBucket));
@@ -212,4 +226,5 @@ void StringMapImpl::RehashTable() {
TheTable = NewTableArray;
NumBuckets = NewSize;
+ NumTombstones = 0;
}
diff --git a/lib/Support/StringRef.cpp b/lib/Support/StringRef.cpp
index 5398051..8c3fc09 100644
--- a/lib/Support/StringRef.cpp
+++ b/lib/Support/StringRef.cpp
@@ -131,7 +131,7 @@ unsigned StringRef::edit_distance(llvm::StringRef Other,
/// find - Search for the first string \arg Str in the string.
///
-/// \return - The index of the first occurence of \arg Str, or npos if not
+/// \return - The index of the first occurrence of \arg Str, or npos if not
/// found.
size_t StringRef::find(StringRef Str, size_t From) const {
size_t N = Str.size();
@@ -145,7 +145,7 @@ size_t StringRef::find(StringRef Str, size_t From) const {
/// rfind - Search for the last string \arg Str in the string.
///
-/// \return - The index of the last occurence of \arg Str, or npos if not
+/// \return - The index of the last occurrence of \arg Str, or npos if not
/// found.
size_t StringRef::rfind(StringRef Str) const {
size_t N = Str.size();
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index 36edf6e..dbdb303 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -41,7 +41,8 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case x86_64: return "x86_64";
case xcore: return "xcore";
case mblaze: return "mblaze";
- case ptx: return "ptx";
+ case ptx32: return "ptx32";
+ case ptx64: return "ptx64";
}
return "<invalid>";
@@ -74,7 +75,8 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case xcore: return "xcore";
- case ptx: return "ptx";
+ case ptx32: return "ptx";
+ case ptx64: return "ptx";
}
}
@@ -84,6 +86,7 @@ const char *Triple::getVendorTypeName(VendorType Kind) {
case Apple: return "apple";
case PC: return "pc";
+ case SCEI: return "scei";
}
return "<invalid>";
@@ -98,8 +101,10 @@ const char *Triple::getOSTypeName(OSType Kind) {
case Darwin: return "darwin";
case DragonFly: return "dragonfly";
case FreeBSD: return "freebsd";
+ case IOS: return "ios";
case Linux: return "linux";
case Lv2: return "lv2";
+ case MacOSX: return "macosx";
case MinGW32: return "mingw32";
case NetBSD: return "netbsd";
case OpenBSD: return "openbsd";
@@ -162,8 +167,10 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
return x86_64;
if (Name == "xcore")
return xcore;
- if (Name == "ptx")
- return ptx;
+ if (Name == "ptx32")
+ return ptx32;
+ if (Name == "ptx64")
+ return ptx64;
return UnknownArch;
}
@@ -202,15 +209,17 @@ Triple::ArchType Triple::getArchTypeForDarwinArchName(StringRef Str) {
Str == "armv6" || Str == "armv7")
return Triple::arm;
- if (Str == "ptx")
- return Triple::ptx;
+ if (Str == "ptx32")
+ return Triple::ptx32;
+ if (Str == "ptx64")
+ return Triple::ptx64;
return Triple::UnknownArch;
}
// Returns architecture name that is understood by the target assembler.
const char *Triple::getArchNameForAssembler() {
- if (getOS() != Triple::Darwin && getVendor() != Triple::Apple)
+ if (!isOSDarwin() && getVendor() != Triple::Apple)
return NULL;
StringRef Str = getArchName();
@@ -235,8 +244,10 @@ const char *Triple::getArchNameForAssembler() {
return "armv6";
if (Str == "armv7" || Str == "thumbv7")
return "armv7";
- if (Str == "ptx")
- return "ptx";
+ if (Str == "ptx32")
+ return "ptx32";
+ if (Str == "ptx64")
+ return "ptx64";
return NULL;
}
@@ -285,8 +296,10 @@ Triple::ArchType Triple::ParseArch(StringRef ArchName) {
return tce;
else if (ArchName == "xcore")
return xcore;
- else if (ArchName == "ptx")
- return ptx;
+ else if (ArchName == "ptx32")
+ return ptx32;
+ else if (ArchName == "ptx64")
+ return ptx64;
else
return UnknownArch;
}
@@ -296,6 +309,8 @@ Triple::VendorType Triple::ParseVendor(StringRef VendorName) {
return Apple;
else if (VendorName == "pc")
return PC;
+ else if (VendorName == "scei")
+ return SCEI;
else
return UnknownVendor;
}
@@ -311,10 +326,14 @@ Triple::OSType Triple::ParseOS(StringRef OSName) {
return DragonFly;
else if (OSName.startswith("freebsd"))
return FreeBSD;
+ else if (OSName.startswith("ios"))
+ return IOS;
else if (OSName.startswith("linux"))
return Linux;
else if (OSName.startswith("lv2"))
return Lv2;
+ else if (OSName.startswith("macosx"))
+ return MacOSX;
else if (OSName.startswith("mingw32"))
return MinGW32;
else if (OSName.startswith("netbsd"))
@@ -523,67 +542,44 @@ StringRef Triple::getOSAndEnvironmentName() const {
static unsigned EatNumber(StringRef &Str) {
assert(!Str.empty() && Str[0] >= '0' && Str[0] <= '9' && "Not a number");
- unsigned Result = Str[0]-'0';
+ unsigned Result = 0;
- // Eat the digit.
- Str = Str.substr(1);
-
- // Handle "darwin11".
- if (Result == 1 && !Str.empty() && Str[0] >= '0' && Str[0] <= '9') {
+ do {
+ // Consume the leading digit.
Result = Result*10 + (Str[0] - '0');
+
// Eat the digit.
Str = Str.substr(1);
- }
+ } while (!Str.empty() && Str[0] >= '0' && Str[0] <= '9');
return Result;
}
-/// getDarwinNumber - Parse the 'darwin number' out of the specific target
-/// triple. For example, if we have darwin8.5 return 8,5,0. If any entry is
-/// not defined, return 0's. This requires that the triple have an OSType of
-/// darwin before it is called.
-void Triple::getDarwinNumber(unsigned &Maj, unsigned &Min,
- unsigned &Revision) const {
- assert(getOS() == Darwin && "Not a darwin target triple!");
+void Triple::getOSVersion(unsigned &Major, unsigned &Minor,
+ unsigned &Micro) const {
StringRef OSName = getOSName();
- assert(OSName.startswith("darwin") && "Unknown darwin target triple!");
-
- // Strip off "darwin".
- OSName = OSName.substr(6);
-
- Maj = Min = Revision = 0;
-
- if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
- return;
- // The major version is the first digit.
- Maj = EatNumber(OSName);
- if (OSName.empty()) return;
+ // Assume that the OS portion of the triple starts with the canonical name.
+ StringRef OSTypeName = getOSTypeName(getOS());
+ if (OSName.startswith(OSTypeName))
+ OSName = OSName.substr(OSTypeName.size());
- // Handle minor version: 10.4.9 -> darwin8.9.
- if (OSName[0] != '.')
- return;
+ // Any unset version defaults to 0.
+ Major = Minor = Micro = 0;
- // Eat the '.'.
- OSName = OSName.substr(1);
-
- if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
- return;
-
- Min = EatNumber(OSName);
- if (OSName.empty()) return;
-
- // Handle revision darwin8.9.1
- if (OSName[0] != '.')
- return;
-
- // Eat the '.'.
- OSName = OSName.substr(1);
+ // Parse up to three components.
+ unsigned *Components[3] = { &Major, &Minor, &Micro };
+ for (unsigned i = 0; i != 3; ++i) {
+ if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
+ break;
- if (OSName.empty() || OSName[0] < '0' || OSName[0] > '9')
- return;
+ // Consume the leading number.
+ *Components[i] = EatNumber(OSName);
- Revision = EatNumber(OSName);
+ // Consume the separator, if present.
+ if (OSName.startswith("."))
+ OSName = OSName.substr(1);
+ }
}
void Triple::setTriple(const Twine &Str) {
diff --git a/lib/Support/Unix/Host.inc b/lib/Support/Unix/Host.inc
index ed74b67..8cbec8c 100644
--- a/lib/Support/Unix/Host.inc
+++ b/lib/Support/Unix/Host.inc
@@ -87,10 +87,7 @@ std::string sys::getHostTriple() {
std::string::size_type DarwinDashIdx = Triple.find("-darwin");
if (DarwinDashIdx != std::string::npos) {
Triple.resize(DarwinDashIdx + strlen("-darwin"));
-
- // Only add the major part of the os version.
- std::string Version = getOSVersion();
- Triple += Version.substr(0, Version.find('.'));
+ Triple += getOSVersion();
}
return Triple;
diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc
index 4312d67..5a57a28 100644
--- a/lib/Support/Unix/Memory.inc
+++ b/lib/Support/Unix/Memory.inc
@@ -124,7 +124,7 @@ bool llvm::sys::Memory::setExecutable (MemoryBlock &M, std::string *ErrMsg) {
(vm_size_t)M.Size, 0, VM_PROT_READ | VM_PROT_EXECUTE | VM_PROT_COPY);
return KERN_SUCCESS == kr;
#else
- return false;
+ return true;
#endif
}
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index 0f6e800..430cf2e 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -869,18 +869,18 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
return false;
}
-const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
+const char *Path::MapInFilePages(int FD, size_t FileSize, off_t Offset) {
int Flags = MAP_PRIVATE;
#ifdef MAP_FILE
Flags |= MAP_FILE;
#endif
- void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, 0);
+ void *BasePtr = ::mmap(0, FileSize, PROT_READ, Flags, FD, Offset);
if (BasePtr == MAP_FAILED)
return 0;
return (const char*)BasePtr;
}
-void Path::UnMapFilePages(const char *BasePtr, uint64_t FileSize) {
+void Path::UnMapFilePages(const char *BasePtr, size_t FileSize) {
::munmap((void*)BasePtr, FileSize);
}
diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc
index 1104bc7..9f0a9ef 100644
--- a/lib/Support/Unix/Program.inc
+++ b/lib/Support/Unix/Program.inc
@@ -132,7 +132,7 @@ static bool RedirectIO(const Path *Path, int FD, std::string* ErrMsg) {
#ifdef HAVE_POSIX_SPAWN
static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
- posix_spawn_file_actions_t &FileActions) {
+ posix_spawn_file_actions_t *FileActions) {
if (Path == 0) // Noop
return false;
const char *File;
@@ -142,7 +142,7 @@ static bool RedirectIO_PS(const Path *Path, int FD, std::string *ErrMsg,
else
File = Path->c_str();
- if (int Err = posix_spawn_file_actions_addopen(&FileActions, FD,
+ if (int Err = posix_spawn_file_actions_addopen(FileActions, FD,
File, FD == 0 ? O_RDONLY : O_WRONLY|O_CREAT, 0666))
return MakeErrMsg(ErrMsg, "Cannot dup2", Err);
return false;
@@ -185,10 +185,13 @@ Program::Execute(const Path &path, const char **args, const char **envp,
// posix_spawn. It is more efficient than fork/exec.
#ifdef HAVE_POSIX_SPAWN
if (memoryLimit == 0) {
- posix_spawn_file_actions_t FileActions;
- posix_spawn_file_actions_init(&FileActions);
+ posix_spawn_file_actions_t FileActionsStore;
+ posix_spawn_file_actions_t *FileActions = 0;
if (redirects) {
+ FileActions = &FileActionsStore;
+ posix_spawn_file_actions_init(FileActions);
+
// Redirect stdin/stdout.
if (RedirectIO_PS(redirects[0], 0, ErrMsg, FileActions) ||
RedirectIO_PS(redirects[1], 1, ErrMsg, FileActions))
@@ -200,7 +203,7 @@ Program::Execute(const Path &path, const char **args, const char **envp,
} else {
// If stdout and stderr should go to the same place, redirect stderr
// to the FD already open for stdout.
- if (int Err = posix_spawn_file_actions_adddup2(&FileActions, 1, 2))
+ if (int Err = posix_spawn_file_actions_adddup2(FileActions, 1, 2))
return !MakeErrMsg(ErrMsg, "Can't redirect stderr to stdout", Err);
}
}
@@ -216,10 +219,11 @@ Program::Execute(const Path &path, const char **args, const char **envp,
// Explicitly initialized to prevent what appears to be a valgrind false
// positive.
pid_t PID = 0;
- int Err = posix_spawn(&PID, path.c_str(), &FileActions, /*attrp*/0,
+ int Err = posix_spawn(&PID, path.c_str(), FileActions, /*attrp*/0,
const_cast<char **>(args), const_cast<char **>(envp));
- posix_spawn_file_actions_destroy(&FileActions);
+ if (FileActions)
+ posix_spawn_file_actions_destroy(FileActions);
if (Err)
return !MakeErrMsg(ErrMsg, "posix_spawn failed", Err);
@@ -232,7 +236,7 @@ Program::Execute(const Path &path, const char **args, const char **envp,
// Create a child process.
int child = fork();
switch (child) {
- // An error occured: Return to the caller.
+ // An error occurred: Return to the caller.
case -1:
MakeErrMsg(ErrMsg, "Couldn't fork");
return false;
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc
index 0a61759..e286869 100644
--- a/lib/Support/Unix/Signals.inc
+++ b/lib/Support/Unix/Signals.inc
@@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===//
//
// This file defines some helpful functions for dealing with the possibility of
-// Unix signals occuring while your program is running.
+// Unix signals occurring while your program is running.
//
//===----------------------------------------------------------------------===//
@@ -274,6 +274,9 @@ void llvm::sys::PrintStackTraceOnErrorSignal() {
#ifdef __APPLE__
+#include <signal.h>
+#include <pthread.h>
+
int raise(int sig) {
return pthread_kill(pthread_self(), sig);
}
@@ -291,9 +294,6 @@ void __assert_rtn(const char *func,
abort();
}
-#include <signal.h>
-#include <pthread.h>
-
void abort() {
raise(SIGABRT);
usleep(1000);
diff --git a/lib/Support/Windows/DynamicLibrary.inc b/lib/Support/Windows/DynamicLibrary.inc
index 2c14366..4227844 100644
--- a/lib/Support/Windows/DynamicLibrary.inc
+++ b/lib/Support/Windows/DynamicLibrary.inc
@@ -41,41 +41,12 @@ using namespace sys;
static std::vector<HMODULE> OpenedHandles;
-#ifdef _WIN64
- typedef DWORD64 ModuleBaseType;
-#else
- typedef ULONG ModuleBaseType;
-#endif
-
extern "C" {
-// Use old callback if:
-// - Not using Visual Studio
-// - Visual Studio 2005 or earlier but only if we are not using the Windows SDK
-// or Windows SDK version is older than 6.0
-// Use new callback if:
-// - Newer Visual Studio (comes with newer SDK).
-// - Visual Studio 2005 with Windows SDK 6.0+
-#if defined(_MSC_VER)
- #if _MSC_VER < 1500 && (!defined(VER_PRODUCTBUILD) || VER_PRODUCTBUILD < 6000)
- #define OLD_ELM_CALLBACK_DECL 1
- #endif
-#elif defined(__MINGW64__)
- // Use new callback.
-#elif defined(__MINGW32__)
- #define OLD_ELM_CALLBACK_DECL 1
-#endif
-#ifdef OLD_ELM_CALLBACK_DECL
- static BOOL CALLBACK ELM_Callback(PSTR ModuleName,
- ModuleBaseType ModuleBase,
+ static BOOL CALLBACK ELM_Callback(WIN32_ELMCB_PCSTR ModuleName,
+ ULONG_PTR ModuleBase,
ULONG ModuleSize,
PVOID UserContext)
-#else
- static BOOL CALLBACK ELM_Callback(PCSTR ModuleName,
- ModuleBaseType ModuleBase,
- ULONG ModuleSize,
- PVOID UserContext)
-#endif
{
// Ignore VC++ runtimes prior to 7.1. Somehow some of them get loaded
// into the process.
diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc
index 625f67a..42a92f9 100644
--- a/lib/Support/Windows/Path.inc
+++ b/lib/Support/Windows/Path.inc
@@ -882,7 +882,17 @@ Path::makeUnique(bool reuse_current, std::string* ErrMsg) {
// Find a numeric suffix that isn't used by an existing file. Assume there
// won't be more than 1 million files with the same prefix. Probably a safe
// bet.
- static unsigned FCounter = 0;
+ static int FCounter = -1;
+ if (FCounter < 0) {
+ // Give arbitrary initial seed.
+ // FIXME: We should use sys::fs::unique_file() in future.
+ LARGE_INTEGER cnt64;
+ DWORD x = GetCurrentProcessId();
+ x = (x << 16) | (x >> 16);
+ if (QueryPerformanceCounter(&cnt64)) // RDTSC
+ x ^= cnt64.HighPart ^ cnt64.LowPart;
+ FCounter = x % 1000000;
+ }
do {
sprintf(FNBuffer+offset, "-%06u", FCounter);
if (++FCounter > 999999)
@@ -908,12 +918,12 @@ Path::createTemporaryFileOnDisk(bool reuse_current, std::string* ErrMsg) {
}
/// MapInFilePages - Not yet implemented on win32.
-const char *Path::MapInFilePages(int FD, uint64_t FileSize) {
+const char *Path::MapInFilePages(int FD, size_t FileSize, off_t Offset) {
return 0;
}
/// MapInFilePages - Not yet implemented on win32.
-void Path::UnMapFilePages(const char *Base, uint64_t FileSize) {
+void Path::UnMapFilePages(const char *Base, size_t FileSize) {
assert(0 && "NOT IMPLEMENTED");
}
diff --git a/lib/Support/Windows/PathV2.inc b/lib/Support/Windows/PathV2.inc
index 8effb0c..af71b73 100644
--- a/lib/Support/Windows/PathV2.inc
+++ b/lib/Support/Windows/PathV2.inc
@@ -449,7 +449,14 @@ error_code status(const Twine &path, file_status &result) {
SmallString<128> path_storage;
SmallVector<wchar_t, 128> path_utf16;
- if (error_code ec = UTF8ToUTF16(path.toStringRef(path_storage),
+ StringRef path8 = path.toStringRef(path_storage);
+ // FIXME: We should detect as many "special file name" as possible.
+ if (path8.compare_lower("nul") == 0) {
+ result = file_status(file_type::character_file);
+ return success;
+ }
+
+ if (error_code ec = UTF8ToUTF16(path8,
path_utf16))
return ec;
@@ -649,7 +656,7 @@ error_code get_magic(const Twine &path, uint32_t len,
::CloseHandle(file);
if (!read_success || (bytes_read != len)) {
// Set result size to the number of bytes read if it's valid.
- if (bytes_read >= 0 && bytes_read <= len)
+ if (bytes_read <= len)
result.set_size(bytes_read);
// ERROR_HANDLE_EOF is mapped to errc::value_too_large.
return ec;
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index 80ea740..5a71fa3 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -220,6 +220,36 @@ raw_ostream &raw_ostream::operator<<(const void *P) {
}
raw_ostream &raw_ostream::operator<<(double N) {
+#ifdef _WIN32
+ // On MSVCRT and compatible, output of %e is incompatible to Posix
+ // by default. Number of exponent digits should be at least 2. "%+03d"
+ // FIXME: Implement our formatter to here or Support/Format.h!
+ int fpcl = _fpclass(N);
+
+ // negative zero
+ if (fpcl == _FPCLASS_NZ)
+ return *this << "-0.000000e+00";
+
+ char buf[16];
+ unsigned len;
+ len = snprintf(buf, sizeof(buf), "%e", N);
+ if (len <= sizeof(buf) - 2) {
+ if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') {
+ int cs = buf[len - 4];
+ if (cs == '+' || cs == '-') {
+ int c1 = buf[len - 2];
+ int c0 = buf[len - 1];
+ if (isdigit(c1) && isdigit(c0)) {
+ // Trim leading '0': "...e+012" -> "...e+12\0"
+ buf[len - 3] = c1;
+ buf[len - 2] = c0;
+ buf[--len] = 0;
+ }
+ }
+ }
+ return this->operator<<(buf);
+ }
+#endif
return this->operator<<(format("%e", N));
}
@@ -265,15 +295,23 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
return write(Ptr, Size);
}
- // Write out the data in buffer-sized blocks until the remainder
- // fits within the buffer.
- do {
- size_t NumBytes = OutBufEnd - OutBufCur;
- copy_to_buffer(Ptr, NumBytes);
- flush_nonempty();
- Ptr += NumBytes;
- Size -= NumBytes;
- } while (OutBufCur+Size > OutBufEnd);
+ size_t NumBytes = OutBufEnd - OutBufCur;
+
+ // If the buffer is empty at this point we have a string that is larger
+ // than the buffer. Directly write the chunk that is a multiple of the
+ // preferred buffer size and put the remainder in the buffer.
+ if (BUILTIN_EXPECT(OutBufCur == OutBufStart, false)) {
+ size_t BytesToWrite = Size - (Size % NumBytes);
+ write_impl(Ptr, BytesToWrite);
+ copy_to_buffer(Ptr + BytesToWrite, Size - BytesToWrite);
+ return *this;
+ }
+
+ // We don't have enough space in the buffer to fit the string in. Insert as
+ // much as possible, flush and start over with the remainder.
+ copy_to_buffer(Ptr, NumBytes);
+ flush_nonempty();
+ return write(Ptr + NumBytes, Size - NumBytes);
}
copy_to_buffer(Ptr, Size);
@@ -458,6 +496,14 @@ raw_fd_ostream::~raw_fd_ostream() {
}
}
+#ifdef __MINGW32__
+ // On mingw, global dtors should not call exit().
+ // report_fatal_error() invokes exit(). We know report_fatal_error()
+ // might not write messages to stderr when any errors were detected
+ // on FD == 2.
+ if (FD == 2) return;
+#endif
+
// If there are any pending errors, report them now. Clients wishing
// to avoid report_fatal_error calls should check for errors with
// has_error() and clear the error flag with clear_error() before
diff --git a/lib/Support/regcomp.c b/lib/Support/regcomp.c
index cd018d5..46c91a9 100644
--- a/lib/Support/regcomp.c
+++ b/lib/Support/regcomp.c
@@ -780,7 +780,7 @@ p_b_cclass(struct parse *p, cset *cs)
const char *u;
char c;
- while (MORE() && isalpha(PEEK()))
+ while (MORE() && isalpha((uch)PEEK()))
NEXT();
len = p->next - sp;
for (cp = cclasses; cp->name != NULL; cp++)
OpenPOWER on IntegriCloud