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 | |