void PtrAnal:: ProcessMod(AstInterface& fa, const std::string& readname, std::list<std::string>& fields, const AstNodePtr& mod) { std::string modname; AstNodePtr p = mod; if (fa.IsVarRef(mod) || fa.IsArrayAccess(mod, &p)) { modname = Get_VarName(fa,p); Stmt stmt_last = fields.size()? field_x_eq_y(modname, fields, readname) : x_eq_y(modname, readname); stmts_pushback(stmts,stmt_last); namemap[mod.get_ptr()] = VarRef(stmt_last,modname); } else { AstInterface::OperatorEnum op; AstNodePtr p2; if (fa.IsUnaryOp(mod,&op, &p) && op == AstInterface::UOP_DEREF) { std::string lhs = Get_VarName(fa,p); Stmt stmt_last = deref_x_eq_y(lhs, fields, readname); stmts_pushback(stmts,stmt_last); namemap[p.get_ptr()] = VarRef(stmt_last,lhs); namemap[mod.get_ptr()] = VarRef(stmt_last, readname); } else if (fa.IsBinaryOp(mod,&op,&p,&p2)) { if (op==AstInterface::BOP_DOT_ACCESS) { std::string field = Local_GetFieldName(fa, p2); fields.push_front(field); ProcessMod(fa, readname, fields, p); Stmt stmt_last = stmts_back(stmts); namemap[mod.get_ptr()] = VarRef(stmt_last, readname); } else if (op==AstInterface::BOP_ARROW_ACCESS) { std::string lhs = Get_VarName(fa, p), field = Local_GetFieldName(fa, p2); fields.push_front(field); Stmt stmt_last = deref_x_eq_y(lhs,fields,readname); stmts_pushback(stmts,stmt_last); namemap[p.get_ptr()] = VarRef(stmt_last,lhs); namemap[mod.get_ptr()] = VarRef(stmt_last, readname); } else { std::cerr << "can't handle " << AstToString(mod) << "\n"; assert(false); // other operations? to be handled later } } else if (fa.IsFunctionCall(mod)) { std::string lhs = Get_VarName(fa, mod); Stmt stmt_last = deref_x_eq_y(lhs, fields, readname); stmts_pushback(stmts,stmt_last); namemap[mod.get_ptr()] = VarRef(stmt_last,lhs); } else { std::cerr << "cannot process " << AstToString(mod) << "\n"; assert(false); // other operations? to be handled later } } }
SymbolicVal SymbolicValGenerator :: GetSymbolicVal( AstInterface &fa, const AstNodePtr& exp) { std::string name; AstNodePtr scope; int val = 0; AstNodePtr s1, s2; AstInterface::AstNodeList l; AstInterface::OperatorEnum opr = (AstInterface::OperatorEnum)0; if (fa.IsVarRef(exp, 0, &name, &scope)) { return new SymbolicVar( name, scope ); } else if (fa.IsConstInt(exp, &val)) { return new SymbolicConst( val ); } else if (fa.IsBinaryOp(exp, &opr, &s1, &s2)) { SymbolicVal v1 = GetSymbolicVal( fa, s1 ), v2 = GetSymbolicVal(fa, s2); switch (opr) { case AstInterface::BOP_TIMES: return v1 * v2; case AstInterface::BOP_PLUS: return v1 + v2; case AstInterface::BOP_MINUS: return v1 - v2; case AstInterface::BOP_DOT_ACCESS: case AstInterface::BOP_ARROW_ACCESS: return new SymbolicAstWrap(exp); case AstInterface::BOP_DIVIDE: return new SymbolicFunction( opr, "/", v1,v2); case AstInterface::BOP_EQ: return new SymbolicFunction( opr, "==", v1,v2); case AstInterface::BOP_LE: return new SymbolicFunction( opr, "<=", v1,v2); case AstInterface::BOP_LT: return new SymbolicFunction( opr, "<", v1,v2); case AstInterface::BOP_NE: return new SymbolicFunction( opr, "!=", v1,v2); case AstInterface::BOP_GT: return new SymbolicFunction( opr, ">", v1,v2); case AstInterface::BOP_GE: return new SymbolicFunction( opr, ">=", v1,v2); case AstInterface::BOP_AND: return new SymbolicFunction( opr, "&&", v1,v2); case AstInterface::BOP_OR: return new SymbolicFunction( opr, "||", v1,v2); case AstInterface::BOP_BIT_RSHIFT: return new SymbolicFunction( opr, ">>", v1,v2); case AstInterface::BOP_BIT_LSHIFT: return new SymbolicFunction( opr, "<<", v1,v2); default: { cerr<<"Error in SymbolicValGenerator::GetSymbolicVal(): unhandled type of binary operator "<< AstInterface::toString(opr) <<endl; assert(false); } } } else if (fa.IsUnaryOp(exp, &opr, &s1)) { SymbolicVal v = GetSymbolicVal( fa, s1); switch (opr) { case AstInterface::UOP_MINUS: return (-1) * v; case AstInterface::UOP_ADDR: return new SymbolicFunction( opr, "&", v); case AstInterface::UOP_DEREF: return new SymbolicFunction( opr, "*", v); case AstInterface::UOP_ALLOCATE: return new SymbolicFunction( opr, "new", v); case AstInterface::UOP_NOT: return new SymbolicFunction( opr, "!", v); case AstInterface::UOP_CAST: return new SymbolicFunction( opr, "cast", v); case AstInterface::UOP_DECR1: return new SymbolicFunction( opr, "--", v); case AstInterface::UOP_INCR1: return new SymbolicFunction( opr, "++", v); default: std::cerr << "Cannot handle " << AstInterface::AstToString(exp) << ":" << opr << "\n"; assert(false); } } else if (fa.IsFunctionCall(exp, &s1, &l) || fa.IsArrayAccess(exp, &s1, &l)) { bool ismin = fa.IsMin(s1), ismax = fa.IsMax(s1); AstInterface::AstNodeList::const_iterator p = l.begin(); if (ismin || ismax) { AstNodePtr s = *p; SymbolicVal v = GetSymbolicVal( fa, s ); for ( ++p; p != l.end(); ++p ) { s = *p; v = (ismin)? Min(v, GetSymbolicVal(fa, s)) : Max(v, GetSymbolicVal(fa, s)); } return v; } if (fa.IsVarRef(s1, 0, &name)) { SymbolicFunction::Arguments args; for ( ; p != l.end(); ++p) { SymbolicVal cur = GetSymbolicVal(fa, *p); args.push_back( cur ); } return new SymbolicFunction( AstInterface::OP_NONE, name, args); } } return new SymbolicAstWrap(exp); }