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

📄 dwarfout.c

📁 GUN开源阻止下的编译器GCC
💻 C
📖 第 1 页 / 共 5 页
字号:
	return FT_void;      case INTEGER_TYPE:	/* Carefully distinguish all the standard types of C,	   without messing up if the language is not C.	   Note that we check only for the names that contain spaces;	   other names might occur by coincidence in other languages.  */	if (TYPE_NAME (type) != 0	    && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL	    && DECL_NAME (TYPE_NAME (type)) != 0	    && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)	  {	    char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));	    if (!strcmp (name, "unsigned char"))	      return FT_unsigned_char;	    if (!strcmp (name, "signed char"))	      return FT_signed_char;	    if (!strcmp (name, "unsigned int"))	      return FT_unsigned_integer;	    if (!strcmp (name, "short int"))	      return FT_short;	    if (!strcmp (name, "short unsigned int"))	      return FT_unsigned_short;	    if (!strcmp (name, "long int"))	      return FT_long;	    if (!strcmp (name, "long unsigned int"))	      return FT_unsigned_long;	    if (!strcmp (name, "long long int"))	      return FT_long_long;		/* Not grok'ed by svr4 SDB */	    if (!strcmp (name, "long long unsigned int"))	      return FT_unsigned_long_long;	/* Not grok'ed by svr4 SDB */	  }	/* Most integer types will be sorted out above, however, for the	   sake of special `array index' integer types, the following code	   is also provided.  */	if (TYPE_PRECISION (type) == INT_TYPE_SIZE)	  return (TREE_UNSIGNED (type) ? FT_unsigned_integer : FT_integer);	if (TYPE_PRECISION (type) == LONG_TYPE_SIZE)	  return (TREE_UNSIGNED (type) ? FT_unsigned_long : FT_long);	if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE)	  return (TREE_UNSIGNED (type) ? FT_unsigned_long_long : FT_long_long);	if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE)	  return (TREE_UNSIGNED (type) ? FT_unsigned_short : FT_short);	if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE)	  return (TREE_UNSIGNED (type) ? FT_unsigned_char : FT_char);	abort ();      case REAL_TYPE:	/* Carefully distinguish all the standard types of C,	   without messing up if the language is not C.  */	if (TYPE_NAME (type) != 0	    && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL	    && DECL_NAME (TYPE_NAME (type)) != 0	    && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)	  {	    char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));	    /* Note that here we can run afowl of a serious bug in "classic"	       svr4 SDB debuggers.  They don't seem to understand the	       FT_ext_prec_float type (even though they should).  */	    if (!strcmp (name, "long double"))	      return FT_ext_prec_float;	  }	if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE)	  return FT_dbl_prec_float;	if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE)	  return FT_float;	/* Note that here we can run afowl of a serious bug in "classic"	   svr4 SDB debuggers.  They don't seem to understand the	   FT_ext_prec_float type (even though they should).  */	if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE)	  return FT_ext_prec_float;	abort ();      case COMPLEX_TYPE:	return FT_complex;	/* GNU FORTRAN COMPLEX type.  */      case CHAR_TYPE:	return FT_char;		/* GNU Pascal CHAR type.  Not used in C.  */      case BOOLEAN_TYPE:	return FT_boolean;	/* GNU FORTRAN BOOLEAN type.  */      default:	abort ();	/* No other TREE_CODEs are Dwarf fundamental types.  */    }  return 0;}/* Given a pointer to an arbitrary ..._TYPE tree node, return a pointer to   the Dwarf "root" type for the given input type.  The Dwarf "root" type   of a given type is generally the same as the given type, except that if   the	given type is a pointer or reference type, then the root type of   the given type is the root type of the "basis" type for the pointer or   reference type.  (This definition of the "root" type is recursive.)   Also, the root type of a `const' qualified type or a `volatile'   qualified type is the root type of the given type without the   qualifiers.  */static treeroot_type (type)     register tree type;{  if (TREE_CODE (type) == ERROR_MARK)    return error_mark_node;  switch (TREE_CODE (type))    {      case ERROR_MARK:	return error_mark_node;      case POINTER_TYPE:      case REFERENCE_TYPE:	return type_main_variant (root_type (TREE_TYPE (type)));      default:	return type_main_variant (type);    }}/* Given a pointer to an arbitrary ..._TYPE tree node, write out a sequence   of zero or more Dwarf "type-modifier" bytes applicable to the type.	*/static voidwrite_modifier_bytes (type, decl_const, decl_volatile)     register tree type;     register int decl_const;     register int decl_volatile;{  if (TREE_CODE (type) == ERROR_MARK)    return;  if (TYPE_READONLY (type) || decl_const)    ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_const);  if (TYPE_VOLATILE (type) || decl_volatile)    ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_volatile);  switch (TREE_CODE (type))    {      case POINTER_TYPE:	ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_pointer_to);	write_modifier_bytes (TREE_TYPE (type), 0, 0);	return;      case REFERENCE_TYPE:	ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_reference_to);	write_modifier_bytes (TREE_TYPE (type), 0, 0);	return;      case ERROR_MARK:      default:	return;    }}/* Given a pointer to an arbitrary ..._TYPE tree node, return non-zero if the   given input type is a Dwarf "fundamental" type.  Otherwise return zero.  */inline inttype_is_fundamental (type)     register tree type;{  switch (TREE_CODE (type))    {      case ERROR_MARK:      case VOID_TYPE:      case INTEGER_TYPE:      case REAL_TYPE:      case COMPLEX_TYPE:      case BOOLEAN_TYPE:      case CHAR_TYPE:	return 1;      case SET_TYPE:      case ARRAY_TYPE:      case RECORD_TYPE:      case UNION_TYPE:      case QUAL_UNION_TYPE:      case ENUMERAL_TYPE:      case FUNCTION_TYPE:      case METHOD_TYPE:      case POINTER_TYPE:      case REFERENCE_TYPE:      case FILE_TYPE:      case OFFSET_TYPE:      case LANG_TYPE:	return 0;      default:	abort ();    }  return 0;}/* Given a pointer to some ..._DECL tree node, generate an assembly language   equate directive which will associate a symbolic name with the current DIE.   The name used is an artificial label generated from the DECL_UID number   associated with the given decl node.  The name it gets equated to is the   symbolic label that we (previously) output at the start of the DIE that   we are currently generating.   Calling this function while generating some "decl related" form of DIE   makes it possible to later refer to the DIE which represents the given   decl simply by re-generating the symbolic name from the ..._DECL node's   UID number.	*/static voidequate_decl_number_to_die_number (decl)     register tree decl;{  /* In the case where we are generating a DIE for some ..._DECL node     which represents either some inline function declaration or some     entity declared within an inline function declaration/definition,     setup a symbolic name for the current DIE so that we have a name     for this DIE that we can easily refer to later on within     AT_abstract_origin attributes.  */  char decl_label[MAX_ARTIFICIAL_LABEL_BYTES];  char die_label[MAX_ARTIFICIAL_LABEL_BYTES];  sprintf (decl_label, DECL_NAME_FMT, DECL_UID (decl));  sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum);  ASM_OUTPUT_DEF (asm_out_file, decl_label, die_label);}/* Given a pointer to some ..._TYPE tree node, generate an assembly language   equate directive which will associate a symbolic name with the current DIE.   The name used is an artificial label generated from the TYPE_UID number   associated with the given type node.  The name it gets equated to is the   symbolic label that we (previously) output at the start of the DIE that   we are currently generating.   Calling this function while generating some "type related" form of DIE   makes it easy to later refer to the DIE which represents the given type   simply by re-generating the alternative name from the ..._TYPE node's   UID number.	*/inline voidequate_type_number_to_die_number (type)     register tree type;{  char type_label[MAX_ARTIFICIAL_LABEL_BYTES];  char die_label[MAX_ARTIFICIAL_LABEL_BYTES];  /* We are generating a DIE to represent the main variant of this type     (i.e the type without any const or volatile qualifiers) so in order     to get the equate to come out right, we need to get the main variant     itself here.  */  type = type_main_variant (type);  sprintf (type_label, TYPE_NAME_FMT, TYPE_UID (type));  sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum);  ASM_OUTPUT_DEF (asm_out_file, type_label, die_label);}static voidoutput_reg_number (rtl)     register rtx rtl;{  register unsigned regno = REGNO (rtl);  if (regno >= FIRST_PSEUDO_REGISTER)    {      warning_with_decl (dwarf_last_decl, "internal regno botch: regno = %d\n",			 regno);      regno = 0;    }  fprintf (asm_out_file, "\t%s\t0x%x",	   UNALIGNED_INT_ASM_OP, DBX_REGISTER_NUMBER (regno));  if (flag_verbose_asm)    {      fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);      PRINT_REG (rtl, 0, asm_out_file);    }  fputc ('\n', asm_out_file);}/* The following routine is a nice and simple transducer.  It converts the   RTL for a variable or parameter (resident in memory) into an equivalent   Dwarf representation of a mechanism for getting the address of that same   variable onto the top of a hypothetical "address evaluation" stack.   When creating memory location descriptors, we are effectively trans-   forming the RTL for a memory-resident object into its Dwarf postfix   expression equivalent.  This routine just recursively descends an   RTL tree, turning it into Dwarf postfix code as it goes.  */static voidoutput_mem_loc_descriptor (rtl)      register rtx rtl;{  /* Note that for a dynamically sized array, the location we will     generate a description of here will be the lowest numbered location     which is actually within the array.  That's *not* necessarily the     same as the zeroth element of the array.  */  switch (GET_CODE (rtl))    {      case SUBREG:	/* The case of a subreg may arise when we have a local (register)	   variable or a formal (register) parameter which doesn't quite	   fill up an entire register.	For now, just assume that it is	   legitimate to make the Dwarf info refer to the whole register	   which contains the given subreg.  */	rtl = XEXP (rtl, 0);	/* Drop thru.  */      case REG:	/* Whenever a register number forms a part of the description of	   the method for calculating the (dynamic) address of a memory	   resident object, DWARF rules require the register number to	   be referred to as a "base register".  This distinction is not	   based in any way upon what category of register the hardware	   believes the given register belongs to.  This is strictly	   DWARF terminology we're dealing with here.	   Note that in cases where the location of a memory-resident data	   object could be expressed as:		    OP_ADD (OP_BASEREG (basereg), OP_CONST (0))	   the actual DWARF location descriptor that we generate may just	   be OP_BASEREG (basereg).  This may look deceptively like the	   object in question was allocated to a register (rather than	   in memory) so DWARF consumers need to be aware of the subtle	   distinction between OP_REG and OP_BASEREG.  */	ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_BASEREG);	output_reg_number (rtl);	break;      case MEM:	output_mem_loc_descriptor (XEXP (rtl, 0));	ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_DEREF4);	break;      case CONST:      case SYMBOL_REF:	ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADDR);	ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl);	break;      case PLUS:	output_mem_loc_descriptor (XEXP (rtl, 0));	output_mem_loc_descriptor (XEXP (rtl, 1));	ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD);	break;      case CONST_INT:	ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST);	ASM_OUTPUT_DWARF_DATA4 (asm_out_file, INTVAL (rtl));	break;      default:	abort ();    }}/* Output a proper Dwarf location descriptor for a variable or parameter   which is either allocated in a register or in a memory location.  For   a register, we just generate an OP_REG and the register number.  For a   memory location we provide a Dwarf postfix expression describing how to   generate the (dynamic) address of the object onto the address stack.  */static voidoutput_loc_descriptor (rtl)     register rtx rtl;{  switch (GET_CODE (rtl))    {    case SUBREG:	/* The case of a subreg may arise when we have a local (register)	   variable or a formal (register) parameter which doesn't quite	   fill up an entire register.	For now, just assume that it is	   legitimate to make the Dwarf info refer to the whole register	   which contains the given subreg.  */	rtl = XEXP (rtl, 0);	/* Drop thru.  */    case REG:	ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_REG);	output_reg_number (rtl);	break;

⌨️ 快捷键说明

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