xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/BackendConsumer.h (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 &HeaderSearchOpts;
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   BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
73                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
74                   const HeaderSearchOptions &HeaderSearchOpts,
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   BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
87                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
88                   const HeaderSearchOptions &HeaderSearchOpts,
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