|
|
1.1 ! root 1: /* Code for handling XREF output from GNU C++. ! 2: Copyright (C) 1992, 1993 Free Software Foundation, Inc. ! 3: Contributed by Michael Tiemann ([email protected]) ! 4: ! 5: This file is part of GNU CC. ! 6: ! 7: GNU CC is free software; you can redistribute it and/or modify ! 8: it under the terms of the GNU General Public License as published by ! 9: the Free Software Foundation; either version 2, or (at your option) ! 10: any later version. ! 11: ! 12: GNU CC is distributed in the hope that it will be useful, ! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 15: GNU General Public License for more details. ! 16: ! 17: You should have received a copy of the GNU General Public License ! 18: along with GNU CC; see the file COPYING. If not, write to ! 19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 20: ! 21: ! 22: #include "config.h" ! 23: #include "tree.h" ! 24: #include <stdio.h> ! 25: #include "cp-tree.h" ! 26: #include "input.h" ! 27: ! 28: #include <ctype.h> ! 29: ! 30: extern char *getpwd (); ! 31: ! 32: extern char *index (); ! 33: extern char *rindex (); ! 34: ! 35: /* The character(s) used to join a directory specification (obtained with ! 36: getwd or equivalent) with a non-absolute file name. */ ! 37: ! 38: #ifndef FILE_NAME_JOINER ! 39: #define FILE_NAME_JOINER "/" ! 40: #endif ! 41: ! 42: /* Nonzero if NAME as a file name is absolute. */ ! 43: #ifndef FILE_NAME_ABSOLUTE_P ! 44: #define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/') ! 45: #endif ! 46: ! 47: /* For cross referencing. */ ! 48: ! 49: int flag_gnu_xref; ! 50: ! 51: /************************************************************************/ ! 52: /* */ ! 53: /* Common definitions */ ! 54: /* */ ! 55: /************************************************************************/ ! 56: ! 57: #ifndef TRUE ! 58: #define TRUE 1 ! 59: #endif ! 60: #ifndef FALSE ! 61: #define FALSE 0 ! 62: #endif ! 63: #ifndef NULL ! 64: #define NULL 0 ! 65: #endif ! 66: ! 67: #define PALLOC(typ) ((typ *) calloc(1,sizeof(typ))) ! 68: ! 69: ! 70: /* Return a malloc'd copy of STR. */ ! 71: #define SALLOC(str) \ ! 72: ((char *) ((str) == NULL ? NULL \ ! 73: : (char *) strcpy ((char *) malloc (strlen ((str)) + 1), (str)))) ! 74: #define SFREE(str) (str != NULL && (free(str),0)) ! 75: ! 76: #define STREQL(s1,s2) (strcmp((s1),(s2)) == 0) ! 77: #define STRNEQ(s1,s2) (strcmp((s1),(s2)) != 0) ! 78: #define STRLSS(s1,s2) (strcmp((s1),(s2)) < 0) ! 79: #define STRLEQ(s1,s2) (strcmp((s1),(s2)) <= 0) ! 80: #define STRGTR(s1,s2) (strcmp((s1),(s2)) > 0) ! 81: #define STRGEQ(s1,s2) (strcmp((s1),(s2)) >= 0) ! 82: ! 83: /************************************************************************/ ! 84: /* */ ! 85: /* Type definitions */ ! 86: /* */ ! 87: /************************************************************************/ ! 88: ! 89: ! 90: typedef struct _XREF_FILE * XREF_FILE; ! 91: typedef struct _XREF_SCOPE * XREF_SCOPE; ! 92: ! 93: typedef struct _XREF_FILE ! 94: { ! 95: char *name; ! 96: char *outname; ! 97: XREF_FILE next; ! 98: } XREF_FILE_INFO; ! 99: ! 100: typedef struct _XREF_SCOPE ! 101: { ! 102: int gid; ! 103: int lid; ! 104: XREF_FILE file; ! 105: int start; ! 106: XREF_SCOPE outer; ! 107: } XREF_SCOPE_INFO; ! 108: ! 109: /************************************************************************/ ! 110: /* */ ! 111: /* Local storage */ ! 112: /* */ ! 113: /************************************************************************/ ! 114: ! 115: static char doing_xref = 0; ! 116: static FILE * xref_file = NULL; ! 117: static char xref_name[1024]; ! 118: static XREF_FILE all_files = NULL; ! 119: static char * wd_name = NULL; ! 120: static XREF_SCOPE cur_scope = NULL; ! 121: static int scope_ctr = 0; ! 122: static XREF_FILE last_file = NULL; ! 123: static tree last_fndecl = NULL; ! 124: ! 125: /************************************************************************/ ! 126: /* */ ! 127: /* Forward definitions */ ! 128: /* */ ! 129: /************************************************************************/ ! 130: ! 131: extern void GNU_xref_begin(); ! 132: extern void GNU_xref_end(); ! 133: extern void GNU_xref_file(); ! 134: extern void GNU_xref_start_scope(); ! 135: extern void GNU_xref_end_scope(); ! 136: extern void GNU_xref_ref(); ! 137: extern void GNU_xref_decl(); ! 138: extern void GNU_xref_call(); ! 139: extern void GNU_xref_function(); ! 140: extern void GNU_xref_assign(); ! 141: extern void GNU_xref_hier(); ! 142: extern void GNU_xref_member(); ! 143: ! 144: static void gen_assign(); ! 145: static XREF_FILE find_file(); ! 146: static char * filename(); ! 147: static char * fctname(); ! 148: static char * declname(); ! 149: static void simplify_type(); ! 150: static char * fixname(); ! 151: static void open_xref_file(); ! 152: ! 153: extern char * type_as_string(); ! 154: ! 155: /* Start cross referencing. FILE is the name of the file we xref. */ ! 156: ! 157: void ! 158: GNU_xref_begin (file) ! 159: char *file; ! 160: { ! 161: doing_xref = 1; ! 162: ! 163: if (file != NULL && STRNEQ (file,"-")) ! 164: { ! 165: open_xref_file(file); ! 166: GNU_xref_file(file); ! 167: } ! 168: } ! 169: ! 170: /* Finish cross-referencing. ERRCNT is the number of errors ! 171: we encountered. */ ! 172: ! 173: void ! 174: GNU_xref_end (ect) ! 175: int ect; ! 176: { ! 177: XREF_FILE xf; ! 178: ! 179: if (!doing_xref) return; ! 180: ! 181: xf = find_file (input_filename); ! 182: if (xf == NULL) return; ! 183: ! 184: while (cur_scope != NULL) ! 185: GNU_xref_end_scope(cur_scope->gid,0,0,0,0); ! 186: ! 187: doing_xref = 0; ! 188: ! 189: if (xref_file == NULL) return; ! 190: ! 191: fclose (xref_file); ! 192: ! 193: xref_file = NULL; ! 194: all_files = NULL; ! 195: ! 196: if (ect > 0) unlink (xref_name); ! 197: } ! 198: ! 199: /* Write out xref for file named NAME. */ ! 200: ! 201: void ! 202: GNU_xref_file (name) ! 203: char *name; ! 204: { ! 205: XREF_FILE xf; ! 206: ! 207: if (!doing_xref || name == NULL) return; ! 208: ! 209: if (xref_file == NULL) ! 210: { ! 211: open_xref_file (name); ! 212: if (!doing_xref) return; ! 213: } ! 214: ! 215: if (all_files == NULL) ! 216: fprintf(xref_file,"SCP * 0 0 0 0 RESET\n"); ! 217: ! 218: xf = find_file (name); ! 219: if (xf != NULL) return; ! 220: ! 221: xf = PALLOC (XREF_FILE_INFO); ! 222: xf->name = SALLOC (name); ! 223: xf->next = all_files; ! 224: all_files = xf; ! 225: ! 226: if (wd_name == NULL) ! 227: wd_name = getpwd (); ! 228: ! 229: if (FILE_NAME_ABSOLUTE_P (name) || ! wd_name) ! 230: xf->outname = xf->name; ! 231: else ! 232: { ! 233: char *nmbuf ! 234: = (char *) malloc (strlen (wd_name) + strlen (FILE_NAME_JOINER) ! 235: + strlen (name) + 1); ! 236: sprintf (nmbuf, "%s%s%s", wd_name, FILE_NAME_JOINER, name); ! 237: name = nmbuf; ! 238: xf->outname = nmbuf; ! 239: } ! 240: ! 241: fprintf (xref_file, "FIL %s %s 0\n", name, wd_name); ! 242: ! 243: filename (xf); ! 244: fctname (NULL); ! 245: } ! 246: ! 247: /* Start a scope identified at level ID. */ ! 248: ! 249: void ! 250: GNU_xref_start_scope (id) ! 251: HOST_WIDE_INT id; ! 252: { ! 253: XREF_SCOPE xs; ! 254: XREF_FILE xf; ! 255: ! 256: if (!doing_xref) return; ! 257: xf = find_file (input_filename); ! 258: ! 259: xs = PALLOC (XREF_SCOPE_INFO); ! 260: xs->file = xf; ! 261: xs->start = lineno; ! 262: if (xs->start <= 0) xs->start = 1; ! 263: xs->gid = id; ! 264: xs->lid = ++scope_ctr; ! 265: xs->outer = cur_scope; ! 266: cur_scope = xs; ! 267: } ! 268: ! 269: /* Finish a scope at level ID. ! 270: INID is ??? ! 271: PRM is ??? ! 272: KEEP is nonzero iff this scope is retained (nonzero if it's ! 273: a compiler-generated invisible scope). ! 274: TRNS is ??? */ ! 275: ! 276: void ! 277: GNU_xref_end_scope (id,inid,prm,keep,trns) ! 278: HOST_WIDE_INT id; ! 279: HOST_WIDE_INT inid; ! 280: int prm,keep,trns; ! 281: { ! 282: XREF_FILE xf; ! 283: XREF_SCOPE xs,lxs,oxs; ! 284: char *stype; ! 285: ! 286: if (!doing_xref) return; ! 287: xf = find_file (input_filename); ! 288: if (xf == NULL) return; ! 289: ! 290: lxs = NULL; ! 291: for (xs = cur_scope; xs != NULL; xs = xs->outer) ! 292: { ! 293: if (xs->gid == id) break; ! 294: lxs = xs; ! 295: } ! 296: if (xs == NULL) return; ! 297: ! 298: if (inid != 0) { ! 299: for (oxs = cur_scope; oxs != NULL; oxs = oxs->outer) { ! 300: if (oxs->gid == inid) break; ! 301: } ! 302: if (oxs == NULL) return; ! 303: inid = oxs->lid; ! 304: } ! 305: ! 306: if (prm == 2) stype = "SUE"; ! 307: else if (prm != 0) stype = "ARGS"; ! 308: else if (keep == 2 || inid != 0) stype = "INTERN"; ! 309: else stype = "EXTERN"; ! 310: ! 311: fprintf (xref_file,"SCP %s %d %d %d %d %s\n", ! 312: filename (xf), xs->start, lineno,xs->lid, inid, stype); ! 313: ! 314: if (lxs == NULL) cur_scope = xs->outer; ! 315: else lxs->outer = xs->outer; ! 316: ! 317: free (xs); ! 318: } ! 319: ! 320: /* Output a reference to NAME in FNDECL. */ ! 321: ! 322: void ! 323: GNU_xref_ref (fndecl,name) ! 324: tree fndecl; ! 325: char *name; ! 326: { ! 327: XREF_FILE xf; ! 328: ! 329: if (!doing_xref) return; ! 330: xf = find_file (input_filename); ! 331: if (xf == NULL) return; ! 332: ! 333: fprintf (xref_file, "REF %s %d %s %s\n", ! 334: filename (xf), lineno, fctname (fndecl), name); ! 335: } ! 336: ! 337: /* Output a reference to DECL in FNDECL. */ ! 338: ! 339: void ! 340: GNU_xref_decl (fndecl,decl) ! 341: tree fndecl; ! 342: tree decl; ! 343: { ! 344: XREF_FILE xf,xf1; ! 345: char *cls; ! 346: char *name; ! 347: char buf[10240]; ! 348: int uselin; ! 349: ! 350: if (!doing_xref) return; ! 351: xf = find_file (input_filename); ! 352: if (xf == NULL) return; ! 353: ! 354: uselin = FALSE; ! 355: ! 356: if (TREE_CODE (decl) == TYPE_DECL) cls = "TYPEDEF"; ! 357: else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; ! 358: else if (TREE_CODE (decl) == VAR_DECL) ! 359: { ! 360: if (fndecl == NULL && TREE_STATIC(decl) ! 361: && TREE_READONLY(decl) && DECL_INITIAL(decl) != 0 ! 362: && !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) ! 363: && DECL_MODE(decl) != BLKmode) cls = "CONST"; ! 364: else if (DECL_EXTERNAL(decl)) cls = "EXTERN"; ! 365: else if (TREE_PUBLIC(decl)) cls = "EXTDEF"; ! 366: else if (TREE_STATIC(decl)) cls = "STATIC"; ! 367: else if (DECL_REGISTER(decl)) cls = "REGISTER"; ! 368: else cls = "AUTO"; ! 369: } ! 370: else if (TREE_CODE (decl) == PARM_DECL) cls = "PARAM"; ! 371: else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; ! 372: else if (TREE_CODE (decl) == CONST_DECL) cls = "CONST"; ! 373: else if (TREE_CODE (decl) == FUNCTION_DECL) ! 374: { ! 375: if (DECL_EXTERNAL (decl)) cls = "EXTERN"; ! 376: else if (TREE_PUBLIC (decl)) cls = "EFUNCTION"; ! 377: else cls = "SFUNCTION"; ! 378: } ! 379: else if (TREE_CODE (decl) == LABEL_DECL) cls = "LABEL"; ! 380: else if (TREE_CODE (decl) == UNION_TYPE) ! 381: { ! 382: cls = "UNIONID"; ! 383: decl = TYPE_NAME (decl); ! 384: uselin = TRUE; ! 385: } ! 386: else if (TREE_CODE (decl) == RECORD_TYPE) ! 387: { ! 388: if (CLASSTYPE_DECLARED_CLASS (decl)) cls = "CLASSID"; ! 389: else if (IS_SIGNATURE (decl)) cls = "SIGNATUREID"; ! 390: else cls = "STRUCTID"; ! 391: decl = TYPE_NAME (decl); ! 392: uselin = TRUE; ! 393: } ! 394: else if (TREE_CODE (decl) == ENUMERAL_TYPE) ! 395: { ! 396: cls = "ENUMID"; ! 397: decl = TYPE_NAME (decl); ! 398: uselin = TRUE; ! 399: } ! 400: else if (TREE_CODE (decl) == TEMPLATE_DECL) ! 401: { ! 402: if (DECL_TEMPLATE_IS_CLASS (decl)) ! 403: cls = "CLASSTEMP"; ! 404: else if (TREE_CODE (DECL_RESULT (decl)) == FUNCTION_DECL) ! 405: cls = "FUNCTEMP"; ! 406: else if (TREE_CODE (DECL_RESULT (decl)) == VAR_DECL) ! 407: cls = "VARTEMP"; ! 408: else ! 409: my_friendly_abort (358); ! 410: uselin = TRUE; ! 411: } ! 412: else cls = "UNKNOWN"; ! 413: ! 414: if (decl == NULL || DECL_NAME (decl) == NULL) return; ! 415: ! 416: if (uselin && decl->decl.linenum > 0 && decl->decl.filename != NULL) ! 417: { ! 418: xf1 = find_file (decl->decl.filename); ! 419: if (xf1 != NULL) ! 420: { ! 421: lineno = decl->decl.linenum; ! 422: xf = xf1; ! 423: } ! 424: } ! 425: ! 426: if (DECL_ASSEMBLER_NAME (decl)) ! 427: name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); ! 428: else ! 429: name = IDENTIFIER_POINTER (DECL_NAME (decl)); ! 430: ! 431: strcpy (buf, type_as_string (TREE_TYPE (decl), 0)); ! 432: simplify_type (buf); ! 433: ! 434: fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", ! 435: filename(xf), lineno, name, ! 436: (cur_scope != NULL ? cur_scope->lid : 0), ! 437: cls, fctname(fndecl), buf); ! 438: ! 439: if (STREQL (cls, "STRUCTID") || STREQL (cls, "UNIONID") ! 440: || STREQL (cls, "SIGNATUREID")) ! 441: { ! 442: cls = "CLASSID"; ! 443: fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", ! 444: filename(xf), lineno,name, ! 445: (cur_scope != NULL ? cur_scope->lid : 0), ! 446: cls, fctname(fndecl), buf); ! 447: } ! 448: } ! 449: ! 450: /* Output a reference to a call to NAME in FNDECL. */ ! 451: ! 452: void ! 453: GNU_xref_call (fndecl, name) ! 454: tree fndecl; ! 455: char *name; ! 456: { ! 457: XREF_FILE xf; ! 458: char buf[1024]; ! 459: char *s; ! 460: ! 461: if (!doing_xref) return; ! 462: xf = find_file (input_filename); ! 463: if (xf == NULL) return; ! 464: name = fixname (name, buf); ! 465: ! 466: for (s = name; *s != 0; ++s) ! 467: if (*s == '_' && s[1] == '_') break; ! 468: if (*s != 0) GNU_xref_ref (fndecl, name); ! 469: ! 470: fprintf (xref_file, "CAL %s %d %s %s\n", ! 471: filename (xf), lineno, name, fctname (fndecl)); ! 472: } ! 473: ! 474: /* Output cross-reference info about FNDECL. If non-NULL, ! 475: ARGS are the arguments for the function (i.e., before the FUNCTION_DECL ! 476: has been fully built). */ ! 477: ! 478: void ! 479: GNU_xref_function (fndecl, args) ! 480: tree fndecl; ! 481: tree args; ! 482: { ! 483: XREF_FILE xf; ! 484: int ct; ! 485: char buf[1024]; ! 486: ! 487: if (!doing_xref) return; ! 488: xf = find_file (input_filename); ! 489: if (xf == NULL) return; ! 490: ! 491: ct = 0; ! 492: buf[0] = 0; ! 493: if (args == NULL) args = DECL_ARGUMENTS (fndecl); ! 494: ! 495: GNU_xref_decl (NULL, fndecl); ! 496: ! 497: for ( ; args != NULL; args = TREE_CHAIN (args)) ! 498: { ! 499: GNU_xref_decl (fndecl,args); ! 500: if (ct != 0) strcat (buf,","); ! 501: strcat (buf, declname (args)); ! 502: ++ct; ! 503: } ! 504: ! 505: fprintf (xref_file, "PRC %s %d %s %d %d %s\n", ! 506: filename(xf), lineno, declname(fndecl), ! 507: (cur_scope != NULL ? cur_scope->lid : 0), ! 508: ct, buf); ! 509: } ! 510: ! 511: /* Output cross-reference info about an assignment to NAME. */ ! 512: ! 513: void ! 514: GNU_xref_assign(name) ! 515: tree name; ! 516: { ! 517: XREF_FILE xf; ! 518: ! 519: if (!doing_xref) return; ! 520: xf = find_file(input_filename); ! 521: if (xf == NULL) return; ! 522: ! 523: gen_assign(xf, name); ! 524: } ! 525: ! 526: static void ! 527: gen_assign(xf, name) ! 528: XREF_FILE xf; ! 529: tree name; ! 530: { ! 531: char *s; ! 532: ! 533: s = NULL; ! 534: ! 535: switch (TREE_CODE (name)) ! 536: { ! 537: case IDENTIFIER_NODE : ! 538: s = IDENTIFIER_POINTER(name); ! 539: break; ! 540: case VAR_DECL : ! 541: s = declname(name); ! 542: break; ! 543: case COMPONENT_REF : ! 544: gen_assign(xf, TREE_OPERAND(name, 0)); ! 545: gen_assign(xf, TREE_OPERAND(name, 1)); ! 546: break; ! 547: case INDIRECT_REF : ! 548: case OFFSET_REF : ! 549: case ARRAY_REF : ! 550: case BUFFER_REF : ! 551: gen_assign(xf, TREE_OPERAND(name, 0)); ! 552: break; ! 553: case COMPOUND_EXPR : ! 554: gen_assign(xf, TREE_OPERAND(name, 1)); ! 555: break; ! 556: default : ! 557: break; ! 558: } ! 559: ! 560: if (s != NULL) ! 561: fprintf(xref_file, "ASG %s %d %s\n", filename(xf), lineno, s); ! 562: } ! 563: ! 564: /* Output cross-reference info about a class hierarchy. ! 565: CLS is the class type of interest. BASE is a baseclass ! 566: for CLS. PUB and VIRT give the access info about ! 567: the class derivation. FRND is nonzero iff BASE is a friend ! 568: of CLS. ! 569: ! 570: ??? Needs to handle nested classes. */ ! 571: void ! 572: GNU_xref_hier(cls, base, pub, virt, frnd) ! 573: char *cls; ! 574: char *base; ! 575: int pub; ! 576: int virt; ! 577: int frnd; ! 578: { ! 579: XREF_FILE xf; ! 580: ! 581: if (!doing_xref) return; ! 582: xf = find_file(input_filename); ! 583: if (xf == NULL) return; ! 584: ! 585: fprintf(xref_file, "HIE %s %d %s %s %d %d %d\n", ! 586: filename(xf), lineno, cls, base, pub, virt, frnd); ! 587: } ! 588: ! 589: /* Output cross-reference info about class members. CLS ! 590: is the containing type; FLD is the class member. */ ! 591: ! 592: void ! 593: GNU_xref_member(cls, fld) ! 594: tree cls; ! 595: tree fld; ! 596: { ! 597: XREF_FILE xf; ! 598: char *prot; ! 599: int confg, pure; ! 600: char *d; ! 601: int i; ! 602: char buf[1024], bufa[1024]; ! 603: ! 604: if (!doing_xref) return; ! 605: xf = find_file(fld->decl.filename); ! 606: if (xf == NULL) return; ! 607: ! 608: if (TREE_PRIVATE (fld)) prot = "PRIVATE"; ! 609: else if (TREE_PROTECTED(fld)) prot = "PROTECTED"; ! 610: else prot = "PUBLIC"; ! 611: ! 612: confg = 0; ! 613: if (TREE_CODE (fld) == FUNCTION_DECL && DECL_CONST_MEMFUNC_P(fld)) ! 614: confg = 1; ! 615: else if (TREE_CODE (fld) == CONST_DECL) ! 616: confg = 1; ! 617: ! 618: pure = 0; ! 619: if (TREE_CODE (fld) == FUNCTION_DECL && DECL_ABSTRACT_VIRTUAL_P(fld)) ! 620: pure = 1; ! 621: ! 622: d = IDENTIFIER_POINTER(cls); ! 623: sprintf(buf, "%d%s", strlen(d), d); ! 624: i = strlen(buf); ! 625: strcpy(bufa, declname(fld)); ! 626: ! 627: #ifdef XREF_SHORT_MEMBER_NAMES ! 628: for (p = &bufa[1]; *p != 0; ++p) ! 629: { ! 630: if (p[0] == '_' && p[1] == '_' && p[2] >= '0' && p[2] <= '9') { ! 631: if (strncmp(&p[2], buf, i) == 0) *p = 0; ! 632: break; ! 633: } ! 634: else if (p[0] == '_' && p[1] == '_' && p[2] == 'C' && p[3] >= '0' && p[3] <= '9') { ! 635: if (strncmp(&p[3], buf, i) == 0) *p = 0; ! 636: break; ! 637: } ! 638: } ! 639: #endif ! 640: ! 641: fprintf(xref_file, "MEM %s %d %s %s %s %d %d %d %d %d %d %d\n", ! 642: filename(xf), fld->decl.linenum, d, bufa, prot, ! 643: (TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1), ! 644: (DECL_INLINE (fld) ? 1 : 0), ! 645: (DECL_FRIEND_P(fld) ? 1 : 0), ! 646: (DECL_VINDEX(fld) ? 1 : 0), ! 647: (TREE_STATIC(fld) ? 1 : 0), ! 648: pure, confg); ! 649: } ! 650: ! 651: /* Find file entry given name. */ ! 652: ! 653: static XREF_FILE ! 654: find_file(name) ! 655: char *name; ! 656: { ! 657: XREF_FILE xf; ! 658: ! 659: for (xf = all_files; xf != NULL; xf = xf->next) { ! 660: if (STREQL(name, xf->name)) break; ! 661: } ! 662: ! 663: return xf; ! 664: } ! 665: ! 666: /* Return filename for output purposes. */ ! 667: ! 668: static char * ! 669: filename(xf) ! 670: XREF_FILE xf; ! 671: { ! 672: if (xf == NULL) { ! 673: last_file = NULL; ! 674: return "*"; ! 675: } ! 676: ! 677: if (last_file == xf) return "*"; ! 678: ! 679: last_file = xf; ! 680: ! 681: return xf->outname; ! 682: } ! 683: ! 684: /* Return function name for output purposes. */ ! 685: ! 686: static char * ! 687: fctname(fndecl) ! 688: tree fndecl; ! 689: { ! 690: static char fctbuf[1024]; ! 691: char *s; ! 692: ! 693: if (fndecl == NULL && last_fndecl == NULL) return "*"; ! 694: ! 695: if (fndecl == NULL) ! 696: { ! 697: last_fndecl = NULL; ! 698: return "*TOP*"; ! 699: } ! 700: ! 701: if (fndecl == last_fndecl) return "*"; ! 702: ! 703: last_fndecl = fndecl; ! 704: ! 705: s = declname(fndecl); ! 706: s = fixname(s, fctbuf); ! 707: ! 708: return s; ! 709: } ! 710: ! 711: /* Return decl name for output purposes. */ ! 712: ! 713: static char * ! 714: declname(dcl) ! 715: tree dcl; ! 716: { ! 717: if (DECL_NAME (dcl) == NULL) return "?"; ! 718: ! 719: if (DECL_ASSEMBLER_NAME (dcl)) ! 720: return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (dcl)); ! 721: else ! 722: return IDENTIFIER_POINTER (DECL_NAME (dcl)); ! 723: } ! 724: ! 725: /* Simplify a type string by removing unneeded parenthesis. */ ! 726: ! 727: static void ! 728: simplify_type(typ) ! 729: char *typ; ! 730: { ! 731: char *s; ! 732: int lvl, i; ! 733: ! 734: i = strlen(typ); ! 735: while (i > 0 && isspace(typ[i-1])) typ[--i] = 0; ! 736: ! 737: if (i > 7 && STREQL(&typ[i-5], "const")) ! 738: { ! 739: typ[i-5] = 0; ! 740: i -= 5; ! 741: } ! 742: ! 743: if (typ[i-1] != ')') return; ! 744: ! 745: s = &typ[i-2]; ! 746: lvl = 1; ! 747: while (*s != 0) { ! 748: if (*s == ')') ++lvl; ! 749: else if (*s == '(') ! 750: { ! 751: --lvl; ! 752: if (lvl == 0) ! 753: { ! 754: s[1] = ')'; ! 755: s[2] = 0; ! 756: break; ! 757: } ! 758: } ! 759: --s; ! 760: } ! 761: ! 762: if (*s != 0 && s[-1] == ')') ! 763: { ! 764: --s; ! 765: --s; ! 766: if (*s == '(') s[2] = 0; ! 767: else if (*s == ':') { ! 768: while (*s != '(') --s; ! 769: s[1] = ')'; ! 770: s[2] = 0; ! 771: } ! 772: } ! 773: } ! 774: ! 775: /* Fixup a function name (take care of embedded spaces). */ ! 776: ! 777: static char * ! 778: fixname(nam, buf) ! 779: char *nam; ! 780: char *buf; ! 781: { ! 782: char *s, *t; ! 783: int fg; ! 784: ! 785: s = nam; ! 786: t = buf; ! 787: fg = 0; ! 788: ! 789: while (*s != 0) ! 790: { ! 791: if (*s == ' ') ! 792: { ! 793: *t++ = '\36'; ! 794: ++fg; ! 795: } ! 796: else *t++ = *s; ! 797: ++s; ! 798: } ! 799: *t = 0; ! 800: ! 801: if (fg == 0) return nam; ! 802: ! 803: return buf; ! 804: } ! 805: ! 806: /* Open file for xrefing. */ ! 807: ! 808: static void ! 809: open_xref_file(file) ! 810: char *file; ! 811: { ! 812: char *s, *t; ! 813: ! 814: #ifdef XREF_FILE_NAME ! 815: XREF_FILE_NAME (xref_name, file); ! 816: #else ! 817: s = rindex (file, '/'); ! 818: if (s == NULL) ! 819: sprintf (xref_name, ".%s.gxref", file); ! 820: else ! 821: { ! 822: ++s; ! 823: strcpy (xref_name, file); ! 824: t = rindex (xref_name, '/'); ! 825: ++t; ! 826: *t++ = '.'; ! 827: strcpy (t, s); ! 828: strcat (t, ".gxref"); ! 829: } ! 830: #endif /* no XREF_FILE_NAME */ ! 831: ! 832: xref_file = fopen(xref_name, "w"); ! 833: ! 834: if (xref_file == NULL) ! 835: { ! 836: error("Can't create cross-reference file `%s'", xref_name); ! 837: doing_xref = 0; ! 838: } ! 839: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.