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