Index: cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h =================================================================== --- cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h +++ cfe/trunk/include/clang/Analysis/AnalysisDeclContext.h @@ -16,6 +16,7 @@ #define LLVM_CLANG_ANALYSIS_ANALYSISDECLCONTEXT_H #include "clang/AST/Decl.h" +#include "clang/Analysis/BodyFarm.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CodeInjector.h" #include "llvm/ADT/DenseMap.h" @@ -409,6 +410,7 @@ typedef llvm::DenseMap> ContextMap; + ASTContext &ASTCtx; ContextMap Contexts; LocationContextManager LocContexts; CFG::BuildOptions cfgBuildOptions; @@ -416,22 +418,25 @@ /// Pointer to an interface that can provide function bodies for /// declarations from external source. std::unique_ptr Injector; - + + /// Pointer to a factory for creating and caching implementations for common + /// methods during the analysis. + BodyFarm *BdyFrm = nullptr; + /// Flag to indicate whether or not bodies should be synthesized /// for well-known functions. bool SynthesizeBodies; public: - AnalysisDeclContextManager(bool useUnoptimizedCFG = false, + AnalysisDeclContextManager(ASTContext &ASTCtx, bool useUnoptimizedCFG = false, bool addImplicitDtors = false, bool addInitializers = false, bool addTemporaryDtors = false, - bool addLifetime = false, - bool addLoopExit = false, + bool addLifetime = false, bool addLoopExit = false, bool synthesizeBodies = false, bool addStaticInitBranches = false, bool addCXXNewAllocator = true, - CodeInjector* injector = nullptr); + CodeInjector *injector = nullptr); ~AnalysisDeclContextManager(); @@ -472,6 +477,9 @@ return LocContexts.getStackFrame(getContext(D), Parent, S, Blk, Idx); } + /// Get and lazily create a {@code BodyFarm} instance. + BodyFarm *getBodyFarm(); + /// Discard all previously created AnalysisDeclContexts. void clear(); Index: cfe/trunk/include/clang/Analysis/BodyFarm.h =================================================================== --- cfe/trunk/include/clang/Analysis/BodyFarm.h +++ cfe/trunk/include/clang/Analysis/BodyFarm.h @@ -0,0 +1,51 @@ +//== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// BodyFarm is a factory for creating faux implementations for functions/methods +// for analysis purposes. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H +#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H + +#include "clang/AST/DeclBase.h" +#include "clang/Basic/LLVM.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/Optional.h" + +namespace clang { + +class ASTContext; +class FunctionDecl; +class ObjCMethodDecl; +class ObjCPropertyDecl; +class Stmt; +class CodeInjector; + +class BodyFarm { +public: + BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {} + + /// Factory method for creating bodies for ordinary functions. + Stmt *getBody(const FunctionDecl *D); + + /// Factory method for creating bodies for Objective-C properties. + Stmt *getBody(const ObjCMethodDecl *D); + +private: + typedef llvm::DenseMap> BodyMap; + + ASTContext &C; + BodyMap Bodies; + CodeInjector *Injector; +}; +} // namespace clang + +#endif Index: cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp =================================================================== --- cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp +++ cfe/trunk/lib/Analysis/AnalysisDeclContext.cpp @@ -13,7 +13,6 @@ //===----------------------------------------------------------------------===// #include "clang/Analysis/AnalysisDeclContext.h" -#include "BodyFarm.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclObjC.h" @@ -23,6 +22,7 @@ #include "clang/Analysis/Analyses/CFGReachabilityAnalysis.h" #include "clang/Analysis/Analyses/LiveVariables.h" #include "clang/Analysis/Analyses/PseudoConstantAnalysis.h" +#include "clang/Analysis/BodyFarm.h" #include "clang/Analysis/CFG.h" #include "clang/Analysis/CFGStmtMap.h" #include "clang/Analysis/Support/BumpVector.h" @@ -63,18 +63,12 @@ cfgBuildOptions.forcedBlkExprs = &forcedBlkExprs; } -AnalysisDeclContextManager::AnalysisDeclContextManager(bool useUnoptimizedCFG, - bool addImplicitDtors, - bool addInitializers, - bool addTemporaryDtors, - bool addLifetime, - bool addLoopExit, - bool synthesizeBodies, - bool addStaticInitBranch, - bool addCXXNewAllocator, - CodeInjector *injector) - : Injector(injector), SynthesizeBodies(synthesizeBodies) -{ +AnalysisDeclContextManager::AnalysisDeclContextManager( + ASTContext &ASTCtx, bool useUnoptimizedCFG, bool addImplicitDtors, + bool addInitializers, bool addTemporaryDtors, bool addLifetime, + bool addLoopExit, bool synthesizeBodies, bool addStaticInitBranch, + bool addCXXNewAllocator, CodeInjector *injector) + : ASTCtx(ASTCtx), Injector(injector), SynthesizeBodies(synthesizeBodies) { cfgBuildOptions.PruneTriviallyFalseEdges = !useUnoptimizedCFG; cfgBuildOptions.AddImplicitDtors = addImplicitDtors; cfgBuildOptions.AddInitializers = addInitializers; @@ -87,11 +81,6 @@ void AnalysisDeclContextManager::clear() { Contexts.clear(); } -static BodyFarm &getBodyFarm(ASTContext &C, CodeInjector *injector = nullptr) { - static BodyFarm *BF = new BodyFarm(C, injector); - return *BF; -} - Stmt *AnalysisDeclContext::getBody(bool &IsAutosynthesized) const { IsAutosynthesized = false; if (const FunctionDecl *FD = dyn_cast(D)) { @@ -99,8 +88,7 @@ if (auto *CoroBody = dyn_cast_or_null(Body)) Body = CoroBody->getBody(); if (Manager && Manager->synthesizeBodies()) { - Stmt *SynthesizedBody = - getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(FD); + Stmt *SynthesizedBody = Manager->getBodyFarm()->getBody(FD); if (SynthesizedBody) { Body = SynthesizedBody; IsAutosynthesized = true; @@ -111,8 +99,7 @@ else if (const ObjCMethodDecl *MD = dyn_cast(D)) { Stmt *Body = MD->getBody(); if (Manager && Manager->synthesizeBodies()) { - Stmt *SynthesizedBody = - getBodyFarm(getASTContext(), Manager->Injector.get()).getBody(MD); + Stmt *SynthesizedBody = Manager->getBodyFarm()->getBody(MD); if (SynthesizedBody) { Body = SynthesizedBody; IsAutosynthesized = true; @@ -317,6 +304,12 @@ return AC.get(); } +BodyFarm *AnalysisDeclContextManager::getBodyFarm() { + if (!BdyFrm) + BdyFrm = new BodyFarm(ASTCtx, Injector.get()); + return BdyFrm; +} + const StackFrameContext * AnalysisDeclContext::getStackFrame(LocationContext const *Parent, const Stmt *S, const CFGBlock *Blk, unsigned Idx) { @@ -610,7 +603,10 @@ } } -AnalysisDeclContextManager::~AnalysisDeclContextManager() {} +AnalysisDeclContextManager::~AnalysisDeclContextManager() { + if (!BdyFrm) + delete BdyFrm; +} LocationContext::~LocationContext() {} Index: cfe/trunk/lib/Analysis/BodyFarm.h =================================================================== --- cfe/trunk/lib/Analysis/BodyFarm.h +++ cfe/trunk/lib/Analysis/BodyFarm.h @@ -1,51 +0,0 @@ -//== BodyFarm.h - Factory for conjuring up fake bodies -------------*- C++ -*-// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// BodyFarm is a factory for creating faux implementations for functions/methods -// for analysis purposes. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H -#define LLVM_CLANG_LIB_ANALYSIS_BODYFARM_H - -#include "clang/AST/DeclBase.h" -#include "clang/Basic/LLVM.h" -#include "llvm/ADT/DenseMap.h" -#include "llvm/ADT/Optional.h" - -namespace clang { - -class ASTContext; -class FunctionDecl; -class ObjCMethodDecl; -class ObjCPropertyDecl; -class Stmt; -class CodeInjector; - -class BodyFarm { -public: - BodyFarm(ASTContext &C, CodeInjector *injector) : C(C), Injector(injector) {} - - /// Factory method for creating bodies for ordinary functions. - Stmt *getBody(const FunctionDecl *D); - - /// Factory method for creating bodies for Objective-C properties. - Stmt *getBody(const ObjCMethodDecl *D); - -private: - typedef llvm::DenseMap > BodyMap; - - ASTContext &C; - BodyMap Bodies; - CodeInjector *Injector; -}; -} - -#endif Index: cfe/trunk/lib/Analysis/BodyFarm.cpp =================================================================== --- cfe/trunk/lib/Analysis/BodyFarm.cpp +++ cfe/trunk/lib/Analysis/BodyFarm.cpp @@ -12,7 +12,7 @@ // //===----------------------------------------------------------------------===// -#include "BodyFarm.h" +#include "clang/Analysis/BodyFarm.h" #include "clang/AST/ASTContext.h" #include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" Index: cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp =================================================================== --- cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp +++ cfe/trunk/lib/StaticAnalyzer/Core/AnalysisManager.cpp @@ -14,33 +14,25 @@ void AnalysisManager::anchor() { } -AnalysisManager::AnalysisManager(ASTContext &ctx, DiagnosticsEngine &diags, - const LangOptions &lang, - const PathDiagnosticConsumers &PDC, - StoreManagerCreator storemgr, - ConstraintManagerCreator constraintmgr, - CheckerManager *checkerMgr, - AnalyzerOptions &Options, - CodeInjector *injector) - : AnaCtxMgr(Options.UnoptimizedCFG, - Options.includeImplicitDtorsInCFG(), - /*AddInitializers=*/true, - Options.includeTemporaryDtorsInCFG(), - Options.includeLifetimeInCFG(), - // Adding LoopExit elements to the CFG is a requirement for loop - // unrolling. - Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(), - Options.shouldSynthesizeBodies(), - Options.shouldConditionalizeStaticInitializers(), - /*addCXXNewAllocator=*/true, - injector), - Ctx(ctx), - Diags(diags), - LangOpts(lang), - PathConsumers(PDC), - CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), - CheckerMgr(checkerMgr), - options(Options) { +AnalysisManager::AnalysisManager( + ASTContext &ASTCtx, DiagnosticsEngine &diags, const LangOptions &lang, + const PathDiagnosticConsumers &PDC, StoreManagerCreator storemgr, + ConstraintManagerCreator constraintmgr, CheckerManager *checkerMgr, + AnalyzerOptions &Options, CodeInjector *injector) + : AnaCtxMgr(ASTCtx, Options.UnoptimizedCFG, + Options.includeImplicitDtorsInCFG(), + /*AddInitializers=*/true, Options.includeTemporaryDtorsInCFG(), + Options.includeLifetimeInCFG(), + // Adding LoopExit elements to the CFG is a requirement for loop + // unrolling. + Options.includeLoopExitInCFG() || Options.shouldUnrollLoops(), + Options.shouldSynthesizeBodies(), + Options.shouldConditionalizeStaticInitializers(), + /*addCXXNewAllocator=*/true, + injector), + Ctx(ASTCtx), Diags(diags), LangOpts(lang), PathConsumers(PDC), + CreateStoreMgr(storemgr), CreateConstraintMgr(constraintmgr), + CheckerMgr(checkerMgr), options(Options) { AnaCtxMgr.getCFGBuildOptions().setAllAlwaysAdd(); }