From: Ted Kremenek <kremenek@apple.com>
Date: Thu, 2 Apr 2009 05:13:24 +0000 (+0000)
Subject: Hack: Add 'PathDiagnostic::flattenLocations()'. Because PlistDiagnosticClient
X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=96a69267fc771dcb288bb7b3c5b5b6d49a9542ff;p=clang

Hack: Add 'PathDiagnostic::flattenLocations()'. Because PlistDiagnosticClient
can use a PathLocation after any reference Stmts are reclaimed,
flattenLocation() converts those references to statements to source ranges.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@68292 91177308-0d34-0410-b5e6-96231b3b80d8
---

diff --git a/include/clang/Analysis/PathDiagnostic.h b/include/clang/Analysis/PathDiagnostic.h
index 234fd18db0..bed2e0e3c9 100644
--- a/include/clang/Analysis/PathDiagnostic.h
+++ b/include/clang/Analysis/PathDiagnostic.h
@@ -101,6 +101,14 @@ public:
     *this = PathDiagnosticLocation();
   }
   
+  void flatten() {
+    if (K == Statement) {
+      R = asRange();
+      K = Range;
+      S = 0;
+    }    
+  }
+  
   const SourceManager& getManager() const { assert(isValid()); return *SM; }
 };
 
@@ -114,6 +122,11 @@ public:
   
   const PathDiagnosticLocation &getStart() const { return Start; }
   const PathDiagnosticLocation &getEnd() const { return End; }
+  
+  void flatten() {
+    Start.flatten();
+    End.flatten();
+  }
 };
 
 //===----------------------------------------------------------------------===//
@@ -154,6 +167,7 @@ public:
   DisplayHint getDisplayHint() const { return Hint; }
   
   virtual PathDiagnosticLocation getLocation() const = 0;
+  virtual void flattenLocations() = 0;
   
   Kind getKind() const { return kind; }
   
@@ -208,6 +222,7 @@ public:
   }  
 
   PathDiagnosticLocation getLocation() const { return Pos; }
+  virtual void flattenLocations() { Pos.flatten(); }
 };
   
 class PathDiagnosticEventPiece : public PathDiagnosticSpotPiece {
@@ -266,12 +281,18 @@ public:
   
   void push_back(const PathDiagnosticLocationPair &X) { LPairs.push_back(X); }
   
-  virtual PathDiagnosticLocation getLocation() const { return getStartLocation(); }
+  virtual PathDiagnosticLocation getLocation() const {
+    return getStartLocation();
+  }
   
   typedef std::vector<PathDiagnosticLocationPair>::iterator iterator;
   iterator begin() { return LPairs.begin(); }
   iterator end()   { return LPairs.end(); }
 
+  virtual void flattenLocations() {
+    for (iterator I=begin(), E=end(); I!=E; ++I) I->flatten();
+  }
+  
   typedef std::vector<PathDiagnosticLocationPair>::const_iterator
           const_iterator;
   const_iterator begin() const { return LPairs.begin(); }
@@ -298,6 +319,11 @@ public:
   iterator begin() { return SubPieces.begin(); }
   iterator end() { return SubPieces.end(); }
   
+  virtual void flattenLocations() {
+    PathDiagnosticSpotPiece::flattenLocations();
+    for (iterator I=begin(), E=end(); I!=E; ++I) (*I)->flattenLocations();
+  }
+  
   typedef std::vector<PathDiagnosticPiece*>::const_iterator const_iterator;
   const_iterator begin() const { return SubPieces.begin(); }
   const_iterator end() const { return SubPieces.end(); }
@@ -434,6 +460,10 @@ public:
   const_reverse_iterator rbegin() const{ return const_reverse_iterator(end()); }
   reverse_iterator rend()              { return reverse_iterator(begin()); }
   const_reverse_iterator rend() const { return const_reverse_iterator(begin());}
+  
+  void flattenLocations() {
+    for (iterator I = begin(), E = end(); I != E; ++I) I->flattenLocations();
+  }
 };
   
   
diff --git a/lib/Frontend/PlistDiagnostics.cpp b/lib/Frontend/PlistDiagnostics.cpp
index 9649cf6188..575c3f3bfc 100644
--- a/lib/Frontend/PlistDiagnostics.cpp
+++ b/lib/Frontend/PlistDiagnostics.cpp
@@ -267,6 +267,10 @@ void PlistDiagnostics::HandlePathDiagnostic(const PathDiagnostic* D) {
     return;
   }
   
+  // We need to flatten the locations (convert Stmt* to locations) because
+  // the referenced statements may be freed by the time the diagnostics
+  // are emitted.
+  const_cast<PathDiagnostic*>(D)->flattenLocations();  
   BatchedDiags.push_back(D);
 }