From 06d4ba388873e6d1cfa9cd715a8935ecc8cd2097 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Sun, 18 Jan 2015 16:23:48 +0000 Subject: Vendor import of clang RELEASE_360/rc1 tag r226102 (effectively, 3.6.0 RC1): https://llvm.org/svn/llvm-project/cfe/tags/RELEASE_360/rc1@226102 --- lib/CodeGen/ModuleBuilder.cpp | 66 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 14 deletions(-) (limited to 'lib/CodeGen/ModuleBuilder.cpp') diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index c5d18d3286a7b..4f1a82e0248dc 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -33,17 +33,41 @@ namespace { std::unique_ptr TD; ASTContext *Ctx; const CodeGenOptions CodeGenOpts; // Intentionally copied in. + + unsigned HandlingTopLevelDecls; + struct HandlingTopLevelDeclRAII { + CodeGeneratorImpl &Self; + HandlingTopLevelDeclRAII(CodeGeneratorImpl &Self) : Self(Self) { + ++Self.HandlingTopLevelDecls; + } + ~HandlingTopLevelDeclRAII() { + if (--Self.HandlingTopLevelDecls == 0) + Self.EmitDeferredDecls(); + } + }; + + CoverageSourceInfo *CoverageInfo; + protected: std::unique_ptr M; std::unique_ptr Builder; + private: + SmallVector DeferredInlineMethodDefinitions; + public: CodeGeneratorImpl(DiagnosticsEngine &diags, const std::string& ModuleName, - const CodeGenOptions &CGO, llvm::LLVMContext& C) - : Diags(diags), CodeGenOpts(CGO), + const CodeGenOptions &CGO, llvm::LLVMContext& C, + CoverageSourceInfo *CoverageInfo = nullptr) + : Diags(diags), Ctx(nullptr), CodeGenOpts(CGO), HandlingTopLevelDecls(0), + CoverageInfo(CoverageInfo), M(new llvm::Module(ModuleName, C)) {} - virtual ~CodeGeneratorImpl() {} + virtual ~CodeGeneratorImpl() { + // There should normally not be any leftover inline method definitions. + assert(DeferredInlineMethodDefinitions.empty() || + Diags.hasErrorOccurred()); + } llvm::Module* GetModule() override { return M.get(); @@ -73,7 +97,7 @@ namespace { M->setDataLayout(Ctx->getTargetInfo().getTargetDescription()); TD.reset(new llvm::DataLayout(Ctx->getTargetInfo().getTargetDescription())); Builder.reset(new CodeGen::CodeGenModule(Context, CodeGenOpts, *M, *TD, - Diags)); + Diags, CoverageInfo)); for (size_t i = 0, e = CodeGenOpts.DependentLibraries.size(); i < e; ++i) HandleDependentLibrary(CodeGenOpts.DependentLibraries[i]); @@ -90,18 +114,28 @@ namespace { if (Diags.hasErrorOccurred()) return true; + HandlingTopLevelDeclRAII HandlingDecl(*this); + // Make sure to emit all elements of a Decl. for (DeclGroupRef::iterator I = DG.begin(), E = DG.end(); I != E; ++I) Builder->EmitTopLevelDecl(*I); - // Emit any deferred inline method definitions. - for (CXXMethodDecl *MD : DeferredInlineMethodDefinitions) - Builder->EmitTopLevelDecl(MD); - DeferredInlineMethodDefinitions.clear(); - return true; } + void EmitDeferredDecls() { + if (DeferredInlineMethodDefinitions.empty()) + return; + + // Emit any deferred inline method definitions. Note that more deferred + // methods may be added during this loop, since ASTConsumer callbacks + // can be invoked if AST inspection results in declarations being added. + HandlingTopLevelDeclRAII HandlingDecl(*this); + for (unsigned I = 0; I != DeferredInlineMethodDefinitions.size(); ++I) + Builder->EmitTopLevelDecl(DeferredInlineMethodDefinitions[I]); + DeferredInlineMethodDefinitions.clear(); + } + void HandleInlineMethodDefinition(CXXMethodDecl *D) override { if (Diags.hasErrorOccurred()) return; @@ -117,6 +151,12 @@ namespace { // void foo() { bar(); } // } A; DeferredInlineMethodDefinitions.push_back(D); + + // 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); } /// HandleTagDeclDefinition - This callback is invoked each time a TagDecl @@ -190,9 +230,6 @@ namespace { void HandleDependentLibrary(llvm::StringRef Lib) override { Builder->AddDependentLib(Lib); } - - private: - std::vector DeferredInlineMethodDefinitions; }; } @@ -202,6 +239,7 @@ CodeGenerator *clang::CreateLLVMCodeGen(DiagnosticsEngine &Diags, const std::string& ModuleName, const CodeGenOptions &CGO, const TargetOptions &/*TO*/, - llvm::LLVMContext& C) { - return new CodeGeneratorImpl(Diags, ModuleName, CGO, C); + llvm::LLVMContext& C, + CoverageSourceInfo *CoverageInfo) { + return new CodeGeneratorImpl(Diags, ModuleName, CGO, C, CoverageInfo); } -- cgit v1.2.3