00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041 #include "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
00085 buf[0] = '\0';
00086 fgets(buf, BUFSIZE, _file);
00087 ost << buf;
00088 } while (1);
00089
00090 ost << '\0';
00091 string s = ost.str();
00092 if(s=="") continue;
00093 strings[_line] = s;
00094
00095
00096
00097 if(s[0]=='#') continue;
00098
00099 Node *node = getNode(s);
00100 index2node[_line] = node;
00101 node2index[node] = _line;
00102 }
00103 }
00104 }
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
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
00149
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 }
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 }
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 }
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 }
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 }
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
00240 if(_name.find("<anonymous-") == -1) {
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 {
00247 if(c->declLoc() != classNode::Anonymous) return;
00248 if(match_coord(_coord, c->coord())) {
00249 assert(!_result);
00250 _result = c;
00251 }
00252 }
00253 }
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 }
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
00295
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 }
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 }
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 }
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 };
00337
00338 NodeInfo::NodeLocator *NodeInfo::NodeLocator::nl = NULL;
00339
00341
00342 NodeInfo::~NodeInfo() {
00343 fclose(_file);
00344 NodeLocator::done();
00345 }
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])
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 }
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
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
00451 #endif
00452 pos = s.rfind("[]");
00453 s.resize(pos);
00454 assert(s.rfind("[]")<0 || s.rfind("[]")>s.length());
00455 #ifndef J_BREEZE
00456 assert(s.rfind("*")<0 || s.rfind("*")>s.length());
00457 #endif
00458
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 }
00516
00517
00518 #ifndef J_BREEZE
00519 typeNode *NodeInfo::readsuef(string s) {
00520 if(!_read_mode) return NULL;
00521
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
00534 unitNode *unit;
00535 Coord coord = getCoord(s, &unit);
00536
00537
00538 pos = s.rfind('@');
00539 s = s.substr(0, pos);
00540
00541 while(s[s.length()-1]==' ')
00542 s.resize(s.length()-1);
00543
00544
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 {
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 }
00588
00589
00590 procNode *NodeInfo::readProc(string s) {
00591 if(!_read_mode) return NULL;
00592
00593 int pos = s.find(':');
00594 s = s.substr(pos+1, string::npos);
00595
00596
00597 unitNode *unit;
00598 Coord coord = getCoord(s, &unit);
00599
00600
00601 pos = s.rfind('@');
00602 s = s.substr(0, pos);
00603
00604
00605 pos = s.find('(');
00606 string args_string = s.substr(pos+1,string::npos);
00607 s = s.substr(0,pos);
00608
00609
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;
00631 }
00632
00633 #else
00634 typeNode *NodeInfo::readClassOrInterface(string s) {
00635 if(!_read_mode) return NULL;
00636
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
00647 unitNode *unit;
00648 Coord coord = getCoord(s, &unit);
00649
00650
00651
00652 pos = s.rfind('@');
00653 s = s.substr(0, pos);
00654
00655
00656 typeNode *type = getType(unit, s);
00657 if(!type) return NULL;
00658 assert(type->typ() == typ);
00659 return type;
00660 }
00661
00662
00663 methodNode *NodeInfo::readMethod(string s) {
00664 if(!_read_mode) return NULL;
00665
00666 int pos = s.find(':');
00667 s = s.substr(pos+1, string::npos);
00668
00669
00670 unitNode *unit;
00671 Coord coord = getCoord(s, &unit);
00672
00673
00674 pos = s.rfind('@');
00675 s = s.substr(0, pos);
00676
00677
00678 pos = s.find('(');
00679 string args_string = s.substr(pos+1,string::npos);
00680 s = s.substr(0,pos);
00681
00682
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
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;
00707 }
00708
00709
00710 constructorNode *NodeInfo::readConstructor(string s) {
00711 if(!_read_mode) return NULL;
00712
00713 int pos = s.find(':');
00714 s = s.substr(pos+1, string::npos);
00715
00716
00717 unitNode *unit;
00718 Coord coord = getCoord(s, &unit);
00719
00720
00721 pos = s.rfind('@');
00722 s = s.substr(0, pos);
00723
00724
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
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;
00748 }
00749 #endif // J_BREEZE
00750
00751
00752 bool NodeInfo::match_args(string args, decl_list formals) {
00753
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) {
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
00776 return false;
00777 }
00778
00779
00780 #ifdef J_BREEZE
00781 fieldvarNode *NodeInfo::readFieldvar(string s) {
00782 if(!_read_mode) return NULL;
00783
00784 int pos = s.find(':');
00785 s = s.substr(pos+1, string::npos);
00786
00787
00788 unitNode *unit;
00789 Coord coord = getCoord(s, &unit);
00790
00791
00792 pos = s.rfind(" @");
00793 s = s.substr(0, pos);
00794
00795
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
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;
00821 }
00822
00823
00824 fieldinitNode *NodeInfo::readFieldinit(string s) {
00825 if(!_read_mode) return NULL;
00826
00827 int pos = s.find(':');
00828 s = s.substr(pos+1, string::npos);
00829
00830
00831 unitNode *unit;
00832 Coord coord = getCoord(s, &unit);
00833
00834
00835 pos = s.rfind(" @");
00836 s = s.substr(0, pos);
00837
00838
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;
00855 }
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
00865 int pos = s.find(':');
00866 s = s.substr(pos+1, string::npos);
00867
00868
00869 unitNode *unit;
00870 Coord coord = getCoord(s, &unit);
00871
00872
00873
00874 pos = s.rfind('@');
00875 s = s.substr(0, pos);
00876
00877
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
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
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
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 }
00924
00925
00926 #ifdef J_BREEZE
00927 newNode *NodeInfo::readNew(string s) {
00928
00929 int pos = s.find(':');
00930 s = s.substr(pos+1, string::npos);
00931
00932
00933 unitNode *unit;
00934 Coord coord = getCoord(s, &unit);
00935
00936
00937
00938 pos = s.rfind('@');
00939 s = s.substr(0, pos);
00940
00941
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
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
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 }
00976 #endif // J_BREEZE
00977
00978
00979 Node *NodeInfo::readExprOrStmt(string s, NodeType typ) {
00980
00981 int pos = s.find(':');
00982 s = s.substr(pos+1, string::npos);
00983
00984
00985 unitNode *unit;
00986 Coord coord = getCoord(s, &unit);
00987
00988
00989
00990 pos = s.rfind('@');
00991 s = s.substr(0, pos);
00992
00993
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
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 }
01020
01021
01022 declNode *NodeInfo::readDecl(string s) {
01023
01024 int pos = s.find(':');
01025 s = s.substr(pos+1, string::npos);
01026
01027
01028 unitNode *unit;
01029 Coord coord = getCoord(s, &unit);
01030
01031
01032
01033 pos = s.rfind('@');
01034 s = s.substr(0, pos);
01035
01036
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
01050 pos = s.rfind(" container=");
01051 string name = s.substr(0,pos);
01052
01053
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 }
01069
01071
01072 #ifdef J_BREEZE
01073
01074
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 }
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;
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;
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 }
01218
01219
01220 #ifdef J_BREEZE
01221
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 }
01243
01244
01245
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 }
01266
01267
01268
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 }
01286
01287
01288
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 }
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 }
01326 #endif // J_BREEZE
01327
01328
01329
01330
01331
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 }
01375
01376
01377 #ifdef J_BREEZE
01378
01379
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 }
01400
01401 #endif // J_BREEZE
01402
01403
01404
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 }
01423
01424
01425
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 }
01441
01442
01443
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 }
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 }
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
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 }
01513
01514
01515 typeNode *NodeInfo::getType(unitNode *unit, string s) {
01516
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
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;
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
01564 if(next.find('@') == -1) {
01565
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
01582 nested = (classNode*) NodeLocator::findClass(next, type);
01583 if(nested)
01584 if(((classNode*)nested)->enclosing() != type)
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
01596 type = nested;
01597 if(pos==-1) break;
01598 nested_string = nested_string.substr(pos+1, string::npos);
01599 }
01600 #endif
01601
01602 return type;
01603 }
01604
01605
01606 #ifdef J_BREEZE
01607 typeNode *NodeInfo::getLibType(string s) {
01608 if(s.length() <= 0) return NULL;
01609
01610 if(s.find('@') != -1) return NULL;
01611
01612
01613 while(s[s.length()-1]==' ')
01614 s.resize(s.length()-1);
01615
01616
01617
01618 string remaining = s;
01619 packageNode *package = NULL;
01620 do {
01621 int pos = remaining.find('.');
01622
01623 if(pos == -1) break;
01624 string prefix = remaining.substr(0, pos);
01625 if(!package)
01626 package = packageNode::findPackage(prefix.c_str());
01627 else
01628 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
01640 return standardPackage::findType(s.c_str());
01641 }
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
01661
01662
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
01699 assert(package);
01700 string s1 = package->fullname() + '.' + s;
01701 s = s1;
01702 }
01703
01704 return s;
01705 }
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 }
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 }
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;
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 }
01795 #endif // not J_BREEZE
01796