Home | History | Annotate | Download | only in CodeGen
      1 //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This builds an AST and converts it to LLVM Code.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "clang/CodeGen/ModuleBuilder.h"
     15 #include "CGDebugInfo.h"
     16 #include "CodeGenModule.h"
     17 #include "clang/AST/ASTContext.h"
     18 #include "clang/AST/DeclObjC.h"
     19 #include "clang/AST/Expr.h"
     20 #include "clang/Basic/Diagnostic.h"
     21 #include "clang/Basic/TargetInfo.h"
     22 #include "clang/Frontend/CodeGenOptions.h"
     23 #include "llvm/ADT/StringRef.h"
     24 #include "llvm/IR/DataLayout.h"
     25 #include "llvm/IR/LLVMContext.h"
     26 #include "llvm/IR/Module.h"
     27 #include <memory>
     28 using namespace clang;
     29 
     30 namespace {
     31   class CodeGeneratorImpl : public CodeGenerator {
     32     DiagnosticsEngine &Diags;
     33     ASTContext *Ctx;
     34     const HeaderSearchOptions &HeaderSearchOpts; // Only used for debug info.
     35     const PreprocessorOptions &PreprocessorOpts; // Only used for debug info.
     36     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
     37 
     38     unsigned HandlingTopLevelDecls;
     39     struct HandlingTopLevelDeclRAII {
     40       CodeGeneratorImpl &Self;
     41       HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) {
     42         ++Self.HandlingTopLevelDecls;
     43       }
     44       ~HandlingTopLevelDeclRAII() {
     45         if (--Self.HandlingTopLevelDecls == 0)
     46           Self.EmitDeferredDecls();
     47       }
     48     };
     49 
     50     CoverageSourceInfo *CoverageInfo;
     51 
     52   protected:
     53     std::unique_ptr<llvm::Module> M;
     54     std::unique_ptr<CodeGen::CodeGenModule> Builder;
     55 
     56   private:
     57     SmallVector<CXXMethodDecl *, 8> DeferredInlineMethodDefinitions;
     58 
     59   public:
     60     CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string &ModuleName,
     61                       const HeaderSearchOptions &HSO,
     62                       const PreprocessorOptions &PPO, const CodeGenOptions &CGO,
     63                       llvm::LLVMContext &C,
     64                       CoverageSourceInfo *CoverageInfo = nullptr)
     65         : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),
     66           PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
     67           CoverageInfo(CoverageInfo),
     68           M(new llvm::Module(ModuleName, C)) {}
     69 
     70     ~CodeGeneratorImpl() override {
     71       // There should normally not be any leftover inline method definitions.
     72       assert(DeferredInlineMethodDefinitions.empty() ||
     73              Diags.hasErrorOccurred());
     74     }
     75 
     76     llvm::Module* GetModule() override {
     77       return M.get();
     78     }
     79 
     80     const Decl *GetDeclForMangledName(StringRef MangledName) override {
     81       GlobalDecl Result;
     82       if (!Builder->lookupRepresentativeDecl(MangledName, Result))
     83         return nullptr;
     84       const Decl *D = Result.getCanonicalDecl().getDecl();
     85       if (auto FD = dyn_cast<FunctionDecl>(D)) {
     86         if (FD->hasBody(FD))
     87           return FD;
     88       } else if (auto TD = dyn_cast<TagDecl>(D)) {
     89         if (auto Def = TD->getDefinition())
     90           return Def;
     91       }
     92       return D;
     93     }
     94 
     95     llvm::Module *ReleaseModule() override { return M.release(); }
     96 
     97     void Initialize(ASTContext &Context) override {
     98       Ctx = &Context;
     99 
    100       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
    101       M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString());
    102       Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
    103                                                PreprocessorOpts, CodeGenOpts,
    104                                                *M, Diags, CoverageInfo));
    105 
    106       for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i)
    107         HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
    108     }
    109 
    110     void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
    111       if (Diags.hasErrorOccurred())
    112         return;
    113 
    114       Builder->HandleCXXStaticMemberVarInstantiation(VD);
    115     }
    116 
    117     bool HandleTopLevelDecl(DeclGroupRef DG) override {
    118       if (Diags.hasErrorOccurred())
    119         return true;
    120 
    121       HandlingTopLevelDeclRAII HandlingDecl(*this);
    122 
    123       // Make sure to emit all elements of a Decl.
    124       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
    125         Builder->EmitTopLevelDecl(*I);
    126 
    127       return true;
    128     }
    129 
    130     void EmitDeferredDecls() {
    131       if (DeferredInlineMethodDefinitions.empty())
    132         return;
    133 
    134       // Emit any deferred inline method definitions. Note that more deferred
    135       // methods may be added during this loop, since ASTConsumer callbacks
    136       // can be invoked if AST inspection results in declarations being added.
    137       HandlingTopLevelDeclRAII HandlingDecl(*this);
    138       for (unsigned I = 0; I != DeferredInlineMethodDefinitions.size(); ++I)
    139         Builder->EmitTopLevelDecl(DeferredInlineMethodDefinitions[I]);
    140       DeferredInlineMethodDefinitions.clear();
    141     }
    142 
    143     void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
    144       if (Diags.hasErrorOccurred())
    145         return;
    146 
    147       assert(D->doesThisDeclarationHaveABody());
    148 
    149       // We may want to emit this definition. However, that decision might be
    150       // based on computing the linkage, and we have to defer that in case we
    151       // are inside of something that will change the method's final linkage,
    152       // e.g.
    153       //   typedef struct {
    154       //     void bar();
    155       //     void foo() { bar(); }
    156       //   } A;
    157       DeferredInlineMethodDefinitions.push_back(D);
    158 
    159       // Provide some coverage mapping even for methods that aren't emitted.
    160       // Don't do this for templated classes though, as they may not be
    161       // instantiable.
    162       if (!D->getParent()->getDescribedClassTemplate())
    163         Builder->AddDeferredUnusedCoverageMapping(D);
    164     }
    165 
    166     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
    167     /// to (e.g. struct, union, enum, class) is completed. This allows the
    168     /// client hack on the type, which can occur at any point in the file
    169     /// (because these can be defined in declspecs).
    170     void HandleTagDeclDefinition(TagDecl *D) override {
    171       if (Diags.hasErrorOccurred())
    172         return;
    173 
    174       Builder->UpdateCompletedType(D);
    175 
    176       // For MSVC compatibility, treat declarations of static data members with
    177       // inline initializers as definitions.
    178       if (Ctx->getTargetInfo().getCXXABI().isMicrosoft()) {
    179         for (Decl *Member : D->decls()) {
    180           if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
    181             if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
    182                 Ctx->DeclMustBeEmitted(VD)) {
    183               Builder->EmitGlobal(VD);
    184             }
    185           }
    186         }
    187       }
    188     }
    189 
    190     void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
    191       if (Diags.hasErrorOccurred())
    192         return;
    193 
    194       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
    195         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
    196           DI->completeRequiredType(RD);
    197     }
    198 
    199     void HandleTranslationUnit(ASTContext &Ctx) override {
    200       if (Diags.hasErrorOccurred()) {
    201         if (Builder)
    202           Builder->clear();
    203         M.reset();
    204         return;
    205       }
    206 
    207       if (Builder)
    208         Builder->Release();
    209     }
    210 
    211     void CompleteTentativeDefinition(VarDecl *D) override {
    212       if (Diags.hasErrorOccurred())
    213         return;
    214 
    215       Builder->EmitTentativeDefinition(D);
    216     }
    217 
    218     void HandleVTable(CXXRecordDecl *RD) override {
    219       if (Diags.hasErrorOccurred())
    220         return;
    221 
    222       Builder->EmitVTable(RD);
    223     }
    224 
    225     void HandleLinkerOptionPragma(llvm::StringRef Opts) override {
    226       Builder->AppendLinkerOptions(Opts);
    227     }
    228 
    229     void HandleDetectMismatch(llvm::StringRef Name,
    230                               llvm::StringRef Value) override {
    231       Builder->AddDetectMismatch(Name, Value);
    232     }
    233 
    234     void HandleDependentLibrary(llvm::StringRef Lib) override {
    235       Builder->AddDependentLib(Lib);
    236     }
    237   };
    238 }
    239 
    240 void CodeGenerator::anchor() { }
    241 
    242 CodeGenerator *clang::CreateLLVMCodeGen(
    243     DiagnosticsEngine &Diags, const std::string &ModuleName,
    244     const HeaderSearchOptions &HeaderSearchOpts,
    245     const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,
    246     llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) {
    247   return new CodeGeneratorImpl(Diags, ModuleName, HeaderSearchOpts,
    248                                PreprocessorOpts, CGO, C, CoverageInfo);
    249 }
    250