Skip to content

Commit c1cddc9

Browse files
committed
Remove TopLevelCommand abstraction completely.
1 parent d41c2ae commit c1cddc9

File tree

5 files changed

+49
-43
lines changed

5 files changed

+49
-43
lines changed

llvm/examples/OptSubcommand/llvm-hello-sub.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ int main(int argc, char **argv) {
8282
T.getCommands(), HandleMultipleSubcommands, HandleOtherPositionals);
8383
// Handle help. When help options is found, ignore all other options and exit
8484
// after printing help.
85+
8586
if (Args.hasArg(OPT_help)) {
8687
T.printHelp(llvm::outs(), "llvm-hello-sub [subcommand] [options]",
8788
"LLVM Hello Subcommand Example", false, false, Visibility(),

llvm/include/llvm/Option/OptParser.td

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,8 @@ class Subcommand<string name, string helpText, string usage = "">
108108
string Usage = usage;
109109
}
110110

111-
// Compile time representation for top level command (aka toolname).
112-
// Offers backward compatibility with existing Option class definitions before
113-
// introduction of commandGroup in Option class to support subcommands.
114-
def TopLevelCommand : Command<"TopLevelCommand">;
115-
116111
class Option<list<string> prefixes, string name, OptionKind kind,
117-
list<Command> commandGroup = [TopLevelCommand]> {
112+
list<Command> commandGroup = []> {
118113
string EnumName = ?; // Uses the def name if undefined.
119114
list<string> Prefixes = prefixes;
120115
string Name = name;
@@ -150,28 +145,27 @@ class Option<list<string> prefixes, string name, OptionKind kind,
150145

151146
// Helpers for defining options.
152147

153-
class Flag<list<string> prefixes, string name,
154-
list<Command> commandGroup = [TopLevelCommand]>
148+
class Flag<list<string> prefixes, string name, list<Command> commandGroup = []>
155149
: Option<prefixes, name, KIND_FLAG, commandGroup>;
156150
class Joined<list<string> prefixes, string name,
157-
list<Command> commandGroup = [TopLevelCommand]>
151+
list<Command> commandGroup = []>
158152
: Option<prefixes, name, KIND_JOINED, commandGroup>;
159153
class Separate<list<string> prefixes, string name,
160-
list<Command> commandGroup = [TopLevelCommand]>
154+
list<Command> commandGroup = []>
161155
: Option<prefixes, name, KIND_SEPARATE, commandGroup>;
162156
class CommaJoined<list<string> prefixes, string name,
163-
list<Command> commandGroup = [TopLevelCommand]>
157+
list<Command> commandGroup = []>
164158
: Option<prefixes, name, KIND_COMMAJOINED, commandGroup>;
165159
class MultiArg<list<string> prefixes, string name, int numargs,
166-
list<Command> commandGroup = [TopLevelCommand]>
160+
list<Command> commandGroup = []>
167161
: Option<prefixes, name, KIND_MULTIARG, commandGroup> {
168162
int NumArgs = numargs;
169163
}
170164
class JoinedOrSeparate<list<string> prefixes, string name,
171-
list<Command> commandGroup = [TopLevelCommand]>
165+
list<Command> commandGroup = []>
172166
: Option<prefixes, name, KIND_JOINED_OR_SEPARATE, commandGroup>;
173167
class JoinedAndSeparate<list<string> prefixes, string name,
174-
list<Command> commandGroup = [TopLevelCommand]>
168+
list<Command> commandGroup = []>
175169
: Option<prefixes, name, KIND_JOINED_AND_SEPARATE, commandGroup>;
176170

177171
// Mix-ins for adding optional attributes.
@@ -295,7 +289,7 @@ class ValueExtractor<code extractor> { code ValueExtractor = extractor; }
295289

296290
// FIXME: Have generator validate that these appear in correct position (and
297291
// aren't duplicated).
298-
def INPUT : Option<[], "<input>", KIND_INPUT, [TopLevelCommand]>;
299-
def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN, [TopLevelCommand]>;
292+
def INPUT : Option<[], "<input>", KIND_INPUT>;
293+
def UNKNOWN : Option<[], "<unknown>", KIND_UNKNOWN>;
300294

301295
#endif // LLVM_OPTION_OPTPARSER_TD

llvm/lib/Option/ArgList.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -218,8 +218,8 @@ StringRef ArgList::getSubcommand(
218218

219219
size_t OldSize = SubCommands.size();
220220
for (const OptTable::Command &CMD : Commands) {
221-
if (StringRef(CMD.Name) == opt::TopLevelCommandName)
222-
continue;
221+
// if (StringRef(CMD.Name) == opt::TopLevelCommandName)
222+
// continue;
223223
if (StringRef(CMD.Name) == A->getValue())
224224
SubCommands.push_back(A->getValue());
225225
}

llvm/lib/Option/OptTable.cpp

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -789,52 +789,62 @@ void OptTable::internalPrintHelp(
789789
std::map<std::string, std::vector<OptionInfo>> GroupedOptionHelp;
790790

791791
const Command *ActiveCommand = getActiveCommand(Commands, Subcommand);
792-
if (ActiveCommand) {
792+
if (!Subcommand.empty()) {
793+
assert(ActiveCommand != nullptr && "Not a valid registered subcommand.");
793794
OS << ActiveCommand->HelpText << "\n\n";
794795
if (!StringRef(ActiveCommand->Usage).empty())
795796
OS << "USAGE: " << ActiveCommand->Usage << "\n\n";
796797
} else {
797798
OS << "USAGE: " << Usage << "\n\n";
798799
if (Commands.size() > 1) {
799800
OS << "SUBCOMMANDS:\n\n";
800-
// This loop prints subcommands list and sets ActiveCommand to
801-
// TopLevelCommand while iterating over all commands.
802-
for (const auto &C : Commands) {
803-
if (StringRef(C.Name) == opt::TopLevelCommandName) {
804-
ActiveCommand = &C;
805-
continue;
806-
}
801+
for (const auto &C : Commands)
807802
OS << C.Name << " - " << C.HelpText << "\n";
808-
}
809803
OS << "\n";
810804
}
811805
}
812806

813-
auto DoesOptionBelongToActiveCommand =
814-
[this, &ActiveCommand](const Info &CandidateInfo) {
815-
// ActiveCommand won't be set for tools that did not create command
816-
// group info table.
817-
if (!ActiveCommand)
818-
return true;
819-
ArrayRef<unsigned> CommandIDs =
820-
CandidateInfo.getCommandIDs(CommandIDsTable);
821-
unsigned ActiveCommandID = ActiveCommand - Commands.data();
822-
return is_contained(CommandIDs, ActiveCommandID);
823-
};
807+
auto DoesOptionBelongToSubcommand = [&](const Info &CandidateInfo) {
808+
// llvm::outs() << CandidateInfo.
809+
ArrayRef<unsigned> CommandIDs =
810+
CandidateInfo.getCommandIDs(CommandIDsTable);
811+
812+
// Options with no commands are global.
813+
if (CommandIDs.empty()) {
814+
// if Subcommand is not empty then don't print global options.
815+
return Subcommand.empty();
816+
}
817+
818+
// If we are not in a subcommand, don't show subcommand-specific options.
819+
if (Subcommand.empty())
820+
return false;
821+
822+
// The command ID is its index in the Commands table.
823+
unsigned ActiveCommandID = ActiveCommand - &Commands[0];
824+
825+
// Check if the option belongs to the active subcommand.
826+
for (unsigned ID : CommandIDs) {
827+
if (ID == ActiveCommandID) {
828+
return true;
829+
}
830+
}
831+
return false;
832+
};
824833

825834
for (unsigned Id = 1, e = getNumOptions() + 1; Id != e; ++Id) {
826835
// FIXME: Split out option groups.
827836
if (getOptionKind(Id) == Option::GroupClass)
828837
continue;
829838

830839
const Info &CandidateInfo = getInfo(Id);
840+
831841
if (!ShowHidden && (CandidateInfo.Flags & opt::HelpHidden))
832842
continue;
833843

834844
if (ExcludeOption(CandidateInfo))
835845
continue;
836846

837-
if (!DoesOptionBelongToActiveCommand(CandidateInfo))
847+
if (!DoesOptionBelongToSubcommand(CandidateInfo))
838848
continue;
839849

840850
// If an alias doesn't have a help text, show a help text for the aliased

llvm/utils/TableGen/OptionParserEmitter.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -262,10 +262,11 @@ static void emitOptionParser(const RecordKeeper &Records, raw_ostream &OS) {
262262

263263
std::vector<const Record *> Commands =
264264
Records.getAllDerivedDefinitions("Command");
265-
// TopLevelCommand should come first.
266-
std::stable_partition(Commands.begin(), Commands.end(), [](const Record *R) {
267-
return R->getName() == opt::TopLevelCommandName;
268-
});
265+
// // TopLevelCommand should come first.
266+
// std::stable_partition(Commands.begin(), Commands.end(), [](const Record *R)
267+
// {
268+
// return R->getName() == opt::TopLevelCommandName;
269+
// });
269270

270271
emitSourceFileHeader("Option Parsing Definitions", OS);
271272

0 commit comments

Comments
 (0)