FrontendAction.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===-- FrontendAction.h - Generic Frontend Action Interface ----*- 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. /// \file
  15. /// Defines the clang::FrontendAction interface and various convenience
  16. /// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
  17. /// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
  18. /// derived from it.
  19. ///
  20. //===----------------------------------------------------------------------===//
  21. #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
  22. #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
  23. #include "clang/AST/ASTConsumer.h"
  24. #include "clang/Basic/LLVM.h"
  25. #include "clang/Basic/LangOptions.h"
  26. #include "clang/Frontend/ASTUnit.h"
  27. #include "clang/Frontend/FrontendOptions.h"
  28. #include "llvm/ADT/StringRef.h"
  29. #include "llvm/Support/Error.h"
  30. #include <memory>
  31. #include <string>
  32. #include <vector>
  33. namespace clang {
  34. class ASTMergeAction;
  35. class CompilerInstance;
  36. /// Abstract base class for actions which can be performed by the frontend.
  37. class FrontendAction {
  38. FrontendInputFile CurrentInput;
  39. std::unique_ptr<ASTUnit> CurrentASTUnit;
  40. CompilerInstance *Instance;
  41. friend class ASTMergeAction;
  42. friend class WrapperFrontendAction;
  43. private:
  44. std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI,
  45. StringRef InFile);
  46. protected:
  47. /// @name Implementation Action Interface
  48. /// @{
  49. /// Prepare to execute the action on the given CompilerInstance.
  50. ///
  51. /// This is called before executing the action on any inputs, and can modify
  52. /// the configuration as needed (including adjusting the input list).
  53. virtual bool PrepareToExecuteAction(CompilerInstance &CI) { return true; }
  54. /// Create the AST consumer object for this action, if supported.
  55. ///
  56. /// This routine is called as part of BeginSourceFile(), which will
  57. /// fail if the AST consumer cannot be created. This will not be called if the
  58. /// action has indicated that it only uses the preprocessor.
  59. ///
  60. /// \param CI - The current compiler instance, provided as a convenience, see
  61. /// getCompilerInstance().
  62. ///
  63. /// \param InFile - The current input file, provided as a convenience, see
  64. /// getCurrentFile().
  65. ///
  66. /// \return The new AST consumer, or null on failure.
  67. virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
  68. StringRef InFile) = 0;
  69. /// Callback before starting processing a single input, giving the
  70. /// opportunity to modify the CompilerInvocation or do some other action
  71. /// before BeginSourceFileAction is called.
  72. ///
  73. /// \return True on success; on failure BeginSourceFileAction(),
  74. /// ExecuteAction() and EndSourceFileAction() will not be called.
  75. virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
  76. /// Callback at the start of processing a single input.
  77. ///
  78. /// \return True on success; on failure ExecutionAction() and
  79. /// EndSourceFileAction() will not be called.
  80. virtual bool BeginSourceFileAction(CompilerInstance &CI) {
  81. return true;
  82. }
  83. /// Callback to run the program action, using the initialized
  84. /// compiler instance.
  85. ///
  86. /// This is guaranteed to only be called between BeginSourceFileAction()
  87. /// and EndSourceFileAction().
  88. virtual void ExecuteAction() = 0;
  89. /// Callback at the end of processing a single input.
  90. ///
  91. /// This is guaranteed to only be called following a successful call to
  92. /// BeginSourceFileAction (and BeginSourceFile).
  93. virtual void EndSourceFileAction() {}
  94. /// Callback at the end of processing a single input, to determine
  95. /// if the output files should be erased or not.
  96. ///
  97. /// By default it returns true if a compiler error occurred.
  98. /// This is guaranteed to only be called following a successful call to
  99. /// BeginSourceFileAction (and BeginSourceFile).
  100. virtual bool shouldEraseOutputFiles();
  101. /// @}
  102. public:
  103. FrontendAction();
  104. virtual ~FrontendAction();
  105. /// @name Compiler Instance Access
  106. /// @{
  107. CompilerInstance &getCompilerInstance() const {
  108. assert(Instance && "Compiler instance not registered!");
  109. return *Instance;
  110. }
  111. void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
  112. /// @}
  113. /// @name Current File Information
  114. /// @{
  115. bool isCurrentFileAST() const {
  116. assert(!CurrentInput.isEmpty() && "No current file!");
  117. return (bool)CurrentASTUnit;
  118. }
  119. const FrontendInputFile &getCurrentInput() const {
  120. return CurrentInput;
  121. }
  122. StringRef getCurrentFile() const {
  123. assert(!CurrentInput.isEmpty() && "No current file!");
  124. return CurrentInput.getFile();
  125. }
  126. StringRef getCurrentFileOrBufferName() const {
  127. assert(!CurrentInput.isEmpty() && "No current file!");
  128. return CurrentInput.isFile()
  129. ? CurrentInput.getFile()
  130. : CurrentInput.getBuffer().getBufferIdentifier();
  131. }
  132. InputKind getCurrentFileKind() const {
  133. assert(!CurrentInput.isEmpty() && "No current file!");
  134. return CurrentInput.getKind();
  135. }
  136. ASTUnit &getCurrentASTUnit() const {
  137. assert(CurrentASTUnit && "No current AST unit!");
  138. return *CurrentASTUnit;
  139. }
  140. Module *getCurrentModule() const;
  141. std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
  142. return std::move(CurrentASTUnit);
  143. }
  144. void setCurrentInput(const FrontendInputFile &CurrentInput,
  145. std::unique_ptr<ASTUnit> AST = nullptr);
  146. /// @}
  147. /// @name Supported Modes
  148. /// @{
  149. /// Is this action invoked on a model file?
  150. ///
  151. /// Model files are incomplete translation units that relies on type
  152. /// information from another translation unit. Check ParseModelFileAction for
  153. /// details.
  154. virtual bool isModelParsingAction() const { return false; }
  155. /// Does this action only use the preprocessor?
  156. ///
  157. /// If so no AST context will be created and this action will be invalid
  158. /// with AST file inputs.
  159. virtual bool usesPreprocessorOnly() const = 0;
  160. /// For AST-based actions, the kind of translation unit we're handling.
  161. virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; }
  162. /// Does this action support use with PCH?
  163. virtual bool hasPCHSupport() const { return true; }
  164. /// Does this action support use with AST files?
  165. virtual bool hasASTFileSupport() const { return true; }
  166. /// Does this action support use with IR files?
  167. virtual bool hasIRSupport() const { return false; }
  168. /// Does this action support use with code completion?
  169. virtual bool hasCodeCompletionSupport() const { return false; }
  170. /// @}
  171. /// @name Public Action Interface
  172. /// @{
  173. /// Prepare the action to execute on the given compiler instance.
  174. bool PrepareToExecute(CompilerInstance &CI) {
  175. return PrepareToExecuteAction(CI);
  176. }
  177. /// Prepare the action for processing the input file \p Input.
  178. ///
  179. /// This is run after the options and frontend have been initialized,
  180. /// but prior to executing any per-file processing.
  181. ///
  182. /// \param CI - The compiler instance this action is being run from. The
  183. /// action may store and use this object up until the matching EndSourceFile
  184. /// action.
  185. ///
  186. /// \param Input - The input filename and kind. Some input kinds are handled
  187. /// specially, for example AST inputs, since the AST file itself contains
  188. /// several objects which would normally be owned by the
  189. /// CompilerInstance. When processing AST input files, these objects should
  190. /// generally not be initialized in the CompilerInstance -- they will
  191. /// automatically be shared with the AST file in between
  192. /// BeginSourceFile() and EndSourceFile().
  193. ///
  194. /// \return True on success; on failure the compilation of this file should
  195. /// be aborted and neither Execute() nor EndSourceFile() should be called.
  196. bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
  197. /// Set the source manager's main input file, and run the action.
  198. llvm::Error Execute();
  199. /// Perform any per-file post processing, deallocate per-file
  200. /// objects, and run statistics and output file cleanup code.
  201. virtual void EndSourceFile();
  202. /// @}
  203. };
  204. /// Abstract base class to use for AST consumer-based frontend actions.
  205. class ASTFrontendAction : public FrontendAction {
  206. protected:
  207. /// Implement the ExecuteAction interface by running Sema on
  208. /// the already-initialized AST consumer.
  209. ///
  210. /// This will also take care of instantiating a code completion consumer if
  211. /// the user requested it and the action supports it.
  212. void ExecuteAction() override;
  213. public:
  214. ASTFrontendAction() {}
  215. bool usesPreprocessorOnly() const override { return false; }
  216. };
  217. class PluginASTAction : public ASTFrontendAction {
  218. virtual void anchor();
  219. public:
  220. std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
  221. StringRef InFile) override = 0;
  222. /// Parse the given plugin command line arguments.
  223. ///
  224. /// \param CI - The compiler instance, for use in reporting diagnostics.
  225. /// \return True if the parsing succeeded; otherwise the plugin will be
  226. /// destroyed and no action run. The plugin is responsible for using the
  227. /// CompilerInstance's Diagnostic object to report errors.
  228. virtual bool ParseArgs(const CompilerInstance &CI,
  229. const std::vector<std::string> &arg) = 0;
  230. enum ActionType {
  231. CmdlineBeforeMainAction, ///< Execute the action before the main action if
  232. ///< on the command line
  233. CmdlineAfterMainAction, ///< Execute the action after the main action if on
  234. ///< the command line
  235. ReplaceAction, ///< Replace the main action
  236. AddBeforeMainAction, ///< Execute the action before the main action
  237. AddAfterMainAction ///< Execute the action after the main action
  238. };
  239. /// Get the action type for this plugin
  240. ///
  241. /// \return The action type. By default we use CmdlineAfterMainAction.
  242. virtual ActionType getActionType() { return CmdlineAfterMainAction; }
  243. };
  244. /// Abstract base class to use for preprocessor-based frontend actions.
  245. class PreprocessorFrontendAction : public FrontendAction {
  246. protected:
  247. /// Provide a default implementation which returns aborts;
  248. /// this method should never be called by FrontendAction clients.
  249. std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
  250. StringRef InFile) override;
  251. public:
  252. bool usesPreprocessorOnly() const override { return true; }
  253. };
  254. /// A frontend action which simply wraps some other runtime-specified
  255. /// frontend action.
  256. ///
  257. /// Deriving from this class allows an action to inject custom logic around
  258. /// some existing action's behavior. It implements every virtual method in
  259. /// the FrontendAction interface by forwarding to the wrapped action.
  260. class WrapperFrontendAction : public FrontendAction {
  261. protected:
  262. std::unique_ptr<FrontendAction> WrappedAction;
  263. bool PrepareToExecuteAction(CompilerInstance &CI) override;
  264. std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
  265. StringRef InFile) override;
  266. bool BeginInvocation(CompilerInstance &CI) override;
  267. bool BeginSourceFileAction(CompilerInstance &CI) override;
  268. void ExecuteAction() override;
  269. void EndSourceFile() override;
  270. void EndSourceFileAction() override;
  271. bool shouldEraseOutputFiles() override;
  272. public:
  273. /// Construct a WrapperFrontendAction from an existing action, taking
  274. /// ownership of it.
  275. WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction);
  276. bool usesPreprocessorOnly() const override;
  277. TranslationUnitKind getTranslationUnitKind() override;
  278. bool hasPCHSupport() const override;
  279. bool hasASTFileSupport() const override;
  280. bool hasIRSupport() const override;
  281. bool hasCodeCompletionSupport() const override;
  282. };
  283. } // end namespace clang
  284. #endif
  285. #ifdef __GNUC__
  286. #pragma GCC diagnostic pop
  287. #endif