xref: /netbsd-src/external/apache2/llvm/dist/clang/lib/CodeGen/ModuleBuilder.cpp (revision e038c9c4676b0f19b1b7dd08a940c6ed64a6d5ae)
17330f729Sjoerg //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
27330f729Sjoerg //
37330f729Sjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
47330f729Sjoerg // See https://llvm.org/LICENSE.txt for license information.
57330f729Sjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
67330f729Sjoerg //
77330f729Sjoerg //===----------------------------------------------------------------------===//
87330f729Sjoerg //
97330f729Sjoerg // This builds an AST and converts it to LLVM Code.
107330f729Sjoerg //
117330f729Sjoerg //===----------------------------------------------------------------------===//
127330f729Sjoerg 
137330f729Sjoerg #include "clang/CodeGen/ModuleBuilder.h"
147330f729Sjoerg #include "CGDebugInfo.h"
157330f729Sjoerg #include "CodeGenModule.h"
167330f729Sjoerg #include "clang/AST/ASTContext.h"
177330f729Sjoerg #include "clang/AST/DeclObjC.h"
187330f729Sjoerg #include "clang/AST/Expr.h"
197330f729Sjoerg #include "clang/Basic/CodeGenOptions.h"
207330f729Sjoerg #include "clang/Basic/Diagnostic.h"
217330f729Sjoerg #include "clang/Basic/TargetInfo.h"
227330f729Sjoerg #include "llvm/ADT/StringRef.h"
237330f729Sjoerg #include "llvm/IR/DataLayout.h"
247330f729Sjoerg #include "llvm/IR/LLVMContext.h"
257330f729Sjoerg #include "llvm/IR/Module.h"
267330f729Sjoerg #include <memory>
277330f729Sjoerg 
287330f729Sjoerg using namespace clang;
297330f729Sjoerg using namespace CodeGen;
307330f729Sjoerg 
317330f729Sjoerg namespace {
327330f729Sjoerg   class CodeGeneratorImpl : public CodeGenerator {
337330f729Sjoerg     DiagnosticsEngine &Diags;
347330f729Sjoerg     ASTContext *Ctx;
357330f729Sjoerg     const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
367330f729Sjoerg     const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
377330f729Sjoerg     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
387330f729Sjoerg 
397330f729Sjoerg     unsigned HandlingTopLevelDecls;
407330f729Sjoerg 
417330f729Sjoerg     /// Use this when emitting decls to block re-entrant decl emission. It will
427330f729Sjoerg     /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl
437330f729Sjoerg     /// emission must be deferred longer, like at the end of a tag definition.
447330f729Sjoerg     struct HandlingTopLevelDeclRAII {
457330f729Sjoerg       CodeGeneratorImpl &Self;
467330f729Sjoerg       bool EmitDeferred;
HandlingTopLevelDeclRAII__anon20d6d9160111::CodeGeneratorImpl::HandlingTopLevelDeclRAII477330f729Sjoerg       HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
487330f729Sjoerg                                bool EmitDeferred = true)
497330f729Sjoerg           : Self(Self), EmitDeferred(EmitDeferred) {
507330f729Sjoerg         ++Self.HandlingTopLevelDecls;
517330f729Sjoerg       }
~HandlingTopLevelDeclRAII__anon20d6d9160111::CodeGeneratorImpl::HandlingTopLevelDeclRAII527330f729Sjoerg       ~HandlingTopLevelDeclRAII() {
537330f729Sjoerg         unsigned Level = --Self.HandlingTopLevelDecls;
547330f729Sjoerg         if (Level == 0 && EmitDeferred)
557330f729Sjoerg           Self.EmitDeferredDecls();
567330f729Sjoerg       }
577330f729Sjoerg     };
587330f729Sjoerg 
597330f729Sjoerg     CoverageSourceInfo *CoverageInfo;
607330f729Sjoerg 
617330f729Sjoerg   protected:
627330f729Sjoerg     std::unique_ptr<llvm::Module> M;
637330f729Sjoerg     std::unique_ptr<CodeGen::CodeGenModule> Builder;
647330f729Sjoerg 
657330f729Sjoerg   private:
667330f729Sjoerg     SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
677330f729Sjoerg 
ExpandModuleName(llvm::StringRef ModuleName,const CodeGenOptions & CGO)687330f729Sjoerg     static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
697330f729Sjoerg                                             const CodeGenOptions &CGO) {
707330f729Sjoerg       if (ModuleName == "-" && !CGO.MainFileName.empty())
717330f729Sjoerg         return CGO.MainFileName;
727330f729Sjoerg       return ModuleName;
737330f729Sjoerg     }
747330f729Sjoerg 
757330f729Sjoerg   public:
CodeGeneratorImpl(DiagnosticsEngine & diags,llvm::StringRef ModuleName,const HeaderSearchOptions & HSO,const PreprocessorOptions & PPO,const CodeGenOptions & CGO,llvm::LLVMContext & C,CoverageSourceInfo * CoverageInfo=nullptr)767330f729Sjoerg     CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
777330f729Sjoerg                       const HeaderSearchOptions &HSO,
787330f729Sjoerg                       const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
797330f729Sjoerg                       llvm::LLVMContext &C,
807330f729Sjoerg                       CoverageSourceInfo *CoverageInfo = nullptr)
817330f729Sjoerg         : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
827330f729Sjoerg           PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
837330f729Sjoerg           CoverageInfo(CoverageInfo),
847330f729Sjoerg           M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {
857330f729Sjoerg       C.setDiscardValueNames(CGO.DiscardValueNames);
867330f729Sjoerg     }
877330f729Sjoerg 
~CodeGeneratorImpl()887330f729Sjoerg     ~CodeGeneratorImpl() override {
897330f729Sjoerg       // There should normally not be any leftover inline method definitions.
907330f729Sjoerg       assert(DeferredInlineMemberFuncDefs.empty() ||
917330f729Sjoerg              Diags.hasErrorOccurred());
927330f729Sjoerg     }
937330f729Sjoerg 
CGM()947330f729Sjoerg     CodeGenModule &CGM() {
957330f729Sjoerg       return *Builder;
967330f729Sjoerg     }
977330f729Sjoerg 
GetModule()987330f729Sjoerg     llvm::Module *GetModule() {
997330f729Sjoerg       return M.get();
1007330f729Sjoerg     }
1017330f729Sjoerg 
getCGDebugInfo()1027330f729Sjoerg     CGDebugInfo *getCGDebugInfo() {
1037330f729Sjoerg       return Builder->getModuleDebugInfo();
1047330f729Sjoerg     }
1057330f729Sjoerg 
ReleaseModule()1067330f729Sjoerg     llvm::Module *ReleaseModule() {
1077330f729Sjoerg       return M.release();
1087330f729Sjoerg     }
1097330f729Sjoerg 
GetDeclForMangledName(StringRef MangledName)1107330f729Sjoerg     const Decl *GetDeclForMangledName(StringRef MangledName) {
1117330f729Sjoerg       GlobalDecl Result;
1127330f729Sjoerg       if (!Builder->lookupRepresentativeDecl(MangledName, Result))
1137330f729Sjoerg         return nullptr;
1147330f729Sjoerg       const Decl *D = Result.getCanonicalDecl().getDecl();
1157330f729Sjoerg       if (auto FD = dyn_cast<FunctionDecl>(D)) {
1167330f729Sjoerg         if (FD->hasBody(FD))
1177330f729Sjoerg           return FD;
1187330f729Sjoerg       } else if (auto TD = dyn_cast<TagDecl>(D)) {
1197330f729Sjoerg         if (auto Def = TD->getDefinition())
1207330f729Sjoerg           return Def;
1217330f729Sjoerg       }
1227330f729Sjoerg       return D;
1237330f729Sjoerg     }
1247330f729Sjoerg 
GetAddrOfGlobal(GlobalDecl global,bool isForDefinition)1257330f729Sjoerg     llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
1267330f729Sjoerg       return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));
1277330f729Sjoerg     }
1287330f729Sjoerg 
StartModule(llvm::StringRef ModuleName,llvm::LLVMContext & C)1297330f729Sjoerg     llvm::Module *StartModule(llvm::StringRef ModuleName,
1307330f729Sjoerg                               llvm::LLVMContext &C) {
1317330f729Sjoerg       assert(!M && "Replacing existing Module?");
1327330f729Sjoerg       M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
1337330f729Sjoerg       Initialize(*Ctx);
1347330f729Sjoerg       return M.get();
1357330f729Sjoerg     }
1367330f729Sjoerg 
Initialize(ASTContext & Context)1377330f729Sjoerg     void Initialize(ASTContext &Context) override {
1387330f729Sjoerg       Ctx = &Context;
1397330f729Sjoerg 
1407330f729Sjoerg       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
141*e038c9c4Sjoerg       M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
1427330f729Sjoerg       const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
1437330f729Sjoerg       if (!SDKVersion.empty())
1447330f729Sjoerg         M->setSDKVersion(SDKVersion);
1457330f729Sjoerg       Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
1467330f729Sjoerg                                                PreprocessorOpts, CodeGenOpts,
1477330f729Sjoerg                                                *M, Diags, CoverageInfo));
1487330f729Sjoerg 
1497330f729Sjoerg       for (auto &&Lib : CodeGenOpts.DependentLibraries)
1507330f729Sjoerg         Builder->AddDependentLib(Lib);
1517330f729Sjoerg       for (auto &&Opt : CodeGenOpts.LinkerOptions)
1527330f729Sjoerg         Builder->AppendLinkerOptions(Opt);
1537330f729Sjoerg     }
1547330f729Sjoerg 
HandleCXXStaticMemberVarInstantiation(VarDecl * VD)1557330f729Sjoerg     void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
1567330f729Sjoerg       if (Diags.hasErrorOccurred())
1577330f729Sjoerg         return;
1587330f729Sjoerg 
1597330f729Sjoerg       Builder->HandleCXXStaticMemberVarInstantiation(VD);
1607330f729Sjoerg     }
1617330f729Sjoerg 
HandleTopLevelDecl(DeclGroupRef DG)1627330f729Sjoerg     bool HandleTopLevelDecl(DeclGroupRef DG) override {
1637330f729Sjoerg       if (Diags.hasErrorOccurred())
1647330f729Sjoerg         return true;
1657330f729Sjoerg 
1667330f729Sjoerg       HandlingTopLevelDeclRAII HandlingDecl(*this);
1677330f729Sjoerg 
1687330f729Sjoerg       // Make sure to emit all elements of a Decl.
1697330f729Sjoerg       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
1707330f729Sjoerg         Builder->EmitTopLevelDecl(*I);
1717330f729Sjoerg 
1727330f729Sjoerg       return true;
1737330f729Sjoerg     }
1747330f729Sjoerg 
EmitDeferredDecls()1757330f729Sjoerg     void EmitDeferredDecls() {
1767330f729Sjoerg       if (DeferredInlineMemberFuncDefs.empty())
1777330f729Sjoerg         return;
1787330f729Sjoerg 
1797330f729Sjoerg       // Emit any deferred inline method definitions. Note that more deferred
1807330f729Sjoerg       // methods may be added during this loop, since ASTConsumer callbacks
1817330f729Sjoerg       // can be invoked if AST inspection results in declarations being added.
1827330f729Sjoerg       HandlingTopLevelDeclRAII HandlingDecl(*this);
1837330f729Sjoerg       for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
1847330f729Sjoerg         Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
1857330f729Sjoerg       DeferredInlineMemberFuncDefs.clear();
1867330f729Sjoerg     }
1877330f729Sjoerg 
HandleInlineFunctionDefinition(FunctionDecl * D)1887330f729Sjoerg     void HandleInlineFunctionDefinition(FunctionDecl *D) override {
1897330f729Sjoerg       if (Diags.hasErrorOccurred())
1907330f729Sjoerg         return;
1917330f729Sjoerg 
1927330f729Sjoerg       assert(D->doesThisDeclarationHaveABody());
1937330f729Sjoerg 
1947330f729Sjoerg       // We may want to emit this definition. However, that decision might be
1957330f729Sjoerg       // based on computing the linkage, and we have to defer that in case we
1967330f729Sjoerg       // are inside of something that will change the method's final linkage,
1977330f729Sjoerg       // e.g.
1987330f729Sjoerg       //   typedef struct {
1997330f729Sjoerg       //     void bar();
2007330f729Sjoerg       //     void foo() { bar(); }
2017330f729Sjoerg       //   } A;
2027330f729Sjoerg       DeferredInlineMemberFuncDefs.push_back(D);
2037330f729Sjoerg 
2047330f729Sjoerg       // Provide some coverage mapping even for methods that aren't emitted.
2057330f729Sjoerg       // Don't do this for templated classes though, as they may not be
2067330f729Sjoerg       // instantiable.
2077330f729Sjoerg       if (!D->getLexicalDeclContext()->isDependentContext())
2087330f729Sjoerg         Builder->AddDeferredUnusedCoverageMapping(D);
2097330f729Sjoerg     }
2107330f729Sjoerg 
2117330f729Sjoerg     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
2127330f729Sjoerg     /// to (e.g. struct, union, enum, class) is completed. This allows the
2137330f729Sjoerg     /// client hack on the type, which can occur at any point in the file
2147330f729Sjoerg     /// (because these can be defined in declspecs).
HandleTagDeclDefinition(TagDecl * D)2157330f729Sjoerg     void HandleTagDeclDefinition(TagDecl *D) override {
2167330f729Sjoerg       if (Diags.hasErrorOccurred())
2177330f729Sjoerg         return;
2187330f729Sjoerg 
2197330f729Sjoerg       // Don't allow re-entrant calls to CodeGen triggered by PCH
2207330f729Sjoerg       // deserialization to emit deferred decls.
2217330f729Sjoerg       HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
2227330f729Sjoerg 
2237330f729Sjoerg       Builder->UpdateCompletedType(D);
2247330f729Sjoerg 
2257330f729Sjoerg       // For MSVC compatibility, treat declarations of static data members with
2267330f729Sjoerg       // inline initializers as definitions.
2277330f729Sjoerg       if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
2287330f729Sjoerg         for (Decl *Member : D->decls()) {
2297330f729Sjoerg           if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
2307330f729Sjoerg             if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
2317330f729Sjoerg                 Ctx->DeclMustBeEmitted(VD)) {
2327330f729Sjoerg               Builder->EmitGlobal(VD);
2337330f729Sjoerg             }
2347330f729Sjoerg           }
2357330f729Sjoerg         }
2367330f729Sjoerg       }
2377330f729Sjoerg       // For OpenMP emit declare reduction functions, if required.
2387330f729Sjoerg       if (Ctx->getLangOpts().OpenMP) {
2397330f729Sjoerg         for (Decl *Member : D->decls()) {
2407330f729Sjoerg           if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
2417330f729Sjoerg             if (Ctx->DeclMustBeEmitted(DRD))
2427330f729Sjoerg               Builder->EmitGlobal(DRD);
2437330f729Sjoerg           } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Member)) {
2447330f729Sjoerg             if (Ctx->DeclMustBeEmitted(DMD))
2457330f729Sjoerg               Builder->EmitGlobal(DMD);
2467330f729Sjoerg           }
2477330f729Sjoerg         }
2487330f729Sjoerg       }
2497330f729Sjoerg     }
2507330f729Sjoerg 
HandleTagDeclRequiredDefinition(const TagDecl * D)2517330f729Sjoerg     void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
2527330f729Sjoerg       if (Diags.hasErrorOccurred())
2537330f729Sjoerg         return;
2547330f729Sjoerg 
2557330f729Sjoerg       // Don't allow re-entrant calls to CodeGen triggered by PCH
2567330f729Sjoerg       // deserialization to emit deferred decls.
2577330f729Sjoerg       HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
2587330f729Sjoerg 
2597330f729Sjoerg       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
2607330f729Sjoerg         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
2617330f729Sjoerg           DI->completeRequiredType(RD);
2627330f729Sjoerg     }
2637330f729Sjoerg 
HandleTranslationUnit(ASTContext & Ctx)2647330f729Sjoerg     void HandleTranslationUnit(ASTContext &Ctx) override {
2657330f729Sjoerg       // Release the Builder when there is no error.
2667330f729Sjoerg       if (!Diags.hasErrorOccurred() && Builder)
2677330f729Sjoerg         Builder->Release();
2687330f729Sjoerg 
2697330f729Sjoerg       // If there are errors before or when releasing the Builder, reset
2707330f729Sjoerg       // the module to stop here before invoking the backend.
2717330f729Sjoerg       if (Diags.hasErrorOccurred()) {
2727330f729Sjoerg         if (Builder)
2737330f729Sjoerg           Builder->clear();
2747330f729Sjoerg         M.reset();
2757330f729Sjoerg         return;
2767330f729Sjoerg       }
2777330f729Sjoerg     }
2787330f729Sjoerg 
AssignInheritanceModel(CXXRecordDecl * RD)2797330f729Sjoerg     void AssignInheritanceModel(CXXRecordDecl *RD) override {
2807330f729Sjoerg       if (Diags.hasErrorOccurred())
2817330f729Sjoerg         return;
2827330f729Sjoerg 
2837330f729Sjoerg       Builder->RefreshTypeCacheForClass(RD);
2847330f729Sjoerg     }
2857330f729Sjoerg 
CompleteTentativeDefinition(VarDecl * D)2867330f729Sjoerg     void CompleteTentativeDefinition(VarDecl *D) override {
2877330f729Sjoerg       if (Diags.hasErrorOccurred())
2887330f729Sjoerg         return;
2897330f729Sjoerg 
2907330f729Sjoerg       Builder->EmitTentativeDefinition(D);
2917330f729Sjoerg     }
2927330f729Sjoerg 
CompleteExternalDeclaration(VarDecl * D)293*e038c9c4Sjoerg     void CompleteExternalDeclaration(VarDecl *D) override {
294*e038c9c4Sjoerg       Builder->EmitExternalDeclaration(D);
295*e038c9c4Sjoerg     }
296*e038c9c4Sjoerg 
HandleVTable(CXXRecordDecl * RD)2977330f729Sjoerg     void HandleVTable(CXXRecordDecl *RD) override {
2987330f729Sjoerg       if (Diags.hasErrorOccurred())
2997330f729Sjoerg         return;
3007330f729Sjoerg 
3017330f729Sjoerg       Builder->EmitVTable(RD);
3027330f729Sjoerg     }
3037330f729Sjoerg   };
3047330f729Sjoerg }
3057330f729Sjoerg 
anchor()3067330f729Sjoerg void CodeGenerator::anchor() { }
3077330f729Sjoerg 
CGM()3087330f729Sjoerg CodeGenModule &CodeGenerator::CGM() {
3097330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)->CGM();
3107330f729Sjoerg }
3117330f729Sjoerg 
GetModule()3127330f729Sjoerg llvm::Module *CodeGenerator::GetModule() {
3137330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)->GetModule();
3147330f729Sjoerg }
3157330f729Sjoerg 
ReleaseModule()3167330f729Sjoerg llvm::Module *CodeGenerator::ReleaseModule() {
3177330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
3187330f729Sjoerg }
3197330f729Sjoerg 
getCGDebugInfo()3207330f729Sjoerg CGDebugInfo *CodeGenerator::getCGDebugInfo() {
3217330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
3227330f729Sjoerg }
3237330f729Sjoerg 
GetDeclForMangledName(llvm::StringRef name)3247330f729Sjoerg const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
3257330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
3267330f729Sjoerg }
3277330f729Sjoerg 
GetAddrOfGlobal(GlobalDecl global,bool isForDefinition)3287330f729Sjoerg llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
3297330f729Sjoerg                                                bool isForDefinition) {
3307330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)
3317330f729Sjoerg            ->GetAddrOfGlobal(global, isForDefinition);
3327330f729Sjoerg }
3337330f729Sjoerg 
StartModule(llvm::StringRef ModuleName,llvm::LLVMContext & C)3347330f729Sjoerg llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
3357330f729Sjoerg                                          llvm::LLVMContext &C) {
3367330f729Sjoerg   return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
3377330f729Sjoerg }
3387330f729Sjoerg 
CreateLLVMCodeGen(DiagnosticsEngine & Diags,llvm::StringRef ModuleName,const HeaderSearchOptions & HeaderSearchOpts,const PreprocessorOptions & PreprocessorOpts,const CodeGenOptions & CGO,llvm::LLVMContext & C,CoverageSourceInfo * CoverageInfo)3397330f729Sjoerg CodeGenerator *clang::CreateLLVMCodeGen(
3407330f729Sjoerg     DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
3417330f729Sjoerg     const HeaderSearchOptions &HeaderSearchOpts,
3427330f729Sjoerg     const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,
3437330f729Sjoerg     llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {
3447330f729Sjoerg   return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts,
3457330f729Sjoerg                                PreprocessorOpts, CGO, C, CoverageInfo);
3467330f729Sjoerg }
347