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

📄 dbxout.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 5 页
字号:
  /* If there was an input error and we don't really have a type,     avoid crashing and write something that is at least valid     by assuming `int'.  */  if (type == error_mark_node)    type = integer_type_node;  else    {      type = TYPE_MAIN_VARIANT (type);      if (TYPE_NAME (type)	  && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL	  && DECL_IGNORED_P (TYPE_NAME (type)))	full = 0;    }  if (TYPE_SYMTAB_ADDRESS (type) == 0)    {      /* Type has no dbx number assigned.  Assign next available number.  */      TYPE_SYMTAB_ADDRESS (type) = next_type_number++;      /* Make sure type vector is long enough to record about this type.  */      if (next_type_number == typevec_len)	{	  typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]);	  bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]);	  typevec_len *= 2;	}    }  /* Output the number of this type, to refer to it.  */  fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));  CHARS (3);#ifdef DBX_TYPE_DEFINED  if (DBX_TYPE_DEFINED (type))    return;#endif  /* If this type's definition has been output or is now being output,     that is all.  */  switch (typevec[TYPE_SYMTAB_ADDRESS (type)])    {    case TYPE_UNSEEN:      break;    case TYPE_XREF:      /* If we have already had a cross reference,	 and either that's all we want or that's the best we could do,	 don't repeat the cross reference.	 Sun dbx crashes if we do.  */      if (! full || TYPE_SIZE (type) == 0	  /* No way in DBX fmt to describe a variable size.  */	  || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)	return;      break;    case TYPE_DEFINED:      return;    }#ifdef DBX_NO_XREFS  /* For systems where dbx output does not allow the `=xsNAME:' syntax,     leave the type-number completely undefined rather than output     a cross-reference.  */  if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE      || TREE_CODE (type) == ENUMERAL_TYPE)    if ((TYPE_NAME (type) != 0 && !full)	|| TYPE_SIZE (type) == 0)      {	typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;	return;      }#endif  /* Output a definition now.  */  fprintf (asmfile, "=");  CHARS (1);  /* Mark it as defined, so that if it is self-referent     we will not get into an infinite recursion of definitions.  */  typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;  switch (TREE_CODE (type))    {    case VOID_TYPE:    case LANG_TYPE:      /* For a void type, just define it as itself; ie, "5=5".	 This makes us consider it defined	 without saying what it is.  The debugger will make it	 a void type when the reference is seen, and nothing will	 ever override that default.  */      fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));      CHARS (3);      break;    case INTEGER_TYPE:      if (type == char_type_node && ! TREE_UNSIGNED (type))	/* Output the type `char' as a subrange of itself!	   I don't understand this definition, just copied it	   from the output of pcc.	   This used to use `r2' explicitly and we used to	   take care to make sure that `char' was type number 2.  */	fprintf (asmfile, "r%d;0;127;", TYPE_SYMTAB_ADDRESS (type));#ifdef WINNING_GDB      else if (TYPE_PRECISION (type) > BITS_PER_WORD)	{	  /* This used to say `r1' and we used to take care	     to make sure that `int' was type number 1.  */	  fprintf (asmfile, "r%d;", TYPE_SYMTAB_ADDRESS (integer_type_node));	  print_int_cst_octal (TYPE_MIN_VALUE (type));	  fprintf (asmfile, ";");	  print_int_cst_octal (TYPE_MAX_VALUE (type));	  fprintf (asmfile, ";");	}#endif      else	/* Output other integer types as subranges of `int'.  */	/* This used to say `r1' and we used to take care	   to make sure that `int' was type number 1.  */	fprintf (asmfile, "r%d;%d;%d;",		 TYPE_SYMTAB_ADDRESS (integer_type_node),		 TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)),		 TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));      CHARS (25);      break;    case REAL_TYPE:      /* This used to say `r1' and we used to take care	 to make sure that `int' was type number 1.  */      fprintf (asmfile, "r%d;%d;0;", TYPE_SYMTAB_ADDRESS (integer_type_node),	       TREE_INT_CST_LOW (size_in_bytes (type)));      CHARS (16);      break;    case CHAR_TYPE:	/* Output the type `char' as a subrange of itself.	   That is what pcc seems to do.  */      fprintf (asmfile, "r%d;0;%d;", TYPE_SYMTAB_ADDRESS (char_type_node),	       TREE_UNSIGNED (type) ? 255 : 127);      CHARS (9);      break;    case BOOLEAN_TYPE:	/* Define as enumeral type (False, True) */      fprintf (asmfile, "eFalse:0,True:1,;");      CHARS (17);      break;    case FILE_TYPE:      putc ('d', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0);      break;    case COMPLEX_TYPE:      /* Differs from the REAL_TYPE by its new data type number */      if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)	{	  fprintf (asmfile, "r%d;%d;0;",		   TYPE_SYMTAB_ADDRESS (type),		   TREE_INT_CST_LOW (size_in_bytes (TREE_TYPE (type))));	  CHARS (15);		/* The number is propably incorrect here */	} else	  abort (); /* What to do with CSImode complex? */      break;    case SET_TYPE:      putc ('S', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0);      break;    case ARRAY_TYPE:      /* Output "a" followed by a range type definition	 for the index type of the array	 followed by a reference to the target-type.	 ar1;0;N;M for an array of type M and size N.  */      /* This used to say `r1' and we used to take care	 to make sure that `int' was type number 1.  */      fprintf (asmfile, "ar%d;0;%d;", TYPE_SYMTAB_ADDRESS (integer_type_node),	       (TYPE_DOMAIN (type)		? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type)))	        : -1));      CHARS (17);      dbxout_type (TREE_TYPE (type), 0, 0);      break;    case RECORD_TYPE:    case UNION_TYPE:      {	int i, n_baseclasses = 0;	if (TYPE_BINFO (type) != 0 && TYPE_BINFO_BASETYPES (type) != 0)	  n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));	/* Output a structure type.  */	if ((TYPE_NAME (type) != 0#if 0 /* Tiemann says this creates output tha "confuses GDB".	 Too bad the info is so vague.  Hope this doesn't lose.  */	     && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL		   && DECL_IGNORED_P (TYPE_NAME (type)))#endif	     && !full)	    || TYPE_SIZE (type) == 0	    /* No way in DBX fmt to describe a variable size.  */	    || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)	  {	    /* If the type is just a cross reference, output one	       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	    if (TYPE_NAME (type) != 0)	      dbxout_type_name (type);	    else	      fprintf (asmfile, "$$%d", anonymous_type_number++);	    fprintf (asmfile, ":");	    typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;	    break;	  }	tem = size_in_bytes (type);	/* Identify record or union, and print its size.  */	fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",		 TREE_INT_CST_LOW (tem));	if (use_gnu_debug_info_extensions)	  {	    if (n_baseclasses)	      {		have_used_extensions = 1;		fprintf (asmfile, "!%d,", n_baseclasses);		CHARS (8);	      }	  }	for (i = 0; i < n_baseclasses; i++)	  {	    tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);	    if (use_gnu_debug_info_extensions)	      {		have_used_extensions = 1;		putc (TREE_VIA_VIRTUAL (child) ? '1'		      : '0',		      asmfile);		putc (TREE_VIA_PUBLIC (child) ? '2'		      : '0',		      asmfile);		fprintf (asmfile, "%d,",			 TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);		CHARS (15);		dbxout_type (BINFO_TYPE (child), 0, 0);		putc (';', asmfile);	      }	    else	      {		/* Print out the base class information with fields		   which have the same names at the types they hold.  */		dbxout_type_name (BINFO_TYPE (child));		putc (':', asmfile);		dbxout_type (BINFO_TYPE (child), full, 0);		fprintf (asmfile, ",%d,%d;",			 TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT,			 TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT);		CHARS (20);	      }	  }      }      CHARS (11);      /* Write out the field declarations.  */      dbxout_type_fields (type);      if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE)	{	  have_used_extensions = 1;	  dbxout_type_methods (type);	}      putc (';', asmfile);      if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE	  /* Avoid the ~ if we don't really need it--it confuses dbx.  */	  && TYPE_VFIELD (type))	{	  have_used_extensions = 1;	  /* Tell GDB+ that it may keep reading.  */	  putc ('~', asmfile);	  /* We need to write out info about what field this class	     uses as its "main" vtable pointer field, because if this	     field is inherited from a base class, GDB cannot necessarily	     figure out which field it's using in time.  */	  if (TYPE_VFIELD (type))	    {	      putc ('%', asmfile);	      dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0);	    }	  putc (';', asmfile);	  CHARS (3);	}      break;    case ENUMERAL_TYPE:      if ((TYPE_NAME (type) != 0 && !full	   && (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL	       && ! DECL_IGNORED_P (TYPE_NAME (type))))	  || TYPE_SIZE (type) == 0)	{	  fprintf (asmfile, "xe");	  CHARS (3);	  dbxout_type_name (type);	  typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;	  fprintf (asmfile, ":");	  return;	}#ifdef DBX_OUTPUT_ENUM      DBX_OUTPUT_ENUM (asmfile, type);#else      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);#endif      break;    case POINTER_TYPE:      putc ('*', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0, 0);      break;    case METHOD_TYPE:      if (use_gnu_debug_info_extensions)	{	  have_used_extensions = 1;	  putc ('#', asmfile);	  CHARS (1);	  if (flag_minimal_debug && !show_arg_types)	    {	      /* Normally, just output the return type.		 The argument types are encoded in the method name.  */	      putc ('#', asmfile);	      dbxout_type (TREE_TYPE (type), 0, 0);	      putc (';', asmfile);	      CHARS (1);	    }	  else	    {	      /* When outputting destructors, we need to write		 the argument types out longhand.  */	      dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0);	      putc (',', asmfile);	      CHARS (1);	      dbxout_type (TREE_TYPE (type), 0, 0);	      dbxout_args (TYPE_ARG_TYPES (type));	      putc (';', asmfile);	      CHARS (1);	    }	}      else	{	  /* Treat it as a function type.  */	  dbxout_type (TREE_TYPE (type), 0, 0);	}      break;    case OFFSET_TYPE:      if (use_gnu_debug_info_extensions)	{	  have_used_extensions = 1;	  putc ('@', asmfile);	  CHARS (1);	  dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0);	  putc (',', asmfile);	  CHARS (1);	  dbxout_type (TREE_TYPE (type), 0, 0);	}      else	{	  /* Should print as an int, because it is really	     just an offset.  */	  dbxout_type (integer_type_node, 0, 0);	}      break;    case REFERENCE_TYPE:      if (use_gnu_debug_info_extensions)	have_used_extensions = 1;      putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0, 0);      break;    case FUNCTION_TYPE:      putc ('f', asmfile);      CHARS (1);      dbxout_type (TREE_TYPE (type), 0, 0);      break;    default:      abort ();    }}/* Print the value of integer constant C, in octal,   handling double precision.  */

⌨️ 快捷键说明

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