Add printing with llvm::raw_ostream methods to SVals.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@58073 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Analysis/SVals.cpp b/lib/Analysis/SVals.cpp
index db1a840..2382b75 100644
--- a/lib/Analysis/SVals.cpp
+++ b/lib/Analysis/SVals.cpp
@@ -397,3 +397,134 @@
       break;
   }
 }
+
+//===----------------------------------------------------------------------===//
+// Pretty-Printing with llvm::raw_ostream.
+//===----------------------------------------------------------------------===//
+
+void SVal::print(llvm::raw_ostream& Out) const {
+
+  switch (getBaseKind()) {
+      
+    case UnknownKind:
+      Out << "Invalid"; break;
+      
+    case NonLocKind:
+      cast<NonLoc>(this)->print(Out); break;
+      
+    case LocKind:
+      cast<Loc>(this)->print(Out); break;
+      
+    case UndefinedKind:
+      Out << "Undefined"; break;
+      
+    default:
+      assert (false && "Invalid SVal.");
+  }
+}
+
+static void printOpcode(llvm::raw_ostream& Out, BinaryOperator::Opcode Op) {
+  
+  switch (Op) {      
+    case BinaryOperator::Mul: Out << '*'  ; break;
+    case BinaryOperator::Div: Out << '/'  ; break;
+    case BinaryOperator::Rem: Out << '%'  ; break;
+    case BinaryOperator::Add: Out << '+'  ; break;
+    case BinaryOperator::Sub: Out << '-'  ; break;
+    case BinaryOperator::Shl: Out << "<<" ; break;
+    case BinaryOperator::Shr: Out << ">>" ; break;
+    case BinaryOperator::LT:  Out << "<"  ; break;
+    case BinaryOperator::GT:  Out << '>'  ; break;
+    case BinaryOperator::LE:  Out << "<=" ; break;
+    case BinaryOperator::GE:  Out << ">=" ; break;    
+    case BinaryOperator::EQ:  Out << "==" ; break;
+    case BinaryOperator::NE:  Out << "!=" ; break;
+    case BinaryOperator::And: Out << '&'  ; break;
+    case BinaryOperator::Xor: Out << '^'  ; break;
+    case BinaryOperator::Or:  Out << '|'  ; break;
+      
+    default: assert(false && "Not yet implemented.");
+  }        
+}
+
+void NonLoc::print(llvm::raw_ostream& Out) const {
+
+  switch (getSubKind()) {  
+
+    case nonloc::ConcreteIntKind:
+      Out << cast<nonloc::ConcreteInt>(this)->getValue().getZExtValue();
+
+      if (cast<nonloc::ConcreteInt>(this)->getValue().isUnsigned())
+        Out << 'U';
+      
+      break;
+      
+    case nonloc::SymbolValKind:
+      Out << '$' << cast<nonloc::SymbolVal>(this)->getSymbol();
+      break;
+     
+    case nonloc::SymIntConstraintValKind: {
+      const nonloc::SymIntConstraintVal& C = 
+        *cast<nonloc::SymIntConstraintVal>(this);
+      
+      Out << '$' << C.getConstraint().getSymbol() << ' ';
+      printOpcode(Out, C.getConstraint().getOpcode());
+      Out << ' ' << C.getConstraint().getInt().getZExtValue();
+      
+      if (C.getConstraint().getInt().isUnsigned())
+        Out << 'U';
+      
+      break;
+    }
+    
+    case nonloc::LocAsIntegerKind: {
+      const nonloc::LocAsInteger& C = *cast<nonloc::LocAsInteger>(this);
+      C.getLoc().print(Out);
+      Out << " [as " << C.getNumBits() << " bit integer]";
+      break;
+    }
+      
+    default:
+      assert (false && "Pretty-printed not implemented for this NonLoc.");
+      break;
+  }
+}
+
+void Loc::print(llvm::raw_ostream& Out) const {
+  
+  switch (getSubKind()) {        
+
+    case loc::ConcreteIntKind:
+      Out << cast<loc::ConcreteInt>(this)->getValue().getZExtValue()
+          << " (Loc)";
+      break;
+      
+    case loc::SymbolValKind:
+      Out << '$' << cast<loc::SymbolVal>(this)->getSymbol();
+      break;
+      
+    case loc::GotoLabelKind:
+      Out << "&&"
+          << cast<loc::GotoLabel>(this)->getLabel()->getID()->getName();
+      break;
+
+    case loc::MemRegionKind:
+      Out << '&' << cast<loc::MemRegionVal>(this)->getRegion()->getString();
+      break;
+      
+    case loc::FuncValKind:
+      Out << "function " 
+          << cast<loc::FuncVal>(this)->getDecl()->getIdentifier()->getName();
+      break;
+      
+    case loc::StringLiteralValKind:
+      Out << "literal \""
+          << cast<loc::StringLiteralVal>(this)->getLiteral()->getStrData()
+          << "\"";
+      break;
+      
+    default:
+      assert (false && "Pretty-printing not implemented for this Loc.");
+      break;
+  }
+}