Tooling.h 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- Tooling.h - Framework for standalone Clang tools ---------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // This file implements functions to run clang tools standalone instead
  15. // of running them as a plugin.
  16. //
  17. // A ClangTool is initialized with a CompilationDatabase and a set of files
  18. // to run over. The tool will then run a user-specified FrontendAction over
  19. // all TUs in which the given files are compiled.
  20. //
  21. // It is also possible to run a FrontendAction over a snippet of code by
  22. // calling runToolOnCode, which is useful for unit testing.
  23. //
  24. // Applications that need more fine grained control over how to run
  25. // multiple FrontendActions over code can use ToolInvocation.
  26. //
  27. // Example tools:
  28. // - running clang -fsyntax-only over source code from an editor to get
  29. // fast syntax checks
  30. // - running match/replace tools over C++ code
  31. //
  32. //===----------------------------------------------------------------------===//
  33. #ifndef LLVM_CLANG_TOOLING_TOOLING_H
  34. #define LLVM_CLANG_TOOLING_TOOLING_H
  35. #include "clang/AST/ASTConsumer.h"
  36. #include "clang/Basic/FileManager.h"
  37. #include "clang/Basic/LLVM.h"
  38. #include "clang/Frontend/FrontendAction.h"
  39. #include "clang/Frontend/PCHContainerOperations.h"
  40. #include "clang/Tooling/ArgumentsAdjusters.h"
  41. #include "llvm/ADT/ArrayRef.h"
  42. #include "llvm/ADT/IntrusiveRefCntPtr.h"
  43. #include "llvm/ADT/StringMap.h"
  44. #include "llvm/ADT/StringRef.h"
  45. #include "llvm/ADT/StringSet.h"
  46. #include "llvm/ADT/Twine.h"
  47. #include "llvm/Option/Option.h"
  48. #include "llvm/Support/VirtualFileSystem.h"
  49. #include <memory>
  50. #include <string>
  51. #include <utility>
  52. #include <vector>
  53. namespace clang {
  54. class CompilerInstance;
  55. class CompilerInvocation;
  56. class DiagnosticConsumer;
  57. class DiagnosticsEngine;
  58. namespace driver {
  59. class Compilation;
  60. } // namespace driver
  61. namespace tooling {
  62. class CompilationDatabase;
  63. /// Retrieves the flags of the `-cc1` job in `Compilation` that has only source
  64. /// files as its inputs.
  65. /// Returns nullptr if there are no such jobs or multiple of them. Note that
  66. /// offloading jobs are ignored.
  67. const llvm::opt::ArgStringList *
  68. getCC1Arguments(DiagnosticsEngine *Diagnostics,
  69. driver::Compilation *Compilation);
  70. /// Interface to process a clang::CompilerInvocation.
  71. ///
  72. /// If your tool is based on FrontendAction, you should be deriving from
  73. /// FrontendActionFactory instead.
  74. class ToolAction {
  75. public:
  76. virtual ~ToolAction();
  77. /// Perform an action for an invocation.
  78. virtual bool
  79. runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
  80. FileManager *Files,
  81. std::shared_ptr<PCHContainerOperations> PCHContainerOps,
  82. DiagnosticConsumer *DiagConsumer) = 0;
  83. };
  84. /// Interface to generate clang::FrontendActions.
  85. ///
  86. /// Having a factory interface allows, for example, a new FrontendAction to be
  87. /// created for each translation unit processed by ClangTool. This class is
  88. /// also a ToolAction which uses the FrontendActions created by create() to
  89. /// process each translation unit.
  90. class FrontendActionFactory : public ToolAction {
  91. public:
  92. ~FrontendActionFactory() override;
  93. /// Invokes the compiler with a FrontendAction created by create().
  94. bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
  95. FileManager *Files,
  96. std::shared_ptr<PCHContainerOperations> PCHContainerOps,
  97. DiagnosticConsumer *DiagConsumer) override;
  98. /// Returns a new clang::FrontendAction.
  99. virtual std::unique_ptr<FrontendAction> create() = 0;
  100. };
  101. /// Returns a new FrontendActionFactory for a given type.
  102. ///
  103. /// T must derive from clang::FrontendAction.
  104. ///
  105. /// Example:
  106. /// std::unique_ptr<FrontendActionFactory> Factory =
  107. /// newFrontendActionFactory<clang::SyntaxOnlyAction>();
  108. template <typename T>
  109. std::unique_ptr<FrontendActionFactory> newFrontendActionFactory();
  110. /// Callbacks called before and after each source file processed by a
  111. /// FrontendAction created by the FrontedActionFactory returned by \c
  112. /// newFrontendActionFactory.
  113. class SourceFileCallbacks {
  114. public:
  115. virtual ~SourceFileCallbacks() = default;
  116. /// Called before a source file is processed by a FrontEndAction.
  117. /// \see clang::FrontendAction::BeginSourceFileAction
  118. virtual bool handleBeginSource(CompilerInstance &CI) {
  119. return true;
  120. }
  121. /// Called after a source file is processed by a FrontendAction.
  122. /// \see clang::FrontendAction::EndSourceFileAction
  123. virtual void handleEndSource() {}
  124. };
  125. /// Returns a new FrontendActionFactory for any type that provides an
  126. /// implementation of newASTConsumer().
  127. ///
  128. /// FactoryT must implement: ASTConsumer *newASTConsumer().
  129. ///
  130. /// Example:
  131. /// struct ProvidesASTConsumers {
  132. /// std::unique_ptr<clang::ASTConsumer> newASTConsumer();
  133. /// } Factory;
  134. /// std::unique_ptr<FrontendActionFactory> FactoryAdapter(
  135. /// newFrontendActionFactory(&Factory));
  136. template <typename FactoryT>
  137. inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
  138. FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks = nullptr);
  139. /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag.
  140. ///
  141. /// \param ToolAction The action to run over the code.
  142. /// \param Code C++ code.
  143. /// \param FileName The file name which 'Code' will be mapped as.
  144. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  145. /// clang modules.
  146. ///
  147. /// \return - True if 'ToolAction' was successfully executed.
  148. bool runToolOnCode(std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
  149. const Twine &FileName = "input.cc",
  150. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  151. std::make_shared<PCHContainerOperations>());
  152. /// The first part of the pair is the filename, the second part the
  153. /// file-content.
  154. using FileContentMappings = std::vector<std::pair<std::string, std::string>>;
  155. /// Runs (and deletes) the tool on 'Code' with the -fsyntax-only flag and
  156. /// with additional other flags.
  157. ///
  158. /// \param ToolAction The action to run over the code.
  159. /// \param Code C++ code.
  160. /// \param Args Additional flags to pass on.
  161. /// \param FileName The file name which 'Code' will be mapped as.
  162. /// \param ToolName The name of the binary running the tool. Standard library
  163. /// header paths will be resolved relative to this.
  164. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  165. /// clang modules.
  166. ///
  167. /// \return - True if 'ToolAction' was successfully executed.
  168. bool runToolOnCodeWithArgs(
  169. std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
  170. const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
  171. const Twine &ToolName = "clang-tool",
  172. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  173. std::make_shared<PCHContainerOperations>(),
  174. const FileContentMappings &VirtualMappedFiles = FileContentMappings());
  175. // Similar to the overload except this takes a VFS.
  176. bool runToolOnCodeWithArgs(
  177. std::unique_ptr<FrontendAction> ToolAction, const Twine &Code,
  178. llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
  179. const std::vector<std::string> &Args, const Twine &FileName = "input.cc",
  180. const Twine &ToolName = "clang-tool",
  181. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  182. std::make_shared<PCHContainerOperations>());
  183. /// Builds an AST for 'Code'.
  184. ///
  185. /// \param Code C++ code.
  186. /// \param FileName The file name which 'Code' will be mapped as.
  187. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  188. /// clang modules.
  189. ///
  190. /// \return The resulting AST or null if an error occurred.
  191. std::unique_ptr<ASTUnit>
  192. buildASTFromCode(StringRef Code, StringRef FileName = "input.cc",
  193. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  194. std::make_shared<PCHContainerOperations>());
  195. /// Builds an AST for 'Code' with additional flags.
  196. ///
  197. /// \param Code C++ code.
  198. /// \param Args Additional flags to pass on.
  199. /// \param FileName The file name which 'Code' will be mapped as.
  200. /// \param ToolName The name of the binary running the tool. Standard library
  201. /// header paths will be resolved relative to this.
  202. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  203. /// clang modules.
  204. ///
  205. /// \param Adjuster A function to filter the command line arguments as specified.
  206. ///
  207. /// \return The resulting AST or null if an error occurred.
  208. std::unique_ptr<ASTUnit> buildASTFromCodeWithArgs(
  209. StringRef Code, const std::vector<std::string> &Args,
  210. StringRef FileName = "input.cc", StringRef ToolName = "clang-tool",
  211. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  212. std::make_shared<PCHContainerOperations>(),
  213. ArgumentsAdjuster Adjuster = getClangStripDependencyFileAdjuster(),
  214. const FileContentMappings &VirtualMappedFiles = FileContentMappings(),
  215. DiagnosticConsumer *DiagConsumer = nullptr);
  216. /// Utility to run a FrontendAction in a single clang invocation.
  217. class ToolInvocation {
  218. public:
  219. /// Create a tool invocation.
  220. ///
  221. /// \param CommandLine The command line arguments to clang. Note that clang
  222. /// uses its binary name (CommandLine[0]) to locate its builtin headers.
  223. /// Callers have to ensure that they are installed in a compatible location
  224. /// (see clang driver implementation) or mapped in via mapVirtualFile.
  225. /// \param FAction The action to be executed.
  226. /// \param Files The FileManager used for the execution. Class does not take
  227. /// ownership.
  228. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  229. /// clang modules.
  230. ToolInvocation(std::vector<std::string> CommandLine,
  231. std::unique_ptr<FrontendAction> FAction, FileManager *Files,
  232. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  233. std::make_shared<PCHContainerOperations>());
  234. /// Create a tool invocation.
  235. ///
  236. /// \param CommandLine The command line arguments to clang.
  237. /// \param Action The action to be executed.
  238. /// \param Files The FileManager used for the execution.
  239. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  240. /// clang modules.
  241. ToolInvocation(std::vector<std::string> CommandLine, ToolAction *Action,
  242. FileManager *Files,
  243. std::shared_ptr<PCHContainerOperations> PCHContainerOps);
  244. ~ToolInvocation();
  245. /// Set a \c DiagnosticConsumer to use during driver command-line parsing and
  246. /// the action invocation itself.
  247. void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
  248. this->DiagConsumer = DiagConsumer;
  249. }
  250. /// Set a \c DiagnosticOptions to use during driver command-line parsing.
  251. void setDiagnosticOptions(DiagnosticOptions *DiagOpts) {
  252. this->DiagOpts = DiagOpts;
  253. }
  254. /// Run the clang invocation.
  255. ///
  256. /// \returns True if there were no errors during execution.
  257. bool run();
  258. private:
  259. bool runInvocation(const char *BinaryName,
  260. driver::Compilation *Compilation,
  261. std::shared_ptr<CompilerInvocation> Invocation,
  262. std::shared_ptr<PCHContainerOperations> PCHContainerOps);
  263. std::vector<std::string> CommandLine;
  264. ToolAction *Action;
  265. bool OwnsAction;
  266. FileManager *Files;
  267. std::shared_ptr<PCHContainerOperations> PCHContainerOps;
  268. DiagnosticConsumer *DiagConsumer = nullptr;
  269. DiagnosticOptions *DiagOpts = nullptr;
  270. };
  271. /// Utility to run a FrontendAction over a set of files.
  272. ///
  273. /// This class is written to be usable for command line utilities.
  274. /// By default the class uses ClangSyntaxOnlyAdjuster to modify
  275. /// command line arguments before the arguments are used to run
  276. /// a frontend action. One could install an additional command line
  277. /// arguments adjuster by calling the appendArgumentsAdjuster() method.
  278. class ClangTool {
  279. public:
  280. /// Constructs a clang tool to run over a list of files.
  281. ///
  282. /// \param Compilations The CompilationDatabase which contains the compile
  283. /// command lines for the given source paths.
  284. /// \param SourcePaths The source files to run over. If a source files is
  285. /// not found in Compilations, it is skipped.
  286. /// \param PCHContainerOps The PCHContainerOperations for loading and creating
  287. /// clang modules.
  288. /// \param BaseFS VFS used for all underlying file accesses when running the
  289. /// tool.
  290. /// \param Files The file manager to use for underlying file operations when
  291. /// running the tool.
  292. ClangTool(const CompilationDatabase &Compilations,
  293. ArrayRef<std::string> SourcePaths,
  294. std::shared_ptr<PCHContainerOperations> PCHContainerOps =
  295. std::make_shared<PCHContainerOperations>(),
  296. IntrusiveRefCntPtr<llvm::vfs::FileSystem> BaseFS =
  297. llvm::vfs::getRealFileSystem(),
  298. IntrusiveRefCntPtr<FileManager> Files = nullptr);
  299. ~ClangTool();
  300. /// Set a \c DiagnosticConsumer to use during parsing.
  301. void setDiagnosticConsumer(DiagnosticConsumer *DiagConsumer) {
  302. this->DiagConsumer = DiagConsumer;
  303. }
  304. /// Map a virtual file to be used while running the tool.
  305. ///
  306. /// \param FilePath The path at which the content will be mapped.
  307. /// \param Content A null terminated buffer of the file's content.
  308. void mapVirtualFile(StringRef FilePath, StringRef Content);
  309. /// Append a command line arguments adjuster to the adjuster chain.
  310. ///
  311. /// \param Adjuster An argument adjuster, which will be run on the output of
  312. /// previous argument adjusters.
  313. void appendArgumentsAdjuster(ArgumentsAdjuster Adjuster);
  314. /// Clear the command line arguments adjuster chain.
  315. void clearArgumentsAdjusters();
  316. /// Runs an action over all files specified in the command line.
  317. ///
  318. /// \param Action Tool action.
  319. ///
  320. /// \returns 0 on success; 1 if any error occurred; 2 if there is no error but
  321. /// some files are skipped due to missing compile commands.
  322. int run(ToolAction *Action);
  323. /// Create an AST for each file specified in the command line and
  324. /// append them to ASTs.
  325. int buildASTs(std::vector<std::unique_ptr<ASTUnit>> &ASTs);
  326. /// Sets whether working directory should be restored after calling run(). By
  327. /// default, working directory is restored. However, it could be useful to
  328. /// turn this off when running on multiple threads to avoid the raciness.
  329. void setRestoreWorkingDir(bool RestoreCWD);
  330. /// Sets whether an error message should be printed out if an action fails. By
  331. /// default, if an action fails, a message is printed out to stderr.
  332. void setPrintErrorMessage(bool PrintErrorMessage);
  333. /// Returns the file manager used in the tool.
  334. ///
  335. /// The file manager is shared between all translation units.
  336. FileManager &getFiles() { return *Files; }
  337. llvm::ArrayRef<std::string> getSourcePaths() const { return SourcePaths; }
  338. private:
  339. const CompilationDatabase &Compilations;
  340. std::vector<std::string> SourcePaths;
  341. std::shared_ptr<PCHContainerOperations> PCHContainerOps;
  342. llvm::IntrusiveRefCntPtr<llvm::vfs::OverlayFileSystem> OverlayFileSystem;
  343. llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem;
  344. llvm::IntrusiveRefCntPtr<FileManager> Files;
  345. // Contains a list of pairs (<file name>, <file content>).
  346. std::vector<std::pair<StringRef, StringRef>> MappedFileContents;
  347. llvm::StringSet<> SeenWorkingDirectories;
  348. ArgumentsAdjuster ArgsAdjuster;
  349. DiagnosticConsumer *DiagConsumer = nullptr;
  350. bool RestoreCWD = true;
  351. bool PrintErrorMessage = true;
  352. };
  353. template <typename T>
  354. std::unique_ptr<FrontendActionFactory> newFrontendActionFactory() {
  355. class SimpleFrontendActionFactory : public FrontendActionFactory {
  356. public:
  357. std::unique_ptr<FrontendAction> create() override {
  358. return std::make_unique<T>();
  359. }
  360. };
  361. return std::unique_ptr<FrontendActionFactory>(
  362. new SimpleFrontendActionFactory);
  363. }
  364. template <typename FactoryT>
  365. inline std::unique_ptr<FrontendActionFactory> newFrontendActionFactory(
  366. FactoryT *ConsumerFactory, SourceFileCallbacks *Callbacks) {
  367. class FrontendActionFactoryAdapter : public FrontendActionFactory {
  368. public:
  369. explicit FrontendActionFactoryAdapter(FactoryT *ConsumerFactory,
  370. SourceFileCallbacks *Callbacks)
  371. : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
  372. std::unique_ptr<FrontendAction> create() override {
  373. return std::make_unique<ConsumerFactoryAdaptor>(ConsumerFactory,
  374. Callbacks);
  375. }
  376. private:
  377. class ConsumerFactoryAdaptor : public ASTFrontendAction {
  378. public:
  379. ConsumerFactoryAdaptor(FactoryT *ConsumerFactory,
  380. SourceFileCallbacks *Callbacks)
  381. : ConsumerFactory(ConsumerFactory), Callbacks(Callbacks) {}
  382. std::unique_ptr<ASTConsumer>
  383. CreateASTConsumer(CompilerInstance &, StringRef) override {
  384. return ConsumerFactory->newASTConsumer();
  385. }
  386. protected:
  387. bool BeginSourceFileAction(CompilerInstance &CI) override {
  388. if (!ASTFrontendAction::BeginSourceFileAction(CI))
  389. return false;
  390. if (Callbacks)
  391. return Callbacks->handleBeginSource(CI);
  392. return true;
  393. }
  394. void EndSourceFileAction() override {
  395. if (Callbacks)
  396. Callbacks->handleEndSource();
  397. ASTFrontendAction::EndSourceFileAction();
  398. }
  399. private:
  400. FactoryT *ConsumerFactory;
  401. SourceFileCallbacks *Callbacks;
  402. };
  403. FactoryT *ConsumerFactory;
  404. SourceFileCallbacks *Callbacks;
  405. };
  406. return std::unique_ptr<FrontendActionFactory>(
  407. new FrontendActionFactoryAdapter(ConsumerFactory, Callbacks));
  408. }
  409. /// Returns the absolute path of \c File, by prepending it with
  410. /// the current directory if \c File is not absolute.
  411. ///
  412. /// Otherwise returns \c File.
  413. /// If 'File' starts with "./", the returned path will not contain the "./".
  414. /// Otherwise, the returned path will contain the literal path-concatenation of
  415. /// the current directory and \c File.
  416. ///
  417. /// The difference to llvm::sys::fs::make_absolute is the canonicalization this
  418. /// does by removing "./" and computing native paths.
  419. ///
  420. /// \param File Either an absolute or relative path.
  421. std::string getAbsolutePath(StringRef File);
  422. /// An overload of getAbsolutePath that works over the provided \p FS.
  423. llvm::Expected<std::string> getAbsolutePath(llvm::vfs::FileSystem &FS,
  424. StringRef File);
  425. /// Changes CommandLine to contain implicit flags that would have been
  426. /// defined had the compiler driver been invoked through the path InvokedAs.
  427. ///
  428. /// For example, when called with \c InvokedAs set to `i686-linux-android-g++`,
  429. /// the arguments '-target', 'i686-linux-android`, `--driver-mode=g++` will
  430. /// be inserted after the first argument in \c CommandLine.
  431. ///
  432. /// This function will not add new `-target` or `--driver-mode` flags if they
  433. /// are already present in `CommandLine` (even if they have different settings
  434. /// than would have been inserted).
  435. ///
  436. /// \pre `llvm::InitializeAllTargets()` has been called.
  437. ///
  438. /// \param CommandLine the command line used to invoke the compiler driver or
  439. /// Clang tool, including the path to the executable as \c CommandLine[0].
  440. /// \param InvokedAs the path to the driver used to infer implicit flags.
  441. ///
  442. /// \note This will not set \c CommandLine[0] to \c InvokedAs. The tooling
  443. /// infrastructure expects that CommandLine[0] is a tool path relative to which
  444. /// the builtin headers can be found.
  445. void addTargetAndModeForProgramName(std::vector<std::string> &CommandLine,
  446. StringRef InvokedAs);
  447. /// Creates a \c CompilerInvocation.
  448. CompilerInvocation *newInvocation(DiagnosticsEngine *Diagnostics,
  449. ArrayRef<const char *> CC1Args,
  450. const char *const BinaryName);
  451. } // namespace tooling
  452. } // namespace clang
  453. #endif // LLVM_CLANG_TOOLING_TOOLING_H
  454. #ifdef __GNUC__
  455. #pragma GCC diagnostic pop
  456. #endif