|
| 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, |
| 78 | + const LangOptions &LangOpts, 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, |
| 92 | + const LangOptions &LangOpts, llvm::Module *Module, |
| 93 | + SmallVector<LinkModule, 4> LinkModules, 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(VarDecl *D) override; |
| 111 | + void AssignInheritanceModel(CXXRecordDecl *RD) override; |
| 112 | + void HandleVTable(CXXRecordDecl *RD) override; |
| 113 | + |
| 114 | + |
| 115 | + // Links each entry in LinkModules into our module. Returns true on error. |
| 116 | + bool LinkInModules(llvm::Module *M, bool ShouldLinkFiles = true); |
| 117 | + |
| 118 | + /// Get the best possible source location to represent a diagnostic that |
| 119 | + /// may have associated debug info. |
| 120 | + const FullSourceLoc getBestLocationFromDebugLoc( |
| 121 | + const llvm::DiagnosticInfoWithLocationBase &D, |
| 122 | + bool &BadDebugInfo, StringRef &Filename, |
| 123 | + unsigned &Line, unsigned &Column) const; |
| 124 | + |
| 125 | + std::optional<FullSourceLoc> getFunctionSourceLocation( |
| 126 | + const llvm::Function &F) const; |
| 127 | + |
| 128 | + void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI); |
| 129 | + /// Specialized handler for InlineAsm diagnostic. |
| 130 | + /// \return True if the diagnostic has been successfully reported, false |
| 131 | + /// otherwise. |
| 132 | + bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D); |
| 133 | + /// Specialized handler for diagnostics reported using SMDiagnostic. |
| 134 | + void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D); |
| 135 | + /// Specialized handler for StackSize diagnostic. |
| 136 | + /// \return True if the diagnostic has been successfully reported, false |
| 137 | + /// otherwise. |
| 138 | + bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D); |
| 139 | + /// Specialized handler for ResourceLimit diagnostic. |
| 140 | + /// \return True if the diagnostic has been successfully reported, false |
| 141 | + /// otherwise. |
| 142 | + bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit &D); |
| 143 | + |
| 144 | + /// Specialized handler for unsupported backend feature diagnostic. |
| 145 | + void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D); |
| 146 | + /// Specialized handlers for optimization remarks. |
| 147 | + /// Note that these handlers only accept remarks and they always handle |
| 148 | + /// them. |
| 149 | + void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D, |
| 150 | + unsigned DiagID); |
| 151 | + void |
| 152 | + OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D); |
| 153 | + void OptimizationRemarkHandler( |
| 154 | + const llvm::OptimizationRemarkAnalysisFPCommute &D); |
| 155 | + void OptimizationRemarkHandler( |
| 156 | + const llvm::OptimizationRemarkAnalysisAliasing &D); |
| 157 | + void OptimizationFailureHandler( |
| 158 | + const llvm::DiagnosticInfoOptimizationFailure &D); |
| 159 | + void DontCallDiagHandler(const llvm::DiagnosticInfoDontCall &D); |
| 160 | + /// Specialized handler for misexpect warnings. |
| 161 | + /// Note that misexpect remarks are emitted through ORE |
| 162 | + void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D); |
| 163 | +}; |
| 164 | + |
| 165 | +} // namespace clang |
| 166 | +#endif |
0 commit comments