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