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