Index: llvm/lib/Support/CommandLine.cpp =================================================================== --- llvm/lib/Support/CommandLine.cpp +++ llvm/lib/Support/CommandLine.cpp @@ -129,6 +129,19 @@ return OS; } +// Use for inline printing (omit leading spaces) +class PrintArgInline { + StringRef ArgName; +public: + PrintArgInline(StringRef ArgName) : ArgName(ArgName) {} + friend raw_ostream &operator<<(raw_ostream &OS, const PrintArgInline &); +}; + +raw_ostream &operator<<(raw_ostream &OS, const PrintArgInline &Arg) { + OS << argPrefix(Arg.ArgName).ltrim() << Arg.ArgName; + return OS; +} + class CommandLineParser { public: // Globals for name and overview of program. Program name is not a string to @@ -1447,7 +1460,7 @@ if (NearestHandler) { // If we know a near match, report it as well. *Errs << ProgramName << ": Did you mean '" - << PrintArg(NearestHandlerString) << "'?\n"; + << PrintArgInline(NearestHandlerString) << "'?\n"; } ErrorParsing = true; @@ -1601,7 +1614,7 @@ if (ArgName.empty()) Errs << HelpStr; // Be nice for positional arguments else - Errs << GlobalParser->ProgramName << ": for the " << PrintArg(ArgName); + Errs << GlobalParser->ProgramName << ": for the " << PrintArgInline(ArgName); Errs << " option: " << Message << "\n"; return true; Index: llvm/unittests/Support/CommandLineTest.cpp =================================================================== --- llvm/unittests/Support/CommandLineTest.cpp +++ llvm/unittests/Support/CommandLineTest.cpp @@ -1653,4 +1653,32 @@ EXPECT_TRUE(Errs.empty()); Errs.clear(); cl::ResetAllOptionOccurrences(); } + +TEST(CommandLineTest, OptionErrorMessage) { + // Test the fix for PR42943. + // + // When there is an error, we expect some error message like: + // prog: for the -a option: [...] + // + // Test whether the "for the -a option"-part is correctly formatted. + cl::ResetCommandLineParser(); + + StackOption OptA("a", cl::desc("Some option")); + StackOption OptLong("long", cl::desc("Some long option")); + + std::string Errs; + raw_string_ostream OS(Errs); + + OptA.error("custom error", OS); + OS.flush(); + EXPECT_FALSE(Errs.find("for the -a option:") == std::string::npos); + Errs.clear(); + + OptLong.error("custom error", OS); + OS.flush(); + EXPECT_FALSE(Errs.find("for the --long option:") == std::string::npos); + Errs.clear(); + + cl::ResetAllOptionOccurrences(); +} } // anonymous namespace