10b57cec5SDimitry Andric //===- CommonOptionsParser.h - common options for clang tools -*- C++ -*-=====//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  This file implements the CommonOptionsParser class used to parse common
100b57cec5SDimitry Andric //  command-line options for clang tools, so that they can be run as separate
110b57cec5SDimitry Andric //  command-line applications with a consistent common interface for handling
120b57cec5SDimitry Andric //  compilation database and input files.
130b57cec5SDimitry Andric //
140b57cec5SDimitry Andric //  It provides a common subset of command-line options, common algorithm
150b57cec5SDimitry Andric //  for locating a compilation database and source files, and help messages
160b57cec5SDimitry Andric //  for the basic command-line interface.
170b57cec5SDimitry Andric //
180b57cec5SDimitry Andric //  It creates a CompilationDatabase and reads common command-line options.
190b57cec5SDimitry Andric //
200b57cec5SDimitry Andric //  This class uses the Clang Tooling infrastructure, see
210b57cec5SDimitry Andric //    http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
220b57cec5SDimitry Andric //  for details on setting it up with LLVM source tree.
230b57cec5SDimitry Andric //
240b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric #ifndef LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
270b57cec5SDimitry Andric #define LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
280b57cec5SDimitry Andric 
290b57cec5SDimitry Andric #include "clang/Tooling/ArgumentsAdjusters.h"
300b57cec5SDimitry Andric #include "clang/Tooling/CompilationDatabase.h"
310b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
320b57cec5SDimitry Andric #include "llvm/Support/Error.h"
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric namespace clang {
350b57cec5SDimitry Andric namespace tooling {
360b57cec5SDimitry Andric /// A parser for options common to all command-line Clang tools.
370b57cec5SDimitry Andric ///
380b57cec5SDimitry Andric /// Parses a common subset of command-line arguments, locates and loads a
390b57cec5SDimitry Andric /// compilation commands database and runs a tool with user-specified action. It
400b57cec5SDimitry Andric /// also contains a help message for the common command-line options.
410b57cec5SDimitry Andric ///
420b57cec5SDimitry Andric /// An example of usage:
430b57cec5SDimitry Andric /// \code
440b57cec5SDimitry Andric /// #include "clang/Frontend/FrontendActions.h"
450b57cec5SDimitry Andric /// #include "clang/Tooling/CommonOptionsParser.h"
460b57cec5SDimitry Andric /// #include "clang/Tooling/Tooling.h"
470b57cec5SDimitry Andric /// #include "llvm/Support/CommandLine.h"
480b57cec5SDimitry Andric ///
490b57cec5SDimitry Andric /// using namespace clang::tooling;
500b57cec5SDimitry Andric /// using namespace llvm;
510b57cec5SDimitry Andric ///
520b57cec5SDimitry Andric /// static cl::OptionCategory MyToolCategory("My tool options");
530b57cec5SDimitry Andric /// static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
540b57cec5SDimitry Andric /// static cl::extrahelp MoreHelp("\nMore help text...\n");
550b57cec5SDimitry Andric /// static cl::opt<bool> YourOwnOption(...);
560b57cec5SDimitry Andric /// ...
570b57cec5SDimitry Andric ///
580b57cec5SDimitry Andric /// int main(int argc, const char **argv) {
590b57cec5SDimitry Andric ///   CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
600b57cec5SDimitry Andric ///   ClangTool Tool(OptionsParser.getCompilations(),
610b57cec5SDimitry Andric ///                  OptionsParser.getSourcePathList());
620b57cec5SDimitry Andric ///   return Tool.run(newFrontendActionFactory<SyntaxOnlyAction>().get());
630b57cec5SDimitry Andric /// }
640b57cec5SDimitry Andric /// \endcode
650b57cec5SDimitry Andric class CommonOptionsParser {
660b57cec5SDimitry Andric 
67fe6060f1SDimitry Andric protected:
680b57cec5SDimitry Andric   /// Parses command-line, initializes a compilation database.
690b57cec5SDimitry Andric   ///
700b57cec5SDimitry Andric   /// This constructor can change argc and argv contents, e.g. consume
710b57cec5SDimitry Andric   /// command-line options used for creating FixedCompilationDatabase.
720b57cec5SDimitry Andric   ///
730b57cec5SDimitry Andric   /// All options not belonging to \p Category become hidden.
740b57cec5SDimitry Andric   ///
750b57cec5SDimitry Andric   /// It also allows calls to set the required number of positional parameters.
76fe6060f1SDimitry Andric   CommonOptionsParser(
77fe6060f1SDimitry Andric       int &argc, const char **argv, llvm::cl::OptionCategory &Category,
78fe6060f1SDimitry Andric       llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore,
790b57cec5SDimitry Andric       const char *Overview = nullptr);
800b57cec5SDimitry Andric 
81fe6060f1SDimitry Andric public:
820b57cec5SDimitry Andric   /// A factory method that is similar to the above constructor, except
830b57cec5SDimitry Andric   /// this returns an error instead exiting the program on error.
840b57cec5SDimitry Andric   static llvm::Expected<CommonOptionsParser>
850b57cec5SDimitry Andric   create(int &argc, const char **argv, llvm::cl::OptionCategory &Category,
86fe6060f1SDimitry Andric          llvm::cl::NumOccurrencesFlag OccurrencesFlag = llvm::cl::OneOrMore,
870b57cec5SDimitry Andric          const char *Overview = nullptr);
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric   /// Returns a reference to the loaded compilations database.
getCompilations()900b57cec5SDimitry Andric   CompilationDatabase &getCompilations() {
910b57cec5SDimitry Andric     return *Compilations;
920b57cec5SDimitry Andric   }
930b57cec5SDimitry Andric 
940b57cec5SDimitry Andric   /// Returns a list of source file paths to process.
getSourcePathList()950b57cec5SDimitry Andric   const std::vector<std::string> &getSourcePathList() const {
960b57cec5SDimitry Andric     return SourcePathList;
970b57cec5SDimitry Andric   }
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   /// Returns the argument adjuster calculated from "--extra-arg" and
1000b57cec5SDimitry Andric   //"--extra-arg-before" options.
getArgumentsAdjuster()1010b57cec5SDimitry Andric   ArgumentsAdjuster getArgumentsAdjuster() { return Adjuster; }
1020b57cec5SDimitry Andric 
1030b57cec5SDimitry Andric   static const char *const HelpMessage;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric private:
1060b57cec5SDimitry Andric   CommonOptionsParser() = default;
1070b57cec5SDimitry Andric 
1080b57cec5SDimitry Andric   llvm::Error init(int &argc, const char **argv,
1090b57cec5SDimitry Andric                    llvm::cl::OptionCategory &Category,
1100b57cec5SDimitry Andric                    llvm::cl::NumOccurrencesFlag OccurrencesFlag,
1110b57cec5SDimitry Andric                    const char *Overview);
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   std::unique_ptr<CompilationDatabase> Compilations;
1140b57cec5SDimitry Andric   std::vector<std::string> SourcePathList;
1150b57cec5SDimitry Andric   ArgumentsAdjuster Adjuster;
1160b57cec5SDimitry Andric };
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric class ArgumentsAdjustingCompilations : public CompilationDatabase {
1190b57cec5SDimitry Andric public:
ArgumentsAdjustingCompilations(std::unique_ptr<CompilationDatabase> Compilations)1200b57cec5SDimitry Andric   ArgumentsAdjustingCompilations(
1210b57cec5SDimitry Andric       std::unique_ptr<CompilationDatabase> Compilations)
1220b57cec5SDimitry Andric       : Compilations(std::move(Compilations)) {}
1230b57cec5SDimitry Andric 
1240b57cec5SDimitry Andric   void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
1250b57cec5SDimitry Andric 
1260b57cec5SDimitry Andric   std::vector<CompileCommand>
1270b57cec5SDimitry Andric   getCompileCommands(StringRef FilePath) const override;
1280b57cec5SDimitry Andric 
1290b57cec5SDimitry Andric   std::vector<std::string> getAllFiles() const override;
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   std::vector<CompileCommand> getAllCompileCommands() const override;
1320b57cec5SDimitry Andric 
1330b57cec5SDimitry Andric private:
1340b57cec5SDimitry Andric   std::unique_ptr<CompilationDatabase> Compilations;
1350b57cec5SDimitry Andric   std::vector<ArgumentsAdjuster> Adjusters;
1360b57cec5SDimitry Andric 
1370b57cec5SDimitry Andric   std::vector<CompileCommand>
1380b57cec5SDimitry Andric   adjustCommands(std::vector<CompileCommand> Commands) const;
1390b57cec5SDimitry Andric };
1400b57cec5SDimitry Andric 
1410b57cec5SDimitry Andric }  // namespace tooling
1420b57cec5SDimitry Andric }  // namespace clang
1430b57cec5SDimitry Andric 
14404eeddc0SDimitry Andric #endif // LLVM_CLANG_TOOLING_COMMONOPTIONSPARSER_H
145