xmlprogparser.cpp

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, Trent Waddington
00003  */
00004 /*==============================================================================
00005  * FILE:       xmlprogparser.cpp
00006  * OVERVIEW:   Implementation of the XMLProgParser and related classes.
00007  *============================================================================*/
00008 /*
00009  * $Revision: 1.31 $    // 1.17.2.8
00010  *
00011  * June 2004 - Trent: created
00012  * NOTE: As of early 2006, this file has likely fallen behind changes to class members, and so probably needs some major
00013  *  work - MVE
00014  */
00015 
00016 #include <stdio.h>
00017 extern "C" {
00018 #include "expat.h"
00019 }
00020 #include "type.h"
00021 #include "cluster.h"
00022 #include "prog.h"
00023 #include "proc.h"
00024 #include "rtl.h"
00025 #include "statement.h"
00026 #include "sigenum.h"
00027 #include "signature.h"
00028 #include "xmlprogparser.h"
00029 #include "boomerang.h"
00030 #include "log.h"
00031 #include "frontend.h"
00032 #if defined(_MSC_VER) && _MSC_VER >= 1400
00033 #pragma warning(disable:4996)       // Warnings about e.g. _strdup deprecated in VS 2005
00034 #endif
00035 
00036 
00037 typedef enum { e_prog, e_procs, e_global, e_cluster, e_libproc, e_userproc, e_local, e_symbol, e_secondexp,
00038            e_proven_true, e_callee, e_caller, e_defines,
00039                e_signature, e_param, e_return, e_rettype, e_prefreturn, e_prefparam,
00040            e_cfg, e_bb, e_inedge, e_outedge, e_livein, e_order, e_revorder,
00041            e_rtl, e_stmt, e_assign, e_assignment, e_phiassign, e_lhs, e_rhs, 
00042            e_callstmt, e_dest, e_argument, e_returnexp, e_returntype,
00043            e_returnstmt, e_returns, e_modifieds,
00044            e_gotostmt, e_branchstmt, e_cond,
00045            e_casestmt,
00046            e_boolasgn,
00047            e_type, e_exp, 
00048            e_voidtype, e_integertype, e_pointertype, e_chartype, e_namedtype, e_arraytype, e_basetype, e_sizetype,
00049            e_location, e_unary, e_binary, e_ternary, e_const, e_terminal, e_typedexp, e_refexp, e_def,
00050            e_subexp1, e_subexp2, e_subexp3, e_unknown = -1 } xmlElement;
00051 
00052 #define TAG(x) &XMLProgParser::start_ ## x, &XMLProgParser::addToContext_ ## x
00053 
00054 _tag XMLProgParser::tags[] = { 
00055     { "prog", TAG(prog) },
00056     { "procs", TAG(procs) },
00057     { "global", TAG(global) },
00058     { "cluster", TAG(cluster) },
00059     { "libproc", TAG(libproc) },
00060     { "userproc", TAG(userproc) },
00061     { "local", TAG(local) },
00062     { "symbol", TAG(symbol) },
00063     { "secondexp", TAG(secondexp) },
00064     { "proven_true", TAG(proven_true) },
00065     { "callee", TAG(callee) },
00066     { "caller", TAG(caller) },
00067     { "defines", TAG(defines) },
00068     { "signature", TAG(signature) },
00069     { "param",  TAG(param) },
00070     { "return", TAG(return) },
00071     { "rettype", TAG(rettype) },
00072     { "prefreturn", TAG(prefreturn) },
00073     { "prefparam", TAG(prefparam) },
00074     { "cfg", TAG(cfg) },
00075     { "bb", TAG(bb) },
00076     { "inedge", TAG(inedge) },
00077     { "outedge", TAG(outedge) },
00078     { "livein", TAG(livein) },
00079     { "order", TAG(order) },
00080     { "revorder", TAG(revorder) },
00081     { "rtl", TAG(rtl) },
00082     { "stmt", TAG(stmt) },
00083     { "assign", TAG(assign) },
00084     { "assignment", TAG(assignment) },
00085     { "phiassign", TAG(phiassign) },
00086     { "lhs", TAG(lhs) },
00087     { "rhs", TAG(rhs) },
00088     { "callstmt", TAG(callstmt) },
00089     { "dest", TAG(dest) },
00090     { "argument", TAG(argument) },
00091     { "returnexp", TAG(returnexp) },
00092     { "returntype", TAG(returntype) },
00093     { "returnstmt", TAG(returnstmt) },
00094     { "returns", TAG(returns) },
00095     { "modifieds", TAG(modifieds) },
00096     { "gotostmt", TAG(gotostmt) },
00097     { "branchstmt", TAG(branchstmt) },
00098     { "cond", TAG(cond) },
00099     { "casestmt", TAG(casestmt) },
00100     { "boolasgn", TAG(boolasgn) },
00101     { "type", TAG(type) },
00102     { "exp", TAG(exp) },
00103     { "voidtype", TAG(voidtype) },
00104     { "integertype", TAG(integertype) },
00105     { "pointertype", TAG(pointertype) },
00106     { "chartype", TAG(chartype) },
00107     { "namedtype", TAG(namedtype) },
00108     { "arraytype", TAG(arraytype) },
00109     { "basetype", TAG(basetype) },
00110     { "sizetype", TAG(sizetype) },
00111     { "location", TAG(location) },
00112     { "unary", TAG(unary) },
00113     { "binary", TAG(binary) },
00114     { "ternary", TAG(ternary) },
00115     { "const", TAG(const) },
00116     { "terminal", TAG(terminal) },
00117     { "typedexp", TAG(typedexp) },
00118     { "refexp", TAG(refexp) },
00119     { "def", TAG(def) },
00120     { "subexp1", TAG(subexp1) },
00121     { "subexp2", TAG(subexp2) },
00122     { "subexp3", TAG(subexp3) },    
00123     { 0, 0, 0}
00124 };
00125 
00126 class Context {
00127 public:
00128     int tag;
00129     int n;
00130     std::string str;
00131     Prog *prog;
00132     Global *global;
00133     Cluster *cluster;
00134     Proc *proc;
00135     Signature *signature;
00136     Cfg *cfg;
00137     BasicBlock *bb;
00138     RTL *rtl;
00139     Statement *stmt;
00140     Parameter *param;
00141     // ImplicitParameter *implicitParam;
00142     Return *ret;
00143     Type *type;
00144     Exp *exp, *symbol;
00145     std::list<Proc*> procs;
00146 
00147         Context(int tag) : tag(tag), prog(NULL), proc(NULL), signature(NULL), cfg(NULL), bb(NULL), rtl(NULL), stmt(NULL), param(NULL), /*implicitParam(NULL),*/ ret(NULL), type(NULL), exp(NULL) { } 
00148 };
00149 
00150 static void XMLCALL
00151 start(void *data, const char *el, const char **attr)
00152 {
00153   ((XMLProgParser*)data)->handleElementStart(el, attr);
00154 }
00155 
00156 static void XMLCALL
00157 end(void *data, const char *el)
00158 {
00159   ((XMLProgParser*)data)->handleElementEnd(el);
00160 }
00161 
00162 static void XMLCALL
00163 text(void *data, const char *s, int len)
00164 {
00165     int mylen;
00166     char buf[1024];
00167     if (len == 1 && *s == '\n')
00168         return;
00169     mylen = len < 1024 ? len : 1023;
00170     memcpy(buf, s, mylen);
00171     buf[mylen] = 0;
00172     printf("error: text in document %i bytes (%s)\n", len, buf);
00173 }
00174 
00175 const char *XMLProgParser::getAttr(const char **attr, const char *name)
00176 {
00177   for (int i = 0; attr[i]; i += 2)
00178     if (!strcmp(attr[i], name))
00179         return attr[i+1];
00180   return NULL;
00181 }
00182 
00183 void XMLProgParser::handleElementStart(const char *el, const char **attr)
00184 {
00185     for (int i = 0; tags[i].tag; i++)
00186     if (!strcmp(el, tags[i].tag)) {
00187         //std::cerr << "got tag: " << tags[i].tag << "\n";
00188         stack.push_front(new Context(i));
00189         (this->*tags[i].start_proc)(attr);
00190         return;
00191     }
00192     std::cerr << "got unknown tag: " << el << "\n";
00193     stack.push_front(new Context(e_unknown));
00194 }
00195 
00196 void XMLProgParser::handleElementEnd(const char *el)
00197 {
00198     //std::cerr << "end tag: " << el << " tos: " << stack.front()->tag << "\n";
00199     std::list<Context*>::iterator it = stack.begin();
00200     if (it != stack.end()) {
00201         it++;
00202         if (it != stack.end()) {
00203             if ((*it)->tag != e_unknown) {
00204                 //std::cerr << " second: " << (*it)->tag << "\n";
00205                 (this->*tags[(*it)->tag].end_proc)(*it, stack.front()->tag);
00206             }
00207             stack.erase(stack.begin());
00208         }
00209     }
00210 }
00211 
00212 void XMLProgParser::addId(const char **attr, void *x)
00213 {
00214     const char *val = getAttr(attr, "id");
00215     if (val) {
00216         //std::cerr << "map id " << val << " to " << std::hex << (int)x << std::dec << "\n";
00217         idToX[atoi(val)] = x;
00218     }
00219 }
00220 
00221 void *XMLProgParser::findId(const char *id)
00222 {
00223     if (id == NULL)
00224     return NULL;
00225     int n = atoi(id);
00226     if (n == 0)
00227         return NULL;
00228     std::map<int, void*>::iterator it = idToX.find(n);
00229     if (it == idToX.end()) {
00230         std::cerr << "findId could not find \"" << id << "\"\n";
00231         assert(false);
00232         return NULL;
00233     }
00234     return (*it).second;
00235 }
00236 
00237 void XMLProgParser::start_prog(const char **attr)
00238 {
00239     if (phase == 1) {
00240         return;
00241     }
00242     stack.front()->prog = new Prog();
00243     addId(attr, stack.front()->prog);
00244     const char *name = getAttr(attr, "name");
00245     if (name)
00246         stack.front()->prog->setName(name);
00247     name = getAttr(attr, "path");
00248     if (name)
00249         stack.front()->prog->m_path = name;
00250     const char *iNumberedProc = getAttr(attr, "iNumberedProc");
00251     stack.front()->prog->m_iNumberedProc = atoi(iNumberedProc);
00252 }
00253 
00254 void XMLProgParser::addToContext_prog(Context *c, int e)
00255 {
00256     if (phase == 1) {
00257         switch(e) {
00258         case e_libproc:
00259         case e_userproc:
00260             Boomerang::get()->alert_load(stack.front()->proc);
00261             break;
00262         }
00263     return;
00264     }
00265     switch(e) {
00266     case e_libproc:
00267         stack.front()->proc->setProg(c->prog);
00268         c->prog->m_procs.push_back(stack.front()->proc);
00269         c->prog->m_procLabels[stack.front()->proc->getNativeAddress()] = stack.front()->proc;
00270         break;
00271     case e_userproc:
00272         stack.front()->proc->setProg(c->prog);
00273         c->prog->m_procs.push_back(stack.front()->proc);
00274         c->prog->m_procLabels[stack.front()->proc->getNativeAddress()] = stack.front()->proc;
00275         break;
00276     case e_procs:
00277         for (std::list<Proc*>::iterator it = stack.front()->procs.begin(); it != stack.front()->procs.end(); it++) {
00278             c->prog->m_procs.push_back(*it);
00279             c->prog->m_procLabels[(*it)->getNativeAddress()] = *it;
00280             Boomerang::get()->alert_load(*it);
00281         }
00282         break;
00283     case e_cluster:
00284         c->prog->m_rootCluster = stack.front()->cluster;
00285         break;
00286     case e_global:
00287         c->prog->globals.insert(stack.front()->global);
00288         break;
00289     default:
00290         if (e == e_unknown)
00291             std::cerr << "unknown tag " << e << " in context prog\n";
00292         else 
00293             std::cerr << "need to handle tag " << tags[e].tag << " in context prog\n";
00294         break;
00295     }
00296 }
00297 
00298 void XMLProgParser::start_procs(const char **attr)
00299 {
00300     if (phase == 1) {
00301         return;
00302     }
00303     stack.front()->procs.clear();
00304 }
00305 
00306 void XMLProgParser::addToContext_procs(Context *c, int e)
00307 {
00308     if (phase == 1) {
00309         return;
00310     }
00311     switch(e) {
00312     case e_libproc:
00313         c->procs.push_back(stack.front()->proc);
00314         break;
00315     case e_userproc:
00316         c->procs.push_back(stack.front()->proc);
00317         break;
00318     default:
00319         if (e == e_unknown)
00320             std::cerr << "unknown tag " << e << " in context procs\n";
00321         else 
00322             std::cerr << "need to handle tag " << tags[e].tag << " in context procs\n";
00323         break;
00324     }
00325 }
00326 
00327 void XMLProgParser::start_global(const char **attr)
00328 {
00329     if (phase == 1) {
00330         return;
00331     }
00332     stack.front()->global = new Global();
00333     addId(attr, stack.front()->global);
00334     const char *name = getAttr(attr, "name");
00335     if (name)
00336         stack.front()->global->nam = name;
00337     const char *uaddr = getAttr(attr, "uaddr");
00338     if (uaddr)
00339         stack.front()->global->uaddr = atoi(uaddr);
00340 }
00341 
00342 void XMLProgParser::addToContext_global(Context *c, int e)
00343 {
00344     if (phase == 1) {
00345         return;
00346     }
00347     switch(e) {
00348     case e_type:
00349         c->global->type = stack.front()->type;
00350         break;
00351     default:
00352         if (e == e_unknown)
00353         std::cerr << "unknown tag " << e << " in context global\n";
00354         else 
00355         std::cerr << "need to handle tag " << tags[e].tag << " in context global\n";
00356         break;
00357     }
00358 }
00359 
00360 void XMLProgParser::start_cluster(const char **attr)
00361 {
00362     if (phase == 1) {
00363         stack.front()->cluster = (Cluster*)findId(getAttr(attr, "id"));
00364         return;
00365     }
00366     stack.front()->cluster = new Cluster();
00367     addId(attr, stack.front()->cluster);
00368     const char *name = getAttr(attr, "name");
00369     if (name)
00370         stack.front()->cluster->setName(name);
00371 }
00372 
00373 void XMLProgParser::addToContext_cluster(Context *c, int e)
00374 {
00375     if (phase == 1) {
00376         return;
00377     }
00378     switch(e) {
00379     case e_cluster:
00380         c->cluster->addChild(stack.front()->cluster);
00381         break;
00382     default:
00383         if (e == e_unknown)
00384         std::cerr << "unknown tag " << e << " in context cluster\n";
00385         else 
00386         std::cerr << "need to handle tag " << tags[e].tag << " in context cluster\n";
00387         break;
00388     }
00389 }
00390 
00391 void XMLProgParser::start_libproc(const char **attr)
00392 {
00393     if (phase == 1) {
00394         stack.front()->proc = (Proc*)findId(getAttr(attr, "id"));
00395         Proc *p = (Proc*)findId(getAttr(attr, "firstCaller"));
00396         if (p)
00397             stack.front()->proc->m_firstCaller = p;
00398         Cluster *c = (Cluster*)findId(getAttr(attr, "cluster"));
00399         if (c)
00400             stack.front()->proc->cluster = c;
00401         return;
00402     }
00403     stack.front()->proc = new LibProc();
00404     addId(attr, stack.front()->proc);
00405     const char *address = getAttr(attr, "address");
00406     if (address)
00407         stack.front()->proc->address = atoi(address);
00408     address = getAttr(attr, "firstCallerAddress");
00409     if (address)
00410         stack.front()->proc->m_firstCallerAddr = atoi(address);
00411 }
00412 
00413 void XMLProgParser::addToContext_libproc(Context *c, int e)
00414 {
00415     if (phase == 1) {
00416         switch(e) {
00417             case e_caller:
00418             CallStatement *call = dynamic_cast<CallStatement*>(stack.front()->stmt);
00419             assert(call);
00420             c->proc->addCaller(call);
00421             break;
00422         }
00423         return;
00424     }
00425     switch(e) {
00426         case e_signature:
00427             c->proc->setSignature(stack.front()->signature);
00428             break;
00429         case e_proven_true:
00430             c->proc->setProvenTrue(stack.front()->exp);
00431             break;
00432         case e_caller:
00433             break;
00434         default:
00435             if (e == e_unknown)
00436             std::cerr << "unknown tag " << e << " in context libproc\n";
00437             else 
00438             std::cerr << "need to handle tag " << tags[e].tag << " in context libproc\n";
00439             break;
00440     }
00441 }
00442 
00443 void XMLProgParser::start_userproc(const char **attr)
00444 {
00445     if (phase == 1) {
00446         stack.front()->proc = (Proc*)findId(getAttr(attr, "id"));
00447         UserProc *u = dynamic_cast<UserProc*>(stack.front()->proc);
00448         assert(u);
00449         Proc *p = (Proc*)findId(getAttr(attr, "firstCaller"));
00450         if (p)
00451             u->m_firstCaller = p;
00452         Cluster *c = (Cluster*)findId(getAttr(attr, "cluster"));
00453         if (c)
00454             u->cluster = c;
00455         ReturnStatement *r = (ReturnStatement*)findId(getAttr(attr, "retstmt"));
00456         if (r)
00457             u->theReturnStatement = r;
00458         return;
00459     }
00460     UserProc *proc = new UserProc();
00461     stack.front()->proc = proc;
00462     addId(attr, proc);
00463 
00464     const char *address = getAttr(attr, "address");
00465     if (address)
00466         proc->address = atoi(address);
00467     address = getAttr(attr, "status");
00468     if (address)
00469         proc->status = (ProcStatus)atoi(address);
00470     address = getAttr(attr, "firstCallerAddress");
00471     if (address)
00472         proc->m_firstCallerAddr = atoi(address);
00473 }
00474 
00475 void XMLProgParser::addToContext_userproc(Context *c, int e)
00476 {
00477     UserProc *userproc = dynamic_cast<UserProc*>(c->proc);
00478     assert(userproc);
00479     if (phase == 1) {
00480         switch(e) {
00481             case e_caller:
00482             {
00483                 CallStatement *call = dynamic_cast<CallStatement*>(stack.front()->stmt);
00484                 assert(call);
00485                 c->proc->addCaller(call);
00486                 break;
00487             }
00488             case e_callee:
00489                 userproc->addCallee(stack.front()->proc);
00490                 break;
00491         }
00492         return;
00493     }
00494     switch(e) {
00495         case e_signature:
00496             c->proc->setSignature(stack.front()->signature);
00497             break;
00498         case e_proven_true:
00499             c->proc->setProvenTrue(stack.front()->exp);
00500             break;
00501         case e_caller:
00502             break;
00503         case e_callee:
00504             break;
00505         case e_cfg:
00506             userproc->setCFG(stack.front()->cfg);
00507             break;
00508         case e_local:
00509             userproc->locals[stack.front()->str.c_str()] = stack.front()->type;
00510             break;
00511         case e_symbol:
00512             userproc->mapSymbolTo(stack.front()->exp, stack.front()->symbol);
00513             break;
00514         default:
00515             if (e == e_unknown)
00516             std::cerr << "unknown tag " << e << " in context userproc\n";
00517             else 
00518             std::cerr << "need to handle tag " << tags[e].tag << " in context userproc\n";
00519             break;
00520     }
00521 }
00522 
00523 void XMLProgParser::start_local(const char **attr)
00524 {
00525     if (phase == 1) {
00526         return;
00527     }
00528     stack.front()->str = getAttr(attr, "name");
00529 }
00530 
00531 void XMLProgParser::addToContext_local(Context *c, int e)
00532 {
00533     if (phase == 1) {
00534         return;
00535     }
00536     switch(e) {
00537         case e_type:
00538             c->type = stack.front()->type;
00539             break;
00540         default:
00541             if (e == e_unknown)
00542             std::cerr << "unknown tag " << e << " in context local\n";
00543             else 
00544             std::cerr << "need to handle tag " << tags[e].tag << " in context local\n";
00545             break;
00546     }
00547 }
00548 
00549 void XMLProgParser::start_symbol(const char **attr)
00550 {
00551     if (phase == 1) {
00552         return;
00553     }
00554 }
00555 
00556 void XMLProgParser::addToContext_symbol(Context *c, int e)
00557 {
00558     if (phase == 1) {
00559         return;
00560     }
00561     switch(e) {
00562         case e_exp:
00563             c->exp = stack.front()->exp;
00564             break;
00565         case e_secondexp:
00566             c->symbol = stack.front()->exp;
00567             break;
00568         default:
00569             if (e == e_unknown)
00570                 std::cerr << "unknown tag " << e << " in context local\n";
00571             else 
00572                 std::cerr << "need to handle tag " << tags[e].tag << " in context local\n";
00573             break;
00574     }
00575 }
00576 
00577 void XMLProgParser::start_proven_true(const char **attr)
00578 {
00579 }
00580 
00581 void XMLProgParser::addToContext_proven_true(Context *c, int e)
00582 {
00583     c->exp = stack.front()->exp;
00584 }
00585 
00586 void XMLProgParser::start_callee(const char **attr)
00587 {
00588     if (phase == 1) {
00589     stack.front()->proc = (Proc*)findId(getAttr(attr, "proc"));
00590     }
00591 }
00592 
00593 void XMLProgParser::addToContext_callee(Context *c, int e)
00594 {
00595 }
00596 
00597 void XMLProgParser::start_caller(const char **attr)
00598 {
00599     if (phase == 1) {
00600     stack.front()->stmt = (Statement*)findId(getAttr(attr, "call"));
00601     }
00602 }
00603 
00604 void XMLProgParser::addToContext_caller(Context *c, int e)
00605 {
00606 }
00607 
00608 void XMLProgParser::start_signature(const char **attr)
00609 {
00610     if (phase == 1) {
00611     stack.front()->signature = (Signature*)findId(getAttr(attr, "id"));
00612     return;
00613     }
00614     const char *plat = getAttr(attr, "platform");
00615     const char *convention = getAttr(attr, "convention");
00616     const char *name = getAttr(attr, "name");
00617 
00618     Signature *sig;
00619     if (plat && convention) {
00620         platform p;
00621         callconv c;
00622         if (!strcmp(plat, "pentium"))
00623             p = PLAT_PENTIUM;
00624         else if (!strcmp(plat, "sparc"))
00625             p = PLAT_SPARC;
00626         else if (!strcmp(plat, "ppc"))
00627             p = PLAT_PPC;
00628         else if (!strcmp(plat, "st20"))
00629             p = PLAT_ST20;
00630         else {
00631             std::cerr << "unknown platform: " << plat << "\n";
00632             assert(false);
00633             p = PLAT_PENTIUM;
00634         }
00635         if (!strcmp(convention, "stdc"))
00636             c = CONV_C;
00637         else if (!strcmp(convention, "pascal"))
00638             c = CONV_PASCAL;
00639         else if (!strcmp(convention, "thiscall"))
00640             c = CONV_THISCALL;
00641         else {
00642             std::cerr << "unknown convention: " << convention << "\n";
00643             assert(false);
00644             c = CONV_C;
00645         }
00646         sig = Signature::instantiate(p, c, name);
00647     } else
00648     sig = new Signature(name);
00649     sig->params.clear();
00650     // sig->implicitParams.clear();
00651     sig->returns.clear();
00652     stack.front()->signature = sig;
00653     addId(attr, sig);
00654     const char *n = getAttr(attr, "ellipsis");
00655     if (n)
00656         sig->ellipsis = atoi(n) > 0;
00657     n = getAttr(attr, "preferedName");
00658     if (n)
00659         sig->preferedName = n;
00660 }
00661 
00662 void XMLProgParser::addToContext_signature(Context *c, int e)
00663 {
00664     if (phase == 1) {
00665         return;
00666     }
00667     switch(e) {
00668         case e_param:
00669             c->signature->appendParameter(stack.front()->param);
00670             break;
00671         case e_return:
00672             c->signature->appendReturn(stack.front()->ret);
00673             break;
00674         case e_rettype:
00675             c->signature->setRetType(stack.front()->type);
00676             break;
00677         case e_prefparam:
00678             c->signature->preferedParams.push_back(stack.front()->n);
00679             break;
00680         case e_prefreturn:
00681             c->signature->preferedReturn = stack.front()->type;
00682             break;
00683         default:
00684             if (e == e_unknown)
00685             std::cerr << "unknown tag " << e << " in context signature\n";
00686             else 
00687             std::cerr << "need to handle tag " << tags[e].tag << " in context signature\n";
00688         break;
00689     }
00690 }
00691 
00692 void XMLProgParser::start_param(const char **attr)
00693 {
00694     if (phase == 1) {
00695         stack.front()->param = (Parameter*)findId(getAttr(attr, "id"));
00696         return;
00697     }
00698     stack.front()->param = new Parameter();
00699     addId(attr, stack.front()->param);
00700     const char *n = getAttr(attr, "name");
00701     if (n)
00702         stack.front()->param->setName(n);
00703 }
00704 
00705 void XMLProgParser::addToContext_param(Context *c, int e)
00706 {
00707     if (phase == 1) {
00708         return;
00709     }
00710     switch(e) {
00711         case e_type:
00712             c->param->setType(stack.front()->type);
00713             break;
00714         case e_exp:
00715             c->param->setExp(stack.front()->exp);
00716             break;
00717         default:
00718             if (e == e_unknown)
00719             std::cerr << "unknown tag " << e << " in context param\n";
00720             else 
00721             std::cerr << "need to handle tag " << tags[e].tag << " in context param\n";
00722         break;
00723     }
00724 }
00725 
00726 void XMLProgParser::start_prefreturn(const char **attr)
00727 {
00728     if (phase == 1) {
00729         return;
00730     }
00731 }
00732 
00733 void XMLProgParser::addToContext_prefreturn(Context *c, int e)
00734 {
00735     if (phase == 1) {
00736         return;
00737     }
00738     c->type = stack.front()->type;
00739 }
00740 
00741 void XMLProgParser::start_prefparam(const char **attr)
00742 {
00743     if (phase == 1) {
00744         return;
00745     }
00746     const char *n = getAttr(attr, "index");
00747     assert(n);
00748     stack.front()->n = atoi(n);
00749 }
00750 
00751 void XMLProgParser::addToContext_prefparam(Context *c, int e)
00752 {
00753     if (phase == 1) {
00754         return;
00755     }
00756 //    switch(e) {
00757 //  default:
00758         if (e == e_unknown)
00759             std::cerr << "unknown tag " << e << " in context prefparam\n";
00760         else 
00761             std::cerr << "need to handle tag " << tags[e].tag << " in context prefparam\n";
00762 //  break;
00763 //    }
00764 }
00765 
00766 void XMLProgParser::start_return(const char **attr)
00767 {
00768     if (phase == 1) {
00769         stack.front()->ret = (Return*)findId(getAttr(attr, "id"));
00770         return;
00771     }
00772     stack.front()->ret = new Return();
00773     addId(attr, stack.front()->ret);
00774 }
00775 
00776 void XMLProgParser::addToContext_return(Context *c, int e)
00777 {
00778     if (phase == 1) {
00779         return;
00780     }
00781     switch(e) {
00782         case e_type:
00783             c->ret->type = stack.front()->type;
00784             break;
00785         case e_exp:
00786             c->ret->exp = stack.front()->exp;
00787             break;
00788         default:
00789             if (e == e_unknown)
00790             std::cerr << "unknown tag " << e << " in context return\n";
00791             else 
00792             std::cerr << "need to handle tag " << tags[e].tag << " in context return\n";
00793         break;
00794     }
00795 }
00796 
00797 void XMLProgParser::start_rettype(const char **attr)
00798 {
00799 }
00800 
00801 void XMLProgParser::addToContext_rettype(Context *c, int e)
00802 {
00803     c->type = stack.front()->type;
00804 }
00805 
00806 void XMLProgParser::start_cfg(const char **attr)
00807 {
00808     if (phase == 1) {
00809         stack.front()->cfg = (Cfg*)findId(getAttr(attr, "id"));
00810         PBB entryBB = (PBB)findId(getAttr(attr, "entryBB"));
00811         if (entryBB)
00812             stack.front()->cfg->setEntryBB(entryBB);
00813         PBB exitBB = (PBB)findId(getAttr(attr, "exitBB"));
00814         if (exitBB)
00815             stack.front()->cfg->setExitBB(exitBB);
00816         return;
00817     }
00818     Cfg *cfg = new Cfg();
00819     stack.front()->cfg = cfg;
00820     addId(attr, cfg);
00821 
00822     const char *str = getAttr(attr, "wellformed");
00823     if (str)
00824         cfg->m_bWellFormed = atoi(str) > 0;
00825     str = getAttr(attr, "lastLabel");
00826     if (str)
00827         cfg->lastLabel = atoi(str);
00828 }
00829 
00830 void XMLProgParser::addToContext_cfg(Context *c, int e)
00831 {
00832     if (phase == 1) {
00833         switch(e) {
00834             case e_order:
00835             c->cfg->Ordering.push_back(stack.front()->bb);
00836             break;
00837             case e_revorder:
00838             c->cfg->revOrdering.push_back(stack.front()->bb);
00839             break;
00840         }
00841         return;
00842     }
00843     switch(e) {
00844         case e_bb:
00845             c->cfg->addBB(stack.front()->bb);
00846             break;
00847         case e_order:
00848             break;
00849         case e_revorder:
00850             break;
00851         default:
00852             if (e == e_unknown)
00853             std::cerr << "unknown tag " << e << " in context cfg\n";
00854             else 
00855             std::cerr << "need to handle tag " << tags[e].tag << " in context cfg\n";
00856             break;
00857     }
00858 }
00859 
00860 void XMLProgParser::start_bb(const char **attr)
00861 {
00862     PBB bb;
00863     if (phase == 1) {
00864         bb = stack.front()->bb = (BasicBlock*)findId(getAttr(attr, "id"));
00865         PBB h = (PBB)findId(getAttr(attr, "m_loopHead"));
00866         if (h)
00867             bb->m_loopHead = h;
00868         h = (PBB)findId(getAttr(attr, "m_caseHead"));
00869         if (h)
00870             bb->m_caseHead = h;
00871         h = (PBB)findId(getAttr(attr, "m_condFollow"));
00872         if (h)
00873             bb->m_condFollow = h;
00874         h = (PBB)findId(getAttr(attr, "m_loopFollow"));
00875         if (h)
00876             bb->m_loopFollow = h;
00877         h = (PBB)findId(getAttr(attr, "m_latchNode"));
00878         if (h)
00879             bb->m_latchNode = h;
00880         // note the rediculous duplication here
00881         h = (PBB)findId(getAttr(attr, "immPDom"));
00882         if (h)
00883             bb->immPDom = h;
00884         h = (PBB)findId(getAttr(attr, "loopHead"));
00885         if (h)
00886             bb->loopHead = h;
00887         h = (PBB)findId(getAttr(attr, "caseHead"));
00888         if (h)
00889             bb->caseHead = h;
00890         h = (PBB)findId(getAttr(attr, "condFollow"));
00891         if (h)
00892             bb->condFollow = h;
00893         h = (PBB)findId(getAttr(attr, "loopFollow"));
00894         if (h)
00895             bb->loopFollow = h;
00896         h = (PBB)findId(getAttr(attr, "latchNode"));
00897         if (h)
00898             bb->latchNode = h;
00899         return;
00900     }
00901     bb = new BasicBlock();
00902     stack.front()->bb = bb;
00903     addId(attr, bb);
00904 
00905     const char *str = getAttr(attr, "nodeType");
00906     if (str)
00907         bb->m_nodeType = (BBTYPE)atoi(str);
00908     str = getAttr(attr, "labelNum");
00909     if (str)
00910         bb->m_iLabelNum = atoi(str);
00911     str = getAttr(attr, "label");
00912     if (str)
00913         bb->m_labelStr = strdup(str);
00914     str = getAttr(attr, "labelneeded");
00915     if (str)
00916         bb->m_labelneeded = atoi(str) > 0;
00917     str = getAttr(attr, "incomplete");
00918     if (str)
00919         bb->m_bIncomplete = atoi(str) > 0;
00920     str = getAttr(attr, "jumpreqd");
00921     if (str)
00922         bb->m_bJumpReqd = atoi(str) > 0;
00923     str = getAttr(attr, "m_traversed");
00924     if (str)
00925         bb->m_iTraversed = atoi(str) > 0;
00926     str = getAttr(attr, "DFTfirst");
00927     if (str)
00928         bb->m_DFTfirst = atoi(str);
00929     str = getAttr(attr, "DFTlast");
00930     if (str)
00931         bb->m_DFTlast = atoi(str);
00932     str = getAttr(attr, "DFTrevfirst");
00933     if (str)
00934         bb->m_DFTrevfirst = atoi(str);
00935     str = getAttr(attr, "DFTrevlast");
00936     if (str)
00937         bb->m_DFTrevlast = atoi(str);
00938     str = getAttr(attr, "structType");
00939     if (str)
00940         bb->m_structType = (SBBTYPE)atoi(str);
00941     str = getAttr(attr, "loopCondType");
00942     if (str)
00943         bb->m_loopCondType = (SBBTYPE)atoi(str);
00944     str = getAttr(attr, "ord");
00945     if (str)
00946         bb->ord = atoi(str);
00947     str = getAttr(attr, "revOrd");
00948     if (str)
00949         bb->revOrd = atoi(str);
00950     str = getAttr(attr, "inEdgesVisited");
00951     if (str)
00952         bb->inEdgesVisited = atoi(str);
00953     str = getAttr(attr, "numForwardInEdges");
00954     if (str)
00955         bb->numForwardInEdges = atoi(str);
00956     str = getAttr(attr, "loopStamp1");
00957     if (str)
00958         bb->loopStamps[0] = atoi(str);
00959     str = getAttr(attr, "loopStamp2");
00960     if (str)
00961         bb->loopStamps[1] = atoi(str);
00962     str = getAttr(attr, "revLoopStamp1");
00963     if (str)
00964         bb->revLoopStamps[0] = atoi(str);
00965     str = getAttr(attr, "revLoopStamp2");
00966     if (str)
00967         bb->revLoopStamps[1] = atoi(str);
00968     str = getAttr(attr, "traversed");
00969     if (str)
00970     bb->traversed = (travType)atoi(str);
00971     str = getAttr(attr, "hllLabel");
00972     if (str)
00973     bb->hllLabel = atoi(str) > 0;
00974     str = getAttr(attr, "labelStr");
00975     if (str)
00976     bb->labelStr = strdup(str);
00977     str = getAttr(attr, "indentLevel");
00978     if (str)
00979     bb->indentLevel = atoi(str);
00980     str = getAttr(attr, "sType");
00981     if (str)
00982         bb->sType = (structType)atoi(str);
00983     str = getAttr(attr, "usType");
00984     if (str)
00985         bb->usType = (unstructType)atoi(str);
00986     str = getAttr(attr, "lType");
00987     if (str)
00988         bb->lType = (loopType)atoi(str);
00989     str = getAttr(attr, "cType");
00990     if (str)
00991         bb->cType = (condType)atoi(str);
00992 }
00993 
00994 void XMLProgParser::addToContext_bb(Context *c, int e)
00995 {
00996     if (phase == 1) {
00997         switch(e) {
00998             case e_inedge:
00999             c->bb->addInEdge(stack.front()->bb);
01000             break;
01001             case e_outedge:
01002             c->bb->addOutEdge(stack.front()->bb);
01003             break;
01004         }
01005         return;
01006     }
01007     switch(e) {
01008         case e_inedge:
01009             break;
01010         case e_outedge:
01011             break;
01012         case e_livein:
01013             c->bb->addLiveIn((Location*)stack.front()->exp);
01014             break;
01015         case e_rtl:
01016             c->bb->addRTL(stack.front()->rtl);
01017             break;
01018         default:
01019             if (e == e_unknown)
01020             std::cerr << "unknown tag " << e << " in context bb\n";
01021             else 
01022             std::cerr << "need to handle tag " << tags[e].tag << " in context bb\n";
01023         break;
01024     }
01025 }
01026 
01027 void XMLProgParser::start_inedge(const char **attr)
01028 {
01029     if (phase == 1)
01030         stack.front()->bb = (BasicBlock*)findId(getAttr(attr, "bb"));
01031     else
01032         stack.front()->bb = NULL;
01033 }
01034 
01035 void XMLProgParser::addToContext_inedge(Context *c, int e)
01036 {
01037 //    switch(e) {
01038 //  default:
01039         if (e == e_unknown)
01040         std::cerr << "unknown tag " << e << " in context inedge\n";
01041         else 
01042         std::cerr << "need to handle tag " << tags[e].tag << " in context inedge\n";
01043 //  break;
01044 //    }
01045 }
01046 
01047 void XMLProgParser::start_outedge(const char **attr)
01048 {
01049     if (phase == 1)
01050         stack.front()->bb = (BasicBlock*)findId(getAttr(attr, "bb"));
01051     else
01052         stack.front()->bb = NULL;
01053 }
01054 
01055 void XMLProgParser::addToContext_outedge(Context *c, int e)
01056 {
01057 //    switch(e) {
01058 //  default:
01059         if (e == e_unknown)
01060             std::cerr << "unknown tag " << e << " in context outedge\n";
01061         else 
01062             std::cerr << "need to handle tag " << tags[e].tag << " in context outedge\n";
01063 //  break;
01064 //    }
01065 }
01066 
01067 void XMLProgParser::start_livein(const char **attr)
01068 {
01069 }
01070 
01071 void XMLProgParser::addToContext_livein(Context *c, int e)
01072 {
01073     c->exp = stack.front()->exp;
01074 }
01075 
01076 void XMLProgParser::start_order(const char **attr)
01077 {
01078     if (phase == 1)
01079         stack.front()->bb = (PBB)findId(getAttr(attr, "bb"));
01080     else 
01081         stack.front()->bb = NULL;
01082 }
01083 
01084 void XMLProgParser::addToContext_order(Context *c, int e)
01085 {
01086 //    switch(e) {
01087 //  default:
01088         if (e == e_unknown)
01089             std::cerr << "unknown tag " << e << " in context order\n";
01090         else 
01091             std::cerr << "need to handle tag " << tags[e].tag << " in context order\n";
01092 //  break;
01093 //    }
01094 }
01095 
01096 void XMLProgParser::start_revorder(const char **attr)
01097 {
01098     if (phase == 1)
01099         stack.front()->bb = (PBB)findId(getAttr(attr, "bb"));
01100     else 
01101         stack.front()->bb = NULL;
01102 }
01103 
01104 void XMLProgParser::addToContext_revorder(Context *c, int e)
01105 {
01106 //    switch(e) {
01107 //  default:
01108         if (e == e_unknown)
01109             std::cerr << "unknown tag " << e << " in context revOrder\n";
01110         else 
01111             std::cerr << "need to handle tag " << tags[e].tag << " in context order\n";
01112 //  break;
01113 //    }
01114 }
01115 
01116 void XMLProgParser::start_rtl(const char **attr)
01117 {
01118     if (phase == 1) {
01119         stack.front()->rtl = (RTL*)findId(getAttr(attr, "id"));
01120         return;
01121     }
01122     stack.front()->rtl = new RTL();
01123     addId(attr, stack.front()->rtl);
01124     const char *a = getAttr(attr, "addr");
01125     if (a)
01126         stack.front()->rtl->nativeAddr = atoi(a);
01127 }
01128 
01129 void XMLProgParser::addToContext_rtl(Context *c, int e)
01130 {
01131     if (phase == 1) {
01132         return;
01133     }
01134     switch(e) {
01135         case e_stmt:
01136             c->rtl->appendStmt(stack.front()->stmt);
01137             break;
01138         default:
01139             if (e == e_unknown)
01140             std::cerr << "unknown tag " << e << " in context rtl\n";
01141             else 
01142             std::cerr << "need to handle tag " << tags[e].tag << " in context rtl\n";
01143         break;
01144     }
01145 }
01146 
01147 void XMLProgParser::start_stmt(const char **attr)
01148 {
01149 }
01150 
01151 void XMLProgParser::addToContext_stmt(Context *c, int e)
01152 {
01153     c->stmt = stack.front()->stmt;
01154 }
01155 
01156 void XMLProgParser::start_assign(const char **attr)
01157 {
01158     if (phase == 1) {
01159         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01160         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01161         if (p)
01162             stack.front()->stmt->setProc(p);
01163         Statement *parent = (Statement*)findId(getAttr(attr, "parent"));
01164         if (parent)
01165             stack.front()->stmt->parent = parent;
01166         return;
01167     }
01168     stack.front()->stmt = new Assign();
01169     addId(attr, stack.front()->stmt);
01170     const char *n = getAttr(attr, "number");
01171     if (n)
01172         stack.front()->stmt->number = atoi(n);
01173 }
01174 
01175 void XMLProgParser::start_assignment(const char **attr)
01176 { 
01177 }
01178 
01179 void XMLProgParser::start_phiassign(const char **attr)
01180 {
01181     // FIXME: TBC
01182 }
01183 
01184 void XMLProgParser::addToContext_assign(Context *c, int e)
01185 {
01186     if (phase == 1) {
01187         return;
01188     }
01189     Assign *assign = dynamic_cast<Assign*>(c->stmt);
01190     assert(assign);
01191     switch(e) {
01192         case e_lhs:
01193             assign->setLeft(stack.front()->exp);
01194             break;
01195         case e_rhs:
01196             assign->setRight(stack.front()->exp);
01197             break;
01198         case e_type:
01199             assert(stack.front()->type);
01200             assign->setType(stack.front()->type);
01201             break;
01202         default:
01203             if (e == e_unknown)
01204                 std::cerr << "unknown tag " << e << " in context assign\n";
01205             else 
01206                 std::cerr << "need to handle tag " << tags[e].tag << " in context assign\n";
01207         break;
01208     }
01209 }
01210 
01211 void XMLProgParser::start_callstmt(const char **attr)
01212 {
01213     if (phase == 1) {
01214         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01215         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01216         if (p)
01217             ((Statement*)stack.front()->stmt)->setProc(p);
01218         Statement *s = (Statement*)findId(getAttr(attr, "parent"));
01219         if (s)
01220             ((Statement*)stack.front()->stmt)->parent = s;
01221         return;
01222     }
01223     CallStatement *call = new CallStatement();
01224     stack.front()->stmt = call;
01225     addId(attr, call);
01226     const char *n = getAttr(attr, "number");
01227     if (n)
01228         call->number = atoi(n);
01229     n = getAttr(attr, "computed");
01230     if (n)
01231         call->m_isComputed = atoi(n) > 0;
01232     n = getAttr(attr, "returnAftercall");
01233     if (n)
01234         call->returnAfterCall = atoi(n) > 0;
01235 }
01236 
01237 void XMLProgParser::addToContext_callstmt(Context *c, int e)
01238 {
01239     CallStatement *call = dynamic_cast<CallStatement*>(c->stmt);
01240     assert(call);
01241     if (phase == 1) {
01242         switch(e) {
01243             case e_dest:
01244             if (stack.front()->proc)
01245                 call->setDestProc(stack.front()->proc);
01246             break;
01247         }
01248         return;
01249     }
01250     Exp* returnExp = NULL;
01251     switch(e) {
01252     case e_dest:
01253         call->setDest(stack.front()->exp);
01254         break;
01255     case e_argument:
01256         call->appendArgument((Assignment*)stack.front()->stmt);
01257         break;
01258     case e_returnexp:
01259         // Assume that the corresponding return type will appear next
01260         returnExp = stack.front()->exp;
01261         break;
01262     default:
01263         if (e == e_unknown)
01264             std::cerr << "unknown tag " << e << " in context callstmt\n";
01265         else 
01266             std::cerr << "need to handle tag " << tags[e].tag << " in context callstmt\n";
01267     break;
01268     }
01269 }
01270 
01271 void XMLProgParser::start_dest(const char **attr)
01272 {
01273     if (phase == 1) {
01274         Proc *p = (Proc*)findId(getAttr(attr, "proc"));
01275         if (p)
01276             stack.front()->proc = p;
01277         return;
01278     }
01279 }
01280 
01281 void XMLProgParser::addToContext_dest(Context *c, int e)
01282 {
01283     c->exp = stack.front()->exp;
01284 }
01285 
01286 void XMLProgParser::start_returnstmt(const char **attr)
01287 {
01288     if (phase == 1) {
01289         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01290         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01291         if (p)
01292             ((Statement*)stack.front()->stmt)->setProc(p);
01293         Statement *s = (Statement*)findId(getAttr(attr, "parent"));
01294         if (s)
01295             ((Statement*)stack.front()->stmt)->parent = s;
01296         return;
01297     }
01298     ReturnStatement *ret = new ReturnStatement();
01299     stack.front()->stmt = ret;
01300     addId(attr, ret);
01301     const char *n = getAttr(attr, "number");
01302     if (n)
01303         ret->number = atoi(n);
01304     n = getAttr(attr, "retAddr");
01305     if (n)
01306         ret->retAddr = atoi(n);
01307 }
01308 
01309 void XMLProgParser::addToContext_returnstmt(Context *c, int e)
01310 {
01311     ReturnStatement *ret = dynamic_cast<ReturnStatement*>(c->stmt);
01312     assert(ret);
01313     if (phase == 1) {
01314         return;
01315     }
01316     switch(e) {
01317         case e_modifieds:
01318             ret->modifieds.append((Assignment*)stack.front()->stmt);
01319             break;
01320         case e_returns:
01321             ret->returns.append((Assignment*)stack.front()->stmt);
01322             break;
01323         default:
01324             if (e == e_unknown)
01325             std::cerr << "unknown tag " << e << " in context returnstmt\n";
01326             else 
01327             std::cerr << "need to handle tag " << tags[e].tag << " in context returnstmt\n";
01328         break;
01329     }
01330 }
01331 
01332 void XMLProgParser::start_returns(const char **attr)
01333 {
01334 }
01335 
01336 void XMLProgParser::addToContext_returns(Context *c, int e)
01337 {
01338 }
01339 
01340 void XMLProgParser::start_modifieds(const char **attr)
01341 {
01342 }
01343 
01344 void XMLProgParser::addToContext_modifieds(Context *c, int e)
01345 {
01346 }
01347 
01348 void XMLProgParser::start_gotostmt(const char **attr)
01349 {
01350     if (phase == 1) {
01351         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01352         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01353         if (p)
01354             ((Statement*)stack.front()->stmt)->setProc(p);
01355         Statement *s = (Statement*)findId(getAttr(attr, "parent"));
01356         if (s)
01357             ((Statement*)stack.front()->stmt)->parent = s;
01358         return;
01359     }
01360     GotoStatement *branch = new GotoStatement();
01361     stack.front()->stmt = branch;
01362     addId(attr, branch);
01363     const char *n = getAttr(attr, "number");
01364     if (n)
01365         branch->number = atoi(n);
01366     n = getAttr(attr, "computed");
01367     if (n)
01368         branch->m_isComputed = atoi(n) > 0;
01369 }
01370 
01371 void XMLProgParser::addToContext_gotostmt(Context *c, int e)
01372 {
01373     GotoStatement *branch = dynamic_cast<GotoStatement*>(c->stmt);
01374     assert(branch);
01375     if (phase == 1) {
01376         return;
01377     }
01378     switch(e) {
01379         case e_dest:
01380             branch->setDest(stack.front()->exp);
01381             break;
01382         default:
01383             if (e == e_unknown)
01384             std::cerr << "unknown tag " << e << " in context gotostmt\n";
01385             else 
01386             std::cerr << "need to handle tag " << tags[e].tag << " in context gotostmt\n";
01387         break;
01388     }
01389 }
01390 
01391 void XMLProgParser::start_branchstmt(const char **attr)
01392 {
01393     if (phase == 1) {
01394         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01395         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01396         if (p)
01397             ((Statement*)stack.front()->stmt)->setProc(p);
01398         Statement *s = (Statement*)findId(getAttr(attr, "parent"));
01399         if (s)
01400             ((Statement*)stack.front()->stmt)->parent = s;
01401         return;
01402     }
01403     BranchStatement *branch = new BranchStatement();
01404     stack.front()->stmt = branch;
01405     addId(attr, branch);
01406     const char *n = getAttr(attr, "number");
01407     if (n)
01408         branch->number = atoi(n);
01409     n = getAttr(attr, "computed");
01410     if (n)
01411         branch->m_isComputed = atoi(n) > 0;
01412     n = getAttr(attr, "jtcond");
01413     if (n)
01414         branch->jtCond = (BRANCH_TYPE)atoi(n);
01415     n = getAttr(attr, "float");
01416     if (n)
01417         branch->bFloat = atoi(n) > 0;
01418 }
01419 
01420 void XMLProgParser::addToContext_branchstmt(Context *c, int e)
01421 {
01422     BranchStatement *branch = dynamic_cast<BranchStatement*>(c->stmt);
01423     assert(branch);
01424     if (phase == 1) {
01425         return;
01426     }
01427     switch(e) {
01428         case e_cond:
01429             branch->setCondExpr(stack.front()->exp);
01430             break;
01431         case e_dest:
01432             branch->setDest(stack.front()->exp);
01433             break;
01434         default:
01435             if (e == e_unknown)
01436                 std::cerr << "unknown tag " << e << " in context branchstmt\n";
01437             else 
01438                 std::cerr << "need to handle tag " << tags[e].tag << " in context branchstmt\n";
01439         break;
01440     }
01441 }
01442 
01443 void XMLProgParser::start_casestmt(const char **attr)
01444 {
01445     if (phase == 1) {
01446         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01447         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01448         if (p)
01449             ((Statement*)stack.front()->stmt)->setProc(p);
01450         Statement *s = (Statement*)findId(getAttr(attr, "parent"));
01451         if (s)
01452             ((Statement*)stack.front()->stmt)->parent = s;
01453         return;
01454     }
01455     CaseStatement *cas = new CaseStatement();
01456     stack.front()->stmt = cas;
01457     addId(attr, cas);
01458     const char *n = getAttr(attr, "number");
01459     if (n)
01460         cas->number = atoi(n);
01461     n = getAttr(attr, "computed");
01462     if (n)
01463         cas->m_isComputed = atoi(n) > 0;
01464 }
01465 
01466 void XMLProgParser::addToContext_casestmt(Context *c, int e)
01467 {
01468     CaseStatement *cas = dynamic_cast<CaseStatement*>(c->stmt);
01469     assert(cas);
01470     if (phase == 1) {
01471         return;
01472     }
01473     switch(e) {
01474         case e_dest:
01475             cas->setDest(stack.front()->exp);
01476             break;
01477         default:
01478             if (e == e_unknown)
01479                 std::cerr << "unknown tag " << e << " in context casestmt\n";
01480             else 
01481                 std::cerr << "need to handle tag " << tags[e].tag << " in context casestmt\n";
01482         break;
01483     }
01484 }
01485 
01486 void XMLProgParser::start_boolasgn(const char **attr)
01487 {
01488     if (phase == 1) {
01489         stack.front()->stmt = (Statement*)findId(getAttr(attr, "id"));
01490         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01491         if (p)
01492             ((Statement*)stack.front()->stmt)->setProc(p);
01493         Statement *s = (Statement*)findId(getAttr(attr, "parent"));
01494         if (s)
01495             ((Statement*)stack.front()->stmt)->parent = s;
01496         return;
01497     }
01498     const char *n = getAttr(attr, "size");
01499     assert(n);
01500     BoolAssign *boo = new BoolAssign(atoi(n));
01501     stack.front()->stmt = boo;
01502     addId(attr, boo);
01503     n = getAttr(attr, "number");
01504     if (n)
01505         boo->number = atoi(n);
01506     n = getAttr(attr, "jtcond");
01507     if (n)
01508         boo->jtCond = (BRANCH_TYPE)atoi(n);
01509     n = getAttr(attr, "float");
01510     if (n)
01511     boo->bFloat = atoi(n) > 0;
01512 }
01513 
01514 void XMLProgParser::addToContext_boolasgn(Context *c, int e)
01515 {
01516     BoolAssign *boo = dynamic_cast<BoolAssign*>(c->stmt);
01517     assert(boo);
01518     if (phase == 1) {
01519         return;
01520     }
01521     switch(e) {
01522         case e_cond:
01523             boo->pCond = stack.front()->exp;
01524             break;
01525         case e_lhs:
01526             boo->lhs = stack.front()->exp;
01527             break;
01528         default:
01529             if (e == e_unknown)
01530             std::cerr << "unknown tag " << e << " in context boolasgn\n";
01531             else 
01532             std::cerr << "need to handle tag " << tags[e].tag << " in context boolasgn\n";
01533         break;
01534     }
01535 }
01536 
01537 void XMLProgParser::start_type(const char **attr)
01538 {
01539 }
01540 
01541 void XMLProgParser::addToContext_type(Context *c, int e)
01542 {
01543     c->type = stack.front()->type;
01544 }
01545 
01546 void XMLProgParser::start_basetype(const char **attr)
01547 {
01548 }
01549 
01550 void XMLProgParser::addToContext_basetype(Context *c, int e)
01551 {
01552     c->type = stack.front()->type;
01553 }
01554 
01555 void XMLProgParser::start_sizetype(const char **attr)
01556 {
01557     if (phase == 1) {
01558         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01559         return;
01560     }
01561     SizeType *ty = new SizeType();
01562     stack.front()->type = ty;
01563     addId(attr, ty);
01564     const char *n = getAttr(attr, "size");
01565     if (n)
01566         ty->size = atoi(n);
01567 }
01568 
01569 void XMLProgParser::addToContext_sizetype(Context *c, int e)
01570 {
01571 //    switch(e) {
01572 //  default:
01573         if (e == e_unknown)
01574             std::cerr << "unknown tag " << e << " in context SizeType\n";
01575         else 
01576             std::cerr << "need to handle tag " << tags[e].tag << " in context SizeType\n";
01577 //  break;
01578 //    }
01579 }
01580 
01581 void XMLProgParser::start_exp(const char **attr)
01582 {
01583 }
01584 
01585 void XMLProgParser::addToContext_exp(Context *c, int e)
01586 {
01587     c->exp = stack.front()->exp;
01588 }
01589 
01590 void XMLProgParser::start_secondexp(const char **attr)
01591 {
01592 }
01593 
01594 void XMLProgParser::addToContext_secondexp(Context *c, int e)
01595 {
01596     c->exp = stack.front()->exp;
01597 }
01598 
01599 void XMLProgParser::start_defines(const char **attr)
01600 {
01601 }
01602 
01603 void XMLProgParser::addToContext_defines(Context *c, int e)
01604 {
01605     c->exp = stack.front()->exp;
01606 }
01607 
01608 void XMLProgParser::start_lhs(const char **attr)
01609 {
01610 }
01611 
01612 void XMLProgParser::addToContext_lhs(Context *c, int e)
01613 {
01614     c->exp = stack.front()->exp;
01615 }
01616 
01617 void XMLProgParser::start_rhs(const char **attr)
01618 {
01619 }
01620 
01621 void XMLProgParser::addToContext_rhs(Context *c, int e)
01622 {
01623     c->exp = stack.front()->exp;
01624 }
01625 
01626 void XMLProgParser::start_argument(const char **attr)
01627 {
01628 }
01629 
01630 void XMLProgParser::addToContext_argument(Context *c, int e)
01631 {
01632     c->exp = stack.front()->exp;
01633 }
01634 
01635 void XMLProgParser::start_returnexp(const char **attr)
01636 {
01637 }
01638 
01639 void XMLProgParser::start_returntype(const char **attr)
01640 {
01641 }
01642 
01643 void XMLProgParser::addToContext_returnexp(Context *c, int e)
01644 {
01645     c->exp = stack.front()->exp;
01646 }
01647 
01648 void XMLProgParser::addToContext_returntype(Context *c, int e)
01649 {
01650     c->type = stack.front()->type;
01651 }
01652 
01653 void XMLProgParser::start_cond(const char **attr)
01654 {
01655 }
01656 
01657 void XMLProgParser::addToContext_cond(Context *c, int e)
01658 {
01659     c->exp = stack.front()->exp;
01660 }
01661 
01662 void XMLProgParser::start_subexp1(const char **attr)
01663 {
01664 }
01665 
01666 void XMLProgParser::addToContext_subexp1(Context *c, int e)
01667 {
01668     c->exp = stack.front()->exp;
01669 }
01670 
01671 void XMLProgParser::start_subexp2(const char **attr)
01672 {
01673 }
01674 
01675 void XMLProgParser::addToContext_subexp2(Context *c, int e)
01676 {
01677     c->exp = stack.front()->exp;
01678 }
01679 
01680 void XMLProgParser::start_subexp3(const char **attr)
01681 {
01682 }
01683 
01684 void XMLProgParser::addToContext_subexp3(Context *c, int e)
01685 {
01686     c->exp = stack.front()->exp;
01687 }
01688 
01689 void XMLProgParser::start_voidtype(const char **attr)
01690 {
01691     if (phase == 1) {
01692         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01693         return;
01694     }
01695     stack.front()->type = new VoidType();
01696     addId(attr, stack.front()->type);
01697 }
01698 
01699 void XMLProgParser::addToContext_voidtype(Context *c, int e)
01700 {
01701 //    switch(e) {
01702 //  default:
01703         if (e == e_unknown)
01704             std::cerr << "unknown tag " << e << " in context voidType\n";
01705         else 
01706             std::cerr << "need to handle tag " << tags[e].tag << " in context voidType\n";
01707 //  break;
01708 //    }
01709 }
01710 
01711 void XMLProgParser::start_integertype(const char **attr)
01712 {
01713     if (phase == 1) {
01714         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01715         return;
01716     }
01717     IntegerType *ty = new IntegerType();
01718     stack.front()->type = ty;
01719     addId(attr, ty);
01720     const char *n = getAttr(attr, "size");
01721     if (n)
01722         ty->size = atoi(n);
01723     n = getAttr(attr, "signedness");
01724     if (n)
01725         ty->signedness = atoi(n);
01726 }
01727 
01728 void XMLProgParser::addToContext_integertype(Context *c, int e)
01729 {
01730 //    switch(e) {
01731 //  default:
01732         if (e == e_unknown)
01733             std::cerr << "unknown tag " << e << " in context integerType\n";
01734         else 
01735             std::cerr << "need to handle tag " << tags[e].tag << " in context integerType\n";
01736 //  break;
01737 //    }
01738 }
01739 
01740 void XMLProgParser::start_pointertype(const char **attr)
01741 {
01742     if (phase == 1) {
01743         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01744         return;
01745     }
01746     stack.front()->type = new PointerType(NULL);
01747     addId(attr, stack.front()->type);
01748 }
01749 
01750 void XMLProgParser::addToContext_pointertype(Context *c, int e)
01751 {
01752     PointerType *p = dynamic_cast<PointerType*>(c->type);
01753     assert(p);
01754     if (phase == 1) {
01755         return;
01756     }
01757     p->setPointsTo(stack.front()->type);
01758 }
01759 
01760 void XMLProgParser::start_chartype(const char **attr)
01761 {
01762     if (phase == 1) {
01763         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01764         return;
01765     }
01766     stack.front()->type = new CharType();
01767     addId(attr, stack.front()->type);
01768 }
01769 
01770 void XMLProgParser::addToContext_chartype(Context *c, int e)
01771 {
01772 //    switch(e) {
01773 //  default:
01774         if (e == e_unknown)
01775             std::cerr << "unknown tag " << e << " in context charType\n";
01776         else 
01777             std::cerr << "need to handle tag " << tags[e].tag << " in context charType\n";
01778 //  break;
01779 //    }
01780 }
01781 
01782 void XMLProgParser::start_namedtype(const char **attr)
01783 {
01784     if (phase == 1) {
01785         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01786         return;
01787     }
01788     stack.front()->type = new NamedType(getAttr(attr, "name"));
01789     addId(attr, stack.front()->type);
01790 }
01791 
01792 void XMLProgParser::addToContext_namedtype(Context *c, int e)
01793 {
01794 //    switch(e) {
01795 //  default:
01796         if (e == e_unknown)
01797             std::cerr << "unknown tag " << e << " in context namedType\n";
01798         else 
01799             std::cerr << "need to handle tag " << tags[e].tag << " in context namedType\n";
01800 //  break;
01801 //    }
01802 }
01803 
01804 void XMLProgParser::start_arraytype(const char **attr)
01805 {
01806     if (phase == 1) {
01807         stack.front()->type = (Type*)findId(getAttr(attr, "id"));
01808         return;
01809     }
01810     ArrayType *a = new ArrayType();
01811     stack.front()->type = a;
01812     addId(attr, a);
01813     const char *len = getAttr(attr, "length");
01814     if (len)
01815         a->length = atoi(len);
01816 }
01817 
01818 void XMLProgParser::addToContext_arraytype(Context *c, int e)
01819 {
01820     ArrayType *a = dynamic_cast<ArrayType*>(c->type);
01821     assert(a);
01822     switch(e) {
01823         case e_basetype:
01824             a->base_type = stack.front()->type;
01825             break;
01826         default:
01827             if (e == e_unknown)
01828                 std::cerr << "unknown tag " << e << " in context arrayType\n";
01829             else 
01830                 std::cerr << "need to handle tag " << tags[e].tag << " in context arrayType\n";
01831             break;
01832     }
01833 }
01834 
01835 void XMLProgParser::start_location(const char **attr)
01836 {
01837     if (phase == 1) {
01838         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
01839         UserProc *p = (UserProc*)findId(getAttr(attr, "proc"));
01840         if (p)
01841             ((Location*)stack.front()->exp)->setProc(p);
01842         return;
01843     }
01844     OPER op = (OPER)operFromString(getAttr(attr, "op"));
01845     assert(op != -1);
01846     stack.front()->exp = new Location(op);
01847     addId(attr, stack.front()->exp);
01848 }
01849 
01850 void XMLProgParser::addToContext_location(Context *c, int e)
01851 {
01852     if (phase == 1) {
01853         return;
01854     }
01855     Location *l = dynamic_cast<Location*>(c->exp);
01856     assert(l);
01857     switch(e) {
01858         case e_subexp1:
01859             c->exp->setSubExp1(stack.front()->exp);
01860             break;
01861         default:
01862             if (e == e_unknown)
01863                 std::cerr << "unknown tag " << e << " in context unary\n";
01864             else 
01865                 std::cerr << "need to handle tag " << tags[e].tag << " in context location\n";
01866         break;
01867     }
01868 }
01869 
01870 void XMLProgParser::start_unary(const char **attr)
01871 {
01872     if (phase == 1) {
01873         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
01874         return;
01875     }
01876     OPER op = (OPER)operFromString(getAttr(attr, "op"));
01877     assert(op != -1);
01878     stack.front()->exp = new Unary(op);
01879     addId(attr, stack.front()->exp);
01880 }
01881 
01882 void XMLProgParser::addToContext_unary(Context *c, int e)
01883 {
01884     if (phase == 1) {
01885         return;
01886     }
01887     switch(e) {
01888         case e_subexp1:
01889             c->exp->setSubExp1(stack.front()->exp);
01890             break;
01891         default:
01892             if (e == e_unknown)
01893             std::cerr << "unknown tag " << e << " in context unary\n";
01894             else 
01895             std::cerr << "need to handle tag " << tags[e].tag << " in context unary\n";
01896         break;
01897     }
01898 }
01899 
01900 void XMLProgParser::start_binary(const char **attr)
01901 {
01902     if (phase == 1) {
01903         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
01904         return;
01905     }
01906     OPER op = (OPER)operFromString(getAttr(attr, "op"));
01907     assert(op != -1);
01908     stack.front()->exp = new Binary(op);
01909     addId(attr, stack.front()->exp);
01910 }
01911 
01912 void XMLProgParser::addToContext_binary(Context *c, int e)
01913 {
01914     if (phase == 1) {
01915         return;
01916     }
01917     switch(e) {
01918         case e_subexp1:
01919             c->exp->setSubExp1(stack.front()->exp);
01920             break;
01921         case e_subexp2:
01922             c->exp->setSubExp2(stack.front()->exp);
01923             break;
01924         default:
01925             if (e == e_unknown)
01926             std::cerr << "unknown tag " << e << " in context binary\n";
01927             else 
01928             std::cerr << "need to handle tag " << tags[e].tag << " in context binary\n";
01929         break;
01930     }
01931 }
01932 
01933 void XMLProgParser::start_ternary(const char **attr)
01934 {
01935     if (phase == 1) {
01936         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
01937         return;
01938     }
01939     OPER op = (OPER)operFromString(getAttr(attr, "op"));
01940     assert(op != -1);
01941     stack.front()->exp = new Ternary(op);
01942     addId(attr, stack.front()->exp);
01943 }
01944 
01945 void XMLProgParser::addToContext_ternary(Context *c, int e)
01946 {
01947     if (phase == 1) {
01948         return;
01949     }
01950     switch(e) {
01951         case e_subexp1:
01952             c->exp->setSubExp1(stack.front()->exp);
01953             break;
01954         case e_subexp2:
01955             c->exp->setSubExp2(stack.front()->exp);
01956             break;
01957         case e_subexp3:
01958             c->exp->setSubExp3(stack.front()->exp);
01959             break;
01960         default:
01961             if (e == e_unknown)
01962                 std::cerr << "unknown tag " << e << " in context ternary\n";
01963             else 
01964                 std::cerr << "need to handle tag " << tags[e].tag << " in context ternary\n";
01965         break;
01966     }
01967 }
01968 
01969 void XMLProgParser::start_const(const char **attr)
01970 {
01971     if (phase == 1) {
01972         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
01973         return;
01974     }
01975     double d;
01976     const char *value = getAttr(attr, "value");
01977     const char *opstring = getAttr(attr, "op");
01978     assert(value);
01979     assert(opstring);
01980     //std::cerr << "got value=" << value << " opstring=" << opstring << "\n";
01981     OPER op = (OPER)operFromString(opstring);
01982     assert(op != -1);
01983     switch(op) {
01984         case opIntConst:
01985             stack.front()->exp = new Const(atoi(value));
01986             addId(attr, stack.front()->exp);
01987             break;
01988         case opStrConst:
01989             stack.front()->exp = new Const(strdup(value));
01990             addId(attr, stack.front()->exp);
01991             break;
01992         case opFltConst:
01993             sscanf(value, "%lf", &d);
01994             stack.front()->exp = new Const(d);
01995             addId(attr, stack.front()->exp);
01996             break;
01997         default:
01998             LOG << "unknown Const op " << op << "\n";
01999             assert(false);
02000     }
02001     //std::cerr << "end of start const\n";
02002 }
02003 
02004 void XMLProgParser::addToContext_const(Context *c, int e)
02005 {
02006 //    switch(e) {
02007 //  default:
02008         if (e == e_unknown)
02009             std::cerr << "unknown tag " << e << " in context const\n";
02010         else 
02011             std::cerr << "need to handle tag " << tags[e].tag << " in context const\n";
02012 //  break;
02013 //    }
02014 }
02015 
02016 void XMLProgParser::start_terminal(const char **attr)
02017 {
02018     if (phase == 1) {
02019         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
02020         return;
02021     }
02022     OPER op = (OPER)operFromString(getAttr(attr, "op"));
02023     assert(op != -1);
02024     stack.front()->exp = new Terminal(op);
02025     addId(attr, stack.front()->exp);
02026 }
02027 
02028 void XMLProgParser::addToContext_terminal(Context *c, int e)
02029 {
02030 //    switch(e) {
02031 //  default:
02032         if (e == e_unknown)
02033             std::cerr << "unknown tag " << e << " in context terminal\n";
02034         else 
02035             std::cerr << "need to handle tag " << tags[e].tag << " in context terminal\n";
02036 //  break;
02037 //    }
02038 }
02039 
02040 void XMLProgParser::start_typedexp(const char **attr)
02041 {
02042     if (phase == 1) {
02043         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
02044         return;
02045     }
02046     stack.front()->exp = new TypedExp();
02047     addId(attr, stack.front()->exp);
02048 }
02049 
02050 void XMLProgParser::addToContext_typedexp(Context *c, int e)
02051 {
02052     TypedExp *t = dynamic_cast<TypedExp*>(c->exp);
02053     assert(t);
02054     switch(e) {
02055         case e_type:
02056             t->type = stack.front()->type;
02057             break;
02058         case e_subexp1:
02059             c->exp->setSubExp1(stack.front()->exp);
02060             break;
02061         default:
02062             if (e == e_unknown)
02063                 std::cerr << "unknown tag " << e << " in context typedexp\n";
02064             else 
02065                 std::cerr << "need to handle tag " << tags[e].tag << " in context typedexp\n";
02066             break;
02067     }
02068 }
02069 
02070 void XMLProgParser::start_refexp(const char **attr)
02071 {
02072     if (phase == 1) {
02073         stack.front()->exp = (Exp*)findId(getAttr(attr, "id"));
02074         RefExp *r = dynamic_cast<RefExp*>(stack.front()->exp);
02075         assert(r);
02076         r->def = (Statement*)findId(getAttr(attr, "def"));
02077         return;
02078     }
02079     stack.front()->exp = new RefExp();
02080     addId(attr, stack.front()->exp);
02081 }
02082 
02083 void XMLProgParser::addToContext_refexp(Context *c, int e)
02084 {
02085     switch(e) {
02086         case e_subexp1:
02087             c->exp->setSubExp1(stack.front()->exp);
02088             break;
02089         default:
02090             if (e == e_unknown)
02091                 std::cerr << "unknown tag " << e << " in context refexp\n";
02092             else 
02093                 std::cerr << "need to handle tag " << tags[e].tag << " in context refexp\n";
02094             break;
02095     }
02096 }
02097 
02098 void XMLProgParser::start_def(const char **attr)
02099 {
02100     if (phase == 1) {
02101         stack.front()->stmt = (Statement*)findId(getAttr(attr, "stmt"));
02102         return;
02103     }
02104 }
02105 
02106 void XMLProgParser::addToContext_def(Context *c, int e)
02107 {
02108 //    switch(e) {
02109 //  default:
02110         if (e == e_unknown)
02111             std::cerr << "unknown tag " << e << " in context def\n";
02112         else 
02113             std::cerr << "need to handle tag " << tags[e].tag << " in context def\n";
02114 //      break;
02115 //    }
02116 }
02117 
02118 Prog *XMLProgParser::parse(const char *filename)
02119 {
02120     FILE *f = fopen(filename, "r");
02121     if (f == NULL)
02122         return NULL;
02123     fclose(f);
02124 
02125     stack.clear();
02126     Prog *prog = NULL;
02127     for (phase = 0; phase < 2; phase++) {
02128         parseFile(filename);
02129         if (stack.front()->prog) {
02130             prog = stack.front()->prog;
02131             parseChildren(prog->getRootCluster());
02132         }
02133     }
02134     if (prog == NULL)
02135         return NULL;
02136     //FrontEnd *pFE = FrontEnd::Load(prog->getPath(), prog);        // Path is usually empty!?
02137     FrontEnd *pFE = FrontEnd::Load(prog->getPathAndName(), prog);
02138     prog->setFrontEnd(pFE);
02139     return prog;
02140 }
02141 
02142 void XMLProgParser::parseFile(const char *filename)
02143 {
02144     FILE *f = fopen(filename, "r");
02145     if (f == NULL)
02146         return;
02147     XML_Parser p = XML_ParserCreate(NULL);
02148     if (! p) {
02149         fprintf(stderr, "Couldn't allocate memory for parser\n");
02150         return;
02151     }
02152 
02153     XML_SetUserData(p, this);
02154     XML_SetElementHandler(p, start, end);
02155     XML_SetCharacterDataHandler(p, text);
02156 
02157     char Buff[8192];
02158 
02159     for (;;) {
02160         int done;
02161         int len;
02162 
02163         len = fread(Buff, 1, sizeof(Buff), f);
02164         if (ferror(f)) {
02165             fprintf(stderr, "Read error\n");
02166             fclose(f);
02167             return;
02168         }
02169         done = feof(f);
02170 
02171         if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) {
02172             if (XML_GetErrorCode(p) != XML_ERROR_NO_ELEMENTS)
02173                 fprintf(stderr, "Parse error at line %d of file %s:\n%s\n", XML_GetCurrentLineNumber(p), filename,
02174                     XML_ErrorString(XML_GetErrorCode(p)));
02175             fclose(f);
02176             return;
02177         }
02178 
02179         if (done)
02180             break;
02181     }
02182     fclose(f);
02183 }
02184 
02185 void XMLProgParser::parseChildren(Cluster *c)
02186 {
02187     std::string path = c->makeDirs();
02188     for (unsigned i = 0; i < c->children.size(); i++) {
02189         std::string d = path + "/" + c->children[i]->getName() + ".xml";
02190         parseFile(d.c_str());
02191         parseChildren(c->children[i]);
02192     }
02193 }
02194 
02195 extern char* operStrings[];
02196 
02197 int XMLProgParser::operFromString(const char *s)
02198 {
02199     for (int i = 0; i < opNumOf; i++)
02200     if (!strcmp(s, operStrings[i]))
02201         return i;
02202     return -1;
02203 }
02204 
02205 
02206 void XMLProgParser::persistToXML(std::ostream &out, Cluster *c)
02207 {
02208     out << "<cluster id=\"" << (int)c << "\" name=\"" << c->name << "\"";
02209     out << ">\n";
02210     for (unsigned i = 0; i < c->children.size(); i++) {
02211         persistToXML(out, c->children[i]);
02212     }
02213     out << "</cluster>\n";
02214 }
02215 
02216 void XMLProgParser::persistToXML(std::ostream &out, Global *g)
02217 {
02218     out << "<global name=\"" << g->nam << "\" uaddr=\"" << (int)g->uaddr << "\">\n";
02219     out << "<type>\n";
02220     persistToXML(out, g->type);
02221     out << "</type>\n";
02222     out << "</global>\n";
02223 }
02224 
02225 void XMLProgParser::persistToXML(Prog *prog)
02226 {
02227     prog->m_rootCluster->openStreams("xml");
02228     std::ofstream &os = prog->m_rootCluster->getStream();
02229     os << "<prog path=\"" << prog->getPath() << "\" name=\"" << prog->getName() << "\" iNumberedProc=\"" <<
02230         prog->m_iNumberedProc << "\">\n";
02231     for (std::set<Global*>::iterator it1 = prog->globals.begin(); it1 != prog->globals.end(); it1++)
02232         persistToXML(os, *it1);
02233     persistToXML(os, prog->m_rootCluster);
02234     for (std::list<Proc*>::iterator it = prog->m_procs.begin(); it != prog->m_procs.end(); it++) {
02235         Proc *p = *it;
02236         persistToXML(p->getCluster()->getStream(), p);
02237     }
02238     os << "</prog>\n";
02239     os.close();
02240     prog->m_rootCluster->closeStreams();
02241 }
02242 
02243 void XMLProgParser::persistToXML(std::ostream &out, LibProc *proc)
02244 {
02245     out << "<libproc id=\"" << (int)proc << "\" address=\"" << (int)proc->address << "\"";
02246     out << " firstCallerAddress=\"" << proc->m_firstCallerAddr << "\"";
02247     if (proc->m_firstCaller)
02248         out << " firstCaller=\"" << (int)proc->m_firstCaller << "\"";
02249     if (proc->cluster)
02250         out << " cluster=\"" << (int)proc->cluster << "\"";
02251     out << ">\n";
02252 
02253     persistToXML(out, proc->signature);
02254 
02255     for (std::set<CallStatement*>::iterator it = proc->callerSet.begin(); it != proc->callerSet.end(); it++)
02256         out << "<caller call=\"" << (int)(*it) << "\"/>\n";
02257     for (std::map<Exp*, Exp*, lessExpStar>::iterator it = proc->provenTrue.begin(); it != proc->provenTrue.end(); it++)
02258     {
02259         out << "<proven_true>\n";
02260         persistToXML(out, it->first);
02261         persistToXML(out, it->second);
02262         out << "</proven_true>\n";
02263     }
02264     out << "</libproc>\n";
02265 }
02266 
02267 void XMLProgParser::persistToXML(std::ostream &out, UserProc *proc)
02268 {
02269     out << "<userproc id=\"" << (int)proc << "\"";
02270     out << " address=\"" << (int)proc->address << "\"";
02271     out << " status=\"" << (int)proc->status << "\"";
02272     out << " firstCallerAddress=\"" << proc->m_firstCallerAddr << "\"";
02273     if (proc->m_firstCaller)
02274         out << " firstCaller=\"" << (int)proc->m_firstCaller << "\"";
02275     if (proc->cluster)
02276         out << " cluster=\"" << (int)proc->cluster << "\"";
02277     if (proc->theReturnStatement)
02278         out << " retstmt=\"" << (int)proc->theReturnStatement << "\"";
02279     out << ">\n";
02280 
02281     persistToXML(out, proc->signature);
02282 
02283     for (std::set<CallStatement*>::iterator it = proc->callerSet.begin(); it != proc->callerSet.end(); it++)
02284         out << "<caller call=\"" << (int)(*it) << "\"/>\n";
02285     for (std::map<Exp*, Exp*, lessExpStar>::iterator it = proc->provenTrue.begin(); it != proc->provenTrue.end(); it++)
02286     {
02287         out << "<proven_true>\n";
02288         persistToXML(out, it->first);
02289         persistToXML(out, it->second);
02290         out << "</proven_true>\n";
02291     }
02292 
02293     for (std::map<std::string, Type*>::iterator it1 = proc->locals.begin(); it1 != proc->locals.end(); it1++) {
02294         out << "<local name=\"" << (*it1).first << "\">\n";
02295         out << "<type>\n";
02296         persistToXML(out, (*it1).second);
02297         out << "</type>\n";
02298         out << "</local>\n";
02299     }
02300 
02301     for (std::multimap<Exp*, Exp*, lessExpStar>::iterator it2 = proc->symbolMap.begin(); it2 != proc->symbolMap.end(); it2++)
02302     {
02303         out << "<symbol>\n";
02304         out << "<exp>\n";
02305         persistToXML(out, (*it2).first);
02306         out << "</exp>\n";
02307         out << "<secondexp>\n";
02308         persistToXML(out, (*it2).second);
02309         out << "</secondexp>\n";
02310         out << "</symbol>\n";
02311     }
02312 
02313 
02314     for (std::list<Proc*>::iterator it = proc->calleeList.begin(); it != proc->calleeList.end(); it++)
02315         out << "<callee proc=\"" << (int)(*it) << "\"/>\n";
02316 
02317     persistToXML(out, proc->cfg);
02318 
02319     out << "</userproc>\n";
02320 }
02321 
02322 void XMLProgParser::persistToXML(std::ostream &out, Proc *proc)
02323 {
02324     if (proc->isLib())
02325         persistToXML(out, (LibProc*)proc);
02326     else
02327         persistToXML(out, (UserProc*)proc);
02328 }
02329 
02330 void XMLProgParser::persistToXML(std::ostream &out, Signature *sig)
02331 {
02332     out << "<signature id=\"" << (int)sig << "\"";
02333     out << " name=\"" << sig->name << "\"";
02334     out << " ellipsis=\"" << (int)sig->ellipsis << "\"";
02335     out << " preferedName=\"" << sig->preferedName << "\"";
02336     if (sig->getPlatform() != PLAT_GENERIC)
02337         out << " platform=\"" << sig->platformName(sig->getPlatform()) << "\"";
02338     if (sig->getConvention() != CONV_NONE)
02339         out << " convention=\"" << sig->conventionName(sig->getConvention()) << "\"";
02340     out << ">\n";
02341     for (unsigned i = 0; i < sig->params.size(); i++) {
02342         out << "<param id=\"" << (int)sig->params[i] << "\" name=\"" << sig->params[i]->getName() << "\">\n";
02343         out << "<type>\n";
02344         persistToXML(out, sig->params[i]->getType());
02345         out << "</type>\n";
02346         out << "<exp>\n";
02347         persistToXML(out, sig->params[i]->getExp());
02348         out << "</exp>\n";
02349         out << "</param>\n";
02350     }
02351     for (Returns::iterator rr = sig->returns.begin(); rr != sig->returns.end(); ++rr) {
02352         out << "<return>\n";
02353         out << "<type>\n";
02354         persistToXML(out, (*rr)->type);
02355         out << "</type>\n";
02356         out << "<exp>\n";
02357         persistToXML(out, (*rr)->exp);
02358         out << "</exp>\n";
02359         out << "</return>\n";
02360     }
02361     if (sig->rettype) {
02362         out << "<rettype>\n";
02363         persistToXML(out, sig->rettype);
02364         out << "</rettype>\n";
02365     }
02366     if (sig->preferedReturn) {
02367         out << "<prefreturn>\n";
02368         persistToXML(out, sig->preferedReturn);
02369         out << "</prefreturn>\n";
02370     }
02371     for (unsigned i = 0; i < sig->preferedParams.size(); i++)
02372         out << "<prefparam index=\"" << sig->preferedParams[i] << "\"/>\n";
02373     out << "</signature>\n";
02374 }
02375 
02376 
02377 void XMLProgParser::persistToXML(std::ostream &out, Type *ty)
02378 {
02379     VoidType *v = dynamic_cast<VoidType*>(ty);
02380     if (v) { 
02381         out << "<voidtype id=\"" << (int)ty << "\"/>\n";
02382         return;
02383     }
02384     FuncType *f = dynamic_cast<FuncType*>(ty);
02385     if (f) {
02386         out << "<functype id=\"" << (int)ty << "\">\n";
02387         persistToXML(out, f->signature);
02388         out << "</functype>\n";
02389         return;
02390     }
02391     IntegerType *i = dynamic_cast<IntegerType*>(ty);
02392     if (i) {
02393         out << "<integertype id=\"" << (int)ty << "\" size=\"" << i->size << "\" signedness=\"" << i->signedness <<
02394             "\"/>\n";
02395         return;
02396     }
02397     FloatType *fl = dynamic_cast<FloatType*>(ty);
02398     if (fl) {
02399         out << "<floattype id=\"" << (int)ty << "\" size=\"" << fl->size << "\"/>\n";
02400         return;
02401     }
02402     BooleanType *b = dynamic_cast<BooleanType*>(ty);
02403     if (b) {
02404         out << "<booleantype id=\"" << (int)ty << "\"/>\n";
02405         return;
02406     }
02407     CharType *c = dynamic_cast<CharType*>(ty);
02408     if (c) {
02409         out << "<chartype id=\"" << (int)ty << "\"/>\n";
02410         return;
02411     }
02412     PointerType *p = dynamic_cast<PointerType*>(ty);
02413     if (p) {
02414         out << "<pointertype id=\"" << (int)ty << "\">\n";
02415         persistToXML(out, p->points_to);
02416         out << "</pointertype>\n";
02417         return;
02418     }
02419     ArrayType *a = dynamic_cast<ArrayType*>(ty);
02420     if (a) {
02421         out << "<arraytype id=\"" << (int)ty << "\" length=\"" << (int)a->length << "\">\n";
02422         out << "<basetype>\n";
02423         persistToXML(out, a->base_type);
02424         out << "</basetype>\n";
02425         out << "</arraytype>\n";
02426         return;
02427     }
02428     NamedType *n = dynamic_cast<NamedType*>(ty);
02429     if (n) {
02430         out << "<namedtype id=\"" << (int)ty << "\" name=\"" << n->name << "\"/>\n";
02431         return;
02432     }
02433     CompoundType *co = dynamic_cast<CompoundType*>(ty);
02434     if (co) {
02435         out << "<compoundtype id=\"" << (int)ty << "\">\n";
02436         for (unsigned i = 0; i < co->names.size(); i++) {
02437             out << "<member name=\"" << co->names[i] << "\">\n";
02438             persistToXML(out, co->types[i]);
02439             out << "</member>\n";
02440         }
02441         out << "</compoundtype>\n";
02442         return;
02443     }
02444     SizeType *sz = dynamic_cast<SizeType*>(ty);
02445     if (sz) {
02446         out << "<sizetype id=\"" << (int)ty << "\" size=\"" << sz->getSize() << "\"/>\n";
02447         return;
02448     }
02449     std::cerr << "unknown type in persistToXML\n";
02450     assert(false);
02451 }
02452 
02453 void XMLProgParser::persistToXML(std::ostream &out, Exp *e)
02454 {
02455     TypeVal *t = dynamic_cast<TypeVal*>(e);
02456     if (t) {
02457         out << "<typeval id=\"" << (int)e << "\" op=\"" << operStrings[t->op] << "\">\n";
02458         out << "<type>\n";
02459         persistToXML(out, t->val);
02460         out << "</type>\n";
02461         out << "</typeval>\n";
02462         return;
02463     } 
02464     Terminal *te = dynamic_cast<Terminal*>(e);
02465     if (te) {
02466         out << "<terminal id=\"" << (int)e << "\" op=\"" << operStrings[te->op] << "\"/>\n";
02467         return;
02468     } 
02469     Const *c = dynamic_cast<Const*>(e);
02470     if (c) {
02471         out << "<const id=\"" << (int)e << "\" op=\"" << operStrings[c->op] << "\"";
02472         out << " conscript=\"" << c->conscript << "\"";
02473         if (c->op == opIntConst)
02474             out << " value=\"" << c->u.i << "\"";
02475         else if (c->op == opFuncConst) 
02476             out << " value=\"" << c->u.a << "\"";
02477         else if (c->op == opFltConst)
02478             out << " value=\"" << c->u.d << "\"";
02479         else if (c->op == opStrConst)
02480             out << " value=\"" << c->u.p << "\"";
02481         else { 
02482             // TODO
02483             // QWord ll;
02484             // Proc* pp;
02485             assert(false);
02486         }
02487         out << "/>\n";
02488         return;
02489     } 
02490     Location *l = dynamic_cast<Location*>(e);
02491     if (l) {
02492         out << "<location id=\"" << (int)e << "\"";
02493         if (l->proc)
02494             out << " proc=\"" << (int)l->proc << "\"";
02495         out << " op=\"" << operStrings[l->op] << "\">\n";
02496         out << "<subexp1>\n";
02497         persistToXML(out, l->subExp1);
02498         out << "</subexp1>\n";
02499         out << "</location>\n";
02500         return;
02501     } 
02502     RefExp *r = dynamic_cast<RefExp*>(e);
02503     if (r) {
02504         out << "<refexp id=\"" << (int)e << "\"";
02505         if (r->def)
02506             out << " def=\"" << (int)r->def << "\"";
02507         out << " op=\"" << operStrings[r->op] << "\">\n";
02508         out << "<subexp1>\n";
02509         persistToXML(out, r->subExp1);
02510         out << "</subexp1>\n";
02511         out << "</refexp>\n";
02512         return;
02513     }
02514     FlagDef *f = dynamic_cast<FlagDef*>(e);
02515     if (f) {
02516         out << "<flagdef id=\"" << (int)e << "\"";
02517         if (f->rtl)
02518             out << " rtl=\"" << (int)f->rtl << "\"";
02519         out << " op=\"" << operStrings[f->op] << "\">\n";
02520         out << "<subexp1>\n";
02521         persistToXML(out, f->subExp1);
02522         out << "</subexp1>\n";
02523         out << "</flagdef>\n";
02524         return;
02525     }
02526     TypedExp *ty = dynamic_cast<TypedExp*>(e);
02527     if (ty) {
02528         out << "<typedexp id=\"" << (int)e << "\" op=\"" << operStrings[ty->op] << "\">\n";
02529         out << "<subexp1>\n";
02530         persistToXML(out, ty->subExp1);
02531         out << "</subexp1>\n";
02532         out << "<type>\n";
02533         persistToXML(out, ty->type);
02534         out << "</type>\n";
02535         out << "</typedexp>\n";
02536             return;
02537     }
02538     Ternary *tn = dynamic_cast<Ternary*>(e);
02539     if (tn) {
02540         out << "<ternary id=\"" << (int)e << "\" op=\"" << operStrings[tn->op] << "\">\n";
02541         out << "<subexp1>\n";
02542         persistToXML(out, tn->subExp1);
02543         out << "</subexp1>\n";
02544         out << "<subexp2>\n";
02545         persistToXML(out, tn->subExp2);
02546         out << "</subexp2>\n";
02547         out << "<subexp3>\n";
02548         persistToXML(out, tn->subExp3);
02549         out << "</subexp3>\n";
02550         out << "</ternary>\n";
02551         return;
02552     }
02553     Binary *b = dynamic_cast<Binary*>(e);
02554     if (b) {
02555         out << "<binary id=\"" << (int)e << "\" op=\"" << operStrings[b->op] << "\">\n";
02556         out << "<subexp1>\n";
02557         persistToXML(out, b->subExp1);
02558         out << "</subexp1>\n";
02559         out << "<subexp2>\n";
02560         persistToXML(out, b->subExp2);
02561         out << "</subexp2>\n";
02562         out << "</binary>\n";
02563         return;
02564     }
02565     Unary *u = dynamic_cast<Unary*>(e);
02566     if (u) {
02567         out << "<unary id=\"" << (int)e << "\" op=\"" << operStrings[u->op] << "\">\n";
02568         out << "<subexp1>\n";
02569         persistToXML(out, u->subExp1);
02570         out << "</subexp1>\n";
02571         out << "</unary>\n";
02572         return;
02573     }
02574     std::cerr << "unknown exp in persistToXML\n";
02575     assert(false);
02576 }
02577 
02578 void XMLProgParser::persistToXML(std::ostream &out, Cfg *cfg)
02579 {
02580     out << "<cfg id=\"" << (int)cfg << "\" wellformed=\"" << (int)cfg->m_bWellFormed << "\" lastLabel=\"" <<
02581         cfg->lastLabel << "\"";
02582     out << " entryBB=\"" << (int)cfg->entryBB << "\"";
02583     out << " exitBB=\"" << (int)cfg->exitBB << "\"";
02584     out << ">\n";
02585 
02586     for (std::list<PBB>::iterator it = cfg->m_listBB.begin(); it != cfg->m_listBB.end(); it++)
02587         persistToXML(out, *it);
02588 
02589     for (unsigned i = 0; i < cfg->Ordering.size(); i++)
02590         out << "<order bb=\"" << (int)cfg->Ordering[i] << "\"/>\n";
02591 
02592     for (unsigned i = 0; i < cfg->revOrdering.size(); i++)
02593         out << "<revorder bb=\"" << (int)cfg->revOrdering[i] << "\"/>\n";
02594 
02595     // TODO
02596     // MAPBB m_mapBB;
02597     // std::set<CallStatement*> callSites;
02598     // std::vector<PBB> BBs;               // Pointers to BBs from indices
02599     // std::map<PBB, int> indices;         // Indices from pointers to BBs
02600     // more
02601     out << "</cfg>\n";
02602 }
02603 
02604 void XMLProgParser::persistToXML(std::ostream &out, BasicBlock *bb)
02605 {
02606     out << "<bb id=\"" << (int)bb << "\" nodeType=\"" << bb->m_nodeType << "\" labelNum=\"" << bb->m_iLabelNum 
02607     << "\" label=\"" << bb->m_labelStr << "\" labelneeded=\"" << (int)bb->m_labelneeded << "\""
02608     << " incomplete=\"" << (int)bb->m_bIncomplete << "\" jumpreqd=\"" << (int)bb->m_bJumpReqd << "\" m_traversed=\"" <<
02609         bb->m_iTraversed << "\"";
02610     out << " DFTfirst=\"" << bb->m_DFTfirst << "\" DFTlast=\"" << bb->m_DFTlast << "\" DFTrevfirst=\"" <<
02611         bb->m_DFTrevfirst << "\" DFTrevlast=\"" << bb->m_DFTrevlast << "\"";
02612     out << " structType=\"" << bb->m_structType << "\"";
02613     out << " loopCondType=\"" << bb->m_loopCondType << "\"";
02614     if (bb->m_loopHead)
02615         out << " m_loopHead=\"" << (int)bb->m_loopHead << "\"";
02616     if (bb->m_caseHead)
02617         out << " m_caseHead=\"" << (int)bb->m_caseHead << "\"";
02618     if (bb->m_condFollow)
02619         out << " m_condFollow=\"" << (int)bb->m_condFollow << "\"";
02620     if (bb->m_loopFollow)
02621         out << " m_loopFollow=\"" << (int)bb->m_loopFollow << "\"";
02622     if (bb->m_latchNode)
02623         out << " m_latchNode=\"" << (int)bb->m_latchNode << "\"";
02624     out << " ord=\"" << bb->ord << "\"";
02625     out << " revOrd=\"" << bb->revOrd << "\"";
02626     out << " inEdgesVisited=\"" << bb->inEdgesVisited << "\"";
02627     out << " numForwardInEdges=\"" << bb->numForwardInEdges << "\"";
02628     out << " loopStamp1=\"" << bb->loopStamps[0] << "\"";
02629     out << " loopStamp2=\"" << bb->loopStamps[1] << "\"";
02630     out << " revLoopStamp1=\"" << bb->revLoopStamps[0] << "\"";
02631     out << " revLoopStamp2=\"" << bb->revLoopStamps[1] << "\"";
02632     out << " traversed=\"" << (int)bb->traversed << "\"";
02633     out << " hllLabel=\"" << (int)bb->hllLabel << "\"";
02634     if (bb->labelStr)
02635         out << " labelStr=\"" << bb->labelStr << "\"";
02636     out << " indentLevel=\"" << bb->indentLevel << "\"";
02637     // note the rediculous duplication here
02638     if (bb->immPDom)
02639         out << " immPDom=\"" << (int)bb->immPDom << "\"";
02640     if (bb->loopHead)
02641         out << " loopHead=\"" << (int)bb->loopHead << "\"";
02642     if (bb->caseHead)
02643         out << " caseHead=\"" << (int)bb->caseHead << "\"";
02644     if (bb->condFollow)
02645         out << " condFollow=\"" << (int)bb->condFollow << "\"";
02646     if (bb->loopFollow)
02647         out << " loopFollow=\"" << (int)bb->loopFollow << "\"";
02648     if (bb->latchNode)
02649     out << " latchNode=\"" << (int)bb->latchNode << "\"";
02650     out << " sType=\"" << (int)bb->sType << "\"";
02651     out << " usType=\"" << (int)bb->usType << "\"";
02652     out << " lType=\"" << (int)bb->lType << "\"";
02653     out << " cType=\"" << (int)bb->cType << "\"";
02654     out << ">\n";
02655 
02656     for (unsigned i = 0; i < bb->m_InEdges.size(); i++)
02657     out << "<inedge bb=\"" << (int)bb->m_InEdges[i] << "\"/>\n";
02658     for (unsigned i = 0; i < bb->m_OutEdges.size(); i++)
02659     out << "<outedge bb=\"" << (int)bb->m_OutEdges[i] << "\"/>\n";
02660 
02661     LocationSet::iterator it;
02662     for (it = bb->liveIn.begin(); it != bb->liveIn.end(); it++) {
02663         out << "<livein>\n";
02664         persistToXML(out, *it);
02665         out << "</livein>\n";
02666     }
02667 
02668     if (bb->m_pRtls) {
02669     for (std::list<RTL*>::iterator it = bb->m_pRtls->begin(); it != bb->m_pRtls->end(); it++)
02670         persistToXML(out, *it);
02671     }
02672     out << "</bb>\n";
02673 }
02674 
02675 void XMLProgParser::persistToXML(std::ostream &out, RTL *rtl)
02676 {
02677     out << "<rtl id=\"" << (int)rtl << "\" addr=\"" << (int)rtl->nativeAddr << "\">\n";
02678     for (std::list<Statement*>::iterator it = rtl->stmtList.begin(); it != rtl->stmtList.end(); it++) {
02679         out << "<stmt>\n";
02680         persistToXML(out, *it);
02681         out << "</stmt>\n";
02682     }
02683     out << "</rtl>\n";
02684 }
02685 
02686 void XMLProgParser::persistToXML(std::ostream &out, Statement *stmt)
02687 {
02688     BoolAssign *b = dynamic_cast<BoolAssign*>(stmt);
02689     if (b) {
02690         out << "<boolasgn id=\"" << (int)stmt << "\" number=\"" << b->number << "\"";
02691         if (b->parent)
02692             out << " parent=\"" << (int)b->parent << "\"";
02693         if (b->proc)
02694             out << " proc=\"" << (int)b->proc << "\"";
02695         out << " jtcond=\"" << b->jtCond << "\"";
02696         out << " float=\"" << (int)b->bFloat << "\"";
02697         out << " size=\"" << b->size << "\"";
02698         out << ">\n";
02699         if (b->pCond) {
02700             out << "<cond>\n";
02701             persistToXML(out, b->pCond);
02702             out << "</cond>\n";
02703         }
02704         out << "</boolasgn>\n";
02705         return;
02706     }
02707     ReturnStatement *r = dynamic_cast<ReturnStatement*>(stmt);
02708     if (r) {
02709         out << "<returnstmt id=\"" << (int)stmt << "\" number=\"" << r->number << "\"";
02710         if (r->parent)
02711             out << " parent=\"" << (int)r->parent << "\"";
02712         if (r->proc)
02713             out << " proc=\"" << (int)r->proc << "\"";
02714         out << " retAddr=\"" << (int)r->retAddr << "\"";
02715         out << ">\n";
02716 
02717         ReturnStatement::iterator rr;
02718         for (rr = r->modifieds.begin(); rr != r->modifieds.end(); ++rr) {
02719             out << "<modifieds>\n";
02720             persistToXML(out, *rr);
02721             out << "</modifieds>\n";
02722         }
02723         for (rr = r->returns.begin(); rr != r->returns.end(); ++rr) {
02724             out << "<returns>\n";
02725             persistToXML(out, *rr);
02726             out << "</returns>\n";
02727         }
02728 
02729         out << "</returnstmt>\n";
02730         return;
02731     }
02732     CallStatement *c = dynamic_cast<CallStatement*>(stmt);
02733     if (c) {
02734         out << "<callstmt id=\"" << (int)stmt << "\" number=\"" << c->number 
02735             << "\" computed=\"" << (int)c->m_isComputed << "\"";
02736         if (c->parent)
02737             out << " parent=\"" << (int)c->parent << "\"";
02738         if (c->proc)
02739             out << " proc=\"" << (int)c->proc << "\"";
02740         out << " returnAfterCall=\"" << (int)c->returnAfterCall << "\"";
02741         out << ">\n";
02742     
02743         if (c->pDest) {
02744             out << "<dest";
02745             if (c->procDest) 
02746                 out << " proc=\"" << (int)c->procDest << "\"";
02747             out << ">\n";
02748             persistToXML(out, c->pDest);
02749             out << "</dest>\n";
02750         }
02751     
02752         StatementList::iterator ss;
02753         for (ss = c->arguments.begin(); ss != c->arguments.end(); ++ss) {
02754             out << "<argument>\n";
02755             persistToXML(out, *ss);
02756             out << "</argument>\n";
02757         }
02758 
02759         for (ss = c->defines.begin(); ss != c->defines.end(); ++ss) {
02760             out << "<defines>\n";
02761             persistToXML(out, *ss);
02762             out << "</defines>\n";
02763         }
02764 
02765         out << "</callstmt>\n";
02766         return;
02767     }
02768     CaseStatement *ca = dynamic_cast<CaseStatement*>(stmt);
02769     if (ca) {
02770         out << "<casestmt id=\"" << (int)stmt << "\" number=\"" << ca->number 
02771             << "\" computed=\"" << (int)ca->m_isComputed << "\"";
02772         if (ca->parent)
02773             out << " parent=\"" << (int)ca->parent << "\"";
02774         if (ca->proc)
02775             out << " proc=\"" << (int)ca->proc << "\"";
02776         out << ">\n";
02777         if (ca->pDest) {
02778             out << "<dest>\n";
02779             persistToXML(out, ca->pDest);
02780             out << "</dest>\n";
02781         }
02782         // TODO
02783         // SWITCH_INFO* pSwitchInfo;   // Ptr to struct with info about the switch
02784         out << "</casestmt>\n";
02785         return;
02786     }
02787     BranchStatement *br = dynamic_cast<BranchStatement*>(stmt);
02788     if (br) {
02789         out << "<branchstmt id=\"" << (int)stmt << "\" number=\"" << br->number 
02790             << "\" computed=\"" << (int)br->m_isComputed << "\""
02791             << " jtcond=\"" << br->jtCond << "\" float=\"" << (int)br->bFloat << "\"";
02792         if (br->parent)
02793             out << " parent=\"" << (int)br->parent << "\"";
02794         if (br->proc)
02795             out << " proc=\"" << (int)br->proc << "\"";
02796         out << ">\n";
02797         if (br->pDest) {
02798             out << "<dest>\n";
02799             persistToXML(out, br->pDest);
02800             out << "</dest>\n";
02801         }
02802         if (br->pCond) {
02803             out << "<cond>\n";
02804             persistToXML(out, br->pCond);
02805             out << "</cond>\n";
02806         }
02807         out << "</branchstmt>\n";
02808         return;
02809     }
02810     GotoStatement *g = dynamic_cast<GotoStatement*>(stmt);
02811     if (g) {
02812         out << "<gotostmt id=\"" << (int)stmt << "\" number=\"" << g->number << "\""
02813             << " computed=\"" << (int) g->m_isComputed << "\"";
02814         if (g->parent)
02815             out << " parent=\"" << (int)g->parent << "\"";
02816         if (g->proc)
02817             out << " proc=\"" << (int)g->proc << "\"";
02818         out << ">\n";
02819         if (g->pDest) {
02820             out << "<dest>\n";
02821             persistToXML(out, g->pDest);
02822             out << "</dest>\n";
02823         }
02824         out << "</gotostmt>\n";
02825         return;
02826     }
02827     PhiAssign *p = dynamic_cast<PhiAssign*>(stmt);
02828     if (p) {
02829         out << "<phiassign id=\"" << (int)stmt << "\" number=\"" << p->number << "\"";
02830         if (p->parent)
02831             out << " parent=\"" << (int)p->parent << "\"";
02832         if (p->proc)
02833             out << " proc=\"" << (int)p->proc << "\"";
02834         out << ">\n";
02835         out << "<lhs>\n";
02836         persistToXML(out, p->lhs);
02837         out << "</lhs>\n";
02838         PhiAssign::iterator it;
02839         for (it = p->begin(); it != p->end(); p++)
02840             out << "<def stmt=\"" << (int)it->def << "\" exp=\"" << (int)it->e << "\" />\n";
02841         out << "</phiassign>\n";
02842         return;
02843     }
02844     Assign *a = dynamic_cast<Assign*>(stmt);
02845     if (a) {
02846         out << "<assign id=\"" << (int)stmt << "\" number=\"" << a->number << "\"";
02847         if (a->parent)
02848             out << " parent=\"" << (int)a->parent << "\"";
02849         if (a->proc)
02850             out << " proc=\"" << (int)a->proc << "\"";
02851         out << ">\n";
02852         out << "<lhs>\n";
02853         persistToXML(out, a->lhs);
02854         out << "</lhs>\n";
02855         out << "<rhs>\n";
02856         persistToXML(out, a->rhs);
02857         out << "</rhs>\n";
02858         if (a->type) {
02859             out << "<type>\n";
02860             persistToXML(out, a->type);
02861             out << "</type>\n";
02862         }
02863         if (a->guard) {
02864             out << "<guard>\n";
02865             persistToXML(out, a->guard);
02866             out << "/guard>\n";
02867         }
02868         out << "</assign>\n";
02869         return;
02870     }
02871     std::cerr << "unknown stmt in persistToXML\n";
02872     assert(false);
02873 }
02874 
02875 void XMLProgParser::addToContext_assignment(Context *c, int e)
02876 {
02877     c->stmt = stack.front()->stmt;
02878 }
02879 
02880 void XMLProgParser::addToContext_phiassign(Context *c, int e)
02881 {
02882     if (phase == 1) {
02883         return;
02884     }
02885     PhiAssign *pa = dynamic_cast<PhiAssign*>(c->stmt);
02886     assert(pa);
02887     switch(e) {
02888     case e_lhs:
02889         pa->setLeft(stack.front()->exp);
02890         break;
02891     // FIXME: More required
02892     default:
02893         if (e == e_unknown)
02894             std::cerr << "unknown tag " << e << " in context assign\n";
02895         else 
02896             std::cerr << "need to handle tag " << tags[e].tag << " in context assign\n";
02897     break;
02898     }
02899 }
02900 

Generated on Tue Sep 19 21:18:36 2006 for Boomerang by  doxygen 1.4.6