xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/BackendConsumer.h (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1*5f757f3fSDimitry Andric //===--- BackendConsumer.h - LLVM BackendConsumer Header File -------------===//
2*5f757f3fSDimitry Andric //
3*5f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*5f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*5f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*5f757f3fSDimitry Andric //
7*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
8*5f757f3fSDimitry Andric 
9*5f757f3fSDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H
10*5f757f3fSDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H
11*5f757f3fSDimitry Andric 
12*5f757f3fSDimitry Andric #include "clang/CodeGen/BackendUtil.h"
13*5f757f3fSDimitry Andric #include "clang/CodeGen/CodeGenAction.h"
14*5f757f3fSDimitry Andric 
15*5f757f3fSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
16*5f757f3fSDimitry Andric #include "llvm/Support/Timer.h"
17*5f757f3fSDimitry Andric 
18*5f757f3fSDimitry Andric namespace llvm {
19*5f757f3fSDimitry Andric   class DiagnosticInfoDontCall;
20*5f757f3fSDimitry Andric }
21*5f757f3fSDimitry Andric 
22*5f757f3fSDimitry Andric namespace clang {
23*5f757f3fSDimitry Andric class ASTContext;
24*5f757f3fSDimitry Andric class CodeGenAction;
25*5f757f3fSDimitry Andric class CoverageSourceInfo;
26*5f757f3fSDimitry Andric 
27*5f757f3fSDimitry Andric class BackendConsumer : public ASTConsumer {
28*5f757f3fSDimitry Andric   using LinkModule = CodeGenAction::LinkModule;
29*5f757f3fSDimitry Andric 
30*5f757f3fSDimitry Andric   virtual void anchor();
31*5f757f3fSDimitry Andric   DiagnosticsEngine &Diags;
32*5f757f3fSDimitry Andric   BackendAction Action;
33*5f757f3fSDimitry Andric   const HeaderSearchOptions &HeaderSearchOpts;
34*5f757f3fSDimitry Andric   const CodeGenOptions &CodeGenOpts;
35*5f757f3fSDimitry Andric   const TargetOptions &TargetOpts;
36*5f757f3fSDimitry Andric   const LangOptions &LangOpts;
37*5f757f3fSDimitry Andric   std::unique_ptr<raw_pwrite_stream> AsmOutStream;
38*5f757f3fSDimitry Andric   ASTContext *Context;
39*5f757f3fSDimitry Andric   IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
40*5f757f3fSDimitry Andric 
41*5f757f3fSDimitry Andric   llvm::Timer LLVMIRGeneration;
42*5f757f3fSDimitry Andric   unsigned LLVMIRGenerationRefCount;
43*5f757f3fSDimitry Andric 
44*5f757f3fSDimitry Andric   /// True if we've finished generating IR. This prevents us from generating
45*5f757f3fSDimitry Andric   /// additional LLVM IR after emitting output in HandleTranslationUnit. This
46*5f757f3fSDimitry Andric   /// can happen when Clang plugins trigger additional AST deserialization.
47*5f757f3fSDimitry Andric   bool IRGenFinished = false;
48*5f757f3fSDimitry Andric 
49*5f757f3fSDimitry Andric   bool TimerIsEnabled = false;
50*5f757f3fSDimitry Andric 
51*5f757f3fSDimitry Andric   std::unique_ptr<CodeGenerator> Gen;
52*5f757f3fSDimitry Andric 
53*5f757f3fSDimitry Andric   SmallVector<LinkModule, 4> LinkModules;
54*5f757f3fSDimitry Andric 
55*5f757f3fSDimitry Andric   // A map from mangled names to their function's source location, used for
56*5f757f3fSDimitry Andric   // backend diagnostics as the Clang AST may be unavailable. We actually use
57*5f757f3fSDimitry Andric   // the mangled name's hash as the key because mangled names can be very
58*5f757f3fSDimitry Andric   // long and take up lots of space. Using a hash can cause name collision,
59*5f757f3fSDimitry Andric   // but that is rare and the consequences are pointing to a wrong source
60*5f757f3fSDimitry Andric   // location which is not severe. This is a vector instead of an actual map
61*5f757f3fSDimitry Andric   // because we optimize for time building this map rather than time
62*5f757f3fSDimitry Andric   // retrieving an entry, as backend diagnostics are uncommon.
63*5f757f3fSDimitry Andric   std::vector<std::pair<llvm::hash_code, FullSourceLoc>>
64*5f757f3fSDimitry Andric     ManglingFullSourceLocs;
65*5f757f3fSDimitry Andric 
66*5f757f3fSDimitry Andric 
67*5f757f3fSDimitry Andric   // This is here so that the diagnostic printer knows the module a diagnostic
68*5f757f3fSDimitry Andric   // refers to.
69*5f757f3fSDimitry Andric   llvm::Module *CurLinkModule = nullptr;
70*5f757f3fSDimitry Andric 
71*5f757f3fSDimitry Andric public:
72*5f757f3fSDimitry Andric   BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
73*5f757f3fSDimitry Andric                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
74*5f757f3fSDimitry Andric                   const HeaderSearchOptions &HeaderSearchOpts,
75*5f757f3fSDimitry Andric                   const PreprocessorOptions &PPOpts,
76*5f757f3fSDimitry Andric                   const CodeGenOptions &CodeGenOpts,
77*5f757f3fSDimitry Andric                   const TargetOptions &TargetOpts,
78*5f757f3fSDimitry Andric                   const LangOptions &LangOpts, const std::string &InFile,
79*5f757f3fSDimitry Andric                   SmallVector<LinkModule, 4> LinkModules,
80*5f757f3fSDimitry Andric                   std::unique_ptr<raw_pwrite_stream> OS, llvm::LLVMContext &C,
81*5f757f3fSDimitry Andric                   CoverageSourceInfo *CoverageInfo = nullptr);
82*5f757f3fSDimitry Andric 
83*5f757f3fSDimitry Andric   // This constructor is used in installing an empty BackendConsumer
84*5f757f3fSDimitry Andric   // to use the clang diagnostic handler for IR input files. It avoids
85*5f757f3fSDimitry Andric   // initializing the OS field.
86*5f757f3fSDimitry Andric   BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
87*5f757f3fSDimitry Andric                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
88*5f757f3fSDimitry Andric                   const HeaderSearchOptions &HeaderSearchOpts,
89*5f757f3fSDimitry Andric                   const PreprocessorOptions &PPOpts,
90*5f757f3fSDimitry Andric                   const CodeGenOptions &CodeGenOpts,
91*5f757f3fSDimitry Andric                   const TargetOptions &TargetOpts,
92*5f757f3fSDimitry Andric                   const LangOptions &LangOpts, llvm::Module *Module,
93*5f757f3fSDimitry Andric                   SmallVector<LinkModule, 4> LinkModules, llvm::LLVMContext &C,
94*5f757f3fSDimitry Andric                   CoverageSourceInfo *CoverageInfo = nullptr);
95*5f757f3fSDimitry Andric 
96*5f757f3fSDimitry Andric   llvm::Module *getModule() const;
97*5f757f3fSDimitry Andric   std::unique_ptr<llvm::Module> takeModule();
98*5f757f3fSDimitry Andric 
99*5f757f3fSDimitry Andric   CodeGenerator *getCodeGenerator();
100*5f757f3fSDimitry Andric 
101*5f757f3fSDimitry Andric   void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
102*5f757f3fSDimitry Andric   void Initialize(ASTContext &Ctx) override;
103*5f757f3fSDimitry Andric   bool HandleTopLevelDecl(DeclGroupRef D) override;
104*5f757f3fSDimitry Andric   void HandleInlineFunctionDefinition(FunctionDecl *D) override;
105*5f757f3fSDimitry Andric   void HandleInterestingDecl(DeclGroupRef D) override;
106*5f757f3fSDimitry Andric   void HandleTranslationUnit(ASTContext &C) override;
107*5f757f3fSDimitry Andric   void HandleTagDeclDefinition(TagDecl *D) override;
108*5f757f3fSDimitry Andric   void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
109*5f757f3fSDimitry Andric   void CompleteTentativeDefinition(VarDecl *D) override;
110*5f757f3fSDimitry Andric   void CompleteExternalDeclaration(VarDecl *D) override;
111*5f757f3fSDimitry Andric   void AssignInheritanceModel(CXXRecordDecl *RD) override;
112*5f757f3fSDimitry Andric   void HandleVTable(CXXRecordDecl *RD) override;
113*5f757f3fSDimitry Andric 
114*5f757f3fSDimitry Andric 
115*5f757f3fSDimitry Andric  // Links each entry in LinkModules into our module.  Returns true on error.
116*5f757f3fSDimitry Andric   bool LinkInModules(llvm::Module *M, bool ShouldLinkFiles = true);
117*5f757f3fSDimitry Andric 
118*5f757f3fSDimitry Andric   /// Get the best possible source location to represent a diagnostic that
119*5f757f3fSDimitry Andric   /// may have associated debug info.
120*5f757f3fSDimitry Andric   const FullSourceLoc getBestLocationFromDebugLoc(
121*5f757f3fSDimitry Andric     const llvm::DiagnosticInfoWithLocationBase &D,
122*5f757f3fSDimitry Andric     bool &BadDebugInfo, StringRef &Filename,
123*5f757f3fSDimitry Andric     unsigned &Line, unsigned &Column) const;
124*5f757f3fSDimitry Andric 
125*5f757f3fSDimitry Andric   std::optional<FullSourceLoc> getFunctionSourceLocation(
126*5f757f3fSDimitry Andric     const llvm::Function &F) const;
127*5f757f3fSDimitry Andric 
128*5f757f3fSDimitry Andric   void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
129*5f757f3fSDimitry Andric   /// Specialized handler for InlineAsm diagnostic.
130*5f757f3fSDimitry Andric   /// \return True if the diagnostic has been successfully reported, false
131*5f757f3fSDimitry Andric   /// otherwise.
132*5f757f3fSDimitry Andric   bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
133*5f757f3fSDimitry Andric   /// Specialized handler for diagnostics reported using SMDiagnostic.
134*5f757f3fSDimitry Andric   void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D);
135*5f757f3fSDimitry Andric   /// Specialized handler for StackSize diagnostic.
136*5f757f3fSDimitry Andric   /// \return True if the diagnostic has been successfully reported, false
137*5f757f3fSDimitry Andric   /// otherwise.
138*5f757f3fSDimitry Andric   bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
139*5f757f3fSDimitry Andric   /// Specialized handler for ResourceLimit diagnostic.
140*5f757f3fSDimitry Andric   /// \return True if the diagnostic has been successfully reported, false
141*5f757f3fSDimitry Andric   /// otherwise.
142*5f757f3fSDimitry Andric   bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit &D);
143*5f757f3fSDimitry Andric 
144*5f757f3fSDimitry Andric   /// Specialized handler for unsupported backend feature diagnostic.
145*5f757f3fSDimitry Andric   void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);
146*5f757f3fSDimitry Andric   /// Specialized handlers for optimization remarks.
147*5f757f3fSDimitry Andric   /// Note that these handlers only accept remarks and they always handle
148*5f757f3fSDimitry Andric   /// them.
149*5f757f3fSDimitry Andric   void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
150*5f757f3fSDimitry Andric                                unsigned DiagID);
151*5f757f3fSDimitry Andric   void
152*5f757f3fSDimitry Andric     OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
153*5f757f3fSDimitry Andric   void OptimizationRemarkHandler(
154*5f757f3fSDimitry Andric     const llvm::OptimizationRemarkAnalysisFPCommute &D);
155*5f757f3fSDimitry Andric   void OptimizationRemarkHandler(
156*5f757f3fSDimitry Andric     const llvm::OptimizationRemarkAnalysisAliasing &D);
157*5f757f3fSDimitry Andric   void OptimizationFailureHandler(
158*5f757f3fSDimitry Andric     const llvm::DiagnosticInfoOptimizationFailure &D);
159*5f757f3fSDimitry Andric   void DontCallDiagHandler(const llvm::DiagnosticInfoDontCall &D);
160*5f757f3fSDimitry Andric   /// Specialized handler for misexpect warnings.
161*5f757f3fSDimitry Andric   /// Note that misexpect remarks are emitted through ORE
162*5f757f3fSDimitry Andric   void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D);
163*5f757f3fSDimitry Andric };
164*5f757f3fSDimitry Andric 
165*5f757f3fSDimitry Andric } // namespace clang
166*5f757f3fSDimitry Andric #endif
167