Clang Project

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