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