1c6cf3295SJacob Lambert //===--- BackendConsumer.h - LLVM BackendConsumer Header File -------------===// 2c6cf3295SJacob Lambert // 3c6cf3295SJacob Lambert // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4c6cf3295SJacob Lambert // See https://llvm.org/LICENSE.txt for license information. 5c6cf3295SJacob Lambert // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6c6cf3295SJacob Lambert // 7c6cf3295SJacob Lambert //===----------------------------------------------------------------------===// 8c6cf3295SJacob Lambert 9c6cf3295SJacob Lambert #ifndef LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H 10c6cf3295SJacob Lambert #define LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H 11c6cf3295SJacob Lambert 12c6cf3295SJacob Lambert #include "clang/CodeGen/BackendUtil.h" 13c6cf3295SJacob Lambert #include "clang/CodeGen/CodeGenAction.h" 14c6cf3295SJacob Lambert 15c6cf3295SJacob Lambert #include "llvm/IR/DiagnosticInfo.h" 16c6cf3295SJacob Lambert #include "llvm/Support/Timer.h" 17c6cf3295SJacob Lambert 18c6cf3295SJacob Lambert namespace llvm { 19c6cf3295SJacob Lambert class DiagnosticInfoDontCall; 20c6cf3295SJacob Lambert } 21c6cf3295SJacob Lambert 22c6cf3295SJacob Lambert namespace clang { 23c6cf3295SJacob Lambert class ASTContext; 24c6cf3295SJacob Lambert class CodeGenAction; 25c6cf3295SJacob Lambert class CoverageSourceInfo; 26c6cf3295SJacob Lambert 27c6cf3295SJacob Lambert class BackendConsumer : public ASTConsumer { 28c6cf3295SJacob Lambert using LinkModule = CodeGenAction::LinkModule; 29c6cf3295SJacob Lambert 30c6cf3295SJacob Lambert virtual void anchor(); 31*48d0eb51SFangrui Song CompilerInstance &CI; 32c6cf3295SJacob Lambert DiagnosticsEngine &Diags; 33c6cf3295SJacob Lambert const CodeGenOptions &CodeGenOpts; 34c6cf3295SJacob Lambert const TargetOptions &TargetOpts; 35c6cf3295SJacob Lambert const LangOptions &LangOpts; 36c6cf3295SJacob Lambert std::unique_ptr<raw_pwrite_stream> AsmOutStream; 375fdcea2dSFangrui Song ASTContext *Context = nullptr; 38c6cf3295SJacob Lambert IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; 39c6cf3295SJacob Lambert 40c6cf3295SJacob Lambert llvm::Timer LLVMIRGeneration; 415fdcea2dSFangrui Song unsigned LLVMIRGenerationRefCount = 0; 42c6cf3295SJacob Lambert 43c6cf3295SJacob Lambert /// True if we've finished generating IR. This prevents us from generating 44c6cf3295SJacob Lambert /// additional LLVM IR after emitting output in HandleTranslationUnit. This 45c6cf3295SJacob Lambert /// can happen when Clang plugins trigger additional AST deserialization. 46c6cf3295SJacob Lambert bool IRGenFinished = false; 47c6cf3295SJacob Lambert 48c6cf3295SJacob Lambert bool TimerIsEnabled = false; 49c6cf3295SJacob Lambert 505fdcea2dSFangrui Song BackendAction Action; 515fdcea2dSFangrui Song 52c6cf3295SJacob Lambert std::unique_ptr<CodeGenerator> Gen; 53c6cf3295SJacob Lambert 54c6cf3295SJacob Lambert SmallVector<LinkModule, 4> LinkModules; 55c6cf3295SJacob Lambert 56c6cf3295SJacob Lambert // A map from mangled names to their function's source location, used for 57c6cf3295SJacob Lambert // backend diagnostics as the Clang AST may be unavailable. We actually use 58c6cf3295SJacob Lambert // the mangled name's hash as the key because mangled names can be very 59c6cf3295SJacob Lambert // long and take up lots of space. Using a hash can cause name collision, 60c6cf3295SJacob Lambert // but that is rare and the consequences are pointing to a wrong source 61c6cf3295SJacob Lambert // location which is not severe. This is a vector instead of an actual map 62c6cf3295SJacob Lambert // because we optimize for time building this map rather than time 63c6cf3295SJacob Lambert // retrieving an entry, as backend diagnostics are uncommon. 64c6cf3295SJacob Lambert std::vector<std::pair<llvm::hash_code, FullSourceLoc>> 65c6cf3295SJacob Lambert ManglingFullSourceLocs; 66c6cf3295SJacob Lambert 67c6cf3295SJacob Lambert 68c6cf3295SJacob Lambert // This is here so that the diagnostic printer knows the module a diagnostic 69c6cf3295SJacob Lambert // refers to. 70c6cf3295SJacob Lambert llvm::Module *CurLinkModule = nullptr; 71c6cf3295SJacob Lambert 72c6cf3295SJacob Lambert public: 73*48d0eb51SFangrui Song BackendConsumer(CompilerInstance &CI, BackendAction Action, 74c6cf3295SJacob Lambert IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 756dd1315cSFangrui Song llvm::LLVMContext &C, SmallVector<LinkModule, 4> LinkModules, 766dd1315cSFangrui Song StringRef InFile, std::unique_ptr<raw_pwrite_stream> OS, 776dd1315cSFangrui Song CoverageSourceInfo *CoverageInfo, 786dd1315cSFangrui Song llvm::Module *CurLinkModule = nullptr); 79c6cf3295SJacob Lambert 80c6cf3295SJacob Lambert llvm::Module *getModule() const; 81c6cf3295SJacob Lambert std::unique_ptr<llvm::Module> takeModule(); 82c6cf3295SJacob Lambert 83c6cf3295SJacob Lambert CodeGenerator *getCodeGenerator(); 84c6cf3295SJacob Lambert 85c6cf3295SJacob Lambert void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override; 86c6cf3295SJacob Lambert void Initialize(ASTContext &Ctx) override; 87c6cf3295SJacob Lambert bool HandleTopLevelDecl(DeclGroupRef D) override; 88c6cf3295SJacob Lambert void HandleInlineFunctionDefinition(FunctionDecl *D) override; 89c6cf3295SJacob Lambert void HandleInterestingDecl(DeclGroupRef D) override; 90c6cf3295SJacob Lambert void HandleTranslationUnit(ASTContext &C) override; 91c6cf3295SJacob Lambert void HandleTagDeclDefinition(TagDecl *D) override; 92c6cf3295SJacob Lambert void HandleTagDeclRequiredDefinition(const TagDecl *D) override; 93c6cf3295SJacob Lambert void CompleteTentativeDefinition(VarDecl *D) override; 94ae0d2244SNick Zavaritsky void CompleteExternalDeclaration(DeclaratorDecl *D) override; 95c6cf3295SJacob Lambert void AssignInheritanceModel(CXXRecordDecl *RD) override; 96c6cf3295SJacob Lambert void HandleVTable(CXXRecordDecl *RD) override; 97c6cf3295SJacob Lambert 98c6cf3295SJacob Lambert // Links each entry in LinkModules into our module. Returns true on error. 992264544eSJacob Lambert bool LinkInModules(llvm::Module *M); 100c6cf3295SJacob Lambert 101c6cf3295SJacob Lambert /// Get the best possible source location to represent a diagnostic that 102c6cf3295SJacob Lambert /// may have associated debug info. 103c6cf3295SJacob Lambert const FullSourceLoc getBestLocationFromDebugLoc( 104c6cf3295SJacob Lambert const llvm::DiagnosticInfoWithLocationBase &D, 105c6cf3295SJacob Lambert bool &BadDebugInfo, StringRef &Filename, 106c6cf3295SJacob Lambert unsigned &Line, unsigned &Column) const; 107c6cf3295SJacob Lambert 108c6cf3295SJacob Lambert std::optional<FullSourceLoc> getFunctionSourceLocation( 109c6cf3295SJacob Lambert const llvm::Function &F) const; 110c6cf3295SJacob Lambert 111c6cf3295SJacob Lambert void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); 112c6cf3295SJacob Lambert /// Specialized handler for InlineAsm diagnostic. 113c6cf3295SJacob Lambert /// \return True if the diagnostic has been successfully reported, false 114c6cf3295SJacob Lambert /// otherwise. 115c6cf3295SJacob Lambert bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); 116c6cf3295SJacob Lambert /// Specialized handler for diagnostics reported using SMDiagnostic. 117c6cf3295SJacob Lambert void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D); 118c6cf3295SJacob Lambert /// Specialized handler for StackSize diagnostic. 119c6cf3295SJacob Lambert /// \return True if the diagnostic has been successfully reported, false 120c6cf3295SJacob Lambert /// otherwise. 121c6cf3295SJacob Lambert bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); 122c6cf3295SJacob Lambert /// Specialized handler for ResourceLimit diagnostic. 123c6cf3295SJacob Lambert /// \return True if the diagnostic has been successfully reported, false 124c6cf3295SJacob Lambert /// otherwise. 125c6cf3295SJacob Lambert bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit &D); 126c6cf3295SJacob Lambert 127c6cf3295SJacob Lambert /// Specialized handler for unsupported backend feature diagnostic. 128c6cf3295SJacob Lambert void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D); 129c6cf3295SJacob Lambert /// Specialized handlers for optimization remarks. 130c6cf3295SJacob Lambert /// Note that these handlers only accept remarks and they always handle 131c6cf3295SJacob Lambert /// them. 132c6cf3295SJacob Lambert void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, 133c6cf3295SJacob Lambert unsigned DiagID); 134c6cf3295SJacob Lambert void 135c6cf3295SJacob Lambert OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D); 136c6cf3295SJacob Lambert void OptimizationRemarkHandler( 137c6cf3295SJacob Lambert const llvm::OptimizationRemarkAnalysisFPCommute &D); 138c6cf3295SJacob Lambert void OptimizationRemarkHandler( 139c6cf3295SJacob Lambert const llvm::OptimizationRemarkAnalysisAliasing &D); 140c6cf3295SJacob Lambert void OptimizationFailureHandler( 141c6cf3295SJacob Lambert const llvm::DiagnosticInfoOptimizationFailure &D); 142c6cf3295SJacob Lambert void DontCallDiagHandler(const llvm::DiagnosticInfoDontCall &D); 143c6cf3295SJacob Lambert /// Specialized handler for misexpect warnings. 144c6cf3295SJacob Lambert /// Note that misexpect remarks are emitted through ORE 145c6cf3295SJacob Lambert void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D); 146c6cf3295SJacob Lambert }; 147c6cf3295SJacob Lambert 148c6cf3295SJacob Lambert } // namespace clang 149c6cf3295SJacob Lambert #endif 150