Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:37:12

0001 //===- CompilationDatabase.h ------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 //  This file provides an interface and multiple implementations for
0010 //  CompilationDatabases.
0011 //
0012 //  While C++ refactoring and analysis tools are not compilers, and thus
0013 //  don't run as part of the build system, they need the exact information
0014 //  of a build in order to be able to correctly understand the C++ code of
0015 //  the project. This information is provided via the CompilationDatabase
0016 //  interface.
0017 //
0018 //  To create a CompilationDatabase from a build directory one can call
0019 //  CompilationDatabase::loadFromDirectory(), which deduces the correct
0020 //  compilation database from the root of the build tree.
0021 //
0022 //  See the concrete subclasses of CompilationDatabase for currently supported
0023 //  formats.
0024 //
0025 //===----------------------------------------------------------------------===//
0026 
0027 #ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
0028 #define LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
0029 
0030 #include "clang/Basic/LLVM.h"
0031 #include "llvm/ADT/ArrayRef.h"
0032 #include "llvm/ADT/StringRef.h"
0033 #include "llvm/ADT/Twine.h"
0034 #include "llvm/Support/VirtualFileSystem.h"
0035 #include <memory>
0036 #include <string>
0037 #include <utility>
0038 #include <vector>
0039 
0040 namespace clang {
0041 namespace tooling {
0042 
0043 /// Specifies the working directory and command of a compilation.
0044 struct CompileCommand {
0045   CompileCommand() = default;
0046   CompileCommand(const Twine &Directory, const Twine &Filename,
0047                  std::vector<std::string> CommandLine, const Twine &Output)
0048       : Directory(Directory.str()), Filename(Filename.str()),
0049         CommandLine(std::move(CommandLine)), Output(Output.str()) {}
0050 
0051   /// The working directory the command was executed from.
0052   std::string Directory;
0053 
0054   /// The source file associated with the command.
0055   std::string Filename;
0056 
0057   /// The command line that was executed.
0058   std::vector<std::string> CommandLine;
0059 
0060   /// The output file associated with the command.
0061   std::string Output;
0062 
0063   /// If this compile command was guessed rather than read from an authoritative
0064   /// source, a short human-readable explanation.
0065   /// e.g. "inferred from foo/bar.h".
0066   std::string Heuristic;
0067 
0068   friend bool operator==(const CompileCommand &LHS, const CompileCommand &RHS) {
0069     return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
0070            LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output &&
0071            LHS.Heuristic == RHS.Heuristic;
0072   }
0073 
0074   friend bool operator!=(const CompileCommand &LHS, const CompileCommand &RHS) {
0075     return !(LHS == RHS);
0076   }
0077 };
0078 
0079 /// Interface for compilation databases.
0080 ///
0081 /// A compilation database allows the user to retrieve compile command lines
0082 /// for the files in a project.
0083 ///
0084 /// Many implementations are enumerable, allowing all command lines to be
0085 /// retrieved. These can be used to run clang tools over a subset of the files
0086 /// in a project.
0087 class CompilationDatabase {
0088 public:
0089   virtual ~CompilationDatabase();
0090 
0091   /// Loads a compilation database from a build directory.
0092   ///
0093   /// Looks at the specified 'BuildDirectory' and creates a compilation database
0094   /// that allows to query compile commands for source files in the
0095   /// corresponding source tree.
0096   ///
0097   /// Returns NULL and sets ErrorMessage if we were not able to build up a
0098   /// compilation database for the build directory.
0099   ///
0100   /// FIXME: Currently only supports JSON compilation databases, which
0101   /// are named 'compile_commands.json' in the given directory. Extend this
0102   /// for other build types (like ninja build files).
0103   static std::unique_ptr<CompilationDatabase>
0104   loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
0105 
0106   /// Tries to detect a compilation database location and load it.
0107   ///
0108   /// Looks for a compilation database in all parent paths of file 'SourceFile'
0109   /// by calling loadFromDirectory.
0110   static std::unique_ptr<CompilationDatabase>
0111   autoDetectFromSource(StringRef SourceFile, std::string &ErrorMessage);
0112 
0113   /// Tries to detect a compilation database location and load it.
0114   ///
0115   /// Looks for a compilation database in directory 'SourceDir' and all
0116   /// its parent paths by calling loadFromDirectory.
0117   static std::unique_ptr<CompilationDatabase>
0118   autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage);
0119 
0120   /// Returns all compile commands in which the specified file was
0121   /// compiled.
0122   ///
0123   /// This includes compile commands that span multiple source files.
0124   /// For example, consider a project with the following compilations:
0125   /// $ clang++ -o test a.cc b.cc t.cc
0126   /// $ clang++ -o production a.cc b.cc -DPRODUCTION
0127   /// A compilation database representing the project would return both command
0128   /// lines for a.cc and b.cc and only the first command line for t.cc.
0129   virtual std::vector<CompileCommand> getCompileCommands(
0130       StringRef FilePath) const = 0;
0131 
0132   /// Returns the list of all files available in the compilation database.
0133   ///
0134   /// By default, returns nothing. Implementations should override this if they
0135   /// can enumerate their source files.
0136   virtual std::vector<std::string> getAllFiles() const { return {}; }
0137 
0138   /// Returns all compile commands for all the files in the compilation
0139   /// database.
0140   ///
0141   /// FIXME: Add a layer in Tooling that provides an interface to run a tool
0142   /// over all files in a compilation database. Not all build systems have the
0143   /// ability to provide a feasible implementation for \c getAllCompileCommands.
0144   ///
0145   /// By default, this is implemented in terms of getAllFiles() and
0146   /// getCompileCommands(). Subclasses may override this for efficiency.
0147   virtual std::vector<CompileCommand> getAllCompileCommands() const;
0148 };
0149 
0150 /// A compilation database that returns a single compile command line.
0151 ///
0152 /// Useful when we want a tool to behave more like a compiler invocation.
0153 /// This compilation database is not enumerable: getAllFiles() returns {}.
0154 class FixedCompilationDatabase : public CompilationDatabase {
0155 public:
0156   /// Creates a FixedCompilationDatabase from the arguments after "--".
0157   ///
0158   /// Parses the given command line for "--". If "--" is found, the rest of
0159   /// the arguments will make up the command line in the returned
0160   /// FixedCompilationDatabase.
0161   /// The arguments after "--" must not include positional parameters or the
0162   /// argv[0] of the tool. Those will be added by the FixedCompilationDatabase
0163   /// when a CompileCommand is requested. The argv[0] of the returned command
0164   /// line will be "clang-tool".
0165   ///
0166   /// Returns NULL in case "--" is not found.
0167   ///
0168   /// The argument list is meant to be compatible with normal llvm command line
0169   /// parsing in main methods.
0170   /// int main(int argc, char **argv) {
0171   ///   std::unique_ptr<FixedCompilationDatabase> Compilations(
0172   ///     FixedCompilationDatabase::loadFromCommandLine(argc, argv));
0173   ///   cl::ParseCommandLineOptions(argc, argv);
0174   ///   ...
0175   /// }
0176   ///
0177   /// \param Argc The number of command line arguments - will be changed to
0178   /// the number of arguments before "--", if "--" was found in the argument
0179   /// list.
0180   /// \param Argv Points to the command line arguments.
0181   /// \param ErrorMsg Contains error text if the function returns null pointer.
0182   /// \param Directory The base directory used in the FixedCompilationDatabase.
0183   static std::unique_ptr<FixedCompilationDatabase>
0184   loadFromCommandLine(int &Argc, const char *const *Argv, std::string &ErrorMsg,
0185                       const Twine &Directory = ".");
0186 
0187   /// Reads flags from the given file, one-per-line.
0188   /// Returns nullptr and sets ErrorMessage if we can't read the file.
0189   static std::unique_ptr<FixedCompilationDatabase>
0190   loadFromFile(StringRef Path, std::string &ErrorMsg);
0191 
0192   /// Reads flags from the given buffer, one-per-line.
0193   /// Directory is the command CWD, typically the parent of compile_flags.txt.
0194   static std::unique_ptr<FixedCompilationDatabase>
0195   loadFromBuffer(StringRef Directory, StringRef Data, std::string &ErrorMsg);
0196 
0197   /// Constructs a compilation data base from a specified directory
0198   /// and command line.
0199   FixedCompilationDatabase(const Twine &Directory,
0200                            ArrayRef<std::string> CommandLine);
0201 
0202   /// Returns the given compile command.
0203   ///
0204   /// Will always return a vector with one entry that contains the directory
0205   /// and command line specified at construction with "clang-tool" as argv[0]
0206   /// and 'FilePath' as positional argument.
0207   std::vector<CompileCommand>
0208   getCompileCommands(StringRef FilePath) const override;
0209 
0210 private:
0211   /// This is built up to contain a single entry vector to be returned from
0212   /// getCompileCommands after adding the positional argument.
0213   std::vector<CompileCommand> CompileCommands;
0214 };
0215 
0216 /// Transforms a compile command so that it applies the same configuration to
0217 /// a different file. Most args are left intact, but tweaks may be needed
0218 /// to certain flags (-x, -std etc).
0219 ///
0220 /// The output command will always end in {"--", Filename}.
0221 tooling::CompileCommand transferCompileCommand(tooling::CompileCommand,
0222                                                StringRef Filename);
0223 
0224 /// Returns a wrapped CompilationDatabase that defers to the provided one,
0225 /// but getCompileCommands() will infer commands for unknown files.
0226 /// The return value of getAllFiles() or getAllCompileCommands() is unchanged.
0227 /// See InterpolatingCompilationDatabase.cpp for details on heuristics.
0228 std::unique_ptr<CompilationDatabase>
0229     inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>);
0230 
0231 /// Returns a wrapped CompilationDatabase that will add -target and -mode flags
0232 /// to commandline when they can be deduced from argv[0] of commandline returned
0233 /// by underlying database.
0234 std::unique_ptr<CompilationDatabase>
0235 inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base);
0236 
0237 /// Returns a wrapped CompilationDatabase that will transform argv[0] to an
0238 /// absolute path, if it currently is a plain tool name, looking it up in
0239 /// PATH.
0240 std::unique_ptr<CompilationDatabase>
0241 inferToolLocation(std::unique_ptr<CompilationDatabase> Base);
0242 
0243 /// Returns a wrapped CompilationDatabase that will expand all rsp(response)
0244 /// files on commandline returned by underlying database.
0245 std::unique_ptr<CompilationDatabase>
0246 expandResponseFiles(std::unique_ptr<CompilationDatabase> Base,
0247                     llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS);
0248 
0249 } // namespace tooling
0250 } // namespace clang
0251 
0252 #endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H