|
|
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 cls = "STRUCTID"; ! 390: decl = TYPE_NAME (decl); ! 391: uselin = TRUE; ! 392: } ! 393: else if (TREE_CODE (decl) == ENUMERAL_TYPE) ! 394: { ! 395: cls = "ENUMID"; ! 396: decl = TYPE_NAME (decl); ! 397: uselin = TRUE; ! 398: } ! 399: else cls = "UNKNOWN"; ! 400: ! 401: if (decl == NULL || DECL_NAME (decl) == NULL) return; ! 402: ! 403: if (uselin && decl->decl.linenum > 0 && decl->decl.filename != NULL) ! 404: { ! 405: xf1 = find_file (decl->decl.filename); ! 406: if (xf1 != NULL) ! 407: { ! 408: lineno = decl->decl.linenum; ! 409: xf = xf1; ! 410: } ! 411: } ! 412: ! 413: if (DECL_ASSEMBLER_NAME (decl)) ! 414: name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); ! 415: else ! 416: name = IDENTIFIER_POINTER (DECL_NAME (decl)); ! 417: ! 418: strcpy (buf, type_as_string (TREE_TYPE (decl), 0)); ! 419: simplify_type (buf); ! 420: ! 421: fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", ! 422: filename(xf), lineno, name, ! 423: (cur_scope != NULL ? cur_scope->lid : 0), ! 424: cls, fctname(fndecl), buf); ! 425: ! 426: if (STREQL (cls, "STRUCTID") || STREQL (cls, "UNIONID")) ! 427: { ! 428: cls = "CLASSID"; ! 429: fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", ! 430: filename(xf), lineno,name, ! 431: (cur_scope != NULL ? cur_scope->lid : 0), ! 432: cls, fctname(fndecl), buf); ! 433: } ! 434: } ! 435: ! 436: /* Output a reference to a call to NAME in FNDECL. */ ! 437: ! 438: void ! 439: GNU_xref_call (fndecl, name) ! 440: tree fndecl; ! 441: char *name; ! 442: { ! 443: XREF_FILE xf; ! 444: char buf[1024]; ! 445: char *s; ! 446: ! 447: if (!doing_xref) return; ! 448: xf = find_file (input_filename); ! 449: if (xf == NULL) return; ! 450: name = fixname (name, buf); ! 451: ! 452: for (s = name; *s != 0; ++s) ! 453: if (*s == '_' && s[1] == '_') break; ! 454: if (*s != 0) GNU_xref_ref (fndecl, name); ! 455: ! 456: fprintf (xref_file, "CAL %s %d %s %s\n", ! 457: filename (xf), lineno, name, fctname (fndecl)); ! 458: } ! 459: ! 460: /* Output cross-reference info about FNDECL. If non-NULL, ! 461: ARGS are the arguments for the function (i.e., before the FUNCTION_DECL ! 462: has been fully built). */ ! 463: ! 464: void ! 465: GNU_xref_function (fndecl, args) ! 466: tree fndecl; ! 467: tree args; ! 468: { ! 469: XREF_FILE xf; ! 470: int ct; ! 471: char buf[1024]; ! 472: ! 473: if (!doing_xref) return; ! 474: xf = find_file (input_filename); ! 475: if (xf == NULL) return; ! 476: ! 477: ct = 0; ! 478: buf[0] = 0; ! 479: if (args == NULL) args = DECL_ARGUMENTS (fndecl); ! 480: ! 481: GNU_xref_decl (NULL, fndecl); ! 482: ! 483: for ( ; args != NULL; args = TREE_CHAIN (args)) ! 484: { ! 485: GNU_xref_decl (fndecl,args); ! 486: if (ct != 0) strcat (buf,","); ! 487: strcat (buf, declname (args)); ! 488: ++ct; ! 489: } ! 490: ! 491: fprintf (xref_file, "PRC %s %d %s %d %d %s\n", ! 492: filename(xf), lineno, declname(fndecl), ! 493: (cur_scope != NULL ? cur_scope->lid : 0), ! 494: ct, buf); ! 495: } ! 496: ! 497: /* Output cross-reference info about an assignment to NAME. */ ! 498: ! 499: void ! 500: GNU_xref_assign(name) ! 501: tree name; ! 502: { ! 503: XREF_FILE xf; ! 504: ! 505: if (!doing_xref) return; ! 506: xf = find_file(input_filename); ! 507: if (xf == NULL) return; ! 508: ! 509: gen_assign(xf, name); ! 510: } ! 511: ! 512: static void ! 513: gen_assign(xf, name) ! 514: XREF_FILE xf; ! 515: tree name; ! 516: { ! 517: char *s; ! 518: ! 519: s = NULL; ! 520: ! 521: switch (TREE_CODE (name)) ! 522: { ! 523: case IDENTIFIER_NODE : ! 524: s = IDENTIFIER_POINTER(name); ! 525: break; ! 526: case VAR_DECL : ! 527: s = declname(name); ! 528: break; ! 529: case COMPONENT_REF : ! 530: gen_assign(xf, TREE_OPERAND(name, 0)); ! 531: gen_assign(xf, TREE_OPERAND(name, 1)); ! 532: break; ! 533: case INDIRECT_REF : ! 534: case OFFSET_REF : ! 535: case ARRAY_REF : ! 536: case BUFFER_REF : ! 537: gen_assign(xf, TREE_OPERAND(name, 0)); ! 538: break; ! 539: case COMPOUND_EXPR : ! 540: gen_assign(xf, TREE_OPERAND(name, 1)); ! 541: break; ! 542: default : ! 543: break; ! 544: } ! 545: ! 546: if (s != NULL) ! 547: fprintf(xref_file, "ASG %s %d %s\n", filename(xf), lineno, s); ! 548: } ! 549: ! 550: /* Output cross-reference info about a class hierarchy. ! 551: CLS is the class type of interest. BASE is a baseclass ! 552: for CLS. PUB and VIRT give the visibility info about ! 553: the class derivation. FRND is nonzero iff BASE is a friend ! 554: of CLS. ! 555: ! 556: ??? Needs to handle nested classes. */ ! 557: void ! 558: GNU_xref_hier(cls, base, pub, virt, frnd) ! 559: char *cls; ! 560: char *base; ! 561: int pub; ! 562: int virt; ! 563: int frnd; ! 564: { ! 565: XREF_FILE xf; ! 566: ! 567: if (!doing_xref) return; ! 568: xf = find_file(input_filename); ! 569: if (xf == NULL) return; ! 570: ! 571: fprintf(xref_file, "HIE %s %d %s %s %d %d %d\n", ! 572: filename(xf), lineno, cls, base, pub, virt, frnd); ! 573: } ! 574: ! 575: /* Output cross-reference info about class members. CLS ! 576: is the containing type; FLD is the class member. */ ! 577: ! 578: void ! 579: GNU_xref_member(cls, fld) ! 580: tree cls; ! 581: tree fld; ! 582: { ! 583: XREF_FILE xf; ! 584: char *prot; ! 585: int confg, pure; ! 586: char *d; ! 587: int i; ! 588: char buf[1024], bufa[1024]; ! 589: ! 590: if (!doing_xref) return; ! 591: xf = find_file(fld->decl.filename); ! 592: if (xf == NULL) return; ! 593: ! 594: if (TREE_PRIVATE (fld)) prot = "PRIVATE"; ! 595: else if (TREE_PROTECTED(fld)) prot = "PROTECTED"; ! 596: else prot = "PUBLIC"; ! 597: ! 598: confg = 0; ! 599: if (TREE_CODE (fld) == FUNCTION_DECL && DECL_CONST_MEMFUNC_P(fld)) ! 600: confg = 1; ! 601: else if (TREE_CODE (fld) == CONST_DECL) ! 602: confg = 1; ! 603: ! 604: pure = 0; ! 605: if (TREE_CODE (fld) == FUNCTION_DECL && DECL_ABSTRACT_VIRTUAL_P(fld)) ! 606: pure = 1; ! 607: ! 608: d = IDENTIFIER_POINTER(cls); ! 609: sprintf(buf, "%d%s", strlen(d), d); ! 610: i = strlen(buf); ! 611: strcpy(bufa, declname(fld)); ! 612: ! 613: #ifdef XREF_SHORT_MEMBER_NAMES ! 614: for (p = &bufa[1]; *p != 0; ++p) ! 615: { ! 616: if (p[0] == '_' && p[1] == '_' && p[2] >= '0' && p[2] <= '9') { ! 617: if (strncmp(&p[2], buf, i) == 0) *p = 0; ! 618: break; ! 619: } ! 620: else if (p[0] == '_' && p[1] == '_' && p[2] == 'C' && p[3] >= '0' && p[3] <= '9') { ! 621: if (strncmp(&p[3], buf, i) == 0) *p = 0; ! 622: break; ! 623: } ! 624: } ! 625: #endif ! 626: ! 627: fprintf(xref_file, "MEM %s %d %s %s %s %d %d %d %d %d %d %d\n", ! 628: filename(xf), fld->decl.linenum, d, bufa, prot, ! 629: (TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1), ! 630: (DECL_INLINE (fld) ? 1 : 0), ! 631: (DECL_FRIEND_P(fld) ? 1 : 0), ! 632: (DECL_VINDEX(fld) ? 1 : 0), ! 633: (TREE_STATIC(fld) ? 1 : 0), ! 634: pure, confg); ! 635: } ! 636: ! 637: /* Find file entry given name. */ ! 638: ! 639: static XREF_FILE ! 640: find_file(name) ! 641: char *name; ! 642: { ! 643: XREF_FILE xf; ! 644: ! 645: for (xf = all_files; xf != NULL; xf = xf->next) { ! 646: if (STREQL(name, xf->name)) break; ! 647: } ! 648: ! 649: return xf; ! 650: } ! 651: ! 652: /* Return filename for output purposes. */ ! 653: ! 654: static char * ! 655: filename(xf) ! 656: XREF_FILE xf; ! 657: { ! 658: if (xf == NULL) { ! 659: last_file = NULL; ! 660: return "*"; ! 661: } ! 662: ! 663: if (last_file == xf) return "*"; ! 664: ! 665: last_file = xf; ! 666: ! 667: return xf->outname; ! 668: } ! 669: ! 670: /* Return function name for output purposes. */ ! 671: ! 672: static char * ! 673: fctname(fndecl) ! 674: tree fndecl; ! 675: { ! 676: static char fctbuf[1024]; ! 677: char *s; ! 678: ! 679: if (fndecl == NULL && last_fndecl == NULL) return "*"; ! 680: ! 681: if (fndecl == NULL) ! 682: { ! 683: last_fndecl = NULL; ! 684: return "*TOP*"; ! 685: } ! 686: ! 687: if (fndecl == last_fndecl) return "*"; ! 688: ! 689: last_fndecl = fndecl; ! 690: ! 691: s = declname(fndecl); ! 692: s = fixname(s, fctbuf); ! 693: ! 694: return s; ! 695: } ! 696: ! 697: /* Return decl name for output purposes. */ ! 698: ! 699: static char * ! 700: declname(dcl) ! 701: tree dcl; ! 702: { ! 703: if (DECL_NAME (dcl) == NULL) return "?"; ! 704: ! 705: if (DECL_ASSEMBLER_NAME (dcl)) ! 706: return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (dcl)); ! 707: else ! 708: return IDENTIFIER_POINTER (DECL_NAME (dcl)); ! 709: } ! 710: ! 711: /* Simplify a type string by removing unneeded parenthesis. */ ! 712: ! 713: static void ! 714: simplify_type(typ) ! 715: char *typ; ! 716: { ! 717: char *s; ! 718: int lvl, i; ! 719: ! 720: i = strlen(typ); ! 721: while (i > 0 && isspace(typ[i-1])) typ[--i] = 0; ! 722: ! 723: if (i > 7 && STREQL(&typ[i-5], "const")) ! 724: { ! 725: typ[i-5] = 0; ! 726: i -= 5; ! 727: } ! 728: ! 729: if (typ[i-1] != ')') return; ! 730: ! 731: s = &typ[i-2]; ! 732: lvl = 1; ! 733: while (*s != 0) { ! 734: if (*s == ')') ++lvl; ! 735: else if (*s == '(') ! 736: { ! 737: --lvl; ! 738: if (lvl == 0) ! 739: { ! 740: s[1] = ')'; ! 741: s[2] = 0; ! 742: break; ! 743: } ! 744: } ! 745: --s; ! 746: } ! 747: ! 748: if (*s != 0 && s[-1] == ')') ! 749: { ! 750: --s; ! 751: --s; ! 752: if (*s == '(') s[2] = 0; ! 753: else if (*s == ':') { ! 754: while (*s != '(') --s; ! 755: s[1] = ')'; ! 756: s[2] = 0; ! 757: } ! 758: } ! 759: } ! 760: ! 761: /* Fixup a function name (take care of embedded spaces). */ ! 762: ! 763: static char * ! 764: fixname(nam, buf) ! 765: char *nam; ! 766: char *buf; ! 767: { ! 768: char *s, *t; ! 769: int fg; ! 770: ! 771: s = nam; ! 772: t = buf; ! 773: fg = 0; ! 774: ! 775: while (*s != 0) ! 776: { ! 777: if (*s == ' ') ! 778: { ! 779: *t++ = '\36'; ! 780: ++fg; ! 781: } ! 782: else *t++ = *s; ! 783: ++s; ! 784: } ! 785: *t = 0; ! 786: ! 787: if (fg == 0) return nam; ! 788: ! 789: return buf; ! 790: } ! 791: ! 792: /* Open file for xrefing. */ ! 793: ! 794: static void ! 795: open_xref_file(file) ! 796: char *file; ! 797: { ! 798: char *s, *t; ! 799: ! 800: #ifdef XREF_FILE_NAME ! 801: XREF_FILE_NAME (xref_name, file); ! 802: #else ! 803: s = rindex (file, '/'); ! 804: if (s == NULL) ! 805: sprintf (xref_name, ".%s.gxref", file); ! 806: else ! 807: { ! 808: ++s; ! 809: strcpy (xref_name, file); ! 810: t = rindex (xref_name, '/'); ! 811: ++t; ! 812: *t++ = '.'; ! 813: strcpy (t, s); ! 814: strcat (t, ".gxref"); ! 815: } ! 816: #endif /* no XREF_FILE_NAME */ ! 817: ! 818: xref_file = fopen(xref_name, "w"); ! 819: ! 820: if (xref_file == NULL) ! 821: { ! 822: error("Can't create cross-reference file `%s'", xref_name); ! 823: doing_xref = 0; ! 824: } ! 825: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.