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). PrepareToExecuteAction(CompilerInstance & CI)55 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. BeginInvocation(CompilerInstance & CI)79 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. BeginSourceFileAction(CompilerInstance & CI)85 virtual bool BeginSourceFileAction(CompilerInstance &CI) { 86 return true; 87 } 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). EndSourceFileAction()100 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 getCompilerInstance()119 CompilerInstance &getCompilerInstance() const { 120 assert(Instance && "Compiler instance not registered!"); 121 return *Instance; 122 } 123 setCompilerInstance(CompilerInstance * Value)124 void setCompilerInstance(CompilerInstance *Value) { Instance = Value; } 125 126 /// @} 127 /// @name Current File Information 128 /// @{ 129 isCurrentFileAST()130 bool isCurrentFileAST() const { 131 assert(!CurrentInput.isEmpty() && "No current file!"); 132 return (bool)CurrentASTUnit; 133 } 134 getCurrentInput()135 const FrontendInputFile &getCurrentInput() const { 136 return CurrentInput; 137 } 138 getCurrentFile()139 StringRef getCurrentFile() const { 140 assert(!CurrentInput.isEmpty() && "No current file!"); 141 return CurrentInput.getFile(); 142 } 143 getCurrentFileOrBufferName()144 StringRef getCurrentFileOrBufferName() const { 145 assert(!CurrentInput.isEmpty() && "No current file!"); 146 return CurrentInput.isFile() 147 ? CurrentInput.getFile() 148 : CurrentInput.getBuffer().getBufferIdentifier(); 149 } 150 getCurrentFileKind()151 InputKind getCurrentFileKind() const { 152 assert(!CurrentInput.isEmpty() && "No current file!"); 153 return CurrentInput.getKind(); 154 } 155 getCurrentASTUnit()156 ASTUnit &getCurrentASTUnit() const { 157 assert(CurrentASTUnit && "No current AST unit!"); 158 return *CurrentASTUnit; 159 } 160 161 Module *getCurrentModule() const; 162 takeCurrentASTUnit()163 std::unique_ptr<ASTUnit> takeCurrentASTUnit() { 164 return std::move(CurrentASTUnit); 165 } 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. isModelParsingAction()179 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. getTranslationUnitKind()188 virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } 189 190 /// Does this action support use with PCH? hasPCHSupport()191 virtual bool hasPCHSupport() const { return true; } 192 193 /// Does this action support use with AST files? hasASTFileSupport()194 virtual bool hasASTFileSupport() const { return true; } 195 196 /// Does this action support use with IR files? hasIRSupport()197 virtual bool hasIRSupport() const { return false; } 198 199 /// Does this action support use with code completion? hasCodeCompletionSupport()200 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. PrepareToExecute(CompilerInstance & CI)207 bool PrepareToExecute(CompilerInstance &CI) { 208 return PrepareToExecuteAction(CI); 209 } 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: ASTFrontendAction()253 ASTFrontendAction() {} usesPreprocessorOnly()254 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. getActionType()284 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: usesPreprocessorOnly()296 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 335