xref: /freebsd-src/contrib/llvm-project/clang/lib/CodeGen/BackendConsumer.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
15f757f3fSDimitry Andric //===--- BackendConsumer.h - LLVM BackendConsumer Header File -------------===//
25f757f3fSDimitry Andric //
35f757f3fSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f757f3fSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f757f3fSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65f757f3fSDimitry Andric //
75f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
85f757f3fSDimitry Andric 
95f757f3fSDimitry Andric #ifndef LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H
105f757f3fSDimitry Andric #define LLVM_CLANG_LIB_CODEGEN_BACKENDCONSUMER_H
115f757f3fSDimitry Andric 
125f757f3fSDimitry Andric #include "clang/CodeGen/BackendUtil.h"
135f757f3fSDimitry Andric #include "clang/CodeGen/CodeGenAction.h"
145f757f3fSDimitry Andric 
155f757f3fSDimitry Andric #include "llvm/IR/DiagnosticInfo.h"
165f757f3fSDimitry Andric #include "llvm/Support/Timer.h"
175f757f3fSDimitry Andric 
185f757f3fSDimitry Andric namespace llvm {
195f757f3fSDimitry Andric   class DiagnosticInfoDontCall;
205f757f3fSDimitry Andric }
215f757f3fSDimitry Andric 
225f757f3fSDimitry Andric namespace clang {
235f757f3fSDimitry Andric class ASTContext;
245f757f3fSDimitry Andric class CodeGenAction;
255f757f3fSDimitry Andric class CoverageSourceInfo;
265f757f3fSDimitry Andric 
275f757f3fSDimitry Andric class BackendConsumer : public ASTConsumer {
285f757f3fSDimitry Andric   using LinkModule = CodeGenAction::LinkModule;
295f757f3fSDimitry Andric 
305f757f3fSDimitry Andric   virtual void anchor();
315f757f3fSDimitry Andric   DiagnosticsEngine &Diags;
325f757f3fSDimitry Andric   BackendAction Action;
335f757f3fSDimitry Andric   const HeaderSearchOptions &HeaderSearchOpts;
345f757f3fSDimitry Andric   const CodeGenOptions &CodeGenOpts;
355f757f3fSDimitry Andric   const TargetOptions &TargetOpts;
365f757f3fSDimitry Andric   const LangOptions &LangOpts;
375f757f3fSDimitry Andric   std::unique_ptr<raw_pwrite_stream> AsmOutStream;
385f757f3fSDimitry Andric   ASTContext *Context;
395f757f3fSDimitry Andric   IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS;
405f757f3fSDimitry Andric 
415f757f3fSDimitry Andric   llvm::Timer LLVMIRGeneration;
425f757f3fSDimitry Andric   unsigned LLVMIRGenerationRefCount;
435f757f3fSDimitry Andric 
445f757f3fSDimitry Andric   /// True if we've finished generating IR. This prevents us from generating
455f757f3fSDimitry Andric   /// additional LLVM IR after emitting output in HandleTranslationUnit. This
465f757f3fSDimitry Andric   /// can happen when Clang plugins trigger additional AST deserialization.
475f757f3fSDimitry Andric   bool IRGenFinished = false;
485f757f3fSDimitry Andric 
495f757f3fSDimitry Andric   bool TimerIsEnabled = false;
505f757f3fSDimitry Andric 
515f757f3fSDimitry Andric   std::unique_ptr<CodeGenerator> Gen;
525f757f3fSDimitry Andric 
535f757f3fSDimitry Andric   SmallVector<LinkModule, 4> LinkModules;
545f757f3fSDimitry Andric 
555f757f3fSDimitry Andric   // A map from mangled names to their function's source location, used for
565f757f3fSDimitry Andric   // backend diagnostics as the Clang AST may be unavailable. We actually use
575f757f3fSDimitry Andric   // the mangled name's hash as the key because mangled names can be very
585f757f3fSDimitry Andric   // long and take up lots of space. Using a hash can cause name collision,
595f757f3fSDimitry Andric   // but that is rare and the consequences are pointing to a wrong source
605f757f3fSDimitry Andric   // location which is not severe. This is a vector instead of an actual map
615f757f3fSDimitry Andric   // because we optimize for time building this map rather than time
625f757f3fSDimitry Andric   // retrieving an entry, as backend diagnostics are uncommon.
635f757f3fSDimitry Andric   std::vector<std::pair<llvm::hash_code, FullSourceLoc>>
645f757f3fSDimitry Andric     ManglingFullSourceLocs;
655f757f3fSDimitry Andric 
665f757f3fSDimitry Andric 
675f757f3fSDimitry Andric   // This is here so that the diagnostic printer knows the module a diagnostic
685f757f3fSDimitry Andric   // refers to.
695f757f3fSDimitry Andric   llvm::Module *CurLinkModule = nullptr;
705f757f3fSDimitry Andric 
715f757f3fSDimitry Andric public:
725f757f3fSDimitry Andric   BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
735f757f3fSDimitry Andric                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
745f757f3fSDimitry Andric                   const HeaderSearchOptions &HeaderSearchOpts,
755f757f3fSDimitry Andric                   const PreprocessorOptions &PPOpts,
765f757f3fSDimitry Andric                   const CodeGenOptions &CodeGenOpts,
77*0fca6ea1SDimitry Andric                   const TargetOptions &TargetOpts, const LangOptions &LangOpts,
78*0fca6ea1SDimitry Andric                   const std::string &InFile,
795f757f3fSDimitry Andric                   SmallVector<LinkModule, 4> LinkModules,
805f757f3fSDimitry Andric                   std::unique_ptr<raw_pwrite_stream> OS, llvm::LLVMContext &C,
815f757f3fSDimitry Andric                   CoverageSourceInfo *CoverageInfo = nullptr);
825f757f3fSDimitry Andric 
835f757f3fSDimitry Andric   // This constructor is used in installing an empty BackendConsumer
845f757f3fSDimitry Andric   // to use the clang diagnostic handler for IR input files. It avoids
855f757f3fSDimitry Andric   // initializing the OS field.
865f757f3fSDimitry Andric   BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags,
875f757f3fSDimitry Andric                   IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS,
885f757f3fSDimitry Andric                   const HeaderSearchOptions &HeaderSearchOpts,
895f757f3fSDimitry Andric                   const PreprocessorOptions &PPOpts,
905f757f3fSDimitry Andric                   const CodeGenOptions &CodeGenOpts,
91*0fca6ea1SDimitry Andric                   const TargetOptions &TargetOpts, const LangOptions &LangOpts,
92*0fca6ea1SDimitry Andric                   llvm::Module *Module, SmallVector<LinkModule, 4> LinkModules,
93*0fca6ea1SDimitry Andric                   llvm::LLVMContext &C,
945f757f3fSDimitry Andric                   CoverageSourceInfo *CoverageInfo = nullptr);
955f757f3fSDimitry Andric 
965f757f3fSDimitry Andric   llvm::Module *getModule() const;
975f757f3fSDimitry Andric   std::unique_ptr<llvm::Module> takeModule();
985f757f3fSDimitry Andric 
995f757f3fSDimitry Andric   CodeGenerator *getCodeGenerator();
1005f757f3fSDimitry Andric 
1015f757f3fSDimitry Andric   void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override;
1025f757f3fSDimitry Andric   void Initialize(ASTContext &Ctx) override;
1035f757f3fSDimitry Andric   bool HandleTopLevelDecl(DeclGroupRef D) override;
1045f757f3fSDimitry Andric   void HandleInlineFunctionDefinition(FunctionDecl *D) override;
1055f757f3fSDimitry Andric   void HandleInterestingDecl(DeclGroupRef D) override;
1065f757f3fSDimitry Andric   void HandleTranslationUnit(ASTContext &C) override;
1075f757f3fSDimitry Andric   void HandleTagDeclDefinition(TagDecl *D) override;
1085f757f3fSDimitry Andric   void HandleTagDeclRequiredDefinition(const TagDecl *D) override;
1095f757f3fSDimitry Andric   void CompleteTentativeDefinition(VarDecl *D) override;
110*0fca6ea1SDimitry Andric   void CompleteExternalDeclaration(DeclaratorDecl *D) override;
1115f757f3fSDimitry Andric   void AssignInheritanceModel(CXXRecordDecl *RD) override;
1125f757f3fSDimitry Andric   void HandleVTable(CXXRecordDecl *RD) override;
1135f757f3fSDimitry Andric 
1145f757f3fSDimitry Andric   // Links each entry in LinkModules into our module.  Returns true on error.
115*0fca6ea1SDimitry Andric   bool LinkInModules(llvm::Module *M);
1165f757f3fSDimitry Andric 
1175f757f3fSDimitry Andric   /// Get the best possible source location to represent a diagnostic that
1185f757f3fSDimitry Andric   /// may have associated debug info.
1195f757f3fSDimitry Andric   const FullSourceLoc getBestLocationFromDebugLoc(
1205f757f3fSDimitry Andric     const llvm::DiagnosticInfoWithLocationBase &D,
1215f757f3fSDimitry Andric     bool &BadDebugInfo, StringRef &Filename,
1225f757f3fSDimitry Andric     unsigned &Line, unsigned &Column) const;
1235f757f3fSDimitry Andric 
1245f757f3fSDimitry Andric   std::optional<FullSourceLoc> getFunctionSourceLocation(
1255f757f3fSDimitry Andric     const llvm::Function &F) const;
1265f757f3fSDimitry Andric 
1275f757f3fSDimitry Andric   void DiagnosticHandlerImpl(const llvm::DiagnosticInfo &DI);
1285f757f3fSDimitry Andric   /// Specialized handler for InlineAsm diagnostic.
1295f757f3fSDimitry Andric   /// \return True if the diagnostic has been successfully reported, false
1305f757f3fSDimitry Andric   /// otherwise.
1315f757f3fSDimitry Andric   bool InlineAsmDiagHandler(const llvm::DiagnosticInfoInlineAsm &D);
1325f757f3fSDimitry Andric   /// Specialized handler for diagnostics reported using SMDiagnostic.
1335f757f3fSDimitry Andric   void SrcMgrDiagHandler(const llvm::DiagnosticInfoSrcMgr &D);
1345f757f3fSDimitry Andric   /// Specialized handler for StackSize diagnostic.
1355f757f3fSDimitry Andric   /// \return True if the diagnostic has been successfully reported, false
1365f757f3fSDimitry Andric   /// otherwise.
1375f757f3fSDimitry Andric   bool StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D);
1385f757f3fSDimitry Andric   /// Specialized handler for ResourceLimit diagnostic.
1395f757f3fSDimitry Andric   /// \return True if the diagnostic has been successfully reported, false
1405f757f3fSDimitry Andric   /// otherwise.
1415f757f3fSDimitry Andric   bool ResourceLimitDiagHandler(const llvm::DiagnosticInfoResourceLimit &D);
1425f757f3fSDimitry Andric 
1435f757f3fSDimitry Andric   /// Specialized handler for unsupported backend feature diagnostic.
1445f757f3fSDimitry Andric   void UnsupportedDiagHandler(const llvm::DiagnosticInfoUnsupported &D);
1455f757f3fSDimitry Andric   /// Specialized handlers for optimization remarks.
1465f757f3fSDimitry Andric   /// Note that these handlers only accept remarks and they always handle
1475f757f3fSDimitry Andric   /// them.
1485f757f3fSDimitry Andric   void EmitOptimizationMessage(const llvm::DiagnosticInfoOptimizationBase &D,
1495f757f3fSDimitry Andric                                unsigned DiagID);
1505f757f3fSDimitry Andric   void
1515f757f3fSDimitry Andric     OptimizationRemarkHandler(const llvm::DiagnosticInfoOptimizationBase &D);
1525f757f3fSDimitry Andric   void OptimizationRemarkHandler(
1535f757f3fSDimitry Andric     const llvm::OptimizationRemarkAnalysisFPCommute &D);
1545f757f3fSDimitry Andric   void OptimizationRemarkHandler(
1555f757f3fSDimitry Andric     const llvm::OptimizationRemarkAnalysisAliasing &D);
1565f757f3fSDimitry Andric   void OptimizationFailureHandler(
1575f757f3fSDimitry Andric     const llvm::DiagnosticInfoOptimizationFailure &D);
1585f757f3fSDimitry Andric   void DontCallDiagHandler(const llvm::DiagnosticInfoDontCall &D);
1595f757f3fSDimitry Andric   /// Specialized handler for misexpect warnings.
1605f757f3fSDimitry Andric   /// Note that misexpect remarks are emitted through ORE
1615f757f3fSDimitry Andric   void MisExpectDiagHandler(const llvm::DiagnosticInfoMisExpect &D);
1625f757f3fSDimitry Andric };
1635f757f3fSDimitry Andric 
1645f757f3fSDimitry Andric } // namespace clang
1655f757f3fSDimitry Andric #endif
166