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 @@ -1321,12 +1321,20 @@ Errs, LongOptionsUseDoubleDash); } +/// Reset all options at least once, so that we can parse different options. void CommandLineParser::ResetAllOptionOccurrences() { - // So that we can parse different command lines multiple times in succession - // we reset all option values to look like they have never been seen before. + // Reset all option values to look like they have never been seen before. + // Options might be reset twice (they can be reference in both OptionsMap + // and one of the other members), but that does not harm. for (auto *SC : RegisteredSubCommands) { for (auto &O : SC->OptionsMap) O.second->reset(); + for (Option *O : SC->PositionalOpts) + O->reset(); + for (Option *O : SC->SinkOpts) + O->reset(); + if (SC->ConsumeAfterOpt) + SC->ConsumeAfterOpt->reset(); } } diff --git a/llvm/unittests/Support/CommandLineTest.cpp b/llvm/unittests/Support/CommandLineTest.cpp --- a/llvm/unittests/Support/CommandLineTest.cpp +++ b/llvm/unittests/Support/CommandLineTest.cpp @@ -1894,4 +1894,34 @@ EXPECT_TRUE(Errs.empty()); } +TEST(CommandLineTest, ResetAllOptionOccurrences) { + cl::ResetCommandLineParser(); + + // -option [sink] input [args] + StackOption Option("option"); + StackOption> Sink(cl::Sink); + StackOption Input(cl::Positional); + StackOption> ExtraArgs(cl::ConsumeAfter); + + const char *Args[] = {"prog", "-option", "-unknown", "input", "-arg"}; + + std::string Errs; + raw_string_ostream OS(Errs); + EXPECT_TRUE(cl::ParseCommandLineOptions(5, Args, StringRef(), &OS)); + EXPECT_TRUE(OS.str().empty()); + + EXPECT_TRUE(Option); + EXPECT_EQ(1, (int)Sink.size()); + EXPECT_EQ("-unknown", Sink[0]); + EXPECT_EQ("input", Input); + EXPECT_EQ(1, (int)ExtraArgs.size()); + EXPECT_EQ("-arg", ExtraArgs[0]); + + cl::ResetAllOptionOccurrences(); + EXPECT_FALSE(Option); + EXPECT_EQ(0, (int)Sink.size()); + EXPECT_EQ(0, Input.getNumOccurrences()); + EXPECT_EQ(0, (int)ExtraArgs.size()); +} + } // anonymous namespace