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