Coverage Report

Created: 2023-11-11 10:31

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