Home | History | Annotate | Download | only in Tooling
      1 //===--- CompilationDatabase.h - --------------------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 //  This file provides an interface and multiple implementations for
     11 //  CompilationDatabases.
     12 //
     13 //  While C++ refactoring and analysis tools are not compilers, and thus
     14 //  don't run as part of the build system, they need the exact information
     15 //  of a build in order to be able to correctly understand the C++ code of
     16 //  the project. This information is provided via the CompilationDatabase
     17 //  interface.
     18 //
     19 //  To create a CompilationDatabase from a build directory one can call
     20 //  CompilationDatabase::loadFromDirectory(), which deduces the correct
     21 //  compilation database from the root of the build tree.
     22 //
     23 //  See the concrete subclasses of CompilationDatabase for currently supported
     24 //  formats.
     25 //
     26 //===----------------------------------------------------------------------===//
     27 
     28 #ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
     29 #define LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
     30 
     31 #include "clang/Basic/LLVM.h"
     32 #include "llvm/ADT/ArrayRef.h"
     33 #include "llvm/ADT/StringRef.h"
     34 #include "llvm/ADT/Twine.h"
     35 #include <memory>
     36 #include <string>
     37 #include <vector>
     38 
     39 namespace clang {
     40 namespace tooling {
     41 
     42 /// \brief Specifies the working directory and command of a compilation.
     43 struct CompileCommand {
     44   CompileCommand() {}
     45   CompileCommand(Twine Directory, Twine Filename,
     46                  std::vector<std::string> CommandLine, Twine Output)
     47       : Directory(Directory.str()),
     48         Filename(Filename.str()),
     49         CommandLine(std::move(CommandLine)),
     50         Output(Output.str()){}
     51 
     52   /// \brief The working directory the command was executed from.
     53   std::string Directory;
     54 
     55   /// The source file associated with the command.
     56   std::string Filename;
     57 
     58   /// \brief The command line that was executed.
     59   std::vector<std::string> CommandLine;
     60 
     61   /// The output file associated with the command.
     62   std::string Output;
     63 };
     64 
     65 /// \brief Interface for compilation databases.
     66 ///
     67 /// A compilation database allows the user to retrieve all compile command lines
     68 /// that a specified file is compiled with in a project.
     69 /// The retrieved compile command lines can be used to run clang tools over
     70 /// a subset of the files in a project.
     71 class CompilationDatabase {
     72 public:
     73   virtual ~CompilationDatabase();
     74 
     75   /// \brief Loads a compilation database from a build directory.
     76   ///
     77   /// Looks at the specified 'BuildDirectory' and creates a compilation database
     78   /// that allows to query compile commands for source files in the
     79   /// corresponding source tree.
     80   ///
     81   /// Returns NULL and sets ErrorMessage if we were not able to build up a
     82   /// compilation database for the build directory.
     83   ///
     84   /// FIXME: Currently only supports JSON compilation databases, which
     85   /// are named 'compile_commands.json' in the given directory. Extend this
     86   /// for other build types (like ninja build files).
     87   static std::unique_ptr<CompilationDatabase>
     88   loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
     89 
     90   /// \brief Tries to detect a compilation database location and load it.
     91   ///
     92   /// Looks for a compilation database in all parent paths of file 'SourceFile'
     93   /// by calling loadFromDirectory.
     94   static std::unique_ptr<CompilationDatabase>
     95   autoDetectFromSource(StringRef SourceFile, std::string &ErrorMessage);
     96 
     97   /// \brief Tries to detect a compilation database location and load it.
     98   ///
     99   /// Looks for a compilation database in directory 'SourceDir' and all
    100   /// its parent paths by calling loadFromDirectory.
    101   static std::unique_ptr<CompilationDatabase>
    102   autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage);
    103 
    104   /// \brief Returns all compile commands in which the specified file was
    105   /// compiled.
    106   ///
    107   /// This includes compile commands that span multiple source files.
    108   /// For example, consider a project with the following compilations:
    109   /// $ clang++ -o test a.cc b.cc t.cc
    110   /// $ clang++ -o production a.cc b.cc -DPRODUCTION
    111   /// A compilation database representing the project would return both command
    112   /// lines for a.cc and b.cc and only the first command line for t.cc.
    113   virtual std::vector<CompileCommand> getCompileCommands(
    114     StringRef FilePath) const = 0;
    115 
    116   /// \brief Returns the list of all files available in the compilation database.
    117   virtual std::vector<std::string> getAllFiles() const = 0;
    118 
    119   /// \brief Returns all compile commands for all the files in the compilation
    120   /// database.
    121   ///
    122   /// FIXME: Add a layer in Tooling that provides an interface to run a tool
    123   /// over all files in a compilation database. Not all build systems have the
    124   /// ability to provide a feasible implementation for \c getAllCompileCommands.
    125   virtual std::vector<CompileCommand> getAllCompileCommands() const = 0;
    126 };
    127 
    128 /// \brief Interface for compilation database plugins.
    129 ///
    130 /// A compilation database plugin allows the user to register custom compilation
    131 /// databases that are picked up as compilation database if the corresponding
    132 /// library is linked in. To register a plugin, declare a static variable like:
    133 ///
    134 /// \code
    135 /// static CompilationDatabasePluginRegistry::Add<MyDatabasePlugin>
    136 /// X("my-compilation-database", "Reads my own compilation database");
    137 /// \endcode
    138 class CompilationDatabasePlugin {
    139 public:
    140   virtual ~CompilationDatabasePlugin();
    141 
    142   /// \brief Loads a compilation database from a build directory.
    143   ///
    144   /// \see CompilationDatabase::loadFromDirectory().
    145   virtual std::unique_ptr<CompilationDatabase>
    146   loadFromDirectory(StringRef Directory, std::string &ErrorMessage) = 0;
    147 };
    148 
    149 /// \brief A compilation database that returns a single compile command line.
    150 ///
    151 /// Useful when we want a tool to behave more like a compiler invocation.
    152 class FixedCompilationDatabase : public CompilationDatabase {
    153 public:
    154   /// \brief Creates a FixedCompilationDatabase from the arguments after "--".
    155   ///
    156   /// Parses the given command line for "--". If "--" is found, the rest of
    157   /// the arguments will make up the command line in the returned
    158   /// FixedCompilationDatabase.
    159   /// The arguments after "--" must not include positional parameters or the
    160   /// argv[0] of the tool. Those will be added by the FixedCompilationDatabase
    161   /// when a CompileCommand is requested. The argv[0] of the returned command
    162   /// line will be "clang-tool".
    163   ///
    164   /// Returns NULL in case "--" is not found.
    165   ///
    166   /// The argument list is meant to be compatible with normal llvm command line
    167   /// parsing in main methods.
    168   /// int main(int argc, char **argv) {
    169   ///   std::unique_ptr<FixedCompilationDatabase> Compilations(
    170   ///     FixedCompilationDatabase::loadFromCommandLine(argc, argv));
    171   ///   cl::ParseCommandLineOptions(argc, argv);
    172   ///   ...
    173   /// }
    174   ///
    175   /// \param Argc The number of command line arguments - will be changed to
    176   /// the number of arguments before "--", if "--" was found in the argument
    177   /// list.
    178   /// \param Argv Points to the command line arguments.
    179   /// \param ErrorMsg Contains error text if the function returns null pointer.
    180   /// \param Directory The base directory used in the FixedCompilationDatabase.
    181   static std::unique_ptr<FixedCompilationDatabase> loadFromCommandLine(
    182       int &Argc, const char *const *Argv, std::string &ErrorMsg,
    183       Twine Directory = ".");
    184 
    185   /// \brief Constructs a compilation data base from a specified directory
    186   /// and command line.
    187   FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine);
    188 
    189   /// \brief Returns the given compile command.
    190   ///
    191   /// Will always return a vector with one entry that contains the directory
    192   /// and command line specified at construction with "clang-tool" as argv[0]
    193   /// and 'FilePath' as positional argument.
    194   std::vector<CompileCommand>
    195   getCompileCommands(StringRef FilePath) const override;
    196 
    197   /// \brief Returns the list of all files available in the compilation database.
    198   ///
    199   /// Note: This is always an empty list for the fixed compilation database.
    200   std::vector<std::string> getAllFiles() const override;
    201 
    202   /// \brief Returns all compile commands for all the files in the compilation
    203   /// database.
    204   ///
    205   /// Note: This is always an empty list for the fixed compilation database.
    206   std::vector<CompileCommand> getAllCompileCommands() const override;
    207 
    208 private:
    209   /// This is built up to contain a single entry vector to be returned from
    210   /// getCompileCommands after adding the positional argument.
    211   std::vector<CompileCommand> CompileCommands;
    212 };
    213 
    214 } // end namespace tooling
    215 } // end namespace clang
    216 
    217 #endif
    218