1 //===--- BackendConsumer.h - LLVM BackendConsumer Header File -------------===//
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
7 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H
10 #define LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H
12 #include "clang/CodeGen/BackendUtil.h"
13 #include "clang/CodeGen/CodeGenAction.h"
15 #include "llvm/IR/DiagnosticInfo.h"
16 #include "llvm/Support/Timer.h"
19 class DiagnosticInfoDontCall
;
25 class CoverageSourceInfo
;
27 class BackendConsumer
: public ASTConsumer
{
28 using LinkModule
= CodeGenAction::LinkModule
;
30 virtual void anchor();
31 DiagnosticsEngine
&Diags
;
33 const HeaderSearchOptions
&HeaderSearchOpts
;
34 const CodeGenOptions
&CodeGenOpts
;
35 const TargetOptions
&TargetOpts
;
36 const LangOptions
&LangOpts
;
37 std::unique_ptr
<raw_pwrite_stream
> AsmOutStream
;
39 IntrusiveRefCntPtr
<llvm::vfs::FileSystem
> FS
;
41 llvm::Timer LLVMIRGeneration
;
42 unsigned LLVMIRGenerationRefCount
;
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;
49 bool TimerIsEnabled
= false;
51 std::unique_ptr
<CodeGenerator
> Gen
;
53 SmallVector
<LinkModule
, 4> LinkModules
;
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
;
67 // This is here so that the diagnostic printer knows the module a diagnostic
69 llvm::Module
*CurLinkModule
= nullptr;
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);
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
,
94 CoverageSourceInfo
*CoverageInfo
= nullptr);
96 llvm::Module
*getModule() const;
97 std::unique_ptr
<llvm::Module
> takeModule();
99 CodeGenerator
*getCodeGenerator();
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
;
114 // Links each entry in LinkModules into our module. Returns true on error.
115 bool LinkInModules(llvm::Module
*M
);
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;
124 std::optional
<FullSourceLoc
> getFunctionSourceLocation(
125 const llvm::Function
&F
) const;
127 void DiagnosticHandlerImpl(const llvm::DiagnosticInfo
&DI
);
128 /// Specialized handler for InlineAsm diagnostic.
129 /// \return True if the diagnostic has been successfully reported, false
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
137 bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize
&D
);
138 /// Specialized handler for ResourceLimit diagnostic.
139 /// \return True if the diagnostic has been successfully reported, false
141 bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit
&D
);
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
148 void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase
&D
,
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
);