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