clang API Documentation

ModuleBuilder.cpp
Go to the documentation of this file.
00001 //===--- ModuleBuilder.cpp - Emit LLVM Code from ASTs ---------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This builds an AST and converts it to LLVM Code.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "clang/CodeGen/ModuleBuilder.h"
00015 #include "CGDebugInfo.h"
00016 #include "CodeGenModule.h"
00017 #include "clang/AST/ASTContext.h"
00018 #include "clang/AST/DeclObjC.h"
00019 #include "clang/AST/Expr.h"
00020 #include "clang/Basic/Diagnostic.h"
00021 #include "clang/Basic/TargetInfo.h"
00022 #include "clang/Frontend/CodeGenOptions.h"
00023 #include "llvm/ADT/StringRef.h"
00024 #include "llvm/IR/DataLayout.h"
00025 #include "llvm/IR/LLVMContext.h"
00026 #include "llvm/IR/Module.h"
00027 #include <memory>
00028 using namespace clang;
00029 
00030 namespace {
00031   class CodeGeneratorImpl : public CodeGenerator {
00032     DiagnosticsEngine &Diags;
00033     std::unique_ptr<const llvm::DataLayout> TD;
00034     ASTContext *Ctx;
00035     const CodeGenOptions CodeGenOpts;  // Intentionally copied in.
00036 
00037     unsigned HandlingTopLevelDecls;
00038     struct HandlingTopLevelDeclRAII {
00039       CodeGeneratorImpl &Self;
00040       HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) {
00041         ++Self.HandlingTopLevelDecls;
00042       }
00043       ~HandlingTopLevelDeclRAII() {
00044         if (--Self.HandlingTopLevelDecls == 0)
00045           Self.EmitDeferredDecls();
00046       }
00047     };
00048 
00049     CoverageSourceInfo *CoverageInfo;
00050 
00051   protected:
00052     std::unique_ptr<llvm::Module> M;
00053     std::unique_ptr<CodeGen::CodeGenModule> Builder;
00054 
00055   public:
00056     CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName,
00057                       const CodeGenOptions &CGO, llvm::LLVMContext& C,
00058                       CoverageSourceInfo *CoverageInfo = nullptr)
00059       : Diags(diags), CodeGenOpts(CGO), HandlingTopLevelDecls(0),
00060         CoverageInfo(CoverageInfo),
00061         M(new llvm::Module(ModuleName, C)) {}
00062 
00063     virtual ~CodeGeneratorImpl() {}
00064 
00065     llvm::Module* GetModule() override {
00066       return M.get();
00067     }
00068 
00069     const Decl *GetDeclForMangledName(StringRef MangledName) override {
00070       GlobalDecl Result;
00071       if (!Builder->lookupRepresentativeDecl(MangledName, Result))
00072         return nullptr;
00073       const Decl *D = Result.getCanonicalDecl().getDecl();
00074       if (auto FD = dyn_cast<FunctionDecl>(D)) {
00075         if (FD->hasBody(FD))
00076           return FD;
00077       } else if (auto TD = dyn_cast<TagDecl>(D)) {
00078         if (auto Def = TD->getDefinition())
00079           return Def;
00080       }
00081       return D;
00082     }
00083 
00084     llvm::Module *ReleaseModule() override { return M.release(); }
00085 
00086     void Initialize(ASTContext &Context) override {
00087       Ctx = &Context;
00088 
00089       M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple());
00090       M->setDataLayout(Ctx->getTargetInfo().getTargetDescription());
00091       TD.reset(new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription()));
00092       Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD,
00093                                                Diags, CoverageInfo));
00094 
00095       for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i)
00096         HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]);
00097     }
00098 
00099     void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override {
00100       if (Diags.hasErrorOccurred())
00101         return;
00102 
00103       Builder->HandleCXXStaticMemberVarInstantiation(VD);
00104     }
00105 
00106     bool HandleTopLevelDecl(DeclGroupRef DG) override {
00107       if (Diags.hasErrorOccurred())
00108         return true;
00109 
00110       HandlingTopLevelDeclRAII HandlingDecl(*this);
00111 
00112       // Make sure to emit all elements of a Decl.
00113       for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I)
00114         Builder->EmitTopLevelDecl(*I);
00115 
00116       return true;
00117     }
00118 
00119     void EmitDeferredDecls() {
00120       if (DeferredInlineMethodDefinitions.empty())
00121         return;
00122 
00123       // Emit any deferred inline method definitions. Note that more deferred
00124       // methods may be added during this loop, since ASTConsumer callbacks
00125       // can be invoked if AST inspection results in declarations being added.
00126       HandlingTopLevelDeclRAII HandlingDecl(*this);
00127       for (unsigned I = 0; I != DeferredInlineMethodDefinitions.size(); ++I)
00128         Builder->EmitTopLevelDecl(DeferredInlineMethodDefinitions[I]);
00129       DeferredInlineMethodDefinitions.clear();
00130     }
00131 
00132     void HandleInlineMethodDefinition(CXXMethodDecl *D) override {
00133       if (Diags.hasErrorOccurred())
00134         return;
00135 
00136       assert(D->doesThisDeclarationHaveABody());
00137 
00138       // We may want to emit this definition. However, that decision might be
00139       // based on computing the linkage, and we have to defer that in case we
00140       // are inside of something that will change the method's final linkage,
00141       // e.g.
00142       //   typedef struct {
00143       //     void bar();
00144       //     void foo() { bar(); }
00145       //   } A;
00146       DeferredInlineMethodDefinitions.push_back(D);
00147 
00148       // Provide some coverage mapping even for methods that aren't emitted.
00149       // Don't do this for templated classes though, as they may not be
00150       // instantiable.
00151       if (!D->getParent()->getDescribedClassTemplate())
00152         Builder->AddDeferredUnusedCoverageMapping(D);
00153     }
00154 
00155     /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl
00156     /// to (e.g. struct, union, enum, class) is completed. This allows the
00157     /// client hack on the type, which can occur at any point in the file
00158     /// (because these can be defined in declspecs).
00159     void HandleTagDeclDefinition(TagDecl *D) override {
00160       if (Diags.hasErrorOccurred())
00161         return;
00162 
00163       Builder->UpdateCompletedType(D);
00164 
00165       // For MSVC compatibility, treat declarations of static data members with
00166       // inline initializers as definitions.
00167       if (Ctx->getLangOpts().MSVCCompat) {
00168         for (Decl *Member : D->decls()) {
00169           if (VarDecl *VD = dyn_cast<VarDecl>(Member)) {
00170             if (Ctx->isMSStaticDataMemberInlineDefinition(VD) &&
00171                 Ctx->DeclMustBeEmitted(VD)) {
00172               Builder->EmitGlobal(VD);
00173             }
00174           }
00175         }
00176       }
00177     }
00178 
00179     void HandleTagDeclRequiredDefinition(const TagDecl *D) override {
00180       if (Diags.hasErrorOccurred())
00181         return;
00182 
00183       if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())
00184         if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))
00185           DI->completeRequiredType(RD);
00186     }
00187 
00188     void HandleTranslationUnit(ASTContext &Ctx) override {
00189       if (Diags.hasErrorOccurred()) {
00190         if (Builder)
00191           Builder->clear();
00192         M.reset();
00193         return;
00194       }
00195 
00196       if (Builder)
00197         Builder->Release();
00198     }
00199 
00200     void CompleteTentativeDefinition(VarDecl *D) override {
00201       if (Diags.hasErrorOccurred())
00202         return;
00203 
00204       Builder->EmitTentativeDefinition(D);
00205     }
00206 
00207     void HandleVTable(CXXRecordDecl *RD, bool DefinitionRequired) override {
00208       if (Diags.hasErrorOccurred())
00209         return;
00210 
00211       Builder->EmitVTable(RD, DefinitionRequired);
00212     }
00213 
00214     void HandleLinkerOptionPragma(llvm::StringRef Opts) override {
00215       Builder->AppendLinkerOptions(Opts);
00216     }
00217 
00218     void HandleDetectMismatch(llvm::StringRef Name,
00219                               llvm::StringRef Value) override {
00220       Builder->AddDetectMismatch(Name, Value);
00221     }
00222 
00223     void HandleDependentLibrary(llvm::StringRef Lib) override {
00224       Builder->AddDependentLib(Lib);
00225     }
00226 
00227   private:
00228     std::vector<CXXMethodDecl *> DeferredInlineMethodDefinitions;
00229   };
00230 }
00231 
00232 void CodeGenerator::anchor() { }
00233 
00234 CodeGenerator *clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags,
00235                                         const std::string& ModuleName,
00236                                         const CodeGenOptions &CGO,
00237                                         const TargetOptions &/*TO*/,
00238                                         llvm::LLVMContext& C,
00239                                         CoverageSourceInfo *CoverageInfo) {
00240   return new CodeGeneratorImpl(Diags, ModuleName, CGO, C, CoverageInfo);
00241 }