1199482Srdivacky//===-- FrontendAction.h - Generic Frontend Action Interface ----*- C++ -*-===// 2199482Srdivacky// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6199482Srdivacky// 7199482Srdivacky//===----------------------------------------------------------------------===// 8249423Sdim/// 9249423Sdim/// \file 10341825Sdim/// Defines the clang::FrontendAction interface and various convenience 11249423Sdim/// abstract classes (clang::ASTFrontendAction, clang::PluginASTAction, 12249423Sdim/// clang::PreprocessorFrontendAction, and clang::WrapperFrontendAction) 13249423Sdim/// derived from it. 14249423Sdim/// 15249423Sdim//===----------------------------------------------------------------------===// 16199482Srdivacky 17199482Srdivacky#ifndef LLVM_CLANG_FRONTEND_FRONTENDACTION_H 18199482Srdivacky#define LLVM_CLANG_FRONTEND_FRONTENDACTION_H 19199482Srdivacky 20280031Sdim#include "clang/AST/ASTConsumer.h" 21226633Sdim#include "clang/Basic/LLVM.h" 22226633Sdim#include "clang/Basic/LangOptions.h" 23280031Sdim#include "clang/Frontend/ASTUnit.h" 24234353Sdim#include "clang/Frontend/FrontendOptions.h" 25199482Srdivacky#include "llvm/ADT/StringRef.h" 26353358Sdim#include "llvm/Support/Error.h" 27276479Sdim#include <memory> 28199482Srdivacky#include <string> 29210299Sed#include <vector> 30199482Srdivacky 31199482Srdivackynamespace clang { 32210299Sedclass ASTMergeAction; 33199482Srdivackyclass CompilerInstance; 34199482Srdivacky 35249423Sdim/// Abstract base class for actions which can be performed by the frontend. 36199482Srdivackyclass FrontendAction { 37234353Sdim FrontendInputFile CurrentInput; 38276479Sdim std::unique_ptr<ASTUnit> CurrentASTUnit; 39199482Srdivacky CompilerInstance *Instance; 40203955Srdivacky friend class ASTMergeAction; 41224145Sdim friend class WrapperFrontendAction; 42199482Srdivacky 43218893Sdimprivate: 44280031Sdim std::unique_ptr<ASTConsumer> CreateWrappedASTConsumer(CompilerInstance &CI, 45280031Sdim StringRef InFile); 46218893Sdim 47199482Srdivackyprotected: 48199482Srdivacky /// @name Implementation Action Interface 49199482Srdivacky /// @{ 50199482Srdivacky 51344779Sdim /// Prepare to execute the action on the given CompilerInstance. 52344779Sdim /// 53344779Sdim /// This is called before executing the action on any inputs, and can modify 54344779Sdim /// the configuration as needed (including adjusting the input list). 55344779Sdim virtual bool PrepareToExecuteAction(CompilerInstance &CI) { return true; } 56344779Sdim 57341825Sdim /// Create the AST consumer object for this action, if supported. 58199482Srdivacky /// 59249423Sdim /// This routine is called as part of BeginSourceFile(), which will 60199482Srdivacky /// fail if the AST consumer cannot be created. This will not be called if the 61199482Srdivacky /// action has indicated that it only uses the preprocessor. 62199482Srdivacky /// 63249423Sdim /// \param CI - The current compiler instance, provided as a convenience, see 64199482Srdivacky /// getCompilerInstance(). 65199482Srdivacky /// 66249423Sdim /// \param InFile - The current input file, provided as a convenience, see 67199482Srdivacky /// getCurrentFile(). 68199482Srdivacky /// 69249423Sdim /// \return The new AST consumer, or null on failure. 70280031Sdim virtual std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 71280031Sdim StringRef InFile) = 0; 72199482Srdivacky 73341825Sdim /// Callback before starting processing a single input, giving the 74224145Sdim /// opportunity to modify the CompilerInvocation or do some other action 75224145Sdim /// before BeginSourceFileAction is called. 76224145Sdim /// 77249423Sdim /// \return True on success; on failure BeginSourceFileAction(), 78249423Sdim /// ExecuteAction() and EndSourceFileAction() will not be called. 79224145Sdim virtual bool BeginInvocation(CompilerInstance &CI) { return true; } 80224145Sdim 81341825Sdim /// Callback at the start of processing a single input. 82199482Srdivacky /// 83249423Sdim /// \return True on success; on failure ExecutionAction() and 84199482Srdivacky /// EndSourceFileAction() will not be called. 85321369Sdim virtual bool BeginSourceFileAction(CompilerInstance &CI) { 86199482Srdivacky return true; 87199482Srdivacky } 88199482Srdivacky 89341825Sdim /// Callback to run the program action, using the initialized 90199482Srdivacky /// compiler instance. 91199482Srdivacky /// 92249423Sdim /// This is guaranteed to only be called between BeginSourceFileAction() 93249423Sdim /// and EndSourceFileAction(). 94199482Srdivacky virtual void ExecuteAction() = 0; 95199482Srdivacky 96341825Sdim /// Callback at the end of processing a single input. 97249423Sdim /// 98249423Sdim /// This is guaranteed to only be called following a successful call to 99234353Sdim /// BeginSourceFileAction (and BeginSourceFile). 100199482Srdivacky virtual void EndSourceFileAction() {} 101199482Srdivacky 102341825Sdim /// Callback at the end of processing a single input, to determine 103261991Sdim /// if the output files should be erased or not. 104261991Sdim /// 105261991Sdim /// By default it returns true if a compiler error occurred. 106261991Sdim /// This is guaranteed to only be called following a successful call to 107261991Sdim /// BeginSourceFileAction (and BeginSourceFile). 108261991Sdim virtual bool shouldEraseOutputFiles(); 109261991Sdim 110199482Srdivacky /// @} 111199482Srdivacky 112199482Srdivackypublic: 113199482Srdivacky FrontendAction(); 114199482Srdivacky virtual ~FrontendAction(); 115199482Srdivacky 116199482Srdivacky /// @name Compiler Instance Access 117199482Srdivacky /// @{ 118199482Srdivacky 119199482Srdivacky CompilerInstance &getCompilerInstance() const { 120199482Srdivacky assert(Instance && "Compiler instance not registered!"); 121199482Srdivacky return *Instance; 122199482Srdivacky } 123199482Srdivacky 124199482Srdivacky void setCompilerInstance(CompilerInstance *Value) { Instance = Value; } 125199482Srdivacky 126199482Srdivacky /// @} 127199482Srdivacky /// @name Current File Information 128199482Srdivacky /// @{ 129199482Srdivacky 130199482Srdivacky bool isCurrentFileAST() const { 131243830Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 132276479Sdim return (bool)CurrentASTUnit; 133199482Srdivacky } 134199482Srdivacky 135234353Sdim const FrontendInputFile &getCurrentInput() const { 136234353Sdim return CurrentInput; 137234353Sdim } 138309124Sdim 139344779Sdim StringRef getCurrentFile() const { 140243830Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 141243830Sdim return CurrentInput.getFile(); 142199482Srdivacky } 143199482Srdivacky 144344779Sdim StringRef getCurrentFileOrBufferName() const { 145344779Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 146344779Sdim return CurrentInput.isFile() 147344779Sdim ? CurrentInput.getFile() 148344779Sdim : CurrentInput.getBuffer()->getBufferIdentifier(); 149344779Sdim } 150344779Sdim 151210299Sed InputKind getCurrentFileKind() const { 152243830Sdim assert(!CurrentInput.isEmpty() && "No current file!"); 153243830Sdim return CurrentInput.getKind(); 154210299Sed } 155210299Sed 156199482Srdivacky ASTUnit &getCurrentASTUnit() const { 157218893Sdim assert(CurrentASTUnit && "No current AST unit!"); 158199482Srdivacky return *CurrentASTUnit; 159199482Srdivacky } 160199482Srdivacky 161321369Sdim Module *getCurrentModule() const; 162321369Sdim 163280031Sdim std::unique_ptr<ASTUnit> takeCurrentASTUnit() { 164280031Sdim return std::move(CurrentASTUnit); 165280031Sdim } 166203955Srdivacky 167276479Sdim void setCurrentInput(const FrontendInputFile &CurrentInput, 168280031Sdim std::unique_ptr<ASTUnit> AST = nullptr); 169199482Srdivacky 170199482Srdivacky /// @} 171199482Srdivacky /// @name Supported Modes 172199482Srdivacky /// @{ 173199482Srdivacky 174341825Sdim /// Is this action invoked on a model file? 175280031Sdim /// 176280031Sdim /// Model files are incomplete translation units that relies on type 177280031Sdim /// information from another translation unit. Check ParseModelFileAction for 178280031Sdim /// details. 179280031Sdim virtual bool isModelParsingAction() const { return false; } 180280031Sdim 181341825Sdim /// Does this action only use the preprocessor? 182249423Sdim /// 183249423Sdim /// If so no AST context will be created and this action will be invalid 184249423Sdim /// with AST file inputs. 185199482Srdivacky virtual bool usesPreprocessorOnly() const = 0; 186199482Srdivacky 187341825Sdim /// For AST-based actions, the kind of translation unit we're handling. 188226633Sdim virtual TranslationUnitKind getTranslationUnitKind() { return TU_Complete; } 189199482Srdivacky 190341825Sdim /// Does this action support use with PCH? 191321369Sdim virtual bool hasPCHSupport() const { return true; } 192199482Srdivacky 193341825Sdim /// Does this action support use with AST files? 194321369Sdim virtual bool hasASTFileSupport() const { return true; } 195199482Srdivacky 196341825Sdim /// Does this action support use with IR files? 197210299Sed virtual bool hasIRSupport() const { return false; } 198210299Sed 199341825Sdim /// Does this action support use with code completion? 200199482Srdivacky virtual bool hasCodeCompletionSupport() const { return false; } 201199482Srdivacky 202199482Srdivacky /// @} 203199482Srdivacky /// @name Public Action Interface 204199482Srdivacky /// @{ 205199482Srdivacky 206344779Sdim /// Prepare the action to execute on the given compiler instance. 207344779Sdim bool PrepareToExecute(CompilerInstance &CI) { 208344779Sdim return PrepareToExecuteAction(CI); 209344779Sdim } 210344779Sdim 211341825Sdim /// Prepare the action for processing the input file \p Input. 212199482Srdivacky /// 213249423Sdim /// This is run after the options and frontend have been initialized, 214249423Sdim /// but prior to executing any per-file processing. 215249423Sdim /// 216199482Srdivacky /// \param CI - The compiler instance this action is being run from. The 217199482Srdivacky /// action may store and use this object up until the matching EndSourceFile 218199482Srdivacky /// action. 219199482Srdivacky /// 220234353Sdim /// \param Input - The input filename and kind. Some input kinds are handled 221210299Sed /// specially, for example AST inputs, since the AST file itself contains 222210299Sed /// several objects which would normally be owned by the 223210299Sed /// CompilerInstance. When processing AST input files, these objects should 224210299Sed /// generally not be initialized in the CompilerInstance -- they will 225249423Sdim /// automatically be shared with the AST file in between 226249423Sdim /// BeginSourceFile() and EndSourceFile(). 227199482Srdivacky /// 228234353Sdim /// \return True on success; on failure the compilation of this file should 229249423Sdim /// be aborted and neither Execute() nor EndSourceFile() should be called. 230234353Sdim bool BeginSourceFile(CompilerInstance &CI, const FrontendInputFile &Input); 231199482Srdivacky 232341825Sdim /// Set the source manager's main input file, and run the action. 233353358Sdim llvm::Error Execute(); 234199482Srdivacky 235341825Sdim /// Perform any per-file post processing, deallocate per-file 236199482Srdivacky /// objects, and run statistics and output file cleanup code. 237199482Srdivacky void EndSourceFile(); 238199482Srdivacky 239199482Srdivacky /// @} 240199482Srdivacky}; 241199482Srdivacky 242341825Sdim/// Abstract base class to use for AST consumer-based frontend actions. 243199482Srdivackyclass ASTFrontendAction : public FrontendAction { 244210299Sedprotected: 245341825Sdim /// Implement the ExecuteAction interface by running Sema on 246249423Sdim /// the already-initialized AST consumer. 247199482Srdivacky /// 248199482Srdivacky /// This will also take care of instantiating a code completion consumer if 249199482Srdivacky /// the user requested it and the action supports it. 250276479Sdim void ExecuteAction() override; 251199482Srdivacky 252199482Srdivackypublic: 253280031Sdim ASTFrontendAction() {} 254276479Sdim bool usesPreprocessorOnly() const override { return false; } 255199482Srdivacky}; 256199482Srdivacky 257210299Sedclass PluginASTAction : public ASTFrontendAction { 258234353Sdim virtual void anchor(); 259280031Sdimpublic: 260280031Sdim std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 261280031Sdim StringRef InFile) override = 0; 262210299Sed 263341825Sdim /// Parse the given plugin command line arguments. 264212904Sdim /// 265212904Sdim /// \param CI - The compiler instance, for use in reporting diagnostics. 266212904Sdim /// \return True if the parsing succeeded; otherwise the plugin will be 267212904Sdim /// destroyed and no action run. The plugin is responsible for using the 268212904Sdim /// CompilerInstance's Diagnostic object to report errors. 269212904Sdim virtual bool ParseArgs(const CompilerInstance &CI, 270212904Sdim const std::vector<std::string> &arg) = 0; 271309124Sdim 272309124Sdim enum ActionType { 273309124Sdim Cmdline, ///< Action is determined by the cc1 command-line 274309124Sdim ReplaceAction, ///< Replace the main action 275309124Sdim AddBeforeMainAction, ///< Execute the action before the main action 276309124Sdim AddAfterMainAction ///< Execute the action after the main action 277309124Sdim }; 278341825Sdim /// Get the action type for this plugin 279309124Sdim /// 280309124Sdim /// \return The action type. If the type is Cmdline then by default the 281309124Sdim /// plugin does nothing and what it does is determined by the cc1 282309124Sdim /// command-line. 283309124Sdim virtual ActionType getActionType() { return Cmdline; } 284210299Sed}; 285210299Sed 286341825Sdim/// Abstract base class to use for preprocessor-based frontend actions. 287199482Srdivackyclass PreprocessorFrontendAction : public FrontendAction { 288199482Srdivackyprotected: 289341825Sdim /// Provide a default implementation which returns aborts; 290199482Srdivacky /// this method should never be called by FrontendAction clients. 291280031Sdim std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 292280031Sdim StringRef InFile) override; 293199482Srdivacky 294199482Srdivackypublic: 295276479Sdim bool usesPreprocessorOnly() const override { return true; } 296199482Srdivacky}; 297199482Srdivacky 298341825Sdim/// A frontend action which simply wraps some other runtime-specified 299249423Sdim/// frontend action. 300249423Sdim/// 301249423Sdim/// Deriving from this class allows an action to inject custom logic around 302249423Sdim/// some existing action's behavior. It implements every virtual method in 303249423Sdim/// the FrontendAction interface by forwarding to the wrapped action. 304224145Sdimclass WrapperFrontendAction : public FrontendAction { 305276479Sdim std::unique_ptr<FrontendAction> WrappedAction; 306224145Sdim 307224145Sdimprotected: 308353358Sdim bool PrepareToExecuteAction(CompilerInstance &CI) override; 309280031Sdim std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI, 310280031Sdim StringRef InFile) override; 311276479Sdim bool BeginInvocation(CompilerInstance &CI) override; 312321369Sdim bool BeginSourceFileAction(CompilerInstance &CI) override; 313276479Sdim void ExecuteAction() override; 314276479Sdim void EndSourceFileAction() override; 315224145Sdim 316224145Sdimpublic: 317224145Sdim /// Construct a WrapperFrontendAction from an existing action, taking 318224145Sdim /// ownership of it. 319309124Sdim WrapperFrontendAction(std::unique_ptr<FrontendAction> WrappedAction); 320224145Sdim 321276479Sdim bool usesPreprocessorOnly() const override; 322276479Sdim TranslationUnitKind getTranslationUnitKind() override; 323276479Sdim bool hasPCHSupport() const override; 324276479Sdim bool hasASTFileSupport() const override; 325276479Sdim bool hasIRSupport() const override; 326276479Sdim bool hasCodeCompletionSupport() const override; 327224145Sdim}; 328224145Sdim 329199482Srdivacky} // end namespace clang 330199482Srdivacky 331199482Srdivacky#endif 332