llvm.org GIT mirror llvm / eb2c1eb
Resubmit "Update llvm command line parser to support subcommands." This fixes an issue where occurrence counts would be unexpectedly reset when parsing different parts of a command line multiple times. **ORIGINAL COMMIT MESSAGE** This allows command line tools to use syntaxes like the following: llvm-foo.exe command1 -o1 -o2 llvm-foo.exe command2 -p1 -p2 Where command1 and command2 contain completely different sets of valid options. This is backwards compatible with previous uses of llvm cl which did not support subcommands, as any option which specifies no optional subcommand (e.g. all existing code) goes into a special "top level" subcommand that expects dashed options to appear immediately after the program name. For example, code which is subcommand unaware would generate a command line such as the following, where no subcommand is specified: llvm-foo.exe -q1 -q2 The top level subcommand can co-exist with actual subcommands, as it is implemented as an actual subcommand which is searched if no explicit subcommand is specified. So llvm-foo.exe as specified above could be written so as to support all three aforementioned command lines simultaneously. There is one additional "special" subcommand called AllSubCommands, which can be used to inject an option into every subcommand. This is useful to support things like help, so that commands such as: llvm-foo.exe --help llvm-foo.exe command1 --help llvm-foo.exe command2 --help All work and display the help for the selected subcommand without having to explicitly go and write code to handle each one separately. This patch is submitted without an example of anything actually using subcommands, but a followup patch will convert the llvm-pdbdump tool to use subcommands. Reviewed By: beanz git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@274171 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 4 years ago
4 changed file(s) with 696 addition(s) and 124 deletion(s). Raw diff Collapse all Expand all
2020 #define LLVM_SUPPORT_COMMANDLINE_H
2121
2222 #include "llvm/ADT/ArrayRef.h"
23 #include "llvm/ADT/SmallPtrSet.h"
2324 #include "llvm/ADT/SmallVector.h"
2425 #include "llvm/ADT/StringMap.h"
2526 #include "llvm/ADT/Twine.h"
2627 #include "llvm/Support/Compiler.h"
28 #include "llvm/Support/ManagedStatic.h"
2729 #include
2830 #include
2931 #include
4244 //===----------------------------------------------------------------------===//
4345 // ParseCommandLineOptions - Command line option processing entry point.
4446 //
45 void ParseCommandLineOptions(int argc, const char *const *argv,
46 const char *Overview = nullptr);
47 bool ParseCommandLineOptions(int argc, const char *const *argv,
48 const char *Overview = nullptr,
49 bool IgnoreErrors = false);
4750
4851 //===----------------------------------------------------------------------===//
4952 // ParseEnvironmentOptions - Environment variable option processing alternate
168171
169172 // The general Option Category (used as default category).
170173 extern OptionCategory GeneralCategory;
174
175 //===----------------------------------------------------------------------===//
176 // SubCommand class
177 //
178 class SubCommand {
179 private:
180 const char *const Name = nullptr;
181 const char *const Description = nullptr;
182
183 protected:
184 void registerSubCommand();
185 void unregisterSubCommand();
186
187 public:
188 SubCommand(const char *const Name, const char *const Description = nullptr)
189 : Name(Name), Description(Description) {
190 registerSubCommand();
191 }
192 SubCommand() {}
193
194 void reset();
195
196 operator bool() const;
197
198 const char *getName() const { return Name; }
199 const char *getDescription() const { return Description; }
200
201 SmallVector
202 SmallVector
203 StringMap
204
205 Option *ConsumeAfterOpt = nullptr; // The ConsumeAfter option if it exists.
206 };
207
208 // A special subcommand representing no subcommand
209 extern ManagedStatic TopLevelSubCommand;
210
211 // A special subcommand that can be used to put an option into all subcommands.
212 extern ManagedStatic AllSubCommands;
171213
172214 //===----------------------------------------------------------------------===//
173215 // Option Base class
208250 StringRef HelpStr; // The descriptive text message for -help
209251 StringRef ValueStr; // String describing what the value of this option is
210252 OptionCategory *Category; // The Category this option belongs to
253 SmallPtrSet Subs; // The subcommands this option belongs to.
211254 bool FullyInitialized; // Has addArguemnt been called?
212255
213256 inline enum NumOccurrencesFlag getNumOccurrencesFlag() const {
228271
229272 // hasArgStr - Return true if the argstr != ""
230273 bool hasArgStr() const { return !ArgStr.empty(); }
274 bool isPositional() const { return getFormattingFlag() == cl::Positional; }
275 bool isSink() const { return getMiscFlags() & cl::Sink; }
276 bool isConsumeAfter() const {
277 return getNumOccurrencesFlag() == cl::ConsumeAfter;
278 }
279 bool isInAllSubCommands() const {
280 return std::any_of(Subs.begin(), Subs.end(), [](const SubCommand *SC) {
281 return SC == &*AllSubCommands;
282 });
283 }
231284
232285 //-------------------------------------------------------------------------===
233286 // Accessor functions set by OptionModifiers
242295 void setMiscFlag(enum MiscFlags M) { Misc |= M; }
243296 void setPosition(unsigned pos) { Position = pos; }
244297 void setCategory(OptionCategory &C) { Category = &C; }
298 void addSubCommand(SubCommand &S) { Subs.insert(&S); }
245299
246300 protected:
247301 explicit Option(enum NumOccurrencesFlag OccurrencesFlag,
286340
287341 public:
288342 inline int getNumOccurrences() const { return NumOccurrences; }
343 inline void reset() { NumOccurrences = 0; }
289344 virtual ~Option() {}
290345 };
291346
346401 cat(OptionCategory &c) : Category(c) {}
347402
348403 template void apply(Opt &O) const { O.setCategory(Category); }
404 };
405
406 // sub - Specify the subcommand that this option belongs to.
407 struct sub {
408 SubCommand ⋐
409 sub(SubCommand &S) : Sub(S) {}
410
411 template void apply(Opt &O) const { O.addSubCommand(Sub); }
349412 };
350413
351414 //===----------------------------------------------------------------------===//
15881651 error("cl::alias must have argument name specified!");
15891652 if (!AliasFor)
15901653 error("cl::alias must have an cl::aliasopt(option) specified!");
1654 Subs = AliasFor->Subs;
15911655 addArgument();
15921656 }
15931657
16681732 /// Hopefully this API can be depricated soon. Any situation where options need
16691733 /// to be modified by tools or libraries should be handled by sane APIs rather
16701734 /// than just handing around a global list.
1671 StringMap
1735 StringMap
16721736
16731737 //===----------------------------------------------------------------------===//
16741738 // Standalone command line processing utilities.
17361800 /// Some tools (like clang-format) like to be able to hide all options that are
17371801 /// not specific to the tool. This function allows a tool to specify a single
17381802 /// option category to display in the -help output.
1739 void HideUnrelatedOptions(cl::OptionCategory &Category);
1803 void HideUnrelatedOptions(cl::OptionCategory &Category,
1804 SubCommand &Sub = *TopLevelSubCommand);
17401805
17411806 /// \brief Mark all options not part of the categories as cl::ReallyHidden.
17421807 ///
17451810 /// Some tools (like clang-format) like to be able to hide all options that are
17461811 /// not specific to the tool. This function allows a tool to specify a single
17471812 /// option category to display in the -help output.
1748 void HideUnrelatedOptions(ArrayRef Categories);
1813 void HideUnrelatedOptions(ArrayRef Categories,
1814 SubCommand &Sub = *TopLevelSubCommand);
1815
1816 /// \brief Reset all command line options to a state that looks as if they have
1817 /// never appeared on the command line. This is useful for being able to parse
1818 /// a command line multiple times (especially useful for writing tests).
1819 void ResetAllOptionOccurrences();
1820
1821 /// \brief Reset the command line parser back to its initial state. This
1822 /// removes
1823 /// all options, categories, and subcommands and returns the parser to a state
1824 /// where no options are supported.
1825 void ResetCommandLineParser();
17491826
17501827 } // End namespace cl
17511828
1818 #include "llvm/Support/CommandLine.h"
1919 #include "llvm-c/Support.h"
2020 #include "llvm/ADT/ArrayRef.h"
21 #include "llvm/ADT/DenseMap.h"
2122 #include "llvm/ADT/STLExtras.h"
2223 #include "llvm/ADT/SmallPtrSet.h"
2324 #include "llvm/ADT/SmallString.h"
9394 // This collects additional help to be printed.
9495 std::vector MoreHelp;
9596
96 SmallVector
97 SmallVector
98 StringMap
99
100 Option *ConsumeAfterOpt; // The ConsumeAfter option if it exists.
101
10297 // This collects the different option categories that have been registered.
10398 SmallPtrSet RegisteredOptionCategories;
10499
105 CommandLineParser() : ProgramOverview(nullptr), ConsumeAfterOpt(nullptr) {}
106
107 void ParseCommandLineOptions(int argc, const char *const *argv,
108 const char *Overview);
100 // This collects the different subcommands that have been registered.
101 SmallPtrSet RegisteredSubCommands;
102
103 CommandLineParser() : ProgramOverview(nullptr), ActiveSubCommand(nullptr) {
104 registerSubCommand(&*TopLevelSubCommand);
105 registerSubCommand(&*AllSubCommands);
106 }
107
108 void ResetAllOptionOccurrences();
109
110 bool ParseCommandLineOptions(int argc, const char *const *argv,
111 const char *Overview, bool IgnoreErrors);
112
113 void addLiteralOption(Option &Opt, SubCommand *SC, const char *Name) {
114 if (Opt.hasArgStr())
115 return;
116 if (!SC->OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
117 errs() << ProgramName << ": CommandLine Error: Option '" << Name
118 << "' registered more than once!\n";
119 report_fatal_error("inconsistency in registered CommandLine options");
120 }
121
122 // If we're adding this to all sub-commands, add it to the ones that have
123 // already been registered.
124 if (SC == &*AllSubCommands) {
125 for (const auto &Sub : RegisteredSubCommands) {
126 if (SC == Sub)
127 continue;
128 addLiteralOption(Opt, Sub, Name);
129 }
130 }
131 }
109132
110133 void addLiteralOption(Option &Opt, const char *Name) {
111 if (!Opt.hasArgStr()) {
112 if (!OptionsMap.insert(std::make_pair(Name, &Opt)).second) {
113 errs() << ProgramName << ": CommandLine Error: Option '" << Name
114 << "' registered more than once!\n";
115 report_fatal_error("inconsistency in registered CommandLine options");
116 }
117 }
118 }
119
120 void addOption(Option *O) {
134 if (Opt.Subs.empty())
135 addLiteralOption(Opt, &*TopLevelSubCommand, Name);
136 else {
137 for (auto SC : Opt.Subs)
138 addLiteralOption(Opt, SC, Name);
139 }
140 }
141
142 void addOption(Option *O, SubCommand *SC) {
121143 bool HadErrors = false;
122144 if (O->hasArgStr()) {
123145 // Add argument to the argument map!
124 if (!OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
146 if (!SC->OptionsMap.insert(std::make_pair(O->ArgStr, O)).second) {
125147 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
126148 << "' registered more than once!\n";
127149 HadErrors = true;
130152
131153 // Remember information about positional options.
132154 if (O->getFormattingFlag() == cl::Positional)
133 PositionalOpts.push_back(O);
155 SC->PositionalOpts.push_back(O);
134156 else if (O->getMiscFlags() & cl::Sink) // Remember sink options
135 SinkOpts.push_back(O);
157 SC->SinkOpts.push_back(O);
136158 else if (O->getNumOccurrencesFlag() == cl::ConsumeAfter) {
137 if (ConsumeAfterOpt) {
159 if (SC->ConsumeAfterOpt) {
138160 O->error("Cannot specify more than one option with cl::ConsumeAfter!");
139161 HadErrors = true;
140162 }
141 ConsumeAfterOpt = O;
163 SC->ConsumeAfterOpt = O;
142164 }
143165
144166 // Fail hard if there were errors. These are strictly unrecoverable and
147169 // linked LLVM distribution.
148170 if (HadErrors)
149171 report_fatal_error("inconsistency in registered CommandLine options");
150 }
151
152 void removeOption(Option *O) {
172
173 // If we're adding this to all sub-commands, add it to the ones that have
174 // already been registered.
175 if (SC == &*AllSubCommands) {
176 for (const auto &Sub : RegisteredSubCommands) {
177 if (SC == Sub)
178 continue;
179 addOption(O, Sub);
180 }
181 }
182 }
183
184 void addOption(Option *O) {
185 if (O->Subs.empty()) {
186 addOption(O, &*TopLevelSubCommand);
187 } else {
188 for (auto SC : O->Subs)
189 addOption(O, SC);
190 }
191 }
192
193 void removeOption(Option *O, SubCommand *SC) {
153194 SmallVector OptionNames;
154195 O->getExtraOptionNames(OptionNames);
155196 if (O->hasArgStr())
156197 OptionNames.push_back(O->ArgStr);
198
199 SubCommand &Sub = *SC;
157200 for (auto Name : OptionNames)
158 OptionsMap.erase(Name);
201 Sub.OptionsMap.erase(Name);
159202
160203 if (O->getFormattingFlag() == cl::Positional)
161 for (auto Opt = PositionalOpts.begin(); Opt != PositionalOpts.end();
162 ++Opt) {
204 for (auto Opt = Sub.PositionalOpts.begin();
205 Opt != Sub.PositionalOpts.end(); ++Opt) {
163206 if (*Opt == O) {
164 PositionalOpts.erase(Opt);
207 Sub.PositionalOpts.erase(Opt);
165208 break;
166209 }
167210 }
168211 else if (O->getMiscFlags() & cl::Sink)
169 for (auto Opt = SinkOpts.begin(); Opt != SinkOpts.end(); ++Opt) {
212 for (auto Opt = Sub.SinkOpts.begin(); Opt != Sub.SinkOpts.end(); ++Opt) {
170213 if (*Opt == O) {
171 SinkOpts.erase(Opt);
214 Sub.SinkOpts.erase(Opt);
172215 break;
173216 }
174217 }
175 else if (O == ConsumeAfterOpt)
176 ConsumeAfterOpt = nullptr;
177 }
178
179 bool hasOptions() {
180 return (!OptionsMap.empty() || !PositionalOpts.empty() ||
181 nullptr != ConsumeAfterOpt);
182 }
183
184 void updateArgStr(Option *O, StringRef NewName) {
185 if (!OptionsMap.insert(std::make_pair(NewName, O)).second) {
218 else if (O == Sub.ConsumeAfterOpt)
219 Sub.ConsumeAfterOpt = nullptr;
220 }
221
222 void removeOption(Option *O) {
223 if (O->Subs.empty())
224 removeOption(O, &*TopLevelSubCommand);
225 else {
226 if (O->isInAllSubCommands()) {
227 for (auto SC : RegisteredSubCommands)
228 removeOption(O, SC);
229 } else {
230 for (auto SC : O->Subs)
231 removeOption(O, SC);
232 }
233 }
234 }
235
236 bool hasOptions(const SubCommand &Sub) const {
237 return (!Sub.OptionsMap.empty() || !Sub.PositionalOpts.empty() ||
238 nullptr != Sub.ConsumeAfterOpt);
239 }
240
241 bool hasOptions() const {
242 for (const auto &S : RegisteredSubCommands) {
243 if (hasOptions(*S))
244 return true;
245 }
246 return false;
247 }
248
249 SubCommand *getActiveSubCommand() { return ActiveSubCommand; }
250
251 void updateArgStr(Option *O, StringRef NewName, SubCommand *SC) {
252 SubCommand &Sub = *SC;
253 if (!Sub.OptionsMap.insert(std::make_pair(NewName, O)).second) {
186254 errs() << ProgramName << ": CommandLine Error: Option '" << O->ArgStr
187255 << "' registered more than once!\n";
188256 report_fatal_error("inconsistency in registered CommandLine options");
189257 }
190 OptionsMap.erase(O->ArgStr);
258 Sub.OptionsMap.erase(O->ArgStr);
259 }
260
261 void updateArgStr(Option *O, StringRef NewName) {
262 if (O->Subs.empty())
263 updateArgStr(O, NewName, &*TopLevelSubCommand);
264 else {
265 for (auto SC : O->Subs)
266 updateArgStr(O, NewName, SC);
267 }
191268 }
192269
193270 void printOptionValues();
202279 RegisteredOptionCategories.insert(cat);
203280 }
204281
282 void registerSubCommand(SubCommand *sub) {
283 assert(count_if(RegisteredSubCommands,
284 [sub](const SubCommand *Sub) {
285 return (sub->getName() != nullptr) &&
286 (Sub->getName() == sub->getName());
287 }) == 0 &&
288 "Duplicate subcommands");
289 RegisteredSubCommands.insert(sub);
290
291 // For all options that have been registered for all subcommands, add the
292 // option to this subcommand now.
293 if (sub != &*AllSubCommands) {
294 for (auto &E : AllSubCommands->OptionsMap) {
295 Option *O = E.second;
296 if ((O->isPositional() || O->isSink() || O->isConsumeAfter()) ||
297 O->hasArgStr())
298 addOption(O, sub);
299 else
300 addLiteralOption(*O, sub, E.first().str().c_str());
301 }
302 }
303 }
304
305 void unregisterSubCommand(SubCommand *sub) {
306 RegisteredSubCommands.erase(sub);
307 }
308
309 void reset() {
310 ActiveSubCommand = nullptr;
311 ProgramName.clear();
312 ProgramOverview = nullptr;
313
314 MoreHelp.clear();
315 RegisteredOptionCategories.clear();
316
317 ResetAllOptionOccurrences();
318 RegisteredSubCommands.clear();
319
320 TopLevelSubCommand->reset();
321 AllSubCommands->reset();
322 registerSubCommand(&*TopLevelSubCommand);
323 registerSubCommand(&*AllSubCommands);
324 }
325
205326 private:
206 Option *LookupOption(StringRef &Arg, StringRef &Value);
327 SubCommand *ActiveSubCommand;
328
329 Option *LookupOption(SubCommand &Sub, StringRef &Arg, StringRef &Value);
330 SubCommand *LookupSubCommand(const char *Name);
207331 };
208332
209333 } // namespace
238362 GlobalParser->registerCategory(this);
239363 }
240364
365 // A special subcommand representing no subcommand
366 ManagedStatic llvm::cl::TopLevelSubCommand;
367
368 // A special subcommand that can be used to put an option into all subcommands.
369 ManagedStatic llvm::cl::AllSubCommands;
370
371 void SubCommand::registerSubCommand() {
372 GlobalParser->registerSubCommand(this);
373 }
374
375 void SubCommand::unregisterSubCommand() {
376 GlobalParser->unregisterSubCommand(this);
377 }
378
379 void SubCommand::reset() {
380 PositionalOpts.clear();
381 SinkOpts.clear();
382 OptionsMap.clear();
383
384 ConsumeAfterOpt = nullptr;
385 }
386
387 SubCommand::operator bool() const {
388 return (GlobalParser->getActiveSubCommand() == this);
389 }
390
241391 //===----------------------------------------------------------------------===//
242392 // Basic, shared command line option processing machinery.
243393 //
245395 /// LookupOption - Lookup the option specified by the specified option on the
246396 /// command line. If there is a value specified (after an equal sign) return
247397 /// that as well. This assumes that leading dashes have already been stripped.
248 Option *CommandLineParser::LookupOption(StringRef &Arg, StringRef &Value) {
398 Option *CommandLineParser::LookupOption(SubCommand &Sub, StringRef &Arg,
399 StringRef &Value) {
249400 // Reject all dashes.
250401 if (Arg.empty())
251402 return nullptr;
403 assert(&Sub != &*AllSubCommands);
252404
253405 size_t EqualPos = Arg.find('=');
254406
255407 // If we have an equals sign, remember the value.
256408 if (EqualPos == StringRef::npos) {
257409 // Look up the option.
258 StringMap
259 return I != OptionsMap.end() ? I->second : nullptr;
410 auto I = Sub.OptionsMap.find(Arg);
411 if (I == Sub.OptionsMap.end())
412 return nullptr;
413
414 return I != Sub.OptionsMap.end() ? I->second : nullptr;
260415 }
261416
262417 // If the argument before the = is a valid option name, we match. If not,
263418 // return Arg unmolested.
264 StringMap
265 OptionsMap.find(Arg.substr(0, EqualPos));
266 if (I == OptionsMap.end())
419 auto I = Sub.OptionsMap.find(Arg.substr(0, EqualPos));
420 if (I == Sub.OptionsMap.end())
267421 return nullptr;
268422
269423 Value = Arg.substr(EqualPos + 1);
270424 Arg = Arg.substr(0, EqualPos);
271425 return I->second;
426 }
427
428 SubCommand *CommandLineParser::LookupSubCommand(const char *Name) {
429 if (Name == nullptr)
430 return &*TopLevelSubCommand;
431 for (auto S : RegisteredSubCommands) {
432 if (S == &*AllSubCommands)
433 continue;
434 if (S->getName() == nullptr)
435 continue;
436
437 if (StringRef(S->getName()) == StringRef(Name))
438 return S;
439 }
440 return &*TopLevelSubCommand;
272441 }
273442
274443 /// LookupNearestOption - Lookup the closest match to the option specified by
819988 ParseCommandLineOptions(newArgc, &newArgv[0], Overview);
820989 }
821990
822 void cl::ParseCommandLineOptions(int argc, const char *const *argv,
823 const char *Overview) {
824 GlobalParser->ParseCommandLineOptions(argc, argv, Overview);
825 }
826
827 void CommandLineParser::ParseCommandLineOptions(int argc,
991 bool cl::ParseCommandLineOptions(int argc, const char *const *argv,
992 const char *Overview, bool IgnoreErrors) {
993 return GlobalParser->ParseCommandLineOptions(argc, argv, Overview,
994 IgnoreErrors);
995 }
996
997 void CommandLineParser::ResetAllOptionOccurrences() {
998 // So that we can parse different command lines multiple times in succession
999 // we reset all option values to look like they have never been seen before.
1000 for (auto SC : RegisteredSubCommands) {
1001 for (auto &O : SC->OptionsMap)
1002 O.second->reset();
1003 }
1004 }
1005
1006 bool CommandLineParser::ParseCommandLineOptions(int argc,
8281007 const char *const *argv,
829 const char *Overview) {
1008 const char *Overview,
1009 bool IgnoreErrors) {
8301010 assert(hasOptions() && "No options specified!");
8311011
8321012 // Expand response files.
8481028
8491029 // Determine whether or not there are an unlimited number of positionals
8501030 bool HasUnlimitedPositionals = false;
1031
1032 int FirstArg = 1;
1033 SubCommand *ChosenSubCommand = &*TopLevelSubCommand;
1034 if (argc >= 2 && argv[FirstArg][0] != '-') {
1035 // If the first argument specifies a valid subcommand, start processing
1036 // options from the second argument.
1037 ChosenSubCommand = LookupSubCommand(argv[FirstArg]);
1038 if (ChosenSubCommand != &*TopLevelSubCommand)
1039 FirstArg = 2;
1040 }
1041 GlobalParser->ActiveSubCommand = ChosenSubCommand;
1042
1043 assert(ChosenSubCommand);
1044 auto &ConsumeAfterOpt = ChosenSubCommand->ConsumeAfterOpt;
1045 auto &PositionalOpts = ChosenSubCommand->PositionalOpts;
1046 auto &SinkOpts = ChosenSubCommand->SinkOpts;
1047 auto &OptionsMap = ChosenSubCommand->OptionsMap;
8511048
8521049 if (ConsumeAfterOpt) {
8531050 assert(PositionalOpts.size() > 0 &&
8641061 else if (ConsumeAfterOpt) {
8651062 // ConsumeAfter cannot be combined with "optional" positional options
8661063 // unless there is only one positional argument...
867 if (PositionalOpts.size() > 1)
868 ErrorParsing |= Opt->error(
869 "error - this positional option will never be matched, "
870 "because it does not Require a value, and a "
871 "cl::ConsumeAfter option is active!");
1064 if (PositionalOpts.size() > 1) {
1065 if (!IgnoreErrors)
1066 Opt->error("error - this positional option will never be matched, "
1067 "because it does not Require a value, and a "
1068 "cl::ConsumeAfter option is active!");
1069 ErrorParsing = true;
1070 }
8721071 } else if (UnboundedFound && !Opt->hasArgStr()) {
8731072 // This option does not "require" a value... Make sure this option is
8741073 // not specified after an option that eats all extra arguments, or this
8751074 // one will never get any!
8761075 //
877 ErrorParsing |= Opt->error("error - option can never match, because "
878 "another positional argument will match an "
879 "unbounded number of values, and this option"
880 " does not require a value!");
881 errs() << ProgramName << ": CommandLine Error: Option '" << Opt->ArgStr
882 << "' is all messed up!\n";
883 errs() << PositionalOpts.size();
1076 if (!IgnoreErrors) {
1077 Opt->error("error - option can never match, because "
1078 "another positional argument will match an "
1079 "unbounded number of values, and this option"
1080 " does not require a value!");
1081 errs() << ProgramName << ": CommandLine Error: Option '"
1082 << Opt->ArgStr << "' is all messed up!\n";
1083 errs() << PositionalOpts.size();
1084 }
1085 ErrorParsing = true;
8841086 }
8851087 UnboundedFound |= EatsUnboundedNumberOfValues(Opt);
8861088 }
8991101
9001102 // Loop over all of the arguments... processing them.
9011103 bool DashDashFound = false; // Have we read '--'?
902 for (int i = 1; i < argc; ++i) {
1104 for (int i = FirstArg; i < argc; ++i) {
9031105 Option *Handler = nullptr;
9041106 Option *NearestHandler = nullptr;
9051107 std::string NearestHandlerString;
9461148 while (!ArgName.empty() && ArgName[0] == '-')
9471149 ArgName = ArgName.substr(1);
9481150
949 Handler = LookupOption(ArgName, Value);
1151 Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
9501152 if (!Handler || Handler->getFormattingFlag() != cl::Positional) {
9511153 ProvidePositionalOption(ActivePositionalArg, argv[i], i);
9521154 continue; // We are done!
9581160 while (!ArgName.empty() && ArgName[0] == '-')
9591161 ArgName = ArgName.substr(1);
9601162
961 Handler = LookupOption(ArgName, Value);
1163 Handler = LookupOption(*ChosenSubCommand, ArgName, Value);
9621164
9631165 // Check to see if this "option" is really a prefixed or grouped argument.
9641166 if (!Handler)
9741176
9751177 if (!Handler) {
9761178 if (SinkOpts.empty()) {
977 errs() << ProgramName << ": Unknown command line argument '" << argv[i]
978 << "'. Try: '" << argv[0] << " -help'\n";
979
980 if (NearestHandler) {
981 // If we know a near match, report it as well.
982 errs() << ProgramName << ": Did you mean '-" << NearestHandlerString
983 << "'?\n";
1179 if (!IgnoreErrors) {
1180 errs() << ProgramName << ": Unknown command line argument '"
1181 << argv[i] << "'. Try: '" << argv[0] << " -help'\n";
1182
1183 if (NearestHandler) {
1184 // If we know a near match, report it as well.
1185 errs() << ProgramName << ": Did you mean '-" << NearestHandlerString
1186 << "'?\n";
1187 }
9841188 }
9851189
9861190 ErrorParsing = true;
10031207
10041208 // Check and handle positional arguments now...
10051209 if (NumPositionalRequired > PositionalVals.size()) {
1006 errs() << ProgramName
1007 << ": Not enough positional command line arguments specified!\n"
1008 << "Must specify at least " << NumPositionalRequired
1009 << " positional arguments: See: " << argv[0] << " -help\n";
1210 if (!IgnoreErrors) {
1211 errs() << ProgramName
1212 << ": Not enough positional command line arguments specified!\n"
1213 << "Must specify at least " << NumPositionalRequired
1214 << " positional arguments: See: " << argv[0] << " -help\n";
1215 }
10101216
10111217 ErrorParsing = true;
10121218 } else if (!HasUnlimitedPositionals &&
10131219 PositionalVals.size() > PositionalOpts.size()) {
1014 errs() << ProgramName << ": Too many positional arguments specified!\n"
1015 << "Can specify at most " << PositionalOpts.size()
1016 << " positional arguments: See: " << argv[0] << " -help\n";
1220 if (!IgnoreErrors) {
1221 errs() << ProgramName << ": Too many positional arguments specified!\n"
1222 << "Can specify at most " << PositionalOpts.size()
1223 << " positional arguments: See: " << argv[0] << " -help\n";
1224 }
10171225 ErrorParsing = true;
10181226
10191227 } else if (!ConsumeAfterOpt) {
11081316 MoreHelp.clear();
11091317
11101318 // If we had an error processing our arguments, don't let the program execute
1111 if (ErrorParsing)
1112 exit(1);
1319 if (ErrorParsing) {
1320 if (!IgnoreErrors)
1321 exit(1);
1322 return false;
1323 }
1324 return true;
11131325 }
11141326
11151327 //===----------------------------------------------------------------------===//
14591671 return strcmp(LHS->first, RHS->first);
14601672 }
14611673
1674 static int SubNameCompare(const std::pair *LHS,
1675 const std::pair *RHS) {
1676 return strcmp(LHS->first, RHS->first);
1677 }
1678
14621679 // Copy Options into a vector so we can sort them as we like.
14631680 static void sortOpts(StringMap
14641681 SmallVectorImpl> &Opts,
14871704 array_pod_sort(Opts.begin(), Opts.end(), OptNameCompare);
14881705 }
14891706
1707 static void
1708 sortSubCommands(const SmallPtrSetImpl &SubMap,
1709 SmallVectorImpl> &Subs) {
1710 for (const auto &S : SubMap) {
1711 if (S->getName() == nullptr)
1712 continue;
1713 Subs.push_back(std::make_pair(S->getName(), S));
1714 }
1715 array_pod_sort(Subs.begin(), Subs.end(), SubNameCompare);
1716 }
1717
14901718 namespace {
14911719
14921720 class HelpPrinter {
14941722 const bool ShowHidden;
14951723 typedef SmallVector, 128>
14961724 StrOptionPairVector;
1725 typedef SmallVector, 128>
1726 StrSubCommandPairVector;
14971727 // Print the options. Opts is assumed to be alphabetically sorted.
14981728 virtual void printOptions(StrOptionPairVector &Opts, size_t MaxArgLen) {
14991729 for (size_t i = 0, e = Opts.size(); i != e; ++i)
15001730 Opts[i].second->printOptionInfo(MaxArgLen);
15011731 }
15021732
1733 void printSubCommands(StrSubCommandPairVector &Subs, size_t MaxSubLen) {
1734 for (const auto &S : Subs) {
1735 outs() << " " << S.first;
1736 if (S.second->getDescription()) {
1737 outs().indent(MaxSubLen - strlen(S.first));
1738 outs() << " - " << S.second->getDescription();
1739 }
1740 outs() << "\n";
1741 }
1742 }
1743
15031744 public:
15041745 explicit HelpPrinter(bool showHidden) : ShowHidden(showHidden) {}
15051746 virtual ~HelpPrinter() {}
15091750 if (!Value)
15101751 return;
15111752
1753 SubCommand *Sub = GlobalParser->getActiveSubCommand();
1754 auto &OptionsMap = Sub->OptionsMap;
1755 auto &PositionalOpts = Sub->PositionalOpts;
1756 auto &ConsumeAfterOpt = Sub->ConsumeAfterOpt;
1757
15121758 StrOptionPairVector Opts;
1513 sortOpts(GlobalParser->OptionsMap, Opts, ShowHidden);
1759 sortOpts(OptionsMap, Opts, ShowHidden);
1760
1761 StrSubCommandPairVector Subs;
1762 sortSubCommands(GlobalParser->RegisteredSubCommands, Subs);
15141763
15151764 if (GlobalParser->ProgramOverview)
15161765 outs() << "OVERVIEW: " << GlobalParser->ProgramOverview << "\n";
15171766
1518 outs() << "USAGE: " << GlobalParser->ProgramName << " [options]";
1519
1520 for (auto Opt : GlobalParser->PositionalOpts) {
1767 if (Sub == &*TopLevelSubCommand)
1768 outs() << "USAGE: " << GlobalParser->ProgramName
1769 << " [subcommand] [options]";
1770 else {
1771 if (Sub->getDescription() != nullptr) {
1772 outs() << "SUBCOMMAND '" << Sub->getName()
1773 << "': " << Sub->getDescription() << "\n\n";
1774 }
1775 outs() << "USAGE: " << GlobalParser->ProgramName << " " << Sub->getName()
1776 << " [options]";
1777 }
1778
1779 for (auto Opt : PositionalOpts) {
15211780 if (Opt->hasArgStr())
15221781 outs() << " --" << Opt->ArgStr;
15231782 outs() << " " << Opt->HelpStr;
15241783 }
15251784
15261785 // Print the consume after option info if it exists...
1527 if (GlobalParser->ConsumeAfterOpt)
1528 outs() << " " << GlobalParser->ConsumeAfterOpt->HelpStr;
1786 if (ConsumeAfterOpt)
1787 outs() << " " << ConsumeAfterOpt->HelpStr;
1788
1789 if (Sub == &*TopLevelSubCommand && Subs.size() > 2) {
1790 // Compute the maximum subcommand length...
1791 size_t MaxSubLen = 0;
1792 for (size_t i = 0, e = Subs.size(); i != e; ++i)
1793 MaxSubLen = std::max(MaxSubLen, strlen(Subs[i].first));
1794
1795 outs() << "\n\n";
1796 outs() << "SUBCOMMANDS:\n\n";
1797 printSubCommands(Subs, MaxSubLen);
1798 outs() << "\n";
1799 outs() << " Type \"" << GlobalParser->ProgramName
1800 << " -help\" to get more help on a specific "
1801 "subcommand";
1802 }
15291803
15301804 outs() << "\n\n";
15311805
16741948 "help-list",
16751949 cl::desc("Display list of available options (-help-list-hidden for more)"),
16761950 cl::location(UncategorizedNormalPrinter), cl::Hidden, cl::ValueDisallowed,
1677 cl::cat(GenericCategory));
1951 cl::cat(GenericCategory), cl::sub(*AllSubCommands));
16781952
16791953 static cl::opt>
16801954 HLHOp("help-list-hidden", cl::desc("Display list of all available options"),
16811955 cl::location(UncategorizedHiddenPrinter), cl::Hidden,
1682 cl::ValueDisallowed, cl::cat(GenericCategory));
1956 cl::ValueDisallowed, cl::cat(GenericCategory),
1957 cl::sub(*AllSubCommands));
16831958
16841959 // Define uncategorized/categorized help printers. These printers change their
16851960 // behaviour at runtime depending on whether one or more Option categories have
16871962 static cl::opt>
16881963 HOp("help", cl::desc("Display available options (-help-hidden for more)"),
16891964 cl::location(WrappedNormalPrinter), cl::ValueDisallowed,
1690 cl::cat(GenericCategory));
1965 cl::cat(GenericCategory), cl::sub(*AllSubCommands));
16911966
16921967 static cl::opt>
16931968 HHOp("help-hidden", cl::desc("Display all available options"),
16941969 cl::location(WrappedHiddenPrinter), cl::Hidden, cl::ValueDisallowed,
1695 cl::cat(GenericCategory));
1970 cl::cat(GenericCategory), cl::sub(*AllSubCommands));
16961971
16971972 static cl::opt PrintOptions(
16981973 "print-options",
16991974 cl::desc("Print non-default options after command line parsing"),
1700 cl::Hidden, cl::init(false), cl::cat(GenericCategory));
1975 cl::Hidden, cl::init(false), cl::cat(GenericCategory),
1976 cl::sub(*AllSubCommands));
17011977
17021978 static cl::opt PrintAllOptions(
17031979 "print-all-options",
17041980 cl::desc("Print all option values after command line parsing"), cl::Hidden,
1705 cl::init(false), cl::cat(GenericCategory));
1981 cl::init(false), cl::cat(GenericCategory), cl::sub(*AllSubCommands));
17061982
17071983 void HelpPrinterWrapper::operator=(bool Value) {
17081984 if (!Value)
17292005 return;
17302006
17312007 SmallVector, 128> Opts;
1732 sortOpts(OptionsMap, Opts, /*ShowHidden*/ true);
2008 sortOpts(ActiveSubCommand->OptionsMap, Opts, /*ShowHidden*/ true);
17332009
17342010 // Compute the maximum argument length...
17352011 size_t MaxArgLen = 0;
18382114 ExtraVersionPrinters->push_back(func);
18392115 }
18402116
1841 StringMap
1842 return GlobalParser->OptionsMap;
1843 }
1844
1845 void cl::HideUnrelatedOptions(cl::OptionCategory &Category) {
1846 for (auto &I : GlobalParser->OptionsMap) {
2117 StringMap) {
2118 auto &Subs = GlobalParser->RegisteredSubCommands;
2119 (void)Subs;
2120 assert(std::find(Subs.begin(), Subs.end(), &Sub) != Subs.end());
2121 return Sub.OptionsMap;
2122 }
2123
2124 void cl::HideUnrelatedOptions(cl::OptionCategory &Category, SubCommand &Sub) {
2125 for (auto &I : Sub.OptionsMap) {
18472126 if (I.second->Category != &Category &&
18482127 I.second->Category != &GenericCategory)
18492128 I.second->setHiddenFlag(cl::ReallyHidden);
18502129 }
18512130 }
18522131
1853 void cl::HideUnrelatedOptions(ArrayRef Categories) {
2132 void cl::HideUnrelatedOptions(ArrayRef Categories,
2133 SubCommand &Sub) {
18542134 auto CategoriesBegin = Categories.begin();
18552135 auto CategoriesEnd = Categories.end();
1856 for (auto &I : GlobalParser->OptionsMap) {
2136 for (auto &I : Sub.OptionsMap) {
18572137 if (std::find(CategoriesBegin, CategoriesEnd, I.second->Category) ==
18582138 CategoriesEnd &&
18592139 I.second->Category != &GenericCategory)
18612141 }
18622142 }
18632143
2144 void cl::ResetCommandLineParser() { GlobalParser->reset(); }
2145 void cl::ResetAllOptionOccurrences() {
2146 GlobalParser->ResetAllOptionOccurrences();
2147 }
2148
18642149 void LLVMParseCommandLineOptions(int argc, const char *const *argv,
18652150 const char *Overview) {
1866 llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
1867 }
2151 llvm::cl::ParseCommandLineOptions(argc, argv, Overview, true);
2152 }
6666 : Base(M0, M1, M2, M3) {}
6767
6868 ~StackOption() override { this->removeArgument(); }
69
70 template StackOption &operator=(const DT &V) {
71 this->setValue(V);
72 return *this;
73 }
74 };
75
76 class StackSubCommand : public cl::SubCommand {
77 public:
78 StackSubCommand(const char *const Name,
79 const char *const Description = nullptr)
80 : SubCommand(Name, Description) {}
81
82 StackSubCommand() : SubCommand() {}
83
84 ~StackSubCommand() { unregisterSubCommand(); }
6985 };
7086
7187
7793 const char ArgString[] = "new-test-option";
7894 const char ValueString[] = "Integer";
7995
80 StringMap &Map = cl::getRegisteredOptions();
96 StringMap &Map =
97 cl::getRegisteredOptions(*cl::TopLevelSubCommand);
8198
8299 ASSERT_TRUE(Map.count("test-option") == 1) <<
83100 "Could not find option in map.";
236253 ASSERT_EQ(cl::NotHidden, TestOption2.getOptionHiddenFlag())
237254 << "Hid extra option that should be visable.";
238255
239 StringMap &Map = cl::getRegisteredOptions();
256 StringMap &Map =
257 cl::getRegisteredOptions(*cl::TopLevelSubCommand);
240258 ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
241259 << "Hid default option that should be visable.";
242260 }
260278 ASSERT_EQ(cl::NotHidden, TestOption3.getOptionHiddenFlag())
261279 << "Hid extra option that should be visable.";
262280
263 StringMap &Map = cl::getRegisteredOptions();
281 StringMap &Map =
282 cl::getRegisteredOptions(*cl::TopLevelSubCommand);
264283 ASSERT_EQ(cl::NotHidden, Map["help"]->getOptionHiddenFlag())
265284 << "Hid default option that should be visable.";
266285 }
267286
287 TEST(CommandLineTest, SetValueInSubcategories) {
288 cl::ResetCommandLineParser();
289
290 StackSubCommand SC1("sc1", "First subcommand");
291 StackSubCommand SC2("sc2", "Second subcommand");
292
293 StackOption TopLevelOpt("top-level", cl::init(false));
294 StackOption SC1Opt("sc1", cl::sub(SC1), cl::init(false));
295 StackOption SC2Opt("sc2", cl::sub(SC2), cl::init(false));
296
297 EXPECT_FALSE(TopLevelOpt);
298 EXPECT_FALSE(SC1Opt);
299 EXPECT_FALSE(SC2Opt);
300 const char *args[] = {"prog", "-top-level"};
301 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
302 EXPECT_TRUE(TopLevelOpt);
303 EXPECT_FALSE(SC1Opt);
304 EXPECT_FALSE(SC2Opt);
305
306 TopLevelOpt = false;
307
308 cl::ResetAllOptionOccurrences();
309 EXPECT_FALSE(TopLevelOpt);
310 EXPECT_FALSE(SC1Opt);
311 EXPECT_FALSE(SC2Opt);
312 const char *args2[] = {"prog", "sc1", "-sc1"};
313 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
314 EXPECT_FALSE(TopLevelOpt);
315 EXPECT_TRUE(SC1Opt);
316 EXPECT_FALSE(SC2Opt);
317
318 SC1Opt = false;
319
320 cl::ResetAllOptionOccurrences();
321 EXPECT_FALSE(TopLevelOpt);
322 EXPECT_FALSE(SC1Opt);
323 EXPECT_FALSE(SC2Opt);
324 const char *args3[] = {"prog", "sc2", "-sc2"};
325 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true));
326 EXPECT_FALSE(TopLevelOpt);
327 EXPECT_FALSE(SC1Opt);
328 EXPECT_TRUE(SC2Opt);
329 }
330
331 TEST(CommandLineTest, LookupFailsInWrongSubCommand) {
332 cl::ResetCommandLineParser();
333
334 StackSubCommand SC1("sc1", "First subcommand");
335 StackSubCommand SC2("sc2", "Second subcommand");
336
337 StackOption SC1Opt("sc1", cl::sub(SC1), cl::init(false));
338 StackOption SC2Opt("sc2", cl::sub(SC2), cl::init(false));
339
340 const char *args[] = {"prog", "sc1", "-sc2"};
341 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, nullptr, true));
342 }
343
344 TEST(CommandLineTest, AddToAllSubCommands) {
345 cl::ResetCommandLineParser();
346
347 StackSubCommand SC1("sc1", "First subcommand");
348 StackOption AllOpt("everywhere", cl::sub(*cl::AllSubCommands),
349 cl::init(false));
350 StackSubCommand SC2("sc2", "Second subcommand");
351
352 const char *args[] = {"prog", "-everywhere"};
353 const char *args2[] = {"prog", "sc1", "-everywhere"};
354 const char *args3[] = {"prog", "sc2", "-everywhere"};
355
356 EXPECT_FALSE(AllOpt);
357 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
358 EXPECT_TRUE(AllOpt);
359
360 AllOpt = false;
361
362 cl::ResetAllOptionOccurrences();
363 EXPECT_FALSE(AllOpt);
364 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
365 EXPECT_TRUE(AllOpt);
366
367 AllOpt = false;
368
369 cl::ResetAllOptionOccurrences();
370 EXPECT_FALSE(AllOpt);
371 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args3, nullptr, true));
372 EXPECT_TRUE(AllOpt);
373 }
374
375 TEST(CommandLineTest, ReparseCommandLineOptions) {
376 cl::ResetCommandLineParser();
377
378 StackOption TopLevelOpt("top-level", cl::sub(*cl::TopLevelSubCommand),
379 cl::init(false));
380
381 const char *args[] = {"prog", "-top-level"};
382
383 EXPECT_FALSE(TopLevelOpt);
384 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
385 EXPECT_TRUE(TopLevelOpt);
386
387 TopLevelOpt = false;
388
389 cl::ResetAllOptionOccurrences();
390 EXPECT_FALSE(TopLevelOpt);
391 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
392 EXPECT_TRUE(TopLevelOpt);
393 }
394
395 TEST(CommandLineTest, RemoveFromRegularSubCommand) {
396 cl::ResetCommandLineParser();
397
398 StackSubCommand SC("sc", "Subcommand");
399 StackOption RemoveOption("remove-option", cl::sub(SC), cl::init(false));
400 StackOption KeepOption("keep-option", cl::sub(SC), cl::init(false));
401
402 const char *args[] = {"prog", "sc", "-remove-option"};
403
404 EXPECT_FALSE(RemoveOption);
405 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args, nullptr, true));
406 EXPECT_TRUE(RemoveOption);
407
408 RemoveOption.removeArgument();
409
410 cl::ResetAllOptionOccurrences();
411 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args, nullptr, true));
412 }
413
414 TEST(CommandLineTest, RemoveFromTopLevelSubCommand) {
415 cl::ResetCommandLineParser();
416
417 StackOption TopLevelRemove(
418 "top-level-remove", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
419 StackOption TopLevelKeep(
420 "top-level-keep", cl::sub(*cl::TopLevelSubCommand), cl::init(false));
421
422 const char *args[] = {"prog", "-top-level-remove"};
423
424 EXPECT_FALSE(TopLevelRemove);
425 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args, nullptr, true));
426 EXPECT_TRUE(TopLevelRemove);
427
428 TopLevelRemove.removeArgument();
429
430 cl::ResetAllOptionOccurrences();
431 EXPECT_FALSE(cl::ParseCommandLineOptions(2, args, nullptr, true));
432 }
433
434 TEST(CommandLineTest, RemoveFromAllSubCommands) {
435 cl::ResetCommandLineParser();
436
437 StackSubCommand SC1("sc1", "First Subcommand");
438 StackSubCommand SC2("sc2", "Second Subcommand");
439 StackOption RemoveOption("remove-option", cl::sub(*cl::AllSubCommands),
440 cl::init(false));
441 StackOption KeepOption("keep-option", cl::sub(*cl::AllSubCommands),
442 cl::init(false));
443
444 const char *args0[] = {"prog", "-remove-option"};
445 const char *args1[] = {"prog", "sc1", "-remove-option"};
446 const char *args2[] = {"prog", "sc2", "-remove-option"};
447
448 // It should work for all subcommands including the top-level.
449 EXPECT_FALSE(RemoveOption);
450 EXPECT_TRUE(cl::ParseCommandLineOptions(2, args0, nullptr, true));
451 EXPECT_TRUE(RemoveOption);
452
453 RemoveOption = false;
454
455 cl::ResetAllOptionOccurrences();
456 EXPECT_FALSE(RemoveOption);
457 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args1, nullptr, true));
458 EXPECT_TRUE(RemoveOption);
459
460 RemoveOption = false;
461
462 cl::ResetAllOptionOccurrences();
463 EXPECT_FALSE(RemoveOption);
464 EXPECT_TRUE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
465 EXPECT_TRUE(RemoveOption);
466
467 RemoveOption.removeArgument();
468
469 // It should not work for any subcommands including the top-level.
470 cl::ResetAllOptionOccurrences();
471 EXPECT_FALSE(cl::ParseCommandLineOptions(2, args0, nullptr, true));
472 cl::ResetAllOptionOccurrences();
473 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args1, nullptr, true));
474 cl::ResetAllOptionOccurrences();
475 EXPECT_FALSE(cl::ParseCommandLineOptions(3, args2, nullptr, true));
476 }
477
268478 } // anonymous namespace
230230 // LoopCount should only be incremented once.
231231 while (true) {
232232 ++LoopCount;
233 ProcessInfo WaitResult = Wait(PI1, 0, true, &Error);
233 ProcessInfo WaitResult = llvm::sys::Wait(PI1, 0, true, &Error);
234234 ASSERT_TRUE(Error.empty());
235235 if (WaitResult.Pid == PI1.Pid)
236236 break;
247247 // cse, LoopCount should be greater than 1 (more than one increment occurs).
248248 while (true) {
249249 ++LoopCount;
250 ProcessInfo WaitResult = Wait(PI2, 0, false, &Error);
250 ProcessInfo WaitResult = llvm::sys::Wait(PI2, 0, false, &Error);
251251 ASSERT_TRUE(Error.empty());
252252 if (WaitResult.Pid == PI2.Pid)
253253 break;