C-Breeze
C Compiler Infrastructure

[ Project home page]
Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

nodeinfo.cc

Go to the documentation of this file.
00001 // $Id: nodeinfo.cc,v 1.6 2003/08/11 19:05:01 toktb Exp $
00002 
00003 // ----------------------------------------------------------------------
00004 //
00005 //  J-Breeze
00006 //  Java Compiler Framework
00007 // 
00008 //  Copyright (c) 2001 University of Texas at Austin
00009 // 
00010 //  Teck B. Tok
00011 //  Samuel Z. Guyer
00012 //  Daniel A. Jimenez
00013 //  Calvin Lin
00014 // 
00015 //  Permission is hereby granted, free of charge, to any person
00016 //  obtaining a copy of this software and associated documentation
00017 //  files (the "Software"), to deal in the Software without
00018 //  restriction, including without limitation the rights to use, copy,
00019 //  modify, merge, publish, distribute, and/or sublicense copies
00020 //  of the Software, and to permit persons to whom the Software is
00021 //  furnished to do so, subject to the following conditions:
00022 //  
00023 //  The above copyright notice and this permission notice shall be
00024 //  included in all copies or substantial portions of the Software.
00025 //  
00026 //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00027 //  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00028 //  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00029 //  NONINFRINGEMENT.  IN NO EVENT SHALL THE UNIVERSITY OF TEXAS AT
00030 //  AUSTIN BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
00031 //  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
00032 //  OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
00033 //  THE SOFTWARE.
00034 //
00035 //  J-Breeze extends from C-Breeze (copyright University of Texas at
00036 //  Austin), part of whose design is inspired by the C-to-C Translator
00037 //  from MIT Laboratory for Computer Science.
00038 //
00039 // ----------------------------------------------------------------------
00040 
00041 #include "nodeinfo.h"
00042 #ifdef J_BREEZE
00043 #include "spackage.h"
00044 #include "conversion.h"
00045 #include "hcfg.h"
00046 #include "ana.h"
00047 #include "chierarchy.h"
00048 #endif
00049 #include <unistd.h>
00050 
00051 NodeInfo::NodeInfo(string filename, bool read, bool verbose) {
00052   _file = NULL;
00053   if(read) {
00054     if(access(filename.c_str(), F_OK) ==0 ||
00055        access(filename.c_str(), R_OK) ==0)
00056     _file = fopen(filename.c_str(), "r");
00057   } else
00058     _file = fopen(filename.c_str(), "w");
00059   if(!_file) {
00060     cerr << "NodeInfo: Unable to open file " << filename << endl;
00061     exit(1);
00062   }
00063 
00064   _read_mode=read;
00065   _verbose=verbose;
00066   _line=0;
00067 
00068   CBZ::PrintLineOffset = true;
00069 #define BUFSIZE 1024
00070 
00071   if(_read_mode) {
00072     while(!feof(_file)) {
00073       ++_line;
00074       char buf[BUFSIZE];
00075       buf[0]='\0';
00076       fgets(buf, BUFSIZE, _file);
00077       if(strlen(buf)==0) continue;
00078       ostringstream ost;
00079       ost << buf;
00080 
00081       do {
00082         if(feof(_file)) break;
00083         if(buf[strlen(buf)-1] =='\n') break;
00084         // not yet read to end of line
00085         buf[0] = '\0';
00086         fgets(buf, BUFSIZE, _file);
00087         ost << buf; // append
00088       } while (1);
00089 
00090       ost << '\0';
00091       string s = ost.str();
00092       if(s=="") continue;
00093       strings[_line] = s;
00094 //cout << "line " << _line << ": " << strings[_line];
00095       /*if(_verbose)
00096         cout << s; */
00097       if(s[0]=='#') continue;
00098 
00099       Node *node = getNode(s);
00100       index2node[_line] = node;
00101       node2index[node] = _line;
00102     }
00103   }
00104 } // NodeInfo
00105 
00106 
00107 extern char *TypNames[];
00108 #ifdef J_BREEZE
00109 #define MAX_Typ Unit
00110 #else
00111 #define MAX_Typ ThreeAddr
00112 #endif
00113 
00114 #ifndef J_BREEZE
00115 list<arrayNode*> NodeInfo::_canonical1;
00116 map<typeNode*,arrayNode*> NodeInfo::_canonical2;
00117 #endif
00118 
00120 
00121 class NodeInfo::NodeLocator : public Walker {
00122 public:
00123 #ifdef J_BREEZE
00124   static Node *findClass(string name, Node *search_in) {
00125     if(!search_in) return NULL;
00126 
00127     // break up name into name and coord
00128     int pos = name.find('@');
00129     string coord_str = name.substr(pos+1, string::npos);
00130     name = name.substr(0, pos);
00131 
00132     pos = coord_str.rfind(':');
00133     string offset = coord_str.substr(pos+1,string::npos);
00134     coord_str = coord_str.substr(0,pos),
00135     pos = coord_str.rfind(':');
00136     string filename = coord_str.substr(0,pos),
00137            line     = coord_str.substr(pos+1,string::npos);
00138     Coord coord = Coord::Unknown;
00139 
00140     int fileno = 0;
00141     while(fileno < CBZ::Files.size()) {
00142       if(CBZ::Files[fileno] == filename) break;
00143       fileno++;
00144     }
00145     if(fileno < CBZ::Files.size())
00146       coord = Coord(atoi(line.c_str()), atoi(offset.c_str()), fileno);
00147 
00148     // note: if look for anonymous class, name should start with substring
00149     // "<anonymous-"; will be found by at_new (if exist)
00150     if(!nl) nl = new NodeLocator (Class, name, coord);
00151     else {
00152       nl->_typ    = Class;
00153       nl->_name   = name;
00154       nl->_coord  = coord;
00155       nl->_result = NULL;
00156     }
00157     search_in->walk(*nl);
00158     return nl->_result;
00159   } // findClass
00160 #endif
00161 
00162   static Node *findCall(NodeType typ, string name, int nargs, Node *search_in,
00163                         Coord coord) {
00164     if(!search_in) return NULL;
00165 
00166     if(!nl) nl = new NodeLocator (typ, name, nargs, coord);
00167     else {
00168       nl->_typ    = typ;
00169       nl->_name   = name;
00170       nl->_coord  = coord;
00171       nl->_nargs  = nargs;
00172       nl->_result = NULL;
00173     }
00174     search_in->walk(*nl);
00175     return nl->_result;
00176   } // findCall
00177 
00178   static Node *findExprOrStmt(NodeType typ, Node *search_in, Coord coord) {
00179     if(!search_in) return NULL;
00180 
00181     if(!nl) nl = new NodeLocator (typ, "", coord);
00182     else {
00183       nl->_typ    = typ;
00184       nl->_name   = "";
00185       nl->_coord  = coord;
00186       nl->_nargs  = -1;
00187       nl->_result = NULL;
00188     }
00189     search_in->walk(*nl);
00190     return nl->_result;
00191   } // findExprOrStmt
00192 
00193   static declNode *findDecl(string name, Node *search_in, Coord coord) {
00194     if(!search_in) return NULL;
00195 
00196     if(!nl) nl = new NodeLocator (Decl, name, coord);
00197     else {
00198       nl->_typ    = Decl;
00199       nl->_name   = name;
00200       nl->_coord  = coord;
00201       nl->_nargs  = -1;
00202       nl->_result = NULL;
00203     }
00204     search_in->walk(*nl);
00205     return (declNode*) nl->_result;
00206   } // findDecl
00207 
00208   inline static void done(void) { if(nl) { delete nl; nl=NULL; } }
00209 
00210 
00211 private:
00212   NodeLocator(NodeType typ, string name, Coord coord)
00213   : _typ(typ), _name(name), _coord(coord), _result(NULL),
00214     Walker(Preorder, Subtree) {}
00215 
00216   NodeLocator(NodeType typ, string name, int nargs, Coord coord)
00217   : _typ(typ), _name(name), _nargs(nargs), _result(NULL), _coord(coord),
00218     Walker(Preorder, Subtree) {}
00219 
00220   static NodeLocator *nl;
00221 
00222   NodeType  _typ;
00223   string    _name;
00224   Coord     _coord;
00225   int       _nargs;
00226   Node     *_result;
00227 
00228   inline bool match_coord(Coord c1, Coord c2) {
00229     return (c1.file()==c2.file()) && (c1.line()==c2.line()) &&
00230            (c1.offset()==c2.offset());
00231   } // match_coord
00232 
00233 #ifdef J_BREEZE
00234   void at_class(classNode *c, Order ord) {
00235     if(_result) return;
00236     if(_typ!=Class) return;
00237     if(c->declLoc() != classNode::Local &&
00238        c->declLoc() != classNode::Anonymous) return;
00239     // look for anonymous class?
00240     if(_name.find("<anonymous-") == -1) { // no
00241       if(c->declLoc() != classNode::Local) return;
00242       if(_name==c->actual_name() && match_coord(_coord, c->coord())) {
00243         assert(!_result);
00244         _result = c;
00245       }
00246     } else { // yes
00247       if(c->declLoc() != classNode::Anonymous) return;
00248       if(match_coord(_coord, c->coord())) {
00249         assert(!_result);
00250         _result = c;
00251       }
00252     }
00253   } // at_class
00254 
00255   void at_new(newNode *n, Order ord) {
00256     if(_result) return;
00257     if(_typ!=New) return;
00258     if(_name==NodeInfo::type_string(n->type()) && n->args().size()==_nargs &&
00259        match_coord(_coord, n->coord())) {
00260       assert(!_result);
00261       _result = n;
00262     }
00263   } // at_new
00264 #endif
00265 
00266 #ifdef J_BREEZE
00267   void at_mcall(mcallNode *c, Order ord)
00268 #else
00269   void at_call(callNode *c, Order ord)
00270 #endif
00271   {
00272     if(_result) return;
00273     if(_typ!=Call) return;
00274     exprNode *c_name = c->name();
00275     string name;
00276     switch(c_name->typ()) {
00277 #ifdef J_BREEZE
00278       case Id: case QualifiedName:
00279         name = qnameNode::expand_name(c_name); break;
00280       case Special:
00281         name = ((specialNode*)c_name)->text(); break;
00282 #else
00283       case Id:
00284         name = ((idNode*)c_name)->name(); break;
00285       case Unary:
00286         name = "<unary>"; break;
00287 #endif
00288       case Binary:
00289         name = "<binary>"; break;
00290       default:
00291         cout << "typ is " << c_name->typ() << endl;
00292         assert(false);
00293     }
00294 //cout << "at_mcall @" << c->coord() << ": " << (_name==name)
00295      //<< (c->args().size()==_nargs) << match_coord(_coord, c->coord()) << endl;
00296     if(_name==name && c->args().size()==_nargs &&
00297        match_coord(_coord, c->coord())) {
00298        if(_result) {
00299          cerr << "NodeLocator: duplicate match: one at " << c->coord()
00300               << "\nthe other at " << _result->coord() << endl;
00301          exit(1);
00302        }
00303       _result = c;
00304     }
00305   } // at_call / at_mcall
00306 
00307   void at_expr(exprNode *expr, Order ord) {
00308     if(_result) return;
00309     if(expr->typ()==_typ && match_coord(_coord, expr->coord()))
00310       _result = expr;
00311   } // at_expr
00312 
00313   void at_stmt(stmtNode *stmt, Order ord) {
00314     if(_result) return;
00315     if(stmt->typ()==_typ && match_coord(_coord, stmt->coord()))
00316       _result = stmt;
00317 #ifdef J_BREEZE
00318     if(stmt->typ()==Block && _typ==Expr &&
00319        match_coord(_coord, ((blockNode*)stmt)->right_brace())) {
00320       if(! StandardAnalysis::hcfg) {
00321         StandardAnalysis::hcfg = new high_cfg;
00322         for (unit_list_p n=CBZ::Program.begin(); n!=CBZ::Program.end(); n++)
00323           (*n)->walk(*StandardAnalysis::hcfg);
00324         ArrayClass::clazz()->walk(*StandardAnalysis::hcfg);
00325       }
00326       _result = StandardAnalysis::hcfg->endblock((blockNode*)stmt);
00327     }
00328 #endif
00329   } // at_stmt
00330 
00331   void at_decl(declNode *decl, Order ord) {
00332     if(_result) return;
00333     if(_typ==Decl && match_coord(_coord, decl->coord()) && _name==decl->name())
00334       _result = decl;
00335   }
00336 }; // class NodeLocator
00337 
00338 NodeInfo::NodeLocator *NodeInfo::NodeLocator::nl = NULL;
00339 
00341 
00342 NodeInfo::~NodeInfo() {
00343   fclose(_file);
00344   NodeLocator::done();
00345 } // ~NodeInfo
00346 
00347 
00348 Node *NodeInfo::getNode(string s) {
00349   if(!_read_mode) return NULL;
00350   int pos = s.find(':');
00351   string prefix = s.substr(0,pos);
00352   int typ1 = 0;
00353   while(typ1<=MAX_Typ) {
00354     if(prefix == TypNames[typ1]) // found
00355       break;
00356     typ1++;
00357   }
00358 
00359   if(typ1>=MAX_Typ) return NULL;
00360   NodeType typ = (NodeType) typ1;
00361 
00362   Node *node = NULL;
00363 
00364   switch(typ) {
00365     case Tdef: case Array:
00366 #ifndef J_BREEZE
00367     case Struct: case Union: case Enum: case sueSpec: case Ptr: case Func:
00368 #endif
00369       node = readType(s);  break;
00370 #ifdef J_BREEZE
00371     case Class:
00372     case Interface: node = readClassOrInterface(s);  break;
00373     case Method: node = readMethod(s);  break;
00374     case FieldVar: node = readFieldvar(s);  break;
00375     case FieldInit: node = readFieldinit(s);  break;
00376     case Constructor: node = readConstructor(s);  break;
00377     case Call: node = readCall(s);  break;
00378     case New: node = readNew(s);  break;
00379 #else
00380     case Proc: node = readProc(s); break;
00381     case Call: node = readCall(s); break;
00382 #endif
00383     case Id: case Binary: case Unary: case Cast: case Ternary: case Initializer:
00384 #ifdef J_BREEZE
00385     case QualifiedName: case Special: case AccessClass: case InstanceOf:
00386 #endif
00387       node = readExprOrStmt(s, typ); break;
00388     case Label: case Switch: case Case: case If: case While: case Do: case For:
00389     case Continue: case Break: case Return: case Block:
00390 #ifdef J_BREEZE
00391     case DeclStmt: case ForInit: case Break_Id: case Continue_Id: case Throw:
00392     case Synchronized: case Try: case Catch: case Finally: case Assert:
00393 #endif
00394     case Expr:
00395       node = readExprOrStmt(s, typ); break;
00396     case Decl: node = readDecl(s); break;
00397     default:
00398       cerr << "NodeInfo::getNode: cannot handle typ " << typ << endl;
00399       exit(1);
00400   }
00401 
00402   if(!node) {
00403     CBZ::Warning(3, Coord::Unknown,
00404                  "NodeInfo: cannot get node for string `" + s + "'");
00405     exit(1);
00406   }
00407   return node;
00408 } // getNode
00409 
00410 
00411 typeNode *NodeInfo::readType(string s) {
00412 #ifdef J_BREEZE
00413   if(s=="Tdef:nullType\n") return Conversion::nullType;
00414 #endif
00415 
00416   // get rid of prefix
00417   int pos = s.find(':');
00418   string prefix = s.substr(0,pos+1);
00419 
00420 #ifndef J_BREEZE
00421   if(prefix=="Struct:" || prefix=="Union:" || prefix=="Enum:" || prefix=="Func:")
00422     return readsuef(s);
00423 #endif
00424 
00425 #ifndef J_BREEZE
00426   bool is_ptr = (prefix == "Ptr:");
00427   if(!is_ptr && prefix != "Array:") return NULL;
00428 #else
00429   if(prefix != "Array:") return NULL;
00430 #endif
00431   s = s.substr(pos+1, string::npos);
00432 
00433   typeNode *base = NULL;
00434   pos = s.rfind("base=");
00435   if(pos>0) {
00436     string ref_base = s.substr(pos+strlen("base="), string::npos);
00437     Node *node = index2node[ atoi(ref_base.c_str()) ];
00438     assert(node);
00439 #ifdef J_BREEZE
00440     assert(node->typ()==Array || node->typ()==Class || node->typ()==Interface);
00441 #else
00442     assert(node->typ()==Array || node->typ()==sueSpec || node->typ()==Ptr ||
00443            node->typ()==Func);
00444 #endif
00445     base = (typeNode*) node;
00446 
00447   } else {
00448 #ifndef J_BREEZE
00449     if(is_ptr) pos = s.rfind("*");
00450     else // fall through
00451 #endif
00452     pos = s.rfind("[]");
00453     s.resize(pos);
00454     assert(s.rfind("[]")<0 || s.rfind("[]")>s.length()); // no further base type
00455 #ifndef J_BREEZE
00456     assert(s.rfind("*")<0 || s.rfind("*")>s.length()); // no further base type
00457 #endif
00458     // assert: base is Prim
00459 #ifdef J_BREEZE
00460     if(s=="byte")
00461       base = new primNode(basic_type::JByte, Coord::Unknown);
00462     else if(s=="short")
00463       base = new primNode(basic_type::JShort, Coord::Unknown);
00464     else if(s=="char")
00465       base = new primNode(basic_type::SChar, Coord::Unknown);
00466     else if(s=="int")
00467       base = new primNode(basic_type::SInt, Coord::Unknown);
00468     else if(s=="long")
00469       base = new primNode(basic_type::JLong, Coord::Unknown);
00470     else if(s=="float")
00471       base = new primNode(basic_type::Float, Coord::Unknown);
00472     else if(s=="double")
00473       base = new primNode(basic_type::Double, Coord::Unknown);
00474     else if(s=="boolean")
00475       base = new primNode(basic_type::Boolean, Coord::Unknown);
00476     else assert(false);
00477 #else
00478     while(s.length()>0) {
00479       pos = s.find(" ");
00480       string s1 = (pos < 0 || pos > (int)s.length()) ? s : s.substr(0,pos);
00481       if(s==s1) s="";
00482       else s = s.substr(pos+1,string::npos);
00483       primNode *base1;
00484       if(s1=="short")
00485         base1 = new primNode(basic_type::Short, Coord::Unknown);
00486       else if(s1=="char")
00487         base1 = new primNode(basic_type::Char, Coord::Unknown);
00488       else if(s1=="int")
00489         base1 = new primNode(basic_type::Int, Coord::Unknown);
00490       else if(s1=="long")
00491         base1 = new primNode(basic_type::Long, Coord::Unknown);
00492       else if(s1=="float")
00493         base1 = new primNode(basic_type::Float, Coord::Unknown);
00494       else if(s1=="double")
00495         base1 = new primNode(basic_type::Double, Coord::Unknown);
00496       else if(s1=="signed")
00497         base1 = new primNode(basic_type::Signed, Coord::Unknown);
00498       else if(s1=="unsigned")
00499         base1 = new primNode(basic_type::Unsigned, Coord::Unknown);
00500       else assert(false);
00501       if(!base) base=base1;
00502       else {
00503         ((primNode*)base)->merge_in(base1);
00504         delete base1;
00505       }
00506     }
00507 #endif
00508   }
00509 
00510 #ifndef J_BREEZE
00511   if(is_ptr)
00512     return new ptrNode(typeNode::NONE, base, Coord::Unknown);
00513 #endif
00514   return new arrayNode(typeNode::NONE, base, NULL, Coord::Unknown);
00515 } // readType
00516 
00517 
00518 #ifndef J_BREEZE
00519 typeNode *NodeInfo::readsuef(string s) {
00520   if(!_read_mode) return NULL;
00521   // get rid of prefix
00522   int pos = s.find(':');
00523   string prefix = s.substr(0,pos);
00524   s = s.substr(pos+1, string::npos);
00525 
00526   NodeType typ;
00527   if(prefix=="Struct")     typ = Struct;
00528   else if(prefix=="Union") typ = Union;
00529   else if(prefix=="Enum")  typ = Enum;
00530   else if(prefix=="Func")  typ = Func;
00531   else assert(false);
00532 
00533   // obtain Coord and unit
00534   unitNode *unit;
00535   Coord coord = getCoord(s, &unit);
00536 
00537   // get rid of coord suffix
00538   pos = s.rfind('@');
00539   s = s.substr(0, pos);
00540   // get rid of trailing spaces
00541   while(s[s.length()-1]==' ')
00542     s.resize(s.length()-1);
00543 
00544   // obtain type
00545   typeNode *type = NULL;
00546   if(typ==Func) {
00547     ostringstream ost;
00548     ost << coord.to_string() << '\0';
00549     string coord_str = ost.str();
00550 cout << coord_str << " vs " << coord << "|\n";
00551     if(unit)
00552       for(def_list_p p=unit->defs().begin(); p!=unit->defs().end();p++)
00553         if((*p)->typ()==Decl && ((declNode*)*p)->type()->typ()==Func) {
00554            funcNode *func = (funcNode*) ((declNode*)*p)->type();
00555            ostringstream ost1;
00556            ost1 << func->coord().to_string() << '\0';
00557            if(coord_str == ost.str())
00558            { type=((declNode*)*p)->type();  break; }
00559         }
00560     for(unit_list_p u=CBZ::Program.begin(); !type && u!=CBZ::Program.end(); u++)
00561       for(def_list_p p=(*u)->defs().begin(); p!=(*u)->defs().end(); p++)
00562         if((*p)->typ()==Decl && ((declNode*)*p)->type()->typ()==Func) {
00563            funcNode *func = (funcNode*) ((declNode*)*p)->type();
00564            ostringstream ost1;
00565            ost1 << func->coord().to_string() << '\0';
00566            if(coord_str == ost.str())
00567            { type=((declNode*)*p)->type();  break; }
00568         }
00569     if(!type) return NULL;
00570     assert(type->typ() == Func);
00571     return type;
00572 
00573   } else { // Struct/Union/Enum
00574     if(unit)
00575       for(suespec_list_p p=unit->suespecs().begin();
00576           p!=unit->suespecs().end();p++)
00577         if((*p)->name() == s) { type=*p;  break; }
00578     for(unit_list_p u=CBZ::Program.begin(); !type && u!=CBZ::Program.end(); u++)
00579       for(suespec_list_p p=(*u)->suespecs().begin();
00580           p!=(*u)->suespecs().end();p++)
00581         if((*p)->name() == s) { type=*p;  break; }
00582     if(!type) return NULL;
00583     assert(type->typ() == sueSpec);
00584     assert(((suespecNode*)type)->owner() == typ);
00585     return type;
00586   }
00587 } // readsuef
00588 
00589 
00590 procNode *NodeInfo::readProc(string s) {
00591   if(!_read_mode) return NULL;
00592   // get rid of prefix "Method:"
00593   int pos = s.find(':');
00594   s = s.substr(pos+1, string::npos);
00595 
00596   // obtain Coord and unit
00597   unitNode *unit;
00598   Coord coord = getCoord(s, &unit);
00599 
00600   // get rid of coord suffix
00601   pos = s.rfind('@');
00602   s = s.substr(0, pos);
00603 
00604   // obtain args
00605   pos = s.find('(');
00606   string args_string = s.substr(pos+1,string::npos);
00607   s = s.substr(0,pos);
00608 
00609   // finally, find method
00610 
00611   if(unit)
00612     for(def_list_p def=unit->defs().begin(); def!=unit->defs().end(); def++) {
00613       if((*def)->typ() != Proc) continue;
00614       procNode *p = (procNode*) *def;
00615       assert(p->decl()->type()->typ()==Func);
00616       decl_list args = ((funcNode*)p->decl()->type())->args();
00617       if(p->decl()->name() == s && match_args(args_string, args))
00618         return p;
00619     }
00620   for(unit_list_p u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++)
00621     for(def_list_p def=(*u)->defs().begin(); def!=(*u)->defs().end(); def++) {
00622       if((*def)->typ() != Proc) continue;
00623       procNode *p = (procNode*) *def;
00624       assert(p->decl()->type()->typ()==Func);
00625       decl_list args = ((funcNode*)p->decl()->type())->args();
00626       if(p->decl()->name() == s && match_args(args_string, args))
00627         return p;
00628     }
00629 
00630   return NULL; // not found
00631 } // readProc
00632 
00633 #else
00634 typeNode *NodeInfo::readClassOrInterface(string s) {
00635   if(!_read_mode) return NULL;
00636   // get rid of prefix
00637   int pos = s.find(':');
00638   string prefix = s.substr(0,pos);
00639   s = s.substr(pos+1, string::npos);
00640 
00641   NodeType typ;
00642   if(prefix=="Class")          typ = Class;
00643   else if(prefix=="Interface") typ = Interface;
00644   else assert(false);
00645 
00646   // obtain Coord and unit
00647   unitNode *unit;
00648   Coord coord = getCoord(s, &unit);
00649   //if(!unit) return NULL;
00650 
00651   // get rid of coord suffix
00652   pos = s.rfind('@');
00653   s = s.substr(0, pos);
00654 
00655   // obtain type
00656   typeNode *type = getType(unit, s);
00657   if(!type) return NULL;
00658   assert(type->typ() == typ);
00659   return type;
00660 } // readClassOrInterface
00661 
00662 
00663 methodNode *NodeInfo::readMethod(string s) {
00664   if(!_read_mode) return NULL;
00665   // get rid of prefix "Method:"
00666   int pos = s.find(':');
00667   s = s.substr(pos+1, string::npos);
00668 
00669   // obtain Coord and unit
00670   unitNode *unit;
00671   Coord coord = getCoord(s, &unit);
00672 
00673   // get rid of coord suffix
00674   pos = s.rfind('@');
00675   s = s.substr(0, pos);
00676 
00677   // obtain args
00678   pos = s.find('(');
00679   string args_string = s.substr(pos+1,string::npos);
00680   s = s.substr(0,pos);
00681 
00682   // obtain type where method is defined.
00683   pos = s.rfind('$');
00684   string type_string = s.substr(0, pos);
00685   typeNode *type = getType(unit, type_string);
00686   if(!type) return NULL;
00687 
00688   // finally, find method
00689   string mtd_string = s.substr(pos+1, string::npos);
00690 
00691   if(standardPackage::existType(type))
00692     standardPackage::addMethods((referenceNode*)type, mtd_string.c_str());
00693 
00694   field_list fields;
00695   if(type->typ() == Class)          fields=((classNode*) type)->fields();
00696   else if(type->typ() == Interface) fields=((interfaceNode*) type)->fields();
00697   else assert(false);
00698 
00699   for(field_list_p f=fields.begin(); f!=fields.end(); f++) {
00700     if((*f)->typ() != Method) continue;
00701     methodNode *m = (methodNode*)*f;
00702     if(m->decl()->name() == mtd_string && match_args(args_string, m->args()))
00703       return m;
00704   }
00705 
00706   return NULL; // not found
00707 } // readMethod
00708 
00709 
00710 constructorNode *NodeInfo::readConstructor(string s) {
00711   if(!_read_mode) return NULL;
00712   // get rid of prefix "Constructor:"
00713   int pos = s.find(':');
00714   s = s.substr(pos+1, string::npos);
00715 
00716   // obtain Coord and unit
00717   unitNode *unit;
00718   Coord coord = getCoord(s, &unit);
00719 
00720   // get rid of coord suffix
00721   pos = s.rfind('@');
00722   s = s.substr(0, pos);
00723 
00724   // obtain type where constructor is defined.
00725   pos = s.rfind('(');
00726   string type_string = s.substr(0, pos);
00727   typeNode *type = getType(unit, type_string);
00728   if(!type) return NULL;
00729 
00730   if(type->typ()==Class && standardPackage::existType(type))
00731     standardPackage::addConstructors((classNode*) type);
00732 
00733   // finally, find constructor
00734   string args_string = s.substr(pos+1,string::npos);
00735   field_list fields;
00736   if(type->typ() == Class)          fields=((classNode*) type)->fields();
00737   else if(type->typ() == Interface) fields=((interfaceNode*) type)->fields();
00738   else assert(false);
00739 
00740   for(field_list_p f=fields.begin(); f!=fields.end(); f++) {
00741     if((*f)->typ() != Constructor) continue;
00742     constructorNode *c = (constructorNode*)*f;
00743     if(match_args(args_string, c->args()))
00744       return c;
00745   }
00746 
00747   return NULL; // not found
00748 } // readConstructor
00749 #endif // J_BREEZE
00750 
00751 
00752 bool NodeInfo::match_args(string args, decl_list formals) {
00753   // args must be in form of "arg1,arg2,...,argn) "
00754   if(formals.empty()) return args[0]==')';
00755   bool last = false;;
00756   for(decl_list_p f=formals.begin(); f!=formals.end(); ) {
00757     if(args=="") return false;
00758     int pos = args.find(',');
00759     if(pos==-1)  { // either last or no argument
00760       pos = args.find(')');
00761       last = true;
00762     }
00763     if(pos==-1) return false;
00764     string arg = args.substr(0, pos);
00765 #ifdef J_BREEZE
00766     if(arg != typenameNode::type_name((*f)->type())) return false;
00767 #else
00768     if(arg != type_name((*f)->type())) return false;
00769 #endif
00770     args = args.substr(pos+1,string::npos);
00771 
00772     f++;
00773     if(last) return f==formals.end();
00774   }
00775   // not yet last arg, but no more formal
00776   return false;
00777 } // match_args
00778 
00779 
00780 #ifdef J_BREEZE
00781 fieldvarNode *NodeInfo::readFieldvar(string s) {
00782   if(!_read_mode) return NULL;
00783   // get rid of prefix "FieldVar:"
00784   int pos = s.find(':');
00785   s = s.substr(pos+1, string::npos);
00786 
00787   // obtain Coord and unit
00788   unitNode *unit;
00789   Coord coord = getCoord(s, &unit);
00790 
00791   // get rid of coord suffix
00792   pos = s.rfind(" @");
00793   s = s.substr(0, pos);
00794 
00795   // obtain type where fieldvar is defined.
00796   pos = s.rfind('$');
00797   string type_string = s.substr(0, pos);
00798   typeNode *type = getType(unit, type_string);
00799   if(!type) return NULL;
00800 
00801   // finally, find fieldvar
00802   string fv_string = s.substr(pos+1, string::npos);
00803 
00804   if(standardPackage::existType(type))
00805     standardPackage::addFieldvar((referenceNode*) type, fv_string.c_str());
00806 
00807   field_list fields;
00808   if(type->typ() == Class)          fields=((classNode*) type)->fields();
00809   else if(type->typ() == Interface) fields=((interfaceNode*) type)->fields();
00810   else assert(false);
00811 
00812   for(field_list_p f=fields.begin(); f!=fields.end(); f++) {
00813     if((*f)->typ() != FieldVar) continue;
00814     fieldvarNode *fv = (fieldvarNode*)*f;
00815     for(decl_list_p d=fv->decls().begin(); d!=fv->decls().end(); d++)
00816       if((*d)->name() == fv_string)
00817         return fv;
00818   }
00819 
00820   return NULL; // not found
00821 } // readFieldvar
00822 
00823 
00824 fieldinitNode *NodeInfo::readFieldinit(string s) {
00825   if(!_read_mode) return NULL;
00826   // get rid of prefix "FieldInit:"
00827   int pos = s.find(':');
00828   s = s.substr(pos+1, string::npos);
00829 
00830   // obtain Coord and unit
00831   unitNode *unit;
00832   Coord coord = getCoord(s, &unit);
00833 
00834   // get rid of coord suffix
00835   pos = s.rfind(" @");
00836   s = s.substr(0, pos);
00837 
00838   // obtain type where fieldinit is defined.
00839   typeNode *type = getType(unit, s);
00840   if(!type) return NULL;
00841 
00842   field_list fields;
00843   if(type->typ() == Class)          fields=((classNode*) type)->fields();
00844   else if(type->typ() == Interface) fields=((interfaceNode*) type)->fields();
00845   else assert(false);
00846 
00847   for(field_list_p f=fields.begin(); f!=fields.end(); f++) {
00848     if((*f)->typ() != FieldInit) continue;
00849     fieldinitNode *fi = (fieldinitNode*)*f;
00850     if(fi->coord().line() == coord.line())
00851       return fi;
00852   }
00853 
00854   return NULL; // not found
00855 } // readFieldinit
00856 #endif // J_BREEZE
00857 
00858 
00859 #ifdef J_BREEZE
00860 mcallNode *NodeInfo::readCall(string s) {
00861 #else
00862 callNode *NodeInfo::readCall(string s) {
00863 #endif // J_BREEZE
00864   // get rid of prefix "Call:"
00865   int pos = s.find(':');
00866   s = s.substr(pos+1, string::npos);
00867 
00868   // obtain Coord and unit
00869   unitNode *unit;
00870   Coord coord = getCoord(s, &unit);
00871   //if(!unit) return NULL;
00872 
00873   // get rid of coord suffix
00874   pos = s.rfind('@');
00875   s = s.substr(0, pos);
00876 
00877   // obtain container, if any
00878   Node *container=NULL;
00879   pos = s.rfind("container=");
00880   if(pos != -1) {
00881     pos = s.rfind('=');
00882     string container_str = s.substr(pos+1, string::npos);
00883     s = s.substr(0,pos);
00884     container = index2node[atoi(container_str.c_str())];
00885 if(!container) cout << "container_str=" << container_str << ", s="<<s<<endl;
00886     assert(container);
00887   } else
00888     container = unit;
00889 
00890   // obtain #args
00891   pos = s.find('(');
00892   int pos2 = s.find(')');
00893   int nargs = atoi(s.substr(pos+1,pos2).c_str());
00894   s = s.substr(0,pos);
00895 
00896   // finally, find newNode
00897 #ifdef J_BREEZE
00898   mcallNode *c = (mcallNode*)
00899 #else
00900   callNode *c = (callNode*)
00901 #endif
00902     NodeLocator::findCall(Call, s, nargs, container, coord);
00903 
00904 #ifndef J_BREEZE
00905   // container could be NULL, due to unknown unit due to included file
00906   for(unit_list_p u=CBZ::Program.begin(); !c && u!=CBZ::Program.end(); u++)
00907     c = (callNode*) NodeLocator::findCall(Call, s, nargs, *u, coord);
00908 #endif
00909 
00910   if(!c) {
00911     cerr << "error in NodeInfo::readCall\n";
00912     cerr << "s=`" << s << "'\n";
00913     if(container->typ()==Unit)
00914       cerr << "container=" << ((unitNode*)container)->input_file() << endl;
00915     else
00916       cerr << "container @" << container->coord() << endl;
00917     cerr << "nargs=" << nargs << endl;
00918     cerr << "coord=" << coord << endl;
00919     exit(1);
00920   }
00921 
00922   return c;
00923 } // readCall
00924 
00925 
00926 #ifdef J_BREEZE
00927 newNode *NodeInfo::readNew(string s) {
00928   // get rid of prefix "New:"
00929   int pos = s.find(':');
00930   s = s.substr(pos+1, string::npos);
00931 
00932   // obtain Coord and unit
00933   unitNode *unit;
00934   Coord coord = getCoord(s, &unit);
00935   //if(!unit) return NULL;
00936 
00937   // get rid of coord suffix
00938   pos = s.rfind('@');
00939   s = s.substr(0, pos);
00940 
00941   // obtain container, if any
00942   Node *container=NULL;
00943   pos = s.rfind("container=");
00944   if(pos != -1) {
00945     pos = s.rfind('=');
00946     string container_str = s.substr(pos+1, string::npos);
00947     s = s.substr(0,pos);
00948     container = index2node[atoi(container_str.c_str())];
00949     assert(container);
00950   } else
00951     container = unit;
00952 
00953   // obtain #args
00954   pos = s.find('(');
00955   int pos2 = s.find(')');
00956   int nargs = atoi(s.substr(pos+1,pos2).c_str());
00957   s = s.substr(0,pos);
00958 
00959   // finally, find newNode
00960   newNode *n
00961     = (newNode*) NodeLocator::findCall(New, s, nargs, container, coord);
00962 
00963   if(!n) {
00964     cerr << "error in NodeInfo::readNew\n";
00965     cerr << "s=`" << s << "'\n";
00966     if(container->typ()==Unit)
00967       cerr << "container=" << ((unitNode*)container)->input_file() << endl;
00968     else
00969       cerr << "container @" << container->coord() << endl;
00970     cerr << "nargs=" << nargs << endl;
00971     cerr << "coord=" << coord << endl;
00972     exit(1);
00973   }
00974   return n;
00975 } // readNew
00976 #endif // J_BREEZE
00977 
00978 
00979 Node *NodeInfo::readExprOrStmt(string s, NodeType typ) {
00980   // get rid of prefix
00981   int pos = s.find(':');
00982   s = s.substr(pos+1, string::npos);
00983 
00984   // obtain Coord and unit
00985   unitNode *unit;
00986   Coord coord = getCoord(s, &unit);
00987   //if(!unit) return NULL;
00988 
00989   // get rid of coord suffix
00990   pos = s.rfind('@');
00991   s = s.substr(0, pos);
00992 
00993   // obtain container, if any
00994   Node *container=NULL;
00995   pos = s.rfind("container=");
00996   assert(pos != -1);
00997   pos = s.rfind('=');
00998   string container_str = s.substr(pos+1, string::npos);
00999   s = s.substr(0,pos);
01000   container = index2node[atoi(container_str.c_str())];
01001 if(!container) cout << "container_str=" << container_str << ", s="<<s<<endl;
01002   assert(container);
01003 
01004   // finally, find Node
01005   Node *e = NodeLocator::findExprOrStmt(typ, container, coord);
01006 
01007   if(!e) {
01008     cerr << "error in NodeInfo::readExprOrStmt\n";
01009     cerr << "s=`" << s << "'\n";
01010     if(container->typ()==Unit)
01011       cerr << "container=" << ((unitNode*)container)->input_file() << endl;
01012     else
01013       cerr << "container @" << container->coord() << endl;
01014     cerr << "coord=" << coord << endl;
01015     exit(1);
01016   }
01017 
01018   return e;
01019 } // readExprOrStmt
01020 
01021 
01022 declNode *NodeInfo::readDecl(string s) {
01023   // get rid of prefix
01024   int pos = s.find(':');
01025   s = s.substr(pos+1, string::npos);
01026 
01027   // obtain Coord and unit
01028   unitNode *unit;
01029   Coord coord = getCoord(s, &unit);
01030   //if(!unit) return NULL;
01031 
01032   // get rid of coord suffix
01033   pos = s.rfind('@');
01034   s = s.substr(0, pos);
01035 
01036   // obtain container, if any
01037   Node *container=NULL;
01038   pos = s.rfind("container=");
01039   assert(pos != -1);
01040   pos = s.rfind('=');
01041   string container_str = s.substr(pos+1, string::npos);
01042   container = index2node[atoi(container_str.c_str())];
01043 if(!container) {
01044   cout << "container_str=" << container_str << ", s="<<s<<endl;
01045   cout << "strings[@] = " << strings[atoi(container_str.c_str())] << endl;
01046 }
01047   assert(container);
01048 
01049   // obtain name of decl
01050   pos = s.rfind(" container=");
01051   string name = s.substr(0,pos);
01052 
01053   // finally, find Node
01054   declNode *d = NodeLocator::findDecl(name, container, coord);
01055 
01056   if(!d) {
01057     cerr << "error in NodeInfo::readDecl\n";
01058     cerr << "s=`" << s << "'\n";
01059     if(container->typ()==Unit)
01060       cerr << "container=" << ((unitNode*)container)->input_file() << endl;
01061     else
01062       cerr << "container @" << container->coord() << endl;
01063     cerr << "coord=" << coord << endl;
01064     exit(1);
01065   }
01066 
01067   return d;
01068 } // readDecl
01069 
01071 
01072 #ifdef J_BREEZE
01073 // format: "Class:nested_type @coord" or
01074 //         "Interface:nested_type @coord" or
01075 void NodeInfo::writeClassOrInterface(referenceNode *ty) {
01076   if(_read_mode || !ty) return;
01077   if(node2index[ty] > 0) return;
01078   NodeType typ = ty->typ();
01079   if(typ!=Class && typ!=Interface) return;
01080 
01081   string s = string(TypNames[typ]) + ':' + type_string(ty);
01082   ostringstream ost;
01083   ost << ty->coord() << '\0';
01084   string s1 = s + string(" @") + ost.str() + string("\n");
01085   s = s1;
01086   fputs(s.c_str(), _file);
01087   index2node[++_line] = ty;
01088   node2index[ty] = _line;
01089   strings[_line] = s;
01090   fflush(_file);
01091 } // writeClassOrInterface
01092 #endif // J_BREEZE
01093 
01094 
01095 void NodeInfo::writeType(typeNode *ty) {
01096   if(_read_mode || !ty) return;
01097   if(node2index[ty] > 0) return;
01098   if(ty->typ() == Prim) return;  // ignore
01099 #ifdef J_BREEZE
01100   ty = classHierarchy::def_type(ty);
01101   if(ty->typ()==Class || ty->typ()==Interface) {
01102     writeClassOrInterface((referenceNode*) ty);
01103     return;
01104   }
01105   
01106 #else
01107 
01108   ty = def_type(ty);
01109   if(ty->typ() == Prim) return;  // ignore
01110   if(ty->typ()==sueSpec) {
01111     if(node2index[ty] > 0) return;
01112     suespecNode *spec = (suespecNode*) ty;
01113     string s = string(TypNames[spec->owner()]) + ':' + spec->name();
01114     ostringstream ost;
01115     ost << ty->coord() << '\0';
01116     string s1 = s + string(" @") + ost.str() + string("\n");
01117     s = s1;
01118     fputs(s.c_str(), _file);
01119     index2node[++_line] = ty;
01120     node2index[ty] = _line;
01121     strings[_line] = s;
01122     fflush(_file);
01123     return;
01124   }
01125 #endif
01126 
01127 #ifdef J_BREEZE
01128   if(ty->typ()==Tdef && ty==Conversion::nullType) {
01129     string s = "Tdef:nullType\n";
01130     fputs(s.c_str(), _file);
01131     index2node[++_line] = ty;
01132     node2index[ty] = _line;
01133     strings[_line] = s;
01134     fflush(_file);
01135     return;
01136   }
01137 #else
01138 #endif
01139 
01140 #ifndef J_BREEZE
01141   if(ty->typ() == Func) {
01142     if(node2index[ty] > 0) return;
01143     string s = string(TypNames[Func]) + ':';
01144     ostringstream ost;
01145     ost << ty->coord() << '\0';
01146     string s1 = s + string(" @") + ost.str() + string("\n");
01147     s = s1;
01148     fputs(s.c_str(), _file);
01149     index2node[++_line] = ty;
01150     node2index[ty] = _line;
01151     strings[_line] = s;
01152     fflush(_file);
01153     return;
01154   }
01155 
01156   if(ty->typ() == Ptr) {
01157     ptrNode *ptr = (ptrNode*) ty;
01158     typeNode *base = def_type(ptr->type());
01159     writeType(base);
01160     int ref_base = node2index[base];
01161     ostringstream ost;
01162     ost << "Ptr:" << type_name(ptr);
01163     if(ref_base>0)
01164       ost << " base=" << ref_base;
01165     ost << '\0';
01166     string s = ost.str() + string("\n");
01167     fputs(s.c_str(), _file);
01168     index2node[++_line] = ptr;
01169     node2index[ptr] = _line;
01170     strings[_line] = s;
01171     fflush(_file);
01172     return;
01173   }
01174 #endif
01175 
01176   if(ty->typ() != Array) {
01177     cerr << "NodeInfo::writeType: typ " << ty->typ() << endl;
01178     exit(1);
01179   }
01180 #ifdef J_BREEZE
01181   arrayNode *array = ArrayClass::canonical((arrayNode*) ty);
01182 #else
01183   arrayNode *array = canonical((arrayNode*) ty);
01184 #endif
01185   if(node2index[array] > 0) return;
01186   typeNode *base = array->type();
01187   if(base->typ()==Array)
01188 #ifdef J_BREEZE
01189     base = ArrayClass::canonical((arrayNode*) base);
01190 #else
01191     base = canonical((arrayNode*) base);
01192 #endif
01193   else
01194 #ifdef J_BREEZE
01195     base = classHierarchy::def_type(base);
01196 #else
01197     base = def_type(base);
01198 #endif
01199   writeType(base);
01200   int ref_base = node2index[base];
01201 
01202   ostringstream ost;
01203 #ifdef J_BREEZE
01204   ost << "Array:" << typenameNode::type_name(array);
01205 #else
01206   ost << "Array:" << type_name(array);
01207 #endif
01208   if(ref_base>0)
01209     ost << " base=" << ref_base;
01210   ost << '\0';
01211   string s = ost.str() + string("\n");
01212   fputs(s.c_str(), _file);
01213   index2node[++_line] = array;
01214   node2index[array] = _line;
01215   strings[_line] = s;
01216   fflush(_file);
01217 } // writeType
01218 
01219 
01220 #ifdef J_BREEZE
01221 // format: "Method:nested_type$method(args) @coord"
01222 void NodeInfo::writeMethod(methodNode *m) {
01223   if(_read_mode || !m) return;
01224   if(node2index[m] > 0) return;
01225   typeNode *fieldof = m->fieldof();
01226 
01227   string s = string(TypNames[Method]) + ':' + type_string(fieldof) + '$' +
01228              m->decl()->name() + "(";
01229   decl_list args = m->args();
01230   for(decl_list_p a=args.begin(); a!=args.end(); ) {
01231     s += typenameNode::type_name((*a)->type());
01232     if(++a!=args.end()) s += ",";
01233   }
01234   ostringstream ost;
01235   ost << m->coord() << '\0';
01236   s += string(") @") + ost.str() + string("\n");
01237   fputs(s.c_str(), _file);
01238   index2node[++_line] = m;
01239   node2index[m] = _line;
01240   strings[_line]   = s;
01241   fflush(_file);
01242 } // writeMethod
01243 
01244 
01245 // format: "Constructor:nested_type$constructor(args) @coord"
01246 void NodeInfo::writeConstructor(constructorNode *c) {
01247   if(_read_mode || !c) return;
01248   if(node2index[c] > 0) return;
01249   typeNode *fieldof = c->fieldof();
01250 
01251   string s = string(TypNames[Constructor]) + ':' + type_string(fieldof) + "(";
01252   decl_list args = c->args();
01253   for(decl_list_p a=args.begin(); a!=args.end(); ) {
01254     s += typenameNode::type_name((*a)->type());
01255     if(++a!=args.end()) s += ",";
01256   }
01257   ostringstream ost;
01258   ost << c->coord() << '\0';
01259   s += string(") @") + ost.str() + "\n";
01260   fputs(s.c_str(), _file);
01261   index2node[++_line] = c;
01262   node2index[c] = _line;
01263   strings[_line]   = s;
01264   fflush(_file);
01265 } // writeConstructor
01266 
01267 
01268 // format: "FieldVar:nested_type$fieldvar @coord"
01269 void NodeInfo::writeFieldvar(fieldvarNode *fv, declNode *d) {
01270   if(_read_mode || !fv) return;
01271   if(node2index[fv] > 0) return;
01272   typeNode *fieldof = fv->fieldof();
01273   if(!d) d=fv->decl();
01274 
01275   string s = string(TypNames[FieldVar]) + ':' + type_string(fieldof) + '$' +
01276              d->name();
01277   ostringstream ost;
01278   ost << fv->coord() << '\0';
01279   s += string(" @") + ost.str() + string("\n");
01280   fputs(s.c_str(), _file);
01281   index2node[++_line] = fv;
01282   node2index[fv] = _line;
01283   strings[_line]   = s;
01284   fflush(_file);
01285 } // writeFieldvar
01286 
01287 
01288 // format: "FieldInit:nested_type @coord"
01289 void NodeInfo::writeFieldinit(fieldinitNode *fi) {
01290   if(_read_mode || !fi) return;
01291   if(node2index[fi] > 0) return;
01292   typeNode *fieldof = fi->fieldof();
01293 
01294   string s = string(TypNames[FieldInit]) + ':' + type_string(fieldof);
01295   ostringstream ost;
01296   ost << fi->coord() << '\0';
01297   s += string(" @") + ost.str() + string("\n");
01298   fputs(s.c_str(), _file);
01299   index2node[++_line] = fi;
01300   node2index[fi] = _line;
01301   strings[_line]   = s;
01302   fflush(_file);
01303 } // writeFieldvar
01304 
01305 #else
01306 void NodeInfo::writeProc(procNode *proc) {
01307   if(_read_mode || !proc) return;
01308   if(node2index[proc] > 0) return;
01309 
01310   string s = string(TypNames[Proc]) + ':' + proc->decl()->name() + "(";
01311   assert(proc->decl()->type()->typ()==Func);
01312   decl_list args = ((funcNode*)proc->decl()->type())->args();
01313   for(decl_list_p a=args.begin(); a!=args.end(); ) {
01314     s += type_name((*a)->type());
01315     if(++a!=args.end()) s += ",";
01316   }
01317   ostringstream ost;
01318   ost << proc->coord() << '\0';
01319   s += string(") @") + ost.str() + string("\n");
01320   fputs(s.c_str(), _file);
01321   index2node[++_line] = proc;
01322   node2index[proc] = _line;
01323   strings[_line]= s;
01324   fflush(_file);
01325 } // writeMethod
01326 #endif // J_BREEZE
01327 
01328 
01329 // format: "Call:name(num_arg) container=n @coord"
01330 //      or "Call:name(num_arg) @coord"
01331 // todo: binary name?
01332 #ifdef J_BREEZE
01333 void NodeInfo::writeCall(mcallNode *c, int container)
01334 #else
01335 void NodeInfo::writeCall(callNode *c, int container)
01336 #endif
01337 {
01338   if(_read_mode || !c) return;
01339   if(node2index[c] > 0) return;
01340   exprNode *c_name = c->name();
01341   string name;
01342   switch(c_name->typ()) {
01343 #ifdef J_BREEZE
01344     case Id: case QualifiedName:
01345       name = qnameNode::expand_name(c_name); break;
01346     case Special:
01347       name = ((specialNode*)c_name)->text(); break;
01348 #else
01349     case Id:
01350       name = ((idNode*)c_name)->name(); break;
01351 #endif
01352     case Binary:
01353       name = "<binary>"; break;
01354     case Unary:
01355       name = "<unary>"; break;
01356     default:
01357       cout << "typ is " << c_name->typ() << endl;
01358       assert(false);
01359   }
01360 
01361   ostringstream ost;
01362   ost << TypNames[Call] << ':' << name << "(" << c->args().size() << ")";
01363 
01364   if(container>0)
01365     ost << " container=" << container;
01366 
01367   ost << " @" << c->coord() << '\0';
01368   string s = ost.str() + string("\n");
01369   fputs(s.c_str(), _file);
01370   index2node[++_line] = c;
01371   node2index[c] = _line;
01372   strings[_line]   = s;
01373   fflush(_file);
01374 } // writeCall
01375 
01376 
01377 #ifdef J_BREEZE
01378 // format: "New:type(num_arg) container=n @coord"
01379 //      or "New:type(num_arg) @coord"
01380 void NodeInfo::writeNew(newNode *n, int container) {
01381   if(_read_mode || !n) return;
01382   if(node2index[n] > 0) return;
01383   typeNode *type = n->type();
01384 
01385   ostringstream ost;
01386   ost << TypNames[New] << ':' << type_string(type) << "(" << n->args().size()
01387       << ")";
01388 
01389   if(container>0)
01390     ost << " container=" << container;
01391 
01392   ost << " @" << n->coord() << '\0';
01393   string s = ost.str() + string("\n");
01394   fputs(s.c_str(), _file);
01395   index2node[++_line] = n;
01396   node2index[n] = _line;
01397   strings[_line]   = s;
01398   fflush(_file);
01399 } // writeNew
01400 
01401 #endif // J_BREEZE
01402 
01403 
01404 // format: "<typ>:container=n @coord"
01405 void NodeInfo::writeExpr(exprNode *e, int container) {
01406   if(_read_mode || !e) return;
01407   if(node2index[e] > 0) return;
01408   if(e->coord().file()==-1) {
01409     cerr << "NodeInfo::writeExpr: cannot write if coord is unknown.\n";
01410     exit(1);
01411   }
01412   assert(container>0);
01413   ostringstream ost;
01414   ost << TypNames[e->typ()] << ':' << " container=" << container;
01415   ost << " @" << e->coord() << '\0';
01416   string str = ost.str() + string("\n");
01417   fputs(str.c_str(), _file);
01418   index2node[++_line] = e;
01419   node2index[e] = _line;
01420   strings[_line]   = str;
01421   fflush(_file);
01422 } // writeExpr
01423 
01424 
01425 // format: "Decl:name container=n @coord"
01426 void NodeInfo::writeDecl(declNode *decl, int container) {
01427   if(_read_mode || !decl) return;
01428   if(node2index[decl] > 0) return;
01429   if(container<=0) return;
01430 
01431   ostringstream ost;
01432   ost << TypNames[Decl] << ":" << decl->name() << " container=" << container
01433       << string(" @") << decl->coord() << '\0';
01434   string str = ost.str() + string("\n");
01435   fputs(str.c_str(), _file);
01436   index2node[++_line] = decl;
01437   node2index[decl] = _line;
01438   strings[_line]   = str;
01439   fflush(_file);
01440 } // writeDecl
01441 
01442 
01443 // format: "<typ>:container=n @coord"
01444 void NodeInfo::writeStmt(stmtNode *s, int container) {
01445   if(_read_mode || !s) return;
01446   if(node2index[s] > 0) return;
01447   if(s->coord().file()==-1) {
01448     cerr << "NodeInfo::writeStmt: cannot write if coord is unknown.\n";
01449     exit(1);
01450   }
01451   assert(container>0);
01452   ostringstream ost;
01453   ost << TypNames[s->typ()] << ':' << " container=" << container;
01454   ost << " @" << s->coord() << '\0';
01455   string str = ost.str() + string("\n");
01456   fputs(str.c_str(), _file);
01457   index2node[++_line] = s;
01458   node2index[s] = _line;
01459   strings[_line]   = str;
01460   fflush(_file);
01461 } // writeStmt
01462 
01463 void NodeInfo::writeString(string s) {
01464   fputs(s.c_str(), _file);
01465   index2node[++_line] = NULL;
01466   strings[_line]   = s;
01467   fflush(_file);
01468 } // writeString
01469 
01471 
01472 Coord NodeInfo::getCoord(string s, unitNode **unit) {
01473   *unit = NULL;
01474   int pos = s.rfind('@');
01475   if(pos==-1) {
01476     if(_verbose)
01477       cerr << "coord not found\n";
01478     return Coord::Unknown;
01479   }
01480   string sub = s.substr(pos+1, string::npos);
01481   pos = sub.rfind(':');
01482   string offset = sub.substr(pos+1,string::npos);
01483   sub = sub.substr(0,pos),
01484   pos = sub.rfind(':');
01485   string filename = sub.substr(0,pos),
01486          line = sub.substr(pos+1,string::npos);
01487   int fileno = 0;
01488   while(fileno < (int)CBZ::Files.size()) {
01489     if(CBZ::Files[fileno] == filename) break;
01490     fileno++;
01491   }
01492   if(fileno >= (int)CBZ::Files.size()) {
01493     if(_verbose && filename!="(unknown)\n") {
01494       cerr << "cannot find fileno for file " << filename << endl;
01495       cerr << "s is " << s << endl;
01496       exit(1);
01497     }
01498     return Coord::Unknown;
01499   }
01500 
01501   // obtain unitNode
01502   for(unit_list_p u=CBZ::Program.begin(); u!=CBZ::Program.end(); u++)
01503     if((*u)->input_file() == filename) {
01504       *unit = *u;
01505       break;
01506     }
01507 #ifdef J_BREEZE  // in C, could be a header file not in CBZ::Program.
01508   assert(*unit);
01509 #endif
01510 
01511   return Coord(atoi(line.c_str()), atoi(offset.c_str()), fileno);
01512 } // getCoord
01513 
01514 
01515 typeNode *NodeInfo::getType(unitNode *unit, string s) {
01516   // get rid of trailing spaces
01517   while(s[s.length()-1]==' ')
01518     s.resize(s.length()-1);
01519 
01520   int pos = s.find('$');
01521   string top_string;
01522   if(pos==-1) top_string = s;
01523   else        top_string = s.substr(0,pos);
01524 
01525   // search for top type in unit
01526   typeNode *type = NULL;
01527   if(unit) {
01528     for(def_list_p def=unit->defs().begin(); def!=unit->defs().end(); def++) {
01529       if((*def)->typ() != Decl) continue;
01530       declNode *d = (declNode*) *def;
01531       if(d->name() == top_string) {
01532         type = d->type();
01533         break;
01534       }
01535     }
01536   }
01537 
01538 #ifdef J_BREEZE
01539   if(!type) {
01540     ArrayClass::clazz();
01541     type = getLibType(top_string);
01542   }
01543 #endif
01544 
01545   if(!type) {
01546     if(_verbose) {
01547       cerr << "getType: cannot find top-type " << top_string << endl;
01548       if(unit) cerr << " in unit " << unit->input_file() << endl;
01549     }
01550     return NULL;
01551   }
01552   if(pos==-1) return type;  // no nested type, done
01553 
01554 #ifdef J_BREEZE
01555   string nested_string = s.substr(pos+1, string::npos);
01556   while(nested_string.length() > 0) {
01557     pos = nested_string.find('$');
01558     string next;
01559     if(pos==-1) next = nested_string;
01560     else        next = nested_string.substr(0,pos);
01561     typeNode *nested = NULL;
01562 
01563     // is next a local/anonymous class?
01564     if(next.find('@') == -1) {
01565       // not a local/anonymous class
01566       field_list fields;
01567       if(type->typ() == Class)          fields=((classNode*) type)->fields();
01568       else if(type->typ() == Interface) fields=((interfaceNode*)type)->fields();
01569       else assert(false);
01570 
01571       for(field_list_p f=fields.begin(); f!=fields.end(); f++) {
01572         if((*f)->typ() != MemberType) continue;
01573         declNode *d = ((membertypeNode*)*f)->member();
01574         if(d->name() == next) {
01575           nested = d->type();
01576           break;
01577         }
01578       }
01579 
01580     } else {
01581       // local/anonymous class, with the help from NodeLocator
01582       nested = (classNode*) NodeLocator::findClass(next, type);
01583       if(nested)
01584         if(((classNode*)nested)->enclosing() != type)  // wrong nested
01585           nested = NULL;
01586     }
01587 
01588     if(!nested) {
01589       if(_verbose)
01590         cerr << "getType: cannot find type " << next << " in type "
01591              << typenameNode::type_name(type) << endl;
01592       return NULL;
01593     }
01594 
01595     // get ready for recursion
01596     type = nested;
01597     if(pos==-1) break;  // done with recursion
01598     nested_string = nested_string.substr(pos+1, string::npos);
01599   }
01600 #endif
01601 
01602   return type;
01603 } // getType
01604 
01605 
01606 #ifdef J_BREEZE
01607 typeNode *NodeInfo::getLibType(string s) {
01608   if(s.length() <= 0) return NULL;
01609   // cannot contain '@'
01610   if(s.find('@') != -1) return NULL;
01611 
01612   // get rid of trailing spaces
01613   while(s[s.length()-1]==' ')
01614     s.resize(s.length()-1);
01615 
01616   // if s is a fully qualified name (including package name):
01617   // format of string: eg. java.io.PrintStream
01618   string remaining = s;
01619   packageNode *package = NULL;
01620   do {
01621     int pos = remaining.find('.'); // '.' was not converted to '$' in
01622                                    // type_string()
01623     if(pos == -1) break;
01624     string prefix = remaining.substr(0, pos);
01625     if(!package)
01626       package = packageNode::findPackage(prefix.c_str());  // main package
01627     else
01628       package = // sub-package
01629         (packageNode*) package->findMember(prefix.c_str(), true, false);
01630     remaining = remaining.substr(pos+1, string::npos);
01631   } while(package);
01632 
01633   if(package) {
01634     declNode *decl =
01635       (declNode*) package->findMember(remaining.c_str(), false, true);
01636     if(decl) return decl->type();
01637   }
01638 
01639   // last resort
01640   return standardPackage::findType(s.c_str());
01641 } // getLibType
01642 #endif
01643 
01644 
01645 #ifdef J_BREEZE
01646 string NodeInfo::type_string(typeNode *ty) {
01647   string s = "";
01648   bool unknown_coord = (ty->coord().file()==-1);
01649   packageNode *package = NULL;
01650   while(ty) {
01651     ty = classHierarchy::def_type(ty);
01652     string extra = "";
01653     bool localOrAnony = (ty->typ()==Class &&
01654                         (((classNode*)ty)->declLoc()==classNode::Local ||
01655                          ((classNode*)ty)->declLoc()==classNode::Anonymous));
01656     if(localOrAnony) {
01657       ostringstream ost;
01658       ost << "@" << ty->coord() << '\0';
01659       extra = ost.str() + string("\0");
01660       // get rid of tail ".java"
01661       /*int pos = extra.rfind(".java");
01662       extra = extra.replace(pos,5,""); */
01663     }
01664 
01665     if(s.length()==0) {
01666       if(extra != "")
01667         s = typenameNode::type_name(ty) + extra;
01668       else
01669         s = typenameNode::type_name(ty);
01670     } else {
01671       string s1;
01672       if(extra != "")
01673         s1 = typenameNode::type_name(ty) + extra + "$" + s;
01674       else
01675         s1 = typenameNode::type_name(ty) + "$" + s;
01676       s = s1;
01677     }
01678     if(ty->typ()==Class) {
01679       package = ((classNode*)ty)->package();
01680       if(localOrAnony)
01681         ty = ((classNode*)ty)->enclosing();
01682       else
01683         break;
01684     } else if(ty->typ()==Interface) {
01685       package = ((interfaceNode*)ty)->package();
01686       if(localOrAnony)
01687         ty = ((interfaceNode*)ty)->enclosing();
01688       else
01689         break;
01690     } else if(ty->typ()==Array) {
01691       package = packageNode::unnamed();
01692       break;
01693     } else
01694       break;
01695   }
01696 
01697   if(unknown_coord) {
01698     // also add in package name
01699     assert(package);
01700     string s1 = package->fullname() + '.' + s;
01701     s = s1;
01702   }
01703 
01704   return s;
01705 } // type_string
01706 #endif
01707 
01708 
01709 #ifndef J_BREEZE
01710 string NodeInfo::type_name(typeNode *t) {
01711   assert(t!=NULL);
01712   switch(t->typ()) {
01713     case Prim: {
01714       basic_type basic = ((primNode*)t)->basic();
01715       return basic.to_string();
01716     }
01717 
01718     case Tdef:
01719       return ((tdefNode*)t)->name();
01720 
01721     case Array:
01722       return type_name( ((arrayNode*) t)->type() ) + "[]\0";
01723 
01724     case Ptr:
01725       return type_name( ((ptrNode*) t)->type() ) + "*\0";
01726 
01727     case Func:
01728       return "(func)";
01729 
01730     case Struct:
01731     case Union:
01732     case Enum:
01733       return string(TypNames[t->typ()]) + "-" + ((sueNode*)t)->spec()->name();
01734 
01735     case sueSpec:
01736 
01737     default:
01738       cout << "typenameNode::type_name: unknown typenode "
01739            << t->typ() << endl;
01740       exit(1);
01741   }
01742 } // type_name
01743 
01744 
01745 typeNode *NodeInfo::def_type(typeNode *ty) {
01746     if(!ty) return NULL;
01747   switch(ty->typ()) {
01748     case Prim:
01749     case Array:
01750     case Ptr:
01751     case Func:
01752     case sueSpec: return ty;
01753     case Struct: case Union: case Enum:
01754       return ((sueNode*)ty)->spec();
01755     case Tdef: {
01756       typeNode *base = def_type( ((tdefNode*) ty)->def());
01757       if(base) return base;
01758       else return ty;
01759     }
01760     default:
01761       cerr << "def_type: shouldn't have typ " << ty->typ() << endl;
01762       exit(1);
01763   }
01764 } // def_type
01765 
01766 arrayNode *NodeInfo::canonical(arrayNode *arr) {
01767   if(!arr) return NULL;
01768   typeNode *base = arr->type();
01769   arrayNode *result;
01770   switch(base->typ()) {
01771     case Prim:
01772       result = NULL;
01773       for(list<arrayNode*>::iterator c=_canonical1.begin();
01774           c!=_canonical1.end(); c++)
01775         if(((primNode*) (*c)->type())->basic() == ((primNode*)base)->basic()) {
01776           result=*c;  break;  // found
01777         }
01778       if(!result) {
01779         _canonical1.push_back(arr);
01780         result = arr;
01781       }
01782       break;
01783     case Array:
01784       base = canonical((arrayNode*) base);
01785       result = _canonical2[base];
01786       if(!result) result = _canonical2[base] = arr;
01787       break;
01788     default:
01789       base = def_type(base);
01790       result = _canonical2[base];
01791       if(!result) result = _canonical2[base] = arr;
01792   }
01793   return result;
01794 } // canonical
01795 #endif // not J_BREEZE
01796 

Generated on August 27, 2003
Back to the C-Breeze home page