📄 dbxout.c
字号:
GCC. It's easier for GDB to parse it when after the N_SO's. This is used in Solaris 2. */#ifdef ASM_IDENTIFY_GCC_AFTER_SOURCE ASM_IDENTIFY_GCC_AFTER_SOURCE (asmfile);#endif lastfile = input_file_name; next_type_number = 1; next_block_number = 2; /* Make sure that types `int' and `char' have numbers 1 and 2. Definitions of other integer types will refer to those numbers. (Actually it should no longer matter what their numbers are. Also, if any types with tags have been defined, dbxout_symbol will output them first, so the numbers won't be 1 and 2. That happens in C++. So it's a good thing it should no longer matter). */#ifdef DBX_OUTPUT_STANDARD_TYPES DBX_OUTPUT_STANDARD_TYPES (syms);#else dbxout_symbol (TYPE_NAME (integer_type_node), 0); dbxout_symbol (TYPE_NAME (char_type_node), 0);#endif /* Get all permanent types that have typedef names, and output them all, except for those already output. */ dbxout_typedefs (syms);}/* Output any typedef names for types described by TYPE_DECLs in SYMS, in the reverse order from that which is found in SYMS. */static voiddbxout_typedefs (syms) tree syms;{ if (syms) { dbxout_typedefs (TREE_CHAIN (syms)); if (TREE_CODE (syms) == TYPE_DECL) { tree type = TREE_TYPE (syms); if (TYPE_NAME (type) && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL && ! TREE_ASM_WRITTEN (TYPE_NAME (type))) dbxout_symbol (TYPE_NAME (type), 0); } }}/* Output debugging info to FILE to switch to sourcefile FILENAME. */voiddbxout_source_file (file, filename) FILE *file; char *filename;{ char ltext_label_name[100]; if (filename && (lastfile == 0 || strcmp (filename, lastfile))) {#ifdef DBX_OUTPUT_SOURCE_FILENAME DBX_OUTPUT_SOURCE_FILENAME (file, filename);#else ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); fprintf (file, "%s \"%s\",%d,0,0,%s\n", ASM_STABS_OP, filename, N_SOL, <ext_label_name[1]);#endif lastfile = filename; }}/* Output a line number symbol entry into output stream FILE, for source file FILENAME and line number LINENO. */voiddbxout_source_line (file, filename, lineno) FILE *file; char *filename; int lineno;{ dbxout_source_file (file, filename);#ifdef ASM_OUTPUT_SOURCE_LINE ASM_OUTPUT_SOURCE_LINE (file, lineno);#else fprintf (file, "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno);#endif}/* At the end of compilation, finish writing the symbol table. Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is to do nothing. */voiddbxout_finish (file, filename) FILE *file; char *filename;{#ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename);#endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */}/* Continue a symbol-description that gets too big. End one symbol table entry with a double-backslash and start a new one, eventually producing something like .stabs "start......\\",code,0,value .stabs "...rest",code,0,value */static voiddbxout_continue (){#ifdef DBX_CONTIN_CHAR fprintf (asmfile, "%c", DBX_CONTIN_CHAR);#else fprintf (asmfile, "\\\\");#endif dbxout_finish_symbol (NULL_TREE); fprintf (asmfile, "%s \"", ASM_STABS_OP); current_sym_nchars = 0;}/* Subroutine of `dbxout_type'. Output the type fields of TYPE. This must be a separate function because anonymous unions require recursive calls. */static voiddbxout_type_fields (type) tree type;{ tree tem; /* Output the name, type, position (in bits), size (in bits) of each field. */ for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) { /* For nameless subunions and subrecords, treat their fields as ours. */ if (DECL_NAME (tem) == NULL_TREE && (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE || TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE)) dbxout_type_fields (TREE_TYPE (tem)); /* Omit here local type decls until we know how to support them. */ else if (TREE_CODE (tem) == TYPE_DECL) continue; /* Omit here the nameless fields that are used to skip bits. */ else if (DECL_NAME (tem) != 0 && TREE_CODE (tem) != CONST_DECL) { /* Continue the line if necessary, but not before the first field. */ if (tem != TYPE_FIELDS (type)) CONTIN; if (use_gnu_debug_info_extensions && flag_minimal_debug && TREE_CODE (tem) == FIELD_DECL && DECL_VIRTUAL_P (tem) && DECL_ASSEMBLER_NAME (tem)) { have_used_extensions = 1; CHARS (3 + IDENTIFIER_LENGTH (DECL_NAME (TYPE_NAME (DECL_FCONTEXT (tem))))); fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile); dbxout_type (DECL_FCONTEXT (tem), 0, 0); fprintf (asmfile, ":"); dbxout_type (TREE_TYPE (tem), 0, 0); fprintf (asmfile, ",%d;", TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); continue; } fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem))); CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem))); if (use_gnu_debug_info_extensions && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem) || TREE_CODE (tem) != FIELD_DECL)) { have_used_extensions = 1; putc ('/', asmfile); putc ((TREE_PRIVATE (tem) ? '0' : TREE_PROTECTED (tem) ? '1' : '2'), asmfile); CHARS (2); } dbxout_type ((TREE_CODE (tem) == FIELD_DECL && DECL_BIT_FIELD_TYPE (tem)) ? DECL_BIT_FIELD_TYPE (tem) : TREE_TYPE (tem), 0, 0); if (TREE_CODE (tem) == VAR_DECL) { if (TREE_STATIC (tem) && use_gnu_debug_info_extensions) { char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); have_used_extensions = 1; fprintf (asmfile, ":%s;", name); CHARS (strlen (name)); } else { /* If TEM is non-static, GDB won't understand it. */ fprintf (asmfile, ",0,0;"); } } else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) { fprintf (asmfile, ",%d,%d;", TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)), TREE_INT_CST_LOW (DECL_SIZE (tem))); } else /* This has yet to be implemented. */ abort (); CHARS (23); } }}/* Subroutine of `dbxout_type_methods'. Output debug info about the method described DECL. DEBUG_NAME is an encoding of the method's type signature. ??? We may be able to do without DEBUG_NAME altogether now. */static voiddbxout_type_method_1 (decl, debug_name) tree decl; char *debug_name;{ tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))); char c1 = 'A', c2; if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) c2 = '?'; else /* it's a METHOD_TYPE. */ { /* A for normal functions. B for `const' member functions. C for `volatile' member functions. D for `const volatile' member functions. */ if (TYPE_READONLY (TREE_TYPE (firstarg))) c1 += 1; if (TYPE_VOLATILE (TREE_TYPE (firstarg))) c1 += 2; if (DECL_VINDEX (decl)) c2 = '*'; else c2 = '.'; } fprintf (asmfile, ":%s;%c%c%c", debug_name, TREE_PRIVATE (decl) ? '0' : TREE_PROTECTED (decl) ? '1' : '2', c1, c2); CHARS (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 6 - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))); if (DECL_VINDEX (decl)) { fprintf (asmfile, "%d;", TREE_INT_CST_LOW (DECL_VINDEX (decl))); dbxout_type (DECL_CONTEXT (decl), 0, 0); fprintf (asmfile, ";"); CHARS (8); }}/* Subroutine of `dbxout_type'. Output debug info about the methods defined in TYPE. */static voiddbxout_type_methods (type) register tree type;{ /* C++: put out the method names and their parameter lists */ tree methods = TYPE_METHODS (type); tree type_encoding; register tree fndecl; register tree last; char formatted_type_identifier_length[16]; register int type_identifier_length; if (methods == NULL_TREE) return; type_encoding = DECL_NAME (TYPE_NAME (type)); /* C++: Template classes break some assumptions made by this code about the class names, constructor names, and encodings for assembler label names. For now, disable output of dbx info for them. */ { char *ptr = IDENTIFIER_POINTER (type_encoding); /* This should use index. (mrs) */ while (*ptr && *ptr != '<') ptr++; if (*ptr != 0) { static int warned; if (!warned) { warned = 1; warning ("dbx info for template class methods not yet supported"); } return; } } type_identifier_length = IDENTIFIER_LENGTH (type_encoding); sprintf(formatted_type_identifier_length, "%d", type_identifier_length); if (TREE_CODE (methods) == FUNCTION_DECL) fndecl = methods; else if (TREE_VEC_ELT (methods, 0) != NULL_TREE) fndecl = TREE_VEC_ELT (methods, 0); else fndecl = TREE_VEC_ELT (methods, 1); while (fndecl) { tree name = DECL_NAME (fndecl); int need_prefix = 1; /* Group together all the methods for the same operation. These differ in the types of the arguments. */ for (last = NULL_TREE; fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last)); fndecl = TREE_CHAIN (fndecl)) /* Output the name of the field (after overloading), as well as the name of the field before overloading, along with its parameter list */ { /* This is the "mangled" name of the method. It encodes the argument types. */ char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); int destructor = 0; CONTIN; last = fndecl; if (DECL_IGNORED_P (fndecl)) continue; if (flag_minimal_debug) { /* Detect ordinary methods because their mangled names start with the operation name. */ if (!strncmp (IDENTIFIER_POINTER (name), debug_name, IDENTIFIER_LENGTH (name))) { debug_name += IDENTIFIER_LENGTH (name); if (debug_name[0] == '_' && debug_name[1] == '_') { 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 destructor = 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, destructor); dbxout_type_method_1 (fndecl, debug_name); } if (!need_prefix) { putc (';', asmfile); CHARS (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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -