1199482Srdivacky//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===// 2199482Srdivacky// 3199482Srdivacky// The LLVM Compiler Infrastructure 4199482Srdivacky// 5199482Srdivacky// This file is distributed under the University of Illinois Open Source 6199482Srdivacky// License. See LICENSE.TXT for details. 7199482Srdivacky// 8199482Srdivacky//===----------------------------------------------------------------------===// 9249423Sdim/// 10249423Sdim/// \file 11249423Sdim/// \brief Defines the clang::FrontendAction interface and various convenience 12249423Sdim/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction, 13249423Sdim/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction) 14249423Sdim/// derived from it. 15249423Sdim/// 16249423Sdim//===----------------------------------------------------------------------===// 17199482Srdivacky 18199482Srdivacky#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H 19199482Srdivacky#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H 20199482Srdivacky 21226633Sdim#include "clang/Basic/LLVM.h" 22226633Sdim#include "clang/Basic/LangOptions.h" 23234353Sdim#include "clang/Frontend/FrontendOptions.h" 24249423Sdim#include "llvm/ADT/OwningPtr.h" 25199482Srdivacky#include "llvm/ADT/StringRef.h" 26199482Srdivacky#include <string> 27210299Sed#include <vector> 28199482Srdivacky 29199482Srdivackynamespace clang { 30210299Sedclass ASTConsumer; 31210299Sedclass ASTMergeAction; 32199482Srdivackyclass ASTUnit; 33199482Srdivackyclass CompilerInstance; 34199482Srdivacky 35249423Sdim/// Abstract base class for actions which can be performed by the frontend. 36199482Srdivackyclass FrontendAction { 37234353Sdim FrontendInputFile CurrentInput; 38234353Sdim OwningPtr<ASTUnit> CurrentASTUnit; 39199482Srdivacky CompilerInstance *Instance; 40203955Srdivacky friend class ASTMergeAction; 41224145Sdim friend class WrapperFrontendAction; 42199482Srdivacky 43218893Sdimprivate: 44218893Sdim ASTConsumer* CreateWrappedASTConsumer(CompilerInstance &CI, 45226633Sdim StringRef InFile); 46218893Sdim 47199482Srdivackyprotected: 48199482Srdivacky /// @name Implementation Action Interface 49199482Srdivacky /// @{ 50199482Srdivacky 51249423Sdim /// \brief Create the AST consumer object for this action, if supported. 52199482Srdivacky /// 53249423Sdim /// This routine is called as part of BeginSourceFile(), which will 54199482Srdivacky /// fail if the AST consumer cannot be created. This will not be called if the 55199482Srdivacky /// action has indicated that it only uses the preprocessor. 56199482Srdivacky /// 57249423Sdim /// \param CI - The current compiler instance, provided as a convenience, see 58199482Srdivacky /// getCompilerInstance(). 59199482Srdivacky /// 60249423Sdim /// \param InFile - The current input file, provided as a convenience, see 61199482Srdivacky /// getCurrentFile(). 62199482Srdivacky /// 63249423Sdim /// \return The new AST consumer, or null on failure. 64199482Srdivacky virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 65226633Sdim StringRef InFile) = 0; 66199482Srdivacky 67224145Sdim /// \brief Callback before starting processing a single input, giving the 68224145Sdim /// opportunity to modify the CompilerInvocation or do some other action 69224145Sdim /// before BeginSourceFileAction is called. 70224145Sdim /// 71249423Sdim /// \return True on success; on failure BeginSourceFileAction(), 72249423Sdim /// ExecuteAction() and EndSourceFileAction() will not be called. 73224145Sdim virtual bool BeginInvocation(CompilerInstance &CI) { return true; } 74224145Sdim 75249423Sdim /// \brief Callback at the start of processing a single input. 76199482Srdivacky /// 77249423Sdim /// \return True on success; on failure ExecutionAction() and 78199482Srdivacky /// EndSourceFileAction() will not be called. 79199482Srdivacky virtual bool BeginSourceFileAction(CompilerInstance &CI, 80226633Sdim StringRef Filename) { 81199482Srdivacky return true; 82199482Srdivacky } 83199482Srdivacky 84249423Sdim /// \brief Callback to run the program action, using the initialized 85199482Srdivacky /// compiler instance. 86199482Srdivacky /// 87249423Sdim /// This is guaranteed to only be called between BeginSourceFileAction() 88249423Sdim /// and EndSourceFileAction(). 89199482Srdivacky virtual void ExecuteAction() = 0; 90199482Srdivacky 91249423Sdim /// \brief Callback at the end of processing a single input. 92249423Sdim /// 93249423Sdim /// This is guaranteed to only be called following a successful call to 94234353Sdim /// BeginSourceFileAction (and BeginSourceFile). 95199482Srdivacky virtual void EndSourceFileAction() {} 96199482Srdivacky 97263508Sdim /// \brief Callback at the end of processing a single input, to determine 98263508Sdim /// if the output files should be erased or not. 99263508Sdim /// 100263508Sdim /// By default it returns true if a compiler error occurred. 101263508Sdim /// This is guaranteed to only be called following a successful call to 102263508Sdim /// BeginSourceFileAction (and BeginSourceFile). 103263508Sdim virtual bool shouldEraseOutputFiles(); 104263508Sdim 105199482Srdivacky /// @} 106199482Srdivacky 107199482Srdivackypublic: 108199482Srdivacky FrontendAction(); 109199482Srdivacky virtual ~FrontendAction(); 110199482Srdivacky 111199482Srdivacky /// @name Compiler Instance Access 112199482Srdivacky /// @{ 113199482Srdivacky 114199482Srdivacky CompilerInstance &getCompilerInstance() const { 115199482Srdivacky assert(Instance && "Compiler instance not registered!"); 116199482Srdivacky return *Instance; 117199482Srdivacky } 118199482Srdivacky 119199482Srdivacky void setCompilerInstance(CompilerInstance *Value) { Instance = Value; } 120199482Srdivacky 121199482Srdivacky /// @} 122199482Srdivacky /// @name Current File Information 123199482Srdivacky /// @{ 124199482Srdivacky 125199482Srdivacky bool isCurrentFileAST() const { 126243830Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 127263508Sdim return CurrentASTUnit.isValid(); 128199482Srdivacky } 129199482Srdivacky 130234353Sdim const FrontendInputFile &getCurrentInput() const { 131234353Sdim return CurrentInput; 132234353Sdim } 133234353Sdim 134243830Sdim const StringRef getCurrentFile() const { 135243830Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 136243830Sdim return CurrentInput.getFile(); 137199482Srdivacky } 138199482Srdivacky 139210299Sed InputKind getCurrentFileKind() const { 140243830Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 141243830Sdim return CurrentInput.getKind(); 142210299Sed } 143210299Sed 144199482Srdivacky ASTUnit &getCurrentASTUnit() const { 145218893Sdim assert(CurrentASTUnit && "No current AST unit!"); 146199482Srdivacky return *CurrentASTUnit; 147199482Srdivacky } 148199482Srdivacky 149203955Srdivacky ASTUnit *takeCurrentASTUnit() { 150203955Srdivacky return CurrentASTUnit.take(); 151203955Srdivacky } 152203955Srdivacky 153234353Sdim void setCurrentInput(const FrontendInputFile &CurrentInput, ASTUnit *AST = 0); 154199482Srdivacky 155199482Srdivacky /// @} 156199482Srdivacky /// @name Supported Modes 157199482Srdivacky /// @{ 158199482Srdivacky 159249423Sdim /// \brief Does this action only use the preprocessor? 160249423Sdim /// 161249423Sdim /// If so no AST context will be created and this action will be invalid 162249423Sdim /// with AST file inputs. 163199482Srdivacky virtual bool usesPreprocessorOnly() const = 0; 164199482Srdivacky 165226633Sdim /// \brief For AST-based actions, the kind of translation unit we're handling. 166226633Sdim virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } 167199482Srdivacky 168249423Sdim /// \brief Does this action support use with PCH? 169199482Srdivacky virtual bool hasPCHSupport() const { return !usesPreprocessorOnly(); } 170199482Srdivacky 171249423Sdim /// \brief Does this action support use with AST files? 172210299Sed virtual bool hasASTFileSupport() const { return !usesPreprocessorOnly(); } 173199482Srdivacky 174249423Sdim /// \brief Does this action support use with IR files? 175210299Sed virtual bool hasIRSupport() const { return false; } 176210299Sed 177249423Sdim /// \brief Does this action support use with code completion? 178199482Srdivacky virtual bool hasCodeCompletionSupport() const { return false; } 179199482Srdivacky 180199482Srdivacky /// @} 181199482Srdivacky /// @name Public Action Interface 182199482Srdivacky /// @{ 183199482Srdivacky 184249423Sdim /// \brief Prepare the action for processing the input file \p Input. 185199482Srdivacky /// 186249423Sdim /// This is run after the options and frontend have been initialized, 187249423Sdim /// but prior to executing any per-file processing. 188249423Sdim /// 189199482Srdivacky /// \param CI - The compiler instance this action is being run from. The 190199482Srdivacky /// action may store and use this object up until the matching EndSourceFile 191199482Srdivacky /// action. 192199482Srdivacky /// 193234353Sdim /// \param Input - The input filename and kind. Some input kinds are handled 194210299Sed /// specially, for example AST inputs, since the AST file itself contains 195210299Sed /// several objects which would normally be owned by the 196210299Sed /// CompilerInstance. When processing AST input files, these objects should 197210299Sed /// generally not be initialized in the CompilerInstance -- they will 198249423Sdim /// automatically be shared with the AST file in between 199249423Sdim /// BeginSourceFile() and EndSourceFile(). 200199482Srdivacky /// 201234353Sdim /// \return True on success; on failure the compilation of this file should 202249423Sdim /// be aborted and neither Execute() nor EndSourceFile() should be called. 203234353Sdim bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input); 204199482Srdivacky 205249423Sdim /// \brief Set the source manager's main input file, and run the action. 206239462Sdim bool Execute(); 207199482Srdivacky 208249423Sdim /// \brief Perform any per-file post processing, deallocate per-file 209199482Srdivacky /// objects, and run statistics and output file cleanup code. 210199482Srdivacky void EndSourceFile(); 211199482Srdivacky 212199482Srdivacky /// @} 213199482Srdivacky}; 214199482Srdivacky 215249423Sdim/// \brief Abstract base class to use for AST consumer-based frontend actions. 216199482Srdivackyclass ASTFrontendAction : public FrontendAction { 217210299Sedprotected: 218249423Sdim /// \brief Implement the ExecuteAction interface by running Sema on 219249423Sdim /// the already-initialized AST consumer. 220199482Srdivacky /// 221199482Srdivacky /// This will also take care of instantiating a code completion consumer if 222199482Srdivacky /// the user requested it and the action supports it. 223199482Srdivacky virtual void ExecuteAction(); 224199482Srdivacky 225199482Srdivackypublic: 226199482Srdivacky virtual bool usesPreprocessorOnly() const { return false; } 227199482Srdivacky}; 228199482Srdivacky 229210299Sedclass PluginASTAction : public ASTFrontendAction { 230234353Sdim virtual void anchor(); 231210299Sedprotected: 232210299Sed virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 233226633Sdim StringRef InFile) = 0; 234210299Sed 235210299Sedpublic: 236249423Sdim /// \brief Parse the given plugin command line arguments. 237212904Sdim /// 238212904Sdim /// \param CI - The compiler instance, for use in reporting diagnostics. 239212904Sdim /// \return True if the parsing succeeded; otherwise the plugin will be 240212904Sdim /// destroyed and no action run. The plugin is responsible for using the 241212904Sdim /// CompilerInstance's Diagnostic object to report errors. 242212904Sdim virtual bool ParseArgs(const CompilerInstance &CI, 243212904Sdim const std::vector<std::string> &arg) = 0; 244210299Sed}; 245210299Sed 246249423Sdim/// \brief Abstract base class to use for preprocessor-based frontend actions. 247199482Srdivackyclass PreprocessorFrontendAction : public FrontendAction { 248199482Srdivackyprotected: 249249423Sdim /// \brief Provide a default implementation which returns aborts; 250199482Srdivacky /// this method should never be called by FrontendAction clients. 251199482Srdivacky virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 252226633Sdim StringRef InFile); 253199482Srdivacky 254199482Srdivackypublic: 255199482Srdivacky virtual bool usesPreprocessorOnly() const { return true; } 256199482Srdivacky}; 257199482Srdivacky 258249423Sdim/// \brief A frontend action which simply wraps some other runtime-specified 259249423Sdim/// frontend action. 260249423Sdim/// 261249423Sdim/// Deriving from this class allows an action to inject custom logic around 262249423Sdim/// some existing action's behavior. It implements every virtual method in 263249423Sdim/// the FrontendAction interface by forwarding to the wrapped action. 264224145Sdimclass WrapperFrontendAction : public FrontendAction { 265234353Sdim OwningPtr<FrontendAction> WrappedAction; 266224145Sdim 267224145Sdimprotected: 268224145Sdim virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, 269226633Sdim StringRef InFile); 270224145Sdim virtual bool BeginInvocation(CompilerInstance &CI); 271224145Sdim virtual bool BeginSourceFileAction(CompilerInstance &CI, 272226633Sdim StringRef Filename); 273224145Sdim virtual void ExecuteAction(); 274224145Sdim virtual void EndSourceFileAction(); 275224145Sdim 276224145Sdimpublic: 277224145Sdim /// Construct a WrapperFrontendAction from an existing action, taking 278224145Sdim /// ownership of it. 279224145Sdim WrapperFrontendAction(FrontendAction *WrappedAction); 280224145Sdim 281224145Sdim virtual bool usesPreprocessorOnly() const; 282226633Sdim virtual TranslationUnitKind getTranslationUnitKind(); 283224145Sdim virtual bool hasPCHSupport() const; 284224145Sdim virtual bool hasASTFileSupport() const; 285224145Sdim virtual bool hasIRSupport() const; 286224145Sdim virtual bool hasCodeCompletionSupport() const; 287224145Sdim}; 288224145Sdim 289199482Srdivacky} // end namespace clang 290199482Srdivacky 291199482Srdivacky#endif 292