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

📄 dbxout.c

📁 这是完整的gcc源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	     and mark the type as partially described.	     If it later becomes defined, we will output	     its real definition.	     If the type has a name, don't nest its definition within	     another type's definition; instead, output an xref	     and let the definition come when the name is defined.  */	  fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");	  CHARS (3);#if 0	  /* This assertion is legitimately false in C++.  */	  /* We shouldn't be outputting a reference to a type before its	     definition unless the type has a tag name.	     A typedef name without a tag name should be impossible.  */	  if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE)	    abort ();#endif	  dbxout_type_name (type);	  fprintf (asmfile, ":");	  typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;	  break;	}      tem = size_in_bytes (type);      fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",	       TREE_INT_CST_LOW (tem));      if (TYPE_BASETYPES (type) && use_gdb_dbx_extensions)	{	  putc ('!', asmfile);	  putc ((TREE_PUBLIC (TYPE_BASETYPES (type)) ? '2' : '0'),		asmfile);	  dbxout_type (TREE_VALUE (TYPE_BASETYPES (type)), 0);	  putc (',', asmfile);	  CHARS (3);	}      CHARS (11);      for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))	/* Output the name, type, position (in bits), size (in bits)	   of each field.  */	/* Omit here the nameless fields that are used to skip bits.  */	if (DECL_NAME (tem) != 0)	  {	    /* Continue the line if necessary,	       but not before the first field.  */	    if (tem != TYPE_FIELDS (type))	      CONTIN;	    fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));	    CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));#ifdef TREE_PRIVATE	    if (use_gdb_dbx_extensions		&& (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)		    || TREE_CODE (tem) != FIELD_DECL))	      {		putc ('/', asmfile);		putc ((TREE_PRIVATE (tem) ? '0'		       : TREE_PROTECTED (tem) ? '1' : '2'),		      asmfile);		CHARS (2);		if (TREE_CODE (tem) == FUNCTION_DECL)		  {		    putc (':', asmfile);		    CHARS (1);		    dbxout_type (TREE_TYPE (tem), 0); /* FUNCTION_TYPE */		    dbxout_args (TYPE_ARG_TYPES (TREE_TYPE (tem)));#ifdef TREE_VIRTUAL		    fprintf (asmfile, ":%s;%c", 			     XSTR (XEXP (DECL_RTL (tem), 0), 0),			     TREE_VIRTUAL (tem) ? '*' : '.');#endif		    CHARS (3 + strlen (XSTR (XEXP (DECL_RTL (tem), 0), 0)));		  }		else		  dbxout_type (TREE_TYPE (tem), 0);	      }	    else#endif	      dbxout_type (TREE_TYPE (tem), 0);	    if (TREE_CODE (tem) == VAR_DECL)	      {		if (use_gdb_dbx_extensions)		  {		    fprintf (asmfile, ":%s", 			     XSTR (XEXP (DECL_RTL (tem), 0), 0));		    CHARS (2 + strlen (XSTR (XEXP (DECL_RTL (tem), 0), 0)));		  }		else		  {		    fprintf (asmfile, ",0,0;");		    CHARS (5);		  }	      }	    else	      {		fprintf (asmfile, ",%d,%d;", DECL_OFFSET (tem),			 (TREE_INT_CST_LOW (DECL_SIZE (tem))			  * DECL_SIZE_UNIT (tem)));		CHARS (23);	      }	  }      putc (';', asmfile);      CHARS (1);      break;    case ENUMERAL_TYPE:      if ((TYPE_NAME (type) != 0 && !full)	  || TYPE_SIZE (type) == 0)	{	  fprintf (asmfile, "xe");	  CHARS (3);	  dbxout_type_name (type);	  typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;	  fprintf (asmfile, ":");	  return;	}      putc ('e', asmfile);      CHARS (1);      for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))	{	  fprintf (asmfile, "%s:%d,", IDENTIFIER_POINTER (TREE_PURPOSE (tem)),		   TREE_INT_CST_LOW (TREE_VALUE (tem)));	  CHARS (11 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));	  if (TREE_CHAIN (tem) != 0)	    CONTIN;	}      putc (';', asmfile);      CHARS (1);      break;    case POINTER_TYPE:      putc ('*', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0);      break;    case METHOD_TYPE:      if (use_gdb_dbx_extensions)	{	  putc ('@', asmfile);	  CHARS (1);	  dbxout_type (TYPE_METHOD_BASETYPE (type), 0);	  putc (',', asmfile);	  CHARS (1);	  dbxout_type (TREE_TYPE (type), 0);	}      else	{	  /* Treat it as a function type.  */	  dbxout_type (TREE_TYPE (type), 0);	}      break;    case OFFSET_TYPE:      if (use_gdb_dbx_extensions)	{	  putc ('@', asmfile);	  CHARS (1);	  dbxout_type (TYPE_OFFSET_BASETYPE (type), 0);	  putc (',', asmfile);	  CHARS (1);	  dbxout_type (TREE_TYPE (type), 0);	}      else	{	  /* Treat it as a function type.  */	  dbxout_type (TREE_TYPE (type), 0);	}      break;    case REFERENCE_TYPE:      putc (use_gdb_dbx_extensions ? '&' : '*', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0);      break;    case FUNCTION_TYPE:      putc ('f', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0);      break;    default:      abort ();    }}/* Output the name of type TYPE, with no punctuation.   Such names can be set up either by typedef declarations   or by struct, enum and union tags.  */static voiddbxout_type_name (type)     register tree type;{  tree t;  if (TYPE_NAME (type) == 0)    abort ();  if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)    {      t = TYPE_NAME (type);    }  else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)    {      t = DECL_NAME (TYPE_NAME (type));    }  else    abort ();  fprintf (asmfile, "%s", IDENTIFIER_POINTER (t));  CHARS (IDENTIFIER_LENGTH (t));}/* Output a .stabs for the symbol defined by DECL,   which must be a ..._DECL node in the normal namespace.   It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.   LOCAL is nonzero if the scope is less than the entire file.  */voiddbxout_symbol (decl, local)     tree decl;     int local;{  int letter = 0;  tree type = TREE_TYPE (decl);  /* If global, first output all types and all     struct, enum and union tags that have been created     and not yet output.  */  if (local == 0)    {      dbxout_tags (gettags ());      dbxout_types (get_permanent_types ());    }  current_sym_code = 0;  current_sym_value = 0;  current_sym_addr = 0;  /* The output will always start with the symbol name,     so count that always in the length-output-so-far.  */  current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl));  switch (TREE_CODE (decl))    {    case CONST_DECL:      /* Enum values are defined by defining the enum type.  */      break;    case FUNCTION_DECL:      if (DECL_RTL (decl) == 0)	return;      if (TREE_EXTERNAL (decl))	break;      if (GET_CODE (DECL_RTL (decl)) != MEM	  || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)	break;      FORCE_TEXT;      fprintf (asmfile, ".stabs \"%s:%c",	       IDENTIFIER_POINTER (DECL_NAME (decl)),	       TREE_PUBLIC (decl) ? 'F' : 'f');      current_sym_code = N_FUN;      current_sym_addr = XEXP (DECL_RTL (decl), 0);      if (TREE_TYPE (TREE_TYPE (decl)))	dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0);      else	dbxout_type (void_type_node, 0);      dbxout_finish_symbol ();      break;    case TYPE_DECL:#if 0      /* This seems all wrong.  Outputting most kinds of types gives no name	 at all.  A true definition gives no name; a cross-ref for a	 structure can give the tag name, but not a type name.	 It seems that no typedef name is defined by outputting a type.  */      /* If this typedef name was defined by outputting the type,	 don't duplicate it.  */      if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED	  && TYPE_NAME (TREE_TYPE (decl)) == decl)	return;#endif      /* Don't output the same typedef twice.  */      if (TREE_ASM_WRITTEN (decl))	return;      /* Output typedef name.  */      FORCE_TEXT;      fprintf (asmfile, ".stabs \"%s:t",	       IDENTIFIER_POINTER (DECL_NAME (decl)));      current_sym_code = N_LSYM;      dbxout_type (TREE_TYPE (decl), 1);      dbxout_finish_symbol ();      /* Prevent duplicate output of a typedef.  */      TREE_ASM_WRITTEN (decl) = 1;      break;          case PARM_DECL:      /* Parm decls go in their own separate chains	 and are output by dbxout_reg_parms and dbxout_parms.  */      abort ();    case VAR_DECL:      if (DECL_RTL (decl) == 0)	return;      /* Don't mention a variable that is external.	 Let the file that defines it describe it.  */      if (TREE_EXTERNAL (decl))	break;      /* Don't mention a variable at all	 if it was completely optimized into nothingness.  */      if (GET_CODE (DECL_RTL (decl)) == REG	  && (REGNO (DECL_RTL (decl)) < 0	      || REGNO (DECL_RTL (decl)) >= FIRST_PSEUDO_REGISTER))	break;      /* The kind-of-variable letter depends on where	 the variable is and on the scope of its name:	 G and N_GSYM for static storage and global scope,	 S for static storage and file scope,	 V for static storage and local scope,	    for those two, use N_LCSYM if data is in bss segment,	    N_STSYM if in data segment, N_FUN otherwise.	    (We used N_FUN originally, then changed to N_STSYM	    to please GDB.  However, it seems that confused ld.	    Now GDB has been fixed to like N_FUN, says Kingdon.)	 no letter at all, and N_LSYM, for auto variable,	 r and N_RSYM for register variable.  */      if (GET_CODE (DECL_RTL (decl)) == MEM	  && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)	{	  if (TREE_PUBLIC (decl))	    {	      letter = 'G';	      current_sym_code = N_GSYM;	    }	  else	    {	      current_sym_addr = XEXP (DECL_RTL (decl), 0);	      letter = TREE_PERMANENT (decl) ? 'S' : 'V';	      if (!DECL_INITIAL (decl))		current_sym_code = N_LCSYM;	      else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))		/* This is not quite right, but it's the closest		   of all the codes that Unix defines.  */		current_sym_code = N_FUN;	      else		{/* Ultrix `as' seems to need this.  */#ifdef DBX_STATIC_STAB_DATA_SECTION		  data_section ();#endif		  current_sym_code = N_STSYM;		}	    }	}      else if (GET_CODE (DECL_RTL (decl)) == REG)	{	  letter = 'r';	  current_sym_code = N_RSYM;	  current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));	}      else if (GET_CODE (DECL_RTL (decl)) == SUBREG)	{	  rtx value = DECL_RTL (decl);	  int offset = 0;	  while (GET_CODE (value) == SUBREG)	    {	      offset += SUBREG_WORD (value);	      value = SUBREG_REG (value);	    }	  letter = 'r';	  current_sym_code = N_RSYM;	  current_sym_value = DBX_REGISTER_NUMBER (REGNO (value) + offset);	}      else if (GET_CODE (DECL_RTL (decl)) == MEM	       && (GET_CODE (XEXP (DECL_RTL (decl), 0)) == MEM		   || (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG		       && REGNO (XEXP (DECL_RTL (decl), 0)) != FRAME_POINTER_REGNUM)))	/* If the value is indirect by memory or by a register	   that isn't the frame pointer	   then it means the object is variable-sized and address through	   that register or stack slot.  DBX has no way to represent this	   so all we can do is output the variable as a pointer.	   If it's not a parameter, ignore it.	   (VAR_DECLs like this can be made by integrate.c.)  */	{	  if (GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)	    {	      letter = 'r';	      current_sym_code = N_RSYM;	      current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (DECL_RTL (decl), 0)));	    }	  else	    {	      current_sym_code = N_LSYM;	      /* DECL_RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).		 We want the value of that CONST_INT.  */	      current_sym_value = INTVAL (XEXP (XEXP (XEXP (DECL_RTL (decl), 0), 0), 1));	    }	  /* Effectively do build_pointer_type, but don't cache this type,	     since it might be temporary whereas the type it points to	     might have been saved for inlining.  */	  type = make_node (POINTER_TYPE);	  TREE_TYPE (type) = TREE_TYPE (decl);	}      else if (GET_CODE (DECL_RTL (decl)) == MEM	       && GET_CODE (XEXP (DECL_RTL (decl), 0)) == REG)	{

⌨️ 快捷键说明

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