⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 c-aux-info.c

📁 GCC编译器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* Generate information regarding function declarations and definitions based   on information stored in GCC's tree structure.  This code implements the   -aux-info option.   Copyright (C) 1989, 1991, 1994, 1995, 1997 Free Software Foundation, Inc.   Contributed by Ron Guilmette (rfg@segfault.us.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 <stdio.h>#include "flags.h"#include "tree.h"#include "c-tree.h"extern char *xmalloc ();enum formals_style_enum {  ansi,  k_and_r_names,  k_and_r_decls};typedef enum formals_style_enum formals_style;static char *data_type;static char *concat			PROTO((char *, char *));static char *concat3			PROTO((char *, char *, char *));static char *affix_data_type		PROTO((char *));static char *gen_formal_list_for_type	PROTO((tree, formals_style));static int   deserves_ellipsis		PROTO((tree));static char *gen_formal_list_for_func_def PROTO((tree, formals_style));static char *gen_type			PROTO((char *, tree, formals_style));static char *gen_decl			PROTO((tree, int, formals_style));/*  Take two strings and mash them together into a newly allocated area.  */static char *concat (s1, s2)     char *s1;     char *s2;{  int size1, size2;  char *ret_val;  if (!s1)    s1 = "";  if (!s2)    s2 = "";  size1 = strlen (s1);  size2 = strlen (s2);  ret_val = xmalloc (size1 + size2 + 1);  strcpy (ret_val, s1);  strcpy (&ret_val[size1], s2);  return ret_val;}/*  Take three strings and mash them together into a newly allocated area.  */static char *concat3 (s1, s2, s3)     char *s1;     char *s2;     char *s3;{  int size1, size2, size3;  char *ret_val;  if (!s1)    s1 = "";  if (!s2)    s2 = "";  if (!s3)    s3 = "";  size1 = strlen (s1);  size2 = strlen (s2);  size3 = strlen (s3);  ret_val = xmalloc (size1 + size2 + size3 + 1);  strcpy (ret_val, s1);  strcpy (&ret_val[size1], s2);  strcpy (&ret_val[size1+size2], s3);  return ret_val;}/* Given a string representing an entire type or an entire declaration   which only lacks the actual "data-type" specifier (at its left end),   affix the data-type specifier to the left end of the given type   specification or object declaration.   Because of C language weirdness, the data-type specifier (which normally   goes in at the very left end) may have to be slipped in just to the   right of any leading "const" or "volatile" qualifiers (there may be more   than one).  Actually this may not be strictly necessary because it seems   that GCC (at least) accepts `<data-type> const foo;' and treats it the   same as `const <data-type> foo;' but people are accustomed to seeing   `const char *foo;' and *not* `char const *foo;' so we try to create types   that look as expected.  */static char *affix_data_type (type_or_decl)     char *type_or_decl;{  char *p = type_or_decl;  char *qualifiers_then_data_type;  char saved;  /* Skip as many leading const's or volatile's as there are.  */  for (;;)    {      if (!strncmp (p, "volatile ", 9))        {          p += 9;          continue;        }      if (!strncmp (p, "const ", 6))        {          p += 6;          continue;        }      break;    }  /* p now points to the place where we can insert the data type.  We have to     add a blank after the data-type of course.  */  if (p == type_or_decl)    return concat3 (data_type, " ", type_or_decl);  saved = *p;  *p = '\0';  qualifiers_then_data_type = concat (type_or_decl, data_type);  *p = saved;  return concat3 (qualifiers_then_data_type, " ", p);}/* Given a tree node which represents some "function type", generate the   source code version of a formal parameter list (of some given style) for   this function type.  Return the whole formal parameter list (including   a pair of surrounding parens) as a string.   Note that if the style   we are currently aiming for is non-ansi, then we just return a pair   of empty parens here.  */static char *gen_formal_list_for_type (fntype, style)     tree fntype;     formals_style style;{  char *formal_list = "";  tree formal_type;  if (style != ansi)    return "()";  formal_type = TYPE_ARG_TYPES (fntype);  while (formal_type && TREE_VALUE (formal_type) != void_type_node)    {      char *this_type;      if (*formal_list)        formal_list = concat (formal_list, ", ");      this_type = gen_type ("", TREE_VALUE (formal_type), ansi);      formal_list	= ((strlen (this_type))	   ? concat (formal_list, affix_data_type (this_type))	   : concat (formal_list, data_type));      formal_type = TREE_CHAIN (formal_type);    }  /* If we got to here, then we are trying to generate an ANSI style formal     parameters list.     New style prototyped ANSI formal parameter lists should in theory always     contain some stuff between the opening and closing parens, even if it is     only "void".     The brutal truth though is that there is lots of old K&R code out there     which contains declarations of "pointer-to-function" parameters and     these almost never have fully specified formal parameter lists associated     with them.  That is, the pointer-to-function parameters are declared     with just empty parameter lists.     In cases such as these, protoize should really insert *something* into     the vacant parameter lists, but what?  It has no basis on which to insert     anything in particular.     Here, we make life easy for protoize by trying to distinguish between     K&R empty parameter lists and new-style prototyped parameter lists     that actually contain "void".  In the latter case we (obviously) want     to output the "void" verbatim, and that what we do.  In the former case,     we do our best to give protoize something nice to insert.     This "something nice" should be something that is still valid (when     re-compiled) but something that can clearly indicate to the user that     more typing information (for the parameter list) should be added (by     hand) at some convenient moment.     The string chosen here is a comment with question marks in it.  */  if (!*formal_list)    {      if (TYPE_ARG_TYPES (fntype))        /* assert (TREE_VALUE (TYPE_ARG_TYPES (fntype)) == void_type_node);  */        formal_list = "void";      else        formal_list = "/* ??? */";    }  else    {      /* If there were at least some parameters, and if the formals-types-list         petered out to a NULL (i.e. without being terminated by a         void_type_node) then we need to tack on an ellipsis.  */      if (!formal_type)        formal_list = concat (formal_list, ", ...");    }  return concat3 (" (", formal_list, ")");}/* For the generation of an ANSI prototype for a function definition, we have   to look at the formal parameter list of the function's own "type" to   determine if the function's formal parameter list should end with an   ellipsis.  Given a tree node, the following function will return non-zero   if the "function type" parameter list should end with an ellipsis.  */static intdeserves_ellipsis (fntype)     tree fntype;{  tree formal_type;  formal_type = TYPE_ARG_TYPES (fntype);  while (formal_type && TREE_VALUE (formal_type) != void_type_node)    formal_type = TREE_CHAIN (formal_type);  /* If there were at least some parameters, and if the formals-types-list     petered out to a NULL (i.e. without being terminated by a void_type_node)     then we need to tack on an ellipsis.  */  return (!formal_type && TYPE_ARG_TYPES (fntype));}/* Generate a parameter list for a function definition (in some given style).   Note that this routine has to be separate (and different) from the code that   generates the prototype parameter lists for function declarations, because   in the case of a function declaration, all we have to go on is a tree node   representing the function's own "function type".  This can tell us the types   of all of the formal parameters for the function, but it cannot tell us the   actual *names* of each of the formal parameters.  We need to output those   parameter names for each function definition.   This routine gets a pointer to a tree node which represents the actual   declaration of the given function, and this DECL node has a list of formal   parameter (variable) declarations attached to it.  These formal parameter   (variable) declaration nodes give us the actual names of the formal   parameters for the given function definition.   This routine returns a string which is the source form for the entire   function formal parameter list.  */static char *gen_formal_list_for_func_def (fndecl, style)     tree fndecl;     formals_style style;{  char *formal_list = "";  tree formal_decl;  formal_decl = DECL_ARGUMENTS (fndecl);  while (formal_decl)    {      char *this_formal;      if (*formal_list && ((style == ansi) || (style == k_and_r_names)))        formal_list = concat (formal_list, ", ");      this_formal = gen_decl (formal_decl, 0, style);      if (style == k_and_r_decls)        formal_list = concat3 (formal_list, this_formal, "; ");      else        formal_list = concat (formal_list, this_formal);      formal_decl = TREE_CHAIN (formal_decl);    }  if (style == ansi)    {      if (!DECL_ARGUMENTS (fndecl))        formal_list = concat (formal_list, "void");      if (deserves_ellipsis (TREE_TYPE (fndecl)))        formal_list = concat (formal_list, ", ...");    }  if ((style == ansi) || (style == k_and_r_names))    formal_list = concat3 (" (", formal_list, ")");  return formal_list;}/* Generate a string which is the source code form for a given type (t).  This   routine is ugly and complex because the C syntax for declarations is ugly   and complex.  This routine is straightforward so long as *no* pointer types,   array types, or function types are involved.   In the simple cases, this routine will return the (string) value which was   passed in as the "ret_val" argument.  Usually, this starts out either as an   empty string, or as the name of the declared item (i.e. the formal function   parameter variable).

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -