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