Renamed RValueDisjunctiveEqual to RValEqualityORSet.
Renamed RValueConjunctiveUnequal to RValInequalityANDSet.
Refactored add/subtract/multiple (and now divide) operations for
RValEqualityORSet to be based on a single template function.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@46374 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/Analysis/GRConstants.cpp b/Analysis/GRConstants.cpp
index 9133ca2..db897b4 100644
--- a/Analysis/GRConstants.cpp
+++ b/Analysis/GRConstants.cpp
@@ -28,9 +28,10 @@
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Compiler.h"
-
#include "llvm/Support/Streams.h"
+#include <functional>
+
#ifndef NDEBUG
#include "llvm/Support/GraphWriter.h"
#include <sstream>
@@ -39,6 +40,7 @@
using namespace clang;
using llvm::dyn_cast;
using llvm::cast;
+using llvm::APSInt;
//===----------------------------------------------------------------------===//
/// ValueKey - A variant smart pointer that wraps either a ValueDecl* or a
@@ -57,7 +59,7 @@
: Raw(reinterpret_cast<uintptr_t>(VD) | IsDecl) {}
ValueKey(Stmt* S, bool isBlkExpr = false)
- : Raw(reinterpret_cast<uintptr_t>(S) | isBlkExpr ? IsBlkExpr : IsSubExpr){}
+ : Raw(reinterpret_cast<uintptr_t>(S) | isBlkExpr ? IsBlkExpr : IsSubExpr) {}
bool isSubExpr() const { return getKind() == IsSubExpr; }
bool isDecl() const { return getKind() == IsDecl; }
@@ -120,8 +122,9 @@
namespace {
-typedef llvm::ImmutableSet<llvm::APSInt > APSIntSetTy;
-
+typedef llvm::ImmutableSet<APSInt > APSIntSetTy;
+
+
class VISIBILITY_HIDDEN ValueManager {
APSIntSetTy::Factory APSIntSetFactory;
ASTContext* Ctx;
@@ -137,12 +140,26 @@
return APSIntSetFactory.GetEmptySet();
}
- APSIntSetTy AddToSet(const APSIntSetTy& Set, const llvm::APSInt& Val) {
+ APSIntSetTy AddToSet(const APSIntSetTy& Set, const APSInt& Val) {
return APSIntSetFactory.Add(Set, Val);
}
};
} // end anonymous namespace
+template <typename OpTy>
+static inline APSIntSetTy APSIntSetOp(ValueManager& ValMgr,
+ APSIntSetTy S1, APSIntSetTy S2,
+ OpTy Op) {
+
+ APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
+
+ for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
+ for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2)
+ M = ValMgr.AddToSet(M, Op(*I1,*I2));
+
+ return M;
+}
+
//===----------------------------------------------------------------------===//
// Expression Values.
//===----------------------------------------------------------------------===//
@@ -225,9 +242,10 @@
RValue EvalAdd(ValueManager& ValMgr, const RValue& RHS) const;
RValue EvalSub(ValueManager& ValMgr, const RValue& RHS) const;
RValue EvalMul(ValueManager& ValMgr, const RValue& RHS) const;
+ RValue EvalDiv(ValueManager& ValMgr, const RValue& RHS) const;
RValue EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
- static RValue GetRValue(ValueManager& ValMgr, const llvm::APSInt& V);
+ static RValue GetRValue(ValueManager& ValMgr, const APSInt& V);
static RValue GetRValue(ValueManager& ValMgr, IntegerLiteral* I);
// Implement isa<T> support.
@@ -244,37 +262,88 @@
namespace {
-enum { RValueDisjunctiveEqualKind = 0x0, NumRValueKind };
+enum { RValEqualityORSetKind,
+ RValInequalityANDSetKind,
+ NumRValueKind };
-class VISIBILITY_HIDDEN RValueDisjunctiveEqual : public RValue {
+class VISIBILITY_HIDDEN RValEqualityORSet : public RValue {
public:
- RValueDisjunctiveEqual(const APSIntSetTy& S)
- : RValue(RValueDisjunctiveEqualKind, S.getRoot()) {}
+ RValEqualityORSet(const APSIntSetTy& S)
+ : RValue(RValEqualityORSetKind, S.getRoot()) {}
APSIntSetTy GetValues() const {
return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
}
- RValueDisjunctiveEqual
- EvalAdd(ValueManager& ValMgr, const RValueDisjunctiveEqual& V) const;
+ RValEqualityORSet
+ EvalAdd(ValueManager& ValMgr, const RValEqualityORSet& V) const {
+ return APSIntSetOp(ValMgr, GetValues(), V.GetValues(),
+ std::plus<APSInt>());
+ }
- RValueDisjunctiveEqual
- EvalSub(ValueManager& ValMgr, const RValueDisjunctiveEqual& V) const;
+ RValEqualityORSet
+ EvalSub(ValueManager& ValMgr, const RValEqualityORSet& V) const {
+ return APSIntSetOp(ValMgr, GetValues(), V.GetValues(),
+ std::minus<APSInt>());
+ }
- RValueDisjunctiveEqual
- EvalMul(ValueManager& ValMgr, const RValueDisjunctiveEqual& V) const;
+ RValEqualityORSet
+ EvalMul(ValueManager& ValMgr, const RValEqualityORSet& V) const {
+ return APSIntSetOp(ValMgr, GetValues(), V.GetValues(),
+ std::multiplies<APSInt>());
+ }
+
+ RValEqualityORSet
+ EvalDiv(ValueManager& ValMgr, const RValEqualityORSet& V) const {
+ return APSIntSetOp(ValMgr, GetValues(), V.GetValues(),
+ std::divides<APSInt>());
+ }
- RValueDisjunctiveEqual
+ RValEqualityORSet
EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
- RValueDisjunctiveEqual
+ RValEqualityORSet
EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
// Implement isa<T> support.
static inline bool classof(const ExprValue* V) {
- return V->getSubKind() == RValueDisjunctiveEqualKind;
+ return V->getSubKind() == RValEqualityORSetKind;
}
};
+
+class VISIBILITY_HIDDEN RValInequalityANDSet : public RValue {
+public:
+ RValInequalityANDSet(const APSIntSetTy& S)
+ : RValue(RValInequalityANDSetKind, S.getRoot()) {}
+
+ APSIntSetTy GetValues() const {
+ return APSIntSetTy(reinterpret_cast<APSIntSetTy::TreeTy*>(getRawPtr()));
+ }
+
+ RValInequalityANDSet
+ EvalAdd(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
+
+ RValInequalityANDSet
+ EvalSub(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
+
+ RValInequalityANDSet
+ EvalMul(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
+
+ RValInequalityANDSet
+ EvalDiv(ValueManager& ValMgr, const RValInequalityANDSet& V) const;
+
+ RValInequalityANDSet
+ EvalCast(ValueManager& ValMgr, Expr* CastExpr) const;
+
+ RValInequalityANDSet
+ EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const;
+
+ // Implement isa<T> support.
+ static inline bool classof(const ExprValue* V) {
+ return V->getSubKind() == RValInequalityANDSetKind;
+ }
+};
+
} // end anonymous namespace
//===----------------------------------------------------------------------===//
@@ -283,15 +352,15 @@
ExprValue ExprValue::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
switch (getSubKind()) {
- case RValueDisjunctiveEqualKind:
- return cast<RValueDisjunctiveEqual>(this)->EvalCast(ValMgr, CastExpr);
+ case RValEqualityORSetKind:
+ return cast<RValEqualityORSet>(this)->EvalCast(ValMgr, CastExpr);
default:
return InvalidValue();
}
}
-RValueDisjunctiveEqual
-RValueDisjunctiveEqual::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
+RValEqualityORSet
+RValEqualityORSet::EvalCast(ValueManager& ValMgr, Expr* CastExpr) const {
QualType T = CastExpr->getType();
assert (T->isIntegerType());
@@ -299,7 +368,7 @@
APSIntSetTy S2 = ValMgr.GetEmptyAPSIntSet();
for (APSIntSetTy::iterator I=S1.begin(), E=S1.end(); I!=E; ++I) {
- llvm::APSInt X = *I;
+ APSInt X = *I;
X.setIsSigned(T->isSignedIntegerType());
X.extOrTrunc(ValMgr.getContext()->getTypeSize(T,CastExpr->getLocStart()));
S2 = ValMgr.AddToSet(S2, X);
@@ -314,15 +383,15 @@
RValue RValue::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const {
switch (getSubKind()) {
- case RValueDisjunctiveEqualKind:
- return cast<RValueDisjunctiveEqual>(this)->EvalMinus(ValMgr, U);
+ case RValEqualityORSetKind:
+ return cast<RValEqualityORSet>(this)->EvalMinus(ValMgr, U);
default:
return cast<RValue>(InvalidValue());
}
}
-RValueDisjunctiveEqual
-RValueDisjunctiveEqual::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const{
+RValEqualityORSet
+RValEqualityORSet::EvalMinus(ValueManager& ValMgr, UnaryOperator* U) const{
assert (U->getType() == U->getSubExpr()->getType());
assert (U->getType()->isIntegerType());
@@ -335,7 +404,7 @@
// FIXME: Shouldn't operator- on APSInt return an APSInt with the proper
// sign?
- llvm::APSInt X(-(*I));
+ APSInt X(-(*I));
X.setIsSigned(true);
S2 = ValMgr.AddToSet(S2, X);
@@ -354,7 +423,7 @@
#define RVALUE_DISPATCH(Op)\
switch (getSubKind()*NumRValueKind+RHS.getSubKind()){\
- RVALUE_DISPATCH_CASE(RValueDisjunctiveEqual,RValueDisjunctiveEqual,Op)\
+ RVALUE_DISPATCH_CASE(RValEqualityORSet,RValEqualityORSet,Op)\
default:\
assert (!isValid() || !RHS.isValid() && "Missing case.");\
break;\
@@ -373,83 +442,21 @@
RVALUE_DISPATCH(Mul)
}
+RValue RValue::EvalDiv(ValueManager& ValMgr, const RValue& RHS) const {
+ RVALUE_DISPATCH(Div)
+}
+
#undef RVALUE_DISPATCH_CASE
#undef RVALUE_DISPATCH
-RValueDisjunctiveEqual
-RValueDisjunctiveEqual::EvalAdd(ValueManager& ValMgr,
- const RValueDisjunctiveEqual& RHS) const {
-
- APSIntSetTy S1 = GetValues();
- APSIntSetTy S2 = RHS.GetValues();
-
- APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
-
- for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
- for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
- // FIXME: operator- on APSInt is really operator* on APInt, which loses
- // the "signess" information (although the bits are correct).
- const llvm::APSInt& X = *I1;
- llvm::APSInt Y = X + *I2;
- Y.setIsSigned(X.isSigned());
- M = ValMgr.AddToSet(M, Y);
- }
-
- return M;
-}
-RValueDisjunctiveEqual
-RValueDisjunctiveEqual::EvalSub(ValueManager& ValMgr,
- const RValueDisjunctiveEqual& RHS) const {
-
- APSIntSetTy S1 = GetValues();
- APSIntSetTy S2 = RHS.GetValues();
-
- APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
-
- for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
- for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
- // FIXME: operator- on APSInt is really operator* on APInt, which loses
- // the "signess" information (although the bits are correct).
- const llvm::APSInt& X = *I1;
- llvm::APSInt Y = X - *I2;
- Y.setIsSigned(X.isSigned());
- M = ValMgr.AddToSet(M, Y);
- }
-
- return M;
-}
-
-RValueDisjunctiveEqual
-RValueDisjunctiveEqual::EvalMul(ValueManager& ValMgr,
- const RValueDisjunctiveEqual& RHS) const {
-
- APSIntSetTy S1 = GetValues();
- APSIntSetTy S2 = RHS.GetValues();
-
- APSIntSetTy M = ValMgr.GetEmptyAPSIntSet();
-
- for (APSIntSetTy::iterator I1=S1.begin(), E1=S2.end(); I1!=E1; ++I1)
- for (APSIntSetTy::iterator I2=S2.begin(), E2=S2.end(); I2!=E2; ++I2) {
- // FIXME: operator* on APSInt is really operator* on APInt, which loses
- // the "signess" information (although the bits are correct).
- const llvm::APSInt& X = *I1;
- llvm::APSInt Y = X * *I2;
- Y.setIsSigned(X.isSigned());
- M = ValMgr.AddToSet(M, Y);
- }
-
- return M;
-}
-
-RValue RValue::GetRValue(ValueManager& ValMgr, const llvm::APSInt& V) {
- return RValueDisjunctiveEqual(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
+RValue RValue::GetRValue(ValueManager& ValMgr, const APSInt& V) {
+ return RValEqualityORSet(ValMgr.AddToSet(ValMgr.GetEmptyAPSIntSet(), V));
}
RValue RValue::GetRValue(ValueManager& ValMgr, IntegerLiteral* I) {
- llvm::APSInt X(I->getValue());
- X.setIsSigned(I->getType()->isSignedIntegerType());
- return GetRValue(ValMgr, X);
+ return GetRValue(ValMgr,
+ APSInt(I->getValue(),I->getType()->isUnsignedIntegerType()));
}
//===----------------------------------------------------------------------===//
@@ -458,7 +465,7 @@
namespace {
-enum { LValueDeclKind=0x0, MaxLValueKind };
+enum { LValueDeclKind, MaxLValueKind };
class VISIBILITY_HIDDEN LValueDecl : public LValue {
public:
@@ -501,8 +508,8 @@
void RValue::print(std::ostream& Out) const {
switch (getSubKind()) {
- case RValueDisjunctiveEqualKind: {
- APSIntSetTy S = cast<RValueDisjunctiveEqual>(this)->GetValues();
+ case RValEqualityORSetKind: {
+ APSIntSetTy S = cast<RValEqualityORSet>(this)->GetValues();
bool first = true;
for (APSIntSetTy::iterator I=S.begin(), E=S.end(); I!=E; ++I) {
@@ -895,7 +902,7 @@
QualType T = U->getType();
unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
- llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
+ APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
RValue R2 = RValue::GetRValue(ValMgr, One);
RValue Result = R1.EvalAdd(ValMgr, R2);
@@ -909,7 +916,7 @@
QualType T = U->getType();
unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
- llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
+ APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
RValue R2 = RValue::GetRValue(ValMgr, One);
RValue Result = R1.EvalSub(ValMgr, R2);
@@ -923,7 +930,7 @@
QualType T = U->getType();
unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
- llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
+ APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
RValue R2 = RValue::GetRValue(ValMgr, One);
RValue Result = R1.EvalAdd(ValMgr, R2);
@@ -937,7 +944,7 @@
QualType T = U->getType();
unsigned bits = getContext()->getTypeSize(T, U->getLocStart());
- llvm::APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
+ APSInt One(llvm::APInt(bits, 1), T->isUnsignedIntegerType());
RValue R2 = RValue::GetRValue(ValMgr, One);
RValue Result = R1.EvalSub(ValMgr, R2);
@@ -1005,6 +1012,13 @@
break;
}
+ case BinaryOperator::Div: {
+ const RValue& R1 = cast<RValue>(V1);
+ const RValue& R2 = cast<RValue>(V2);
+ Nodify(Dst, B, N2, SetValue(St, B, R1.EvalDiv(ValMgr, R2)));
+ break;
+ }
+
case BinaryOperator::Assign: {
const LValue& L1 = cast<LValue>(V1);
const RValue& R2 = cast<RValue>(V2);