Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:36:55

0001 //===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 ///
0009 /// \file
0010 /// Defines the clang::FrontendAction interface and various convenience
0011 /// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction,
0012 /// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction)
0013 /// derived from it.
0014 ///
0015 //===----------------------------------------------------------------------===//
0016 
0017 #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H
0018 #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H
0019 
0020 #include "clang/AST/ASTConsumer.h"
0021 #include "clang/Basic/LLVM.h"
0022 #include "clang/Basic/LangOptions.h"
0023 #include "clang/Frontend/ASTUnit.h"
0024 #include "clang/Frontend/CompilerInstance.h"
0025 #include "clang/Frontend/FrontendOptions.h"
0026 #include "llvm/ADT/StringRef.h"
0027 #include "llvm/Support/Error.h"
0028 #include <memory>
0029 #include <string>
0030 #include <vector>
0031 
0032 namespace clang {
0033 class ASTMergeAction;
0034 class CompilerInstance;
0035 
0036 /// Abstract base class for actions which can be performed by the frontend.
0037 class FrontendAction {
0038   FrontendInputFile CurrentInput;
0039   std::unique_ptr<ASTUnit> CurrentASTUnit;
0040   CompilerInstance *Instance;
0041   friend class ASTMergeAction;
0042   friend class WrapperFrontendAction;
0043 
0044 private:
0045   std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI,
0046                                                         StringRef InFile);
0047 
0048 protected:
0049   /// @name Implementation Action Interface
0050   /// @{
0051 
0052   /// Prepare to execute the action on the given CompilerInstance.
0053   ///
0054   /// This is called before executing the action on any inputs, and can modify
0055   /// the configuration as needed (including adjusting the input list).
0056   virtual bool PrepareToExecuteAction(CompilerInstance &CI) { return true; }
0057 
0058   /// Create the AST consumer object for this action, if supported.
0059   ///
0060   /// This routine is called as part of BeginSourceFile(), which will
0061   /// fail if the AST consumer cannot be created. This will not be called if the
0062   /// action has indicated that it only uses the preprocessor.
0063   ///
0064   /// \param CI - The current compiler instance, provided as a convenience, see
0065   /// getCompilerInstance().
0066   ///
0067   /// \param InFile - The current input file, provided as a convenience, see
0068   /// getCurrentFile().
0069   ///
0070   /// \return The new AST consumer, or null on failure.
0071   virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
0072                                                          StringRef InFile) = 0;
0073 
0074   /// Callback before starting processing a single input, giving the
0075   /// opportunity to modify the CompilerInvocation or do some other action
0076   /// before BeginSourceFileAction is called.
0077   ///
0078   /// \return True on success; on failure BeginSourceFileAction(),
0079   /// ExecuteAction() and EndSourceFileAction() will not be called.
0080   virtual bool BeginInvocation(CompilerInstance &CI) { return true; }
0081 
0082   /// Callback at the start of processing a single input.
0083   ///
0084   /// \return True on success; on failure ExecutionAction() and
0085   /// EndSourceFileAction() will not be called.
0086   virtual bool BeginSourceFileAction(CompilerInstance &CI) {
0087     return true;
0088   }
0089 
0090   /// Callback to run the program action, using the initialized
0091   /// compiler instance.
0092   ///
0093   /// This is guaranteed to only be called between BeginSourceFileAction()
0094   /// and EndSourceFileAction().
0095   virtual void ExecuteAction() = 0;
0096 
0097   /// Callback at the end of processing a single input.
0098   ///
0099   /// This is guaranteed to only be called following a successful call to
0100   /// BeginSourceFileAction (and BeginSourceFile).
0101   virtual void EndSourceFileAction() {}
0102 
0103   /// Callback at the end of processing a single input, to determine
0104   /// if the output files should be erased or not.
0105   ///
0106   /// By default it returns true if a compiler error occurred.
0107   /// This is guaranteed to only be called following a successful call to
0108   /// BeginSourceFileAction (and BeginSourceFile).
0109   virtual bool shouldEraseOutputFiles();
0110 
0111   /// @}
0112 
0113 public:
0114   FrontendAction();
0115   virtual ~FrontendAction();
0116 
0117   /// @name Compiler Instance Access
0118   /// @{
0119 
0120   CompilerInstance &getCompilerInstance() const {
0121     assert(Instance && "Compiler instance not registered!");
0122     return *Instance;
0123   }
0124 
0125   void setCompilerInstance(CompilerInstance *Value) { Instance = Value; }
0126 
0127   /// @}
0128   /// @name Current File Information
0129   /// @{
0130 
0131   bool isCurrentFileAST() const {
0132     assert(!CurrentInput.isEmpty() && "No current file!");
0133     return (bool)CurrentASTUnit;
0134   }
0135 
0136   const FrontendInputFile &getCurrentInput() const {
0137     return CurrentInput;
0138   }
0139 
0140   StringRef getCurrentFile() const {
0141     assert(!CurrentInput.isEmpty() && "No current file!");
0142     return CurrentInput.getFile();
0143   }
0144 
0145   StringRef getCurrentFileOrBufferName() const {
0146     assert(!CurrentInput.isEmpty() && "No current file!");
0147     return CurrentInput.isFile()
0148                ? CurrentInput.getFile()
0149                : CurrentInput.getBuffer().getBufferIdentifier();
0150   }
0151 
0152   InputKind getCurrentFileKind() const {
0153     assert(!CurrentInput.isEmpty() && "No current file!");
0154     return CurrentInput.getKind();
0155   }
0156 
0157   ASTUnit &getCurrentASTUnit() const {
0158     assert(CurrentASTUnit && "No current AST unit!");
0159     return *CurrentASTUnit;
0160   }
0161 
0162   Module *getCurrentModule() const;
0163 
0164   std::unique_ptr<ASTUnit> takeCurrentASTUnit() {
0165     return std::move(CurrentASTUnit);
0166   }
0167 
0168   void setCurrentInput(const FrontendInputFile &CurrentInput,
0169                        std::unique_ptr<ASTUnit> AST = nullptr);
0170 
0171   /// @}
0172   /// @name Supported Modes
0173   /// @{
0174 
0175   /// Is this action invoked on a model file?
0176   ///
0177   /// Model files are incomplete translation units that relies on type
0178   /// information from another translation unit. Check ParseModelFileAction for
0179   /// details.
0180   virtual bool isModelParsingAction() const { return false; }
0181 
0182   /// Does this action only use the preprocessor?
0183   ///
0184   /// If so no AST context will be created and this action will be invalid
0185   /// with AST file inputs.
0186   virtual bool usesPreprocessorOnly() const = 0;
0187 
0188   /// For AST-based actions, the kind of translation unit we're handling.
0189   virtual TranslationUnitKind getTranslationUnitKind() {
0190     // The ASTContext, if exists, knows the exact TUKind of the frondend.
0191     if (Instance && Instance->hasASTContext())
0192       return Instance->getASTContext().TUKind;
0193     return TU_Complete;
0194   }
0195 
0196   /// Does this action support use with PCH?
0197   virtual bool hasPCHSupport() const { return true; }
0198 
0199   /// Does this action support use with AST files?
0200   virtual bool hasASTFileSupport() const { return true; }
0201 
0202   /// Does this action support use with IR files?
0203   virtual bool hasIRSupport() const { return false; }
0204 
0205   /// Does this action support use with code completion?
0206   virtual bool hasCodeCompletionSupport() const { return false; }
0207 
0208   /// @}
0209   /// @name Public Action Interface
0210   /// @{
0211 
0212   /// Prepare the action to execute on the given compiler instance.
0213   bool PrepareToExecute(CompilerInstance &CI) {
0214     return PrepareToExecuteAction(CI);
0215   }
0216 
0217   /// Prepare the action for processing the input file \p Input.
0218   ///
0219   /// This is run after the options and frontend have been initialized,
0220   /// but prior to executing any per-file processing.
0221   ///
0222   /// \param CI - The compiler instance this action is being run from. The
0223   /// action may store and use this object up until the matching EndSourceFile
0224   /// action.
0225   ///
0226   /// \param Input - The input filename and kind. Some input kinds are handled
0227   /// specially, for example AST inputs, since the AST file itself contains
0228   /// several objects which would normally be owned by the
0229   /// CompilerInstance. When processing AST input files, these objects should
0230   /// generally not be initialized in the CompilerInstance -- they will
0231   /// automatically be shared with the AST file in between
0232   /// BeginSourceFile() and EndSourceFile().
0233   ///
0234   /// \return True on success; on failure the compilation of this file should
0235   /// be aborted and neither Execute() nor EndSourceFile() should be called.
0236   bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input);
0237 
0238   /// Set the source manager's main input file, and run the action.
0239   llvm::Error Execute();
0240 
0241   /// Perform any per-file post processing, deallocate per-file
0242   /// objects, and run statistics and output file cleanup code.
0243   virtual void EndSourceFile();
0244 
0245   /// @}
0246 };
0247 
0248 /// Abstract base class to use for AST consumer-based frontend actions.
0249 class ASTFrontendAction : public FrontendAction {
0250 protected:
0251   /// Implement the ExecuteAction interface by running Sema on
0252   /// the already-initialized AST consumer.
0253   ///
0254   /// This will also take care of instantiating a code completion consumer if
0255   /// the user requested it and the action supports it.
0256   void ExecuteAction() override;
0257 
0258 public:
0259   ASTFrontendAction() {}
0260   bool usesPreprocessorOnly() const override { return false; }
0261 };
0262 
0263 class PluginASTAction : public ASTFrontendAction {
0264   virtual void anchor();
0265 public:
0266   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
0267                                                  StringRef InFile) override = 0;
0268 
0269   /// Parse the given plugin command line arguments.
0270   ///
0271   /// \param CI - The compiler instance, for use in reporting diagnostics.
0272   /// \return True if the parsing succeeded; otherwise the plugin will be
0273   /// destroyed and no action run. The plugin is responsible for using the
0274   /// CompilerInstance's Diagnostic object to report errors.
0275   virtual bool ParseArgs(const CompilerInstance &CI,
0276                          const std::vector<std::string> &arg) = 0;
0277 
0278   enum ActionType {
0279     CmdlineBeforeMainAction, ///< Execute the action before the main action if
0280                              ///< on the command line
0281     CmdlineAfterMainAction,  ///< Execute the action after the main action if on
0282                              ///< the command line
0283     ReplaceAction,           ///< Replace the main action
0284     AddBeforeMainAction,     ///< Execute the action before the main action
0285     AddAfterMainAction       ///< Execute the action after the main action
0286   };
0287   /// Get the action type for this plugin
0288   ///
0289   /// \return The action type. By default we use CmdlineAfterMainAction.
0290   virtual ActionType getActionType() { return CmdlineAfterMainAction; }
0291 };
0292 
0293 /// Abstract base class to use for preprocessor-based frontend actions.
0294 class PreprocessorFrontendAction : public FrontendAction {
0295 protected:
0296   /// Provide a default implementation which returns aborts;
0297   /// this method should never be called by FrontendAction clients.
0298   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
0299                                                  StringRef InFile) override;
0300 
0301 public:
0302   bool usesPreprocessorOnly() const override { return true; }
0303 };
0304 
0305 /// A frontend action which simply wraps some other runtime-specified
0306 /// frontend action.
0307 ///
0308 /// Deriving from this class allows an action to inject custom logic around
0309 /// some existing action's behavior. It implements every virtual method in
0310 /// the FrontendAction interface by forwarding to the wrapped action.
0311 class WrapperFrontendAction : public FrontendAction {
0312 protected:
0313   std::unique_ptr<FrontendAction> WrappedAction;
0314 
0315   bool PrepareToExecuteAction(CompilerInstance &CI) override;
0316   std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
0317                                                  StringRef InFile) override;
0318   bool BeginInvocation(CompilerInstance &CI) override;
0319   bool BeginSourceFileAction(CompilerInstance &CI) override;
0320   void ExecuteAction() override;
0321   void EndSourceFile() override;
0322   void EndSourceFileAction() override;
0323   bool shouldEraseOutputFiles() override;
0324 
0325 public:
0326   /// Construct a WrapperFrontendAction from an existing action, taking
0327   /// ownership of it.
0328   WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction);
0329 
0330   bool usesPreprocessorOnly() const override;
0331   TranslationUnitKind getTranslationUnitKind() override;
0332   bool hasPCHSupport() const override;
0333   bool hasASTFileSupport() const override;
0334   bool hasIRSupport() const override;
0335   bool hasCodeCompletionSupport() const override;
0336 };
0337 
0338 }  // end namespace clang
0339 
0340 #endif