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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H 10 #define LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H 11 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 18 namespace llvm { 19 class DiagnosticInfoDontCall; 20 } 21 22 namespace clang { 23 class ASTContext; 24 class CodeGenAction; 25 class CoverageSourceInfo; 26 27 class 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 /// True if we've finished generating IR. This prevents us from generating 44 /// additional LLVM IR after emitting output in HandleTranslationUnit. This 45 /// can happen when Clang plugins trigger additional AST deserialization. 46 bool IRGenFinished = false; 47 48 bool TimerIsEnabled = false; 49 50 BackendAction Action; 51 52 std::unique_ptr<CodeGenerator> Gen; 53 54 SmallVector<LinkModule, 4> LinkModules; 55 56 // A map from mangled names to their function's source location, used for 57 // backend diagnostics as the Clang AST may be unavailable. We actually use 58 // the mangled name's hash as the key because mangled names can be very 59 // long and take up lots of space. Using a hash can cause name collision, 60 // but that is rare and the consequences are pointing to a wrong source 61 // location which is not severe. This is a vector instead of an actual map 62 // because we optimize for time building this map rather than time 63 // retrieving an entry, as backend diagnostics are uncommon. 64 std::vector<std::pair<llvm::hash_code, FullSourceLoc>> 65 ManglingFullSourceLocs; 66 67 68 // This is here so that the diagnostic printer knows the module a diagnostic 69 // refers to. 70 llvm::Module *CurLinkModule = nullptr; 71 72 public: 73 BackendConsumer(CompilerInstance &CI, BackendAction Action, 74 IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, 75 llvm::LLVMContext &C, SmallVector<LinkModule, 4> LinkModules, 76 StringRef InFile, std::unique_ptr<raw_pwrite_stream> OS, 77 CoverageSourceInfo *CoverageInfo, 78 llvm::Module *CurLinkModule = nullptr); 79 80 llvm::Module *getModule() const; 81 std::unique_ptr<llvm::Module> takeModule(); 82 83 CodeGenerator *getCodeGenerator(); 84 85 void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override; 86 void Initialize(ASTContext &Ctx) override; 87 bool HandleTopLevelDecl(DeclGroupRef D) override; 88 void HandleInlineFunctionDefinition(FunctionDecl *D) override; 89 void HandleInterestingDecl(DeclGroupRef D) override; 90 void HandleTranslationUnit(ASTContext &C) override; 91 void HandleTagDeclDefinition(TagDecl *D) override; 92 void HandleTagDeclRequiredDefinition(const TagDecl *D) override; 93 void CompleteTentativeDefinition(VarDecl *D) override; 94 void CompleteExternalDeclaration(DeclaratorDecl *D) override; 95 void AssignInheritanceModel(CXXRecordDecl *RD) override; 96 void HandleVTable(CXXRecordDecl *RD) override; 97 98 // Links each entry in LinkModules into our module. Returns true on error. 99 bool LinkInModules(llvm::Module *M); 100 101 /// Get the best possible source location to represent a diagnostic that 102 /// may have associated debug info. 103 const FullSourceLoc getBestLocationFromDebugLoc( 104 const llvm::DiagnosticInfoWithLocationBase &D, 105 bool &BadDebugInfo, StringRef &Filename, 106 unsigned &Line, unsigned &Column) const; 107 108 std::optional<FullSourceLoc> getFunctionSourceLocation( 109 const llvm::Function &F) const; 110 111 void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); 112 /// Specialized handler for InlineAsm diagnostic. 113 /// \return True if the diagnostic has been successfully reported, false 114 /// otherwise. 115 bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); 116 /// Specialized handler for diagnostics reported using SMDiagnostic. 117 void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D); 118 /// Specialized handler for StackSize diagnostic. 119 /// \return True if the diagnostic has been successfully reported, false 120 /// otherwise. 121 bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); 122 /// Specialized handler for ResourceLimit diagnostic. 123 /// \return True if the diagnostic has been successfully reported, false 124 /// otherwise. 125 bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit &D); 126 127 /// Specialized handler for unsupported backend feature diagnostic. 128 void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D); 129 /// Specialized handlers for optimization remarks. 130 /// Note that these handlers only accept remarks and they always handle 131 /// them. 132 void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, 133 unsigned DiagID); 134 void 135 OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D); 136 void OptimizationRemarkHandler( 137 const llvm::OptimizationRemarkAnalysisFPCommute &D); 138 void OptimizationRemarkHandler( 139 const llvm::OptimizationRemarkAnalysisAliasing &D); 140 void OptimizationFailureHandler( 141 const llvm::DiagnosticInfoOptimizationFailure &D); 142 void DontCallDiagHandler(const llvm::DiagnosticInfoDontCall &D); 143 /// Specialized handler for misexpect warnings. 144 /// Note that misexpect remarks are emitted through ORE 145 void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D); 146 }; 147 148 } // namespace clang 149 #endif 150