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