15f757f3fSDimitry Andric //===--- BackendConsumer.h - LLVM BackendConsumer Header File -------------===// 25f757f3fSDimitry Andric // 35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65f757f3fSDimitry Andric // 75f757f3fSDimitry Andric //===----------------------------------------------------------------------===// 85f757f3fSDimitry Andric 95f757f3fSDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H 105f757f3fSDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H 115f757f3fSDimitry Andric 125f757f3fSDimitry Andric #include "clang/CodeGen/BackendUtil.h" 135f757f3fSDimitry Andric #include "clang/CodeGen/CodeGenAction.h" 145f757f3fSDimitry Andric 155f757f3fSDimitry Andric #include "llvm/IR/DiagnosticInfo.h" 165f757f3fSDimitry Andric #include "llvm/Support/Timer.h" 175f757f3fSDimitry Andric 185f757f3fSDimitry Andric namespace llvm { 195f757f3fSDimitry Andric class DiagnosticInfoDontCall; 205f757f3fSDimitry Andric } 215f757f3fSDimitry Andric 225f757f3fSDimitry Andric namespace clang { 235f757f3fSDimitry Andric class ASTContext; 245f757f3fSDimitry Andric class CodeGenAction; 255f757f3fSDimitry Andric class CoverageSourceInfo; 265f757f3fSDimitry Andric 275f757f3fSDimitry Andric class BackendConsumer : public ASTConsumer { 285f757f3fSDimitry Andric using LinkModule = CodeGenAction::LinkModule; 295f757f3fSDimitry Andric 305f757f3fSDimitry Andric virtual void anchor(); 315f757f3fSDimitry Andric DiagnosticsEngine &Diags; 325f757f3fSDimitry Andric BackendAction Action; 335f757f3fSDimitry Andric const HeaderSearchOptions &HeaderSearchOpts; 345f757f3fSDimitry Andric const CodeGenOptions &CodeGenOpts; 355f757f3fSDimitry Andric const TargetOptions &TargetOpts; 365f757f3fSDimitry Andric const LangOptions &LangOpts; 375f757f3fSDimitry Andric std::unique_ptr<raw_pwrite_stream> AsmOutStream; 385f757f3fSDimitry Andric ASTContext *Context; 395f757f3fSDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; 405f757f3fSDimitry Andric 415f757f3fSDimitry Andric llvm::Timer LLVMIRGeneration; 425f757f3fSDimitry Andric unsigned LLVMIRGenerationRefCount; 435f757f3fSDimitry Andric 445f757f3fSDimitry Andric /// True if we've finished generating IR. This prevents us from generating 455f757f3fSDimitry Andric /// additional LLVM IR after emitting output in HandleTranslationUnit. This 465f757f3fSDimitry Andric /// can happen when Clang plugins trigger additional AST deserialization. 475f757f3fSDimitry Andric bool IRGenFinished = false; 485f757f3fSDimitry Andric 495f757f3fSDimitry Andric bool TimerIsEnabled = false; 505f757f3fSDimitry Andric 515f757f3fSDimitry Andric std::unique_ptr<CodeGenerator> Gen; 525f757f3fSDimitry Andric 535f757f3fSDimitry Andric SmallVector<LinkModule, 4> LinkModules; 545f757f3fSDimitry Andric 555f757f3fSDimitry Andric // A map from mangled names to their function's source location, used for 565f757f3fSDimitry Andric // backend diagnostics as the Clang AST may be unavailable. We actually use 575f757f3fSDimitry Andric // the mangled name's hash as the key because mangled names can be very 585f757f3fSDimitry Andric // long and take up lots of space. Using a hash can cause name collision, 595f757f3fSDimitry Andric // but that is rare and the consequences are pointing to a wrong source 605f757f3fSDimitry Andric // location which is not severe. This is a vector instead of an actual map 615f757f3fSDimitry Andric // because we optimize for time building this map rather than time 625f757f3fSDimitry Andric // retrieving an entry, as backend diagnostics are uncommon. 635f757f3fSDimitry Andric std::vector<std::pair<llvm::hash_code, FullSourceLoc>> 645f757f3fSDimitry Andric ManglingFullSourceLocs; 655f757f3fSDimitry Andric 665f757f3fSDimitry Andric 675f757f3fSDimitry Andric // This is here so that the diagnostic printer knows the module a diagnostic 685f757f3fSDimitry Andric // refers to. 695f757f3fSDimitry Andric llvm::Module *CurLinkModule = nullptr; 705f757f3fSDimitry Andric 715f757f3fSDimitry Andric public: 725f757f3fSDimitry Andric BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, 735f757f3fSDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 745f757f3fSDimitry Andric const HeaderSearchOptions &HeaderSearchOpts, 755f757f3fSDimitry Andric const PreprocessorOptions &PPOpts, 765f757f3fSDimitry Andric const CodeGenOptions &CodeGenOpts, 77*0fca6ea1SDimitry Andric const TargetOptions &TargetOpts, const LangOptions &LangOpts, 78*0fca6ea1SDimitry Andric const std::string &InFile, 795f757f3fSDimitry Andric SmallVector<LinkModule, 4> LinkModules, 805f757f3fSDimitry Andric std::unique_ptr<raw_pwrite_stream> OS, llvm::LLVMContext &C, 815f757f3fSDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr); 825f757f3fSDimitry Andric 835f757f3fSDimitry Andric // This constructor is used in installing an empty BackendConsumer 845f757f3fSDimitry Andric // to use the clang diagnostic handler for IR input files. It avoids 855f757f3fSDimitry Andric // initializing the OS field. 865f757f3fSDimitry Andric BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, 875f757f3fSDimitry Andric IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 885f757f3fSDimitry Andric const HeaderSearchOptions &HeaderSearchOpts, 895f757f3fSDimitry Andric const PreprocessorOptions &PPOpts, 905f757f3fSDimitry Andric const CodeGenOptions &CodeGenOpts, 91*0fca6ea1SDimitry Andric const TargetOptions &TargetOpts, const LangOptions &LangOpts, 92*0fca6ea1SDimitry Andric llvm::Module *Module, SmallVector<LinkModule, 4> LinkModules, 93*0fca6ea1SDimitry Andric llvm::LLVMContext &C, 945f757f3fSDimitry Andric CoverageSourceInfo *CoverageInfo = nullptr); 955f757f3fSDimitry Andric 965f757f3fSDimitry Andric llvm::Module *getModule() const; 975f757f3fSDimitry Andric std::unique_ptr<llvm::Module> takeModule(); 985f757f3fSDimitry Andric 995f757f3fSDimitry Andric CodeGenerator *getCodeGenerator(); 1005f757f3fSDimitry Andric 1015f757f3fSDimitry Andric void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override; 1025f757f3fSDimitry Andric void Initialize(ASTContext &Ctx) override; 1035f757f3fSDimitry Andric bool HandleTopLevelDecl(DeclGroupRef D) override; 1045f757f3fSDimitry Andric void HandleInlineFunctionDefinition(FunctionDecl *D) override; 1055f757f3fSDimitry Andric void HandleInterestingDecl(DeclGroupRef D) override; 1065f757f3fSDimitry Andric void HandleTranslationUnit(ASTContext &C) override; 1075f757f3fSDimitry Andric void HandleTagDeclDefinition(TagDecl *D) override; 1085f757f3fSDimitry Andric void HandleTagDeclRequiredDefinition(const TagDecl *D) override; 1095f757f3fSDimitry Andric void CompleteTentativeDefinition(VarDecl *D) override; 110*0fca6ea1SDimitry Andric void CompleteExternalDeclaration(DeclaratorDecl *D) override; 1115f757f3fSDimitry Andric void AssignInheritanceModel(CXXRecordDecl *RD) override; 1125f757f3fSDimitry Andric void HandleVTable(CXXRecordDecl *RD) override; 1135f757f3fSDimitry Andric 1145f757f3fSDimitry Andric // Links each entry in LinkModules into our module. Returns true on error. 115*0fca6ea1SDimitry Andric bool LinkInModules(llvm::Module *M); 1165f757f3fSDimitry Andric 1175f757f3fSDimitry Andric /// Get the best possible source location to represent a diagnostic that 1185f757f3fSDimitry Andric /// may have associated debug info. 1195f757f3fSDimitry Andric const FullSourceLoc getBestLocationFromDebugLoc( 1205f757f3fSDimitry Andric const llvm::DiagnosticInfoWithLocationBase &D, 1215f757f3fSDimitry Andric bool &BadDebugInfo, StringRef &Filename, 1225f757f3fSDimitry Andric unsigned &Line, unsigned &Column) const; 1235f757f3fSDimitry Andric 1245f757f3fSDimitry Andric std::optional<FullSourceLoc> getFunctionSourceLocation( 1255f757f3fSDimitry Andric const llvm::Function &F) const; 1265f757f3fSDimitry Andric 1275f757f3fSDimitry Andric void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); 1285f757f3fSDimitry Andric /// Specialized handler for InlineAsm diagnostic. 1295f757f3fSDimitry Andric /// \return True if the diagnostic has been successfully reported, false 1305f757f3fSDimitry Andric /// otherwise. 1315f757f3fSDimitry Andric bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); 1325f757f3fSDimitry Andric /// Specialized handler for diagnostics reported using SMDiagnostic. 1335f757f3fSDimitry Andric void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D); 1345f757f3fSDimitry Andric /// Specialized handler for StackSize diagnostic. 1355f757f3fSDimitry Andric /// \return True if the diagnostic has been successfully reported, false 1365f757f3fSDimitry Andric /// otherwise. 1375f757f3fSDimitry Andric bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); 1385f757f3fSDimitry Andric /// Specialized handler for ResourceLimit diagnostic. 1395f757f3fSDimitry Andric /// \return True if the diagnostic has been successfully reported, false 1405f757f3fSDimitry Andric /// otherwise. 1415f757f3fSDimitry Andric bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit &D); 1425f757f3fSDimitry Andric 1435f757f3fSDimitry Andric /// Specialized handler for unsupported backend feature diagnostic. 1445f757f3fSDimitry Andric void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D); 1455f757f3fSDimitry Andric /// Specialized handlers for optimization remarks. 1465f757f3fSDimitry Andric /// Note that these handlers only accept remarks and they always handle 1475f757f3fSDimitry Andric /// them. 1485f757f3fSDimitry Andric void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, 1495f757f3fSDimitry Andric unsigned DiagID); 1505f757f3fSDimitry Andric void 1515f757f3fSDimitry Andric OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D); 1525f757f3fSDimitry Andric void OptimizationRemarkHandler( 1535f757f3fSDimitry Andric const llvm::OptimizationRemarkAnalysisFPCommute &D); 1545f757f3fSDimitry Andric void OptimizationRemarkHandler( 1555f757f3fSDimitry Andric const llvm::OptimizationRemarkAnalysisAliasing &D); 1565f757f3fSDimitry Andric void OptimizationFailureHandler( 1575f757f3fSDimitry Andric const llvm::DiagnosticInfoOptimizationFailure &D); 1585f757f3fSDimitry Andric void DontCallDiagHandler(const llvm::DiagnosticInfoDontCall &D); 1595f757f3fSDimitry Andric /// Specialized handler for misexpect warnings. 1605f757f3fSDimitry Andric /// Note that misexpect remarks are emitted through ORE 1615f757f3fSDimitry Andric void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D); 1625f757f3fSDimitry Andric }; 1635f757f3fSDimitry Andric 1645f757f3fSDimitry Andric } // namespace clang 1655f757f3fSDimitry Andric #endif 166