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 #include <sstream>
00042 #include "c_breeze.h"
00043 #include "dismantle.h"
00044 #include "ref_clone_changer.h"
00045
00046 StaticToGlobalDismantle::StaticToGlobalDismantle(void) :
00047 Changer(Both, Subtree, false),
00048 _cur_unit(0),
00049 _cur_proc(0),
00050 _declareProc(false)
00051 {}
00052
00053 class UpdateTdefChanger : public Changer {
00054 public:
00055 UpdateTdefChanger(const map<typeNode *, string> & newNames) :
00056 Changer(Preorder, Subtree, false),
00057 _newNames(newNames)
00058 {}
00059 Node * at_tdef(tdefNode * the_tdef, Order ord) {
00060 if ( _newNames.find(the_tdef->def()) != _newNames.end() )
00061 the_tdef->name(_newNames[the_tdef->def()]);
00062 return the_tdef;
00063 }
00064 private:
00065 map<typeNode *, string> _newNames;
00066 };
00067
00068 Node * StaticToGlobalDismantle::at_unit(unitNode * the_unit, Order ord) {
00069 if ( ord == Preorder ) {
00070 _cur_unit = the_unit;
00071 _topLevelSuespecs.clear();
00072 } else {
00073 UpdateTdefChanger utc(_newTypedefName);
00074 the_unit->change(utc);
00075 }
00076 return the_unit;
00077 }
00078
00079 void StaticToGlobalDismantle::rename_decl(declNode * to_rename,
00080 procNode * the_proc) {
00081 if ( to_rename->storage_class() != declNode::EXTERN ) {
00082 if ( !to_rename->name().empty() ) {
00083
00084 ostringstream ost;
00085 ost << DismantleUtil::new_id() << "_" << the_proc->decl()->name()
00086 << "_" << to_rename->name();
00087 to_rename->name(ost.str());
00088
00089
00090 for ( id_list_p id = to_rename->ref_list().begin();
00091 id != to_rename->ref_list().end();
00092 id++ )
00093 (*id)->name(to_rename->name());
00094
00095 if ( to_rename->storage_class() == declNode::TYPEDEF ) {
00096 _newTypedefName[to_rename->type()] = to_rename->name();
00097
00098 if ( sueNode * the_sue = dynamic_cast<sueNode *>(to_rename->type()) ) {
00099
00100
00101 suespecNode * the_suespec = the_sue->spec();
00102 if (_topLevelSuespecs.find(the_suespec) == _topLevelSuespecs.end()) {
00103 ostringstream sueost;
00104 sueost << DismantleUtil::new_id() << "_"
00105 << the_proc->decl()->name()
00106 << "_" << the_suespec->name();
00107 the_suespec->name(sueost.str());
00108 }
00109 }
00110 }
00111 } else {
00112
00113 sueNode * the_sue = dynamic_cast<sueNode *>(to_rename->type());
00114 assert(the_sue);
00115 suespecNode * the_suespec = the_sue->spec();
00116
00117 ostringstream ost;
00118 ost << DismantleUtil::new_id() << "_" << the_proc->decl()->name()
00119 << "_" << the_suespec->name();
00120 the_suespec->name(ost.str());
00121 }
00122 }
00123 }
00124
00125 Node * StaticToGlobalDismantle::at_proc(procNode * the_proc, Order ord) {
00126 if ( ord == Preorder ) {
00127 _cur_proc = the_proc;
00128 _declsToMove.clear();
00129 _declareProc = false;
00130 } else {
00131 assert(_blockStack.empty());
00132 def_list_p procIter = find(_cur_unit->defs().begin(),
00133 _cur_unit->defs().end(),
00134 the_proc);
00135 if ( _declareProc ) {
00136 declNode * proc_decl =
00137 (declNode *) ref_clone_changer::clone(the_proc->decl(), false);
00138 proc_decl->decl_location(declNode::TOP);
00139 _cur_unit->defs().insert(procIter, proc_decl);
00140 }
00141
00142 set<declNode *> moved;
00143 for ( map<declNode *, decl_list>::iterator p = _declsToMove.begin();
00144 p != _declsToMove.end();
00145 p++ ) {
00146 for ( decl_list_p q = p->second.begin(); q != p->second.end(); q++ ) {
00147 if ( moved.find(*q) == moved.end() ) {
00148 _cur_unit->defs().insert(procIter, *q);
00149 moved.insert(*q);
00150 (*q)->decl_location(declNode::TOP);
00151 rename_decl(*q, the_proc);
00152 }
00153 }
00154 _cur_unit->defs().insert(procIter, p->first);
00155 p->first->decl_location(declNode::TOP);
00156 rename_decl(p->first, the_proc);
00157 }
00158 }
00159 return the_proc;
00160 }
00161
00162 Node * StaticToGlobalDismantle::at_block(blockNode * the_block, Order ord) {
00163 if ( ord == Preorder ) {
00164 _blockStack.push_front(the_block);
00165 } else {
00166 assert(_blockStack.front() == the_block);
00167 _blockStack.pop_front();
00168 }
00169 return the_block;
00170 }
00171
00172 class RequiresGatherer : public Walker {
00173 public:
00174 RequiresGatherer(void) :
00175 Walker(Preorder, Subtree)
00176 {}
00177 virtual void at_id(idNode * the_id, Order ord) {
00178 _decls.push_back(the_id->decl());
00179 the_id->decl()->walk(*this);
00180 }
00181 virtual void at_tdef(tdefNode * the_tdef, Order ord) {
00182 _types.push_back(the_tdef->def());
00183 the_tdef->def()->walk(*this);
00184 }
00185 virtual void at_sue(sueNode * the_sue, Order ord) {
00186 _types.push_back(the_sue);
00187 }
00188 bool requires(declNode * the_decl) {
00189 bool isReqdDecl = ( find(_decls.begin(), _decls.end(), the_decl)
00190 != _decls.end() );
00191 bool isReqdTypedef = the_decl->storage_class() == declNode::TYPEDEF
00192 && ( find(_types.begin(), _types.end(), the_decl->type())
00193 != _types.end() );
00194 bool isAbstract = the_decl->name().empty();
00195 bool matchingSuespec = false;
00196 if ( sueNode * decl_sue = dynamic_cast<sueNode *>(the_decl->type()) ) {
00197 suespecNode * decl_spec = decl_sue->spec();
00198 for ( list<typeNode *>::iterator p = _types.begin();
00199 p != _types.end();
00200 p++ ) {
00201 if ( sueNode * the_sue = dynamic_cast<sueNode *>(*p) )
00202 if ( decl_spec == the_sue->spec() )
00203 matchingSuespec = true;
00204 }
00205 }
00206
00207 return ( isReqdDecl || isReqdTypedef || (isAbstract && matchingSuespec) );
00208 }
00209 private:
00210 decl_list _decls;
00211 list < typeNode * > _types;
00212 };
00213
00214 Node * StaticToGlobalDismantle::at_decl(declNode * the_decl, Order ord) {
00215 if ( ord == Preorder ) {
00216 if ( the_decl->decl_location() == declNode::TOP ) {
00217
00218
00219 if ( sueNode * the_sue = dynamic_cast<sueNode *>(the_decl->type()) ) {
00220 _topLevelSuespecs.insert(the_sue->spec());
00221 }
00222 } else if ( the_decl->storage_class() == declNode::STATIC
00223 && the_decl->decl_location() == declNode::BLOCK ) {
00224
00225 _declsToMove[the_decl].clear();
00226
00227 RequiresGatherer rg;
00228 the_decl->walk(rg);
00229
00230 _declareProc = _declareProc || rg.requires(_cur_proc->decl());
00231
00232 decl_list_p iter = _declsToMove[the_decl].end();
00233 block_list_p p = _blockStack.begin();
00234 while ( p != _blockStack.end() ) {
00235 blockNode * cur_block = *p;
00236 p++;
00237
00238
00239 decl_list_p q = cur_block->decls().begin();
00240 while ( q != cur_block->decls().end() ) {
00241 declNode * cur_decl = *q;
00242 q++;
00243
00244 if ( rg.requires(cur_decl) ) {
00245 cur_block->decls().remove(cur_decl);
00246 _declsToMove[the_decl].insert(iter, cur_decl);
00247 }
00248 }
00249 iter = _declsToMove[the_decl].begin();
00250 }
00251 return NULL;
00252 }
00253 }
00254 return the_decl;
00255 }