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/Basic/LLVM.h" 22 #include "clang/Basic/LangOptions.h" 23 #include "clang/Frontend/FrontendOptions.h" 24 #include "llvm/ADT/OwningPtr.h" 25 #include "llvm/ADT/StringRef.h" 26 #include <string> 27 #include <vector> 28 29 namespace clang { 30 class ASTConsumer; 31 class ASTMergeAction; 32 class ASTUnit; 33 class CompilerInstance; 34 35 /// Abstract base class for actions which can be performed by the frontend. 36 class FrontendAction { 37 FrontendInputFile CurrentInput; 38 OwningPtr<ASTUnit> CurrentASTUnit; 39 CompilerInstance *Instance; 40 friend class ASTMergeAction; 41 friend class WrapperFrontendAction; 42 43 private: 44 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 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. BeginInvocation(CompilerInstance & CI)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. BeginSourceFileAction(CompilerInstance & CI,StringRef Filename)79 virtual bool BeginSourceFileAction(CompilerInstance &CI, 80 StringRef Filename) { 81 return true; 82 } 83 84 /// \brief Callback to run the program action, using the initialized 85 /// compiler instance. 86 /// 87 /// This is guaranteed to only be called between BeginSourceFileAction() 88 /// and EndSourceFileAction(). 89 virtual void ExecuteAction() = 0; 90 91 /// \brief Callback at the end of processing a single input. 92 /// 93 /// This is guaranteed to only be called following a successful call to 94 /// BeginSourceFileAction (and BeginSourceFile). EndSourceFileAction()95 virtual void EndSourceFileAction() {} 96 97 /// @} 98 99 public: 100 FrontendAction(); 101 virtual ~FrontendAction(); 102 103 /// @name Compiler Instance Access 104 /// @{ 105 getCompilerInstance()106 CompilerInstance &getCompilerInstance() const { 107 assert(Instance && "Compiler instance not registered!"); 108 return *Instance; 109 } 110 setCompilerInstance(CompilerInstance * Value)111 void setCompilerInstance(CompilerInstance *Value) { Instance = Value; } 112 113 /// @} 114 /// @name Current File Information 115 /// @{ 116 isCurrentFileAST()117 bool isCurrentFileAST() const { 118 assert(!CurrentInput.isEmpty() && "No current file!"); 119 return CurrentASTUnit != 0; 120 } 121 getCurrentInput()122 const FrontendInputFile &getCurrentInput() const { 123 return CurrentInput; 124 } 125 getCurrentFile()126 const StringRef getCurrentFile() const { 127 assert(!CurrentInput.isEmpty() && "No current file!"); 128 return CurrentInput.getFile(); 129 } 130 getCurrentFileKind()131 InputKind getCurrentFileKind() const { 132 assert(!CurrentInput.isEmpty() && "No current file!"); 133 return CurrentInput.getKind(); 134 } 135 getCurrentASTUnit()136 ASTUnit &getCurrentASTUnit() const { 137 assert(CurrentASTUnit && "No current AST unit!"); 138 return *CurrentASTUnit; 139 } 140 takeCurrentASTUnit()141 ASTUnit *takeCurrentASTUnit() { 142 return CurrentASTUnit.take(); 143 } 144 145 void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0); 146 147 /// @} 148 /// @name Supported Modes 149 /// @{ 150 151 /// \brief Does this action only use the preprocessor? 152 /// 153 /// If so no AST context will be created and this action will be invalid 154 /// with AST file inputs. 155 virtual bool usesPreprocessorOnly() const = 0; 156 157 /// \brief For AST-based actions, the kind of translation unit we're handling. getTranslationUnitKind()158 virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } 159 160 /// \brief Does this action support use with PCH? hasPCHSupport()161 virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } 162 163 /// \brief Does this action support use with AST files? hasASTFileSupport()164 virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); } 165 166 /// \brief Does this action support use with IR files? hasIRSupport()167 virtual bool hasIRSupport() const { return false; } 168 169 /// \brief Does this action support use with code completion? hasCodeCompletionSupport()170 virtual bool hasCodeCompletionSupport() const { return false; } 171 172 /// @} 173 /// @name Public Action Interface 174 /// @{ 175 176 /// \brief Prepare the action for processing the input file \p Input. 177 /// 178 /// This is run after the options and frontend have been initialized, 179 /// but prior to executing any per-file processing. 180 /// 181 /// \param CI - The compiler instance this action is being run from. The 182 /// action may store and use this object up until the matching EndSourceFile 183 /// action. 184 /// 185 /// \param Input - The input filename and kind. Some input kinds are handled 186 /// specially, for example AST inputs, since the AST file itself contains 187 /// several objects which would normally be owned by the 188 /// CompilerInstance. When processing AST input files, these objects should 189 /// generally not be initialized in the CompilerInstance -- they will 190 /// automatically be shared with the AST file in between 191 /// BeginSourceFile() and EndSourceFile(). 192 /// 193 /// \return True on success; on failure the compilation of this file should 194 /// be aborted and neither Execute() nor EndSourceFile() should be called. 195 bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input); 196 197 /// \brief Set the source manager's main input file, and run the action. 198 bool Execute(); 199 200 /// \brief Perform any per-file post processing, deallocate per-file 201 /// objects, and run statistics and output file cleanup code. 202 void EndSourceFile(); 203 204 /// @} 205 }; 206 207 /// \brief Abstract base class to use for AST consumer-based frontend actions. 208 class ASTFrontendAction : public FrontendAction { 209 protected: 210 /// \brief Implement the ExecuteAction interface by running Sema on 211 /// the already-initialized AST consumer. 212 /// 213 /// This will also take care of instantiating a code completion consumer if 214 /// the user requested it and the action supports it. 215 virtual void ExecuteAction(); 216 217 public: usesPreprocessorOnly()218 virtual bool usesPreprocessorOnly() const { return false; } 219 }; 220 221 class PluginASTAction : public ASTFrontendAction { 222 virtual void anchor(); 223 protected: 224 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 225 StringRef InFile) = 0; 226 227 public: 228 /// \brief Parse the given plugin command line arguments. 229 /// 230 /// \param CI - The compiler instance, for use in reporting diagnostics. 231 /// \return True if the parsing succeeded; otherwise the plugin will be 232 /// destroyed and no action run. The plugin is responsible for using the 233 /// CompilerInstance's Diagnostic object to report errors. 234 virtual bool ParseArgs(const CompilerInstance &CI, 235 const std::vector<std::string> &arg) = 0; 236 }; 237 238 /// \brief Abstract base class to use for preprocessor-based frontend actions. 239 class PreprocessorFrontendAction : public FrontendAction { 240 protected: 241 /// \brief Provide a default implementation which returns aborts; 242 /// this method should never be called by FrontendAction clients. 243 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 244 StringRef InFile); 245 246 public: usesPreprocessorOnly()247 virtual bool usesPreprocessorOnly() const { return true; } 248 }; 249 250 /// \brief A frontend action which simply wraps some other runtime-specified 251 /// frontend action. 252 /// 253 /// Deriving from this class allows an action to inject custom logic around 254 /// some existing action's behavior. It implements every virtual method in 255 /// the FrontendAction interface by forwarding to the wrapped action. 256 class WrapperFrontendAction : public FrontendAction { 257 OwningPtr<FrontendAction> WrappedAction; 258 259 protected: 260 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 261 StringRef InFile); 262 virtual bool BeginInvocation(CompilerInstance &CI); 263 virtual bool BeginSourceFileAction(CompilerInstance &CI, 264 StringRef Filename); 265 virtual void ExecuteAction(); 266 virtual void EndSourceFileAction(); 267 268 public: 269 /// Construct a WrapperFrontendAction from an existing action, taking 270 /// ownership of it. 271 WrapperFrontendAction(FrontendAction *WrappedAction); 272 273 virtual bool usesPreprocessorOnly() const; 274 virtual TranslationUnitKind getTranslationUnitKind(); 275 virtual bool hasPCHSupport() const; 276 virtual bool hasASTFileSupport() const; 277 virtual bool hasIRSupport() const; 278 virtual bool hasCodeCompletionSupport() const; 279 }; 280 281 } // end namespace clang 282 283 #endif 284