diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2016-07-23 20:44:14 +0000 | 
| commit | 2b6b257f4e5503a7a2675bdb8735693db769f75c (patch) | |
| tree | e85e046ae7003fe3bcc8b5454cd0fa3f7407b470 /lib/CodeGen/ModuleBuilder.cpp | |
| parent | b4348ed0b7e90c0831b925fbee00b5f179a99796 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/ModuleBuilder.cpp')
| -rw-r--r-- | lib/CodeGen/ModuleBuilder.cpp | 130 | 
1 files changed, 100 insertions, 30 deletions
| diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index 0be5c5592b22..952d1627fa84 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -25,7 +25,9 @@  #include "llvm/IR/LLVMContext.h"  #include "llvm/IR/Module.h"  #include <memory> +  using namespace clang; +using namespace CodeGen;  namespace {    class CodeGeneratorImpl : public CodeGenerator { @@ -36,13 +38,21 @@ namespace {      const CodeGenOptions CodeGenOpts;  // Intentionally copied in.      unsigned HandlingTopLevelDecls; + +    /// Use this when emitting decls to block re-entrant decl emission. It will +    /// emit all deferred decls on scope exit. Set EmitDeferred to false if decl +    /// emission must be deferred longer, like at the end of a tag definition.      struct HandlingTopLevelDeclRAII {        CodeGeneratorImpl &Self; -      HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) { +      bool EmitDeferred; +      HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self, +                               bool EmitDeferred = true) +          : Self(Self), EmitDeferred(EmitDeferred) {          ++Self.HandlingTopLevelDecls;        }        ~HandlingTopLevelDeclRAII() { -        if (--Self.HandlingTopLevelDecls == 0) +        unsigned Level = --Self.HandlingTopLevelDecls; +        if (Level == 0 && EmitDeferred)            Self.EmitDeferredDecls();        }      }; @@ -57,15 +67,16 @@ namespace {      SmallVector<CXXMethodDecl *, 8> DeferredInlineMethodDefinitions;    public: -    CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string &ModuleName, +    CodeGeneratorImpl(DiagnosticsEngine &diags, llvm::StringRef ModuleName,                        const HeaderSearchOptions &HSO,                        const PreprocessorOptions &PPO, const CodeGenOptions &CGO,                        llvm::LLVMContext &C,                        CoverageSourceInfo *CoverageInfo = nullptr)          : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO),            PreprocessorOpts(PPO), CodeGenOpts(CGO), HandlingTopLevelDecls(0), -          CoverageInfo(CoverageInfo), -          M(new llvm::Module(ModuleName, C)) {} +          CoverageInfo(CoverageInfo), M(new llvm::Module(ModuleName, C)) { +      C.setDiscardValueNames(CGO.DiscardValueNames); +    }      ~CodeGeneratorImpl() override {        // There should normally not be any leftover inline method definitions. @@ -73,11 +84,19 @@ namespace {               Diags.hasErrorOccurred());      } -    llvm::Module* GetModule() override { +    CodeGenModule &CGM() { +      return *Builder; +    } + +    llvm::Module *GetModule() {        return M.get();      } -    const Decl *GetDeclForMangledName(StringRef MangledName) override { +    llvm::Module *ReleaseModule() { +      return M.release(); +    } + +    const Decl *GetDeclForMangledName(StringRef MangledName) {        GlobalDecl Result;        if (!Builder->lookupRepresentativeDecl(MangledName, Result))          return nullptr; @@ -92,19 +111,23 @@ namespace {        return D;      } -    llvm::Module *ReleaseModule() override { return M.release(); } +    llvm::Constant *GetAddrOfGlobal(GlobalDecl global, bool isForDefinition) { +      return Builder->GetAddrOfGlobal(global, isForDefinition); +    }      void Initialize(ASTContext &Context) override {        Ctx = &Context;        M->setTargetTriple(Ctx->getTargetInfo().getTriple().getTriple()); -      M->setDataLayout(Ctx->getTargetInfo().getDataLayoutString()); +      M->setDataLayout(Ctx->getTargetInfo().getDataLayout());        Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,                                                 PreprocessorOpts, CodeGenOpts,                                                 *M, Diags, CoverageInfo)); -      for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i) -        HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]); +      for (auto &&Lib : CodeGenOpts.DependentLibraries) +        Builder->AddDependentLib(Lib); +      for (auto &&Opt : CodeGenOpts.LinkerOptions) +        Builder->AppendLinkerOptions(Opt);      }      void HandleCXXStaticMemberVarInstantiation(VarDecl *VD) override { @@ -140,12 +163,23 @@ namespace {        DeferredInlineMethodDefinitions.clear();      } -    void HandleInlineMethodDefinition(CXXMethodDecl *D) override { +    void HandleInlineFunctionDefinition(FunctionDecl *D) override {        if (Diags.hasErrorOccurred())          return;        assert(D->doesThisDeclarationHaveABody()); +      // Handle friend functions. +      if (D->isInIdentifierNamespace(Decl::IDNS_OrdinaryFriend)) { +        if (Ctx->getTargetInfo().getCXXABI().isMicrosoft() +            && !D->getLexicalDeclContext()->isDependentContext()) +          Builder->EmitTopLevelDecl(D); +        return; +      } + +      // Otherwise, must be a method. +      auto MD = cast<CXXMethodDecl>(D); +        // We may want to emit this definition. However, that decision might be        // based on computing the linkage, and we have to defer that in case we        // are inside of something that will change the method's final linkage, @@ -154,13 +188,13 @@ namespace {        //     void bar();        //     void foo() { bar(); }        //   } A; -      DeferredInlineMethodDefinitions.push_back(D); +      DeferredInlineMethodDefinitions.push_back(MD);        // Provide some coverage mapping even for methods that aren't emitted.        // Don't do this for templated classes though, as they may not be        // instantiable. -      if (!D->getParent()->getDescribedClassTemplate()) -        Builder->AddDeferredUnusedCoverageMapping(D); +      if (!MD->getParent()->getDescribedClassTemplate()) +        Builder->AddDeferredUnusedCoverageMapping(MD);      }      /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl @@ -171,6 +205,10 @@ namespace {        if (Diags.hasErrorOccurred())          return; +      // Don't allow re-entrant calls to CodeGen triggered by PCH +      // deserialization to emit deferred decls. +      HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false); +        Builder->UpdateCompletedType(D);        // For MSVC compatibility, treat declarations of static data members with @@ -185,27 +223,50 @@ namespace {            }          }        } +      // For OpenMP emit declare reduction functions, if required. +      if (Ctx->getLangOpts().OpenMP) { +        for (Decl *Member : D->decls()) { +          if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(Member)) { +            if (Ctx->DeclMustBeEmitted(DRD)) +              Builder->EmitGlobal(DRD); +          } +        } +      }      }      void HandleTagDeclRequiredDefinition(const TagDecl *D) override {        if (Diags.hasErrorOccurred())          return; +      // Don't allow re-entrant calls to CodeGen triggered by PCH +      // deserialization to emit deferred decls. +      HandlingTopLevelDeclRAII HandlingDecl(*this, /*EmitDeferred=*/false); +        if (CodeGen::CGDebugInfo *DI = Builder->getModuleDebugInfo())          if (const RecordDecl *RD = dyn_cast<RecordDecl>(D))            DI->completeRequiredType(RD);      }      void HandleTranslationUnit(ASTContext &Ctx) override { +      // Release the Builder when there is no error. +      if (!Diags.hasErrorOccurred() && Builder) +        Builder->Release(); + +      // If there are errors before or when releasing the Builder, reset +      // the module to stop here before invoking the backend.        if (Diags.hasErrorOccurred()) {          if (Builder)            Builder->clear();          M.reset();          return;        } +    } -      if (Builder) -        Builder->Release(); +    void AssignInheritanceModel(CXXRecordDecl *RD) override { +      if (Diags.hasErrorOccurred()) +        return; + +      Builder->RefreshTypeCacheForClass(RD);      }      void CompleteTentativeDefinition(VarDecl *D) override { @@ -221,26 +282,35 @@ namespace {        Builder->EmitVTable(RD);      } +  }; +} -    void HandleLinkerOptionPragma(llvm::StringRef Opts) override { -      Builder->AppendLinkerOptions(Opts); -    } +void CodeGenerator::anchor() { } -    void HandleDetectMismatch(llvm::StringRef Name, -                              llvm::StringRef Value) override { -      Builder->AddDetectMismatch(Name, Value); -    } +CodeGenModule &CodeGenerator::CGM() { +  return static_cast<CodeGeneratorImpl*>(this)->CGM(); +} -    void HandleDependentLibrary(llvm::StringRef Lib) override { -      Builder->AddDependentLib(Lib); -    } -  }; +llvm::Module *CodeGenerator::GetModule() { +  return static_cast<CodeGeneratorImpl*>(this)->GetModule();  } -void CodeGenerator::anchor() { } +llvm::Module *CodeGenerator::ReleaseModule() { +  return static_cast<CodeGeneratorImpl*>(this)->ReleaseModule(); +} + +const Decl *CodeGenerator::GetDeclForMangledName(llvm::StringRef name) { +  return static_cast<CodeGeneratorImpl*>(this)->GetDeclForMangledName(name); +} + +llvm::Constant *CodeGenerator::GetAddrOfGlobal(GlobalDecl global, +                                               bool isForDefinition) { +  return static_cast<CodeGeneratorImpl*>(this) +           ->GetAddrOfGlobal(global, isForDefinition); +}  CodeGenerator *clang::CreateLLVMCodeGen( -    DiagnosticsEngine &Diags, const std::string &ModuleName, +    DiagnosticsEngine &Diags, llvm::StringRef ModuleName,      const HeaderSearchOptions &HeaderSearchOpts,      const PreprocessorOptions &PreprocessorOpts, const CodeGenOptions &CGO,      llvm::LLVMContext &C, CoverageSourceInfo *CoverageInfo) { | 
