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