forked from OSchip/llvm-project
[analyzer] Merge implementations of SymInt, IntSym, and SymSym exprs
Summary: SymIntExpr, IntSymExpr, and SymSymExpr share a big portion of logic that used to be duplicated across all three classes. New implementation also adds an easy way of introducing another type of operands into the mix. Differential Revision: https://reviews.llvm.org/D79156
This commit is contained in:
parent
f5192d7fb7
commit
bb2ae74717
|
@ -326,136 +326,83 @@ public:
|
|||
Kind k = SE->getKind();
|
||||
return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS;
|
||||
}
|
||||
|
||||
protected:
|
||||
static unsigned computeOperandComplexity(const SymExpr *Value) {
|
||||
return Value->computeComplexity();
|
||||
}
|
||||
static unsigned computeOperandComplexity(const llvm::APSInt &Value) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const llvm::APSInt *getPointer(const llvm::APSInt &Value) {
|
||||
return &Value;
|
||||
}
|
||||
static const SymExpr *getPointer(const SymExpr *Value) { return Value; }
|
||||
|
||||
static void dumpToStreamImpl(raw_ostream &os, const SymExpr *Value);
|
||||
static void dumpToStreamImpl(raw_ostream &os, const llvm::APSInt &Value);
|
||||
static void dumpToStreamImpl(raw_ostream &os, BinaryOperator::Opcode op);
|
||||
};
|
||||
|
||||
/// Template implementation for all binary symbolic expressions
|
||||
template <class LHSTYPE, class RHSTYPE, SymExpr::Kind ClassKind>
|
||||
class BinarySymExprImpl : public BinarySymExpr {
|
||||
LHSTYPE LHS;
|
||||
RHSTYPE RHS;
|
||||
|
||||
public:
|
||||
BinarySymExprImpl(LHSTYPE lhs, BinaryOperator::Opcode op, RHSTYPE rhs,
|
||||
QualType t)
|
||||
: BinarySymExpr(ClassKind, op, t), LHS(lhs), RHS(rhs) {
|
||||
assert(getPointer(lhs));
|
||||
assert(getPointer(rhs));
|
||||
}
|
||||
|
||||
void dumpToStream(raw_ostream &os) const override {
|
||||
dumpToStreamImpl(os, LHS);
|
||||
dumpToStreamImpl(os, getOpcode());
|
||||
dumpToStreamImpl(os, RHS);
|
||||
}
|
||||
|
||||
LHSTYPE getLHS() const { return LHS; }
|
||||
RHSTYPE getRHS() const { return RHS; }
|
||||
|
||||
unsigned computeComplexity() const override {
|
||||
if (Complexity == 0)
|
||||
Complexity =
|
||||
computeOperandComplexity(RHS) + computeOperandComplexity(LHS);
|
||||
return Complexity;
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID &ID, LHSTYPE lhs,
|
||||
BinaryOperator::Opcode op, RHSTYPE rhs, QualType t) {
|
||||
ID.AddInteger((unsigned)ClassKind);
|
||||
ID.AddPointer(getPointer(lhs));
|
||||
ID.AddInteger(op);
|
||||
ID.AddPointer(getPointer(rhs));
|
||||
ID.Add(t);
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID &ID) override {
|
||||
Profile(ID, LHS, getOpcode(), RHS, getType());
|
||||
}
|
||||
|
||||
// Implement isa<T> support.
|
||||
static bool classof(const SymExpr *SE) { return SE->getKind() == ClassKind; }
|
||||
};
|
||||
|
||||
/// Represents a symbolic expression like 'x' + 3.
|
||||
class SymIntExpr : public BinarySymExpr {
|
||||
const SymExpr *LHS;
|
||||
const llvm::APSInt& RHS;
|
||||
|
||||
public:
|
||||
SymIntExpr(const SymExpr *lhs, BinaryOperator::Opcode op,
|
||||
const llvm::APSInt &rhs, QualType t)
|
||||
: BinarySymExpr(SymIntExprKind, op, t), LHS(lhs), RHS(rhs) {
|
||||
assert(lhs);
|
||||
}
|
||||
|
||||
void dumpToStream(raw_ostream &os) const override;
|
||||
|
||||
const SymExpr *getLHS() const { return LHS; }
|
||||
const llvm::APSInt &getRHS() const { return RHS; }
|
||||
|
||||
unsigned computeComplexity() const override {
|
||||
if (Complexity == 0)
|
||||
Complexity = 1 + LHS->computeComplexity();
|
||||
return Complexity;
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
|
||||
BinaryOperator::Opcode op, const llvm::APSInt& rhs,
|
||||
QualType t) {
|
||||
ID.AddInteger((unsigned) SymIntExprKind);
|
||||
ID.AddPointer(lhs);
|
||||
ID.AddInteger(op);
|
||||
ID.AddPointer(&rhs);
|
||||
ID.Add(t);
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) override {
|
||||
Profile(ID, LHS, getOpcode(), RHS, getType());
|
||||
}
|
||||
|
||||
// Implement isa<T> support.
|
||||
static bool classof(const SymExpr *SE) {
|
||||
return SE->getKind() == SymIntExprKind;
|
||||
}
|
||||
};
|
||||
using SymIntExpr = BinarySymExprImpl<const SymExpr *, const llvm::APSInt &,
|
||||
SymExpr::Kind::SymIntExprKind>;
|
||||
|
||||
/// Represents a symbolic expression like 3 - 'x'.
|
||||
class IntSymExpr : public BinarySymExpr {
|
||||
const llvm::APSInt& LHS;
|
||||
const SymExpr *RHS;
|
||||
|
||||
public:
|
||||
IntSymExpr(const llvm::APSInt &lhs, BinaryOperator::Opcode op,
|
||||
const SymExpr *rhs, QualType t)
|
||||
: BinarySymExpr(IntSymExprKind, op, t), LHS(lhs), RHS(rhs) {
|
||||
assert(rhs);
|
||||
}
|
||||
|
||||
void dumpToStream(raw_ostream &os) const override;
|
||||
|
||||
const SymExpr *getRHS() const { return RHS; }
|
||||
const llvm::APSInt &getLHS() const { return LHS; }
|
||||
|
||||
unsigned computeComplexity() const override {
|
||||
if (Complexity == 0)
|
||||
Complexity = 1 + RHS->computeComplexity();
|
||||
return Complexity;
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID& ID, const llvm::APSInt& lhs,
|
||||
BinaryOperator::Opcode op, const SymExpr *rhs,
|
||||
QualType t) {
|
||||
ID.AddInteger((unsigned) IntSymExprKind);
|
||||
ID.AddPointer(&lhs);
|
||||
ID.AddInteger(op);
|
||||
ID.AddPointer(rhs);
|
||||
ID.Add(t);
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) override {
|
||||
Profile(ID, LHS, getOpcode(), RHS, getType());
|
||||
}
|
||||
|
||||
// Implement isa<T> support.
|
||||
static bool classof(const SymExpr *SE) {
|
||||
return SE->getKind() == IntSymExprKind;
|
||||
}
|
||||
};
|
||||
using IntSymExpr = BinarySymExprImpl<const llvm::APSInt &, const SymExpr *,
|
||||
SymExpr::Kind::IntSymExprKind>;
|
||||
|
||||
/// Represents a symbolic expression like 'x' + 'y'.
|
||||
class SymSymExpr : public BinarySymExpr {
|
||||
const SymExpr *LHS;
|
||||
const SymExpr *RHS;
|
||||
|
||||
public:
|
||||
SymSymExpr(const SymExpr *lhs, BinaryOperator::Opcode op, const SymExpr *rhs,
|
||||
QualType t)
|
||||
: BinarySymExpr(SymSymExprKind, op, t), LHS(lhs), RHS(rhs) {
|
||||
assert(lhs);
|
||||
assert(rhs);
|
||||
}
|
||||
|
||||
const SymExpr *getLHS() const { return LHS; }
|
||||
const SymExpr *getRHS() const { return RHS; }
|
||||
|
||||
void dumpToStream(raw_ostream &os) const override;
|
||||
|
||||
unsigned computeComplexity() const override {
|
||||
if (Complexity == 0)
|
||||
Complexity = RHS->computeComplexity() + LHS->computeComplexity();
|
||||
return Complexity;
|
||||
}
|
||||
|
||||
static void Profile(llvm::FoldingSetNodeID& ID, const SymExpr *lhs,
|
||||
BinaryOperator::Opcode op, const SymExpr *rhs, QualType t) {
|
||||
ID.AddInteger((unsigned) SymSymExprKind);
|
||||
ID.AddPointer(lhs);
|
||||
ID.AddInteger(op);
|
||||
ID.AddPointer(rhs);
|
||||
ID.Add(t);
|
||||
}
|
||||
|
||||
void Profile(llvm::FoldingSetNodeID& ID) override {
|
||||
Profile(ID, LHS, getOpcode(), RHS, getType());
|
||||
}
|
||||
|
||||
// Implement isa<T> support.
|
||||
static bool classof(const SymExpr *SE) {
|
||||
return SE->getKind() == SymSymExprKind;
|
||||
}
|
||||
};
|
||||
using SymSymExpr = BinarySymExprImpl<const SymExpr *, const SymExpr *,
|
||||
SymExpr::Kind::SymSymExprKind>;
|
||||
|
||||
class SymbolManager {
|
||||
using DataSetTy = llvm::FoldingSet<SymExpr>;
|
||||
|
|
|
@ -34,45 +34,27 @@ using namespace ento;
|
|||
|
||||
void SymExpr::anchor() {}
|
||||
|
||||
LLVM_DUMP_METHOD void SymExpr::dump() const {
|
||||
dumpToStream(llvm::errs());
|
||||
LLVM_DUMP_METHOD void SymExpr::dump() const { dumpToStream(llvm::errs()); }
|
||||
|
||||
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS, const SymExpr *Sym) {
|
||||
OS << '(';
|
||||
Sym->dumpToStream(OS);
|
||||
OS << ')';
|
||||
}
|
||||
|
||||
void SymIntExpr::dumpToStream(raw_ostream &os) const {
|
||||
os << '(';
|
||||
getLHS()->dumpToStream(os);
|
||||
os << ") "
|
||||
<< BinaryOperator::getOpcodeStr(getOpcode()) << ' ';
|
||||
if (getRHS().isUnsigned())
|
||||
os << getRHS().getZExtValue();
|
||||
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS,
|
||||
const llvm::APSInt &Value) {
|
||||
if (Value.isUnsigned())
|
||||
OS << Value.getZExtValue();
|
||||
else
|
||||
os << getRHS().getSExtValue();
|
||||
if (getRHS().isUnsigned())
|
||||
os << 'U';
|
||||
OS << Value.getSExtValue();
|
||||
if (Value.isUnsigned())
|
||||
OS << 'U';
|
||||
}
|
||||
|
||||
void IntSymExpr::dumpToStream(raw_ostream &os) const {
|
||||
if (getLHS().isUnsigned())
|
||||
os << getLHS().getZExtValue();
|
||||
else
|
||||
os << getLHS().getSExtValue();
|
||||
if (getLHS().isUnsigned())
|
||||
os << 'U';
|
||||
os << ' '
|
||||
<< BinaryOperator::getOpcodeStr(getOpcode())
|
||||
<< " (";
|
||||
getRHS()->dumpToStream(os);
|
||||
os << ')';
|
||||
}
|
||||
|
||||
void SymSymExpr::dumpToStream(raw_ostream &os) const {
|
||||
os << '(';
|
||||
getLHS()->dumpToStream(os);
|
||||
os << ") "
|
||||
<< BinaryOperator::getOpcodeStr(getOpcode())
|
||||
<< " (";
|
||||
getRHS()->dumpToStream(os);
|
||||
os << ')';
|
||||
void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS,
|
||||
BinaryOperator::Opcode Op) {
|
||||
OS << ' ' << BinaryOperator::getOpcodeStr(Op) << ' ';
|
||||
}
|
||||
|
||||
void SymbolCast::dumpToStream(raw_ostream &os) const {
|
||||
|
|
Loading…
Reference in New Issue