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 #ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H 11 #define LLVM_CLANG_FRONTEND_FRONTENDACTION_H 12 13 #include "llvm/ADT/StringRef.h" 14 #include "llvm/ADT/OwningPtr.h" 15 #include <string> 16 #include <vector> 17 18 namespace llvm { 19 class raw_ostream; 20 } 21 22 namespace clang { 23 class ASTConsumer; 24 class ASTMergeAction; 25 class ASTUnit; 26 class CompilerInstance; 27 28 enum InputKind { 29 IK_None, 30 IK_Asm, 31 IK_C, 32 IK_CXX, 33 IK_ObjC, 34 IK_ObjCXX, 35 IK_PreprocessedC, 36 IK_PreprocessedCXX, 37 IK_PreprocessedObjC, 38 IK_PreprocessedObjCXX, 39 IK_OpenCL, 40 IK_CUDA, 41 IK_AST, 42 IK_LLVM_IR 43 }; 44 45 46 /// FrontendAction - Abstract base class for actions which can be performed by 47 /// the frontend. 48 class FrontendAction { 49 std::string CurrentFile; 50 InputKind CurrentFileKind; 51 llvm::OwningPtr<ASTUnit> CurrentASTUnit; 52 CompilerInstance *Instance; 53 friend class ASTMergeAction; 54 friend class WrapperFrontendAction; 55 56 private: 57 ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI, 58 llvm::StringRef InFile); 59 60 protected: 61 /// @name Implementation Action Interface 62 /// @{ 63 64 /// CreateASTConsumer - Create the AST consumer object for this action, if 65 /// supported. 66 /// 67 /// This routine is called as part of \see BeginSourceAction(), which will 68 /// fail if the AST consumer cannot be created. This will not be called if the 69 /// action has indicated that it only uses the preprocessor. 70 /// 71 /// \param CI - The current compiler instance, provided as a convenience, \see 72 /// getCompilerInstance(). 73 /// 74 /// \param InFile - The current input file, provided as a convenience, \see 75 /// getCurrentFile(). 76 /// 77 /// \return The new AST consumer, or 0 on failure. 78 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 79 llvm::StringRef InFile) = 0; 80 81 /// \brief Callback before starting processing a single input, giving the 82 /// opportunity to modify the CompilerInvocation or do some other action 83 /// before BeginSourceFileAction is called. 84 /// 85 /// \return True on success; on failure \see BeginSourceFileAction() and 86 /// ExecutionAction() and EndSourceFileAction() will not be called. 87 virtual bool BeginInvocation(CompilerInstance &CI) { return true; } 88 89 /// BeginSourceFileAction - Callback at the start of processing a single 90 /// input. 91 /// 92 /// \return True on success; on failure \see ExecutionAction() and 93 /// EndSourceFileAction() will not be called. 94 virtual bool BeginSourceFileAction(CompilerInstance &CI, 95 llvm::StringRef Filename) { 96 return true; 97 } 98 99 /// ExecuteAction - Callback to run the program action, using the initialized 100 /// compiler instance. 101 /// 102 /// This routine is guaranteed to only be called between \see 103 /// BeginSourceFileAction() and \see EndSourceFileAction(). 104 virtual void ExecuteAction() = 0; 105 106 /// EndSourceFileAction - Callback at the end of processing a single input; 107 /// this is guaranteed to only be called following a successful call to 108 /// BeginSourceFileAction (and BeingSourceFile). 109 virtual void EndSourceFileAction() {} 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(!CurrentFile.empty() && "No current file!"); 133 return CurrentASTUnit != 0; 134 } 135 136 const std::string &getCurrentFile() const { 137 assert(!CurrentFile.empty() && "No current file!"); 138 return CurrentFile; 139 } 140 141 InputKind getCurrentFileKind() const { 142 assert(!CurrentFile.empty() && "No current file!"); 143 return CurrentFileKind; 144 } 145 146 ASTUnit &getCurrentASTUnit() const { 147 assert(CurrentASTUnit && "No current AST unit!"); 148 return *CurrentASTUnit; 149 } 150 151 ASTUnit *takeCurrentASTUnit() { 152 return CurrentASTUnit.take(); 153 } 154 155 void setCurrentFile(llvm::StringRef Value, InputKind Kind, ASTUnit *AST = 0); 156 157 /// @} 158 /// @name Supported Modes 159 /// @{ 160 161 /// usesPreprocessorOnly - Does this action only use the preprocessor? If so 162 /// no AST context will be created and this action will be invalid with AST 163 /// file inputs. 164 virtual bool usesPreprocessorOnly() const = 0; 165 166 /// usesCompleteTranslationUnit - For AST based actions, should the 167 /// translation unit be completed? 168 virtual bool usesCompleteTranslationUnit() { return true; } 169 170 /// hasPCHSupport - Does this action support use with PCH? 171 virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } 172 173 /// hasASTFileSupport - Does this action support use with AST files? 174 virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); } 175 176 /// hasIRSupport - Does this action support use with IR files? 177 virtual bool hasIRSupport() const { return false; } 178 179 /// hasCodeCompletionSupport - Does this action support use with code 180 /// completion? 181 virtual bool hasCodeCompletionSupport() const { return false; } 182 183 /// @} 184 /// @name Public Action Interface 185 /// @{ 186 187 /// BeginSourceFile - Prepare the action for processing the input file \arg 188 /// Filename; this is run after the options and frontend have been 189 /// initialized, but prior to executing any per-file processing. 190 /// 191 /// \param CI - The compiler instance this action is being run from. The 192 /// action may store and use this object up until the matching EndSourceFile 193 /// action. 194 /// 195 /// \param Filename - The input filename, which will be made available to 196 /// clients via \see getCurrentFile(). 197 /// 198 /// \param InputKind - The type of input. Some input kinds are handled 199 /// specially, for example AST inputs, since the AST file itself contains 200 /// several objects which would normally be owned by the 201 /// CompilerInstance. When processing AST input files, these objects should 202 /// generally not be initialized in the CompilerInstance -- they will 203 /// automatically be shared with the AST file in between \see 204 /// BeginSourceFile() and \see EndSourceFile(). 205 /// 206 /// \return True on success; the compilation of this file should be aborted 207 /// and neither Execute nor EndSourceFile should be called. 208 bool BeginSourceFile(CompilerInstance &CI, llvm::StringRef Filename, 209 InputKind Kind); 210 211 /// Execute - Set the source managers main input file, and run the action. 212 void Execute(); 213 214 /// EndSourceFile - Perform any per-file post processing, deallocate per-file 215 /// objects, and run statistics and output file cleanup code. 216 void EndSourceFile(); 217 218 /// @} 219 }; 220 221 /// ASTFrontendAction - Abstract base class to use for AST consumer based 222 /// frontend actions. 223 class ASTFrontendAction : public FrontendAction { 224 protected: 225 /// ExecuteAction - Implement the ExecuteAction interface by running Sema on 226 /// the already initialized AST consumer. 227 /// 228 /// This will also take care of instantiating a code completion consumer if 229 /// the user requested it and the action supports it. 230 virtual void ExecuteAction(); 231 232 public: 233 virtual bool usesPreprocessorOnly() const { return false; } 234 }; 235 236 class PluginASTAction : public ASTFrontendAction { 237 protected: 238 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 239 llvm::StringRef InFile) = 0; 240 241 public: 242 /// ParseArgs - Parse the given plugin command line arguments. 243 /// 244 /// \param CI - The compiler instance, for use in reporting diagnostics. 245 /// \return True if the parsing succeeded; otherwise the plugin will be 246 /// destroyed and no action run. The plugin is responsible for using the 247 /// CompilerInstance's Diagnostic object to report errors. 248 virtual bool ParseArgs(const CompilerInstance &CI, 249 const std::vector<std::string> &arg) = 0; 250 }; 251 252 /// PreprocessorFrontendAction - Abstract base class to use for preprocessor 253 /// based frontend actions. 254 class PreprocessorFrontendAction : public FrontendAction { 255 protected: 256 /// CreateASTConsumer - Provide a default implementation which returns aborts, 257 /// this method should never be called by FrontendAction clients. 258 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 259 llvm::StringRef InFile); 260 261 public: 262 virtual bool usesPreprocessorOnly() const { return true; } 263 }; 264 265 /// WrapperFrontendAction - A frontend action which simply wraps some other 266 /// runtime specified frontend action. Deriving from this class allows an 267 /// action to inject custom logic around some existing action's behavior. It 268 /// implements every virtual method in the FrontendAction interface by 269 /// forwarding to the wrapped action. 270 class WrapperFrontendAction : public FrontendAction { 271 llvm::OwningPtr<FrontendAction> WrappedAction; 272 273 protected: 274 virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 275 llvm::StringRef InFile); 276 virtual bool BeginInvocation(CompilerInstance &CI); 277 virtual bool BeginSourceFileAction(CompilerInstance &CI, 278 llvm::StringRef Filename); 279 virtual void ExecuteAction(); 280 virtual void EndSourceFileAction(); 281 282 public: 283 /// Construct a WrapperFrontendAction from an existing action, taking 284 /// ownership of it. 285 WrapperFrontendAction(FrontendAction *WrappedAction); 286 287 virtual bool usesPreprocessorOnly() const; 288 virtual bool usesCompleteTranslationUnit(); 289 virtual bool hasPCHSupport() const; 290 virtual bool hasASTFileSupport() const; 291 virtual bool hasIRSupport() const; 292 virtual bool hasCodeCompletionSupport() const; 293 }; 294 295 } // end namespace clang 296 297 #endif 298