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 } } }
std::string PtrAnal:: Get_VarName(AstInterface& fa, const AstNodePtr& rhs) { NameMap::const_iterator p = namemap.find(rhs.get_ptr()); if (p != namemap.end()) { VarRef cur = (*p).second; return cur.name; } std::string readname, res; AstNodePtr readscope; AstNodePtr lhs1, rhs1; bool readlhs; if (fa.IsVarRef(rhs, 0, &readname, &readscope)) { assert(readname != ""); res = Local_GetVarName(fa, readscope, readname); } else if (fa.IsConstant(rhs,&res,&readname)) { if (res == "string") { readname = Local_GetVarName(fa, rhs); Stmt stmt = allocate_x(readname); stmts_pushback(stmts,stmt); res= readname; } else res = Local_GetConstName(fa, readname); } else if (fa.IsUnaryOp(rhs) || fa.IsBinaryOp(rhs) || fa.IsFunctionCall(rhs)) { readname = Local_GetVarName(fa, rhs); ProcessExpression(fa, readname, rhs); res = readname; } else if (fa.IsAssignment(rhs,&lhs1,&rhs1,&readlhs)) { ProcessAssign(fa, lhs1, rhs1, readlhs); VarRef cur = namemap[lhs1.get_ptr()]; if (cur.name == "") { std::cerr << "does not have map for " << AstToString(lhs1) << " in " << AstToString(rhs) << "\n"; assert(0); } namemap[rhs.get_ptr()] = cur; res = cur.name; } else { std::cerr << "No name found for " << AstToString(rhs) << "\n"; assert(false); } if (res == "") { std::cerr << "No name found for " << AstToString(rhs) << "\n"; assert(false); } return res; }
bool ArrayUseAccessFunction::get_modify(AstInterface& fa, const AstNodePtr& fc, CollectObject<AstNodePtr>* collect) { AstInterface::AstNodeList args; if (prev1 != 0 && prev1->get_modify(fa, fc, collect)) return true; std::string sig; AstNodePtr f; if (fa.IsFunctionCall(fc, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) { return true; } return false; }
bool ArrayUseAccessFunction::get_read(AstInterface& fa, const AstNodePtr& fc, CollectObject<AstNodePtr>* collect) { AstInterface::AstNodeList args; if (prev1 != 0 && prev1->get_read(fa, fc, collect)) return true; std::string sig; AstNodePtr f; if (fa.IsFunctionCall(fc, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) { if (collect != 0) { AstInterface::AstNodeList::const_iterator argp = args.begin(); for ( ++argp; argp != args.end(); ++argp) { (*collect)(*argp); } } return true; } return false; }
bool ArrayUseAccessFunction:: IsArrayAccess( AstInterface& fa, const AstNodePtr& s, AstNodePtr* array, AstInterface::AstNodeList* index) { AstInterface::AstNodeList args; if (prev != 0 && prev->IsArrayAccess(fa, s, array, index)) return true; std::string sig; AstNodePtr f; if (fa.IsFunctionCall(s, &f,&args) && fa.IsVarRef(f,0,&sig) && sig == funcname) { AstInterface::AstNodeList::const_iterator p = args.begin(); if (array != 0) *array = *p; if (index != 0) { for (++p; p != args.end(); ++p) { index->push_back(*p); } } return true; } return false; }
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: 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); default: 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 " << AstToString(exp) << ":" << opr << "\n"; assert(false); } } else if (fa.IsFunctionCall(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(exp, 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); }
void PtrAnal:: ProcessExpression( AstInterface& fa, const std::string& _modname, const AstNodePtr& rhs) { AstInterface::OperatorEnum op; std::string modname = _modname; AstNodePtr p,p1,p2; AstInterface::AstNodeList args, out; if (fa.IsFunctionCall(rhs, &p, &args, &out)) { typedef std::pair<AstNodePtr,std::string> RefRec; std::list<RefRec> refs; std::string fname = Get_VarName(fa,p); refs.push_back(RefRec(p,fname)); std::list<std::string> pargs, pres; for (AstInterface::AstNodeList::const_iterator p = args.begin(); p != args.end(); ++p) { AstNodePtr cur = *p; std::string curname = Get_VarName(fa, cur); pargs.push_back(curname); refs.push_back(RefRec(cur,curname)); } pres.push_back(modname); for (AstInterface::AstNodeList::const_iterator p2 = out.begin(); p2 != out.end(); ++p2) { AstNodePtr cur = *p2; std::string curname = Get_VarName(fa, cur); pres.push_back(curname); refs.push_back(RefRec(cur,curname)); } Stmt stmt = funccall_x(fname, pargs, pres); stmts_pushback(stmts,stmt); for (std::list<RefRec>::const_iterator p3 = refs.begin(); p3 != refs.end(); ++p3) { RefRec cur = *p3; namemap[cur.first.get_ptr()] = PtrAnal::VarRef(stmt,cur.second); } } else if (fa.IsUnaryOp(rhs,&op, &p) ) { std::string readname; if (modname == "") { modname = Local_GetVarName(fa, rhs); } switch (op) { case AstInterface::UOP_ADDR: { readname= Get_VarName(fa, p); Stmt stmt = x_eq_addr_y(modname, readname); stmts_pushback(stmts,stmt); namemap[p.get_ptr()] = VarRef(stmt,readname); namemap[rhs.get_ptr()] = VarRef(stmt,modname); break; } case AstInterface::UOP_DEREF: { readname= Get_VarName(fa, p); Stmt stmt = x_eq_deref_y(modname, "", readname); stmts_pushback(stmts,stmt); namemap[p.get_ptr()] = VarRef(stmt,readname); namemap[rhs.get_ptr()] = VarRef(stmt,modname); break; } case AstInterface::UOP_ALLOCATE: { Stmt stmt = allocate_x(modname) ; stmts_pushback(stmts,stmt); break; } default: { readname = Get_VarName(fa,p); std::list<std::string> opds; opds.push_back(readname); Stmt stmt_last = x_eq_op_y(OTHER,modname, opds); stmts_pushback(stmts,stmt_last); namemap[p.get_ptr()] = VarRef(stmt_last,readname); namemap[rhs.get_ptr()] = VarRef(stmt_last,modname); break; } } } else if (fa.IsBinaryOp(rhs, &op, &p1, &p2)) { std::list<std::string> opds; std::string readname , refname; if (modname == "") { modname = Local_GetVarName(fa, rhs); } Stmt stmt_last=0; switch (op) { case AstInterface::BOP_DOT_ACCESS: { readname = Get_VarName(fa, p1); refname = Local_GetFieldName(fa, p2); stmt_last = x_eq_field_y( modname, refname, readname); stmts_pushback(stmts,stmt_last); break; } case AstInterface::BOP_ARROW_ACCESS: { readname = Get_VarName(fa, p1); refname = Local_GetFieldName(fa, p2); stmt_last = x_eq_deref_y(modname, refname, readname); stmts_pushback(stmts,stmt_last); break; } default: { readname = Get_VarName(fa,p1); refname = Get_VarName(fa,p2); opds.push_back(readname); opds.push_back(refname); OpType opt = OTHER; switch (op) { case AstInterface::BOP_EQ: opt = EQ; break; case AstInterface::BOP_LT: opt = LT; break; case AstInterface::BOP_GT: opt = GT; break; case AstInterface::BOP_LE: opt = LE; break; case AstInterface::BOP_GE: opt = GE; break; case AstInterface::BOP_NE: opt = NE; break; default: break; } stmt_last = x_eq_op_y( opt, modname, opds); stmts_pushback(stmts,stmt_last); } } namemap[p1.get_ptr()] = VarRef(stmt_last,readname); namemap[p2.get_ptr()] = VarRef(stmt_last,refname); namemap[rhs.get_ptr()] = VarRef(stmt_last,modname); } else { std::string cur = Get_VarName(fa, rhs); assert (cur != ""); if (modname != "") { Stmt stmt_last = x_eq_y(modname, cur); stmts_pushback(stmts,stmt_last); namemap[rhs.get_ptr()] = VarRef(stmt_last,cur); } } }