00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <assert.h>
00043 #include "c_breeze.h"
00044 #include "dismantle.h"
00045 #include "ref_clone_changer.h"
00046
00047 ArrowDismantle::ArrowDismantle(void):
00048 Changer(Postorder, Subtree, false)
00049 {}
00050
00051 Node * ArrowDismantle::at_binary(binaryNode * the_binary, Order ord) {
00052 Operator * op = the_binary->op();
00053 if ( op->id() == Operator::ARROW ) {
00054
00055 unaryNode * deref = new unaryNode(Operator::INDIR,
00056 the_binary->left(),
00057 the_binary->left()->coord());
00058 binaryNode * dot = new binaryNode('.', deref, the_binary->right(),
00059 the_binary->right()->coord());
00060 dot->type((typeNode*) ref_clone_changer::clone(the_binary->type(),
00061 false));
00062 return dot;
00063 }
00064 return the_binary;
00065 }
00066
00067 map<unsigned int, unsigned int> ExpressionDismantle::_op_assign_map;
00068 set<unsigned int> ExpressionDismantle::_op_post;
00069
00070 void ExpressionDismantle::init() {
00071 if ( _op_assign_map.empty() ) {
00072 _op_assign_map[Operator::PLUSassign] = '+';
00073 _op_assign_map[Operator::MINUSassign] = '-';
00074 _op_assign_map[Operator::MULTassign] = '*';
00075 _op_assign_map[Operator::DIVassign] = '/';
00076 _op_assign_map[Operator::MODassign] = '%';
00077 _op_assign_map[Operator::ANDassign] = '&';
00078 _op_assign_map[Operator::ORassign] = '|';
00079 _op_assign_map[Operator::LSassign] = Operator::LS;
00080 _op_assign_map[Operator::RSassign] = Operator::RS;
00081 _op_assign_map[Operator::ERassign] = '^';
00082 _op_assign_map[Operator::PREINC] = Operator::PLUSassign;
00083 _op_assign_map[Operator::POSTINC] = Operator::PLUSassign;
00084 _op_assign_map[Operator::PREDEC] = Operator::MINUSassign;
00085 _op_assign_map[Operator::POSTDEC] = Operator::MINUSassign;
00086 }
00087
00088 if( _op_post.empty() ) {
00089 _op_post.insert(Operator::POSTINC);
00090 _op_post.insert(Operator::POSTDEC);
00091 }
00092 }
00093
00094 ExpressionDismantle::ExpressionDismantle(void):
00095 Changer(Both, Subtree, false),
00096 _new_block(NULL),
00097 _in_type(0)
00098 {}
00099
00100 Node * ExpressionDismantle::at_exprstmt(exprstmtNode * the_exprstmt,
00101 Order ord) {
00102 if ( ord == Preorder ) {
00103
00104 if ( the_exprstmt->expr() ) {
00105 ArrowDismantle ad;
00106 the_exprstmt = (exprstmtNode *) the_exprstmt->change(ad);
00107 _new_block = new blockNode(NULL, NULL, the_exprstmt->coord());
00108 }
00109 } else {
00110
00111
00112 if ( _new_block ) {
00113 blockNode * ret = _new_block;
00114 _new_block = NULL;
00115
00116
00117 ExpressionDismantle ed;
00118 return ret->change(ed);
00119 }
00120 }
00121 return the_exprstmt;
00122 }
00123
00124 Node * ExpressionDismantle::at_type(typeNode * the_type, Order ord) {
00125
00126
00127 if ( ord == Preorder )
00128 _in_type++;
00129 else
00130 _in_type--;
00131 return the_type;
00132 }
00133
00134
00135 Node * ExpressionDismantle::at_binary(binaryNode * the_binary,
00136 Order ord) {
00137 if ( !_new_block || _in_type )
00138 return the_binary;
00139
00140 if ( ord == Postorder ) {
00141 Operator * op = the_binary->op();
00142 exprNode * left = the_binary->left();
00143 exprNode * right = the_binary->right();
00144 exprNode * ret = the_binary;
00145
00146 switch ( op->id() ) {
00147 case '=':
00148 {
00149 if ( left->typ() == Id ) {
00150
00151 left = new operandNode((idNode *) ref_clone_changer::clone(left,
00152 false),
00153 left->coord());
00154 }
00155
00156 if ( right->typ() != Operand ) {
00157 assert(right->typ() == Id || right->typ() == Const);
00158 right = new operandNode((indexNode *) right, right->coord());
00159 }
00160 assert(left->typ() == Operand && right->typ() == Operand);
00161 threeAddrNode * new_stmt = new threeAddrNode((operandNode *) left,
00162 (operandNode *) right,
00163 the_binary->coord());
00164 _new_block->stmts().push_back(new_stmt);
00165
00166
00167 ret = (operandNode *) ref_clone_changer::clone(left, false);
00168 }
00169 break;
00170 case Operator::PLUSassign: case Operator::MINUSassign:
00171 case Operator::MULTassign: case Operator::DIVassign:
00172 case Operator::MODassign: case Operator::ANDassign:
00173 case Operator::ORassign: case Operator::LSassign:
00174 case Operator::RSassign: case Operator::ERassign:
00175 {
00176
00177
00178
00179
00180
00181 exprNode * new_rhs =
00182 new binaryNode(_op_assign_map[op->id()],
00183 (exprNode*) ref_clone_changer::clone(left,
00184 false),
00185 right);
00186 new_rhs->type((typeNode *) ref_clone_changer::clone(the_binary->type(),
00187 false));
00188 the_binary->right(new_rhs);
00189 the_binary->op(Operators::table['=']);
00190 _new_block->stmts().push_back(new exprstmtNode(the_binary));
00191 ret = (exprNode *) ref_clone_changer::clone(left, false);
00192 }
00193 break;
00194 case '.':
00195 {
00196 if ( left->typ() == Id ) {
00197
00198 left = new operandNode((idNode *) left, left->coord());
00199 } else {
00200 assert(left->typ() == Operand);
00201 operandNode * left_oper = (operandNode *) left;
00202 if(left_oper->addr()) {
00203 cout << "Error: does not make sense to access field in \"(";
00204 output_context oc(cout);
00205 left_oper->output(oc,NULL);
00206 cout << ").";
00207 right->output(oc,NULL);
00208 cout << "\" at " << the_binary->coord() << "\n";
00209 exit(1);
00210 }
00211 if ( left_oper->index() ) {
00212
00213
00214
00215
00216
00217
00218
00219 typeNode * left_type =
00220 new ptrNode(typeNode::NONE, left_oper->type());
00221 declNode * tmp_arry_decl =
00222 DismantleUtil::new_temp_decl(left_type,
00223 the_binary->coord());
00224 _new_block->decls().push_back(tmp_arry_decl);
00225 left_oper->addr(true);
00226 threeAddrNode * assign_tmp_array =
00227 new threeAddrNode(new operandNode(new idNode(tmp_arry_decl),
00228 left_oper->coord()),
00229 left_oper,
00230 left_oper->coord());
00231 _new_block->stmts().push_back(assign_tmp_array);
00232 left = new operandNode(new idNode(tmp_arry_decl), true, false,
00233 left_oper->coord());
00234 }
00235 }
00236 assert(left->typ() == Operand && right->typ() == Id);
00237 ((operandNode *) left)->fields().push_back((idNode *) right);
00238
00239
00240 ret = left;
00241 }
00242 break;
00243 case Operator::Index:
00244 {
00245 if ( left->typ() == Id ) {
00246
00247 left = new operandNode((idNode *) left, left->coord());
00248 } else if ( left->typ() == Const ) {
00249
00250 left = new operandNode((constNode *) left, left->coord());
00251 } else if ( left->typ() == Operand ) {
00252
00253 operandNode * left_oper = (operandNode *) left;
00254 if(left_oper->addr()) {
00255
00256 typeNode * left_type = left_oper->type();
00257 declNode * tmp_addr_decl =
00258 DismantleUtil::new_temp_decl(left_type, the_binary->coord());
00259 _new_block->decls().push_back(tmp_addr_decl);
00260 threeAddrNode * assign_tmp_addr =
00261 new threeAddrNode(new operandNode(new idNode(tmp_addr_decl),
00262 left->coord()),
00263 (operandNode *) left,
00264 left->coord());
00265 _new_block->stmts().push_back(assign_tmp_addr);
00266 left_oper=new operandNode(new idNode(tmp_addr_decl), left->coord());
00267 left = left_oper;
00268 }
00269 if ( left_oper->index() ) {
00270 typeNode * left_type = left_oper->type();
00271 declNode * tmp_arry_decl =
00272 DismantleUtil::new_temp_decl(left_type,
00273 the_binary->coord());
00274 _new_block->decls().push_back(tmp_arry_decl);
00275 threeAddrNode * assign_tmp_array =
00276 new threeAddrNode(new operandNode(new idNode(tmp_arry_decl),
00277 left->coord()),
00278 (operandNode *) left,
00279 left->coord());
00280 _new_block->stmts().push_back(assign_tmp_array);
00281 left = new operandNode(new idNode(tmp_arry_decl),
00282 left->coord());
00283 }
00284 }
00285 if ( right->typ() == Operand ) {
00286
00287 declNode * index_decl =
00288 DismantleUtil::new_temp_decl(right->type(),
00289 the_binary->coord());
00290 _new_block->decls().push_back(index_decl);
00291 threeAddrNode * assign_index =
00292 new threeAddrNode(new operandNode(new idNode(index_decl),
00293 right->coord()),
00294 (operandNode *) right);
00295 _new_block->stmts().push_back(assign_index);
00296 right = new idNode(index_decl);
00297 }
00298
00299 assert(left->typ() == Operand && ( right->typ() == Id
00300 || right->typ() == Const ) );
00301 ((operandNode *) left)->index((indexNode *)right);
00302
00303
00304 ret = left;
00305 }
00306 break;
00307 case '*': case '/': case '%': case '+': case '-': case Operator::LS:
00308 case Operator::RS: case '&': case '|': case '^': case Operator::LE:
00309 case Operator::GE: case Operator::EQ: case Operator::NE: case '<':
00310 case '>':
00311 {
00312 if ( left->typ() != Operand ) {
00313 assert(left->typ() == Id || left->typ() == Const);
00314 left = new operandNode((indexNode *) left, left->coord());
00315 }
00316 if ( right->typ() != Operand ) {
00317 assert(right->typ() == Id || right->typ() == Const);
00318 right = new operandNode((indexNode *) right, right->coord()) ;
00319 }
00320 assert(left->typ() == Operand && right->typ() == Operand);
00321 declNode * temp_decl =
00322 DismantleUtil::new_temp_decl(the_binary->type(),
00323 the_binary->coord());
00324 _new_block->decls().push_back(temp_decl);
00325 threeAddrNode * assign_temp =
00326 new threeAddrNode(new operandNode(new idNode(temp_decl),
00327 the_binary->coord()),
00328 (operandNode *) left,
00329 op->id(),
00330 (operandNode *) right);
00331 _new_block->stmts().push_back(assign_temp);
00332 ret = new idNode(temp_decl);
00333 }
00334 break;
00335 default:
00336 cout << "Unknown binary op to dismantle: " << op->id() << endl;
00337 break;
00338 }
00339 return ret;
00340 }
00341 return the_binary;
00342 }
00343
00344
00345 Node * ExpressionDismantle::at_unary(unaryNode * the_unary,
00346 Order ord) {
00347 if ( !_new_block || _in_type )
00348 return the_unary;
00349
00350 Operator * op = the_unary->op();
00351 exprNode * expr = the_unary->expr();
00352 exprNode * ret = the_unary;
00353
00354 if ( ord == Preorder ) {
00355 switch ( op->id() ) {
00356 case Operator::SIZEOF:
00357 {
00358 if ( expr ) {
00359 the_unary->sizeof_type(the_unary->expr()->type());
00360 the_unary->expr(NULL);
00361 return the_unary;
00362 }
00363 }
00364 break;
00365 }
00366 }
00367
00368 if ( ord == Postorder ) {
00369 switch ( op->id() ) {
00370 case Operator::SIZEOF:
00371 {
00372 assert(the_unary->expr() == NULL && the_unary->sizeof_type() != NULL);
00373 declNode * unary_temp_decl =
00374 DismantleUtil::new_temp_decl(the_unary->type(),
00375 the_unary->coord());
00376 _new_block->decls().push_back(unary_temp_decl);
00377 threeAddrNode * assign_unary_temp =
00378 new threeAddrNode(new operandNode(new idNode(unary_temp_decl),
00379 the_unary->coord()),
00380 the_unary->sizeof_type(),
00381 the_unary->coord());
00382 _new_block->stmts().push_back(assign_unary_temp);
00383 return new idNode(unary_temp_decl);
00384 }
00385 break;
00386 case Operator::UMINUS: case Operator::UPLUS: case '!': case '~':
00387 {
00388 if ( expr->typ() == Operand ) {
00389 operandNode * expr_oper = (operandNode *) expr;
00390 declNode * temp_decl =
00391 DismantleUtil::new_temp_decl(expr->type(),
00392 expr->coord());
00393 _new_block->decls().push_back(temp_decl);
00394 threeAddrNode * assign_temp =
00395 new threeAddrNode(new operandNode(new idNode(temp_decl),
00396 expr_oper->coord()),
00397 expr_oper);
00398 _new_block->stmts().push_back(assign_temp);
00399 expr = new idNode(temp_decl, expr->coord());
00400 }
00401 assert(expr->typ() == Id || expr->typ() == Const);
00402 typeNode * unary_type = the_unary->type();
00403 declNode * unary_temp_decl =
00404 DismantleUtil::new_temp_decl(unary_type,
00405 expr->coord());
00406 _new_block->decls().push_back(unary_temp_decl);
00407 threeAddrNode * assign_unary_temp =
00408 new threeAddrNode(new operandNode(new idNode(unary_temp_decl),
00409 expr->coord()),
00410 op->id(),
00411 new operandNode((indexNode *) expr,
00412 expr->coord()));
00413 _new_block->stmts().push_back(assign_unary_temp);
00414 ret = new idNode(unary_temp_decl);
00415 }
00416 break;
00417 case Operator::ADDRESS:
00418 {
00419 if ( expr->typ() == Operand ) {
00420 operandNode * expr_oper = (operandNode *) expr;
00421 expr_oper->addr(true);
00422 ret = expr_oper;
00423 } else {
00424 assert(expr->typ() == Id);
00425 expr = new operandNode((indexNode*) expr, false, true);
00426 }
00427 ret = expr;
00428 }
00429 break;
00430 case Operator::INDIR:
00431 {
00432 if ( expr->typ() == Operand ) {
00433 operandNode * expr_oper = (operandNode *) expr;
00434 if ( expr_oper->star() ||
00435 ! expr_oper->fields().empty() ||
00436 expr_oper->index()) {
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 declNode * temp_decl =
00459 DismantleUtil::new_temp_decl(expr->type(),
00460 expr->coord());
00461 _new_block->decls().push_back(temp_decl);
00462 threeAddrNode * assign_temp =
00463 new threeAddrNode(new operandNode(new idNode(temp_decl),
00464 expr_oper->coord()),
00465 expr_oper);
00466 _new_block->stmts().push_back(assign_temp);
00467 expr = new operandNode(new idNode(temp_decl), true, false);
00468 } else if(expr_oper->addr())
00469 expr_oper->addr(false);
00470 else
00471 expr_oper->star(true);
00472 } else {
00473 assert(expr->typ() == Id || expr->typ() == Const);
00474 expr = new operandNode((indexNode *) expr, true, false);
00475 }
00476 ret = expr;
00477 }
00478 break;
00479 case Operator::PREINC: case Operator::POSTINC:
00480 case Operator::PREDEC: case Operator::POSTDEC:
00481 {
00482
00483
00484
00485
00486 bool post_op = false;
00487 if ( _op_post.find(the_unary->op()->id()) !=
00488 _op_post.end() ) {
00489 declNode * temp_decl =
00490 DismantleUtil::new_temp_decl(the_unary->type(),
00491 the_unary->coord());
00492
00493 exprNode * clone_expr = (exprNode *) ref_clone_changer::clone(expr,
00494 false);
00495 exprstmtNode * assign_temp =
00496 new exprstmtNode(new binaryNode('=',
00497 new idNode(temp_decl,
00498 the_unary->coord()),
00499 clone_expr,
00500 the_unary->coord()));
00501 assign_temp->expr()->type((typeNode *)
00502 ref_clone_changer::clone(the_unary->type(),
00503 false));
00504 _new_block->decls().push_back(temp_decl);
00505 _new_block->stmts().push_back(assign_temp);
00506 ret = new idNode(temp_decl, the_unary->coord());
00507 post_op = true;
00508 }
00509
00510 constNode * one = new constNode(constant::constant(1));
00511 exprstmtNode * update =
00512 new exprstmtNode(new binaryNode(_op_assign_map[op->id()],
00513 expr,
00514 one,
00515 the_unary->coord()));
00516 update->expr()->type(the_unary->type());
00517 _new_block->stmts().push_back(update);
00518 if ( !post_op )
00519 ret = (exprNode *) ref_clone_changer::clone(expr, false);
00520 }
00521 break;
00522 default:
00523 cout << "Unknown unary op to dismantle: " << op->id() << endl;
00524 break;
00525 }
00526 return ret;
00527 }
00528 return the_unary;
00529 }
00530
00531 Node * ExpressionDismantle::at_call(callNode * the_call, Order ord) {
00532 if ( !_new_block || _in_type )
00533 return the_call;
00534
00535 if ( ord == Postorder ) {
00536 operand_list * args = new operand_list;
00537 for ( expr_list_p p = the_call->args().begin();
00538 p != the_call->args().end();
00539 p++ ) {
00540 operandNode * arg;
00541 if ( (*p)->typ() != Operand ) {
00542 assert((*p)->typ() == Id || (*p)->typ() == Const);
00543 arg = new operandNode((indexNode *) *p, (*p)->coord());
00544 } else
00545 arg = (operandNode *) *p;
00546 args->push_back(arg);
00547 }
00548
00549 exprNode * call_expr = the_call->name();
00550 if ( call_expr->typ() == Id ) {
00551 call_expr = new operandNode((idNode *) call_expr, call_expr->coord());
00552 }
00553 assert(call_expr->typ() == Operand);
00554 operandNode * call_oper = (operandNode *) call_expr;
00555
00556
00557 if ( the_call->type() &&
00558 the_call->type()->is_void() ) {
00559 threeAddrNode * call =
00560 new threeAddrNode(call_oper, args, the_call->coord());
00561 _new_block->stmts().push_back(call);
00562 return call;
00563 } else {
00564 declNode * return_decl =
00565 DismantleUtil::new_temp_decl(the_call->type(),
00566 the_call->coord());
00567 _new_block->decls().push_back(return_decl);
00568 threeAddrNode * assign_return =
00569 new threeAddrNode(new operandNode(new idNode(return_decl)), call_oper,
00570 args, the_call->coord());
00571 _new_block->stmts().push_back(assign_return);
00572 return new idNode(return_decl, the_call->coord());
00573 }
00574 }
00575 return the_call;
00576 }
00577
00578 Node * ExpressionDismantle::at_comma(commaNode * the_comma,
00579 Order ord) {
00580 if ( ord == Postorder ) {
00581 exprNode * last_expr = *(the_comma->exprs().rbegin());
00582 if ( last_expr->typ() == Id || last_expr->typ() == Const ) {
00583 last_expr = new operandNode((indexNode *) last_expr);
00584 }
00585 assert(last_expr->typ() == Operand);
00586 return last_expr;
00587 }
00588 return the_comma;
00589 }
00590
00591 Node * ExpressionDismantle::at_cast(castNode * the_cast, Order ord) {
00592 if ( !_new_block || _in_type )
00593 return the_cast;
00594
00595
00596 if ( ord == Postorder ) {
00597 exprNode * expr = the_cast->expr();
00598 if ( expr->typ() == ThreeAddr ) {
00599 assert( the_cast->type()->is_void() );
00600 return expr;
00601 } else if ( expr->typ() != Operand ) {
00602 assert(expr->typ() == Id || expr->typ() == Const);
00603 expr = new operandNode((indexNode *) expr);
00604 }
00605 assert(expr->typ() == Operand);
00606 ((operandNode *) expr)->cast(the_cast->type());
00607 return expr;
00608 }
00609 return the_cast;
00610 }
00611
00612
00613
00614
00615
00616