Generalize caching mechanism for bugs reports.  Now individual BugTypes
can decide the policy on how to cache related bugs.  This allows us to
properly to handle warning about multiple leaks in the same location in the
ref count checker (not yet done).


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49918 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/BasicObjCFoundationChecks.cpp b/lib/Analysis/BasicObjCFoundationChecks.cpp
index 958f85d..7e51aee 100644
--- a/lib/Analysis/BasicObjCFoundationChecks.cpp
+++ b/lib/Analysis/BasicObjCFoundationChecks.cpp
@@ -54,7 +54,7 @@
 
 namespace {
   
-class VISIBILITY_HIDDEN NilArg : public BugType {
+class VISIBILITY_HIDDEN NilArg : public BugTypeCacheLocation {
 public:
   virtual ~NilArg() {}
   
diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp
index e74295c..e69c5a6 100644
--- a/lib/Analysis/BugReporter.cpp
+++ b/lib/Analysis/BugReporter.cpp
@@ -357,12 +357,14 @@
   }
 }
 
-bool BugReporter::IsCached(ExplodedNode<ValueState>* N) {
+bool BugTypeCacheLocation::isCached(BugReport& R) {
+  
+  ExplodedNode<ValueState>* N = R.getEndNode();
   
   if (!N)
     return false;
-  
-  // HACK: Cache the location of the error.  Don't emit the same
+
+  // Cache the location of the error.  Don't emit the same
   // warning for the same error type that occurs at the same program
   // location but along a different path.
   
@@ -371,14 +373,13 @@
   if (CachedErrors.count(p))
     return true;
   
-  CachedErrors.insert(p);
-  
+  CachedErrors.insert(p);  
   return false;
 }
 
 void BugReporter::EmitWarning(BugReport& R) {
 
-  if (IsCached(R.getEndNode()))
+  if (R.getBugType().isCached(R))
     return;
 
   PathDiagnostic D(R.getName());  
diff --git a/lib/Analysis/CFRefCount.cpp b/lib/Analysis/CFRefCount.cpp
index 3eb0379..253e005 100644
--- a/lib/Analysis/CFRefCount.cpp
+++ b/lib/Analysis/CFRefCount.cpp
@@ -1268,7 +1268,7 @@
   // Bug Descriptions. //
   //===-------------===//  
   
-  class VISIBILITY_HIDDEN CFRefBug : public BugType {
+  class VISIBILITY_HIDDEN CFRefBug : public BugTypeCacheLocation {
   protected:
     CFRefCount& TF;
     
@@ -1331,7 +1331,7 @@
   class VISIBILITY_HIDDEN CFRefReport : public RangedBugReport {
     SymbolID Sym;
   public:
-    CFRefReport(const BugType& D, ExplodedNode<ValueState> *n, SymbolID sym)
+    CFRefReport(BugType& D, ExplodedNode<ValueState> *n, SymbolID sym)
       : RangedBugReport(D, n), Sym(sym) {}
         
     virtual ~CFRefReport() {}
diff --git a/lib/Analysis/DeadStores.cpp b/lib/Analysis/DeadStores.cpp
index 719b5eb..6858e3a 100644
--- a/lib/Analysis/DeadStores.cpp
+++ b/lib/Analysis/DeadStores.cpp
@@ -109,7 +109,7 @@
   std::list<std::string> Strs;
   FullSourceLoc L;
 public:
-  DiagBugReport(const BugType& D, FullSourceLoc l) :
+  DiagBugReport(BugType& D, FullSourceLoc l) :
     RangedBugReport(D, NULL), L(l) {}
   
   virtual ~DiagBugReport() {}
@@ -124,7 +124,7 @@
   
 class VISIBILITY_HIDDEN DiagCollector : public DiagnosticClient {
   std::list<DiagBugReport> Reports;
-  const BugType& D;
+  BugType& D;
 public:
   DiagCollector(BugType& d) : D(d) {}
   
@@ -159,7 +159,7 @@
   iterator end() { return Reports.end(); }
 };
   
-class VISIBILITY_HIDDEN DeadStoresChecker : public BugType {
+class VISIBILITY_HIDDEN DeadStoresChecker : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "dead store";
diff --git a/lib/Analysis/GRSimpleVals.cpp b/lib/Analysis/GRSimpleVals.cpp
index ea8762a..2c14dde 100644
--- a/lib/Analysis/GRSimpleVals.cpp
+++ b/lib/Analysis/GRSimpleVals.cpp
@@ -40,8 +40,7 @@
 }
 
 template <typename ITER>
-void GenericEmitWarnings(BugReporter& BR, const BugType& D,
-                         ITER I, ITER E) {
+void GenericEmitWarnings(BugReporter& BR, BugType& D, ITER I, ITER E) {
   
   for (; I != E; ++I) {
     BugReport R(D, GetNode(I));    
@@ -55,7 +54,7 @@
 
 namespace {
   
-class VISIBILITY_HIDDEN NullDeref : public BugType {
+class VISIBILITY_HIDDEN NullDeref : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "null dereference";
@@ -72,7 +71,7 @@
   }
 };
 
-class VISIBILITY_HIDDEN UndefDeref : public BugType {
+class VISIBILITY_HIDDEN UndefDeref : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "bad dereference";
@@ -89,7 +88,7 @@
   }
 };
   
-class VISIBILITY_HIDDEN UndefBranch : public BugType {
+class VISIBILITY_HIDDEN UndefBranch : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "uninitialized value";
@@ -106,7 +105,7 @@
   }
 };
   
-class VISIBILITY_HIDDEN DivZero : public BugType {
+class VISIBILITY_HIDDEN DivZero : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "divide-by-zero";
@@ -123,7 +122,7 @@
   }
 };
 
-class VISIBILITY_HIDDEN UndefResult : public BugType {
+class VISIBILITY_HIDDEN UndefResult : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "undefined result";
@@ -140,7 +139,7 @@
   }
 };
   
-class VISIBILITY_HIDDEN BadCall : public BugType {
+class VISIBILITY_HIDDEN BadCall : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "invalid function call";
@@ -158,7 +157,7 @@
 };
   
   
-class VISIBILITY_HIDDEN BadArg : public BugType {
+class VISIBILITY_HIDDEN BadArg : public BugTypeCacheLocation {
 public:
   
   virtual ~BadArg() {}
@@ -214,7 +213,7 @@
   }
 };
 
-class VISIBILITY_HIDDEN BadReceiver : public BugType {
+class VISIBILITY_HIDDEN BadReceiver : public BugTypeCacheLocation {
 public:  
   virtual const char* getName() const {
     return "bad receiver";
@@ -245,7 +244,7 @@
   }
 };
   
-class VISIBILITY_HIDDEN RetStack : public BugType {
+class VISIBILITY_HIDDEN RetStack : public BugTypeCacheLocation {
 public:
   virtual const char* getName() const {
     return "return of stack address";