📄 dbxout.c
字号:
CHARS (IDENTIFIER_LENGTH (name) + 2); need_prefix = 0; } } dbxout_type (TREE_TYPE (fndecl), 0, destructor); dbxout_type_method_1 (fndecl, debug_name); } if (!need_prefix) { putc (';', asmfile); CHARS (1); } }}/* Emit a "range" type specification, which has the form: "r<index type>;<lower bound>;<upper bound>;". TYPE is an INTEGER_TYPE. */static voiddbxout_range_type (type) tree type;{ fprintf (asmfile, "r"); if (TREE_TYPE (type)) dbxout_type (TREE_TYPE (type), 0, 0); else if (TREE_CODE (type) != INTEGER_TYPE) dbxout_type (type, 0, 0); /* E.g. Pascal's ARRAY [BOOLEAN] of INTEGER */ else { /* This used to say `r1' and we used to take care to make sure that `int' was type number 1. */ fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (integer_type_node)); } if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST) fprintf (asmfile, ";%d", TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))); else fprintf (asmfile, ";0"); if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST) fprintf (asmfile, ";%d;", TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))); else fprintf (asmfile, ";-1;");}/* Output a reference to a type. If the type has not yet been described in the dbx output, output its definition now. For a type already defined, just refer to its definition using the type number. If FULL is nonzero, and the type has been described only with a forward-reference, output the definition now. If FULL is zero in this case, just refer to the forward-reference using the number previously allocated. If SHOW_ARG_TYPES is nonzero, we output a description of the argument types for a METHOD_TYPE. */static voiddbxout_type (type, full, show_arg_types) tree type; int full; int show_arg_types;{ register tree tem; static int anonymous_type_number = 0; /* 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 && TYPE_DECL_SUPPRESS_DEBUG (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 ((char *) (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 we have already used GNU debug info extensions, then it is OK to output a cross reference. This is necessary to get proper C++ debug output. */ if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE || TREE_CODE (type) == QUAL_UNION_TYPE || TREE_CODE (type) == ENUMERAL_TYPE) && ! use_gnu_debug_info_extensions) /* We must use the same test here as we use twice below when deciding whether to emit a cross-reference. */ if ((TYPE_NAME (type) != 0 && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && DECL_IGNORED_P (TYPE_NAME (type))) && !full) || TYPE_SIZE (type) == 0 /* No way in DBX fmt to describe a variable size. */ || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) { 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)); else if (use_gnu_debug_info_extensions && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node) || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_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;", 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, ";"); } else /* Output other integer types as subranges of `int'. */ dbxout_range_type (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), int_size_in_bytes (type)); CHARS (16); break; case CHAR_TYPE: if (use_gnu_debug_info_extensions) fprintf (asmfile, "@s%d;-20;", BITS_PER_UNIT * int_size_in_bytes (type)); else /* 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: if (use_gnu_debug_info_extensions) fprintf (asmfile, "@s%d;-16;", BITS_PER_UNIT * int_size_in_bytes (type)); else /* 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, 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), int_size_in_bytes (TREE_TYPE (type))); CHARS (15); /* The number is probably incorrect here. */ } else { /* Output a complex integer type as a structure, pending some other way to do it. */ fprintf (asmfile, "s%d", int_size_in_bytes (type)); fprintf (asmfile, "real:"); CHARS (10); dbxout_type (TREE_TYPE (type), 0, 0); fprintf (asmfile, ",%d,%d;", 0, TYPE_PRECISION (TREE_TYPE (type))); CHARS (8); fprintf (asmfile, "imag:"); CHARS (5); dbxout_type (TREE_TYPE (type), 0, 0); fprintf (asmfile, ",%d,%d;;", TYPE_PRECISION (TREE_TYPE (type)), TYPE_PRECISION (TREE_TYPE (type))); CHARS (9); } break; case SET_TYPE: if (use_gnu_debug_info_extensions) { have_used_extensions = 1; fprintf (asmfile, "@s%d;", BITS_PER_UNIT * int_size_in_bytes (type)); /* Check if a bitstring type, which in Chill is different from a [power]set. */ if (TYPE_STRING_FLAG (type)) fprintf (asmfile, "@S;"); } putc ('S', asmfile); CHARS (1); dbxout_type (TYPE_DOMAIN (type), 0, 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 a C array of type M and size N+1. */ /* Check if a character string type, which in Chill is different from an array of characters. */ if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions) { have_used_extensions = 1; fprintf (asmfile, "@S;"); } tem = TYPE_DOMAIN (type); if (tem == NULL) fprintf (asmfile, "ar%d;0;-1;", TYPE_SYMTAB_ADDRESS (integer_type_node)); else { fprintf (asmfile, "a"); dbxout_range_type (tem); } CHARS (17); dbxout_type (TREE_TYPE (type), 0, 0); break; case RECORD_TYPE: case UNION_TYPE: case QUAL_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. We must use the same test here as we use in the DBX_NO_XREFS case above. */ if ((TYPE_NAME (type) != 0 && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && DECL_IGNORED_P (TYPE_NAME (type))) && !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; } /* Identify record or union, and print its size. */ fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d", int_size_in_bytes (type)); 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); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -