aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Support
diff options
context:
space:
mode:
authorStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
committerStephen Hines <srhines@google.com>2015-03-23 12:10:34 -0700
commitebe69fe11e48d322045d5949c83283927a0d790b (patch)
treec92f1907a6b8006628a4b01615f38264d29834ea /lib/Support
parentb7d2e72b02a4cb8034f32f8247a2558d2434e121 (diff)
downloadexternal_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.zip
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.gz
external_llvm-ebe69fe11e48d322045d5949c83283927a0d790b.tar.bz2
Update aosp/master LLVM for rebase to r230699.
Change-Id: I2b5be30509658cb8266be782de0ab24f9099f9b9
Diffstat (limited to 'lib/Support')
-rw-r--r--lib/Support/APFloat.cpp2
-rw-r--r--lib/Support/APInt.cpp22
-rw-r--r--lib/Support/CMakeLists.txt28
-rw-r--r--lib/Support/CommandLine.cpp868
-rw-r--r--lib/Support/Compression.cpp6
-rw-r--r--lib/Support/ConvertUTFWrapper.cpp45
-rw-r--r--lib/Support/Debug.cpp66
-rw-r--r--lib/Support/Dwarf.cpp360
-rw-r--r--lib/Support/Errno.cpp8
-rw-r--r--lib/Support/ErrorHandling.cpp2
-rw-r--r--lib/Support/FileOutputBuffer.cpp27
-rw-r--r--lib/Support/Host.cpp99
-rw-r--r--lib/Support/LockFileManager.cpp54
-rw-r--r--lib/Support/MemoryBuffer.cpp6
-rw-r--r--lib/Support/Path.cpp13
-rw-r--r--lib/Support/PrettyStackTrace.cpp50
-rw-r--r--lib/Support/Process.cpp25
-rw-r--r--lib/Support/RandomNumberGenerator.cpp30
-rw-r--r--lib/Support/ScaledNumber.cpp2
-rw-r--r--lib/Support/SmallPtrSet.cpp19
-rw-r--r--lib/Support/SpecialCaseList.cpp58
-rw-r--r--lib/Support/StreamingMemoryObject.cpp4
-rw-r--r--lib/Support/StringMap.cpp5
-rw-r--r--lib/Support/ThreadLocal.cpp47
-rw-r--r--lib/Support/Triple.cpp58
-rw-r--r--lib/Support/Unix/Host.inc30
-rw-r--r--lib/Support/Unix/Memory.inc19
-rw-r--r--lib/Support/Unix/Path.inc113
-rw-r--r--lib/Support/Unix/Process.inc50
-rw-r--r--lib/Support/Unix/Program.inc26
-rw-r--r--lib/Support/Unix/Signals.inc2
-rw-r--r--lib/Support/Unix/ThreadLocal.inc45
-rw-r--r--lib/Support/Valgrind.cpp3
-rw-r--r--lib/Support/Windows/Path.inc159
-rw-r--r--lib/Support/Windows/Process.inc31
-rw-r--r--lib/Support/Windows/Program.inc20
-rw-r--r--lib/Support/Windows/Signals.inc51
-rw-r--r--lib/Support/Windows/ThreadLocal.inc2
-rw-r--r--lib/Support/Windows/WindowsSupport.h13
-rw-r--r--lib/Support/Windows/explicit_symbols.inc6
-rw-r--r--lib/Support/YAMLParser.cpp10
-rw-r--r--lib/Support/YAMLTraits.cpp18
-rw-r--r--lib/Support/raw_ostream.cpp10
-rw-r--r--lib/Support/regcomp.c21
44 files changed, 1103 insertions, 1430 deletions
diff --git a/lib/Support/APFloat.cpp b/lib/Support/APFloat.cpp
index 295b16c..393ecf4 100644
--- a/lib/Support/APFloat.cpp
+++ b/lib/Support/APFloat.cpp
@@ -1823,7 +1823,7 @@ APFloat::fusedMultiplyAdd(const APFloat &multiplicand,
/* If two numbers add (exactly) to zero, IEEE 754 decrees it is a
positive zero unless rounding to minus infinity, except that
adding two like-signed zeroes gives that zero. */
- if (category == fcZero && sign != addend.sign)
+ if (category == fcZero && !(fs & opUnderflow) && sign != addend.sign)
sign = (rounding_mode == rmTowardNegative);
} else {
fs = multiplySpecials(multiplicand);
diff --git a/lib/Support/APInt.cpp b/lib/Support/APInt.cpp
index c20eeb2..50a639c 100644
--- a/lib/Support/APInt.cpp
+++ b/lib/Support/APInt.cpp
@@ -713,7 +713,7 @@ unsigned APInt::countLeadingZerosSlowCase() const {
unsigned APInt::countLeadingOnes() const {
if (isSingleWord())
- return CountLeadingOnes_64(VAL << (APINT_BITS_PER_WORD - BitWidth));
+ return llvm::countLeadingOnes(VAL << (APINT_BITS_PER_WORD - BitWidth));
unsigned highWordBits = BitWidth % APINT_BITS_PER_WORD;
unsigned shift;
@@ -724,13 +724,13 @@ unsigned APInt::countLeadingOnes() const {
shift = APINT_BITS_PER_WORD - highWordBits;
}
int i = getNumWords() - 1;
- unsigned Count = CountLeadingOnes_64(pVal[i] << shift);
+ unsigned Count = llvm::countLeadingOnes(pVal[i] << shift);
if (Count == highWordBits) {
for (i--; i >= 0; --i) {
if (pVal[i] == -1ULL)
Count += APINT_BITS_PER_WORD;
else {
- Count += CountLeadingOnes_64(pVal[i]);
+ Count += llvm::countLeadingOnes(pVal[i]);
break;
}
}
@@ -756,14 +756,14 @@ unsigned APInt::countTrailingOnesSlowCase() const {
for (; i < getNumWords() && pVal[i] == -1ULL; ++i)
Count += APINT_BITS_PER_WORD;
if (i < getNumWords())
- Count += CountTrailingOnes_64(pVal[i]);
+ Count += llvm::countTrailingOnes(pVal[i]);
return std::min(Count, BitWidth);
}
unsigned APInt::countPopulationSlowCase() const {
unsigned Count = 0;
for (unsigned i = 0; i < getNumWords(); ++i)
- Count += CountPopulation_64(pVal[i]);
+ Count += llvm::countPopulation(pVal[i]);
return Count;
}
@@ -1956,6 +1956,18 @@ APInt APInt::srem(const APInt &RHS) const {
void APInt::udivrem(const APInt &LHS, const APInt &RHS,
APInt &Quotient, APInt &Remainder) {
+ assert(LHS.BitWidth == RHS.BitWidth && "Bit widths must be the same");
+
+ // First, deal with the easy case
+ if (LHS.isSingleWord()) {
+ assert(RHS.VAL != 0 && "Divide by zero?");
+ uint64_t QuotVal = LHS.VAL / RHS.VAL;
+ uint64_t RemVal = LHS.VAL % RHS.VAL;
+ Quotient = APInt(LHS.BitWidth, QuotVal);
+ Remainder = APInt(LHS.BitWidth, RemVal);
+ return;
+ }
+
// Get some size facts about the dividend and divisor
unsigned lhsBits = LHS.getActiveBits();
unsigned lhsWords = !lhsBits ? 0 : (APInt::whichWord(lhsBits - 1) + 1);
diff --git a/lib/Support/CMakeLists.txt b/lib/Support/CMakeLists.txt
index fa62591..a44c1a3 100644
--- a/lib/Support/CMakeLists.txt
+++ b/lib/Support/CMakeLists.txt
@@ -121,30 +121,10 @@ add_llvm_library(LLVMSupport
Valgrind.cpp
Watchdog.cpp
- ADDITIONAL_HEADERS
- Unix/Host.inc
- Unix/Memory.inc
- Unix/Mutex.inc
- Unix/Path.inc
- Unix/Process.inc
- Unix/Program.inc
- Unix/RWMutex.inc
- Unix/Signals.inc
- Unix/ThreadLocal.inc
- Unix/TimeValue.inc
- Unix/Watchdog.inc
- Windows/DynamicLibrary.inc
- Windows/Host.inc
- Windows/Memory.inc
- Windows/Mutex.inc
- Windows/Path.inc
- Windows/Process.inc
- Windows/Program.inc
- Windows/RWMutex.inc
- Windows/Signals.inc
- Windows/ThreadLocal.inc
- Windows/TimeValue.inc
- Windows/Watchdog.inc
+ ADDITIONAL_HEADER_DIRS
+ Unix
+ Windows
+ ${LLVM_MAIN_INCLUDE_DIR}/llvm/Support
LINK_LIBS ${system_libs}
)
diff --git a/lib/Support/CommandLine.cpp b/lib/Support/CommandLine.cpp
index 985c877..b49ec36 100644
--- a/lib/Support/CommandLine.cpp
+++ b/lib/Support/CommandLine.cpp
@@ -44,7 +44,8 @@ using namespace cl;
//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
-namespace llvm { namespace cl {
+namespace llvm {
+namespace cl {
TEMPLATE_INSTANTIATION(class basic_parser<bool>);
TEMPLATE_INSTANTIATION(class basic_parser<boolOrDefault>);
TEMPLATE_INSTANTIATION(class basic_parser<int>);
@@ -60,7 +61,8 @@ TEMPLATE_INSTANTIATION(class opt<int>);
TEMPLATE_INSTANTIATION(class opt<std::string>);
TEMPLATE_INSTANTIATION(class opt<char>);
TEMPLATE_INSTANTIATION(class opt<bool>);
-} } // end namespace llvm::cl
+}
+} // end namespace llvm::cl
// Pin the vtables to this file.
void GenericOptionValue::anchor() {}
@@ -81,151 +83,193 @@ void StringSaver::anchor() {}
//===----------------------------------------------------------------------===//
-// Globals for name and overview of program. Program name is not a string to
-// avoid static ctor/dtor issues.
-static char ProgramName[80] = "<premain>";
-static const char *ProgramOverview = nullptr;
+namespace {
-// This collects additional help to be printed.
-static ManagedStatic<std::vector<const char*> > MoreHelp;
+class CommandLineParser {
+public:
+ // Globals for name and overview of program. Program name is not a string to
+ // avoid static ctor/dtor issues.
+ std::string ProgramName;
+ const char *ProgramOverview;
-extrahelp::extrahelp(const char *Help)
- : morehelp(Help) {
- MoreHelp->push_back(Help);
-}
+ // This collects additional help to be printed.
+ std::vector<const char *> MoreHelp;
-static bool OptionListChanged = false;
+ SmallVector<Option *, 4> PositionalOpts;
+ SmallVector<Option *, 4> SinkOpts;
+ StringMap<Option *> OptionsMap;
-// MarkOptionsChanged - Internal helper function.
-void cl::MarkOptionsChanged() {
- OptionListChanged = true;
-}
+ Option *ConsumeAfterOpt; // The ConsumeAfter option if it exists.
-/// RegisteredOptionList - This is the list of the command line options that
-/// have statically constructed themselves.
-static Option *RegisteredOptionList = nullptr;
+ // This collects the different option categories that have been registered.
+ SmallPtrSet<OptionCategory *, 16> RegisteredOptionCategories;
-void Option::addArgument() {
- assert(!NextRegistered && "argument multiply registered!");
+ CommandLineParser() : ProgramOverview(nullptr), ConsumeAfterOpt(nullptr) {}
- NextRegistered = RegisteredOptionList;
- RegisteredOptionList = this;
- MarkOptionsChanged();
-}
+ void ParseCommandLineOptions(int argc, const char *const *argv,
+ const char *Overview);
-void Option::removeArgument() {
- if (RegisteredOptionList == this) {
- RegisteredOptionList = NextRegistered;
- MarkOptionsChanged();
- return;
+ void addLiteralOption(Option &Opt, const char *Name) {
+ if (!Opt.hasArgStr()) {
+ if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
+ errs() << ProgramName << ": CommandLine Error: Option '" << Name
+ << "' registered more than once!\n";
+ report_fatal_error("inconsistency in registered CommandLine options");
+ }
+ }
}
- Option *O = RegisteredOptionList;
- for (; O->NextRegistered != this; O = O->NextRegistered)
- ;
- O->NextRegistered = NextRegistered;
- MarkOptionsChanged();
-}
-
-// This collects the different option categories that have been registered.
-typedef SmallPtrSet<OptionCategory*,16> OptionCatSet;
-static ManagedStatic<OptionCatSet> RegisteredOptionCategories;
-
-// Initialise the general option category.
-OptionCategory llvm::cl::GeneralCategory("General options");
-
-void OptionCategory::registerCategory() {
- assert(std::count_if(RegisteredOptionCategories->begin(),
- RegisteredOptionCategories->end(),
- [this](const OptionCategory *Category) {
- return getName() == Category->getName();
- }) == 0 && "Duplicate option categories");
- RegisteredOptionCategories->insert(this);
-}
-
-//===----------------------------------------------------------------------===//
-// Basic, shared command line option processing machinery.
-//
-
-/// GetOptionInfo - Scan the list of registered options, turning them into data
-/// structures that are easier to handle.
-static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts,
- SmallVectorImpl<Option*> &SinkOpts,
- StringMap<Option*> &OptionsMap) {
- bool HadErrors = false;
- SmallVector<const char*, 16> OptionNames;
- Option *CAOpt = nullptr; // The ConsumeAfter option if it exists.
- for (Option *O = RegisteredOptionList; O; O = O->getNextRegisteredOption()) {
- // If this option wants to handle multiple option names, get the full set.
- // This handles enum options like "-O1 -O2" etc.
- O->getExtraOptionNames(OptionNames);
- if (O->ArgStr[0])
- OptionNames.push_back(O->ArgStr);
-
- // Handle named options.
- for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
+ void addOption(Option *O) {
+ bool HadErrors = false;
+ if (O->ArgStr[0]) {
// Add argument to the argument map!
- if (!OptionsMap.insert(std::make_pair(OptionNames[i], O)).second) {
- errs() << ProgramName << ": CommandLine Error: Option '"
- << OptionNames[i] << "' registered more than once!\n";
+ if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
+ errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
+ << "' registered more than once!\n";
HadErrors = true;
}
}
- OptionNames.clear();
-
// Remember information about positional options.
if (O->getFormattingFlag() == cl::Positional)
PositionalOpts.push_back(O);
else if (O->getMiscFlags() & cl::Sink) // Remember sink options
SinkOpts.push_back(O);
else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
- if (CAOpt) {
+ if (ConsumeAfterOpt) {
O->error("Cannot specify more than one option with cl::ConsumeAfter!");
HadErrors = true;
}
- CAOpt = O;
+ ConsumeAfterOpt = O;
+ }
+
+ // Fail hard if there were errors. These are strictly unrecoverable and
+ // indicate serious issues such as conflicting option names or an
+ // incorrectly
+ // linked LLVM distribution.
+ if (HadErrors)
+ report_fatal_error("inconsistency in registered CommandLine options");
+ }
+
+ void removeOption(Option *O) {
+ SmallVector<const char *, 16> OptionNames;
+ O->getExtraOptionNames(OptionNames);
+ if (O->ArgStr[0])
+ OptionNames.push_back(O->ArgStr);
+ for (auto Name : OptionNames)
+ OptionsMap.erase(StringRef(Name));
+
+ if (O->getFormattingFlag() == cl::Positional)
+ for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end();
+ ++Opt) {
+ if (*Opt == O) {
+ PositionalOpts.erase(Opt);
+ break;
+ }
+ }
+ else if (O->getMiscFlags() & cl::Sink)
+ for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) {
+ if (*Opt == O) {
+ SinkOpts.erase(Opt);
+ break;
+ }
+ }
+ else if (O == ConsumeAfterOpt)
+ ConsumeAfterOpt = nullptr;
+ }
+
+ bool hasOptions() {
+ return (!OptionsMap.empty() || !PositionalOpts.empty() ||
+ nullptr != ConsumeAfterOpt);
+ }
+
+ void updateArgStr(Option *O, const char *NewName) {
+ if (!OptionsMap.insert(std::make_pair(NewName, O)).second) {
+ errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
+ << "' registered more than once!\n";
+ report_fatal_error("inconsistency in registered CommandLine options");
}
+ OptionsMap.erase(StringRef(O->ArgStr));
}
- if (CAOpt)
- PositionalOpts.push_back(CAOpt);
+ void printOptionValues();
- // Make sure that they are in order of registration not backwards.
- std::reverse(PositionalOpts.begin(), PositionalOpts.end());
+ void registerCategory(OptionCategory *cat) {
+ assert(std::count_if(RegisteredOptionCategories.begin(),
+ RegisteredOptionCategories.end(),
+ [cat](const OptionCategory *Category) {
+ return cat->getName() == Category->getName();
+ }) == 0 &&
+ "Duplicate option categories");
+
+ RegisteredOptionCategories.insert(cat);
+ }
- // Fail hard if there were errors. These are strictly unrecoverable and
- // indicate serious issues such as conflicting option names or an incorrectly
- // linked LLVM distribution.
- if (HadErrors)
- report_fatal_error("inconsistency in registered CommandLine options");
+private:
+ Option *LookupOption(StringRef &Arg, StringRef &Value);
+};
+
+} // namespace
+
+static ManagedStatic<CommandLineParser> GlobalParser;
+
+void cl::AddLiteralOption(Option &O, const char *Name) {
+ GlobalParser->addLiteralOption(O, Name);
+}
+
+extrahelp::extrahelp(const char *Help) : morehelp(Help) {
+ GlobalParser->MoreHelp.push_back(Help);
+}
+
+void Option::addArgument() {
+ GlobalParser->addOption(this);
+ FullyInitialized = true;
+}
+
+void Option::removeArgument() { GlobalParser->removeOption(this); }
+
+void Option::setArgStr(const char *S) {
+ if (FullyInitialized)
+ GlobalParser->updateArgStr(this, S);
+ ArgStr = S;
}
+// Initialise the general option category.
+OptionCategory llvm::cl::GeneralCategory("General options");
+
+void OptionCategory::registerCategory() {
+ GlobalParser->registerCategory(this);
+}
+
+//===----------------------------------------------------------------------===//
+// Basic, shared command line option processing machinery.
+//
/// LookupOption - Lookup the option specified by the specified option on the
/// command line. If there is a value specified (after an equal sign) return
/// that as well. This assumes that leading dashes have already been stripped.
-static Option *LookupOption(StringRef &Arg, StringRef &Value,
- const StringMap<Option*> &OptionsMap) {
+Option *CommandLineParser::LookupOption(StringRef &Arg, StringRef &Value) {
// Reject all dashes.
- if (Arg.empty()) return nullptr;
+ if (Arg.empty())
+ return nullptr;
size_t EqualPos = Arg.find('=');
// If we have an equals sign, remember the value.
if (EqualPos == StringRef::npos) {
// Look up the option.
- StringMap<Option*>::const_iterator I = OptionsMap.find(Arg);
+ StringMap<Option *>::const_iterator I = OptionsMap.find(Arg);
return I != OptionsMap.end() ? I->second : nullptr;
}
// If the argument before the = is a valid option name, we match. If not,
// return Arg unmolested.
- StringMap<Option*>::const_iterator I =
- OptionsMap.find(Arg.substr(0, EqualPos));
- if (I == OptionsMap.end()) return nullptr;
+ StringMap<Option *>::const_iterator I =
+ OptionsMap.find(Arg.substr(0, EqualPos));
+ if (I == OptionsMap.end())
+ return nullptr;
- Value = Arg.substr(EqualPos+1);
+ Value = Arg.substr(EqualPos + 1);
Arg = Arg.substr(0, EqualPos);
return I->second;
}
@@ -235,23 +279,25 @@ static Option *LookupOption(StringRef &Arg, StringRef &Value,
/// (after an equal sign) return that as well. This assumes that leading dashes
/// have already been stripped.
static Option *LookupNearestOption(StringRef Arg,
- const StringMap<Option*> &OptionsMap,
+ const StringMap<Option *> &OptionsMap,
std::string &NearestString) {
// Reject all dashes.
- if (Arg.empty()) return nullptr;
+ if (Arg.empty())
+ return nullptr;
// Split on any equal sign.
std::pair<StringRef, StringRef> SplitArg = Arg.split('=');
- StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.
+ StringRef &LHS = SplitArg.first; // LHS == Arg when no '=' is present.
StringRef &RHS = SplitArg.second;
// Find the closest match.
Option *Best = nullptr;
unsigned BestDistance = 0;
- for (StringMap<Option*>::const_iterator it = OptionsMap.begin(),
- ie = OptionsMap.end(); it != ie; ++it) {
+ for (StringMap<Option *>::const_iterator it = OptionsMap.begin(),
+ ie = OptionsMap.end();
+ it != ie; ++it) {
Option *O = it->second;
- SmallVector<const char*, 16> OptionNames;
+ SmallVector<const char *, 16> OptionNames;
O->getExtraOptionNames(OptionNames);
if (O->ArgStr[0])
OptionNames.push_back(O->ArgStr);
@@ -261,7 +307,7 @@ static Option *LookupNearestOption(StringRef Arg,
for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
StringRef Name = OptionNames[i];
unsigned Distance = StringRef(Name).edit_distance(
- Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
+ Flag, /*AllowReplacements=*/true, /*MaxEditDistance=*/BestDistance);
if (!Best || Distance < BestDistance) {
Best = O;
BestDistance = Distance;
@@ -292,8 +338,8 @@ static bool CommaSeparateAndAddOccurrence(Option *Handler, unsigned pos,
if (Handler->addOccurrence(pos, ArgName, Val.substr(0, Pos), MultiArg))
return true;
// Erase the portion before the comma, AND the comma.
- Val = Val.substr(Pos+1);
- Value.substr(Pos+1); // Increment the original value pointer as well.
+ Val = Val.substr(Pos + 1);
+ Value.substr(Pos + 1); // Increment the original value pointer as well.
// Check for another comma.
Pos = Val.find(',');
}
@@ -320,9 +366,10 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName,
switch (Handler->getValueExpectedFlag()) {
case ValueRequired:
if (!Value.data()) { // No value specified?
- if (i+1 >= argc)
+ if (i + 1 >= argc)
return Handler->error("requires a value!");
// Steal the next argument, like for '-o filename'
+ assert(argv && "null check");
Value = argv[++i];
}
break;
@@ -332,8 +379,8 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName,
" with ValueDisallowed modifier!");
if (Value.data())
- return Handler->error("does not allow a value! '" +
- Twine(Value) + "' specified.");
+ return Handler->error("does not allow a value! '" + Twine(Value) +
+ "' specified.");
break;
case ValueOptional:
break;
@@ -354,8 +401,9 @@ static inline bool ProvideOption(Option *Handler, StringRef ArgName,
}
while (NumAdditionalVals > 0) {
- if (i+1 >= argc)
+ if (i + 1 >= argc)
return Handler->error("not enough values!");
+ assert(argv && "null check");
Value = argv[++i];
if (CommaSeparateAndAddOccurrence(Handler, i, ArgName, Value, MultiArg))
@@ -371,7 +419,6 @@ static bool ProvidePositionalOption(Option *Handler, StringRef Arg, int i) {
return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy);
}
-
// Option predicates...
static inline bool isGrouping(const Option *O) {
return O->getFormattingFlag() == cl::Grouping;
@@ -387,39 +434,42 @@ static inline bool isPrefixedOrGrouping(const Option *O) {
// otherwise return null.
//
static Option *getOptionPred(StringRef Name, size_t &Length,
- bool (*Pred)(const Option*),
- const StringMap<Option*> &OptionsMap) {
+ bool (*Pred)(const Option *),
+ const StringMap<Option *> &OptionsMap) {
- StringMap<Option*>::const_iterator OMI = OptionsMap.find(Name);
+ StringMap<Option *>::const_iterator OMI = OptionsMap.find(Name);
// Loop while we haven't found an option and Name still has at least two
// characters in it (so that the next iteration will not be the empty
// string.
while (OMI == OptionsMap.end() && Name.size() > 1) {
- Name = Name.substr(0, Name.size()-1); // Chop off the last character.
+ Name = Name.substr(0, Name.size() - 1); // Chop off the last character.
OMI = OptionsMap.find(Name);
}
if (OMI != OptionsMap.end() && Pred(OMI->second)) {
Length = Name.size();
- return OMI->second; // Found one!
+ return OMI->second; // Found one!
}
- return nullptr; // No option found!
+ return nullptr; // No option found!
}
/// HandlePrefixedOrGroupedOption - The specified argument string (which started
/// with at least one '-') does not fully match an available option. Check to
/// see if this is a prefix or grouped option. If so, split arg into output an
/// Arg/Value pair and return the Option to parse it with.
-static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
- bool &ErrorParsing,
- const StringMap<Option*> &OptionsMap) {
- if (Arg.size() == 1) return nullptr;
+static Option *
+HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
+ bool &ErrorParsing,
+ const StringMap<Option *> &OptionsMap) {
+ if (Arg.size() == 1)
+ return nullptr;
// Do the lookup!
size_t Length = 0;
Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);
- if (!PGOpt) return nullptr;
+ if (!PGOpt)
+ return nullptr;
// If the option is a prefixed option, then the value is simply the
// rest of the name... so fall through to later processing, by
@@ -445,8 +495,8 @@ static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
assert(PGOpt->getValueExpectedFlag() != cl::ValueRequired &&
"Option can not be cl::Grouping AND cl::ValueRequired!");
int Dummy = 0;
- ErrorParsing |= ProvideOption(PGOpt, OneArgName,
- StringRef(), 0, nullptr, Dummy);
+ ErrorParsing |=
+ ProvideOption(PGOpt, OneArgName, StringRef(), 0, nullptr, Dummy);
// Get the next grouping option.
PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);
@@ -456,8 +506,6 @@ static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
return PGOpt;
}
-
-
static bool RequiresValue(const Option *O) {
return O->getNumOccurrencesFlag() == cl::Required ||
O->getNumOccurrencesFlag() == cl::OneOrMore;
@@ -468,17 +516,11 @@ static bool EatsUnboundedNumberOfValues(const Option *O) {
O->getNumOccurrencesFlag() == cl::OneOrMore;
}
-static bool isWhitespace(char C) {
- return strchr(" \t\n\r\f\v", C);
-}
+static bool isWhitespace(char C) { return strchr(" \t\n\r\f\v", C); }
-static bool isQuote(char C) {
- return C == '\"' || C == '\'';
-}
+static bool isQuote(char C) { return C == '\"' || C == '\''; }
-static bool isGNUSpecial(char C) {
- return strchr("\\\"\' ", C);
-}
+static bool isGNUSpecial(char C) { return strchr("\\\"\' ", C); }
void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
SmallVectorImpl<const char *> &NewArgv,
@@ -493,13 +535,14 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
NewArgv.push_back(nullptr);
++I;
}
- if (I == E) break;
+ if (I == E)
+ break;
}
// Backslashes can escape backslashes, spaces, and other quotes. Otherwise
// they are literal. This makes it much easier to read Windows file paths.
if (I + 1 < E && Src[I] == '\\' && isGNUSpecial(Src[I + 1])) {
- ++I; // Skip the escape.
+ ++I; // Skip the escape.
Token.push_back(Src[I]);
continue;
}
@@ -514,7 +557,8 @@ void cl::TokenizeGNUCommandLine(StringRef Src, StringSaver &Saver,
Token.push_back(Src[I]);
++I;
}
- if (I == E) break;
+ if (I == E)
+ break;
continue;
}
@@ -654,6 +698,12 @@ void cl::TokenizeWindowsCommandLine(StringRef Src, StringSaver &Saver,
NewArgv.push_back(nullptr);
}
+// It is called byte order marker but the UTF-8 BOM is actually not affected
+// by the host system's endianness.
+static bool hasUTF8ByteOrderMark(ArrayRef<char> S) {
+ return (S.size() >= 3 && S[0] == '\xef' && S[1] == '\xbb' && S[2] == '\xbf');
+}
+
static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &NewArgv,
@@ -673,6 +723,11 @@ static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
return false;
Str = StringRef(UTF8Buf);
}
+ // If we see UTF-8 BOM sequence at the beginning of a file, we shall remove
+ // these bytes before parsing.
+ // Reference: http://en.wikipedia.org/wiki/UTF-8#Byte_order_mark
+ else if (hasUTF8ByteOrderMark(BufRef))
+ Str = StringRef(BufRef.data() + 3, BufRef.size() - 3);
// Tokenize the contents into NewArgv.
Tokenizer(Str, Saver, NewArgv, MarkEOLs);
@@ -689,7 +744,7 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
bool AllExpanded = true;
// Don't cache Argv.size() because it can change.
- for (unsigned I = 0; I != Argv.size(); ) {
+ for (unsigned I = 0; I != Argv.size();) {
const char *Arg = Argv[I];
// Check if it is an EOL marker
if (Arg == nullptr) {
@@ -726,22 +781,23 @@ bool cl::ExpandResponseFiles(StringSaver &Saver, TokenizerCallback Tokenizer,
}
namespace {
- class StrDupSaver : public StringSaver {
- std::vector<char*> Dups;
- public:
- ~StrDupSaver() {
- for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end();
- I != E; ++I) {
- char *Dup = *I;
- free(Dup);
- }
- }
- const char *SaveString(const char *Str) override {
- char *Dup = strdup(Str);
- Dups.push_back(Dup);
- return Dup;
+class StrDupSaver : public StringSaver {
+ std::vector<char *> Dups;
+
+public:
+ ~StrDupSaver() {
+ for (std::vector<char *>::iterator I = Dups.begin(), E = Dups.end(); I != E;
+ ++I) {
+ char *Dup = *I;
+ free(Dup);
}
- };
+ }
+ const char *SaveString(const char *Str) override {
+ char *Dup = strdup(Str);
+ Dups.push_back(Dup);
+ return Dup;
+ }
+};
}
/// ParseEnvironmentOptions - An alternative entry point to the
@@ -773,31 +829,25 @@ void cl::ParseEnvironmentOptions(const char *progName, const char *envVar,
ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
}
-void cl::ParseCommandLineOptions(int argc, const char * const *argv,
+void cl::ParseCommandLineOptions(int argc, const char *const *argv,
const char *Overview) {
- // Process all registered options.
- SmallVector<Option*, 4> PositionalOpts;
- SmallVector<Option*, 4> SinkOpts;
- StringMap<Option*> Opts;
- GetOptionInfo(PositionalOpts, SinkOpts, Opts);
+ GlobalParser->ParseCommandLineOptions(argc, argv, Overview);
+}
- assert((!Opts.empty() || !PositionalOpts.empty()) &&
- "No options specified!");
+void CommandLineParser::ParseCommandLineOptions(int argc,
+ const char *const *argv,
+ const char *Overview) {
+ assert(hasOptions() && "No options specified!");
// Expand response files.
- SmallVector<const char *, 20> newArgv;
- for (int i = 0; i != argc; ++i)
- newArgv.push_back(argv[i]);
+ SmallVector<const char *, 20> newArgv(argv, argv + argc);
StrDupSaver Saver;
ExpandResponseFiles(Saver, TokenizeGNUCommandLine, newArgv);
argv = &newArgv[0];
argc = static_cast<int>(newArgv.size());
// Copy the program name into ProgName, making sure not to overflow it.
- StringRef ProgName = sys::path::filename(argv[0]);
- size_t Len = std::min(ProgName.size(), size_t(79));
- memcpy(ProgramName, ProgName.data(), Len);
- ProgramName[Len] = '\0';
+ ProgramName = sys::path::filename(argv[0]);
ProgramOverview = Overview;
bool ErrorParsing = false;
@@ -808,29 +858,26 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Determine whether or not there are an unlimited number of positionals
bool HasUnlimitedPositionals = false;
- Option *ConsumeAfterOpt = nullptr;
+ if (ConsumeAfterOpt) {
+ assert(PositionalOpts.size() > 0 &&
+ "Cannot specify cl::ConsumeAfter without a positional argument!");
+ }
if (!PositionalOpts.empty()) {
- if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
- assert(PositionalOpts.size() > 1 &&
- "Cannot specify cl::ConsumeAfter without a positional argument!");
- ConsumeAfterOpt = PositionalOpts[0];
- }
// Calculate how many positional values are _required_.
bool UnboundedFound = false;
- for (size_t i = ConsumeAfterOpt ? 1 : 0, e = PositionalOpts.size();
- i != e; ++i) {
+ for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
Option *Opt = PositionalOpts[i];
if (RequiresValue(Opt))
++NumPositionalRequired;
else if (ConsumeAfterOpt) {
// ConsumeAfter cannot be combined with "optional" positional options
// unless there is only one positional argument...
- if (PositionalOpts.size() > 2)
- ErrorParsing |=
- Opt->error("error - this positional option will never be matched, "
- "because it does not Require a value, and a "
- "cl::ConsumeAfter option is active!");
+ if (PositionalOpts.size() > 1)
+ ErrorParsing |= Opt->error(
+ "error - this positional option will never be matched, "
+ "because it does not Require a value, and a "
+ "cl::ConsumeAfter option is active!");
} else if (UnboundedFound && !Opt->ArgStr[0]) {
// This option does not "require" a value... Make sure this option is
// not specified after an option that eats all extra arguments, or this
@@ -840,6 +887,9 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
"another positional argument will match an "
"unbounded number of values, and this option"
" does not require a value!");
+ errs() << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr
+ << "' is all messed up!\n";
+ errs() << PositionalOpts.size();
}
UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
}
@@ -849,7 +899,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// PositionalVals - A vector of "positional" arguments we accumulate into
// the process at the end.
//
- SmallVector<std::pair<StringRef,unsigned>, 4> PositionalVals;
+ SmallVector<std::pair<StringRef, unsigned>, 4> PositionalVals;
// If the program has named positional arguments, and the name has been run
// across, keep track of which positional argument was named. Otherwise put
@@ -857,7 +907,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
Option *ActivePositionalArg = nullptr;
// Loop over all of the arguments... processing them.
- bool DashDashFound = false; // Have we read '--'?
+ bool DashDashFound = false; // Have we read '--'?
for (int i = 1; i < argc; ++i) {
Option *Handler = nullptr;
Option *NearestHandler = nullptr;
@@ -865,17 +915,6 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
StringRef Value;
StringRef ArgName = "";
- // If the option list changed, this means that some command line
- // option has just been registered or deregistered. This can occur in
- // response to things like -load, etc. If this happens, rescan the options.
- if (OptionListChanged) {
- PositionalOpts.clear();
- SinkOpts.clear();
- Opts.clear();
- GetOptionInfo(PositionalOpts, SinkOpts, Opts);
- OptionListChanged = false;
- }
-
// Check to see if this is a positional argument. This argument is
// considered to be positional if it doesn't start with '-', if it is "-"
// itself, or if we have seen "--" already.
@@ -884,19 +923,19 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Positional argument!
if (ActivePositionalArg) {
ProvidePositionalOption(ActivePositionalArg, argv[i], i);
- continue; // We are done!
+ continue; // We are done!
}
if (!PositionalOpts.empty()) {
- PositionalVals.push_back(std::make_pair(argv[i],i));
+ PositionalVals.push_back(std::make_pair(argv[i], i));
// All of the positional arguments have been fulfulled, give the rest to
// the consume after option... if it's specified...
//
if (PositionalVals.size() >= NumPositionalRequired && ConsumeAfterOpt) {
for (++i; i < argc; ++i)
- PositionalVals.push_back(std::make_pair(argv[i],i));
- break; // Handle outside of the argument processing loop...
+ PositionalVals.push_back(std::make_pair(argv[i], i));
+ break; // Handle outside of the argument processing loop...
}
// Delay processing positional arguments until the end...
@@ -904,59 +943,60 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
}
} else if (argv[i][0] == '-' && argv[i][1] == '-' && argv[i][2] == 0 &&
!DashDashFound) {
- DashDashFound = true; // This is the mythical "--"?
- continue; // Don't try to process it as an argument itself.
+ DashDashFound = true; // This is the mythical "--"?
+ continue; // Don't try to process it as an argument itself.
} else if (ActivePositionalArg &&
(ActivePositionalArg->getMiscFlags() & PositionalEatsArgs)) {
// If there is a positional argument eating options, check to see if this
// option is another positional argument. If so, treat it as an argument,
// otherwise feed it to the eating positional.
- ArgName = argv[i]+1;
+ ArgName = argv[i] + 1;
// Eat leading dashes.
while (!ArgName.empty() && ArgName[0] == '-')
ArgName = ArgName.substr(1);
- Handler = LookupOption(ArgName, Value, Opts);
+ Handler = LookupOption(ArgName, Value);
if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
ProvidePositionalOption(ActivePositionalArg, argv[i], i);
- continue; // We are done!
+ continue; // We are done!
}
- } else { // We start with a '-', must be an argument.
- ArgName = argv[i]+1;
+ } else { // We start with a '-', must be an argument.
+ ArgName = argv[i] + 1;
// Eat leading dashes.
while (!ArgName.empty() && ArgName[0] == '-')
ArgName = ArgName.substr(1);
- Handler = LookupOption(ArgName, Value, Opts);
+ Handler = LookupOption(ArgName, Value);
// Check to see if this "option" is really a prefixed or grouped argument.
if (!Handler)
- Handler = HandlePrefixedOrGroupedOption(ArgName, Value,
- ErrorParsing, Opts);
+ Handler = HandlePrefixedOrGroupedOption(ArgName, Value, ErrorParsing,
+ OptionsMap);
// Otherwise, look for the closest available option to report to the user
// in the upcoming error.
if (!Handler && SinkOpts.empty())
- NearestHandler = LookupNearestOption(ArgName, Opts,
- NearestHandlerString);
+ NearestHandler =
+ LookupNearestOption(ArgName, OptionsMap, NearestHandlerString);
}
if (!Handler) {
if (SinkOpts.empty()) {
- errs() << ProgramName << ": Unknown command line argument '"
- << argv[i] << "'. Try: '" << argv[0] << " -help'\n";
+ errs() << ProgramName << ": Unknown command line argument '" << argv[i]
+ << "'. Try: '" << argv[0] << " -help'\n";
if (NearestHandler) {
// If we know a near match, report it as well.
- errs() << ProgramName << ": Did you mean '-"
- << NearestHandlerString << "'?\n";
+ errs() << ProgramName << ": Did you mean '-" << NearestHandlerString
+ << "'?\n";
}
ErrorParsing = true;
} else {
- for (SmallVectorImpl<Option*>::iterator I = SinkOpts.begin(),
- E = SinkOpts.end(); I != E ; ++I)
+ for (SmallVectorImpl<Option *>::iterator I = SinkOpts.begin(),
+ E = SinkOpts.end();
+ I != E; ++I)
(*I)->addOccurrence(i, "", argv[i]);
}
continue;
@@ -973,17 +1013,16 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Check and handle positional arguments now...
if (NumPositionalRequired > PositionalVals.size()) {
errs() << ProgramName
- << ": Not enough positional command line arguments specified!\n"
- << "Must specify at least " << NumPositionalRequired
- << " positional arguments: See: " << argv[0] << " -help\n";
+ << ": Not enough positional command line arguments specified!\n"
+ << "Must specify at least " << NumPositionalRequired
+ << " positional arguments: See: " << argv[0] << " -help\n";
ErrorParsing = true;
} else if (!HasUnlimitedPositionals &&
PositionalVals.size() > PositionalOpts.size()) {
- errs() << ProgramName
- << ": Too many positional arguments specified!\n"
- << "Can specify at most " << PositionalOpts.size()
- << " positional arguments: See: " << argv[0] << " -help\n";
+ errs() << ProgramName << ": Too many positional arguments specified!\n"
+ << "Can specify at most " << PositionalOpts.size()
+ << " positional arguments: See: " << argv[0] << " -help\n";
ErrorParsing = true;
} else if (!ConsumeAfterOpt) {
@@ -994,7 +1033,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
ProvidePositionalOption(PositionalOpts[i], PositionalVals[ValNo].first,
PositionalVals[ValNo].second);
ValNo++;
- --NumPositionalRequired; // We fulfilled our duty...
+ --NumPositionalRequired; // We fulfilled our duty...
}
// If we _can_ give this option more arguments, do so now, as long as we
@@ -1002,13 +1041,13 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// option even _WANTS_ any more.
//
bool Done = PositionalOpts[i]->getNumOccurrencesFlag() == cl::Required;
- while (NumVals-ValNo > NumPositionalRequired && !Done) {
+ while (NumVals - ValNo > NumPositionalRequired && !Done) {
switch (PositionalOpts[i]->getNumOccurrencesFlag()) {
case cl::Optional:
- Done = true; // Optional arguments want _at most_ one value
- // FALL THROUGH
- case cl::ZeroOrMore: // Zero or more will take all they can get...
- case cl::OneOrMore: // One or more will take all they can get...
+ Done = true; // Optional arguments want _at most_ one value
+ // FALL THROUGH
+ case cl::ZeroOrMore: // Zero or more will take all they can get...
+ case cl::OneOrMore: // One or more will take all they can get...
ProvidePositionalOption(PositionalOpts[i],
PositionalVals[ValNo].first,
PositionalVals[ValNo].second);
@@ -1016,7 +1055,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
break;
default:
llvm_unreachable("Internal error, unexpected NumOccurrences flag in "
- "positional argument processing!");
+ "positional argument processing!");
}
}
}
@@ -1036,8 +1075,8 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// positional option and keep the rest for the consume after. The above
// loop would have assigned no values to positional options in this case.
//
- if (PositionalOpts.size() == 2 && ValNo == 0 && !PositionalVals.empty()) {
- ErrorParsing |= ProvidePositionalOption(PositionalOpts[1],
+ if (PositionalOpts.size() == 1 && ValNo == 0 && !PositionalVals.empty()) {
+ ErrorParsing |= ProvidePositionalOption(PositionalOpts[0],
PositionalVals[ValNo].first,
PositionalVals[ValNo].second);
ValNo++;
@@ -1046,13 +1085,13 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Handle over all of the rest of the arguments to the
// cl::ConsumeAfter command line option...
for (; ValNo != PositionalVals.size(); ++ValNo)
- ErrorParsing |= ProvidePositionalOption(ConsumeAfterOpt,
- PositionalVals[ValNo].first,
- PositionalVals[ValNo].second);
+ ErrorParsing |=
+ ProvidePositionalOption(ConsumeAfterOpt, PositionalVals[ValNo].first,
+ PositionalVals[ValNo].second);
}
// Loop over args and make sure all required args are specified!
- for (const auto &Opt : Opts) {
+ for (const auto &Opt : OptionsMap) {
switch (Opt.second->getNumOccurrencesFlag()) {
case Required:
case OneOrMore:
@@ -1060,7 +1099,7 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
Opt.second->error("must be specified at least once!");
ErrorParsing = true;
}
- // Fall through
+ // Fall through
default:
break;
}
@@ -1070,19 +1109,16 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
// Note that if ReadResponseFiles == true, this must be done before the
// memory allocated for the expanded command line is free()d below.
DEBUG(dbgs() << "Args: ";
- for (int i = 0; i < argc; ++i)
- dbgs() << argv[i] << ' ';
- dbgs() << '\n';
- );
+ for (int i = 0; i < argc; ++i) dbgs() << argv[i] << ' ';
+ dbgs() << '\n';);
// Free all of the memory allocated to the map. Command line options may only
// be processed once!
- Opts.clear();
- PositionalOpts.clear();
- MoreHelp->clear();
+ MoreHelp.clear();
// If we had an error processing our arguments, don't let the program execute
- if (ErrorParsing) exit(1);
+ if (ErrorParsing)
+ exit(1);
}
//===----------------------------------------------------------------------===//
@@ -1090,20 +1126,21 @@ void cl::ParseCommandLineOptions(int argc, const char * const *argv,
//
bool Option::error(const Twine &Message, StringRef ArgName) {
- if (!ArgName.data()) ArgName = ArgStr;
+ if (!ArgName.data())
+ ArgName = ArgStr;
if (ArgName.empty())
- errs() << HelpStr; // Be nice for positional arguments
+ errs() << HelpStr; // Be nice for positional arguments
else
- errs() << ProgramName << ": for the -" << ArgName;
+ errs() << GlobalParser->ProgramName << ": for the -" << ArgName;
errs() << " option: " << Message << "\n";
return true;
}
-bool Option::addOccurrence(unsigned pos, StringRef ArgName,
- StringRef Value, bool MultiArg) {
+bool Option::addOccurrence(unsigned pos, StringRef ArgName, StringRef Value,
+ bool MultiArg) {
if (!MultiArg)
- NumOccurrences++; // Increment the number of times we have been seen
+ NumOccurrences++; // Increment the number of times we have been seen
switch (getNumOccurrencesFlag()) {
case Optional:
@@ -1113,21 +1150,22 @@ bool Option::addOccurrence(unsigned pos, StringRef ArgName,
case Required:
if (NumOccurrences > 1)
return error("must occur exactly one time!", ArgName);
- // Fall through
+ // Fall through
case OneOrMore:
case ZeroOrMore:
- case ConsumeAfter: break;
+ case ConsumeAfter:
+ break;
}
return handleOccurrence(pos, ArgName, Value);
}
-
// getValueStr - Get the value description string, using "DefaultMsg" if nothing
// has been specified yet.
//
static const char *getValueStr(const Option &O, const char *DefaultMsg) {
- if (O.ValueStr[0] == 0) return DefaultMsg;
+ if (O.ValueStr[0] == 0)
+ return DefaultMsg;
return O.ValueStr;
}
@@ -1136,9 +1174,7 @@ static const char *getValueStr(const Option &O, const char *DefaultMsg) {
//
// Return the width of the option tag for printing...
-size_t alias::getOptionWidth() const {
- return std::strlen(ArgStr)+6;
-}
+size_t alias::getOptionWidth() const { return std::strlen(ArgStr) + 6; }
static void printHelpStr(StringRef HelpStr, size_t Indent,
size_t FirstLineIndentedBy) {
@@ -1167,7 +1203,7 @@ void alias::printOptionInfo(size_t GlobalWidth) const {
size_t basic_parser_impl::getOptionWidth(const Option &O) const {
size_t Len = std::strlen(O.ArgStr);
if (const char *ValName = getValueName())
- Len += std::strlen(getValueStr(O, ValName))+3;
+ Len += std::strlen(getValueStr(O, ValName)) + 3;
return Len + 6;
}
@@ -1188,14 +1224,13 @@ void basic_parser_impl::printOptionInfo(const Option &O,
void basic_parser_impl::printOptionName(const Option &O,
size_t GlobalWidth) const {
outs() << " -" << O.ArgStr;
- outs().indent(GlobalWidth-std::strlen(O.ArgStr));
+ outs().indent(GlobalWidth - std::strlen(O.ArgStr));
}
-
// parser<bool> implementation
//
-bool parser<bool>::parse(Option &O, StringRef ArgName,
- StringRef Arg, bool &Value) {
+bool parser<bool>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ bool &Value) {
if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
Arg == "1") {
Value = true;
@@ -1212,8 +1247,8 @@ bool parser<bool>::parse(Option &O, StringRef ArgName,
// parser<boolOrDefault> implementation
//
-bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName,
- StringRef Arg, boolOrDefault &Value) {
+bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ boolOrDefault &Value) {
if (Arg == "" || Arg == "true" || Arg == "TRUE" || Arg == "True" ||
Arg == "1") {
Value = BOU_TRUE;
@@ -1230,8 +1265,8 @@ bool parser<boolOrDefault>::parse(Option &O, StringRef ArgName,
// parser<int> implementation
//
-bool parser<int>::parse(Option &O, StringRef ArgName,
- StringRef Arg, int &Value) {
+bool parser<int>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ int &Value) {
if (Arg.getAsInteger(0, Value))
return O.error("'" + Arg + "' value invalid for integer argument!");
return false;
@@ -1239,8 +1274,8 @@ bool parser<int>::parse(Option &O, StringRef ArgName,
// parser<unsigned> implementation
//
-bool parser<unsigned>::parse(Option &O, StringRef ArgName,
- StringRef Arg, unsigned &Value) {
+bool parser<unsigned>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ unsigned &Value) {
if (Arg.getAsInteger(0, Value))
return O.error("'" + Arg + "' value invalid for uint argument!");
@@ -1250,7 +1285,8 @@ bool parser<unsigned>::parse(Option &O, StringRef ArgName,
// parser<unsigned long long> implementation
//
bool parser<unsigned long long>::parse(Option &O, StringRef ArgName,
- StringRef Arg, unsigned long long &Value){
+ StringRef Arg,
+ unsigned long long &Value) {
if (Arg.getAsInteger(0, Value))
return O.error("'" + Arg + "' value invalid for uint argument!");
@@ -1269,13 +1305,13 @@ static bool parseDouble(Option &O, StringRef Arg, double &Value) {
return false;
}
-bool parser<double>::parse(Option &O, StringRef ArgName,
- StringRef Arg, double &Val) {
+bool parser<double>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ double &Val) {
return parseDouble(O, Arg, Val);
}
-bool parser<float>::parse(Option &O, StringRef ArgName,
- StringRef Arg, float &Val) {
+bool parser<float>::parse(Option &O, StringRef ArgName, StringRef Arg,
+ float &Val) {
double dVal;
if (parseDouble(O, Arg, dVal))
return true;
@@ -1283,8 +1319,6 @@ bool parser<float>::parse(Option &O, StringRef ArgName,
return false;
}
-
-
// generic_parser_base implementation
//
@@ -1301,18 +1335,17 @@ unsigned generic_parser_base::findOption(const char *Name) {
return e;
}
-
// Return the width of the option tag for printing...
size_t generic_parser_base::getOptionWidth(const Option &O) const {
if (O.hasArgStr()) {
- size_t Size = std::strlen(O.ArgStr)+6;
+ size_t Size = std::strlen(O.ArgStr) + 6;
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- Size = std::max(Size, std::strlen(getOption(i))+8);
+ Size = std::max(Size, std::strlen(getOption(i)) + 8);
return Size;
} else {
size_t BaseSize = 0;
for (unsigned i = 0, e = getNumOptions(); i != e; ++i)
- BaseSize = std::max(BaseSize, std::strlen(getOption(i))+8);
+ BaseSize = std::max(BaseSize, std::strlen(getOption(i)) + 8);
return BaseSize;
}
}
@@ -1327,7 +1360,7 @@ void generic_parser_base::printOptionInfo(const Option &O,
printHelpStr(O.HelpStr, GlobalWidth, std::strlen(O.ArgStr) + 6);
for (unsigned i = 0, e = getNumOptions(); i != e; ++i) {
- size_t NumSpaces = GlobalWidth-strlen(getOption(i))-8;
+ size_t NumSpaces = GlobalWidth - strlen(getOption(i)) - 8;
outs() << " =" << getOption(i);
outs().indent(NumSpaces) << " - " << getDescription(i) << '\n';
}
@@ -1347,12 +1380,11 @@ 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 {
+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));
+ outs().indent(GlobalWidth - std::strlen(O.ArgStr));
unsigned NumOpts = getNumOptions();
for (unsigned i = 0; i != NumOpts; ++i) {
@@ -1377,25 +1409,25 @@ printGenericOptionDiff(const Option &O, const GenericOptionValue &Value,
// 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"; \
- } \
+#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)
@@ -1406,9 +1438,9 @@ 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 {
+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;
@@ -1421,8 +1453,8 @@ printOptionDiff(const Option &O, StringRef V, OptionValue<std::string> D,
}
// Print a placeholder for options that don't yet support printOptionDiff().
-void basic_parser_impl::
-printOptionNoValue(const Option &O, size_t GlobalWidth) const {
+void basic_parser_impl::printOptionNoValue(const Option &O,
+ size_t GlobalWidth) const {
printOptionName(O, GlobalWidth);
outs() << "= *cannot print option value*\n";
}
@@ -1432,19 +1464,18 @@ printOptionNoValue(const Option &O, size_t GlobalWidth) const {
//
static int OptNameCompare(const void *LHS, const void *RHS) {
- typedef std::pair<const char *, Option*> pair_ty;
+ typedef std::pair<const char *, Option *> pair_ty;
- return strcmp(((const pair_ty*)LHS)->first, ((const pair_ty*)RHS)->first);
+ return strcmp(((const pair_ty *)LHS)->first, ((const 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.
+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();
+ for (StringMap<Option *>::iterator I = OptMap.begin(), E = OptMap.end();
I != E; ++I) {
// Ignore really-hidden options.
if (I->second->getOptionHiddenFlag() == ReallyHidden)
@@ -1458,8 +1489,8 @@ sortOpts(StringMap<Option*> &OptMap,
if (!OptionSet.insert(I->second).second)
continue;
- Opts.push_back(std::pair<const char *, Option*>(I->getKey().data(),
- I->second));
+ Opts.push_back(
+ std::pair<const char *, Option *>(I->getKey().data(), I->second));
}
// Sort the options list alphabetically.
@@ -1471,7 +1502,8 @@ namespace {
class HelpPrinter {
protected:
const bool ShowHidden;
- typedef SmallVector<std::pair<const char *, Option*>,128> StrOptionPairVector;
+ typedef SmallVector<std::pair<const char *, Option *>, 128>
+ StrOptionPairVector;
// Print the options. Opts is assumed to be alphabetically sorted.
virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
for (size_t i = 0, e = Opts.size(); i != e; ++i)
@@ -1484,36 +1516,26 @@ public:
// Invoke the printer.
void operator=(bool Value) {
- if (Value == false) return;
-
- // Get all the options.
- SmallVector<Option*, 4> PositionalOpts;
- SmallVector<Option*, 4> SinkOpts;
- StringMap<Option*> OptMap;
- GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
+ if (Value == false)
+ return;
StrOptionPairVector Opts;
- sortOpts(OptMap, Opts, ShowHidden);
-
- if (ProgramOverview)
- outs() << "OVERVIEW: " << ProgramOverview << "\n";
+ sortOpts(GlobalParser->OptionsMap, Opts, ShowHidden);
- outs() << "USAGE: " << ProgramName << " [options]";
+ if (GlobalParser->ProgramOverview)
+ outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";
- // Print out the positional options.
- Option *CAOpt = nullptr; // The cl::ConsumeAfter option, if it exists...
- if (!PositionalOpts.empty() &&
- PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
- CAOpt = PositionalOpts[0];
+ outs() << "USAGE: " << GlobalParser->ProgramName << " [options]";
- for (size_t i = CAOpt != nullptr, e = PositionalOpts.size(); i != e; ++i) {
- if (PositionalOpts[i]->ArgStr[0])
- outs() << " --" << PositionalOpts[i]->ArgStr;
- outs() << " " << PositionalOpts[i]->HelpStr;
+ for (auto Opt : GlobalParser->PositionalOpts) {
+ if (Opt->ArgStr[0])
+ outs() << " --" << Opt->ArgStr;
+ outs() << " " << Opt->HelpStr;
}
// Print the consume after option info if it exists...
- if (CAOpt) outs() << " " << CAOpt->HelpStr;
+ if (GlobalParser->ConsumeAfterOpt)
+ outs() << " " << GlobalParser->ConsumeAfterOpt->HelpStr;
outs() << "\n\n";
@@ -1526,11 +1548,9 @@ public:
printOptions(Opts, MaxArgLen);
// Print any extra help the user has declared.
- for (std::vector<const char *>::iterator I = MoreHelp->begin(),
- E = MoreHelp->end();
- I != E; ++I)
- outs() << *I;
- MoreHelp->clear();
+ for (auto I : GlobalParser->MoreHelp)
+ outs() << I;
+ GlobalParser->MoreHelp.clear();
// Halt the program since help information was printed
exit(0);
@@ -1549,17 +1569,17 @@ public:
}
// Make sure we inherit our base class's operator=()
- using HelpPrinter::operator= ;
+ using HelpPrinter::operator=;
protected:
void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) override {
std::vector<OptionCategory *> SortedCategories;
- std::map<OptionCategory *, std::vector<Option *> > CategorizedOptions;
+ std::map<OptionCategory *, std::vector<Option *>> CategorizedOptions;
// Collect registered option categories into vector in preparation for
// sorting.
- for (OptionCatSet::const_iterator I = RegisteredOptionCategories->begin(),
- E = RegisteredOptionCategories->end();
+ for (auto I = GlobalParser->RegisteredOptionCategories.begin(),
+ E = GlobalParser->RegisteredOptionCategories.end();
I != E; ++I) {
SortedCategories.push_back(*I);
}
@@ -1631,9 +1651,9 @@ private:
public:
explicit HelpPrinterWrapper(HelpPrinter &UncategorizedPrinter,
- CategorizedHelpPrinter &CategorizedPrinter) :
- UncategorizedPrinter(UncategorizedPrinter),
- CategorizedPrinter(CategorizedPrinter) { }
+ CategorizedHelpPrinter &CategorizedPrinter)
+ : UncategorizedPrinter(UncategorizedPrinter),
+ CategorizedPrinter(CategorizedPrinter) {}
// Invoke the printer.
void operator=(bool Value);
@@ -1648,7 +1668,6 @@ static HelpPrinter UncategorizedHiddenPrinter(true);
static CategorizedHelpPrinter CategorizedNormalPrinter(false);
static CategorizedHelpPrinter CategorizedHiddenPrinter(true);
-
// Declare HelpPrinter wrappers that will decide whether or not to invoke
// a categorizing help printer
static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter,
@@ -1656,41 +1675,45 @@ static HelpPrinterWrapper WrappedNormalPrinter(UncategorizedNormalPrinter,
static HelpPrinterWrapper WrappedHiddenPrinter(UncategorizedHiddenPrinter,
CategorizedHiddenPrinter);
+// Define a category for generic options that all tools should have.
+static cl::OptionCategory GenericCategory("Generic Options");
+
// Define uncategorized help printers.
// -help-list is hidden by default because if Option categories are being used
// then -help behaves the same as -help-list.
-static cl::opt<HelpPrinter, true, parser<bool> >
-HLOp("help-list",
- cl::desc("Display list of available options (-help-list-hidden for more)"),
- cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed);
+static cl::opt<HelpPrinter, true, parser<bool>> HLOp(
+ "help-list",
+ cl::desc("Display list of available options (-help-list-hidden for more)"),
+ cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed,
+ cl::cat(GenericCategory));
-static cl::opt<HelpPrinter, true, parser<bool> >
-HLHOp("help-list-hidden",
- cl::desc("Display list of all available options"),
- cl::location(UncategorizedHiddenPrinter), cl::Hidden, cl::ValueDisallowed);
+static cl::opt<HelpPrinter, true, parser<bool>>
+ HLHOp("help-list-hidden", cl::desc("Display list of all available options"),
+ cl::location(UncategorizedHiddenPrinter), cl::Hidden,
+ cl::ValueDisallowed, cl::cat(GenericCategory));
// Define uncategorized/categorized help printers. These printers change their
// behaviour at runtime depending on whether one or more Option categories have
// been declared.
-static cl::opt<HelpPrinterWrapper, true, parser<bool> >
-HOp("help", cl::desc("Display available options (-help-hidden for more)"),
- cl::location(WrappedNormalPrinter), cl::ValueDisallowed);
-
-static cl::opt<HelpPrinterWrapper, true, parser<bool> >
-HHOp("help-hidden", cl::desc("Display all available options"),
- cl::location(WrappedHiddenPrinter), 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));
+static cl::opt<HelpPrinterWrapper, true, parser<bool>>
+ HOp("help", cl::desc("Display available options (-help-hidden for more)"),
+ cl::location(WrappedNormalPrinter), cl::ValueDisallowed,
+ cl::cat(GenericCategory));
+
+static cl::opt<HelpPrinterWrapper, true, parser<bool>>
+ HHOp("help-hidden", cl::desc("Display all available options"),
+ cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed,
+ cl::cat(GenericCategory));
+
+static cl::opt<bool> PrintOptions(
+ "print-options",
+ cl::desc("Print non-default options after command line parsing"),
+ cl::Hidden, cl::init(false), cl::cat(GenericCategory));
+
+static cl::opt<bool> PrintAllOptions(
+ "print-all-options",
+ cl::desc("Print all option values after command line parsing"), cl::Hidden,
+ cl::init(false), cl::cat(GenericCategory));
void HelpPrinterWrapper::operator=(bool Value) {
if (Value == false)
@@ -1699,29 +1722,25 @@ void HelpPrinterWrapper::operator=(bool Value) {
// Decide which printer to invoke. If more than one option category is
// registered then it is useful to show the categorized help instead of
// uncategorized help.
- if (RegisteredOptionCategories->size() > 1) {
+ if (GlobalParser->RegisteredOptionCategories.size() > 1) {
// unhide -help-list option so user can have uncategorized output if they
// want it.
HLOp.setHiddenFlag(NotHidden);
CategorizedPrinter = true; // Invoke categorized printer
- }
- else
+ } else
UncategorizedPrinter = true; // Invoke uncategorized printer
}
// Print the value of each option.
-void cl::PrintOptionValues() {
- if (!PrintOptions && !PrintAllOptions) return;
+void cl::PrintOptionValues() { GlobalParser->printOptionValues(); }
- // Get all the options.
- SmallVector<Option*, 4> PositionalOpts;
- SmallVector<Option*, 4> SinkOpts;
- StringMap<Option*> OptMap;
- GetOptionInfo(PositionalOpts, SinkOpts, OptMap);
+void CommandLineParser::printOptionValues() {
+ if (!PrintOptions && !PrintAllOptions)
+ return;
- SmallVector<std::pair<const char *, Option*>, 128> Opts;
- sortOpts(OptMap, Opts, /*ShowHidden*/true);
+ SmallVector<std::pair<const char *, Option *>, 128> Opts;
+ sortOpts(OptionsMap, Opts, /*ShowHidden*/ true);
// Compute the maximum argument length...
size_t MaxArgLen = 0;
@@ -1734,7 +1753,7 @@ void cl::PrintOptionValues() {
static void (*OverrideVersionPrinter)() = nullptr;
-static std::vector<void (*)()>* ExtraVersionPrinters = nullptr;
+static std::vector<void (*)()> *ExtraVersionPrinters = nullptr;
namespace {
class VersionPrinter {
@@ -1756,7 +1775,8 @@ public:
OS << " with assertions";
#endif
std::string CPU = sys::getHostCPUName();
- if (CPU == "generic") CPU = "(unknown)";
+ if (CPU == "generic")
+ CPU = "(unknown)";
OS << ".\n"
#if (ENABLE_TIMESTAMPS == 1)
<< " Built " << __DATE__ << " (" << __TIME__ << ").\n"
@@ -1765,7 +1785,8 @@ public:
<< " Host CPU: " << CPU << '\n';
}
void operator=(bool OptionWasSpecified) {
- if (!OptionWasSpecified) return;
+ if (!OptionWasSpecified)
+ return;
if (OverrideVersionPrinter != nullptr) {
(*OverrideVersionPrinter)();
@@ -1788,13 +1809,13 @@ public:
};
} // End anonymous namespace
-
// Define the --version option that prints out the LLVM version for the tool
static VersionPrinter VersionPrinterInstance;
-static cl::opt<VersionPrinter, true, parser<bool> >
-VersOp("version", cl::desc("Display the version of this program"),
- cl::location(VersionPrinterInstance), cl::ValueDisallowed);
+static cl::opt<VersionPrinter, true, parser<bool>>
+ VersOp("version", cl::desc("Display the version of this program"),
+ cl::location(VersionPrinterInstance), cl::ValueDisallowed,
+ cl::cat(GenericCategory));
// Utility function for printing the help message.
void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
@@ -1816,13 +1837,9 @@ void cl::PrintHelpMessage(bool Hidden, bool Categorized) {
}
/// Utility function for printing version number.
-void cl::PrintVersionMessage() {
- VersionPrinterInstance.print();
-}
+void cl::PrintVersionMessage() { VersionPrinterInstance.print(); }
-void cl::SetVersionPrinter(void (*func)()) {
- OverrideVersionPrinter = func;
-}
+void cl::SetVersionPrinter(void (*func)()) { OverrideVersionPrinter = func; }
void cl::AddExtraVersionPrinter(void (*func)()) {
if (!ExtraVersionPrinters)
@@ -1831,14 +1848,27 @@ void cl::AddExtraVersionPrinter(void (*func)()) {
ExtraVersionPrinters->push_back(func);
}
-void cl::getRegisteredOptions(StringMap<Option*> &Map)
-{
- // Get all the options.
- SmallVector<Option*, 4> PositionalOpts; //NOT USED
- SmallVector<Option*, 4> SinkOpts; //NOT USED
- assert(Map.size() == 0 && "StringMap must be empty");
- GetOptionInfo(PositionalOpts, SinkOpts, Map);
- return;
+StringMap<Option *> &cl::getRegisteredOptions() {
+ return GlobalParser->OptionsMap;
+}
+
+void cl::HideUnrelatedOptions(cl::OptionCategory &Category) {
+ for (auto &I : GlobalParser->OptionsMap) {
+ if (I.second->Category != &Category &&
+ I.second->Category != &GenericCategory)
+ I.second->setHiddenFlag(cl::ReallyHidden);
+ }
+}
+
+void cl::HideUnrelatedOptions(ArrayRef<const cl::OptionCategory *> Categories) {
+ auto CategoriesBegin = Categories.begin();
+ auto CategoriesEnd = Categories.end();
+ for (auto &I : GlobalParser->OptionsMap) {
+ if (std::find(CategoriesBegin, CategoriesEnd, I.second->Category) ==
+ CategoriesEnd &&
+ I.second->Category != &GenericCategory)
+ I.second->setHiddenFlag(cl::ReallyHidden);
+ }
}
void LLVMParseCommandLineOptions(int argc, const char *const *argv,
diff --git a/lib/Support/Compression.cpp b/lib/Support/Compression.cpp
index c32eb213..17ae295 100644
--- a/lib/Support/Compression.cpp
+++ b/lib/Support/Compression.cpp
@@ -54,6 +54,9 @@ zlib::Status zlib::compress(StringRef InputBuffer,
Status Res = encodeZlibReturnValue(::compress2(
(Bytef *)CompressedBuffer.data(), &CompressedSize,
(const Bytef *)InputBuffer.data(), InputBuffer.size(), CLevel));
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(CompressedBuffer.data(), CompressedSize);
CompressedBuffer.resize(CompressedSize);
return Res;
}
@@ -65,6 +68,9 @@ zlib::Status zlib::uncompress(StringRef InputBuffer,
Status Res = encodeZlibReturnValue(::uncompress(
(Bytef *)UncompressedBuffer.data(), (uLongf *)&UncompressedSize,
(const Bytef *)InputBuffer.data(), InputBuffer.size()));
+ // Tell MemorySanitizer that zlib output buffer is fully initialized.
+ // This avoids a false report when running LLVM with uninstrumented ZLib.
+ __msan_unpoison(UncompressedBuffer.data(), UncompressedSize);
UncompressedBuffer.resize(UncompressedSize);
return Res;
}
diff --git a/lib/Support/ConvertUTFWrapper.cpp b/lib/Support/ConvertUTFWrapper.cpp
index e45335d..1bbef23 100644
--- a/lib/Support/ConvertUTFWrapper.cpp
+++ b/lib/Support/ConvertUTFWrapper.cpp
@@ -109,8 +109,9 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
if (Src[0] == UNI_UTF16_BYTE_ORDER_MARK_NATIVE)
Src++;
- // Just allocate enough space up front. We'll shrink it later.
- Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT);
+ // Just allocate enough space up front. We'll shrink it later. Allocate
+ // enough that we can fit a null terminator without reallocating.
+ Out.resize(SrcBytes.size() * UNI_MAX_UTF8_BYTES_PER_CODE_POINT + 1);
UTF8 *Dst = reinterpret_cast<UTF8 *>(&Out[0]);
UTF8 *DstEnd = Dst + Out.size();
@@ -124,6 +125,46 @@ bool convertUTF16ToUTF8String(ArrayRef<char> SrcBytes, std::string &Out) {
}
Out.resize(reinterpret_cast<char *>(Dst) - &Out[0]);
+ Out.push_back(0);
+ Out.pop_back();
+ return true;
+}
+
+bool convertUTF8ToUTF16String(StringRef SrcUTF8,
+ SmallVectorImpl<UTF16> &DstUTF16) {
+ assert(DstUTF16.empty());
+
+ // Avoid OOB by returning early on empty input.
+ if (SrcUTF8.empty()) {
+ DstUTF16.push_back(0);
+ DstUTF16.pop_back();
+ return true;
+ }
+
+ const UTF8 *Src = reinterpret_cast<const UTF8 *>(SrcUTF8.begin());
+ const UTF8 *SrcEnd = reinterpret_cast<const UTF8 *>(SrcUTF8.end());
+
+ // Allocate the same number of UTF-16 code units as UTF-8 code units. Encoding
+ // as UTF-16 should always require the same amount or less code units than the
+ // UTF-8 encoding. Allocate one extra byte for the null terminator though,
+ // so that someone calling DstUTF16.data() gets a null terminated string.
+ // We resize down later so we don't have to worry that this over allocates.
+ DstUTF16.resize(SrcUTF8.size()+1);
+ UTF16 *Dst = &DstUTF16[0];
+ UTF16 *DstEnd = Dst + DstUTF16.size();
+
+ ConversionResult CR =
+ ConvertUTF8toUTF16(&Src, SrcEnd, &Dst, DstEnd, strictConversion);
+ assert(CR != targetExhausted);
+
+ if (CR != conversionOK) {
+ DstUTF16.clear();
+ return false;
+ }
+
+ DstUTF16.resize(Dst - &DstUTF16[0]);
+ DstUTF16.push_back(0);
+ DstUTF16.pop_back();
return true;
}
diff --git a/lib/Support/Debug.cpp b/lib/Support/Debug.cpp
index 8246542..9c58ae8 100644
--- a/lib/Support/Debug.cpp
+++ b/lib/Support/Debug.cpp
@@ -25,15 +25,51 @@
#include "llvm/Support/Debug.h"
#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Signals.h"
#include "llvm/Support/circular_raw_ostream.h"
-#include "llvm/Support/ManagedStatic.h"
+
+#undef isCurrentDebugType
+#undef setCurrentDebugType
using namespace llvm;
+// Even though LLVM might be built with NDEBUG, define symbols that the code
+// built without NDEBUG can depend on via the llvm/Support/Debug.h header.
+namespace llvm {
+/// Exported boolean set by the -debug option.
+bool DebugFlag = false;
+
+static ManagedStatic<std::vector<std::string>> CurrentDebugType;
+
+/// Return true if the specified string is the debug type
+/// specified on the command line, or if none was specified on the command line
+/// with the -debug-only=X option.
+bool isCurrentDebugType(const char *DebugType) {
+ if (CurrentDebugType->empty())
+ return true;
+ // see if DebugType is in list. Note: do not use find() as that forces us to
+ // unnecessarily create an std::string instance.
+ for (auto d : *CurrentDebugType) {
+ if (d == DebugType)
+ return true;
+ }
+ return false;
+}
+
+/// Set the current debug type, as if the -debug-only=X
+/// option were specified. Note that DebugFlag also needs to be set to true for
+/// debug output to be produced.
+///
+void setCurrentDebugType(const char *Type) {
+ CurrentDebugType->clear();
+ CurrentDebugType->push_back(Type);
+}
+
+} // namespace llvm
+
// All Debug.h functionality is a no-op in NDEBUG mode.
#ifndef NDEBUG
-bool llvm::DebugFlag; // DebugFlag - Exported boolean set by the -debug option
// -debug - Command line option to enable the DEBUG statements in the passes.
// This flag may only be enabled in debug builds.
@@ -51,14 +87,14 @@ DebugBufferSize("debug-buffer-size",
cl::Hidden,
cl::init(0));
-static ManagedStatic<std::string> CurrentDebugType;
-
namespace {
struct DebugOnlyOpt {
void operator=(const std::string &Val) const {
- DebugFlag |= !Val.empty();
- *CurrentDebugType = Val;
+ if (Val.empty())
+ return;
+ DebugFlag = true;
+ CurrentDebugType->push_back(Val);
}
};
@@ -68,7 +104,7 @@ static DebugOnlyOpt DebugOnlyOptLoc;
static cl::opt<DebugOnlyOpt, true, cl::parser<std::string> >
DebugOnly("debug-only", cl::desc("Enable a specific type of debug output"),
- cl::Hidden, cl::value_desc("debug string"),
+ cl::Hidden, cl::ZeroOrMore, cl::value_desc("debug string"),
cl::location(DebugOnlyOptLoc), cl::ValueRequired);
// Signal handlers - dump debug output on termination.
@@ -82,22 +118,6 @@ static void debug_user_sig_handler(void *Cookie) {
dbgout->flushBufferWithBanner();
}
-// isCurrentDebugType - Return true if the specified string is the debug type
-// specified on the command line, or if none was specified on the command line
-// with the -debug-only=X option.
-//
-bool llvm::isCurrentDebugType(const char *DebugType) {
- return CurrentDebugType->empty() || DebugType == *CurrentDebugType;
-}
-
-/// setCurrentDebugType - Set the current debug type, as if the -debug-only=X
-/// option were specified. Note that DebugFlag also needs to be set to true for
-/// debug output to be produced.
-///
-void llvm::setCurrentDebugType(const char *Type) {
- *CurrentDebugType = Type;
-}
-
/// dbgs - Return a circular-buffered debug stream.
raw_ostream &llvm::dbgs() {
// Do one-time initialization in a thread-safe way.
diff --git a/lib/Support/Dwarf.cpp b/lib/Support/Dwarf.cpp
index 4b6337e..95c4bc3 100644
--- a/lib/Support/Dwarf.cpp
+++ b/lib/Support/Dwarf.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Dwarf.h"
+#include "llvm/ADT/StringSwitch.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
@@ -19,87 +20,19 @@ using namespace dwarf;
const char *llvm::dwarf::TagString(unsigned Tag) {
switch (Tag) {
- case DW_TAG_array_type: return "DW_TAG_array_type";
- case DW_TAG_class_type: return "DW_TAG_class_type";
- case DW_TAG_entry_point: return "DW_TAG_entry_point";
- case DW_TAG_enumeration_type: return "DW_TAG_enumeration_type";
- case DW_TAG_formal_parameter: return "DW_TAG_formal_parameter";
- case DW_TAG_imported_declaration: return "DW_TAG_imported_declaration";
- case DW_TAG_label: return "DW_TAG_label";
- case DW_TAG_lexical_block: return "DW_TAG_lexical_block";
- case DW_TAG_member: return "DW_TAG_member";
- case DW_TAG_pointer_type: return "DW_TAG_pointer_type";
- case DW_TAG_reference_type: return "DW_TAG_reference_type";
- case DW_TAG_compile_unit: return "DW_TAG_compile_unit";
- case DW_TAG_string_type: return "DW_TAG_string_type";
- case DW_TAG_structure_type: return "DW_TAG_structure_type";
- case DW_TAG_subroutine_type: return "DW_TAG_subroutine_type";
- case DW_TAG_typedef: return "DW_TAG_typedef";
- case DW_TAG_union_type: return "DW_TAG_union_type";
- case DW_TAG_unspecified_parameters: return "DW_TAG_unspecified_parameters";
- case DW_TAG_variant: return "DW_TAG_variant";
- case DW_TAG_common_block: return "DW_TAG_common_block";
- case DW_TAG_common_inclusion: return "DW_TAG_common_inclusion";
- case DW_TAG_inheritance: return "DW_TAG_inheritance";
- case DW_TAG_inlined_subroutine: return "DW_TAG_inlined_subroutine";
- case DW_TAG_module: return "DW_TAG_module";
- case DW_TAG_ptr_to_member_type: return "DW_TAG_ptr_to_member_type";
- case DW_TAG_set_type: return "DW_TAG_set_type";
- case DW_TAG_subrange_type: return "DW_TAG_subrange_type";
- case DW_TAG_with_stmt: return "DW_TAG_with_stmt";
- case DW_TAG_access_declaration: return "DW_TAG_access_declaration";
- case DW_TAG_base_type: return "DW_TAG_base_type";
- case DW_TAG_catch_block: return "DW_TAG_catch_block";
- case DW_TAG_const_type: return "DW_TAG_const_type";
- case DW_TAG_constant: return "DW_TAG_constant";
- case DW_TAG_enumerator: return "DW_TAG_enumerator";
- case DW_TAG_file_type: return "DW_TAG_file_type";
- case DW_TAG_friend: return "DW_TAG_friend";
- case DW_TAG_namelist: return "DW_TAG_namelist";
- case DW_TAG_namelist_item: return "DW_TAG_namelist_item";
- case DW_TAG_packed_type: return "DW_TAG_packed_type";
- case DW_TAG_subprogram: return "DW_TAG_subprogram";
- case DW_TAG_template_type_parameter: return "DW_TAG_template_type_parameter";
- case DW_TAG_template_value_parameter: return "DW_TAG_template_value_parameter";
- case DW_TAG_thrown_type: return "DW_TAG_thrown_type";
- case DW_TAG_try_block: return "DW_TAG_try_block";
- case DW_TAG_variant_part: return "DW_TAG_variant_part";
- case DW_TAG_variable: return "DW_TAG_variable";
- case DW_TAG_volatile_type: return "DW_TAG_volatile_type";
- case DW_TAG_dwarf_procedure: return "DW_TAG_dwarf_procedure";
- case DW_TAG_restrict_type: return "DW_TAG_restrict_type";
- case DW_TAG_interface_type: return "DW_TAG_interface_type";
- case DW_TAG_namespace: return "DW_TAG_namespace";
- case DW_TAG_imported_module: return "DW_TAG_imported_module";
- case DW_TAG_unspecified_type: return "DW_TAG_unspecified_type";
- case DW_TAG_partial_unit: return "DW_TAG_partial_unit";
- case DW_TAG_imported_unit: return "DW_TAG_imported_unit";
- case DW_TAG_condition: return "DW_TAG_condition";
- case DW_TAG_shared_type: return "DW_TAG_shared_type";
- case DW_TAG_lo_user: return "DW_TAG_lo_user";
- case DW_TAG_hi_user: return "DW_TAG_hi_user";
- case DW_TAG_auto_variable: return "DW_TAG_auto_variable";
- case DW_TAG_arg_variable: return "DW_TAG_arg_variable";
- case DW_TAG_expression: return "DW_TAG_expression";
- case DW_TAG_rvalue_reference_type: return "DW_TAG_rvalue_reference_type";
- case DW_TAG_template_alias: return "DW_TAG_template_alias";
- case DW_TAG_coarray_type: return "DW_TAG_coarray_type";
- case DW_TAG_generic_subrange: return "DW_TAG_generic_subrange";
- case DW_TAG_dynamic_type: return "DW_TAG_dynamic_type";
- case DW_TAG_MIPS_loop: return "DW_TAG_MIPS_loop";
- case DW_TAG_type_unit: return "DW_TAG_type_unit";
- case DW_TAG_format_label: return "DW_TAG_format_label";
- case DW_TAG_function_template: return "DW_TAG_function_template";
- case DW_TAG_class_template: return "DW_TAG_class_template";
- case DW_TAG_GNU_template_template_param:
- return "DW_TAG_GNU_template_template_param";
- case DW_TAG_GNU_template_parameter_pack:
- return "DW_TAG_GNU_template_parameter_pack";
- case DW_TAG_GNU_formal_parameter_pack:
- return "DW_TAG_GNU_formal_parameter_pack";
- case DW_TAG_APPLE_property: return "DW_TAG_APPLE_property";
+ default: return nullptr;
+#define HANDLE_DW_TAG(ID, NAME) \
+ case DW_TAG_##NAME: \
+ return "DW_TAG_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
+}
+
+unsigned llvm::dwarf::getTag(StringRef TagString) {
+ return StringSwitch<unsigned>(TagString)
+#define HANDLE_DW_TAG(ID, NAME) .Case("DW_TAG_" #NAME, DW_TAG_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(DW_TAG_invalid);
}
const char *llvm::dwarf::ChildrenString(unsigned Children) {
@@ -306,193 +239,36 @@ const char *llvm::dwarf::FormEncodingString(unsigned Encoding) {
const char *llvm::dwarf::OperationEncodingString(unsigned Encoding) {
switch (Encoding) {
- case DW_OP_addr: return "DW_OP_addr";
- case DW_OP_deref: return "DW_OP_deref";
- case DW_OP_const1u: return "DW_OP_const1u";
- case DW_OP_const1s: return "DW_OP_const1s";
- case DW_OP_const2u: return "DW_OP_const2u";
- case DW_OP_const2s: return "DW_OP_const2s";
- case DW_OP_const4u: return "DW_OP_const4u";
- case DW_OP_const4s: return "DW_OP_const4s";
- case DW_OP_const8u: return "DW_OP_const8u";
- case DW_OP_const8s: return "DW_OP_const8s";
- case DW_OP_constu: return "DW_OP_constu";
- case DW_OP_consts: return "DW_OP_consts";
- case DW_OP_dup: return "DW_OP_dup";
- case DW_OP_drop: return "DW_OP_drop";
- case DW_OP_over: return "DW_OP_over";
- case DW_OP_pick: return "DW_OP_pick";
- case DW_OP_swap: return "DW_OP_swap";
- case DW_OP_rot: return "DW_OP_rot";
- case DW_OP_xderef: return "DW_OP_xderef";
- case DW_OP_abs: return "DW_OP_abs";
- case DW_OP_and: return "DW_OP_and";
- case DW_OP_div: return "DW_OP_div";
- case DW_OP_minus: return "DW_OP_minus";
- case DW_OP_mod: return "DW_OP_mod";
- case DW_OP_mul: return "DW_OP_mul";
- case DW_OP_neg: return "DW_OP_neg";
- case DW_OP_not: return "DW_OP_not";
- case DW_OP_or: return "DW_OP_or";
- case DW_OP_plus: return "DW_OP_plus";
- case DW_OP_plus_uconst: return "DW_OP_plus_uconst";
- case DW_OP_shl: return "DW_OP_shl";
- case DW_OP_shr: return "DW_OP_shr";
- case DW_OP_shra: return "DW_OP_shra";
- case DW_OP_xor: return "DW_OP_xor";
- case DW_OP_skip: return "DW_OP_skip";
- case DW_OP_bra: return "DW_OP_bra";
- case DW_OP_eq: return "DW_OP_eq";
- case DW_OP_ge: return "DW_OP_ge";
- case DW_OP_gt: return "DW_OP_gt";
- case DW_OP_le: return "DW_OP_le";
- case DW_OP_lt: return "DW_OP_lt";
- case DW_OP_ne: return "DW_OP_ne";
- case DW_OP_lit0: return "DW_OP_lit0";
- case DW_OP_lit1: return "DW_OP_lit1";
- case DW_OP_lit2: return "DW_OP_lit2";
- case DW_OP_lit3: return "DW_OP_lit3";
- case DW_OP_lit4: return "DW_OP_lit4";
- case DW_OP_lit5: return "DW_OP_lit5";
- case DW_OP_lit6: return "DW_OP_lit6";
- case DW_OP_lit7: return "DW_OP_lit7";
- case DW_OP_lit8: return "DW_OP_lit8";
- case DW_OP_lit9: return "DW_OP_lit9";
- case DW_OP_lit10: return "DW_OP_lit10";
- case DW_OP_lit11: return "DW_OP_lit11";
- case DW_OP_lit12: return "DW_OP_lit12";
- case DW_OP_lit13: return "DW_OP_lit13";
- case DW_OP_lit14: return "DW_OP_lit14";
- case DW_OP_lit15: return "DW_OP_lit15";
- case DW_OP_lit16: return "DW_OP_lit16";
- case DW_OP_lit17: return "DW_OP_lit17";
- case DW_OP_lit18: return "DW_OP_lit18";
- case DW_OP_lit19: return "DW_OP_lit19";
- case DW_OP_lit20: return "DW_OP_lit20";
- case DW_OP_lit21: return "DW_OP_lit21";
- case DW_OP_lit22: return "DW_OP_lit22";
- case DW_OP_lit23: return "DW_OP_lit23";
- case DW_OP_lit24: return "DW_OP_lit24";
- case DW_OP_lit25: return "DW_OP_lit25";
- case DW_OP_lit26: return "DW_OP_lit26";
- case DW_OP_lit27: return "DW_OP_lit27";
- case DW_OP_lit28: return "DW_OP_lit28";
- case DW_OP_lit29: return "DW_OP_lit29";
- case DW_OP_lit30: return "DW_OP_lit30";
- case DW_OP_lit31: return "DW_OP_lit31";
- case DW_OP_reg0: return "DW_OP_reg0";
- case DW_OP_reg1: return "DW_OP_reg1";
- case DW_OP_reg2: return "DW_OP_reg2";
- case DW_OP_reg3: return "DW_OP_reg3";
- case DW_OP_reg4: return "DW_OP_reg4";
- case DW_OP_reg5: return "DW_OP_reg5";
- case DW_OP_reg6: return "DW_OP_reg6";
- case DW_OP_reg7: return "DW_OP_reg7";
- case DW_OP_reg8: return "DW_OP_reg8";
- case DW_OP_reg9: return "DW_OP_reg9";
- case DW_OP_reg10: return "DW_OP_reg10";
- case DW_OP_reg11: return "DW_OP_reg11";
- case DW_OP_reg12: return "DW_OP_reg12";
- case DW_OP_reg13: return "DW_OP_reg13";
- case DW_OP_reg14: return "DW_OP_reg14";
- case DW_OP_reg15: return "DW_OP_reg15";
- case DW_OP_reg16: return "DW_OP_reg16";
- case DW_OP_reg17: return "DW_OP_reg17";
- case DW_OP_reg18: return "DW_OP_reg18";
- case DW_OP_reg19: return "DW_OP_reg19";
- case DW_OP_reg20: return "DW_OP_reg20";
- case DW_OP_reg21: return "DW_OP_reg21";
- case DW_OP_reg22: return "DW_OP_reg22";
- case DW_OP_reg23: return "DW_OP_reg23";
- case DW_OP_reg24: return "DW_OP_reg24";
- case DW_OP_reg25: return "DW_OP_reg25";
- case DW_OP_reg26: return "DW_OP_reg26";
- case DW_OP_reg27: return "DW_OP_reg27";
- case DW_OP_reg28: return "DW_OP_reg28";
- case DW_OP_reg29: return "DW_OP_reg29";
- case DW_OP_reg30: return "DW_OP_reg30";
- case DW_OP_reg31: return "DW_OP_reg31";
- case DW_OP_breg0: return "DW_OP_breg0";
- case DW_OP_breg1: return "DW_OP_breg1";
- case DW_OP_breg2: return "DW_OP_breg2";
- case DW_OP_breg3: return "DW_OP_breg3";
- case DW_OP_breg4: return "DW_OP_breg4";
- case DW_OP_breg5: return "DW_OP_breg5";
- case DW_OP_breg6: return "DW_OP_breg6";
- case DW_OP_breg7: return "DW_OP_breg7";
- case DW_OP_breg8: return "DW_OP_breg8";
- case DW_OP_breg9: return "DW_OP_breg9";
- case DW_OP_breg10: return "DW_OP_breg10";
- case DW_OP_breg11: return "DW_OP_breg11";
- case DW_OP_breg12: return "DW_OP_breg12";
- case DW_OP_breg13: return "DW_OP_breg13";
- case DW_OP_breg14: return "DW_OP_breg14";
- case DW_OP_breg15: return "DW_OP_breg15";
- case DW_OP_breg16: return "DW_OP_breg16";
- case DW_OP_breg17: return "DW_OP_breg17";
- case DW_OP_breg18: return "DW_OP_breg18";
- case DW_OP_breg19: return "DW_OP_breg19";
- case DW_OP_breg20: return "DW_OP_breg20";
- case DW_OP_breg21: return "DW_OP_breg21";
- case DW_OP_breg22: return "DW_OP_breg22";
- case DW_OP_breg23: return "DW_OP_breg23";
- case DW_OP_breg24: return "DW_OP_breg24";
- case DW_OP_breg25: return "DW_OP_breg25";
- case DW_OP_breg26: return "DW_OP_breg26";
- case DW_OP_breg27: return "DW_OP_breg27";
- case DW_OP_breg28: return "DW_OP_breg28";
- case DW_OP_breg29: return "DW_OP_breg29";
- case DW_OP_breg30: return "DW_OP_breg30";
- case DW_OP_breg31: return "DW_OP_breg31";
- case DW_OP_regx: return "DW_OP_regx";
- case DW_OP_fbreg: return "DW_OP_fbreg";
- case DW_OP_bregx: return "DW_OP_bregx";
- case DW_OP_piece: return "DW_OP_piece";
- case DW_OP_deref_size: return "DW_OP_deref_size";
- case DW_OP_xderef_size: return "DW_OP_xderef_size";
- case DW_OP_nop: return "DW_OP_nop";
- case DW_OP_push_object_address: return "DW_OP_push_object_address";
- case DW_OP_call2: return "DW_OP_call2";
- case DW_OP_call4: return "DW_OP_call4";
- 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_implicit_value: return "DW_OP_implicit_value";
- case DW_OP_stack_value: return "DW_OP_stack_value";
-
- // GNU thread-local storage
- case DW_OP_GNU_push_tls_address: return "DW_OP_GNU_push_tls_address";
-
- // DWARF5 Fission Proposal Op Extensions
- case DW_OP_GNU_addr_index: return "DW_OP_GNU_addr_index";
- case DW_OP_GNU_const_index: return "DW_OP_GNU_const_index";
+ default: return nullptr;
+#define HANDLE_DW_OP(ID, NAME) \
+ case DW_OP_##NAME: \
+ return "DW_OP_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
+}
+
+unsigned llvm::dwarf::getOperationEncoding(StringRef OperationEncodingString) {
+ return StringSwitch<unsigned>(OperationEncodingString)
+#define HANDLE_DW_OP(ID, NAME) .Case("DW_OP_" #NAME, DW_OP_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(0);
}
const char *llvm::dwarf::AttributeEncodingString(unsigned Encoding) {
switch (Encoding) {
- case DW_ATE_address: return "DW_ATE_address";
- case DW_ATE_boolean: return "DW_ATE_boolean";
- case DW_ATE_complex_float: return "DW_ATE_complex_float";
- case DW_ATE_float: return "DW_ATE_float";
- case DW_ATE_signed: return "DW_ATE_signed";
- case DW_ATE_signed_char: return "DW_ATE_signed_char";
- case DW_ATE_unsigned: return "DW_ATE_unsigned";
- case DW_ATE_unsigned_char: return "DW_ATE_unsigned_char";
- case DW_ATE_imaginary_float: return "DW_ATE_imaginary_float";
- case DW_ATE_UTF: return "DW_ATE_UTF";
- case DW_ATE_packed_decimal: return "DW_ATE_packed_decimal";
- case DW_ATE_numeric_string: return "DW_ATE_numeric_string";
- case DW_ATE_edited: return "DW_ATE_edited";
- case DW_ATE_signed_fixed: return "DW_ATE_signed_fixed";
- case DW_ATE_unsigned_fixed: return "DW_ATE_unsigned_fixed";
- case DW_ATE_decimal_float: return "DW_ATE_decimal_float";
- case DW_ATE_lo_user: return "DW_ATE_lo_user";
- case DW_ATE_hi_user: return "DW_ATE_hi_user";
+ default: return nullptr;
+#define HANDLE_DW_ATE(ID, NAME) \
+ case DW_ATE_##NAME: \
+ return "DW_ATE_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
+}
+
+unsigned llvm::dwarf::getAttributeEncoding(StringRef EncodingString) {
+ return StringSwitch<unsigned>(EncodingString)
+#define HANDLE_DW_ATE(ID, NAME) .Case("DW_ATE_" #NAME, DW_ATE_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(0);
}
const char *llvm::dwarf::DecimalSignString(unsigned Sign) {
@@ -538,47 +314,39 @@ const char *llvm::dwarf::VisibilityString(unsigned Visibility) {
const char *llvm::dwarf::VirtualityString(unsigned Virtuality) {
switch (Virtuality) {
- case DW_VIRTUALITY_none: return "DW_VIRTUALITY_none";
- case DW_VIRTUALITY_virtual: return "DW_VIRTUALITY_virtual";
- case DW_VIRTUALITY_pure_virtual: return "DW_VIRTUALITY_pure_virtual";
+ default:
+ return nullptr;
+#define HANDLE_DW_VIRTUALITY(ID, NAME) \
+ case DW_VIRTUALITY_##NAME: \
+ return "DW_VIRTUALITY_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
+}
+
+unsigned llvm::dwarf::getVirtuality(StringRef VirtualityString) {
+ return StringSwitch<unsigned>(VirtualityString)
+#define HANDLE_DW_VIRTUALITY(ID, NAME) \
+ .Case("DW_VIRTUALITY_" #NAME, DW_VIRTUALITY_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(DW_VIRTUALITY_invalid);
}
const char *llvm::dwarf::LanguageString(unsigned Language) {
switch (Language) {
- case DW_LANG_C89: return "DW_LANG_C89";
- case DW_LANG_C: return "DW_LANG_C";
- case DW_LANG_Ada83: return "DW_LANG_Ada83";
- case DW_LANG_C_plus_plus: return "DW_LANG_C_plus_plus";
- case DW_LANG_Cobol74: return "DW_LANG_Cobol74";
- case DW_LANG_Cobol85: return "DW_LANG_Cobol85";
- case DW_LANG_Fortran77: return "DW_LANG_Fortran77";
- case DW_LANG_Fortran90: return "DW_LANG_Fortran90";
- case DW_LANG_Pascal83: return "DW_LANG_Pascal83";
- case DW_LANG_Modula2: return "DW_LANG_Modula2";
- case DW_LANG_Java: return "DW_LANG_Java";
- case DW_LANG_C99: return "DW_LANG_C99";
- case DW_LANG_Ada95: return "DW_LANG_Ada95";
- case DW_LANG_Fortran95: return "DW_LANG_Fortran95";
- case DW_LANG_PLI: return "DW_LANG_PLI";
- case DW_LANG_ObjC: return "DW_LANG_ObjC";
- case DW_LANG_ObjC_plus_plus: return "DW_LANG_ObjC_plus_plus";
- case DW_LANG_UPC: return "DW_LANG_UPC";
- case DW_LANG_D: return "DW_LANG_D";
- case DW_LANG_Python: return "DW_LANG_Python";
- case DW_LANG_OpenCL: return "DW_LANG_OpenCL";
- case DW_LANG_Go: return "DW_LANG_Go";
- case DW_LANG_Modula3: return "DW_LANG_Modula3";
- case DW_LANG_Haskell: return "DW_LANG_Haskell";
- case DW_LANG_C_plus_plus_03: return "DW_LANG_C_plus_plus_03";
- case DW_LANG_C_plus_plus_11: return "DW_LANG_C_plus_plus_11";
- case DW_LANG_OCaml: return "DW_LANG_OCaml";
- case DW_LANG_lo_user: return "DW_LANG_lo_user";
- case DW_LANG_Mips_Assembler: return "DW_LANG_Mips_Assembler";
- case DW_LANG_hi_user: return "DW_LANG_hi_user";
+ default:
+ return nullptr;
+#define HANDLE_DW_LANG(ID, NAME) \
+ case DW_LANG_##NAME: \
+ return "DW_LANG_" #NAME;
+#include "llvm/Support/Dwarf.def"
}
- return nullptr;
+}
+
+unsigned llvm::dwarf::getLanguage(StringRef LanguageString) {
+ return StringSwitch<unsigned>(LanguageString)
+#define HANDLE_DW_LANG(ID, NAME) .Case("DW_LANG_" #NAME, DW_LANG_##NAME)
+#include "llvm/Support/Dwarf.def"
+ .Default(0);
}
const char *llvm::dwarf::CaseString(unsigned Case) {
diff --git a/lib/Support/Errno.cpp b/lib/Support/Errno.cpp
index 1eefa3e..3ba2a12 100644
--- a/lib/Support/Errno.cpp
+++ b/lib/Support/Errno.cpp
@@ -35,12 +35,14 @@ std::string StrError() {
#endif // HAVE_ERRNO_H
std::string StrError(int errnum) {
- const int MaxErrStrLen = 2000;
- char buffer[MaxErrStrLen];
- buffer[0] = '\0';
std::string str;
if (errnum == 0)
return str;
+#if defined(HAVE_STRERROR_R) || HAVE_DECL_STRERROR_S
+ const int MaxErrStrLen = 2000;
+ char buffer[MaxErrStrLen];
+ buffer[0] = '\0';
+#endif
#ifdef HAVE_STRERROR_R
// strerror_r is thread-safe.
diff --git a/lib/Support/ErrorHandling.cpp b/lib/Support/ErrorHandling.cpp
index 8e65066..a25e21a 100644
--- a/lib/Support/ErrorHandling.cpp
+++ b/lib/Support/ErrorHandling.cpp
@@ -19,10 +19,10 @@
#include "llvm/Config/config.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Errc.h"
-#include "llvm/Support/Signals.h"
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/MutexGuard.h"
+#include "llvm/Support/Signals.h"
#include "llvm/Support/Threading.h"
#include "llvm/Support/WindowsError.h"
#include "llvm/Support/raw_ostream.h"
diff --git a/lib/Support/FileOutputBuffer.cpp b/lib/Support/FileOutputBuffer.cpp
index c62655d..b176a8b 100644
--- a/lib/Support/FileOutputBuffer.cpp
+++ b/lib/Support/FileOutputBuffer.cpp
@@ -12,12 +12,18 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Errc.h"
-#include "llvm/Support/FileOutputBuffer.h"
-#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/FileOutputBuffer.h"
#include "llvm/Support/raw_ostream.h"
#include <system_error>
+#if !defined(_MSC_VER) && !defined(__MINGW32__)
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
using llvm::sys::fs::mapped_file_region;
namespace llvm {
@@ -71,10 +77,17 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size,
if (EC)
return EC;
+ EC = sys::fs::resize_file(FD, Size);
+ if (EC)
+ return EC;
+
auto MappedFile = llvm::make_unique<mapped_file_region>(
- FD, true, mapped_file_region::readwrite, Size, 0, EC);
+ FD, mapped_file_region::readwrite, Size, 0, EC);
+ int Ret = close(FD);
if (EC)
return EC;
+ if (Ret)
+ return std::error_code(errno, std::generic_category());
Result.reset(
new FileOutputBuffer(std::move(MappedFile), FilePath, TempFilePath));
@@ -82,16 +95,10 @@ FileOutputBuffer::create(StringRef FilePath, size_t Size,
return std::error_code();
}
-std::error_code FileOutputBuffer::commit(int64_t NewSmallerSize) {
+std::error_code FileOutputBuffer::commit() {
// Unmap buffer, letting OS flush dirty pages to file on disk.
Region.reset();
- // If requested, resize file as part of commit.
- if ( NewSmallerSize != -1 ) {
- std::error_code EC = sys::fs::resize_file(Twine(TempPath), NewSmallerSize);
- if (EC)
- return EC;
- }
// Rename file to final name.
return sys::fs::rename(Twine(TempPath), Twine(FinalPath));
diff --git a/lib/Support/Host.cpp b/lib/Support/Host.cpp
index 8782e2e..42bc342 100644
--- a/lib/Support/Host.cpp
+++ b/lib/Support/Host.cpp
@@ -17,8 +17,8 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Config/config.h"
-#include "llvm/Support/DataStream.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/FileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include <string.h>
@@ -49,6 +49,26 @@
using namespace llvm;
+#if defined(__linux__)
+static ssize_t LLVM_ATTRIBUTE_UNUSED readCpuInfo(void *Buf, size_t Size) {
+ // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
+ // memory buffer because the 'file' has 0 size (it can be read from only
+ // as a stream).
+
+ int FD;
+ std::error_code EC = sys::fs::openFileForRead("/proc/cpuinfo", FD);
+ if (EC) {
+ DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << EC.message() << "\n");
+ return -1;
+ }
+ int Ret = read(FD, Buf, Size);
+ int CloseStatus = close(FD);
+ if (CloseStatus)
+ return -1;
+ return Ret;
+}
+#endif
+
#if defined(i386) || defined(__i386__) || defined(__x86__) || defined(_M_IX86)\
|| defined(__x86_64__) || defined(_M_AMD64) || defined (_M_X64)
@@ -117,18 +137,13 @@ static bool GetX86CpuIDAndInfoEx(unsigned value, unsigned subleaf,
"c" (subleaf));
return false;
#elif defined(_MSC_VER)
- // __cpuidex was added in MSVC++ 9.0 SP1
- #if (_MSC_VER > 1500) || (_MSC_VER == 1500 && _MSC_FULL_VER >= 150030729)
- int registers[4];
- __cpuidex(registers, value, subleaf);
- *rEAX = registers[0];
- *rEBX = registers[1];
- *rECX = registers[2];
- *rEDX = registers[3];
- return false;
- #else
- return true;
- #endif
+ int registers[4];
+ __cpuidex(registers, value, subleaf);
+ *rEAX = registers[0];
+ *rEBX = registers[1];
+ *rECX = registers[2];
+ *rEDX = registers[3];
+ return false;
#else
return true;
#endif
@@ -489,22 +504,12 @@ StringRef sys::getHostCPUName() {
// processor type. On Linux, this is exposed through the /proc/cpuinfo file.
const char *generic = "generic";
- // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
- // memory buffer because the 'file' has 0 size (it can be read from only
- // as a stream).
-
- std::string Err;
- DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
- if (!DS) {
- DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
- return generic;
- }
-
// The cpu line is second (after the 'processor: 0' line), so if this
// buffer is too small then something has changed (or is wrong).
char buffer[1024];
- size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
- delete DS;
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return generic;
const char *CPUInfoStart = buffer;
const char *CPUInfoEnd = buffer + CPUInfoSize;
@@ -578,22 +583,13 @@ StringRef sys::getHostCPUName() {
StringRef sys::getHostCPUName() {
// The cpuid register on arm is not accessible from user space. On Linux,
// it is exposed through the /proc/cpuinfo file.
- // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
- // memory buffer because the 'file' has 0 size (it can be read from only
- // as a stream).
-
- std::string Err;
- DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
- if (!DS) {
- DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
- return "generic";
- }
// Read 1024 bytes from /proc/cpuinfo, which should contain the CPU part line
// in all cases.
char buffer[1024];
- size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
- delete DS;
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return "generic";
StringRef Str(buffer, CPUInfoSize);
@@ -643,22 +639,13 @@ StringRef sys::getHostCPUName() {
#elif defined(__linux__) && defined(__s390x__)
StringRef sys::getHostCPUName() {
// STIDP is a privileged operation, so use /proc/cpuinfo instead.
- // Note: We cannot mmap /proc/cpuinfo here and then process the resulting
- // memory buffer because the 'file' has 0 size (it can be read from only
- // as a stream).
-
- std::string Err;
- DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
- if (!DS) {
- DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
- return "generic";
- }
// The "processor 0:" line comes after a fair amount of other information,
// including a cache breakdown, but this should be plenty.
char buffer[2048];
- size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
- delete DS;
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return "generic";
StringRef Str(buffer, CPUInfoSize);
SmallVector<StringRef, 32> Lines;
@@ -690,18 +677,12 @@ StringRef sys::getHostCPUName() {
#if defined(__linux__) && (defined(__arm__) || defined(__aarch64__))
bool sys::getHostCPUFeatures(StringMap<bool> &Features) {
- std::string Err;
- DataStreamer *DS = getDataFileStreamer("/proc/cpuinfo", &Err);
- if (!DS) {
- DEBUG(dbgs() << "Unable to open /proc/cpuinfo: " << Err << "\n");
- return false;
- }
-
// Read 1024 bytes from /proc/cpuinfo, which should contain the Features line
// in all cases.
char buffer[1024];
- size_t CPUInfoSize = DS->GetBytes((unsigned char*) buffer, sizeof(buffer));
- delete DS;
+ ssize_t CPUInfoSize = readCpuInfo(buffer, sizeof(buffer));
+ if (CPUInfoSize == -1)
+ return false;
StringRef Str(buffer, CPUInfoSize);
diff --git a/lib/Support/LockFileManager.cpp b/lib/Support/LockFileManager.cpp
index 5b82c36..ec3158c 100644
--- a/lib/Support/LockFileManager.cpp
+++ b/lib/Support/LockFileManager.cpp
@@ -186,9 +186,8 @@ LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() {
Interval.tv_sec = 0;
Interval.tv_nsec = 1000000;
#endif
- // Don't wait more than five minutes for the file to appear.
- unsigned MaxSeconds = 300;
- bool LockFileGone = false;
+ // Don't wait more than one minute for the file to appear.
+ const unsigned MaxSeconds = 60;
do {
// Sleep for the designated interval, to allow the owning process time to
// finish up and remove the lock file.
@@ -199,47 +198,18 @@ LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() {
#else
nanosleep(&Interval, nullptr);
#endif
- bool LockFileJustDisappeared = false;
- // If the lock file is still expected to be there, check whether it still
- // is.
- if (!LockFileGone) {
- if (sys::fs::access(LockFileName.c_str(), sys::fs::AccessMode::Exist) ==
- errc::no_such_file_or_directory) {
- LockFileGone = true;
- LockFileJustDisappeared = true;
- }
+ if (sys::fs::access(LockFileName.c_str(), sys::fs::AccessMode::Exist) ==
+ errc::no_such_file_or_directory) {
+ // If the original file wasn't created, somone thought the lock was dead.
+ if (!sys::fs::exists(FileName.str()))
+ return Res_OwnerDied;
+ return Res_Success;
}
- // If the lock file is no longer there, check if the original file is
- // available now.
- if (LockFileGone) {
- if (sys::fs::exists(FileName.str())) {
- return Res_Success;
- }
-
- // The lock file is gone, so now we're waiting for the original file to
- // show up. If this just happened, reset our waiting intervals and keep
- // waiting.
- if (LockFileJustDisappeared) {
- MaxSeconds = 5;
-
-#if LLVM_ON_WIN32
- Interval = 1;
-#else
- Interval.tv_sec = 0;
- Interval.tv_nsec = 1000000;
-#endif
- continue;
- }
- }
-
- // If we're looking for the lock file to disappear, but the process
- // owning the lock died without cleaning up, just bail out.
- if (!LockFileGone &&
- !processStillExecuting((*Owner).first, (*Owner).second)) {
+ // If the process owning the lock died without cleaning up, just bail out.
+ if (!processStillExecuting((*Owner).first, (*Owner).second))
return Res_OwnerDied;
- }
// Exponentially increase the time we wait for the lock to be removed.
#if LLVM_ON_WIN32
@@ -263,3 +233,7 @@ LockFileManager::WaitForUnlockResult LockFileManager::waitForUnlock() {
// Give up.
return Res_Timeout;
}
+
+std::error_code LockFileManager::unsafeRemoveLockFile() {
+ return sys::fs::remove(LockFileName.str());
+}
diff --git a/lib/Support/MemoryBuffer.cpp b/lib/Support/MemoryBuffer.cpp
index 7eb0752..379db88 100644
--- a/lib/Support/MemoryBuffer.cpp
+++ b/lib/Support/MemoryBuffer.cpp
@@ -203,8 +203,8 @@ class MemoryBufferMMapFile : public MemoryBuffer {
public:
MemoryBufferMMapFile(bool RequiresNullTerminator, int FD, uint64_t Len,
- uint64_t Offset, std::error_code EC)
- : MFR(FD, false, sys::fs::mapped_file_region::readonly,
+ uint64_t Offset, std::error_code &EC)
+ : MFR(FD, sys::fs::mapped_file_region::readonly,
getLegalMapSize(Len, Offset), getLegalMapOffset(Offset), EC) {
if (!EC) {
const char *Start = getStart(Len, Offset);
@@ -330,7 +330,7 @@ static ErrorOr<std::unique_ptr<MemoryBuffer>>
getOpenFileImpl(int FD, const Twine &Filename, uint64_t FileSize,
uint64_t MapSize, int64_t Offset, bool RequiresNullTerminator,
bool IsVolatileSize) {
- static int PageSize = sys::process::get_self()->page_size();
+ static int PageSize = sys::Process::getPageSize();
// Default is to map the full file.
if (MapSize == uint64_t(-1)) {
diff --git a/lib/Support/Path.cpp b/lib/Support/Path.cpp
index a7a9919..a11bb7f 100644
--- a/lib/Support/Path.cpp
+++ b/lib/Support/Path.cpp
@@ -14,9 +14,9 @@
#include "llvm/Support/COFF.h"
#include "llvm/Support/Endian.h"
#include "llvm/Support/Errc.h"
-#include "llvm/Support/Path.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/FileSystem.h"
+#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include <cctype>
#include <cstdio>
@@ -888,6 +888,14 @@ bool is_other(file_status status) {
!is_directory(status);
}
+std::error_code is_other(const Twine &Path, bool &Result) {
+ file_status FileStatus;
+ if (std::error_code EC = status(Path, FileStatus))
+ return EC;
+ Result = is_other(FileStatus);
+ return std::error_code();
+}
+
void directory_entry::replace_filename(const Twine &filename, file_status st) {
SmallString<128> path(Path.begin(), Path.end());
path::remove_filename(path);
@@ -952,7 +960,7 @@ file_magic identify_magic(StringRef Magic) {
unsigned low = Data2MSB ? 17 : 16;
if (Magic[high] == 0)
switch (Magic[low]) {
- default: break;
+ default: return file_magic::elf;
case 1: return file_magic::elf_relocatable;
case 2: return file_magic::elf_executable;
case 3: return file_magic::elf_shared_object;
@@ -1004,6 +1012,7 @@ file_magic identify_magic(StringRef Magic) {
case 8: return file_magic::macho_bundle;
case 9: return file_magic::macho_dynamically_linked_shared_lib_stub;
case 10: return file_magic::macho_dsym_companion;
+ case 11: return file_magic::macho_kext_bundle;
}
break;
}
diff --git a/lib/Support/PrettyStackTrace.cpp b/lib/Support/PrettyStackTrace.cpp
index 987778a..f9f8cab 100644
--- a/lib/Support/PrettyStackTrace.cpp
+++ b/lib/Support/PrettyStackTrace.cpp
@@ -16,9 +16,8 @@
#include "llvm-c/Core.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/Config/config.h" // Get autoconf configuration settings
-#include "llvm/Support/ManagedStatic.h"
+#include "llvm/Support/Compiler.h"
#include "llvm/Support/Signals.h"
-#include "llvm/Support/ThreadLocal.h"
#include "llvm/Support/Watchdog.h"
#include "llvm/Support/raw_ostream.h"
@@ -28,7 +27,17 @@
using namespace llvm;
-static ManagedStatic<sys::ThreadLocal<const PrettyStackTraceEntry> > PrettyStackTraceHead;
+// If backtrace support is not enabled, compile out support for pretty stack
+// traces. This has the secondary effect of not requiring thread local storage
+// when backtrace support is disabled.
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+
+// We need a thread local pointer to manage the stack of our stack trace
+// objects, but we *really* cannot tolerate destructors running and do not want
+// to pay any overhead of synchronizing. As a consequence, we use a raw
+// thread-local variable.
+static LLVM_THREAD_LOCAL const PrettyStackTraceEntry *PrettyStackTraceHead =
+ nullptr;
static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
unsigned NextID = 0;
@@ -46,12 +55,12 @@ static unsigned PrintStack(const PrettyStackTraceEntry *Entry, raw_ostream &OS){
/// PrintCurStackTrace - Print the current stack trace to the specified stream.
static void PrintCurStackTrace(raw_ostream &OS) {
// Don't print an empty trace.
- if (!PrettyStackTraceHead->get()) return;
+ if (!PrettyStackTraceHead) return;
// If there are pretty stack frames registered, walk and emit them.
OS << "Stack dump:\n";
- PrintStack(PrettyStackTraceHead->get(), OS);
+ PrintStack(PrettyStackTraceHead, OS);
OS.flush();
}
@@ -99,28 +108,23 @@ static void CrashHandler(void *) {
#endif
}
+// defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+#endif
+
PrettyStackTraceEntry::PrettyStackTraceEntry() {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
// Link ourselves.
- NextEntry = PrettyStackTraceHead->get();
- PrettyStackTraceHead->set(this);
+ NextEntry = PrettyStackTraceHead;
+ PrettyStackTraceHead = this;
+#endif
}
PrettyStackTraceEntry::~PrettyStackTraceEntry() {
- // Do nothing if PrettyStackTraceHead is uninitialized. This can only happen
- // if a shutdown occurred after we created the PrettyStackTraceEntry. That
- // does occur in the following idiom:
- //
- // PrettyStackTraceProgram X(...);
- // llvm_shutdown_obj Y;
- //
- // Without this check, we may end up removing ourselves from the stack trace
- // after PrettyStackTraceHead has already been destroyed.
- if (!PrettyStackTraceHead.isConstructed())
- return;
-
- assert(PrettyStackTraceHead->get() == this &&
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
+ assert(PrettyStackTraceHead == this &&
"Pretty stack trace entry destruction is out of order");
- PrettyStackTraceHead->set(getNextEntry());
+ PrettyStackTraceHead = getNextEntry();
+#endif
}
void PrettyStackTraceString::print(raw_ostream &OS) const {
@@ -135,15 +139,19 @@ void PrettyStackTraceProgram::print(raw_ostream &OS) const {
OS << '\n';
}
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
static bool RegisterCrashPrinter() {
sys::AddSignalHandler(CrashHandler, nullptr);
return false;
}
+#endif
void llvm::EnablePrettyStackTrace() {
+#if defined(HAVE_BACKTRACE) && defined(ENABLE_BACKTRACES)
// The first time this is called, we register the crash printer.
static bool HandlerRegistered = RegisterCrashPrinter();
(void)HandlerRegistered;
+#endif
}
void LLVMEnablePrettyStackTrace() {
diff --git a/lib/Support/Process.cpp b/lib/Support/Process.cpp
index 0d42e0e..ad67e1b 100644
--- a/lib/Support/Process.cpp
+++ b/lib/Support/Process.cpp
@@ -26,25 +26,6 @@ using namespace sys;
//=== independent code.
//===----------------------------------------------------------------------===//
-// Empty virtual destructor to anchor the vtable for the process class.
-process::~process() {}
-
-self_process *process::get_self() {
- // Use a function local static for thread safe initialization and allocate it
- // as a raw pointer to ensure it is never destroyed.
- static self_process *SP = new self_process();
-
- return SP;
-}
-
-// The destructor for the self_process subclass must never actually be
-// executed. There should be at most one instance of this class, and that
-// instance should live until the process terminates to avoid the potential for
-// racy accesses during shutdown.
-self_process::~self_process() {
- llvm_unreachable("This destructor must never be executed!");
-}
-
/// \brief A helper function to compute the elapsed wall-time since the program
/// started.
///
@@ -63,12 +44,6 @@ static TimeValue getElapsedWallTime() {
/// create race conditions during program startup or shutdown.
static volatile TimeValue DummyTimeValue = getElapsedWallTime();
-// Implement this routine by using the static helpers above. They're already
-// portable.
-TimeValue self_process::get_wall_time() const {
- return getElapsedWallTime();
-}
-
Optional<std::string> Process::FindInEnvPath(const std::string& EnvName,
const std::string& FileName)
{
diff --git a/lib/Support/RandomNumberGenerator.cpp b/lib/Support/RandomNumberGenerator.cpp
index c50e7cb..2943137 100644
--- a/lib/Support/RandomNumberGenerator.cpp
+++ b/lib/Support/RandomNumberGenerator.cpp
@@ -7,16 +7,16 @@
//
//===----------------------------------------------------------------------===//
//
-// This file implements random number generation (RNG).
+// This file implements deterministic random number generation (RNG).
// The current implementation is NOT cryptographically secure as it uses
// the C++11 <random> facilities.
//
//===----------------------------------------------------------------------===//
#define DEBUG_TYPE "rng"
-#include "llvm/Support/RandomNumberGenerator.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
+#include "llvm/Support/RandomNumberGenerator.h"
using namespace llvm;
@@ -31,31 +31,25 @@ Seed("rng-seed", cl::value_desc("seed"),
RandomNumberGenerator::RandomNumberGenerator(StringRef Salt) {
DEBUG(
if (Seed == 0)
- errs() << "Warning! Using unseeded random number generator.\n"
+ dbgs() << "Warning! Using unseeded random number generator.\n"
);
- // Combine seed and salt using std::seed_seq.
- // Entropy: Seed-low, Seed-high, Salt...
+ // Combine seed and salts using std::seed_seq.
+ // Data: Seed-low, Seed-high, Salt
+ // Note: std::seed_seq can only store 32-bit values, even though we
+ // are using a 64-bit RNG. This isn't a problem since the Mersenne
+ // twister constructor copies these correctly into its initial state.
std::vector<uint32_t> Data;
- Data.reserve(2 + Salt.size()/4 + 1);
+ Data.reserve(2 + Salt.size());
Data.push_back(Seed);
Data.push_back(Seed >> 32);
- uint32_t Pack = 0;
- for (size_t I = 0; I < Salt.size(); ++I) {
- Pack <<= 8;
- Pack += Salt[I];
-
- if (I%4 == 3)
- Data.push_back(Pack);
- }
- Data.push_back(Pack);
+ std::copy(Salt.begin(), Salt.end(), Data.end());
std::seed_seq SeedSeq(Data.begin(), Data.end());
Generator.seed(SeedSeq);
}
-uint64_t RandomNumberGenerator::next(uint64_t Max) {
- std::uniform_int_distribution<uint64_t> distribution(0, Max - 1);
- return distribution(Generator);
+uint_fast64_t RandomNumberGenerator::operator()() {
+ return Generator();
}
diff --git a/lib/Support/ScaledNumber.cpp b/lib/Support/ScaledNumber.cpp
index fc6d4e7..6f6699c 100644
--- a/lib/Support/ScaledNumber.cpp
+++ b/lib/Support/ScaledNumber.cpp
@@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/ScaledNumber.h"
-
#include "llvm/ADT/APFloat.h"
#include "llvm/Support/Debug.h"
@@ -169,6 +168,7 @@ static std::string toStringAPFloat(uint64_t D, int E, unsigned Precision) {
int Shift = 63 - (NewE - E);
assert(Shift <= LeadingZeros);
assert(Shift == LeadingZeros || NewE == ScaledNumbers::MaxScale);
+ assert(Shift >= 0 && Shift < 64 && "undefined behavior");
D <<= Shift;
E = NewE;
diff --git a/lib/Support/SmallPtrSet.cpp b/lib/Support/SmallPtrSet.cpp
index c87ee7d..358c8e8 100644
--- a/lib/Support/SmallPtrSet.cpp
+++ b/lib/Support/SmallPtrSet.cpp
@@ -50,11 +50,12 @@ SmallPtrSetImplBase::insert_imp(const void *Ptr) {
}
// Otherwise, hit the big set case, which will call grow.
}
-
- if (NumElements*4 >= CurArraySize*3) {
+
+ if (LLVM_UNLIKELY(NumElements * 4 >= CurArraySize * 3)) {
// If more than 3/4 of the array is full, grow.
Grow(CurArraySize < 64 ? 128 : CurArraySize*2);
- } else if (CurArraySize-(NumElements+NumTombstones) < CurArraySize/8) {
+ } else if (LLVM_UNLIKELY(CurArraySize - (NumElements + NumTombstones) <
+ CurArraySize / 8)) {
// If fewer of 1/8 of the array is empty (meaning that many are filled with
// tombstones), rehash.
Grow(CurArraySize);
@@ -107,16 +108,16 @@ const void * const *SmallPtrSetImplBase::FindBucketFor(const void *Ptr) const {
const void *const *Array = CurArray;
const void *const *Tombstone = nullptr;
while (1) {
- // Found Ptr's bucket?
- if (Array[Bucket] == Ptr)
- return Array+Bucket;
-
// If we found an empty bucket, the pointer doesn't exist in the set.
// Return a tombstone if we've seen one so far, or the empty bucket if
// not.
- if (Array[Bucket] == getEmptyMarker())
+ if (LLVM_LIKELY(Array[Bucket] == getEmptyMarker()))
return Tombstone ? Tombstone : Array+Bucket;
-
+
+ // Found Ptr's bucket?
+ if (LLVM_LIKELY(Array[Bucket] == Ptr))
+ return Array+Bucket;
+
// If this is a tombstone, remember it. If Ptr ends up not in the set, we
// prefer to return it than something that would require more probing.
if (Array[Bucket] == getTombstoneMarker() && !Tombstone)
diff --git a/lib/Support/SpecialCaseList.cpp b/lib/Support/SpecialCaseList.cpp
index 785cc60..c312cc1 100644
--- a/lib/Support/SpecialCaseList.cpp
+++ b/lib/Support/SpecialCaseList.cpp
@@ -46,19 +46,27 @@ struct SpecialCaseList::Entry {
}
};
-SpecialCaseList::SpecialCaseList() : Entries() {}
+SpecialCaseList::SpecialCaseList() : Entries(), Regexps(), IsCompiled(false) {}
-std::unique_ptr<SpecialCaseList> SpecialCaseList::create(StringRef Path,
- std::string &Error) {
- if (Path.empty())
- return std::unique_ptr<SpecialCaseList>(new SpecialCaseList());
- ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
- MemoryBuffer::getFile(Path);
- if (std::error_code EC = FileOrErr.getError()) {
- Error = (Twine("Can't open file '") + Path + "': " + EC.message()).str();
- return nullptr;
+std::unique_ptr<SpecialCaseList>
+SpecialCaseList::create(const std::vector<std::string> &Paths,
+ std::string &Error) {
+ std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
+ for (auto Path : Paths) {
+ ErrorOr<std::unique_ptr<MemoryBuffer>> FileOrErr =
+ MemoryBuffer::getFile(Path);
+ if (std::error_code EC = FileOrErr.getError()) {
+ Error = (Twine("can't open file '") + Path + "': " + EC.message()).str();
+ return nullptr;
+ }
+ std::string ParseError;
+ if (!SCL->parse(FileOrErr.get().get(), ParseError)) {
+ Error = (Twine("error parsing file '") + Path + "': " + ParseError).str();
+ return nullptr;
+ }
}
- return create(FileOrErr.get().get(), Error);
+ SCL->compile();
+ return SCL;
}
std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
@@ -66,12 +74,14 @@ std::unique_ptr<SpecialCaseList> SpecialCaseList::create(const MemoryBuffer *MB,
std::unique_ptr<SpecialCaseList> SCL(new SpecialCaseList());
if (!SCL->parse(MB, Error))
return nullptr;
+ SCL->compile();
return SCL;
}
-std::unique_ptr<SpecialCaseList> SpecialCaseList::createOrDie(StringRef Path) {
+std::unique_ptr<SpecialCaseList>
+SpecialCaseList::createOrDie(const std::vector<std::string> &Paths) {
std::string Error;
- if (auto SCL = create(Path, Error))
+ if (auto SCL = create(Paths, Error))
return SCL;
report_fatal_error(Error);
}
@@ -80,12 +90,8 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
// Iterate through each line in the blacklist file.
SmallVector<StringRef, 16> Lines;
SplitString(MB->getBuffer(), Lines, "\n\r");
- StringMap<StringMap<std::string> > Regexps;
- assert(Entries.empty() &&
- "parse() should be called on an empty SpecialCaseList");
int LineNo = 1;
- for (SmallVectorImpl<StringRef>::iterator I = Lines.begin(), E = Lines.end();
- I != E; ++I, ++LineNo) {
+ for (auto I = Lines.begin(), E = Lines.end(); I != E; ++I, ++LineNo) {
// Ignore empty lines and lines starting with "#"
if (I->empty() || I->startswith("#"))
continue;
@@ -94,7 +100,7 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
StringRef Prefix = SplitLine.first;
if (SplitLine.second.empty()) {
// Missing ':' in the line.
- Error = (Twine("Malformed line ") + Twine(LineNo) + ": '" +
+ Error = (Twine("malformed line ") + Twine(LineNo) + ": '" +
SplitLine.first + "'").str();
return false;
}
@@ -119,7 +125,7 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
Regex CheckRE(Regexp);
std::string REError;
if (!CheckRE.isValid(REError)) {
- Error = (Twine("Malformed regex in line ") + Twine(LineNo) + ": '" +
+ Error = (Twine("malformed regex in line ") + Twine(LineNo) + ": '" +
SplitLine.second + "': " + REError).str();
return false;
}
@@ -129,10 +135,14 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
Regexps[Prefix][Category] += "|";
Regexps[Prefix][Category] += "^" + Regexp + "$";
}
+ return true;
+}
+void SpecialCaseList::compile() {
+ assert(!IsCompiled && "compile() should only be called once");
// Iterate through each of the prefixes, and create Regexs for them.
- for (StringMap<StringMap<std::string> >::const_iterator I = Regexps.begin(),
- E = Regexps.end();
+ for (StringMap<StringMap<std::string>>::const_iterator I = Regexps.begin(),
+ E = Regexps.end();
I != E; ++I) {
for (StringMap<std::string>::const_iterator II = I->second.begin(),
IE = I->second.end();
@@ -140,13 +150,15 @@ bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
Entries[I->getKey()][II->getKey()].RegEx.reset(new Regex(II->getValue()));
}
}
- return true;
+ Regexps.clear();
+ IsCompiled = true;
}
SpecialCaseList::~SpecialCaseList() {}
bool SpecialCaseList::inSection(StringRef Section, StringRef Query,
StringRef Category) const {
+ assert(IsCompiled && "SpecialCaseList::compile() was not called!");
StringMap<StringMap<Entry> >::const_iterator I = Entries.find(Section);
if (I == Entries.end()) return false;
StringMap<Entry>::const_iterator II = I->second.find(Category);
diff --git a/lib/Support/StreamingMemoryObject.cpp b/lib/Support/StreamingMemoryObject.cpp
index 68beeef..f39bc56 100644
--- a/lib/Support/StreamingMemoryObject.cpp
+++ b/lib/Support/StreamingMemoryObject.cpp
@@ -45,8 +45,8 @@ private:
return static_cast<std::ptrdiff_t>(address) < LastChar - FirstChar;
}
- RawMemoryObject(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
- void operator=(const RawMemoryObject&) LLVM_DELETED_FUNCTION;
+ RawMemoryObject(const RawMemoryObject&) = delete;
+ void operator=(const RawMemoryObject&) = delete;
};
uint64_t RawMemoryObject::readBytes(uint8_t *Buf, uint64_t Size,
diff --git a/lib/Support/StringMap.cpp b/lib/Support/StringMap.cpp
index ddb7349..7be9466 100644
--- a/lib/Support/StringMap.cpp
+++ b/lib/Support/StringMap.cpp
@@ -188,9 +188,10 @@ unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
// 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) {
+ if (LLVM_UNLIKELY(NumItems * 4 > NumBuckets * 3)) {
NewSize = NumBuckets*2;
- } else if (NumBuckets-(NumItems+NumTombstones) <= NumBuckets/8) {
+ } else if (LLVM_UNLIKELY(NumBuckets - (NumItems + NumTombstones) <=
+ NumBuckets / 8)) {
NewSize = NumBuckets;
} else {
return BucketNo;
diff --git a/lib/Support/ThreadLocal.cpp b/lib/Support/ThreadLocal.cpp
index 2dec9eb..9da1603 100644
--- a/lib/Support/ThreadLocal.cpp
+++ b/lib/Support/ThreadLocal.cpp
@@ -31,58 +31,14 @@ void ThreadLocalImpl::setInstance(const void* d) {
void **pd = reinterpret_cast<void**>(&data);
*pd = const_cast<void*>(d);
}
-const void* ThreadLocalImpl::getInstance() {
+void *ThreadLocalImpl::getInstance() {
void **pd = reinterpret_cast<void**>(&data);
return *pd;
}
void ThreadLocalImpl::removeInstance() {
- setInstance(0);
-}
-}
-#else
-
-#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
-
-#include <cassert>
-#include <pthread.h>
-#include <stdlib.h>
-
-namespace llvm {
-using namespace sys;
-
-ThreadLocalImpl::ThreadLocalImpl() : data() {
- static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- int errorcode = pthread_key_create(key, nullptr);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-ThreadLocalImpl::~ThreadLocalImpl() {
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- int errorcode = pthread_key_delete(*key);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-void ThreadLocalImpl::setInstance(const void* d) {
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- int errorcode = pthread_setspecific(*key, d);
- assert(errorcode == 0);
- (void) errorcode;
-}
-
-const void* ThreadLocalImpl::getInstance() {
- pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
- return pthread_getspecific(*key);
-}
-
-void ThreadLocalImpl::removeInstance() {
setInstance(nullptr);
}
-
}
-
#elif defined(LLVM_ON_UNIX)
#include "Unix/ThreadLocal.inc"
#elif defined( LLVM_ON_WIN32)
@@ -90,4 +46,3 @@ void ThreadLocalImpl::removeInstance() {
#else
#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 set in Support/ThreadLocal.cpp
#endif
-#endif
diff --git a/lib/Support/Triple.cpp b/lib/Support/Triple.cpp
index 4a4773e..e74b23c 100644
--- a/lib/Support/Triple.cpp
+++ b/lib/Support/Triple.cpp
@@ -23,6 +23,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case aarch64_be: return "aarch64_be";
case arm: return "arm";
case armeb: return "armeb";
+ case bpf: return "bpf";
case hexagon: return "hexagon";
case mips: return "mips";
case mipsel: return "mipsel";
@@ -33,6 +34,7 @@ const char *Triple::getArchTypeName(ArchType Kind) {
case ppc64le: return "powerpc64le";
case ppc: return "powerpc";
case r600: return "r600";
+ case amdgcn: return "amdgcn";
case sparc: return "sparc";
case sparcv9: return "sparcv9";
case systemz: return "s390x";
@@ -82,7 +84,10 @@ const char *Triple::getArchTypePrefix(ArchType Kind) {
case hexagon: return "hexagon";
- case r600: return "r600";
+ case amdgcn:
+ case r600: return "amdgpu";
+
+ case bpf: return "bpf";
case sparcv9:
case sparc: return "sparc";
@@ -157,6 +162,8 @@ const char *Triple::getOSTypeName(OSType Kind) {
case AIX: return "aix";
case CUDA: return "cuda";
case NVCL: return "nvcl";
+ case AMDHSA: return "amdhsa";
+ case PS4: return "ps4";
}
llvm_unreachable("Invalid OSType");
@@ -188,6 +195,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("arm64", aarch64) // "arm64" is an alias for "aarch64"
.Case("arm", arm)
.Case("armeb", armeb)
+ .Case("bpf", bpf)
.Case("mips", mips)
.Case("mipsel", mipsel)
.Case("mips64", mips64)
@@ -198,6 +206,7 @@ Triple::ArchType Triple::getArchTypeForLLVMName(StringRef Name) {
.Case("ppc", ppc)
.Case("ppc64le", ppc64le)
.Case("r600", r600)
+ .Case("amdgcn", amdgcn)
.Case("hexagon", hexagon)
.Case("sparc", sparc)
.Case("sparcv9", sparcv9)
@@ -242,13 +251,21 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
if (ArchName.startswith("armv")) {
offset = 3;
- arch = Triple::arm;
+ if (ArchName.endswith("eb")) {
+ arch = Triple::armeb;
+ ArchName = ArchName.substr(0, ArchName.size() - 2);
+ } else
+ arch = Triple::arm;
} else if (ArchName.startswith("armebv")) {
offset = 5;
arch = Triple::armeb;
} else if (ArchName.startswith("thumbv")) {
offset = 5;
- arch = Triple::thumb;
+ if (ArchName.endswith("eb")) {
+ arch = Triple::thumbeb;
+ ArchName = ArchName.substr(0, ArchName.size() - 2);
+ } else
+ arch = Triple::thumb;
} else if (ArchName.startswith("thumbebv")) {
offset = 7;
arch = Triple::thumbeb;
@@ -258,7 +275,7 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
.Cases("v3", "v3m", isThumb ? Triple::UnknownArch : arch)
.Cases("v4", "v4t", arch)
.Cases("v5", "v5e", "v5t", "v5te", "v5tej", arch)
- .Cases("v6", "v6j", "v6k", "v6m", arch)
+ .Cases("v6", "v6j", "v6k", "v6m", "v6sm", arch)
.Cases("v6t2", "v6z", "v6zk", arch)
.Cases("v7", "v7a", "v7em", "v7l", arch)
.Cases("v7m", "v7r", "v7s", arch)
@@ -267,6 +284,8 @@ static Triple::ArchType parseARMArch(StringRef ArchName) {
}
static Triple::ArchType parseArch(StringRef ArchName) {
+ Triple::ArchType ARMArch(parseARMArch(ArchName));
+
return StringSwitch<Triple::ArchType>(ArchName)
.Cases("i386", "i486", "i586", "i686", Triple::x86)
// FIXME: Do we need to support these?
@@ -276,15 +295,18 @@ static Triple::ArchType parseArch(StringRef ArchName) {
.Cases("powerpc64", "ppu", Triple::ppc64)
.Case("powerpc64le", Triple::ppc64le)
.Case("xscale", Triple::arm)
- .StartsWith("arm", parseARMArch(ArchName))
- .StartsWith("thumb", parseARMArch(ArchName))
- .StartsWith("aarch64", parseARMArch(ArchName))
+ .Case("xscaleeb", Triple::armeb)
+ .StartsWith("arm", ARMArch)
+ .StartsWith("thumb", ARMArch)
+ .StartsWith("aarch64", ARMArch)
.Case("msp430", Triple::msp430)
.Cases("mips", "mipseb", "mipsallegrex", Triple::mips)
.Cases("mipsel", "mipsallegrexel", Triple::mipsel)
.Cases("mips64", "mips64eb", Triple::mips64)
.Case("mips64el", Triple::mips64el)
.Case("r600", Triple::r600)
+ .Case("amdgcn", Triple::amdgcn)
+ .Case("bpf", Triple::bpf)
.Case("hexagon", Triple::hexagon)
.Case("s390x", Triple::systemz)
.Case("sparc", Triple::sparc)
@@ -345,6 +367,8 @@ static Triple::OSType parseOS(StringRef OSName) {
.StartsWith("aix", Triple::AIX)
.StartsWith("cuda", Triple::CUDA)
.StartsWith("nvcl", Triple::NVCL)
+ .StartsWith("amdhsa", Triple::AMDHSA)
+ .StartsWith("ps4", Triple::PS4)
.Default(Triple::UnknownOS);
}
@@ -373,6 +397,9 @@ static Triple::ObjectFormatType parseFormat(StringRef EnvironmentName) {
}
static Triple::SubArchType parseSubArch(StringRef SubArchName) {
+ if (SubArchName.endswith("eb"))
+ SubArchName = SubArchName.substr(0, SubArchName.size() - 2);
+
return StringSwitch<Triple::SubArchType>(SubArchName)
.EndsWith("v8", Triple::ARMSubArch_v8)
.EndsWith("v8a", Triple::ARMSubArch_v8)
@@ -385,6 +412,7 @@ static Triple::SubArchType parseSubArch(StringRef SubArchName) {
.EndsWith("v7s", Triple::ARMSubArch_v7s)
.EndsWith("v6", Triple::ARMSubArch_v6)
.EndsWith("v6m", Triple::ARMSubArch_v6m)
+ .EndsWith("v6sm", Triple::ARMSubArch_v6m)
.EndsWith("v6t2", Triple::ARMSubArch_v6t2)
.EndsWith("v5", Triple::ARMSubArch_v5)
.EndsWith("v5e", Triple::ARMSubArch_v5)
@@ -788,7 +816,11 @@ void Triple::setOS(OSType Kind) {
}
void Triple::setEnvironment(EnvironmentType Kind) {
- setEnvironmentName(getEnvironmentTypeName(Kind));
+ if (ObjectFormat == getDefaultFormat(*this))
+ return setEnvironmentName(getEnvironmentTypeName(Kind));
+
+ setEnvironmentName((getEnvironmentTypeName(Kind) + Twine("-") +
+ getObjectFormatTypeName(ObjectFormat)).str());
}
void Triple::setObjectFormat(ObjectFormatType Kind) {
@@ -862,6 +894,8 @@ static unsigned getArchPointerBitWidth(llvm::Triple::ArchType Arch) {
case llvm::Triple::aarch64:
case llvm::Triple::aarch64_be:
+ case llvm::Triple::amdgcn:
+ case llvm::Triple::bpf:
case llvm::Triple::le64:
case llvm::Triple::mips64:
case llvm::Triple::mips64el:
@@ -897,6 +931,8 @@ Triple Triple::get32BitArchVariant() const {
case Triple::UnknownArch:
case Triple::aarch64:
case Triple::aarch64_be:
+ case Triple::amdgcn:
+ case Triple::bpf:
case Triple::msp430:
case Triple::systemz:
case Triple::ppc64le:
@@ -958,8 +994,10 @@ Triple Triple::get64BitArchVariant() const {
case Triple::aarch64:
case Triple::aarch64_be:
+ case Triple::bpf:
case Triple::le64:
case Triple::amdil64:
+ case Triple::amdgcn:
case Triple::hsail64:
case Triple::spir64:
case Triple::mips64:
@@ -1013,6 +1051,8 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
offset = 5;
if (offset != StringRef::npos && MArch.substr(offset, 2) == "eb")
offset += 2;
+ if (MArch.endswith("eb"))
+ MArch = MArch.substr(0, MArch.size() - 2);
if (offset != StringRef::npos)
result = llvm::StringSwitch<const char *>(MArch.substr(offset))
.Cases("v2", "v2a", "arm2")
@@ -1027,7 +1067,7 @@ const char *Triple::getARMCPUForArch(StringRef MArch) const {
.Case("v6j", "arm1136j-s")
.Cases("v6z", "v6zk", "arm1176jzf-s")
.Case("v6t2", "arm1156t2-s")
- .Cases("v6m", "v6-m", "cortex-m0")
+ .Cases("v6m", "v6-m", "v6sm", "v6s-m", "cortex-m0")
.Cases("v7", "v7a", "v7-a", "v7l", "v7-l", "cortex-a8")
.Cases("v7s", "v7-s", "swift")
.Cases("v7r", "v7-r", "cortex-r4")
diff --git a/lib/Support/Unix/Host.inc b/lib/Support/Unix/Host.inc
index fcb3638..4572171 100644
--- a/lib/Support/Unix/Host.inc
+++ b/lib/Support/Unix/Host.inc
@@ -16,12 +16,12 @@
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
-#include "llvm/Config/config.h"
-#include "llvm/ADT/StringRef.h"
#include "Unix.h"
-#include <sys/utsname.h>
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Config/config.h"
#include <cctype>
#include <string>
+#include <sys/utsname.h>
using namespace llvm;
@@ -35,29 +35,15 @@ static std::string getOSVersion() {
}
std::string sys::getDefaultTargetTriple() {
- StringRef TargetTripleString(LLVM_DEFAULT_TARGET_TRIPLE);
- std::pair<StringRef, StringRef> ArchSplit = TargetTripleString.split('-');
-
- // Normalize the arch, since the target triple may not actually match the
- // target.
- std::string Arch = ArchSplit.first;
-
- std::string Triple(Arch);
- Triple += '-';
- Triple += ArchSplit.second;
-
- // Force i<N>86 to i386.
- if (Triple[0] == 'i' && isdigit(Triple[1]) &&
- Triple[2] == '8' && Triple[3] == '6')
- Triple[1] = '3';
+ std::string TargetTripleString(LLVM_DEFAULT_TARGET_TRIPLE);
// On darwin, we want to update the version to match that of the
// target.
- std::string::size_type DarwinDashIdx = Triple.find("-darwin");
+ std::string::size_type DarwinDashIdx = TargetTripleString.find("-darwin");
if (DarwinDashIdx != std::string::npos) {
- Triple.resize(DarwinDashIdx + strlen("-darwin"));
- Triple += getOSVersion();
+ TargetTripleString.resize(DarwinDashIdx + strlen("-darwin"));
+ TargetTripleString += getOSVersion();
}
- return Triple::normalize(Triple);
+ return Triple::normalize(TargetTripleString);
}
diff --git a/lib/Support/Unix/Memory.inc b/lib/Support/Unix/Memory.inc
index c9d89a8..c421ee8 100644
--- a/lib/Support/Unix/Memory.inc
+++ b/lib/Support/Unix/Memory.inc
@@ -88,7 +88,7 @@ Memory::allocateMappedMemory(size_t NumBytes,
if (NumBytes == 0)
return MemoryBlock();
- static const size_t PageSize = process::get_self()->page_size();
+ static const size_t PageSize = Process::getPageSize();
const size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
@@ -181,7 +181,7 @@ Memory::AllocateRWX(size_t NumBytes, const MemoryBlock* NearBlock,
std::string *ErrMsg) {
if (NumBytes == 0) return MemoryBlock();
- size_t PageSize = process::get_self()->page_size();
+ size_t PageSize = Process::getPageSize();
size_t NumPages = (NumBytes+PageSize-1)/PageSize;
int fd = -1;
@@ -333,23 +333,12 @@ void Memory::InvalidateInstructionCache(const void *Addr,
for (intptr_t Line = StartLine; Line < EndLine; Line += LineSize)
asm volatile("icbi 0, %0" : : "r"(Line));
asm volatile("isync");
-# elif (defined(__arm__) || defined(__aarch64__)) && defined(__GNUC__)
+# elif (defined(__arm__) || defined(__aarch64__) || defined(__mips__)) && \
+ defined(__GNUC__)
// FIXME: Can we safely always call this for __GNUC__ everywhere?
const char *Start = static_cast<const char *>(Addr);
const char *End = Start + Len;
__clear_cache(const_cast<char *>(Start), const_cast<char *>(End));
-# elif defined(__mips__)
- const char *Start = static_cast<const char *>(Addr);
-# if defined(ANDROID)
- // The declaration of "cacheflush" in Android bionic:
- // extern int cacheflush(long start, long end, long flags);
- const char *End = Start + Len;
- long LStart = reinterpret_cast<long>(const_cast<char *>(Start));
- long LEnd = reinterpret_cast<long>(const_cast<char *>(End));
- cacheflush(LStart, LEnd, BCACHE);
-# else
- cacheflush(const_cast<char *>(Start), Len, BCACHE);
-# endif
# endif
#endif // end apple
diff --git a/lib/Support/Unix/Path.inc b/lib/Support/Unix/Path.inc
index 634d404..973d010 100644
--- a/lib/Support/Unix/Path.inc
+++ b/lib/Support/Unix/Path.inc
@@ -62,31 +62,6 @@
using namespace llvm;
-namespace {
- /// This class automatically closes the given file descriptor when it goes out
- /// of scope. You can take back explicit ownership of the file descriptor by
- /// calling take(). The destructor does not verify that close was successful.
- /// Therefore, never allow this class to call close on a file descriptor that
- /// has been read from or written to.
- struct AutoFD {
- int FileDescriptor;
-
- AutoFD(int fd) : FileDescriptor(fd) {}
- ~AutoFD() {
- if (FileDescriptor >= 0)
- ::close(FileDescriptor);
- }
-
- int take() {
- int ret = FileDescriptor;
- FileDescriptor = -1;
- return ret;
- }
-
- operator int() const {return FileDescriptor;}
- };
-}
-
namespace llvm {
namespace sys {
namespace fs {
@@ -175,7 +150,7 @@ std::string getMainExecutable(const char *argv0, void *MainAddr) {
// /proc is not always mounted under Linux (chroot for example).
ssize_t len = readlink(aPath.str().c_str(), exe_path, sizeof(exe_path));
if (len >= 0)
- return StringRef(exe_path, len);
+ return std::string(exe_path, len);
} else {
// Fall back to the classical detection.
if (getprogpath(exe_path, argv0) != NULL)
@@ -311,11 +286,8 @@ std::error_code rename(const Twine &from, const Twine &to) {
return std::error_code();
}
-std::error_code resize_file(const Twine &path, uint64_t size) {
- SmallString<128> path_storage;
- StringRef p = path.toNullTerminatedStringRef(path_storage);
-
- if (::truncate(p.begin(), size) == -1)
+std::error_code resize_file(int FD, uint64_t Size) {
+ if (::ftruncate(FD, Size) == -1)
return std::error_code(errno, std::generic_category());
return std::error_code();
@@ -440,80 +412,28 @@ std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
#endif
}
-std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
- AutoFD ScopedFD(FD);
- if (!CloseFD)
- ScopedFD.take();
-
- // Figure out how large the file is.
- struct stat FileInfo;
- if (fstat(FD, &FileInfo) == -1)
- return std::error_code(errno, std::generic_category());
- uint64_t FileSize = FileInfo.st_size;
-
- if (Size == 0)
- Size = FileSize;
- else if (FileSize < Size) {
- // We need to grow the file.
- if (ftruncate(FD, Size) == -1)
- return std::error_code(errno, std::generic_category());
- }
+std::error_code mapped_file_region::init(int FD, uint64_t Offset,
+ mapmode Mode) {
+ assert(Size != 0);
int flags = (Mode == readwrite) ? MAP_SHARED : MAP_PRIVATE;
int prot = (Mode == readonly) ? PROT_READ : (PROT_READ | PROT_WRITE);
-#ifdef MAP_FILE
- flags |= MAP_FILE;
-#endif
Mapping = ::mmap(nullptr, Size, prot, flags, FD, Offset);
if (Mapping == MAP_FAILED)
return std::error_code(errno, std::generic_category());
return std::error_code();
}
-mapped_file_region::mapped_file_region(const Twine &path,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- std::error_code &ec)
- : Mode(mode)
- , Size(length)
- , Mapping() {
- // Make sure that the requested size fits within SIZE_T.
- if (length > std::numeric_limits<size_t>::max()) {
- ec = make_error_code(errc::invalid_argument);
- return;
- }
-
- SmallString<128> path_storage;
- StringRef name = path.toNullTerminatedStringRef(path_storage);
- int oflags = (mode == readonly) ? O_RDONLY : O_RDWR;
- int ofd = ::open(name.begin(), oflags);
- if (ofd == -1) {
- ec = std::error_code(errno, std::generic_category());
- return;
- }
-
- ec = init(ofd, true, offset);
- if (ec)
- Mapping = nullptr;
-}
-
-mapped_file_region::mapped_file_region(int fd,
- bool closefd,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- std::error_code &ec)
- : Mode(mode)
- , Size(length)
- , Mapping() {
+mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec)
+ : Size(length), Mapping() {
// Make sure that the requested size fits within SIZE_T.
if (length > std::numeric_limits<size_t>::max()) {
ec = make_error_code(errc::invalid_argument);
return;
}
- ec = init(fd, closefd, offset);
+ ec = init(fd, offset, mode);
if (ec)
Mapping = nullptr;
}
@@ -523,16 +443,6 @@ mapped_file_region::~mapped_file_region() {
::munmap(Mapping, Size);
}
-mapped_file_region::mapped_file_region(mapped_file_region &&other)
- : Mode(other.Mode), Size(other.Size), Mapping(other.Mapping) {
- other.Mapping = nullptr;
-}
-
-mapped_file_region::mapmode mapped_file_region::flags() const {
- assert(Mapping && "Mapping failed but used anyway!");
- return Mode;
-}
-
uint64_t mapped_file_region::size() const {
assert(Mapping && "Mapping failed but used anyway!");
return Size;
@@ -540,7 +450,6 @@ uint64_t mapped_file_region::size() const {
char *mapped_file_region::data() const {
assert(Mapping && "Mapping failed but used anyway!");
- assert(Mode != readonly && "Cannot get non-const data for readonly mapping!");
return reinterpret_cast<char*>(Mapping);
}
@@ -550,7 +459,7 @@ const char *mapped_file_region::const_data() const {
}
int mapped_file_region::alignment() {
- return process::get_self()->page_size();
+ return Process::getPageSize();
}
std::error_code detail::directory_iterator_construct(detail::DirIterState &it,
diff --git a/lib/Support/Unix/Process.inc b/lib/Support/Unix/Process.inc
index a429bb3..df13bd2 100644
--- a/lib/Support/Unix/Process.inc
+++ b/lib/Support/Unix/Process.inc
@@ -39,6 +39,9 @@
!defined(__OpenBSD__) && !defined(__Bitrig__)
#include <malloc.h>
#endif
+#if defined(HAVE_MALLCTL)
+#include <malloc_np.h>
+#endif
#ifdef HAVE_MALLOC_MALLOC_H
#include <malloc/malloc.h>
#endif
@@ -57,10 +60,6 @@
using namespace llvm;
using namespace sys;
-process::id_type self_process::get_id() {
- return getpid();
-}
-
static std::pair<TimeValue, TimeValue> getRUsageTimes() {
#if defined(HAVE_GETRUSAGE)
struct rusage RU;
@@ -80,43 +79,19 @@ static std::pair<TimeValue, TimeValue> getRUsageTimes() {
#endif
}
-TimeValue self_process::get_user_time() const {
-#if _POSIX_TIMERS > 0 && _POSIX_CPUTIME > 0
- // Try to get a high resolution CPU timer.
- struct timespec TS;
- if (::clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &TS) == 0)
- return TimeValue(static_cast<TimeValue::SecondsType>(TS.tv_sec),
- static_cast<TimeValue::NanoSecondsType>(TS.tv_nsec));
-#endif
-
- // Otherwise fall back to rusage based timing.
- return getRUsageTimes().first;
-}
-
-TimeValue self_process::get_system_time() const {
- // We can only collect system time by inspecting the results of getrusage.
- return getRUsageTimes().second;
-}
-
// On Cygwin, getpagesize() returns 64k(AllocationGranularity) and
// offset in mmap(3) should be aligned to the AllocationGranularity.
-static unsigned getPageSize() {
+unsigned Process::getPageSize() {
#if defined(HAVE_GETPAGESIZE)
- const int page_size = ::getpagesize();
+ static const int page_size = ::getpagesize();
#elif defined(HAVE_SYSCONF)
- long page_size = ::sysconf(_SC_PAGE_SIZE);
+ static long page_size = ::sysconf(_SC_PAGE_SIZE);
#else
#warning Cannot get the page size on this machine
#endif
return static_cast<unsigned>(page_size);
}
-// This constructor guaranteed to be run exactly once on a single thread, and
-// sets up various process invariants that can be queried cheaply from then on.
-self_process::self_process() : PageSize(getPageSize()) {
-}
-
-
size_t Process::GetMallocUsage() {
#if defined(HAVE_MALLINFO)
struct mallinfo mi;
@@ -126,6 +101,12 @@ size_t Process::GetMallocUsage() {
malloc_statistics_t Stats;
malloc_zone_statistics(malloc_default_zone(), &Stats);
return Stats.size_in_use; // darwin
+#elif defined(HAVE_MALLCTL)
+ size_t alloc, sz;
+ sz = sizeof(size_t);
+ if (mallctl("stats.allocated", &alloc, &sz, NULL, 0) == 0)
+ return alloc;
+ return 0;
#elif defined(HAVE_SBRK)
// Note this is only an approximation and more closely resembles
// the value returned by mallinfo in the arena field.
@@ -133,8 +114,7 @@ size_t Process::GetMallocUsage() {
char *EndOfMemory = (char*)sbrk(0);
if (EndOfMemory != ((char*)-1) && StartOfMemory != ((char*)-1))
return EndOfMemory - StartOfMemory;
- else
- return 0;
+ return 0;
#else
#warning Cannot get malloc info on this platform
return 0;
@@ -219,8 +199,8 @@ public:
}
private:
- FDCloser(const FDCloser &) LLVM_DELETED_FUNCTION;
- void operator=(const FDCloser &) LLVM_DELETED_FUNCTION;
+ FDCloser(const FDCloser &) = delete;
+ void operator=(const FDCloser &) = delete;
int &FD;
bool KeepOpen;
diff --git a/lib/Support/Unix/Program.inc b/lib/Support/Unix/Program.inc
index 0670ad3..baf2767 100644
--- a/lib/Support/Unix/Program.inc
+++ b/lib/Support/Unix/Program.inc
@@ -42,7 +42,18 @@
#define _RESTRICT_KYWD
#endif
#include <spawn.h>
-#if !defined(__APPLE__)
+
+#if defined(__APPLE__)
+#include <TargetConditionals.h>
+#endif
+
+#if defined(__APPLE__) && !(defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE)
+#define USE_NSGETENVIRON 1
+#else
+#define USE_NSGETENVIRON 0
+#endif
+
+#if !USE_NSGETENVIRON
extern char **environ;
#else
#include <crt_externs.h> // _NSGetEnviron
@@ -63,11 +74,12 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name,
if (Name.find('/') != StringRef::npos)
return std::string(Name);
- if (Paths.empty()) {
- SmallVector<StringRef, 16> SearchPaths;
- SplitString(std::getenv("PATH"), SearchPaths, ":");
- return findProgramByName(Name, SearchPaths);
- }
+ SmallVector<StringRef, 16> EnvironmentPaths;
+ if (Paths.empty())
+ if (const char *PathEnv = std::getenv("PATH")) {
+ SplitString(PathEnv, EnvironmentPaths, ":");
+ Paths = EnvironmentPaths;
+ }
for (auto Path : Paths) {
if (Path.empty())
@@ -216,7 +228,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
}
if (!envp)
-#if !defined(__APPLE__)
+#if !USE_NSGETENVIRON
envp = const_cast<const char **>(environ);
#else
// environ is missing in dylibs.
diff --git a/lib/Support/Unix/Signals.inc b/lib/Support/Unix/Signals.inc
index e8f4643..665c7de 100644
--- a/lib/Support/Unix/Signals.inc
+++ b/lib/Support/Unix/Signals.inc
@@ -480,6 +480,8 @@ static void PrintStackTraceSignalHandler(void *) {
PrintStackTrace(stderr);
}
+void llvm::sys::DisableSystemDialogsOnCrash() {}
+
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIGABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void llvm::sys::PrintStackTraceOnErrorSignal() {
diff --git a/lib/Support/Unix/ThreadLocal.inc b/lib/Support/Unix/ThreadLocal.inc
index f14d0fa..31c3f38 100644
--- a/lib/Support/Unix/ThreadLocal.inc
+++ b/lib/Support/Unix/ThreadLocal.inc
@@ -16,11 +16,54 @@
//=== is guaranteed to work on *all* UNIX variants.
//===----------------------------------------------------------------------===//
+#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_GETSPECIFIC)
+
+#include <cassert>
+#include <pthread.h>
+#include <stdlib.h>
+
+namespace llvm {
+using namespace sys;
+
+ThreadLocalImpl::ThreadLocalImpl() : data() {
+ static_assert(sizeof(pthread_key_t) <= sizeof(data), "size too big");
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ int errorcode = pthread_key_create(key, nullptr);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+ThreadLocalImpl::~ThreadLocalImpl() {
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ int errorcode = pthread_key_delete(*key);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+void ThreadLocalImpl::setInstance(const void* d) {
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ int errorcode = pthread_setspecific(*key, d);
+ assert(errorcode == 0);
+ (void) errorcode;
+}
+
+void *ThreadLocalImpl::getInstance() {
+ pthread_key_t* key = reinterpret_cast<pthread_key_t*>(&data);
+ return pthread_getspecific(*key);
+}
+
+void ThreadLocalImpl::removeInstance() {
+ setInstance(nullptr);
+}
+
+}
+#else
namespace llvm {
using namespace sys;
ThreadLocalImpl::ThreadLocalImpl() : data() { }
ThreadLocalImpl::~ThreadLocalImpl() { }
void ThreadLocalImpl::setInstance(const void* d) { data = const_cast<void*>(d);}
-const void* ThreadLocalImpl::getInstance() { return data; }
+void *ThreadLocalImpl::getInstance() { return data; }
void ThreadLocalImpl::removeInstance() { setInstance(0); }
}
+#endif
diff --git a/lib/Support/Valgrind.cpp b/lib/Support/Valgrind.cpp
index 2c6d6aa..facf8d9 100644
--- a/lib/Support/Valgrind.cpp
+++ b/lib/Support/Valgrind.cpp
@@ -53,7 +53,6 @@ void llvm::sys::ValgrindDiscardTranslations(const void *Addr, size_t Len) {
#endif // !HAVE_VALGRIND_VALGRIND_H
-#if LLVM_ENABLE_THREADS != 0 && !defined(NDEBUG)
// These functions require no implementation, tsan just looks at the arguments
// they're called with. However, they are required to be weak as some other
// application or library may already be providing these definitions for the
@@ -72,4 +71,4 @@ void AnnotateIgnoreWritesBegin(const char *file, int line) {}
LLVM_ATTRIBUTE_WEAK void AnnotateIgnoreWritesEnd(const char *file, int line);
void AnnotateIgnoreWritesEnd(const char *file, int line) {}
}
-#endif
+
diff --git a/lib/Support/Windows/Path.inc b/lib/Support/Windows/Path.inc
index 365031c..d8b5702 100644
--- a/lib/Support/Windows/Path.inc
+++ b/lib/Support/Windows/Path.inc
@@ -44,6 +44,7 @@ using namespace llvm;
using llvm::sys::windows::UTF8ToUTF16;
using llvm::sys::windows::UTF16ToUTF8;
+using llvm::sys::path::widenPath;
static std::error_code windows_error(DWORD E) {
return mapWindowsError(E);
@@ -59,11 +60,15 @@ static bool is_separator(const wchar_t value) {
}
}
+namespace llvm {
+namespace sys {
+namespace path {
+
// Convert a UTF-8 path to UTF-16. Also, if the absolute equivalent of the
// path is longer than CreateDirectory can tolerate, make it absolute and
// prefixed by '\\?\'.
-static std::error_code widenPath(const Twine &Path8,
- SmallVectorImpl<wchar_t> &Path16) {
+std::error_code widenPath(const Twine &Path8,
+ SmallVectorImpl<wchar_t> &Path16) {
const size_t MaxDirLen = MAX_PATH - 12; // Must leave room for 8.3 filename.
// Several operations would convert Path8 to SmallString; more efficient to
@@ -111,9 +116,8 @@ static std::error_code widenPath(const Twine &Path8,
// Just use the caller's original path.
return UTF8ToUTF16(Path8Str, Path16);
}
+} // end namespace path
-namespace llvm {
-namespace sys {
namespace fs {
std::string getMainExecutable(const char *argv0, void *MainExecAddr) {
@@ -268,21 +272,12 @@ std::error_code rename(const Twine &from, const Twine &to) {
return ec;
}
-std::error_code resize_file(const Twine &path, uint64_t size) {
- SmallVector<wchar_t, 128> path_utf16;
-
- if (std::error_code ec = widenPath(path, path_utf16))
- return ec;
-
- int fd = ::_wopen(path_utf16.begin(), O_BINARY | _O_RDWR, S_IWRITE);
- if (fd == -1)
- return std::error_code(errno, std::generic_category());
+std::error_code resize_file(int FD, uint64_t Size) {
#ifdef HAVE__CHSIZE_S
- errno_t error = ::_chsize_s(fd, size);
+ errno_t error = ::_chsize_s(FD, Size);
#else
- errno_t error = ::_chsize(fd, size);
+ errno_t error = ::_chsize(FD, Size);
#endif
- ::close(fd);
return std::error_code(error, std::generic_category());
}
@@ -463,17 +458,15 @@ std::error_code setLastModificationAndAccessTime(int FD, TimeValue Time) {
return std::error_code();
}
-std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset) {
- FileDescriptor = FD;
+std::error_code mapped_file_region::init(int FD, uint64_t Offset,
+ mapmode Mode) {
// Make sure that the requested size fits within SIZE_T.
- if (Size > std::numeric_limits<SIZE_T>::max()) {
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
+ if (Size > std::numeric_limits<SIZE_T>::max())
return make_error_code(errc::invalid_argument);
- }
+
+ HANDLE FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(FD));
+ if (FileHandle == INVALID_HANDLE_VALUE)
+ return make_error_code(errc::bad_file_descriptor);
DWORD flprotect;
switch (Mode) {
@@ -482,18 +475,13 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
case priv: flprotect = PAGE_WRITECOPY; break;
}
- FileMappingHandle =
+ HANDLE FileMappingHandle =
::CreateFileMappingW(FileHandle, 0, flprotect,
(Offset + Size) >> 32,
(Offset + Size) & 0xffffffff,
0);
if (FileMappingHandle == NULL) {
std::error_code ec = windows_error(GetLastError());
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
return ec;
}
@@ -511,11 +499,6 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
if (Mapping == NULL) {
std::error_code ec = windows_error(GetLastError());
::CloseHandle(FileMappingHandle);
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
return ec;
}
@@ -526,11 +509,6 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
std::error_code ec = windows_error(GetLastError());
::UnmapViewOfFile(Mapping);
::CloseHandle(FileMappingHandle);
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor);
- } else
- ::CloseHandle(FileHandle);
return ec;
}
Size = mbi.RegionSize;
@@ -539,84 +517,15 @@ std::error_code mapped_file_region::init(int FD, bool CloseFD, uint64_t Offset)
// Close all the handles except for the view. It will keep the other handles
// alive.
::CloseHandle(FileMappingHandle);
- if (FileDescriptor) {
- if (CloseFD)
- _close(FileDescriptor); // Also closes FileHandle.
- } else
- ::CloseHandle(FileHandle);
return std::error_code();
}
-mapped_file_region::mapped_file_region(const Twine &path,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- std::error_code &ec)
- : Mode(mode)
- , Size(length)
- , Mapping()
- , FileDescriptor()
- , FileHandle(INVALID_HANDLE_VALUE)
- , FileMappingHandle() {
- SmallVector<wchar_t, 128> path_utf16;
-
- // Convert path to UTF-16.
- if ((ec = widenPath(path, path_utf16)))
- return;
-
- // Get file handle for creating a file mapping.
- FileHandle = ::CreateFileW(c_str(path_utf16),
- Mode == readonly ? GENERIC_READ
- : GENERIC_READ | GENERIC_WRITE,
- Mode == readonly ? FILE_SHARE_READ
- : 0,
- 0,
- Mode == readonly ? OPEN_EXISTING
- : OPEN_ALWAYS,
- Mode == readonly ? FILE_ATTRIBUTE_READONLY
- : FILE_ATTRIBUTE_NORMAL,
- 0);
- if (FileHandle == INVALID_HANDLE_VALUE) {
- ec = windows_error(::GetLastError());
- return;
- }
-
- FileDescriptor = 0;
- ec = init(FileDescriptor, true, offset);
- if (ec) {
- Mapping = FileMappingHandle = 0;
- FileHandle = INVALID_HANDLE_VALUE;
- FileDescriptor = 0;
- }
-}
-
-mapped_file_region::mapped_file_region(int fd,
- bool closefd,
- mapmode mode,
- uint64_t length,
- uint64_t offset,
- std::error_code &ec)
- : Mode(mode)
- , Size(length)
- , Mapping()
- , FileDescriptor(fd)
- , FileHandle(INVALID_HANDLE_VALUE)
- , FileMappingHandle() {
- FileHandle = reinterpret_cast<HANDLE>(_get_osfhandle(fd));
- if (FileHandle == INVALID_HANDLE_VALUE) {
- if (closefd)
- _close(FileDescriptor);
- FileDescriptor = 0;
- ec = make_error_code(errc::bad_file_descriptor);
- return;
- }
-
- ec = init(FileDescriptor, closefd, offset);
- if (ec) {
- Mapping = FileMappingHandle = 0;
- FileHandle = INVALID_HANDLE_VALUE;
- FileDescriptor = 0;
- }
+mapped_file_region::mapped_file_region(int fd, mapmode mode, uint64_t length,
+ uint64_t offset, std::error_code &ec)
+ : Size(length), Mapping() {
+ ec = init(fd, offset, mode);
+ if (ec)
+ Mapping = 0;
}
mapped_file_region::~mapped_file_region() {
@@ -624,30 +533,12 @@ mapped_file_region::~mapped_file_region() {
::UnmapViewOfFile(Mapping);
}
-mapped_file_region::mapped_file_region(mapped_file_region &&other)
- : Mode(other.Mode)
- , Size(other.Size)
- , Mapping(other.Mapping)
- , FileDescriptor(other.FileDescriptor)
- , FileHandle(other.FileHandle)
- , FileMappingHandle(other.FileMappingHandle) {
- other.Mapping = other.FileMappingHandle = 0;
- other.FileHandle = INVALID_HANDLE_VALUE;
- other.FileDescriptor = 0;
-}
-
-mapped_file_region::mapmode mapped_file_region::flags() const {
- assert(Mapping && "Mapping failed but used anyway!");
- return Mode;
-}
-
uint64_t mapped_file_region::size() const {
assert(Mapping && "Mapping failed but used anyway!");
return Size;
}
char *mapped_file_region::data() const {
- assert(Mode != readonly && "Cannot get non-const data for readonly mapping!");
assert(Mapping && "Mapping failed but used anyway!");
return reinterpret_cast<char*>(Mapping);
}
diff --git a/lib/Support/Windows/Process.inc b/lib/Support/Windows/Process.inc
index 3819e63..854eac7 100644
--- a/lib/Support/Windows/Process.inc
+++ b/lib/Support/Windows/Process.inc
@@ -49,10 +49,6 @@
using namespace llvm;
using namespace sys;
-process::id_type self_process::get_id() {
- return GetCurrentProcessId();
-}
-
static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
ULARGE_INTEGER TimeInteger;
TimeInteger.LowPart = Time.dwLowDateTime;
@@ -65,28 +61,10 @@ static TimeValue getTimeValueFromFILETIME(FILETIME Time) {
(TimeInteger.QuadPart % 10000000) * 100));
}
-TimeValue self_process::get_user_time() const {
- FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
- if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
- &UserTime) == 0)
- return TimeValue();
-
- return getTimeValueFromFILETIME(UserTime);
-}
-
-TimeValue self_process::get_system_time() const {
- FILETIME ProcCreate, ProcExit, KernelTime, UserTime;
- if (GetProcessTimes(GetCurrentProcess(), &ProcCreate, &ProcExit, &KernelTime,
- &UserTime) == 0)
- return TimeValue();
-
- return getTimeValueFromFILETIME(KernelTime);
-}
-
// This function retrieves the page size using GetNativeSystemInfo() and is
// present solely so it can be called once to initialize the self_process member
// below.
-static unsigned getPageSize() {
+static unsigned computePageSize() {
// GetNativeSystemInfo() provides the physical page size which may differ
// from GetSystemInfo() in 32-bit applications running under WOW64.
SYSTEM_INFO info;
@@ -96,12 +74,11 @@ static unsigned getPageSize() {
return static_cast<unsigned>(info.dwPageSize);
}
-// This constructor guaranteed to be run exactly once on a single thread, and
-// sets up various process invariants that can be queried cheaply from then on.
-self_process::self_process() : PageSize(getPageSize()) {
+unsigned Process::getPageSize() {
+ static unsigned Ret = computePageSize();
+ return Ret;
}
-
size_t
Process::GetMallocUsage()
{
diff --git a/lib/Support/Windows/Program.inc b/lib/Support/Windows/Program.inc
index 72c2a58..c370077 100644
--- a/lib/Support/Windows/Program.inc
+++ b/lib/Support/Windows/Program.inc
@@ -15,8 +15,8 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/Support/ConvertUTF.h"
#include "llvm/Support/FileSystem.h"
-#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/WindowsError.h"
+#include "llvm/Support/raw_ostream.h"
#include <cstdio>
#include <fcntl.h>
#include <io.h>
@@ -62,7 +62,8 @@ ErrorOr<std::string> sys::findProgramByName(StringRef Name,
SmallVector<StringRef, 12> PathExts;
PathExts.push_back("");
PathExts.push_back(".exe"); // FIXME: This must be in %PATHEXT%.
- SplitString(std::getenv("PATHEXT"), PathExts, ";");
+ if (const char *PathExtEnv = std::getenv("PATHEXT"))
+ SplitString(PathExtEnv, PathExts, ";");
SmallVector<wchar_t, MAX_PATH> U16Result;
DWORD Len = MAX_PATH;
@@ -117,14 +118,19 @@ static HANDLE RedirectIO(const StringRef *path, int fd, std::string* ErrMsg) {
sa.bInheritHandle = TRUE;
SmallVector<wchar_t, 128> fnameUnicode;
- if (windows::UTF8ToUTF16(fname, fnameUnicode))
- return INVALID_HANDLE_VALUE;
-
+ if (path->empty()) {
+ // Don't play long-path tricks on "NUL".
+ if (windows::UTF8ToUTF16(fname, fnameUnicode))
+ return INVALID_HANDLE_VALUE;
+ } else {
+ if (path::widenPath(fname, fnameUnicode))
+ return INVALID_HANDLE_VALUE;
+ }
h = CreateFileW(fnameUnicode.data(), fd ? GENERIC_WRITE : GENERIC_READ,
FILE_SHARE_READ, &sa, fd == 0 ? OPEN_EXISTING : CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
if (h == INVALID_HANDLE_VALUE) {
- MakeErrMsg(ErrMsg, std::string(fname) + ": Can't open file for " +
+ MakeErrMsg(ErrMsg, fname + ": Can't open file for " +
(fd ? "input: " : "output: "));
}
@@ -322,7 +328,7 @@ static bool Execute(ProcessInfo &PI, StringRef Program, const char **args,
fflush(stderr);
SmallVector<wchar_t, MAX_PATH> ProgramUtf16;
- if (std::error_code ec = windows::UTF8ToUTF16(Program, ProgramUtf16)) {
+ if (std::error_code ec = path::widenPath(Program, ProgramUtf16)) {
SetLastError(ec.value());
MakeErrMsg(ErrMsg,
std::string("Unable to convert application name to UTF-16"));
diff --git a/lib/Support/Windows/Signals.inc b/lib/Support/Windows/Signals.inc
index 35ba6f8..aa1aa72 100644
--- a/lib/Support/Windows/Signals.inc
+++ b/lib/Support/Windows/Signals.inc
@@ -13,6 +13,7 @@
#include "llvm/Support/FileSystem.h"
#include <algorithm>
+#include <signal.h>
#include <stdio.h>
#include <vector>
@@ -165,7 +166,6 @@ static std::vector<std::string> *FilesToRemove = NULL;
static std::vector<std::pair<void(*)(void*), void*> > *CallBacksToRun = 0;
static bool RegisteredUnhandledExceptionFilter = false;
static bool CleanupExecuted = false;
-static bool ExitOnUnhandledExceptions = false;
static PTOP_LEVEL_EXCEPTION_FILTER OldFilter = NULL;
// Windows creates a new thread to execute the console handler when an event
@@ -184,7 +184,8 @@ namespace llvm {
/// AvoidMessageBoxHook - Emulates hitting "retry" from an "abort, retry,
/// ignore" CRT debug report dialog. "retry" raises an exception which
/// ultimately triggers our stack dumper.
-static int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
+static LLVM_ATTRIBUTE_UNUSED int
+AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
// Set *Return to the retry code for the return value of _CrtDbgReport:
// http://msdn.microsoft.com/en-us/library/8hyw4sy7(v=vs.71).aspx
// This may also trigger just-in-time debugging via DebugBreak().
@@ -196,6 +197,12 @@ static int AvoidMessageBoxHook(int ReportType, char *Message, int *Return) {
#endif
+extern "C" void HandleAbort(int Sig) {
+ if (Sig == SIGABRT) {
+ LLVM_BUILTIN_TRAP;
+ }
+}
+
static void RegisterHandler() {
#if __MINGW32__ && !defined(__MINGW64_VERSION_MAJOR)
// On MinGW.org, we need to load up the symbols explicitly, because the
@@ -226,17 +233,6 @@ static void RegisterHandler() {
OldFilter = SetUnhandledExceptionFilter(LLVMUnhandledExceptionFilter);
SetConsoleCtrlHandler(LLVMConsoleCtrlHandler, TRUE);
- // Environment variable to disable any kind of crash dialog.
- if (getenv("LLVM_DISABLE_CRASH_REPORT")) {
-#ifdef _MSC_VER
- _CrtSetReportHook(AvoidMessageBoxHook);
-#endif
- SetErrorMode(SEM_FAILCRITICALERRORS |
- SEM_NOGPFAULTERRORBOX |
- SEM_NOOPENFILEERRORBOX);
- ExitOnUnhandledExceptions = true;
- }
-
// IMPORTANT NOTE: Caller must call LeaveCriticalSection(&CriticalSection) or
// else multi-threading problems will ensue.
}
@@ -276,9 +272,29 @@ void sys::DontRemoveFileOnSignal(StringRef Filename) {
LeaveCriticalSection(&CriticalSection);
}
+void sys::DisableSystemDialogsOnCrash() {
+ // Crash to stack trace handler on abort.
+ signal(SIGABRT, HandleAbort);
+
+ // The following functions are not reliably accessible on MinGW.
+#ifdef _MSC_VER
+ // We're already handling writing a "something went wrong" message.
+ _set_abort_behavior(0, _WRITE_ABORT_MSG);
+ // Disable Dr. Watson.
+ _set_abort_behavior(0, _CALL_REPORTFAULT);
+ _CrtSetReportHook(AvoidMessageBoxHook);
+#endif
+
+ // Disable standard error dialog box.
+ SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
+ SEM_NOOPENFILEERRORBOX);
+ _set_error_mode(_OUT_TO_STDERR);
+}
+
/// PrintStackTraceOnErrorSignal - When an error signal (such as SIBABRT or
/// SIGSEGV) is delivered to the process, print a stack trace and then exit.
void sys::PrintStackTraceOnErrorSignal() {
+ DisableSystemDialogsOnCrash();
RegisterHandler();
LeaveCriticalSection(&CriticalSection);
}
@@ -437,14 +453,7 @@ static LONG WINAPI LLVMUnhandledExceptionFilter(LPEXCEPTION_POINTERS ep) {
fputc('\n', stderr);
}
- if (ExitOnUnhandledExceptions)
- _exit(ep->ExceptionRecord->ExceptionCode);
-
- // Allow dialog box to pop up allowing choice to start debugger.
- if (OldFilter)
- return (*OldFilter)(ep);
- else
- return EXCEPTION_CONTINUE_SEARCH;
+ _exit(ep->ExceptionRecord->ExceptionCode);
}
static BOOL WINAPI LLVMConsoleCtrlHandler(DWORD dwCtrlType) {
diff --git a/lib/Support/Windows/ThreadLocal.inc b/lib/Support/Windows/ThreadLocal.inc
index 14ce619..b9cb8ff 100644
--- a/lib/Support/Windows/ThreadLocal.inc
+++ b/lib/Support/Windows/ThreadLocal.inc
@@ -34,7 +34,7 @@ ThreadLocalImpl::~ThreadLocalImpl() {
TlsFree(*tls);
}
-const void* ThreadLocalImpl::getInstance() {
+void *ThreadLocalImpl::getInstance() {
DWORD* tls = reinterpret_cast<DWORD*>(&data);
return TlsGetValue(*tls);
}
diff --git a/lib/Support/Windows/WindowsSupport.h b/lib/Support/Windows/WindowsSupport.h
index 6d9c5fb..5bb0b8d 100644
--- a/lib/Support/Windows/WindowsSupport.h
+++ b/lib/Support/Windows/WindowsSupport.h
@@ -19,6 +19,9 @@
//=== is guaranteed to work on *all* Win32 variants.
//===----------------------------------------------------------------------===//
+#ifndef LLVM_SUPPORT_WINDOWSSUPPORT_H
+#define LLVM_SUPPORT_WINDOWSSUPPORT_H
+
// mingw-w64 tends to define it as 0x0502 in its headers.
#undef _WIN32_WINNT
#undef _WIN32_IE
@@ -30,6 +33,7 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/Twine.h"
#include "llvm/Config/config.h" // Get build system configuration settings
#include "llvm/Support/Compiler.h"
#include <system_error>
@@ -88,7 +92,7 @@ public:
}
// True if Handle is valid.
- LLVM_EXPLICIT operator bool() const {
+ explicit operator bool() const {
return HandleTraits::IsValid(Handle) ? true : false;
}
@@ -162,6 +166,11 @@ c_str(SmallVectorImpl<T> &str) {
}
namespace sys {
+namespace path {
+std::error_code widenPath(const Twine &Path8,
+ SmallVectorImpl<wchar_t> &Path16);
+} // end namespace path
+
namespace windows {
std::error_code UTF8ToUTF16(StringRef utf8, SmallVectorImpl<wchar_t> &utf16);
std::error_code UTF16ToUTF8(const wchar_t *utf16, size_t utf16_len,
@@ -172,3 +181,5 @@ std::error_code UTF16ToCurCP(const wchar_t *utf16, size_t utf16_len,
} // end namespace windows
} // end namespace sys
} // end namespace llvm.
+
+#endif
diff --git a/lib/Support/Windows/explicit_symbols.inc b/lib/Support/Windows/explicit_symbols.inc
index cd56b13..bbbf7ea 100644
--- a/lib/Support/Windows/explicit_symbols.inc
+++ b/lib/Support/Windows/explicit_symbols.inc
@@ -10,9 +10,15 @@
#ifdef HAVE___CHKSTK
EXPLICIT_SYMBOL(__chkstk)
#endif
+#ifdef HAVE___CHKSTK_MS
+ EXPLICIT_SYMBOL(__chkstk_ms)
+#endif
#ifdef HAVE____CHKSTK
EXPLICIT_SYMBOL(___chkstk)
#endif
+#ifdef HAVE____CHKSTK_MS
+ EXPLICIT_SYMBOL(___chkstk_ms)
+#endif
#ifdef HAVE___MAIN
EXPLICIT_SYMBOL(__main) // FIXME: Don't call it.
#endif
diff --git a/lib/Support/YAMLParser.cpp b/lib/Support/YAMLParser.cpp
index 4688ff1..6ae7945 100644
--- a/lib/Support/YAMLParser.cpp
+++ b/lib/Support/YAMLParser.cpp
@@ -1528,12 +1528,10 @@ Stream::~Stream() {}
bool Stream::failed() { return scanner->failed(); }
void Stream::printError(Node *N, const Twine &Msg) {
- SmallVector<SMRange, 1> Ranges;
- Ranges.push_back(N->getSourceRange());
scanner->printError( N->getSourceRange().Start
, SourceMgr::DK_Error
, Msg
- , Ranges);
+ , N->getSourceRange());
}
document_iterator Stream::begin() {
@@ -1570,11 +1568,11 @@ std::string Node::getVerbatimTag() const {
if (Raw.find_last_of('!') == 0) {
Ret = Doc->getTagMap().find("!")->second;
Ret += Raw.substr(1);
- return std::move(Ret);
+ return Ret;
} else if (Raw.startswith("!!")) {
Ret = Doc->getTagMap().find("!!")->second;
Ret += Raw.substr(2);
- return std::move(Ret);
+ return Ret;
} else {
StringRef TagHandle = Raw.substr(0, Raw.find_last_of('!') + 1);
std::map<StringRef, StringRef>::const_iterator It =
@@ -1588,7 +1586,7 @@ std::string Node::getVerbatimTag() const {
setError(Twine("Unknown tag handle ") + TagHandle, T);
}
Ret += Raw.substr(Raw.find_last_of('!') + 1);
- return std::move(Ret);
+ return Ret;
}
}
diff --git a/lib/Support/YAMLTraits.cpp b/lib/Support/YAMLTraits.cpp
index 81edca2..43a0e10 100644
--- a/lib/Support/YAMLTraits.cpp
+++ b/lib/Support/YAMLTraits.cpp
@@ -8,12 +8,12 @@
//===----------------------------------------------------------------------===//
#include "llvm/Support/Errc.h"
-#include "llvm/Support/YAMLTraits.h"
#include "llvm/ADT/Twine.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/YAMLParser.h"
+#include "llvm/Support/YAMLTraits.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
#include <cstring>
@@ -233,6 +233,13 @@ bool Input::matchEnumScalar(const char *Str, bool) {
return false;
}
+bool Input::matchEnumFallback() {
+ if (ScalarMatchFound)
+ return false;
+ ScalarMatchFound = true;
+ return true;
+}
+
void Input::endEnumScalar() {
if (!ScalarMatchFound) {
setError(CurrentNode, "unknown enumerated scalar");
@@ -508,6 +515,13 @@ bool Output::matchEnumScalar(const char *Str, bool Match) {
return false;
}
+bool Output::matchEnumFallback() {
+ if (EnumerationMatchFound)
+ return false;
+ EnumerationMatchFound = true;
+ return true;
+}
+
void Output::endEnumScalar() {
if (!EnumerationMatchFound)
llvm_unreachable("bad runtime enum value");
@@ -669,7 +683,7 @@ StringRef ScalarTraits<StringRef>::input(StringRef Scalar, void *,
Val = Scalar;
return StringRef();
}
-
+
void ScalarTraits<std::string>::output(const std::string &Val, void *,
raw_ostream &Out) {
Out << Val;
diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp
index bbbbe4a..051e2dd 100644
--- a/lib/Support/raw_ostream.cpp
+++ b/lib/Support/raw_ostream.cpp
@@ -242,7 +242,7 @@ raw_ostream &raw_ostream::operator<<(double N) {
char buf[16];
unsigned len;
- len = snprintf(buf, sizeof(buf), "%e", N);
+ len = format("%e", N).snprint(buf, sizeof(buf));
if (len <= sizeof(buf) - 2) {
if (len >= 5 && buf[len - 5] == 'e' && buf[len - 3] == '0') {
int cs = buf[len - 4];
@@ -312,6 +312,7 @@ raw_ostream &raw_ostream::write(const char *Ptr, size_t Size) {
// than the buffer. Directly write the chunk that is a multiple of the
// preferred buffer size and put the remainder in the buffer.
if (LLVM_UNLIKELY(OutBufCur == OutBufStart)) {
+ assert(NumBytes != 0 && "undefined behavior");
size_t BytesToWrite = Size - (Size % NumBytes);
write_impl(Ptr, BytesToWrite);
size_t BytesRemaining = Size - BytesToWrite;
@@ -409,9 +410,12 @@ raw_ostream &raw_ostream::operator<<(const FormattedString &FS) {
raw_ostream &raw_ostream::operator<<(const FormattedNumber &FN) {
if (FN.Hex) {
unsigned Nibbles = (64 - countLeadingZeros(FN.HexValue)+3)/4;
- unsigned Width = (FN.Width > Nibbles+2) ? FN.Width : Nibbles+2;
-
+ unsigned PrefixChars = FN.HexPrefix ? 2 : 0;
+ unsigned Width = std::max(FN.Width, Nibbles + PrefixChars);
+
char NumberBuffer[20] = "0x0000000000000000";
+ if (!FN.HexPrefix)
+ NumberBuffer[1] = '0';
char *EndPtr = NumberBuffer+Width;
char *CurPtr = EndPtr;
const char A = FN.Upper ? 'A' : 'a';
diff --git a/lib/Support/regcomp.c b/lib/Support/regcomp.c
index 0b5b765..ebde64f 100644
--- a/lib/Support/regcomp.c
+++ b/lib/Support/regcomp.c
@@ -49,6 +49,14 @@
#include "regcclass.h"
#include "regcname.h"
+#include "llvm/Config/config.h"
+#if HAVE_STDINT_H
+#include <stdint.h>
+#else
+/* Pessimistically bound memory use */
+#define SIZE_MAX UINT_MAX
+#endif
+
/*
* parse structure, passed up and down to avoid global variables and
* other clumsinesses
@@ -1069,6 +1077,8 @@ allocset(struct parse *p)
p->ncsalloc += CHAR_BIT;
nc = p->ncsalloc;
+ if (nc > SIZE_MAX / sizeof(cset))
+ goto nomem;
assert(nc % CHAR_BIT == 0);
nbytes = nc / CHAR_BIT * css;
@@ -1412,6 +1422,11 @@ enlarge(struct parse *p, sopno size)
if (p->ssize >= size)
return;
+ if ((uintptr_t)size > SIZE_MAX / sizeof(sop)) {
+ SETERROR(REG_ESPACE);
+ return;
+ }
+
sp = (sop *)realloc(p->strip, size*sizeof(sop));
if (sp == NULL) {
SETERROR(REG_ESPACE);
@@ -1428,6 +1443,12 @@ static void
stripsnug(struct parse *p, struct re_guts *g)
{
g->nstates = p->slen;
+ if ((uintptr_t)p->slen > SIZE_MAX / sizeof(sop)) {
+ g->strip = p->strip;
+ SETERROR(REG_ESPACE);
+ return;
+ }
+
g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof(sop));
if (g->strip == NULL) {
SETERROR(REG_ESPACE);