Home | History | Annotate | Line # | Download | only in CodeGen
      1 //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
      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 // This builds an AST and converts it to LLVM Code.
     10 //
     11 //===----------------------------------------------------------------------===//
     12 
     13 #include "clang/CodeGen/ModuleBuilder.h"
     14 #include "CGDebugInfo.h"
     15 #include "CodeGenModule.h"
     16 #include "clang/AST/ASTContext.h"
     17 #include "clang/AST/DeclObjC.h"
     18 #include "clang/AST/Expr.h"
     19 #include "clang/Basic/CodeGenOptions.h"
     20 #include "clang/Basic/Diagnostic.h"
     21 #include "clang/Basic/TargetInfo.h"
     22 #include "llvm/ADT/StringRef.h"
     23 #include "llvm/IR/DataLayout.h"
     24 #include "llvm/IR/LLVMContext.h"
     25 #include "llvm/IR/Module.h"
     26 #include <memory>
     27 
     28 using namespace clang;
     29 using namespace CodeGen;
     30 
     31 namespace {
     32   class CodeGeneratorImpl : public CodeGenerator {
     33     DiagnosticsEngine &Diags;
     34     ASTContext *Ctx;
     35     const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
     36     const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
     37     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
     38 
     39     unsigned HandlingTopLevelDecls;
     40 
     41     /// Use this when emitting decls to block re-entrant decl emission. It will
     42     /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl
     43     /// emission must be deferred longer, like at the end of a tag definition.
     44     struct HandlingTopLevelDeclRAII {
     45       CodeGeneratorImpl &Self;
     46       bool EmitDeferred;
     47       HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self,
     48                                bool EmitDeferred = true)
     49           : Self(Self), EmitDeferred(EmitDeferred) {
     50         ++Self.HandlingTopLevelDecls;
     51       }
     52       ~HandlingTopLevelDeclRAII() {
     53         unsigned Level = --Self.HandlingTopLevelDecls;
     54         if (Level == 0 && EmitDeferred)
     55           Self.EmitDeferredDecls();
     56       }
     57     };
     58 
     59     CoverageSourceInfo *CoverageInfo;
     60 
     61   protected:
     62     std::unique_ptr<llvm::Module> M;
     63     std::unique_ptr<CodeGen::CodeGenModule> Builder;
     64 
     65   private:
     66     SmallVector<FunctionDecl *, 8> DeferredInlineMemberFuncDefs;
     67 
     68     static llvm::StringRef ExpandModuleName(llvm::StringRef ModuleName,
     69                                             const CodeGenOptions &CGO) {
     70       if (ModuleName == "-" && !CGO.MainFileName.empty())
     71         return CGO.MainFileName;
     72       return ModuleName;
     73     }
     74 
     75   public:
     76     CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,
     77                       const HeaderSearchOptions &HSO,
     78                       const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
     79                       llvm::LLVMContext &C,
     80                       CoverageSourceInfo *CoverageInfo = nullptr)
     81         : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
     82           PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
     83           CoverageInfo(CoverageInfo),
     84           M(new llvm::Module(ExpandModuleName(ModuleName, CGO), C)) {
     85       C.setDiscardValueNames(CGO.DiscardValueNames);
     86     }
     87 
     88     ~CodeGeneratorImpl() override {
     89       // There should normally not be any leftover inline method definitions.
     90       assert(DeferredInlineMemberFuncDefs.empty() ||
     91              Diags.hasErrorOccurred());
     92     }
     93 
     94     CodeGenModule &CGM() {
     95       return *Builder;
     96     }
     97 
     98     llvm::Module *GetModule() {
     99       return M.get();
    100     }
    101 
    102     CGDebugInfo *getCGDebugInfo() {
    103       return Builder->getModuleDebugInfo();
    104     }
    105 
    106     llvm::Module *ReleaseModule() {
    107       return M.release();
    108     }
    109 
    110     const Decl *GetDeclForMangledName(StringRef MangledName) {
    111       GlobalDecl Result;
    112       if (!Builder->lookupRepresentativeDecl(MangledName, Result))
    113         return nullptr;
    114       const Decl *D = Result.getCanonicalDecl().getDecl();
    115       if (auto FD = dyn_cast<FunctionDecl>(D)) {
    116         if (FD->hasBody(FD))
    117           return FD;
    118       } else if (auto TD = dyn_cast<TagDecl>(D)) {
    119         if (auto Def = TD->getDefinition())
    120           return Def;
    121       }
    122       return D;
    123     }
    124 
    125     llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) {
    126       return Builder->GetAddrOfGlobal(global, ForDefinition_t(isForDefinition));
    127     }
    128 
    129     llvm::Module *StartModule(llvm::StringRef ModuleName,
    130                               llvm::LLVMContext &C) {
    131       assert(!M && "Replacing existing Module?");
    132       M.reset(new llvm::Module(ExpandModuleName(ModuleName, CodeGenOpts), C));
    133       Initialize(*Ctx);
    134       return M.get();
    135     }
    136 
    137     void Initialize(ASTContext &Context) override {
    138       Ctx = &Context;
    139 
    140       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
    141       M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
    142       const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
    143       if (!SDKVersion.empty())
    144         M->setSDKVersion(SDKVersion);
    145       Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
    146                                                PreprocessorOpts, CodeGenOpts,
    147                                                *M, Diags, CoverageInfo));
    148 
    149       for (auto &&Lib : CodeGenOpts.DependentLibraries)
    150         Builder->AddDependentLib(Lib);
    151       for (auto &&Opt : CodeGenOpts.LinkerOptions)
    152         Builder->AppendLinkerOptions(Opt);
    153     }
    154 
    155     void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
    156       if (Diags.hasErrorOccurred())
    157         return;
    158 
    159       Builder->HandleCXXStaticMemberVarInstantiation(VD);
    160     }
    161 
    162     bool HandleTopLevelDecl(DeclGroupRef DG) override {
    163       if (Diags.hasErrorOccurred())
    164         return true;
    165 
    166       HandlingTopLevelDeclRAII HandlingDecl(*this);
    167 
    168       // Make sure to emit all elements of a Decl.
    169       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
    170         Builder->EmitTopLevelDecl(*I);
    171 
    172       return true;
    173     }
    174 
    175     void EmitDeferredDecls() {
    176       if (DeferredInlineMemberFuncDefs.empty())
    177         return;
    178 
    179       // Emit any deferred inline method definitions. Note that more deferred
    180       // methods may be added during this loop, since ASTConsumer callbacks
    181       // can be invoked if AST inspection results in declarations being added.
    182       HandlingTopLevelDeclRAII HandlingDecl(*this);
    183       for (unsigned I = 0; I != DeferredInlineMemberFuncDefs.size(); ++I)
    184         Builder->EmitTopLevelDecl(DeferredInlineMemberFuncDefs[I]);
    185       DeferredInlineMemberFuncDefs.clear();
    186     }
    187 
    188     void HandleInlineFunctionDefinition(FunctionDecl *D) override {
    189       if (Diags.hasErrorOccurred())
    190         return;
    191 
    192       assert(D->doesThisDeclarationHaveABody());
    193 
    194       // We may want to emit this definition. However, that decision might be
    195       // based on computing the linkage, and we have to defer that in case we
    196       // are inside of something that will change the method's final linkage,
    197       // e.g.
    198       //   typedef struct {
    199       //     void bar();
    200       //     void foo() { bar(); }
    201       //   } A;
    202       DeferredInlineMemberFuncDefs.push_back(D);
    203 
    204       // Provide some coverage mapping even for methods that aren't emitted.
    205       // Don't do this for templated classes though, as they may not be
    206       // instantiable.
    207       if (!D->getLexicalDeclContext()->isDependentContext())
    208         Builder->AddDeferredUnusedCoverageMapping(D);
    209     }
    210 
    211     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
    212     /// to (e.g. struct, union, enum, class) is completed. This allows the
    213     /// client hack on the type, which can occur at any point in the file
    214     /// (because these can be defined in declspecs).
    215     void HandleTagDeclDefinition(TagDecl *D) override {
    216       if (Diags.hasErrorOccurred())
    217         return;
    218 
    219       // Don't allow re-entrant calls to CodeGen triggered by PCH
    220       // deserialization to emit deferred decls.
    221       HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
    222 
    223       Builder->UpdateCompletedType(D);
    224 
    225       // For MSVC compatibility, treat declarations of static data members with
    226       // inline initializers as definitions.
    227       if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
    228         for (Decl *Member : D->decls()) {
    229           if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
    230             if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
    231                 Ctx->DeclMustBeEmitted(VD)) {
    232               Builder->EmitGlobal(VD);
    233             }
    234           }
    235         }
    236       }
    237       // For OpenMP emit declare reduction functions, if required.
    238       if (Ctx->getLangOpts().OpenMP) {
    239         for (Decl *Member : D->decls()) {
    240           if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) {
    241             if (Ctx->DeclMustBeEmitted(DRD))
    242               Builder->EmitGlobal(DRD);
    243           } else if (auto *DMD = dyn_cast<OMPDeclareMapperDecl>(Member)) {
    244             if (Ctx->DeclMustBeEmitted(DMD))
    245               Builder->EmitGlobal(DMD);
    246           }
    247         }
    248       }
    249     }
    250 
    251     void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
    252       if (Diags.hasErrorOccurred())
    253         return;
    254 
    255       // Don't allow re-entrant calls to CodeGen triggered by PCH
    256       // deserialization to emit deferred decls.
    257       HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false);
    258 
    259       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
    260         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
    261           DI->completeRequiredType(RD);
    262     }
    263 
    264     void HandleTranslationUnit(ASTContext &Ctx) override {
    265       // Release the Builder when there is no error.
    266       if (!Diags.hasErrorOccurred() && Builder)
    267         Builder->Release();
    268 
    269       // If there are errors before or when releasing the Builder, reset
    270       // the module to stop here before invoking the backend.
    271       if (Diags.hasErrorOccurred()) {
    272         if (Builder)
    273           Builder->clear();
    274         M.reset();
    275         return;
    276       }
    277     }
    278 
    279     void AssignInheritanceModel(CXXRecordDecl *RD) override {
    280       if (Diags.hasErrorOccurred())
    281         return;
    282 
    283       Builder->RefreshTypeCacheForClass(RD);
    284     }
    285 
    286     void CompleteTentativeDefinition(VarDecl *D) override {
    287       if (Diags.hasErrorOccurred())
    288         return;
    289 
    290       Builder->EmitTentativeDefinition(D);
    291     }
    292 
    293     void CompleteExternalDeclaration(VarDecl *D) override {
    294       Builder->EmitExternalDeclaration(D);
    295     }
    296 
    297     void HandleVTable(CXXRecordDecl *RD) override {
    298       if (Diags.hasErrorOccurred())
    299         return;
    300 
    301       Builder->EmitVTable(RD);
    302     }
    303   };
    304 }
    305 
    306 void CodeGenerator::anchor() { }
    307 
    308 CodeGenModule &CodeGenerator::CGM() {
    309   return static_cast<CodeGeneratorImpl*>(this)->CGM();
    310 }
    311 
    312 llvm::Module *CodeGenerator::GetModule() {
    313   return static_cast<CodeGeneratorImpl*>(this)->GetModule();
    314 }
    315 
    316 llvm::Module *CodeGenerator::ReleaseModule() {
    317   return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule();
    318 }
    319 
    320 CGDebugInfo *CodeGenerator::getCGDebugInfo() {
    321   return static_cast<CodeGeneratorImpl*>(this)->getCGDebugInfo();
    322 }
    323 
    324 const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) {
    325   return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name);
    326 }
    327 
    328 llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global,
    329                                                bool isForDefinition) {
    330   return static_cast<CodeGeneratorImpl*>(this)
    331            ->GetAddrOfGlobal(global, isForDefinition);
    332 }
    333 
    334 llvm::Module *CodeGenerator::StartModule(llvm::StringRef ModuleName,
    335                                          llvm::LLVMContext &C) {
    336   return static_cast<CodeGeneratorImpl*>(this)->StartModule(ModuleName, C);
    337 }
    338 
    339 CodeGenerator *clang::CreateLLVMCodeGen(
    340     DiagnosticsEngine &Diags, llvm::StringRef ModuleName,
    341     const HeaderSearchOptions &HeaderSearchOpts,
    342     const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,
    343     llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {
    344   return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts,
    345                                PreprocessorOpts, CGO, C, CoverageInfo);
    346 }
    347