📄 dbxout.c
字号:
/* 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 + -