diff --git a/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp --- a/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp +++ b/clang-tools-extra/clang-change-namespace/tool/ClangChangeNamespace.cpp @@ -99,8 +99,13 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - tooling::CommonOptionsParser OptionsParser(argc, argv, - ChangeNamespaceCategory); + auto ExpectedParser = + tooling::CommonOptionsParser::create(argc, argv, ChangeNamespaceCategory); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + tooling::CommonOptionsParser &OptionsParser = ExpectedParser.get(); const auto &Files = OptionsParser.getSourcePathList(); tooling::RefactoringTool Tool(OptionsParser.getCompilations(), Files); llvm::ErrorOr> AllowedPatterns = diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp --- a/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp +++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/tool/FindAllSymbolsMain.cpp @@ -128,7 +128,14 @@ } // namespace find_all_symbols int main(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, FindAllSymbolsCategory); + auto ExpectedParser = + CommonOptionsParser::create(argc, argv, FindAllSymbolsCategory); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + + CommonOptionsParser &OptionsParser = ExpectedParser.get(); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); diff --git a/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp b/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp --- a/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp +++ b/clang-tools-extra/clang-include-fixer/tool/ClangIncludeFixer.cpp @@ -263,7 +263,13 @@ } int includeFixerMain(int argc, const char **argv) { - tooling::CommonOptionsParser options(argc, argv, IncludeFixerCategory); + auto ExpectedParser = + tooling::CommonOptionsParser::create(argc, argv, IncludeFixerCategory); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + tooling::CommonOptionsParser &options = ExpectedParser.get(); tooling::ClangTool tool(options.getCompilations(), options.getSourcePathList()); diff --git a/clang-tools-extra/clang-move/tool/ClangMove.cpp b/clang-tools-extra/clang-move/tool/ClangMove.cpp --- a/clang-tools-extra/clang-move/tool/ClangMove.cpp +++ b/clang-tools-extra/clang-move/tool/ClangMove.cpp @@ -95,7 +95,13 @@ int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); - tooling::CommonOptionsParser OptionsParser(argc, argv, ClangMoveCategory); + auto ExpectedParser = + tooling::CommonOptionsParser::create(argc, argv, ClangMoveCategory); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + tooling::CommonOptionsParser &OptionsParser = ExpectedParser.get(); if (OldDependOnNew && NewDependOnOld) { llvm::errs() << "Provide either --old_depend_on_new or " diff --git a/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp b/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp --- a/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp +++ b/clang-tools-extra/clang-reorder-fields/tool/ClangReorderFields.cpp @@ -50,8 +50,14 @@ const char Usage[] = "A tool to reorder fields in C/C++ structs/classes.\n"; int main(int argc, const char **argv) { - tooling::CommonOptionsParser OP(argc, argv, ClangReorderFieldsCategory, - Usage); + auto ExpectedParser = tooling::CommonOptionsParser::create( + argc, argv, ClangReorderFieldsCategory, cl::OneOrMore, Usage); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + + tooling::CommonOptionsParser &OP = ExpectedParser.get(); auto Files = OP.getSourcePathList(); tooling::RefactoringTool Tool(OP.getCompilations(), Files); diff --git a/clang-tools-extra/test/clang-query/invalid-command-line.cpp b/clang-tools-extra/test/clang-query/invalid-command-line.cpp --- a/clang-tools-extra/test/clang-query/invalid-command-line.cpp +++ b/clang-tools-extra/test/clang-query/invalid-command-line.cpp @@ -1,4 +1,4 @@ // RUN: not clang-query --invalid-arg 2>&1 | FileCheck %s -// CHECK: error: [CommonOptionsParser]: clang-query{{(\.exe)?}}: Unknown command line argument '--invalid-arg'. Try: 'clang-query{{(\.exe)?}} --help' +// CHECK: error: clang-query{{(\.exe)?}}: Unknown command line argument '--invalid-arg'. Try: 'clang-query{{(\.exe)?}} --help' // CHECK-NEXT: clang-query{{(\.exe)?}}: Did you mean '--extra-arg'? diff --git a/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp b/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp --- a/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp +++ b/clang-tools-extra/test/clang-tidy/infrastructure/invalid-command-line.cpp @@ -1,4 +1,4 @@ // RUN: not clang-tidy --invalid-arg 2>&1 | FileCheck %s -// CHECK: error: [CommonOptionsParser]: clang-tidy{{(\.exe)?}}: Unknown command line argument '--invalid-arg'. Try: 'clang-tidy{{(\.exe)?}} --help' +// CHECK: error: clang-tidy{{(\.exe)?}}: Unknown command line argument '--invalid-arg'. Try: 'clang-tidy{{(\.exe)?}} --help' // CHECK-NEXT: clang-tidy{{(\.exe)?}}: Did you mean '--extra-arg'? diff --git a/clang/docs/LibASTMatchersTutorial.rst b/clang/docs/LibASTMatchersTutorial.rst --- a/clang/docs/LibASTMatchersTutorial.rst +++ b/clang/docs/LibASTMatchersTutorial.rst @@ -141,7 +141,13 @@ static cl::extrahelp MoreHelp("\nMore help text...\n"); int main(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); + auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory); + if (!ExpectedParser) { + // Fail gracefully for unsupported options. + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser& OptionsParser = ExpectedParser.get(); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); return Tool.run(newFrontendActionFactory().get()); @@ -282,7 +288,13 @@ .. code-block:: c++ int main(int argc, const char **argv) { - CommonOptionsParser OptionsParser(argc, argv, MyToolCategory); + auto ExpectedParser = CommonOptionsParser::create(argc, argv, MyToolCategory); + if (!ExpectedParser) { + // Fail gracefully for unsupported options. + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser& OptionsParser = ExpectedParser.get(); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); diff --git a/clang/include/clang/Tooling/CommonOptionsParser.h b/clang/include/clang/Tooling/CommonOptionsParser.h --- a/clang/include/clang/Tooling/CommonOptionsParser.h +++ b/clang/include/clang/Tooling/CommonOptionsParser.h @@ -63,21 +63,8 @@ /// } /// \endcode class CommonOptionsParser { -public: - /// Parses command-line, initializes a compilation database. - /// - /// This constructor can change argc and argv contents, e.g. consume - /// command-line options used for creating FixedCompilationDatabase. - /// - /// All options not belonging to \p Category become hidden. - /// - /// This constructor exits program in case of error. - CommonOptionsParser(int &argc, const char **argv, - llvm::cl::OptionCategory &Category, - const char *Overview = nullptr) - : CommonOptionsParser(argc, argv, Category, llvm::cl::OneOrMore, - Overview) {} +protected: /// Parses command-line, initializes a compilation database. /// /// This constructor can change argc and argv contents, e.g. consume @@ -86,16 +73,17 @@ /// All options not belonging to \p Category become hidden. /// /// It also allows calls to set the required number of positional parameters. - CommonOptionsParser(int &argc, const char **argv, - llvm::cl::OptionCategory &Category, - llvm::cl::NumOccurrencesFlag OccurrencesFlag, - const char *Overview = nullptr); + CommonOptionsParser( + int &argc, const char **argv, llvm::cl::OptionCategory &Category, + llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore, + const char *Overview = nullptr); +public: /// A factory method that is similar to the above constructor, except /// this returns an error instead exiting the program on error. static llvm::Expected create(int &argc, const char **argv, llvm::cl::OptionCategory &Category, - llvm::cl::NumOccurrencesFlag OccurrencesFlag, + llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore, const char *Overview = nullptr); /// Returns a reference to the loaded compilations database. diff --git a/clang/lib/Tooling/CommonOptionsParser.cpp b/clang/lib/Tooling/CommonOptionsParser.cpp --- a/clang/lib/Tooling/CommonOptionsParser.cpp +++ b/clang/lib/Tooling/CommonOptionsParser.cpp @@ -115,8 +115,7 @@ // Stop initializing if command-line option parsing failed. if (!cl::ParseCommandLineOptions(argc, argv, Overview, &OS)) { OS.flush(); - return llvm::make_error("[CommonOptionsParser]: " + - ErrorMessage, + return llvm::make_error(ErrorMessage, llvm::inconvertibleErrorCode()); } diff --git a/clang/tools/clang-check/ClangCheck.cpp b/clang/tools/clang-check/ClangCheck.cpp --- a/clang/tools/clang-check/ClangCheck.cpp +++ b/clang/tools/clang-check/ClangCheck.cpp @@ -160,7 +160,13 @@ llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); - CommonOptionsParser OptionsParser(argc, argv, ClangCheckCategory); + auto ExpectedParser = + CommonOptionsParser::create(argc, argv, ClangCheckCategory); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser &OptionsParser = ExpectedParser.get(); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); diff --git a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp --- a/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp +++ b/clang/tools/clang-extdef-mapping/ClangExtDefMapGen.cpp @@ -119,8 +119,13 @@ const char *Overview = "\nThis tool collects the USR name and location " "of external definitions in the source files " "(excluding headers).\n"; - CommonOptionsParser OptionsParser(argc, argv, ClangExtDefMapGenCategory, - cl::ZeroOrMore, Overview); + auto ExpectedParser = CommonOptionsParser::create( + argc, argv, ClangExtDefMapGenCategory, cl::ZeroOrMore, Overview); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser &OptionsParser = ExpectedParser.get(); ClangTool Tool(OptionsParser.getCompilations(), OptionsParser.getSourcePathList()); diff --git a/clang/tools/clang-refactor/ClangRefactor.cpp b/clang/tools/clang-refactor/ClangRefactor.cpp --- a/clang/tools/clang-refactor/ClangRefactor.cpp +++ b/clang/tools/clang-refactor/ClangRefactor.cpp @@ -612,9 +612,14 @@ ClangRefactorTool RefactorTool; - CommonOptionsParser Options( + auto ExpectedParser = CommonOptionsParser::create( argc, argv, cl::GeneralCategory, cl::ZeroOrMore, "Clang-based refactoring tool for C, C++ and Objective-C"); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + CommonOptionsParser &Options = ExpectedParser.get(); if (auto Err = RefactorTool.Init()) { llvm::errs() << llvm::toString(std::move(Err)) << "\n"; diff --git a/clang/tools/clang-rename/ClangRename.cpp b/clang/tools/clang-rename/ClangRename.cpp --- a/clang/tools/clang-rename/ClangRename.cpp +++ b/clang/tools/clang-rename/ClangRename.cpp @@ -98,7 +98,13 @@ cl::cat(ClangRenameOptions)); int main(int argc, const char **argv) { - tooling::CommonOptionsParser OP(argc, argv, ClangRenameOptions); + auto ExpectedParser = + tooling::CommonOptionsParser::create(argc, argv, ClangRenameOptions); + if (!ExpectedParser) { + llvm::errs() << ExpectedParser.takeError(); + return 1; + } + tooling::CommonOptionsParser &OP = ExpectedParser.get(); if (!Input.empty()) { // Populate QualifiedNames and NewNames from a YAML file.