From: Ted Kremenek Date: Tue, 5 Feb 2008 23:08:41 +0000 (+0000) Subject: Added pretty-printing support for lval::SymIntConstraintVal and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0806acf6a197ac7bd5c87649c0429e64e5d0db06;p=clang Added pretty-printing support for lval::SymIntConstraintVal and nonlval::SymIntConstraintVal. Reworked transfer function for '==' and '!=' for LValues to return SymIntConstraintVal when comparing a symbol with a constant. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46778 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Analysis/RValues.cpp b/Analysis/RValues.cpp index c5c5bdeaa8..33d9d656a7 100644 --- a/Analysis/RValues.cpp +++ b/Analysis/RValues.cpp @@ -223,49 +223,109 @@ NonLValue NonLValue::NE(ValueManager& ValMgr, const NonLValue& RHS) const { NonLValue LValue::EQ(ValueManager& ValMgr, const LValue& RHS) const { - if (getSubKind() != RHS.getSubKind()) - return NonLValue::GetIntTruthValue(ValMgr, false); - switch (getSubKind()) { default: assert(false && "EQ not implemented for this LValue."); return cast(InvalidValue()); - case lval::ConcreteIntKind: { - bool b = cast(this)->getValue() == - cast(RHS).getValue(); - - return NonLValue::GetIntTruthValue(ValMgr, b); - } + case lval::ConcreteIntKind: + if (isa(RHS)) { + bool b = cast(this)->getValue() == + cast(RHS).getValue(); + + return NonLValue::GetIntTruthValue(ValMgr, b); + } + else if (isa(RHS)) { + + const SymIntConstraint& C = + ValMgr.getConstraint(cast(RHS).getSymbol(), + BinaryOperator::EQ, + cast(this)->getValue()); + + return nonlval::SymIntConstraintVal(C); + } + + break; + + case lval::SymbolValKind: { + if (isa(RHS)) { + + const SymIntConstraint& C = + ValMgr.getConstraint(cast(this)->getSymbol(), + BinaryOperator::EQ, + cast(RHS).getValue()); + + return nonlval::SymIntConstraintVal(C); + } + + assert (!isa(RHS) && "FIXME: Implement unification."); - case lval::DeclValKind: { - bool b = cast(*this) == cast(RHS); - return NonLValue::GetIntTruthValue(ValMgr, b); + break; } + + case lval::DeclValKind: + if (isa(RHS)) { + bool b = cast(*this) == cast(RHS); + return NonLValue::GetIntTruthValue(ValMgr, b); + } + + break; } + + return NonLValue::GetIntTruthValue(ValMgr, false); } NonLValue LValue::NE(ValueManager& ValMgr, const LValue& RHS) const { - if (getSubKind() != RHS.getSubKind()) - return NonLValue::GetIntTruthValue(ValMgr, true); - switch (getSubKind()) { default: - assert(false && "EQ not implemented for this LValue."); + assert(false && "NE not implemented for this LValue."); return cast(InvalidValue()); - case lval::ConcreteIntKind: { - bool b = cast(this)->getValue() != - cast(RHS).getValue(); + case lval::ConcreteIntKind: + if (isa(RHS)) { + bool b = cast(this)->getValue() != + cast(RHS).getValue(); + + return NonLValue::GetIntTruthValue(ValMgr, b); + } + else if (isa(RHS)) { + + const SymIntConstraint& C = + ValMgr.getConstraint(cast(RHS).getSymbol(), + BinaryOperator::NE, + cast(this)->getValue()); + + return nonlval::SymIntConstraintVal(C); + } - return NonLValue::GetIntTruthValue(ValMgr, b); - } + break; - case lval::DeclValKind: { - bool b = cast(*this) != cast(RHS); - return NonLValue::GetIntTruthValue(ValMgr, b); - } + case lval::SymbolValKind: { + if (isa(RHS)) { + + const SymIntConstraint& C = + ValMgr.getConstraint(cast(this)->getSymbol(), + BinaryOperator::NE, + cast(RHS).getValue()); + + return nonlval::SymIntConstraintVal(C); + } + + assert (!isa(RHS) && "FIXME: Implement sym !=."); + + break; + } + + case lval::DeclValKind: + if (isa(RHS)) { + bool b = cast(*this) == cast(RHS); + return NonLValue::GetIntTruthValue(ValMgr, b); + } + + break; } + + return NonLValue::GetIntTruthValue(ValMgr, true); } @@ -320,6 +380,14 @@ void RValue::print(std::ostream& Out) const { } } +static void printOpcode(std::ostream& Out, BinaryOperator::Opcode Op) { + switch (Op) { + case BinaryOperator::EQ: Out << "=="; break; + case BinaryOperator::NE: Out << "!="; break; + default: assert(false && "Not yet implemented."); + } +} + void NonLValue::print(std::ostream& Out) const { switch (getSubKind()) { case nonlval::ConcreteIntKind: @@ -327,8 +395,18 @@ void NonLValue::print(std::ostream& Out) const { break; case nonlval::SymbolValKind: - Out << '$' << cast(this)->getSymbolID(); + Out << '$' << cast(this)->getSymbol(); break; + + case nonlval::SymIntConstraintValKind: { + const nonlval::SymIntConstraintVal& C = + *cast(this); + + Out << '$' << C.getConstraint().getSymbol() << ' '; + printOpcode(Out, C.getConstraint().getOpcode()); + Out << ' ' << C.getConstraint().getInt().toString(); + break; + } default: assert (false && "Pretty-printed not implemented for this NonLValue."); @@ -336,6 +414,7 @@ void NonLValue::print(std::ostream& Out) const { } } + void LValue::print(std::ostream& Out) const { switch (getSubKind()) { case lval::ConcreteIntKind: @@ -344,9 +423,19 @@ void LValue::print(std::ostream& Out) const { break; case lval::SymbolValKind: - Out << '$' << cast(this)->getSymbolID(); + Out << '$' << cast(this)->getSymbol(); break; + case lval::SymIntConstraintValKind: { + const lval::SymIntConstraintVal& C = + *cast(this); + + Out << '$' << C.getConstraint().getSymbol() << ' '; + printOpcode(Out, C.getConstraint().getOpcode()); + Out << ' ' << C.getConstraint().getInt().toString(); + break; + } + case lval::DeclValKind: Out << '&' << cast(this)->getDecl()->getIdentifier()->getName(); diff --git a/Analysis/RValues.h b/Analysis/RValues.h index 1db0a185d4..9c788cac35 100644 --- a/Analysis/RValues.h +++ b/Analysis/RValues.h @@ -339,7 +339,7 @@ namespace nonlval { : NonLValue(SymbolValKind, reinterpret_cast((uintptr_t) SymID)) {} - SymbolID getSymbolID() const { + SymbolID getSymbol() const { return (SymbolID) reinterpret_cast(getRawPtr()); } @@ -442,6 +442,7 @@ namespace nonlval { namespace lval { enum Kind { SymbolValKind, + SymIntConstraintValKind, DeclValKind, ConcreteIntKind, NumKind }; @@ -451,7 +452,7 @@ namespace lval { SymbolVal(unsigned SymID) : LValue(SymbolValKind, reinterpret_cast((uintptr_t) SymID)) {} - SymbolID getSymbolID() const { + SymbolID getSymbol() const { return (SymbolID) reinterpret_cast(getRawPtr()); } @@ -459,6 +460,20 @@ namespace lval { return V->getSubKind() == SymbolValKind; } }; + + class SymIntConstraintVal : public LValue { + public: + SymIntConstraintVal(const SymIntConstraint& C) + : LValue(SymIntConstraintValKind, reinterpret_cast(&C)) {} + + const SymIntConstraint& getConstraint() const { + return *reinterpret_cast(getRawPtr()); + } + + static inline bool classof(const RValue* V) { + return isa(V) && V->getSubKind() == SymIntConstraintValKind; + } + }; class DeclVal : public LValue { public: