home *** CD-ROM | disk | FTP | other *** search
/ OpenStep 4.2J (Developer) / os42jdev.iso / NextDeveloper / Source / GNU / gcc / cp / xref.c < prev   
C/C++ Source or Header  |  1996-02-07  |  18KB  |  841 lines

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