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 "c_breeze.h"
00043 #include "dismantle.h"
00044 #include <sstream>
00045
00046 FlattenDismantle::FlattenDismantle(void):
00047 Changer(Both, Subtree, false),
00048 _new_body(NULL),
00049 _last_stmt(NULL),
00050 _vars()
00051 {}
00052
00053 Node * FlattenDismantle::at_proc(procNode * the_proc, Order ord) {
00054 if ( ord == Preorder ) {
00055 _new_body = new blockNode(NULL, NULL);
00056 _last_stmt = NULL;
00057 assert(the_proc->decl()->type()->typ() == Func);
00058 decl_list & args = ((funcNode *) the_proc->decl()->type())->args();
00059 for ( decl_list_p arg_decl = args.begin(); arg_decl != args.end();
00060 arg_decl++ ) {
00061 _vars.insert((*arg_decl)->name());
00062 }
00063 } else {
00064
00065 stmt_list_p next = _new_body->stmts().begin();
00066 stmtNode *prev = NULL;
00067 while ( next != _new_body->stmts().end() ) {
00068 stmt_list_p curr = next;
00069 next++;
00070 if ( next != _new_body->stmts().end()
00071 && (*curr)->typ() == Label
00072 && (*next)->typ() == Goto ) {
00073 labelNode * the_label = (labelNode *) *curr;
00074 labelNode * new_label = ((gotoNode *) *next)->label();
00075 goto_list_p next_goto = the_label->references().begin();
00076 while ( next_goto != the_label->references().end() ) {
00077 gotoNode * curr_goto = *next_goto;
00078 next_goto++;
00079 curr_goto->label(new_label);
00080 }
00081 _new_body->stmts().erase(curr);
00082 curr = next;
00083 next++;
00084 if(prev && prev->typ() != Goto) {
00085
00086 prev = *curr;
00087 } else {
00088 _new_body->stmts().erase(curr);
00089
00090 }
00091 } else
00092 prev = *curr;
00093 }
00094 the_proc->body(_new_body);
00095 }
00096 return the_proc;
00097 }
00098
00099 Node * FlattenDismantle::at_decl(declNode * the_decl, Order ord) {
00100 if ( ord == Preorder ) {
00101 if ( the_decl->decl_location() == declNode::BLOCK ) {
00102 int next_num = 0;
00103 string base_name(the_decl->name());
00104 bool changed_name = false;
00105
00106 while ( _vars.find(the_decl->name()) != _vars.end() ) {
00107 ostringstream ost;
00108 ost << base_name << next_num;
00109 the_decl->name(ost.str());
00110 next_num++;
00111 changed_name = true;
00112 }
00113 if ( changed_name ) {
00114
00115 for ( id_list_p p = the_decl->ref_list().begin();
00116 p != the_decl->ref_list().end();
00117 p++ ) {
00118 (*p)->name(the_decl->name());
00119 }
00120 }
00121 _vars.insert(the_decl->name());
00122 _new_body->decls().push_back(the_decl);
00123 }
00124 }
00125 return the_decl;
00126 }
00127
00128 Node * FlattenDismantle::at_label(labelNode * the_label, Order ord) {
00129
00130 if ( ord == Preorder
00131 && the_label->references().size() > 0 )
00132 if ( _last_stmt && _last_stmt->typ() == Label ) {
00133
00134
00135 goto_list_p next = the_label->references().begin();
00136 while ( next != the_label->references().end() ) {
00137 gotoNode * curr = *next;
00138 next++;
00139 curr->label((labelNode *) _last_stmt);
00140 }
00141 } else {
00142 int next_num = 0;
00143 string base_name(the_label->name());
00144 bool changed_name = false;
00145
00146 while ( _labels.find(the_label->name()) != _labels.end() ) {
00147 ostringstream ost;
00148 ost << base_name << next_num;
00149 the_label->name(ost.str());
00150 next_num++;
00151 changed_name = true;
00152 }
00153 if (changed_name ) {
00154
00155 for ( goto_list_p p = the_label->references().begin();
00156 p != the_label->references().end();
00157 p++ ) {
00158 (*p)->name(the_label->name());
00159 }
00160 }
00161
00162 _labels.insert(the_label->name());
00163 _new_body->stmts().push_back(the_label);
00164 _last_stmt = the_label;
00165 }
00166 return the_label;
00167 }
00168
00169 Node * FlattenDismantle::at_threeAddr(threeAddrNode * the_3addr,
00170 Order ord) {
00171 if ( ord == Preorder ) {
00172 _new_body->stmts().push_back(the_3addr);
00173 _last_stmt = the_3addr;
00174 }
00175 return the_3addr;
00176 }
00177
00178
00179 Node * FlattenDismantle::at_goto(gotoNode * the_goto, Order ord) {
00180 if ( ord == Preorder ) {
00181
00182 if ( ! (_last_stmt && _last_stmt->typ() == Goto) ) {
00183 _new_body->stmts().push_back(the_goto);
00184 _last_stmt = the_goto;
00185 }
00186 }
00187 return the_goto;
00188 }
00189
00190 Node * FlattenDismantle::at_return(returnNode * the_return,
00191 Order ord) {
00192 if ( ord == Preorder ) {
00193 _new_body->stmts().push_back(the_return);
00194 _last_stmt = the_return;
00195 }
00196 return the_return;
00197 }
00198
00199 Node * FlattenDismantle::at_exprstmt(exprstmtNode * the_exprstmt,
00200 Order ord) {
00201 if ( ord == Preorder ) {
00202 if ( the_exprstmt->expr() ) {
00203 _new_body->stmts().push_back(the_exprstmt);
00204 _last_stmt = the_exprstmt;
00205 }
00206 }
00207 return the_exprstmt;
00208 }