[Analyzer] Do not use static storage to for implementations created in BodyFarm.cpp

Differential Revision: https://reviews.llvm.org/D39208

llvm-svn: 316400
diff --git a/clang/lib/Analysis/AnalysisDeclContext.cpp b/clang/lib/Analysis/AnalysisDeclContext.cpp
index 73eb142..2171194 100644
--- a/clang/lib/Analysis/AnalysisDeclContext.cpp
+++ b/clang/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<FunctionDecl>(D)) {
@@ -99,8 +88,7 @@
     if (auto *CoroBody = dyn_cast_or_null<CoroutineBodyStmt>(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<ObjCMethodDecl>(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() {}
 
diff --git a/clang/lib/Analysis/BodyFarm.cpp b/clang/lib/Analysis/BodyFarm.cpp
index 6a8b529..dd34884 100644
--- a/clang/lib/Analysis/BodyFarm.cpp
+++ b/clang/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"
diff --git a/clang/lib/Analysis/BodyFarm.h b/clang/lib/Analysis/BodyFarm.h
deleted file mode 100644
index edbe996..0000000
--- a/clang/lib/Analysis/BodyFarm.h
+++ /dev/null
@@ -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<const Decl *, Optional<Stmt *> > BodyMap;
-
-  ASTContext &C;
-  BodyMap Bodies;
-  CodeInjector *Injector;
-};
-}
-
-#endif