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