📄 xref.c
字号:
/* Code for handling XREF output from GNU C++. Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. Contributed by Michael Tiemann (tiemann@cygnus.com)This file is part of GNU CC.GNU CC is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2, or (at your option)any later version.GNU CC is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with GNU CC; see the file COPYING. If not, write tothe Free Software Foundation, 59 Temple Place - Suite 330,Boston, MA 02111-1307, USA. */#include "config.h"#include "system.h"#include "tree.h"#include "cp-tree.h"#include "input.h"#include "toplev.h"extern char *getpwd PROTO((void));/* The character(s) used to join a directory specification (obtained with getwd or equivalent) with a non-absolute file name. */#ifndef FILE_NAME_JOINER#define FILE_NAME_JOINER "/"#endif/* Nonzero if NAME as a file name is absolute. */#ifndef FILE_NAME_ABSOLUTE_P#define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/')#endif/* For cross referencing. */int flag_gnu_xref;/************************************************************************//* *//* Common definitions *//* *//************************************************************************/#ifndef TRUE#define TRUE 1#endif#ifndef FALSE#define FALSE 0#endif#define PALLOC(typ) ((typ *) calloc(1,sizeof(typ)))/* Return a malloc'd copy of STR. */#define SALLOC(str) \ ((char *) ((str) == NULL ? NULL \ : (char *) strcpy ((char *) malloc (strlen ((str)) + 1), (str))))#define SFREE(str) (str != NULL && (free(str),0))#define STREQL(s1,s2) (strcmp((s1),(s2)) == 0)#define STRNEQ(s1,s2) (strcmp((s1),(s2)) != 0)#define STRLSS(s1,s2) (strcmp((s1),(s2)) < 0)#define STRLEQ(s1,s2) (strcmp((s1),(s2)) <= 0)#define STRGTR(s1,s2) (strcmp((s1),(s2)) > 0)#define STRGEQ(s1,s2) (strcmp((s1),(s2)) >= 0)/************************************************************************//* *//* Type definitions *//* *//************************************************************************/typedef struct _XREF_FILE * XREF_FILE;typedef struct _XREF_SCOPE * XREF_SCOPE;typedef struct _XREF_FILE{ const char *name; const char *outname; XREF_FILE next;} XREF_FILE_INFO;typedef struct _XREF_SCOPE{ int gid; int lid; XREF_FILE file; int start; XREF_SCOPE outer;} XREF_SCOPE_INFO;/************************************************************************//* *//* Local storage *//* *//************************************************************************/static char doing_xref = 0;static FILE * xref_file = NULL;static char xref_name[1024];static XREF_FILE all_files = NULL;static char * wd_name = NULL;static XREF_SCOPE cur_scope = NULL;static int scope_ctr = 0;static XREF_FILE last_file = NULL;static tree last_fndecl = NULL;/************************************************************************//* *//* Forward definitions *//* *//************************************************************************/static void gen_assign PROTO((XREF_FILE, tree));static XREF_FILE find_file PROTO((const char *));static const char * filename PROTO((XREF_FILE));static const char * fctname PROTO((tree));static const char * declname PROTO((tree));static void simplify_type PROTO((char *));static const char * fixname PROTO((const char *, char *));static void open_xref_file PROTO((const char *));static const char * classname PROTO((tree));/* Start cross referencing. FILE is the name of the file we xref. */voidGNU_xref_begin (file) const char *file;{ doing_xref = 1; if (file != NULL && STRNEQ (file,"-")) { open_xref_file(file); GNU_xref_file(file); }}/* Finish cross-referencing. ERRCNT is the number of errors we encountered. */voidGNU_xref_end (ect) int ect;{ XREF_FILE xf; if (!doing_xref) return; xf = find_file (input_filename); if (xf == NULL) return; while (cur_scope != NULL) GNU_xref_end_scope(cur_scope->gid,0,0,0); doing_xref = 0; if (xref_file == NULL) return; fclose (xref_file); xref_file = NULL; all_files = NULL; if (ect > 0) unlink (xref_name);}/* Write out xref for file named NAME. */voidGNU_xref_file (name) const char *name;{ XREF_FILE xf; if (!doing_xref || name == NULL) return; if (xref_file == NULL) { open_xref_file (name); if (!doing_xref) return; } if (all_files == NULL) fprintf(xref_file,"SCP * 0 0 0 0 RESET\n"); xf = find_file (name); if (xf != NULL) return; xf = PALLOC (XREF_FILE_INFO); xf->name = SALLOC (name); xf->next = all_files; all_files = xf; if (wd_name == NULL) wd_name = getpwd (); if (FILE_NAME_ABSOLUTE_P (name) || ! wd_name) xf->outname = xf->name; else { char *nmbuf = (char *) xmalloc (strlen (wd_name) + strlen (FILE_NAME_JOINER) + strlen (name) + 1); sprintf (nmbuf, "%s%s%s", wd_name, FILE_NAME_JOINER, name); name = nmbuf; xf->outname = nmbuf; } fprintf (xref_file, "FIL %s %s 0\n", name, wd_name); filename (xf); fctname (NULL);}/* Start a scope identified at level ID. */voidGNU_xref_start_scope (id) HOST_WIDE_INT id;{ XREF_SCOPE xs; XREF_FILE xf; if (!doing_xref) return; xf = find_file (input_filename); xs = PALLOC (XREF_SCOPE_INFO); xs->file = xf; xs->start = lineno; if (xs->start <= 0) xs->start = 1; xs->gid = id; xs->lid = ++scope_ctr; xs->outer = cur_scope; cur_scope = xs;}/* Finish a scope at level ID. INID is ??? PRM is ??? KEEP is nonzero iff this scope is retained (nonzero if it's a compiler-generated invisible scope). TRNS is ??? */voidGNU_xref_end_scope (id,inid,prm,keep) HOST_WIDE_INT id; HOST_WIDE_INT inid; int prm,keep;{ XREF_FILE xf; XREF_SCOPE xs,lxs,oxs; const char *stype; if (!doing_xref) return; xf = find_file (input_filename); if (xf == NULL) return; lxs = NULL; for (xs = cur_scope; xs != NULL; xs = xs->outer) { if (xs->gid == id) break; lxs = xs; } if (xs == NULL) return; if (inid != 0) { for (oxs = cur_scope; oxs != NULL; oxs = oxs->outer) { if (oxs->gid == inid) break; } if (oxs == NULL) return; inid = oxs->lid; } if (prm == 2) stype = "SUE"; else if (prm != 0) stype = "ARGS"; else if (keep == 2 || inid != 0) stype = "INTERN"; else stype = "EXTERN"; fprintf (xref_file, "SCP %s %d %d %d ", filename (xf), xs->start, lineno,xs->lid); fprintf (xref_file, HOST_WIDE_INT_PRINT_DEC, inid); fprintf (xref_file, " %s\n", stype); if (lxs == NULL) cur_scope = xs->outer; else lxs->outer = xs->outer; free (xs);}/* Output a reference to NAME in FNDECL. */voidGNU_xref_ref (fndecl,name) tree fndecl; const char *name;{ XREF_FILE xf; if (!doing_xref) return; xf = find_file (input_filename); if (xf == NULL) return; fprintf (xref_file, "REF %s %d %s %s\n", filename (xf), lineno, fctname (fndecl), name);}/* Output a reference to DECL in FNDECL. */voidGNU_xref_decl (fndecl,decl) tree fndecl; tree decl;{ XREF_FILE xf,xf1; const char *cls = 0; const char *name; char buf[10240]; int uselin; if (!doing_xref) return; xf = find_file (input_filename); if (xf == NULL) return; uselin = FALSE; if (TREE_CODE (decl) == TYPE_DECL) cls = "TYPEDEF"; else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; else if (TREE_CODE (decl) == VAR_DECL) { if (fndecl == NULL && TREE_STATIC(decl) && TREE_READONLY(decl) && DECL_INITIAL(decl) != 0 && !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) && DECL_MODE(decl) != BLKmode) cls = "CONST"; else if (DECL_EXTERNAL(decl)) cls = "EXTERN"; else if (TREE_PUBLIC(decl)) cls = "EXTDEF"; else if (TREE_STATIC(decl)) cls = "STATIC"; else if (DECL_REGISTER(decl)) cls = "REGISTER"; else cls = "AUTO"; } else if (TREE_CODE (decl) == PARM_DECL) cls = "PARAM"; else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; else if (TREE_CODE (decl) == CONST_DECL) cls = "CONST"; else if (TREE_CODE (decl) == FUNCTION_DECL) { if (DECL_EXTERNAL (decl)) cls = "EXTERN"; else if (TREE_PUBLIC (decl)) cls = "EFUNCTION"; else cls = "SFUNCTION"; } else if (TREE_CODE (decl) == LABEL_DECL) cls = "LABEL"; else if (TREE_CODE (decl) == UNION_TYPE) { cls = "UNIONID"; decl = TYPE_NAME (decl); uselin = TRUE; } else if (TREE_CODE (decl) == RECORD_TYPE) { if (CLASSTYPE_DECLARED_CLASS (decl)) cls = "CLASSID"; else if (IS_SIGNATURE (decl)) cls = "SIGNATUREID"; else cls = "STRUCTID"; decl = TYPE_NAME (decl); uselin = TRUE; } else if (TREE_CODE (decl) == ENUMERAL_TYPE) { cls = "ENUMID"; decl = TYPE_NAME (decl); uselin = TRUE; } else if (TREE_CODE (decl) == TEMPLATE_DECL) { if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL) cls = "CLASSTEMP"; else if (TREE_CODE (DECL_RESULT (decl)) == FUNCTION_DECL) cls = "FUNCTEMP"; else if (TREE_CODE (DECL_RESULT (decl)) == VAR_DECL) cls = "VARTEMP"; else my_friendly_abort (358); uselin = TRUE; } else cls = "UNKNOWN"; if (decl == NULL || DECL_NAME (decl) == NULL) return; if (uselin && decl->decl.linenum > 0 && decl->decl.filename != NULL) { xf1 = find_file (decl->decl.filename); if (xf1 != NULL) { lineno = decl->decl.linenum; xf = xf1; } } if (DECL_ASSEMBLER_NAME (decl)) name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); else name = IDENTIFIER_POINTER (DECL_NAME (decl)); strcpy (buf, type_as_string (TREE_TYPE (decl), 0)); simplify_type (buf); fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", filename(xf), lineno, name, (cur_scope != NULL ? cur_scope->lid : 0), cls, fctname(fndecl), buf); if (STREQL (cls, "STRUCTID") || STREQL (cls, "UNIONID") || STREQL (cls, "SIGNATUREID"))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -