]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/clang/include/clang/Tooling/CompilationDatabase.h
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / clang / include / clang / Tooling / CompilationDatabase.h
1 //===- CompilationDatabase.h ------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 //  This file provides an interface and multiple implementations for
10 //  CompilationDatabases.
11 //
12 //  While C++ refactoring and analysis tools are not compilers, and thus
13 //  don't run as part of the build system, they need the exact information
14 //  of a build in order to be able to correctly understand the C++ code of
15 //  the project. This information is provided via the CompilationDatabase
16 //  interface.
17 //
18 //  To create a CompilationDatabase from a build directory one can call
19 //  CompilationDatabase::loadFromDirectory(), which deduces the correct
20 //  compilation database from the root of the build tree.
21 //
22 //  See the concrete subclasses of CompilationDatabase for currently supported
23 //  formats.
24 //
25 //===----------------------------------------------------------------------===//
26
27 #ifndef LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
28 #define LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H
29
30 #include "clang/Basic/LLVM.h"
31 #include "llvm/ADT/ArrayRef.h"
32 #include "llvm/ADT/StringRef.h"
33 #include "llvm/ADT/Twine.h"
34 #include <memory>
35 #include <string>
36 #include <utility>
37 #include <vector>
38
39 namespace clang {
40 namespace tooling {
41
42 /// Specifies the working directory and command of a compilation.
43 struct CompileCommand {
44   CompileCommand() = default;
45   CompileCommand(Twine Directory, Twine Filename,
46                  std::vector<std::string> CommandLine, Twine Output)
47       : Directory(Directory.str()), Filename(Filename.str()),
48         CommandLine(std::move(CommandLine)), Output(Output.str()){}
49
50   /// The working directory the command was executed from.
51   std::string Directory;
52
53   /// The source file associated with the command.
54   std::string Filename;
55
56   /// The command line that was executed.
57   std::vector<std::string> CommandLine;
58
59   /// The output file associated with the command.
60   std::string Output;
61
62   /// If this compile command was guessed rather than read from an authoritative
63   /// source, a short human-readable explanation.
64   /// e.g. "inferred from foo/bar.h".
65   std::string Heuristic;
66
67   friend bool operator==(const CompileCommand &LHS, const CompileCommand &RHS) {
68     return LHS.Directory == RHS.Directory && LHS.Filename == RHS.Filename &&
69            LHS.CommandLine == RHS.CommandLine && LHS.Output == RHS.Output &&
70            LHS.Heuristic == RHS.Heuristic;
71   }
72
73   friend bool operator!=(const CompileCommand &LHS, const CompileCommand &RHS) {
74     return !(LHS == RHS);
75   }
76 };
77
78 /// Interface for compilation databases.
79 ///
80 /// A compilation database allows the user to retrieve compile command lines
81 /// for the files in a project.
82 ///
83 /// Many implementations are enumerable, allowing all command lines to be
84 /// retrieved. These can be used to run clang tools over a subset of the files
85 /// in a project.
86 class CompilationDatabase {
87 public:
88   virtual ~CompilationDatabase();
89
90   /// Loads a compilation database from a build directory.
91   ///
92   /// Looks at the specified 'BuildDirectory' and creates a compilation database
93   /// that allows to query compile commands for source files in the
94   /// corresponding source tree.
95   ///
96   /// Returns NULL and sets ErrorMessage if we were not able to build up a
97   /// compilation database for the build directory.
98   ///
99   /// FIXME: Currently only supports JSON compilation databases, which
100   /// are named 'compile_commands.json' in the given directory. Extend this
101   /// for other build types (like ninja build files).
102   static std::unique_ptr<CompilationDatabase>
103   loadFromDirectory(StringRef BuildDirectory, std::string &ErrorMessage);
104
105   /// Tries to detect a compilation database location and load it.
106   ///
107   /// Looks for a compilation database in all parent paths of file 'SourceFile'
108   /// by calling loadFromDirectory.
109   static std::unique_ptr<CompilationDatabase>
110   autoDetectFromSource(StringRef SourceFile, std::string &ErrorMessage);
111
112   /// Tries to detect a compilation database location and load it.
113   ///
114   /// Looks for a compilation database in directory 'SourceDir' and all
115   /// its parent paths by calling loadFromDirectory.
116   static std::unique_ptr<CompilationDatabase>
117   autoDetectFromDirectory(StringRef SourceDir, std::string &ErrorMessage);
118
119   /// Returns all compile commands in which the specified file was
120   /// compiled.
121   ///
122   /// This includes compile commands that span multiple source files.
123   /// For example, consider a project with the following compilations:
124   /// $ clang++ -o test a.cc b.cc t.cc
125   /// $ clang++ -o production a.cc b.cc -DPRODUCTION
126   /// A compilation database representing the project would return both command
127   /// lines for a.cc and b.cc and only the first command line for t.cc.
128   virtual std::vector<CompileCommand> getCompileCommands(
129       StringRef FilePath) const = 0;
130
131   /// Returns the list of all files available in the compilation database.
132   ///
133   /// By default, returns nothing. Implementations should override this if they
134   /// can enumerate their source files.
135   virtual std::vector<std::string> getAllFiles() const { return {}; }
136
137   /// Returns all compile commands for all the files in the compilation
138   /// database.
139   ///
140   /// FIXME: Add a layer in Tooling that provides an interface to run a tool
141   /// over all files in a compilation database. Not all build systems have the
142   /// ability to provide a feasible implementation for \c getAllCompileCommands.
143   ///
144   /// By default, this is implemented in terms of getAllFiles() and
145   /// getCompileCommands(). Subclasses may override this for efficiency.
146   virtual std::vector<CompileCommand> getAllCompileCommands() const;
147 };
148
149 /// 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 /// This compilation database is not enumerable: getAllFiles() returns {}.
153 class FixedCompilationDatabase : public CompilationDatabase {
154 public:
155   /// Creates a FixedCompilationDatabase from the arguments after "--".
156   ///
157   /// Parses the given command line for "--". If "--" is found, the rest of
158   /// the arguments will make up the command line in the returned
159   /// FixedCompilationDatabase.
160   /// The arguments after "--" must not include positional parameters or the
161   /// argv[0] of the tool. Those will be added by the FixedCompilationDatabase
162   /// when a CompileCommand is requested. The argv[0] of the returned command
163   /// line will be "clang-tool".
164   ///
165   /// Returns NULL in case "--" is not found.
166   ///
167   /// The argument list is meant to be compatible with normal llvm command line
168   /// parsing in main methods.
169   /// int main(int argc, char **argv) {
170   ///   std::unique_ptr<FixedCompilationDatabase> Compilations(
171   ///     FixedCompilationDatabase::loadFromCommandLine(argc, argv));
172   ///   cl::ParseCommandLineOptions(argc, argv);
173   ///   ...
174   /// }
175   ///
176   /// \param Argc The number of command line arguments - will be changed to
177   /// the number of arguments before "--", if "--" was found in the argument
178   /// list.
179   /// \param Argv Points to the command line arguments.
180   /// \param ErrorMsg Contains error text if the function returns null pointer.
181   /// \param Directory The base directory used in the FixedCompilationDatabase.
182   static std::unique_ptr<FixedCompilationDatabase> loadFromCommandLine(
183       int &Argc, const char *const *Argv, std::string &ErrorMsg,
184       Twine Directory = ".");
185
186   /// Reads flags from the given file, one-per line.
187   /// Returns nullptr and sets ErrorMessage if we can't read the file.
188   static std::unique_ptr<FixedCompilationDatabase>
189   loadFromFile(StringRef Path, std::string &ErrorMsg);
190
191   /// Constructs a compilation data base from a specified directory
192   /// and command line.
193   FixedCompilationDatabase(Twine Directory, ArrayRef<std::string> CommandLine);
194
195   /// Returns the given compile command.
196   ///
197   /// Will always return a vector with one entry that contains the directory
198   /// and command line specified at construction with "clang-tool" as argv[0]
199   /// and 'FilePath' as positional argument.
200   std::vector<CompileCommand>
201   getCompileCommands(StringRef FilePath) const override;
202
203 private:
204   /// This is built up to contain a single entry vector to be returned from
205   /// getCompileCommands after adding the positional argument.
206   std::vector<CompileCommand> CompileCommands;
207 };
208
209 /// Returns a wrapped CompilationDatabase that defers to the provided one,
210 /// but getCompileCommands() will infer commands for unknown files.
211 /// The return value of getAllFiles() or getAllCompileCommands() is unchanged.
212 /// See InterpolatingCompilationDatabase.cpp for details on heuristics.
213 std::unique_ptr<CompilationDatabase>
214     inferMissingCompileCommands(std::unique_ptr<CompilationDatabase>);
215
216 /// Returns a wrapped CompilationDatabase that will add -target and -mode flags
217 /// to commandline when they can be deduced from argv[0] of commandline returned
218 /// by underlying database.
219 std::unique_ptr<CompilationDatabase>
220 inferTargetAndDriverMode(std::unique_ptr<CompilationDatabase> Base);
221
222 } // namespace tooling
223 } // namespace clang
224
225 #endif // LLVM_CLANG_TOOLING_COMPILATIONDATABASE_H