Rework use of loc::SymbolVal in the retain/release checker to use the new method
SVal::getAsLocSymbol(). This simplifies the code and allows the retain/release
checker to (I believe) also correctly reason about location symbols wrapped in
SymbolicRegions.

Along the way I cleaned up SymbolRef a little, disallowing implicit casts to
'unsigned'.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@65972 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index 2017c4b..c12c2d2 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -54,6 +54,42 @@
   return symbol_iterator();
 }
 
+/// getAsLocSymbol - If this SVal is a location (subclasses Loc) and 
+///  wraps a symbol, return that SymbolRef.  Otherwise return a SymbolRef
+///  where 'isValid()' returns false.
+SymbolRef SVal::getAsLocSymbol() const {
+  if (const loc::SymbolVal *X = dyn_cast<loc::SymbolVal>(this))
+    return X->getSymbol();
+
+  if (const loc::MemRegionVal *X = dyn_cast<loc::MemRegionVal>(this)) {
+    const MemRegion *R = X->getRegion();
+    
+    while (R) {
+      // Blast through region views.
+      if (const TypedViewRegion *View = dyn_cast<TypedViewRegion>(R)) {
+        R = View->getSuperRegion();
+        continue;
+      }
+      
+      if (const SymbolicRegion *SymR = dyn_cast<SymbolicRegion>(R))
+        return SymR->getSymbol();
+      
+      break;
+    }
+  }
+  
+  return SymbolRef();
+}
+
+/// getAsSymbol - If this Sval wraps a symbol return that SymbolRef.
+///  Otherwise return a SymbolRef where 'isValid()' returns false.
+SymbolRef SVal::getAsSymbol() const {
+  if (const nonloc::SymbolVal *X = dyn_cast<nonloc::SymbolVal>(this))
+    return X->getSymbol();
+  
+  return getAsLocSymbol();
+}
+
 //===----------------------------------------------------------------------===//
 // Other Iterators.
 //===----------------------------------------------------------------------===//