#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
//===----------------------------------------------------------------------===//
// Template instantiations and anchors.
//
// Globals for name and overview of program. Program name is not a string to
// avoid static ctor/dtor issues.
static char ProgramName[80] = "<premain>";
// Globals for name and overview of program. Program name is not a string to
// avoid static ctor/dtor issues.
static char ProgramName[80] = "<premain>";
// This collects additional help to be printed.
static ManagedStatic<std::vector<const char*> > MoreHelp;
// This collects additional help to be printed.
static ManagedStatic<std::vector<const char*> > MoreHelp;
/// RegisteredOptionList - This is the list of the command line options that
/// have statically constructed themselves.
/// RegisteredOptionList - This is the list of the command line options that
/// have statically constructed themselves.
assert(RegisteredOptionList == this && "argument is not the last registered");
RegisteredOptionList = NextRegistered;
MarkOptionsChanged();
assert(RegisteredOptionList == this && "argument is not the last registered");
RegisteredOptionList = NextRegistered;
MarkOptionsChanged();
static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts,
SmallVectorImpl<Option*> &SinkOpts,
StringMap<Option*> &OptionsMap) {
static void GetOptionInfo(SmallVectorImpl<Option*> &PositionalOpts,
SmallVectorImpl<Option*> &SinkOpts,
StringMap<Option*> &OptionsMap) {
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.
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.
for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
// Add argument to the argument map!
if (OptionsMap.GetOrCreateValue(OptionNames[i], O).second != O) {
for (size_t i = 0, e = OptionNames.size(); i != e; ++i) {
// Add argument to the argument map!
if (OptionsMap.GetOrCreateValue(OptionNames[i], O).second != O) {
- errs() << ProgramName << ": CommandLine Error: Argument '"
- << OptionNames[i] << "' defined more than once!\n";
+ errs() << ProgramName << ": CommandLine Error: Option '"
+ << OptionNames[i] << "' registered more than once!\n";
+ HadErrors = true;
else if (O->getMiscFlags() & cl::Sink) // Remember sink options
SinkOpts.push_back(O);
else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
else if (O->getMiscFlags() & cl::Sink) // Remember sink options
SinkOpts.push_back(O);
else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
// Make sure that they are in order of registration not backwards.
std::reverse(PositionalOpts.begin(), PositionalOpts.end());
// Make sure that they are in order of registration not backwards.
std::reverse(PositionalOpts.begin(), PositionalOpts.end());
+
+ // 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");
static Option *LookupOption(StringRef &Arg, StringRef &Value,
const StringMap<Option*> &OptionsMap) {
// Reject all dashes.
static Option *LookupOption(StringRef &Arg, StringRef &Value,
const StringMap<Option*> &OptionsMap) {
// Reject all dashes.
}
// 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 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));
Value = Arg.substr(EqualPos+1);
Arg = Arg.substr(0, EqualPos);
Value = Arg.substr(EqualPos+1);
Arg = Arg.substr(0, EqualPos);
const StringMap<Option*> &OptionsMap,
std::string &NearestString) {
// Reject all dashes.
const StringMap<Option*> &OptionsMap,
std::string &NearestString) {
// Reject all dashes.
// Split on any equal sign.
std::pair<StringRef, StringRef> SplitArg = Arg.split('=');
// Split on any equal sign.
std::pair<StringRef, StringRef> SplitArg = Arg.split('=');
unsigned BestDistance = 0;
for (StringMap<Option*>::const_iterator it = OptionsMap.begin(),
ie = OptionsMap.end(); it != ie; ++it) {
unsigned BestDistance = 0;
for (StringMap<Option*>::const_iterator it = OptionsMap.begin(),
ie = OptionsMap.end(); it != ie; ++it) {
if (i+1 >= argc)
return Handler->error("requires a value!");
// Steal the next argument, like for '-o filename'
if (i+1 >= argc)
return Handler->error("requires a value!");
// Steal the next argument, like for '-o filename'
- return ProvideOption(Handler, Handler->ArgStr, Arg, 0, 0, Dummy);
+ return ProvideOption(Handler, Handler->ArgStr, Arg, 0, nullptr, Dummy);
static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
bool &ErrorParsing,
const StringMap<Option*> &OptionsMap) {
static Option *HandlePrefixedOrGroupedOption(StringRef &Arg, StringRef &Value,
bool &ErrorParsing,
const StringMap<Option*> &OptionsMap) {
// Do the lookup!
size_t Length = 0;
Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);
// Do the lookup!
size_t Length = 0;
Option *PGOpt = getOptionPred(Arg, Length, isPrefixedOrGrouping, OptionsMap);
// If the option is a prefixed option, then the value is simply the
// rest of the name... so fall through to later processing, by
// If the option is a prefixed option, then the value is simply the
// rest of the name... so fall through to later processing, by
"Option can not be cl::Grouping AND cl::ValueRequired!");
int Dummy = 0;
ErrorParsing |= ProvideOption(PGOpt, OneArgName,
"Option can not be cl::Grouping AND cl::ValueRequired!");
int Dummy = 0;
ErrorParsing |= ProvideOption(PGOpt, OneArgName,
- StringRef(), 0, 0, Dummy);
+ StringRef(), 0, nullptr, Dummy);
// Get the next grouping option.
PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);
// Get the next grouping option.
PGOpt = getOptionPred(Arg, Length, isGrouping, OptionsMap);
static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &NewArgv) {
static bool ExpandResponseFile(const char *FName, StringSaver &Saver,
TokenizerCallback Tokenizer,
SmallVectorImpl<const char *> &NewArgv) {
- OwningPtr<MemoryBuffer> MemBuf;
- if (MemoryBuffer::getFile(FName, MemBuf))
+ ErrorOr<std::unique_ptr<MemoryBuffer>> MemBufOrErr =
+ MemoryBuffer::getFile(FName);
+ if (!MemBufOrErr)
std::string UTF8Buf;
if (hasUTF16ByteOrderMark(BufRef)) {
if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))
std::string UTF8Buf;
if (hasUTF16ByteOrderMark(BufRef)) {
if (!convertUTF16ToUTF8String(BufRef, UTF8Buf))
argc = static_cast<int>(newArgv.size());
// Copy the program name into ProgName, making sure not to overflow it.
argc = static_cast<int>(newArgv.size());
// Copy the program name into ProgName, making sure not to overflow it.
size_t Len = std::min(ProgName.size(), size_t(79));
memcpy(ProgramName, ProgName.data(), Len);
ProgramName[Len] = '\0';
size_t Len = std::min(ProgName.size(), size_t(79));
memcpy(ProgramName, ProgName.data(), Len);
ProgramName[Len] = '\0';
// Determine whether or not there are an unlimited number of positionals
bool HasUnlimitedPositionals = false;
// Determine whether or not there are an unlimited number of positionals
bool HasUnlimitedPositionals = false;
if (!PositionalOpts.empty()) {
if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
assert(PositionalOpts.size() > 1 &&
if (!PositionalOpts.empty()) {
if (PositionalOpts[0]->getNumOccurrencesFlag() == cl::ConsumeAfter) {
assert(PositionalOpts.size() > 1 &&
// If the program has named positional arguments, and the name has been run
// across, keep track of which positional argument was named. Otherwise put
// the positional args into the PositionalVals list...
// If the program has named positional arguments, and the name has been run
// across, keep track of which positional argument was named. Otherwise put
// the positional args into the PositionalVals list...
// Loop over all of the arguments... processing them.
bool DashDashFound = false; // Have we read '--'?
for (int i = 1; i < argc; ++i) {
// Loop over all of the arguments... processing them.
bool DashDashFound = false; // Have we read '--'?
for (int i = 1; i < argc; ++i) {
// All of the positional arguments have been fulfulled, give the rest to
// the consume after option... if it's specified...
//
// All of the positional arguments have been fulfulled, give the rest to
// the consume after option... if it's specified...
//
for (++i; i < argc; ++i)
PositionalVals.push_back(std::make_pair(argv[i],i));
break; // Handle outside of the argument processing loop...
for (++i; i < argc; ++i)
PositionalVals.push_back(std::make_pair(argv[i],i));
break; // Handle outside of the argument processing loop...
Handler = LookupOption(ArgName, Value, Opts);
// Check to see if this "option" is really a prefixed or grouped argument.
Handler = LookupOption(ArgName, Value, Opts);
// Check to see if this "option" is really a prefixed or grouped argument.
Handler = HandlePrefixedOrGroupedOption(ArgName, Value,
ErrorParsing, Opts);
// Otherwise, look for the closest available option to report to the user
// in the upcoming error.
Handler = HandlePrefixedOrGroupedOption(ArgName, Value,
ErrorParsing, Opts);
// Otherwise, look for the closest available option to report to the user
// in the upcoming error.
if (SinkOpts.empty()) {
errs() << ProgramName << ": Unknown command line argument '"
<< argv[i] << "'. Try: '" << argv[0] << " -help'\n";
if (SinkOpts.empty()) {
errs() << ProgramName << ": Unknown command line argument '"
<< argv[i] << "'. Try: '" << argv[0] << " -help'\n";
// Positional args have already been handled if ConsumeAfter is specified.
unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
// Positional args have already been handled if ConsumeAfter is specified.
unsigned ValNo = 0, NumVals = static_cast<unsigned>(PositionalVals.size());
for (size_t i = 0, e = PositionalOpts.size(); i != e; ++i) {
- for (StringMap<Option*>::iterator I = Opts.begin(),
- E = Opts.end(); I != E; ++I) {
- switch (I->second->getNumOccurrencesFlag()) {
+ for (const auto &Opt : Opts) {
+ switch (Opt.second->getNumOccurrencesFlag()) {
if (!PositionalOpts.empty() &&
PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
CAOpt = PositionalOpts[0];
if (!PositionalOpts.empty() &&
PositionalOpts[0]->getNumOccurrencesFlag() == ConsumeAfter)
CAOpt = PositionalOpts[0];
if (PositionalOpts[i]->ArgStr[0])
outs() << " --" << PositionalOpts[i]->ArgStr;
outs() << " " << PositionalOpts[i]->HelpStr;
if (PositionalOpts[i]->ArgStr[0])
outs() << " --" << PositionalOpts[i]->ArgStr;
outs() << " " << PositionalOpts[i]->HelpStr;
outs() << '\n';
for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(),
E = ExtraVersionPrinters->end();
outs() << '\n';
for (std::vector<void (*)()>::iterator I = ExtraVersionPrinters->begin(),
E = ExtraVersionPrinters->end();