diff --git a/llvm/include/llvm/Support/CommandLine.h b/llvm/include/llvm/Support/CommandLine.h --- a/llvm/include/llvm/Support/CommandLine.h +++ b/llvm/include/llvm/Support/CommandLine.h @@ -285,7 +285,8 @@ StringRef ValueStr; // String describing what the value of this option is SmallVector Categories; // The Categories this option belongs to - SmallPtrSet Subs; // The subcommands this option belongs to. + + SmallPtrSet getSubCommands() const; inline enum NumOccurrencesFlag getNumOccurrencesFlag() const { return (enum NumOccurrencesFlag)Occurrences; @@ -304,6 +305,7 @@ } inline unsigned getMiscFlags() const { return Misc; } + inline bool isFullyInitialized() const { return FullyInitialized; } inline unsigned getPosition() const { return Position; } inline unsigned getNumAdditionalVals() const { return AdditionalVals; } @@ -317,12 +319,6 @@ return getNumOccurrencesFlag() == cl::ConsumeAfter; } - bool isInAllSubCommands() const { - return any_of(Subs, [](const SubCommand *SC) { - return SC == &*AllSubCommands; - }); - } - //-------------------------------------------------------------------------=== // Accessor functions set by OptionModifiers // @@ -336,7 +332,6 @@ void setMiscFlag(enum MiscFlags M) { Misc |= M; } void setPosition(unsigned pos) { Position = pos; } void addCategory(OptionCategory &C); - void addSubCommand(SubCommand &S) { Subs.insert(&S); } protected: explicit Option(enum NumOccurrencesFlag OccurrencesFlag, @@ -354,7 +349,14 @@ // addArgument - Register this argument with the commandline system. // - void addArgument(); + void addArgument(SubCommand &SC); + + // addArgument - Only called in done() method to add default + // TopLevelSubCommand. + void addArgument() { + if (!isFullyInitialized()) + addArgument(*TopLevelSubCommand); + } /// Unregisters this option from the CommandLine system. /// @@ -465,7 +467,7 @@ sub(SubCommand &S) : Sub(S) {} - template void apply(Opt &O) const { O.addSubCommand(Sub); } + template void apply(Opt &O) const { O.addArgument(Sub); } }; //===----------------------------------------------------------------------===// @@ -1772,11 +1774,9 @@ error("cl::alias must have argument name specified!"); if (!AliasFor) error("cl::alias must have an cl::aliasopt(option) specified!"); - if (!Subs.empty()) - error("cl::alias must not have cl::sub(), aliased option's cl::sub() will be used!"); - Subs = AliasFor->Subs; Categories = AliasFor->Categories; - addArgument(); + for(auto SC: AliasFor->getSubCommands()) + addArgument(*SC); } public: diff --git a/llvm/lib/Support/CommandLine.cpp b/llvm/lib/Support/CommandLine.cpp --- a/llvm/lib/Support/CommandLine.cpp +++ b/llvm/lib/Support/CommandLine.cpp @@ -142,7 +142,7 @@ // This collects Options added with the cl::DefaultOption flag. Since they can // be overridden, they are not added to the appropriate SubCommands until // ParseCommandLineOptions actually runs. - SmallVector DefaultOptions; + SmallVector, 4> DefaultOptions; // This collects the different option categories that have been registered. SmallPtrSet RegisteredOptionCategories; @@ -182,15 +182,16 @@ } void addLiteralOption(Option &Opt, StringRef Name) { - if (Opt.Subs.empty()) - addLiteralOption(Opt, &*TopLevelSubCommand, Name); - else { - for (auto SC : Opt.Subs) - addLiteralOption(Opt, SC, Name); - } + for(auto *SC: Opt.getSubCommands()) + addLiteralOption(Opt, SC, Name); } - void addOption(Option *O, SubCommand *SC) { + void addOption(Option *O, SubCommand *SC, bool ProcessDefaultOptions = false) { + if (!ProcessDefaultOptions && O->isDefaultOption()) { + DefaultOptions.push_back(std::make_pair(O, SC)); + return; + } + bool HadErrors = false; if (O->hasArgStr()) { // If it's a DefaultOption, check to make sure it isn't already there. @@ -232,22 +233,14 @@ for (const auto &Sub : RegisteredSubCommands) { if (SC == Sub) continue; - addOption(O, Sub); + addOption(O, Sub, ProcessDefaultOptions); } } } - void addOption(Option *O, bool ProcessDefaultOption = false) { - if (!ProcessDefaultOption && O->isDefaultOption()) { - DefaultOptions.push_back(O); - return; - } - - if (O->Subs.empty()) { - addOption(O, &*TopLevelSubCommand); - } else { - for (auto SC : O->Subs) - addOption(O, SC); + void addDefaultOptions() { + for (auto P: DefaultOptions) { + addOption(P.first, P.second, true); } } @@ -285,17 +278,8 @@ } void removeOption(Option *O) { - if (O->Subs.empty()) - removeOption(O, &*TopLevelSubCommand); - else { - if (O->isInAllSubCommands()) { - for (auto SC : RegisteredSubCommands) - removeOption(O, SC); - } else { - for (auto SC : O->Subs) - removeOption(O, SC); - } - } + for (auto SC : RegisteredSubCommands) + removeOption(O, SC); } bool hasOptions(const SubCommand &Sub) const { @@ -324,17 +308,8 @@ } void updateArgStr(Option *O, StringRef NewName) { - if (O->Subs.empty()) - updateArgStr(O, NewName, &*TopLevelSubCommand); - else { - if (O->isInAllSubCommands()) { - for (auto SC : RegisteredSubCommands) - updateArgStr(O, NewName, SC); - } else { - for (auto SC : O->Subs) - updateArgStr(O, NewName, SC); - } - } + for (auto SC : RegisteredSubCommands) + updateArgStr(O, NewName, SC); } void printOptionValues(); @@ -427,13 +402,25 @@ GlobalParser->MoreHelp.push_back(Help); } -void Option::addArgument() { - GlobalParser->addOption(this); +void Option::addArgument(SubCommand &SC) { + GlobalParser->addOption(this, &SC); FullyInitialized = true; } void Option::removeArgument() { GlobalParser->removeOption(this); } +SmallPtrSet Option::getSubCommands() const { + SmallPtrSet Subs; + for(auto SC: GlobalParser->getRegisteredSubcommands()) { + auto I = SC->OptionsMap.find(ArgStr); + if(I != SC->OptionsMap.end()) + Subs.insert(SC); + } + if(ArgStr.empty()) + Subs.insert(&*TopLevelSubCommand); + return Subs; +} + void Option::setArgStr(StringRef S) { if (FullyInitialized) GlobalParser->updateArgStr(this, S); @@ -1261,9 +1248,7 @@ auto &SinkOpts = ChosenSubCommand->SinkOpts; auto &OptionsMap = ChosenSubCommand->OptionsMap; - for (auto O: DefaultOptions) { - addOption(O, true); - } + addDefaultOptions(); if (ConsumeAfterOpt) { assert(PositionalOpts.size() > 0 &&