From 509bd9e30a09646489e36fe73afbdcc2d1795fad Mon Sep 17 00:00:00 2001 From: Zhongxing Xu Date: Fri, 24 Oct 2008 06:00:12 +0000 Subject: [PATCH] Add printing with llvm::raw_ostream methods to SVals. llvm-svn: 58073 --- .../clang/Analysis/PathSensitive/SVals.h | 3 + clang/lib/Analysis/SVals.cpp | 131 ++++++++++++++++++ 2 files changed, 134 insertions(+) diff --git a/clang/include/clang/Analysis/PathSensitive/SVals.h b/clang/include/clang/Analysis/PathSensitive/SVals.h index a228980bb4d8..e3ca9689fe76 100644 --- a/clang/include/clang/Analysis/PathSensitive/SVals.h +++ b/clang/include/clang/Analysis/PathSensitive/SVals.h @@ -89,6 +89,7 @@ public: bool isZeroConstant() const; void print(std::ostream& OS) const; + void print(llvm::raw_ostream& OS) const; void printStdErr() const; typedef const SymbolID* symbol_iterator; @@ -126,6 +127,7 @@ protected: public: void print(std::ostream& Out) const; + void print(llvm::raw_ostream& Out) const; // Utility methods to create NonLocs. static NonLoc MakeVal(BasicValueFactory& BasicVals, uint64_t X, QualType T); @@ -151,6 +153,7 @@ protected: public: void print(std::ostream& Out) const; + void print(llvm::raw_ostream& Out) const; static Loc MakeVal(AddrLabelExpr* E); diff --git a/clang/lib/Analysis/SVals.cpp b/clang/lib/Analysis/SVals.cpp index db1a8403fb82..2382b759e578 100644 --- a/clang/lib/Analysis/SVals.cpp +++ b/clang/lib/Analysis/SVals.cpp @@ -397,3 +397,134 @@ void Loc::print(std::ostream& Out) const { 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(this)->print(Out); break; + + case LocKind: + cast(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(this)->getValue().getZExtValue(); + + if (cast(this)->getValue().isUnsigned()) + Out << 'U'; + + break; + + case nonloc::SymbolValKind: + Out << '$' << cast(this)->getSymbol(); + break; + + case nonloc::SymIntConstraintValKind: { + const nonloc::SymIntConstraintVal& C = + *cast(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(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(this)->getValue().getZExtValue() + << " (Loc)"; + break; + + case loc::SymbolValKind: + Out << '$' << cast(this)->getSymbol(); + break; + + case loc::GotoLabelKind: + Out << "&&" + << cast(this)->getLabel()->getID()->getName(); + break; + + case loc::MemRegionKind: + Out << '&' << cast(this)->getRegion()->getString(); + break; + + case loc::FuncValKind: + Out << "function " + << cast(this)->getDecl()->getIdentifier()->getName(); + break; + + case loc::StringLiteralValKind: + Out << "literal \"" + << cast(this)->getLiteral()->getStrData() + << "\""; + break; + + default: + assert (false && "Pretty-printing not implemented for this Loc."); + break; + } +}