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 &; |
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 | (BackendAction Action, DiagnosticsEngine &Diags, |
73 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, |
74 | const HeaderSearchOptions &, |
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 | (BackendAction Action, DiagnosticsEngine &Diags, |
87 | IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, |
88 | const HeaderSearchOptions &, |
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 | |