diff options
Diffstat (limited to 'lib/CodeGen/ModuleBuilder.cpp')
-rw-r--r-- | lib/CodeGen/ModuleBuilder.cpp | 66 |
1 files changed, 52 insertions, 14 deletions
diff --git a/lib/CodeGen/ModuleBuilder.cpp b/lib/CodeGen/ModuleBuilder.cpp index c5d18d3286a7..4f1a82e0248d 100644 --- a/lib/CodeGen/ModuleBuilder.cpp +++ b/lib/CodeGen/ModuleBuilder.cpp @@ -33,17 +33,41 @@ namespace { std::unique_ptr<const llvm::DataLayout> 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<llvm::Module> M; std::unique_ptr<CodeGen::CodeGenModule> Builder; + private: + SmallVector<CXXMethodDecl *, 8> 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<CXXMethodDecl *> 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); } |