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