dbxout.c
来自「GCC编译器源代码」· C语言 代码 · 共 2,183 行 · 第 1/5 页
C
2,183 行
char *method_name = debug_name + 2; char *length_ptr = formatted_type_identifier_length; /* Get past const and volatile qualifiers. */ while (*method_name == 'C' || *method_name == 'V') method_name++; /* Skip digits for length of type_encoding. */ while (*method_name == *length_ptr && *length_ptr) length_ptr++, method_name++; if (! strncmp (method_name, IDENTIFIER_POINTER (type_encoding), type_identifier_length)) method_name += type_identifier_length; debug_name = method_name; } } /* Detect constructors by their style of name mangling. */ else if (debug_name[0] == '_' && debug_name[1] == '_') { char *ctor_name = debug_name + 2; char *length_ptr = formatted_type_identifier_length; while (*ctor_name == 'C' || *ctor_name == 'V') ctor_name++; /* Skip digits for length of type_encoding. */ while (*ctor_name == *length_ptr && *length_ptr) length_ptr++, ctor_name++; if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name, type_identifier_length)) debug_name = ctor_name + type_identifier_length; } /* The other alternative is a destructor. */ else show_arg_types = 1; /* Output the operation name just once, for the first method that we output. */ if (need_prefix) { fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name)); CHARS (IDENTIFIER_LENGTH (name) + 2); need_prefix = 0; } } dbxout_type (TREE_TYPE (fndecl), 0, show_arg_types); 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 { /* Traditionally, we made sure 'int' was type 1, and builtin types were defined to be sub-ranges of int. Unfortunately, this does not allow us to distinguish true sub-ranges from integer types. So, instead we define integer (non-sub-range) types as sub-ranges of themselves. */ dbxout_type_index (type); } 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 { /* Try to find the "main variant" with the same name but not const or volatile. (Since stabs does not distinguish const and volatile, there is no need to make them separate types. But types with different names are usefully distinguished.) */ for (tem = TYPE_MAIN_VARIANT (type); tem; tem = TYPE_NEXT_VARIANT (tem)) if (!TYPE_READONLY (tem) && !TYPE_VOLATILE (tem) && TYPE_NAME (tem) == TYPE_NAME (type)) { type = tem; break; } 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 = (struct typeinfo *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]); bzero ((char *) (typevec + typevec_len), typevec_len * sizeof typevec[0]); typevec_len *= 2; }#ifdef DBX_USE_BINCL typevec[TYPE_SYMTAB_ADDRESS (type)].file_number = current_file->file_number; typevec[TYPE_SYMTAB_ADDRESS (type)].type_number = current_file->next_type_number++;#endif } /* Output the number of this type, to refer to it. */ dbxout_type_index (type);#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)].status) { 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)].status = 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)].status = TYPE_DEFINED; if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && DECL_ORIGINAL_TYPE (TYPE_NAME (type))) { dbxout_type (DECL_ORIGINAL_TYPE (TYPE_NAME (type)), 0, 0); return; } 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. */ dbxout_type_index (type); 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"); dbxout_type_index (type); fprintf (asmfile, ";0;127;"); } 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"); dbxout_type_index (integer_type_node); fprintf (asmfile, ";"); 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 (22); 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"); dbxout_type_index (integer_type_node); fprintf (asmfile, ";%d;0;", int_size_in_bytes (type)); CHARS (13); 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"); dbxout_type_index (char_type_node); fprintf (asmfile, ";0;%d;", 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"); dbxout_type_index (type); fprintf (asmfile, ";%d;0;", int_size_in_bytes (TREE_TYPE (type))); CHARS (12); /* 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"); dbxout_type_index (integer_type_node); fprintf (asmfile, ";0;-1;"); } else { fprintf (asmfile, "a"); dbxout_range_type (tem); } CHARS (14); 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)].status = TYPE_XREF; break; } /* Identify record or union, and print its size. */ fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?