diff --git a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h --- a/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h +++ b/clang/include/clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h @@ -326,136 +326,83 @@ Kind k = SE->getKind(); return k >= BEGIN_BINARYSYMEXPRS && k <= END_BINARYSYMEXPRS; } -}; - -/// 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); +protected: + static unsigned computeOperandComplexity(const SymExpr *Value) { + return Value->computeComplexity(); } - - 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 unsigned computeOperandComplexity(const llvm::APSInt &Value) { + return 1; } - 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); + static const llvm::APSInt *getPointer(const llvm::APSInt &Value) { + return &Value; } + static const SymExpr *getPointer(const SymExpr *Value) { return Value; } - void Profile(llvm::FoldingSetNodeID& ID) override { - Profile(ID, LHS, getOpcode(), RHS, getType()); - } - - // Implement isa support. - static bool classof(const SymExpr *SE) { - return SE->getKind() == SymIntExprKind; - } + 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); }; -/// Represents a symbolic expression like 3 - 'x'. -class IntSymExpr : public BinarySymExpr { - const llvm::APSInt& LHS; - const SymExpr *RHS; +/// Template implementation for all binary symbolic expressions +template +class BinarySymExprImpl : public BinarySymExpr { + LHSTYPE LHS; + RHSTYPE 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); + 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; + void dumpToStream(raw_ostream &os) const override { + dumpToStreamImpl(os, LHS); + dumpToStreamImpl(os, getOpcode()); + dumpToStreamImpl(os, RHS); + } - const SymExpr *getRHS() const { return RHS; } - const llvm::APSInt &getLHS() const { return LHS; } + LHSTYPE getLHS() const { return LHS; } + RHSTYPE getRHS() const { return RHS; } unsigned computeComplexity() const override { if (Complexity == 0) - Complexity = 1 + RHS->computeComplexity(); + Complexity = + computeOperandComplexity(RHS) + computeOperandComplexity(LHS); 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); + 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(rhs); + ID.AddPointer(getPointer(rhs)); ID.Add(t); } - void Profile(llvm::FoldingSetNodeID& ID) override { + void Profile(llvm::FoldingSetNodeID &ID) override { Profile(ID, LHS, getOpcode(), RHS, getType()); } // Implement isa support. - static bool classof(const SymExpr *SE) { - return SE->getKind() == IntSymExprKind; - } + static bool classof(const SymExpr *SE) { return SE->getKind() == ClassKind; } }; -/// 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); - } +/// Represents a symbolic expression like 'x' + 3. +using SymIntExpr = BinarySymExprImpl; - void Profile(llvm::FoldingSetNodeID& ID) override { - Profile(ID, LHS, getOpcode(), RHS, getType()); - } +/// Represents a symbolic expression like 3 - 'x'. +using IntSymExpr = BinarySymExprImpl; - // Implement isa support. - static bool classof(const SymExpr *SE) { - return SE->getKind() == SymSymExprKind; - } -}; +/// Represents a symbolic expression like 'x' + 'y'. +using SymSymExpr = BinarySymExprImpl; class SymbolManager { using DataSetTy = llvm::FoldingSet; diff --git a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp --- a/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp +++ b/clang/lib/StaticAnalyzer/Core/SymbolManager.cpp @@ -34,45 +34,27 @@ void SymExpr::anchor() {} -LLVM_DUMP_METHOD void SymExpr::dump() const { - dumpToStream(llvm::errs()); -} +LLVM_DUMP_METHOD void SymExpr::dump() const { dumpToStream(llvm::errs()); } -void SymIntExpr::dumpToStream(raw_ostream &os) const { - os << '('; - getLHS()->dumpToStream(os); - os << ") " - << BinaryOperator::getOpcodeStr(getOpcode()) << ' '; - if (getRHS().isUnsigned()) - os << getRHS().getZExtValue(); - else - os << getRHS().getSExtValue(); - if (getRHS().isUnsigned()) - os << 'U'; +void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS, const SymExpr *Sym) { + OS << '('; + Sym->dumpToStream(OS); + OS << ')'; } -void IntSymExpr::dumpToStream(raw_ostream &os) const { - if (getLHS().isUnsigned()) - os << getLHS().getZExtValue(); +void BinarySymExpr::dumpToStreamImpl(raw_ostream &OS, + const llvm::APSInt &Value) { + if (Value.isUnsigned()) + OS << Value.getZExtValue(); else - os << getLHS().getSExtValue(); - if (getLHS().isUnsigned()) - os << 'U'; - os << ' ' - << BinaryOperator::getOpcodeStr(getOpcode()) - << " ("; - getRHS()->dumpToStream(os); - os << ')'; + OS << Value.getSExtValue(); + if (Value.isUnsigned()) + OS << 'U'; } -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 {