|
|
1.1 ! root 1: /* Output dbx-format symbol table information from GNU compiler. ! 2: Copyright (C) 1987, 1988, 1992, 1993 Free Software Foundation, Inc. ! 3: ! 4: This file is part of GNU CC. ! 5: ! 6: GNU CC is free software; you can redistribute it and/or modify ! 7: it under the terms of the GNU General Public License as published by ! 8: the Free Software Foundation; either version 2, or (at your option) ! 9: any later version. ! 10: ! 11: GNU CC is distributed in the hope that it will be useful, ! 12: but WITHOUT ANY WARRANTY; without even the implied warranty of ! 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! 14: GNU General Public License for more details. ! 15: ! 16: You should have received a copy of the GNU General Public License ! 17: along with GNU CC; see the file COPYING. If not, write to ! 18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ! 19: ! 20: ! 21: /* Output dbx-format symbol table data. ! 22: This consists of many symbol table entries, each of them ! 23: a .stabs assembler pseudo-op with four operands: ! 24: a "name" which is really a description of one symbol and its type, ! 25: a "code", which is a symbol defined in stab.h whose name starts with N_, ! 26: an unused operand always 0, ! 27: and a "value" which is an address or an offset. ! 28: The name is enclosed in doublequote characters. ! 29: ! 30: Each function, variable, typedef, and structure tag ! 31: has a symbol table entry to define it. ! 32: The beginning and end of each level of name scoping within ! 33: a function are also marked by special symbol table entries. ! 34: ! 35: The "name" consists of the symbol name, a colon, a kind-of-symbol letter, ! 36: and a data type number. The data type number may be followed by ! 37: "=" and a type definition; normally this will happen the first time ! 38: the type number is mentioned. The type definition may refer to ! 39: other types by number, and those type numbers may be followed ! 40: by "=" and nested definitions. ! 41: ! 42: This can make the "name" quite long. ! 43: When a name is more than 80 characters, we split the .stabs pseudo-op ! 44: into two .stabs pseudo-ops, both sharing the same "code" and "value". ! 45: The first one is marked as continued with a double-backslash at the ! 46: end of its "name". ! 47: ! 48: The kind-of-symbol letter distinguished function names from global ! 49: variables from file-scope variables from parameters from auto ! 50: variables in memory from typedef names from register variables. ! 51: See `dbxout_symbol'. ! 52: ! 53: The "code" is mostly redundant with the kind-of-symbol letter ! 54: that goes in the "name", but not entirely: for symbols located ! 55: in static storage, the "code" says which segment the address is in, ! 56: which controls how it is relocated. ! 57: ! 58: The "value" for a symbol in static storage ! 59: is the core address of the symbol (actually, the assembler ! 60: label for the symbol). For a symbol located in a stack slot ! 61: it is the stack offset; for one in a register, the register number. ! 62: For a typedef symbol, it is zero. ! 63: ! 64: If DEBUG_SYMS_TEXT is defined, all debugging symbols must be ! 65: output while in the text section. ! 66: ! 67: For more on data type definitions, see `dbxout_type'. */ ! 68: ! 69: /* Include these first, because they may define MIN and MAX. */ ! 70: #include <stdio.h> ! 71: #include <errno.h> ! 72: ! 73: #include "config.h" ! 74: #include "tree.h" ! 75: #include "rtl.h" ! 76: #include "flags.h" ! 77: #include "regs.h" ! 78: #include "insn-config.h" ! 79: #include "reload.h" ! 80: #include "defaults.h" ! 81: #include "output.h" /* ASM_OUTPUT_SOURCE_LINE may refer to sdb functions. */ ! 82: ! 83: #ifndef errno ! 84: extern int errno; ! 85: #endif ! 86: ! 87: #ifdef XCOFF_DEBUGGING_INFO ! 88: #include "xcoffout.h" ! 89: #endif ! 90: ! 91: #ifndef ASM_STABS_OP ! 92: #define ASM_STABS_OP ".stabs" ! 93: #endif ! 94: ! 95: #ifndef ASM_STABN_OP ! 96: #define ASM_STABN_OP ".stabn" ! 97: #endif ! 98: ! 99: #ifndef DBX_TYPE_DECL_STABS_CODE ! 100: #define DBX_TYPE_DECL_STABS_CODE N_LSYM ! 101: #endif ! 102: ! 103: #ifndef DBX_STATIC_CONST_VAR_CODE ! 104: #define DBX_STATIC_CONST_VAR_CODE N_FUN ! 105: #endif ! 106: ! 107: #ifndef DBX_REGPARM_STABS_CODE ! 108: #define DBX_REGPARM_STABS_CODE N_RSYM ! 109: #endif ! 110: ! 111: #ifndef DBX_REGPARM_STABS_LETTER ! 112: #define DBX_REGPARM_STABS_LETTER 'P' ! 113: #endif ! 114: ! 115: #ifndef DBX_MEMPARM_STABS_LETTER ! 116: #define DBX_MEMPARM_STABS_LETTER 'p' ! 117: #endif ! 118: ! 119: #ifndef FILE_NAME_JOINER ! 120: #define FILE_NAME_JOINER "/" ! 121: #endif ! 122: ! 123: /* Nonzero means if the type has methods, only output debugging ! 124: information if methods are actually written to the asm file. */ ! 125: ! 126: static int flag_minimal_debug = 1; ! 127: ! 128: /* Nonzero if we have actually used any of the GDB extensions ! 129: to the debugging format. The idea is that we use them for the ! 130: first time only if there's a strong reason, but once we have done that, ! 131: we use them whenever convenient. */ ! 132: ! 133: static int have_used_extensions = 0; ! 134: ! 135: char *getpwd (); ! 136: ! 137: /* Typical USG systems don't have stab.h, and they also have ! 138: no use for DBX-format debugging info. */ ! 139: ! 140: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) ! 141: ! 142: #ifdef DEBUG_SYMS_TEXT ! 143: #define FORCE_TEXT text_section (); ! 144: #else ! 145: #define FORCE_TEXT ! 146: #endif ! 147: ! 148: #if defined (USG) || defined (NO_STAB_H) ! 149: #include "gstab.h" /* If doing DBX on sysV, use our own stab.h. */ ! 150: #else ! 151: #include <stab.h> /* On BSD, use the system's stab.h. */ ! 152: ! 153: /* This is a GNU extension we need to reference in this file. */ ! 154: #ifndef N_CATCH ! 155: #define N_CATCH 0x54 ! 156: #endif ! 157: #endif /* not USG */ ! 158: ! 159: #ifdef __GNU_STAB__ ! 160: #define STAB_CODE_TYPE enum __stab_debug_code ! 161: #else ! 162: #define STAB_CODE_TYPE int ! 163: #endif ! 164: ! 165: /* 1 if PARM is passed to this function in memory. */ ! 166: ! 167: #define PARM_PASSED_IN_MEMORY(PARM) \ ! 168: (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM) ! 169: ! 170: /* A C expression for the integer offset value of an automatic variable ! 171: (N_LSYM) having address X (an RTX). */ ! 172: #ifndef DEBUGGER_AUTO_OFFSET ! 173: #define DEBUGGER_AUTO_OFFSET(X) \ ! 174: (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0) ! 175: #endif ! 176: ! 177: /* A C expression for the integer offset value of an argument (N_PSYM) ! 178: having address X (an RTX). The nominal offset is OFFSET. */ ! 179: #ifndef DEBUGGER_ARG_OFFSET ! 180: #define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET) ! 181: #endif ! 182: ! 183: /* Stream for writing to assembler file. */ ! 184: ! 185: static FILE *asmfile; ! 186: ! 187: /* Last source file name mentioned in a NOTE insn. */ ! 188: ! 189: static char *lastfile; ! 190: ! 191: /* Current working directory. */ ! 192: ! 193: static char *cwd; ! 194: ! 195: enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED}; ! 196: ! 197: /* Vector recording the status of describing C data types. ! 198: When we first notice a data type (a tree node), ! 199: we assign it a number using next_type_number. ! 200: That is its index in this vector. ! 201: The vector element says whether we have yet output ! 202: the definition of the type. TYPE_XREF says we have ! 203: output it as a cross-reference only. */ ! 204: ! 205: enum typestatus *typevec; ! 206: ! 207: /* Number of elements of space allocated in `typevec'. */ ! 208: ! 209: static int typevec_len; ! 210: ! 211: /* In dbx output, each type gets a unique number. ! 212: This is the number for the next type output. ! 213: The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */ ! 214: ! 215: static int next_type_number; ! 216: ! 217: /* In dbx output, we must assign symbol-blocks id numbers ! 218: in the order in which their beginnings are encountered. ! 219: We output debugging info that refers to the beginning and ! 220: end of the ranges of code in each block ! 221: with assembler labels LBBn and LBEn, where n is the block number. ! 222: The labels are generated in final, which assigns numbers to the ! 223: blocks in the same way. */ ! 224: ! 225: static int next_block_number; ! 226: ! 227: /* These variables are for dbxout_symbol to communicate to ! 228: dbxout_finish_symbol. ! 229: current_sym_code is the symbol-type-code, a symbol N_... define in stab.h. ! 230: current_sym_value and current_sym_addr are two ways to address the ! 231: value to store in the symtab entry. ! 232: current_sym_addr if nonzero represents the value as an rtx. ! 233: If that is zero, current_sym_value is used. This is used ! 234: when the value is an offset (such as for auto variables, ! 235: register variables and parms). */ ! 236: ! 237: static STAB_CODE_TYPE current_sym_code; ! 238: static int current_sym_value; ! 239: static rtx current_sym_addr; ! 240: ! 241: /* Number of chars of symbol-description generated so far for the ! 242: current symbol. Used by CHARS and CONTIN. */ ! 243: ! 244: static int current_sym_nchars; ! 245: ! 246: /* Report having output N chars of the current symbol-description. */ ! 247: ! 248: #define CHARS(N) (current_sym_nchars += (N)) ! 249: ! 250: /* Break the current symbol-description, generating a continuation, ! 251: if it has become long. */ ! 252: ! 253: #ifndef DBX_CONTIN_LENGTH ! 254: #define DBX_CONTIN_LENGTH 80 ! 255: #endif ! 256: ! 257: #if DBX_CONTIN_LENGTH > 0 ! 258: #define CONTIN \ ! 259: do {if (current_sym_nchars > DBX_CONTIN_LENGTH) dbxout_continue ();} while (0) ! 260: #else ! 261: #define CONTIN ! 262: #endif ! 263: ! 264: void dbxout_types (); ! 265: void dbxout_args (); ! 266: void dbxout_symbol (); ! 267: static void dbxout_type_name (); ! 268: static void dbxout_type (); ! 269: static void dbxout_typedefs (); ! 270: static void dbxout_symbol_name (); ! 271: static void dbxout_symbol_location (); ! 272: static void dbxout_prepare_symbol (); ! 273: static void dbxout_finish_symbol (); ! 274: static void dbxout_continue (); ! 275: static void print_int_cst_octal (); ! 276: static void print_octal (); ! 277: ! 278: #if 0 /* Not clear we will actually need this. */ ! 279: ! 280: /* Return the absolutized filename for the given relative ! 281: filename. Note that if that filename is already absolute, it may ! 282: still be returned in a modified form because this routine also ! 283: eliminates redundant slashes and single dots and eliminates double ! 284: dots to get a shortest possible filename from the given input ! 285: filename. The absolutization of relative filenames is made by ! 286: assuming that the given filename is to be taken as relative to ! 287: the first argument (cwd) or to the current directory if cwd is ! 288: NULL. */ ! 289: ! 290: static char * ! 291: abspath (rel_filename) ! 292: char *rel_filename; ! 293: { ! 294: /* Setup the current working directory as needed. */ ! 295: char *abs_buffer ! 296: = (char *) alloca (strlen (cwd) + strlen (rel_filename) + 1); ! 297: char *endp = abs_buffer; ! 298: char *outp, *inp; ! 299: char *value; ! 300: ! 301: /* Copy the filename (possibly preceded by the current working ! 302: directory name) into the absolutization buffer. */ ! 303: ! 304: { ! 305: char *src_p; ! 306: ! 307: if (rel_filename[0] != '/') ! 308: { ! 309: src_p = cwd; ! 310: while (*endp++ = *src_p++) ! 311: continue; ! 312: *(endp-1) = '/'; /* overwrite null */ ! 313: } ! 314: src_p = rel_filename; ! 315: while (*endp++ = *src_p++) ! 316: continue; ! 317: if (endp[-1] == '/') ! 318: *endp = '\0'; ! 319: ! 320: /* Now make a copy of abs_buffer into abs_buffer, shortening the ! 321: filename (by taking out slashes and dots) as we go. */ ! 322: ! 323: outp = inp = abs_buffer; ! 324: *outp++ = *inp++; /* copy first slash */ ! 325: for (;;) ! 326: { ! 327: if (!inp[0]) ! 328: break; ! 329: else if (inp[0] == '/' && outp[-1] == '/') ! 330: { ! 331: inp++; ! 332: continue; ! 333: } ! 334: else if (inp[0] == '.' && outp[-1] == '/') ! 335: { ! 336: if (!inp[1]) ! 337: break; ! 338: else if (inp[1] == '/') ! 339: { ! 340: inp += 2; ! 341: continue; ! 342: } ! 343: else if ((inp[1] == '.') && (inp[2] == 0 || inp[2] == '/')) ! 344: { ! 345: inp += (inp[2] == '/') ? 3 : 2; ! 346: outp -= 2; ! 347: while (outp >= abs_buffer && *outp != '/') ! 348: outp--; ! 349: if (outp < abs_buffer) ! 350: { ! 351: /* Catch cases like /.. where we try to backup to a ! 352: point above the absolute root of the logical file ! 353: system. */ ! 354: ! 355: fprintf (stderr, "%s: invalid file name: %s\n", ! 356: pname, rel_filename); ! 357: exit (1); ! 358: } ! 359: *++outp = '\0'; ! 360: continue; ! 361: } ! 362: } ! 363: *outp++ = *inp++; ! 364: } ! 365: ! 366: /* On exit, make sure that there is a trailing null, and make sure that ! 367: the last character of the returned string is *not* a slash. */ ! 368: ! 369: *outp = '\0'; ! 370: if (outp[-1] == '/') ! 371: *--outp = '\0'; ! 372: ! 373: /* Make a copy (in the heap) of the stuff left in the absolutization ! 374: buffer and return a pointer to the copy. */ ! 375: ! 376: value = (char *) oballoc (strlen (abs_buffer) + 1); ! 377: strcpy (value, abs_buffer); ! 378: return value; ! 379: } ! 380: #endif /* 0 */ ! 381: ! 382: /* At the beginning of compilation, start writing the symbol table. ! 383: Initialize `typevec' and output the standard data types of C. */ ! 384: ! 385: void ! 386: dbxout_init (asm_file, input_file_name, syms) ! 387: FILE *asm_file; ! 388: char *input_file_name; ! 389: tree syms; ! 390: { ! 391: char ltext_label_name[100]; ! 392: ! 393: asmfile = asm_file; ! 394: ! 395: typevec_len = 100; ! 396: typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]); ! 397: bzero (typevec, typevec_len * sizeof typevec[0]); ! 398: ! 399: /* Convert Ltext into the appropriate format for local labels in case ! 400: the system doesn't insert underscores in front of user generated ! 401: labels. */ ! 402: ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); ! 403: ! 404: /* Put the current working directory in an N_SO symbol. */ ! 405: #ifndef DBX_WORKING_DIRECTORY /* Only some versions of DBX want this, ! 406: but GDB always does. */ ! 407: if (use_gnu_debug_info_extensions) ! 408: #endif ! 409: { ! 410: if (!cwd && (cwd = getpwd ()) && (!*cwd || cwd[strlen (cwd) - 1] != '/')) ! 411: { ! 412: char *wdslash = xmalloc (strlen (cwd) + sizeof (FILE_NAME_JOINER)); ! 413: sprintf (wdslash, "%s%s", cwd, FILE_NAME_JOINER); ! 414: cwd = wdslash; ! 415: } ! 416: if (cwd) ! 417: { ! 418: #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY ! 419: DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asmfile, cwd); ! 420: #else /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ ! 421: fprintf (asmfile, "%s ", ASM_STABS_OP); ! 422: output_quoted_string (asmfile, cwd); ! 423: fprintf (asmfile, ",%d,0,0,%s\n", N_SO, <ext_label_name[1]); ! 424: #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ ! 425: } ! 426: } ! 427: ! 428: #ifdef DBX_OUTPUT_MAIN_SOURCE_FILENAME ! 429: /* This should NOT be DBX_OUTPUT_SOURCE_FILENAME. That ! 430: would give us an N_SOL, and we want an N_SO. */ ! 431: DBX_OUTPUT_MAIN_SOURCE_FILENAME (asmfile, input_file_name); ! 432: #else /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ ! 433: /* We include outputting `Ltext:' here, ! 434: because that gives you a way to override it. */ ! 435: /* Used to put `Ltext:' before the reference, but that loses on sun 4. */ ! 436: fprintf (asmfile, "%s ", ASM_STABS_OP); ! 437: output_quoted_string (asmfile, input_file_name); ! 438: fprintf (asmfile, ",%d,0,0,%s\n", ! 439: N_SO, <ext_label_name[1]); ! 440: text_section (); ! 441: ASM_OUTPUT_INTERNAL_LABEL (asmfile, "Ltext", 0); ! 442: #endif /* no DBX_OUTPUT_MAIN_SOURCE_FILENAME */ ! 443: ! 444: /* Possibly output something to inform GDB that this compilation was by ! 445: GCC. It's easier for GDB to parse it when after the N_SO's. This ! 446: is used in Solaris 2. */ ! 447: #ifdef ASM_IDENTIFY_GCC_AFTER_SOURCE ! 448: ASM_IDENTIFY_GCC_AFTER_SOURCE (asmfile); ! 449: #endif ! 450: ! 451: lastfile = input_file_name; ! 452: ! 453: next_type_number = 1; ! 454: next_block_number = 2; ! 455: ! 456: /* Make sure that types `int' and `char' have numbers 1 and 2. ! 457: Definitions of other integer types will refer to those numbers. ! 458: (Actually it should no longer matter what their numbers are. ! 459: Also, if any types with tags have been defined, dbxout_symbol ! 460: will output them first, so the numbers won't be 1 and 2. That ! 461: happens in C++. So it's a good thing it should no longer matter). */ ! 462: ! 463: #ifdef DBX_OUTPUT_STANDARD_TYPES ! 464: DBX_OUTPUT_STANDARD_TYPES (syms); ! 465: #else ! 466: dbxout_symbol (TYPE_NAME (integer_type_node), 0); ! 467: dbxout_symbol (TYPE_NAME (char_type_node), 0); ! 468: #endif ! 469: ! 470: /* Get all permanent types that have typedef names, ! 471: and output them all, except for those already output. */ ! 472: ! 473: dbxout_typedefs (syms); ! 474: } ! 475: ! 476: /* Output any typedef names for types described by TYPE_DECLs in SYMS, ! 477: in the reverse order from that which is found in SYMS. */ ! 478: ! 479: static void ! 480: dbxout_typedefs (syms) ! 481: tree syms; ! 482: { ! 483: if (syms) ! 484: { ! 485: dbxout_typedefs (TREE_CHAIN (syms)); ! 486: if (TREE_CODE (syms) == TYPE_DECL) ! 487: { ! 488: tree type = TREE_TYPE (syms); ! 489: if (TYPE_NAME (type) ! 490: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 491: && ! TREE_ASM_WRITTEN (TYPE_NAME (type))) ! 492: dbxout_symbol (TYPE_NAME (type), 0); ! 493: } ! 494: } ! 495: } ! 496: ! 497: /* Output debugging info to FILE to switch to sourcefile FILENAME. */ ! 498: ! 499: void ! 500: dbxout_source_file (file, filename) ! 501: FILE *file; ! 502: char *filename; ! 503: { ! 504: char ltext_label_name[100]; ! 505: ! 506: if (filename && (lastfile == 0 || strcmp (filename, lastfile))) ! 507: { ! 508: #ifdef DBX_OUTPUT_SOURCE_FILENAME ! 509: DBX_OUTPUT_SOURCE_FILENAME (file, filename); ! 510: #else ! 511: ASM_GENERATE_INTERNAL_LABEL (ltext_label_name, "Ltext", 0); ! 512: fprintf (file, "%s ", ASM_STABS_OP); ! 513: output_quoted_string (file, filename); ! 514: fprintf (file, ",%d,0,0,%s\n", N_SOL, <ext_label_name[1]); ! 515: #endif ! 516: lastfile = filename; ! 517: } ! 518: } ! 519: ! 520: /* Output a line number symbol entry into output stream FILE, ! 521: for source file FILENAME and line number LINENO. */ ! 522: ! 523: void ! 524: dbxout_source_line (file, filename, lineno) ! 525: FILE *file; ! 526: char *filename; ! 527: int lineno; ! 528: { ! 529: dbxout_source_file (file, filename); ! 530: ! 531: #ifdef ASM_OUTPUT_SOURCE_LINE ! 532: ASM_OUTPUT_SOURCE_LINE (file, lineno); ! 533: #else ! 534: fprintf (file, "\t%s %d,0,%d\n", ASM_STABD_OP, N_SLINE, lineno); ! 535: #endif ! 536: } ! 537: ! 538: /* At the end of compilation, finish writing the symbol table. ! 539: Unless you define DBX_OUTPUT_MAIN_SOURCE_FILE_END, the default is ! 540: to do nothing. */ ! 541: ! 542: void ! 543: dbxout_finish (file, filename) ! 544: FILE *file; ! 545: char *filename; ! 546: { ! 547: #ifdef DBX_OUTPUT_MAIN_SOURCE_FILE_END ! 548: DBX_OUTPUT_MAIN_SOURCE_FILE_END (file, filename); ! 549: #endif /* DBX_OUTPUT_MAIN_SOURCE_FILE_END */ ! 550: } ! 551: ! 552: /* Continue a symbol-description that gets too big. ! 553: End one symbol table entry with a double-backslash ! 554: and start a new one, eventually producing something like ! 555: .stabs "start......\\",code,0,value ! 556: .stabs "...rest",code,0,value */ ! 557: ! 558: static void ! 559: dbxout_continue () ! 560: { ! 561: #ifdef DBX_CONTIN_CHAR ! 562: fprintf (asmfile, "%c", DBX_CONTIN_CHAR); ! 563: #else ! 564: fprintf (asmfile, "\\\\"); ! 565: #endif ! 566: dbxout_finish_symbol (NULL_TREE); ! 567: fprintf (asmfile, "%s \"", ASM_STABS_OP); ! 568: current_sym_nchars = 0; ! 569: } ! 570: ! 571: /* Subroutine of `dbxout_type'. Output the type fields of TYPE. ! 572: This must be a separate function because anonymous unions require ! 573: recursive calls. */ ! 574: ! 575: static void ! 576: dbxout_type_fields (type) ! 577: tree type; ! 578: { ! 579: tree tem; ! 580: /* Output the name, type, position (in bits), size (in bits) of each ! 581: field. */ ! 582: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) ! 583: { ! 584: /* For nameless subunions and subrecords, treat their fields as ours. */ ! 585: if (DECL_NAME (tem) == NULL_TREE ! 586: && (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE ! 587: || TREE_CODE (TREE_TYPE (tem)) == QUAL_UNION_TYPE ! 588: || TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE)) ! 589: dbxout_type_fields (TREE_TYPE (tem)); ! 590: /* Omit here local type decls until we know how to support them. */ ! 591: else if (TREE_CODE (tem) == TYPE_DECL) ! 592: continue; ! 593: /* Omit fields whose position or size are variable. */ ! 594: else if (TREE_CODE (tem) == FIELD_DECL ! 595: && (TREE_CODE (DECL_FIELD_BITPOS (tem)) != INTEGER_CST ! 596: || TREE_CODE (DECL_SIZE (tem)) != INTEGER_CST)) ! 597: continue; ! 598: /* Omit here the nameless fields that are used to skip bits. */ ! 599: else if (DECL_NAME (tem) != 0 && TREE_CODE (tem) != CONST_DECL) ! 600: { ! 601: /* Continue the line if necessary, ! 602: but not before the first field. */ ! 603: if (tem != TYPE_FIELDS (type)) ! 604: CONTIN; ! 605: ! 606: if (use_gnu_debug_info_extensions ! 607: && flag_minimal_debug ! 608: && TREE_CODE (tem) == FIELD_DECL ! 609: && DECL_VIRTUAL_P (tem) ! 610: && DECL_ASSEMBLER_NAME (tem)) ! 611: { ! 612: have_used_extensions = 1; ! 613: CHARS (3 + IDENTIFIER_LENGTH (DECL_NAME (TYPE_NAME (DECL_FCONTEXT (tem))))); ! 614: fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile); ! 615: dbxout_type (DECL_FCONTEXT (tem), 0, 0); ! 616: fprintf (asmfile, ":"); ! 617: dbxout_type (TREE_TYPE (tem), 0, 0); ! 618: fprintf (asmfile, ",%d;", ! 619: TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))); ! 620: continue; ! 621: } ! 622: ! 623: fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem))); ! 624: CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem))); ! 625: ! 626: if (use_gnu_debug_info_extensions ! 627: && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem) ! 628: || TREE_CODE (tem) != FIELD_DECL)) ! 629: { ! 630: have_used_extensions = 1; ! 631: putc ('/', asmfile); ! 632: putc ((TREE_PRIVATE (tem) ? '0' ! 633: : TREE_PROTECTED (tem) ? '1' : '2'), ! 634: asmfile); ! 635: CHARS (2); ! 636: } ! 637: ! 638: dbxout_type ((TREE_CODE (tem) == FIELD_DECL ! 639: && DECL_BIT_FIELD_TYPE (tem)) ! 640: ? DECL_BIT_FIELD_TYPE (tem) ! 641: : TREE_TYPE (tem), 0, 0); ! 642: ! 643: if (TREE_CODE (tem) == VAR_DECL) ! 644: { ! 645: if (TREE_STATIC (tem) && use_gnu_debug_info_extensions) ! 646: { ! 647: char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)); ! 648: have_used_extensions = 1; ! 649: fprintf (asmfile, ":%s;", name); ! 650: CHARS (strlen (name)); ! 651: } ! 652: else ! 653: { ! 654: /* If TEM is non-static, GDB won't understand it. */ ! 655: fprintf (asmfile, ",0,0;"); ! 656: } ! 657: } ! 658: else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST) ! 659: { ! 660: fprintf (asmfile, ",%d,%d;", ! 661: TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)), ! 662: TREE_INT_CST_LOW (DECL_SIZE (tem))); ! 663: } ! 664: CHARS (23); ! 665: } ! 666: } ! 667: } ! 668: ! 669: /* Subroutine of `dbxout_type_methods'. Output debug info about the ! 670: method described DECL. DEBUG_NAME is an encoding of the method's ! 671: type signature. ??? We may be able to do without DEBUG_NAME altogether ! 672: now. */ ! 673: ! 674: static void ! 675: dbxout_type_method_1 (decl, debug_name) ! 676: tree decl; ! 677: char *debug_name; ! 678: { ! 679: tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl))); ! 680: char c1 = 'A', c2; ! 681: ! 682: if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) ! 683: c2 = '?'; ! 684: else /* it's a METHOD_TYPE. */ ! 685: { ! 686: /* A for normal functions. ! 687: B for `const' member functions. ! 688: C for `volatile' member functions. ! 689: D for `const volatile' member functions. */ ! 690: if (TYPE_READONLY (TREE_TYPE (firstarg))) ! 691: c1 += 1; ! 692: if (TYPE_VOLATILE (TREE_TYPE (firstarg))) ! 693: c1 += 2; ! 694: ! 695: if (DECL_VINDEX (decl)) ! 696: c2 = '*'; ! 697: else ! 698: c2 = '.'; ! 699: } ! 700: ! 701: fprintf (asmfile, ":%s;%c%c%c", debug_name, ! 702: TREE_PRIVATE (decl) ? '0' : TREE_PROTECTED (decl) ? '1' : '2', c1, c2); ! 703: CHARS (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 6 ! 704: - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)))); ! 705: if (DECL_VINDEX (decl)) ! 706: { ! 707: fprintf (asmfile, "%d;", ! 708: TREE_INT_CST_LOW (DECL_VINDEX (decl))); ! 709: dbxout_type (DECL_CONTEXT (decl), 0, 0); ! 710: fprintf (asmfile, ";"); ! 711: CHARS (8); ! 712: } ! 713: } ! 714: ! 715: /* Subroutine of `dbxout_type'. Output debug info about the methods defined ! 716: in TYPE. */ ! 717: ! 718: static void ! 719: dbxout_type_methods (type) ! 720: register tree type; ! 721: { ! 722: /* C++: put out the method names and their parameter lists */ ! 723: tree methods = TYPE_METHODS (type); ! 724: tree type_encoding; ! 725: register tree fndecl; ! 726: register tree last; ! 727: char formatted_type_identifier_length[16]; ! 728: register int type_identifier_length; ! 729: ! 730: if (methods == NULL_TREE) ! 731: return; ! 732: ! 733: type_encoding = DECL_NAME (TYPE_NAME (type)); ! 734: ! 735: /* C++: Template classes break some assumptions made by this code about ! 736: the class names, constructor names, and encodings for assembler ! 737: label names. For now, disable output of dbx info for them. */ ! 738: { ! 739: char *ptr = IDENTIFIER_POINTER (type_encoding); ! 740: /* This should use index. (mrs) */ ! 741: while (*ptr && *ptr != '<') ptr++; ! 742: if (*ptr != 0) ! 743: { ! 744: static int warned; ! 745: if (!warned) ! 746: { ! 747: warned = 1; ! 748: #ifdef HAVE_TEMPLATES ! 749: if (warn_template_debugging) ! 750: warning ("dbx info for template class methods not yet supported"); ! 751: #endif ! 752: } ! 753: return; ! 754: } ! 755: } ! 756: ! 757: type_identifier_length = IDENTIFIER_LENGTH (type_encoding); ! 758: ! 759: sprintf(formatted_type_identifier_length, "%d", type_identifier_length); ! 760: ! 761: if (TREE_CODE (methods) == FUNCTION_DECL) ! 762: fndecl = methods; ! 763: else if (TREE_VEC_ELT (methods, 0) != NULL_TREE) ! 764: fndecl = TREE_VEC_ELT (methods, 0); ! 765: else ! 766: fndecl = TREE_VEC_ELT (methods, 1); ! 767: ! 768: while (fndecl) ! 769: { ! 770: tree name = DECL_NAME (fndecl); ! 771: int need_prefix = 1; ! 772: ! 773: /* Group together all the methods for the same operation. ! 774: These differ in the types of the arguments. */ ! 775: for (last = NULL_TREE; ! 776: fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last)); ! 777: fndecl = TREE_CHAIN (fndecl)) ! 778: /* Output the name of the field (after overloading), as ! 779: well as the name of the field before overloading, along ! 780: with its parameter list */ ! 781: { ! 782: /* This is the "mangled" name of the method. ! 783: It encodes the argument types. */ ! 784: char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); ! 785: int destructor = 0; ! 786: ! 787: CONTIN; ! 788: ! 789: last = fndecl; ! 790: ! 791: if (DECL_IGNORED_P (fndecl)) ! 792: continue; ! 793: ! 794: if (flag_minimal_debug) ! 795: { ! 796: /* Detect ordinary methods because their mangled names ! 797: start with the operation name. */ ! 798: if (!strncmp (IDENTIFIER_POINTER (name), debug_name, ! 799: IDENTIFIER_LENGTH (name))) ! 800: { ! 801: debug_name += IDENTIFIER_LENGTH (name); ! 802: if (debug_name[0] == '_' && debug_name[1] == '_') ! 803: { ! 804: char *method_name = debug_name + 2; ! 805: char *length_ptr = formatted_type_identifier_length; ! 806: /* Get past const and volatile qualifiers. */ ! 807: while (*method_name == 'C' || *method_name == 'V') ! 808: method_name++; ! 809: /* Skip digits for length of type_encoding. */ ! 810: while (*method_name == *length_ptr && *length_ptr) ! 811: length_ptr++, method_name++; ! 812: if (! strncmp (method_name, ! 813: IDENTIFIER_POINTER (type_encoding), ! 814: type_identifier_length)) ! 815: method_name += type_identifier_length; ! 816: debug_name = method_name; ! 817: } ! 818: } ! 819: /* Detect constructors by their style of name mangling. */ ! 820: else if (debug_name[0] == '_' && debug_name[1] == '_') ! 821: { ! 822: char *ctor_name = debug_name + 2; ! 823: char *length_ptr = formatted_type_identifier_length; ! 824: while (*ctor_name == 'C' || *ctor_name == 'V') ! 825: ctor_name++; ! 826: /* Skip digits for length of type_encoding. */ ! 827: while (*ctor_name == *length_ptr && *length_ptr) ! 828: length_ptr++, ctor_name++; ! 829: if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name, ! 830: type_identifier_length)) ! 831: debug_name = ctor_name + type_identifier_length; ! 832: } ! 833: /* The other alternative is a destructor. */ ! 834: else ! 835: destructor = 1; ! 836: ! 837: /* Output the operation name just once, for the first method ! 838: that we output. */ ! 839: if (need_prefix) ! 840: { ! 841: fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name)); ! 842: CHARS (IDENTIFIER_LENGTH (name) + 2); ! 843: need_prefix = 0; ! 844: } ! 845: } ! 846: ! 847: dbxout_type (TREE_TYPE (fndecl), 0, destructor); ! 848: ! 849: dbxout_type_method_1 (fndecl, debug_name); ! 850: } ! 851: if (!need_prefix) ! 852: { ! 853: putc (';', asmfile); ! 854: CHARS (1); ! 855: } ! 856: } ! 857: } ! 858: ! 859: /* Emit a "range" type specification, which has the form: ! 860: "r<index type>;<lower bound>;<upper bound>;". ! 861: TYPE is an INTEGER_TYPE. */ ! 862: ! 863: static void ! 864: dbxout_range_type (type) ! 865: tree type; ! 866: { ! 867: fprintf (asmfile, "r"); ! 868: if (TREE_TYPE (type) && TREE_CODE (TREE_TYPE(type)) != INTEGER_TYPE) ! 869: dbxout_type (TREE_TYPE (type), 0, 0); ! 870: else ! 871: { ! 872: /* This used to say `r1' and we used to take care ! 873: to make sure that `int' was type number 1. */ ! 874: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (integer_type_node)); ! 875: } ! 876: if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST) ! 877: fprintf (asmfile, ";%d", ! 878: TREE_INT_CST_LOW (TYPE_MIN_VALUE (type))); ! 879: else ! 880: fprintf (asmfile, ";0"); ! 881: if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST) ! 882: fprintf (asmfile, ";%d;", ! 883: TREE_INT_CST_LOW (TYPE_MAX_VALUE (type))); ! 884: else ! 885: fprintf (asmfile, ";-1;"); ! 886: } ! 887: ! 888: /* Output a reference to a type. If the type has not yet been ! 889: described in the dbx output, output its definition now. ! 890: For a type already defined, just refer to its definition ! 891: using the type number. ! 892: ! 893: If FULL is nonzero, and the type has been described only with ! 894: a forward-reference, output the definition now. ! 895: If FULL is zero in this case, just refer to the forward-reference ! 896: using the number previously allocated. ! 897: ! 898: If SHOW_ARG_TYPES is nonzero, we output a description of the argument ! 899: types for a METHOD_TYPE. */ ! 900: ! 901: static void ! 902: dbxout_type (type, full, show_arg_types) ! 903: tree type; ! 904: int full; ! 905: int show_arg_types; ! 906: { ! 907: register tree tem; ! 908: static int anonymous_type_number = 0; ! 909: ! 910: /* If there was an input error and we don't really have a type, ! 911: avoid crashing and write something that is at least valid ! 912: by assuming `int'. */ ! 913: if (type == error_mark_node) ! 914: type = integer_type_node; ! 915: else ! 916: { ! 917: type = TYPE_MAIN_VARIANT (type); ! 918: if (TYPE_NAME (type) ! 919: && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 920: && DECL_IGNORED_P (TYPE_NAME (type))) ! 921: full = 0; ! 922: } ! 923: ! 924: if (TYPE_SYMTAB_ADDRESS (type) == 0) ! 925: { ! 926: /* Type has no dbx number assigned. Assign next available number. */ ! 927: TYPE_SYMTAB_ADDRESS (type) = next_type_number++; ! 928: ! 929: /* Make sure type vector is long enough to record about this type. */ ! 930: ! 931: if (next_type_number == typevec_len) ! 932: { ! 933: typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]); ! 934: bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]); ! 935: typevec_len *= 2; ! 936: } ! 937: } ! 938: ! 939: /* Output the number of this type, to refer to it. */ ! 940: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type)); ! 941: CHARS (3); ! 942: ! 943: #ifdef DBX_TYPE_DEFINED ! 944: if (DBX_TYPE_DEFINED (type)) ! 945: return; ! 946: #endif ! 947: ! 948: /* If this type's definition has been output or is now being output, ! 949: that is all. */ ! 950: ! 951: switch (typevec[TYPE_SYMTAB_ADDRESS (type)]) ! 952: { ! 953: case TYPE_UNSEEN: ! 954: break; ! 955: case TYPE_XREF: ! 956: /* If we have already had a cross reference, ! 957: and either that's all we want or that's the best we could do, ! 958: don't repeat the cross reference. ! 959: Sun dbx crashes if we do. */ ! 960: if (! full || TYPE_SIZE (type) == 0 ! 961: /* No way in DBX fmt to describe a variable size. */ ! 962: || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) ! 963: return; ! 964: break; ! 965: case TYPE_DEFINED: ! 966: return; ! 967: } ! 968: ! 969: #ifdef DBX_NO_XREFS ! 970: /* For systems where dbx output does not allow the `=xsNAME:' syntax, ! 971: leave the type-number completely undefined rather than output ! 972: a cross-reference. */ ! 973: if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE ! 974: || TREE_CODE (type) == QUAL_UNION_TYPE ! 975: || TREE_CODE (type) == ENUMERAL_TYPE) ! 976: ! 977: if ((TYPE_NAME (type) != 0 && !full) ! 978: || TYPE_SIZE (type) == 0) ! 979: { ! 980: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF; ! 981: return; ! 982: } ! 983: #endif ! 984: ! 985: /* Output a definition now. */ ! 986: ! 987: fprintf (asmfile, "="); ! 988: CHARS (1); ! 989: ! 990: /* Mark it as defined, so that if it is self-referent ! 991: we will not get into an infinite recursion of definitions. */ ! 992: ! 993: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED; ! 994: ! 995: switch (TREE_CODE (type)) ! 996: { ! 997: case VOID_TYPE: ! 998: case LANG_TYPE: ! 999: /* For a void type, just define it as itself; ie, "5=5". ! 1000: This makes us consider it defined ! 1001: without saying what it is. The debugger will make it ! 1002: a void type when the reference is seen, and nothing will ! 1003: ever override that default. */ ! 1004: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type)); ! 1005: CHARS (3); ! 1006: break; ! 1007: ! 1008: case INTEGER_TYPE: ! 1009: if (type == char_type_node && ! TREE_UNSIGNED (type)) ! 1010: /* Output the type `char' as a subrange of itself! ! 1011: I don't understand this definition, just copied it ! 1012: from the output of pcc. ! 1013: This used to use `r2' explicitly and we used to ! 1014: take care to make sure that `char' was type number 2. */ ! 1015: fprintf (asmfile, "r%d;0;127;", TYPE_SYMTAB_ADDRESS (type)); ! 1016: else if (use_gnu_debug_info_extensions ! 1017: && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node) ! 1018: || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT)) ! 1019: { ! 1020: /* This used to say `r1' and we used to take care ! 1021: to make sure that `int' was type number 1. */ ! 1022: fprintf (asmfile, "r%d;", TYPE_SYMTAB_ADDRESS (integer_type_node)); ! 1023: print_int_cst_octal (TYPE_MIN_VALUE (type)); ! 1024: fprintf (asmfile, ";"); ! 1025: print_int_cst_octal (TYPE_MAX_VALUE (type)); ! 1026: fprintf (asmfile, ";"); ! 1027: } ! 1028: else /* Output other integer types as subranges of `int'. */ ! 1029: dbxout_range_type (type); ! 1030: CHARS (25); ! 1031: break; ! 1032: ! 1033: case REAL_TYPE: ! 1034: /* This used to say `r1' and we used to take care ! 1035: to make sure that `int' was type number 1. */ ! 1036: fprintf (asmfile, "r%d;%d;0;", TYPE_SYMTAB_ADDRESS (integer_type_node), ! 1037: int_size_in_bytes (type)); ! 1038: CHARS (16); ! 1039: break; ! 1040: ! 1041: case CHAR_TYPE: ! 1042: if (use_gnu_debug_info_extensions) ! 1043: fprintf (asmfile, "@s%d;-20;", ! 1044: BITS_PER_UNIT * int_size_in_bytes (type)); ! 1045: else ! 1046: /* Output the type `char' as a subrange of itself. ! 1047: That is what pcc seems to do. */ ! 1048: fprintf (asmfile, "r%d;0;%d;", TYPE_SYMTAB_ADDRESS (char_type_node), ! 1049: TREE_UNSIGNED (type) ? 255 : 127); ! 1050: CHARS (9); ! 1051: break; ! 1052: ! 1053: case BOOLEAN_TYPE: ! 1054: if (use_gnu_debug_info_extensions) ! 1055: fprintf (asmfile, "@s%d;-16;", ! 1056: BITS_PER_UNIT * int_size_in_bytes (type)); ! 1057: else /* Define as enumeral type (False, True) */ ! 1058: fprintf (asmfile, "eFalse:0,True:1,;"); ! 1059: CHARS (17); ! 1060: break; ! 1061: ! 1062: case FILE_TYPE: ! 1063: putc ('d', asmfile); ! 1064: CHARS (1); ! 1065: dbxout_type (TREE_TYPE (type), 0, 0); ! 1066: break; ! 1067: ! 1068: case COMPLEX_TYPE: ! 1069: /* Differs from the REAL_TYPE by its new data type number */ ! 1070: ! 1071: if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE) ! 1072: { ! 1073: fprintf (asmfile, "r%d;%d;0;", ! 1074: TYPE_SYMTAB_ADDRESS (type), ! 1075: int_size_in_bytes (TREE_TYPE (type))); ! 1076: CHARS (15); /* The number is probably incorrect here. */ ! 1077: } ! 1078: else ! 1079: { ! 1080: /* Output a complex integer type as a structure, ! 1081: pending some other way to do it. */ ! 1082: fprintf (asmfile, "s%d", int_size_in_bytes (type)); ! 1083: ! 1084: fprintf (asmfile, "real:"); ! 1085: CHARS (10); ! 1086: dbxout_type (TREE_TYPE (type), 0, 0); ! 1087: fprintf (asmfile, ",%d,%d;", ! 1088: 0, TYPE_PRECISION (TREE_TYPE (type))); ! 1089: CHARS (8); ! 1090: fprintf (asmfile, "imag:"); ! 1091: CHARS (5); ! 1092: dbxout_type (TREE_TYPE (type), 0, 0); ! 1093: fprintf (asmfile, ",%d,%d;;", ! 1094: TYPE_PRECISION (TREE_TYPE (type)), ! 1095: TYPE_PRECISION (TREE_TYPE (type))); ! 1096: CHARS (9); ! 1097: } ! 1098: break; ! 1099: ! 1100: case SET_TYPE: ! 1101: putc ('S', asmfile); ! 1102: CHARS (1); ! 1103: dbxout_type (TYPE_DOMAIN (type), 0, 0); ! 1104: break; ! 1105: ! 1106: case ARRAY_TYPE: ! 1107: /* Output "a" followed by a range type definition ! 1108: for the index type of the array ! 1109: followed by a reference to the target-type. ! 1110: ar1;0;N;M for a C array of type M and size N+1. */ ! 1111: tem = TYPE_DOMAIN (type); ! 1112: if (tem == NULL) ! 1113: fprintf (asmfile, "ar%d;0;-1;", ! 1114: TYPE_SYMTAB_ADDRESS (integer_type_node)); ! 1115: else ! 1116: { ! 1117: fprintf (asmfile, "a"); ! 1118: dbxout_range_type (tem); ! 1119: } ! 1120: CHARS (17); ! 1121: dbxout_type (TREE_TYPE (type), 0, 0); ! 1122: break; ! 1123: ! 1124: case RECORD_TYPE: ! 1125: case UNION_TYPE: ! 1126: case QUAL_UNION_TYPE: ! 1127: { ! 1128: int i, n_baseclasses = 0; ! 1129: ! 1130: if (TYPE_BINFO (type) != 0 && TYPE_BINFO_BASETYPES (type) != 0) ! 1131: n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)); ! 1132: ! 1133: /* Output a structure type. */ ! 1134: if ((TYPE_NAME (type) != 0 ! 1135: /* Long ago, Tiemann said this creates output that "confuses GDB". ! 1136: In April 93, [email protected] said there is no such problem. ! 1137: The type decls made automatically by struct specifiers ! 1138: are marked with DECL_IGNORED_P in C++. */ ! 1139: #if 0 /* This creates output for anonymous classes which confuses GDB. */ ! 1140: && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 1141: && DECL_IGNORED_P (TYPE_NAME (type))) ! 1142: #endif ! 1143: && !full) ! 1144: || TYPE_SIZE (type) == 0 ! 1145: /* No way in DBX fmt to describe a variable size. */ ! 1146: || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) ! 1147: { ! 1148: /* If the type is just a cross reference, output one ! 1149: and mark the type as partially described. ! 1150: If it later becomes defined, we will output ! 1151: its real definition. ! 1152: If the type has a name, don't nest its definition within ! 1153: another type's definition; instead, output an xref ! 1154: and let the definition come when the name is defined. */ ! 1155: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu"); ! 1156: CHARS (3); ! 1157: #if 0 /* This assertion is legitimately false in C++. */ ! 1158: /* We shouldn't be outputting a reference to a type before its ! 1159: definition unless the type has a tag name. ! 1160: A typedef name without a tag name should be impossible. */ ! 1161: if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE) ! 1162: abort (); ! 1163: #endif ! 1164: if (TYPE_NAME (type) != 0) ! 1165: dbxout_type_name (type); ! 1166: else ! 1167: fprintf (asmfile, "$$%d", anonymous_type_number++); ! 1168: fprintf (asmfile, ":"); ! 1169: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF; ! 1170: break; ! 1171: } ! 1172: ! 1173: /* Identify record or union, and print its size. */ ! 1174: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d", ! 1175: int_size_in_bytes (type)); ! 1176: ! 1177: if (use_gnu_debug_info_extensions) ! 1178: { ! 1179: if (n_baseclasses) ! 1180: { ! 1181: have_used_extensions = 1; ! 1182: fprintf (asmfile, "!%d,", n_baseclasses); ! 1183: CHARS (8); ! 1184: } ! 1185: } ! 1186: for (i = 0; i < n_baseclasses; i++) ! 1187: { ! 1188: tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i); ! 1189: if (use_gnu_debug_info_extensions) ! 1190: { ! 1191: have_used_extensions = 1; ! 1192: putc (TREE_VIA_VIRTUAL (child) ? '1' ! 1193: : '0', ! 1194: asmfile); ! 1195: putc (TREE_VIA_PUBLIC (child) ? '2' ! 1196: : '0', ! 1197: asmfile); ! 1198: fprintf (asmfile, "%d,", ! 1199: TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT); ! 1200: CHARS (15); ! 1201: dbxout_type (BINFO_TYPE (child), 0, 0); ! 1202: putc (';', asmfile); ! 1203: } ! 1204: else ! 1205: { ! 1206: /* Print out the base class information with fields ! 1207: which have the same names at the types they hold. */ ! 1208: dbxout_type_name (BINFO_TYPE (child)); ! 1209: putc (':', asmfile); ! 1210: dbxout_type (BINFO_TYPE (child), full, 0); ! 1211: fprintf (asmfile, ",%d,%d;", ! 1212: TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT, ! 1213: TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT); ! 1214: CHARS (20); ! 1215: } ! 1216: } ! 1217: } ! 1218: ! 1219: CHARS (11); ! 1220: ! 1221: /* Write out the field declarations. */ ! 1222: dbxout_type_fields (type); ! 1223: if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE) ! 1224: { ! 1225: have_used_extensions = 1; ! 1226: dbxout_type_methods (type); ! 1227: } ! 1228: putc (';', asmfile); ! 1229: ! 1230: if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE ! 1231: /* Avoid the ~ if we don't really need it--it confuses dbx. */ ! 1232: && TYPE_VFIELD (type)) ! 1233: { ! 1234: have_used_extensions = 1; ! 1235: ! 1236: /* Tell GDB+ that it may keep reading. */ ! 1237: putc ('~', asmfile); ! 1238: ! 1239: /* We need to write out info about what field this class ! 1240: uses as its "main" vtable pointer field, because if this ! 1241: field is inherited from a base class, GDB cannot necessarily ! 1242: figure out which field it's using in time. */ ! 1243: if (TYPE_VFIELD (type)) ! 1244: { ! 1245: putc ('%', asmfile); ! 1246: dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0); ! 1247: } ! 1248: putc (';', asmfile); ! 1249: CHARS (3); ! 1250: } ! 1251: break; ! 1252: ! 1253: case ENUMERAL_TYPE: ! 1254: if ((TYPE_NAME (type) != 0 && !full ! 1255: && (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL ! 1256: && ! DECL_IGNORED_P (TYPE_NAME (type)))) ! 1257: || TYPE_SIZE (type) == 0) ! 1258: { ! 1259: fprintf (asmfile, "xe"); ! 1260: CHARS (3); ! 1261: dbxout_type_name (type); ! 1262: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF; ! 1263: fprintf (asmfile, ":"); ! 1264: return; ! 1265: } ! 1266: #ifdef DBX_OUTPUT_ENUM ! 1267: DBX_OUTPUT_ENUM (asmfile, type); ! 1268: #else ! 1269: putc ('e', asmfile); ! 1270: CHARS (1); ! 1271: for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem)) ! 1272: { ! 1273: fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem))); ! 1274: if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0) ! 1275: fprintf (asmfile, "%lu", ! 1276: (unsigned long) TREE_INT_CST_LOW (TREE_VALUE (tem))); ! 1277: else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1 ! 1278: && TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0) ! 1279: fprintf (asmfile, "%ld", ! 1280: (long) TREE_INT_CST_LOW (TREE_VALUE (tem))); ! 1281: else ! 1282: print_int_cst_octal (TREE_VALUE (tem)); ! 1283: fprintf (asmfile, ","); ! 1284: CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem))); ! 1285: if (TREE_CHAIN (tem) != 0) ! 1286: CONTIN; ! 1287: } ! 1288: putc (';', asmfile); ! 1289: CHARS (1); ! 1290: #endif ! 1291: break; ! 1292: ! 1293: case POINTER_TYPE: ! 1294: putc ('*', asmfile); ! 1295: CHARS (1); ! 1296: dbxout_type (TREE_TYPE (type), 0, 0); ! 1297: break; ! 1298: ! 1299: case METHOD_TYPE: ! 1300: if (use_gnu_debug_info_extensions) ! 1301: { ! 1302: have_used_extensions = 1; ! 1303: putc ('#', asmfile); ! 1304: CHARS (1); ! 1305: if (flag_minimal_debug && !show_arg_types) ! 1306: { ! 1307: /* Normally, just output the return type. ! 1308: The argument types are encoded in the method name. */ ! 1309: putc ('#', asmfile); ! 1310: dbxout_type (TREE_TYPE (type), 0, 0); ! 1311: putc (';', asmfile); ! 1312: CHARS (1); ! 1313: } ! 1314: else ! 1315: { ! 1316: /* When outputting destructors, we need to write ! 1317: the argument types out longhand. */ ! 1318: dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0); ! 1319: putc (',', asmfile); ! 1320: CHARS (1); ! 1321: dbxout_type (TREE_TYPE (type), 0, 0); ! 1322: dbxout_args (TYPE_ARG_TYPES (type)); ! 1323: putc (';', asmfile); ! 1324: CHARS (1); ! 1325: } ! 1326: } ! 1327: else ! 1328: { ! 1329: /* Treat it as a function type. */ ! 1330: dbxout_type (TREE_TYPE (type), 0, 0); ! 1331: } ! 1332: break; ! 1333: ! 1334: case OFFSET_TYPE: ! 1335: if (use_gnu_debug_info_extensions) ! 1336: { ! 1337: have_used_extensions = 1; ! 1338: putc ('@', asmfile); ! 1339: CHARS (1); ! 1340: dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0); ! 1341: putc (',', asmfile); ! 1342: CHARS (1); ! 1343: dbxout_type (TREE_TYPE (type), 0, 0); ! 1344: } ! 1345: else ! 1346: { ! 1347: /* Should print as an int, because it is really ! 1348: just an offset. */ ! 1349: dbxout_type (integer_type_node, 0, 0); ! 1350: } ! 1351: break; ! 1352: ! 1353: case REFERENCE_TYPE: ! 1354: if (use_gnu_debug_info_extensions) ! 1355: have_used_extensions = 1; ! 1356: putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile); ! 1357: CHARS (1); ! 1358: dbxout_type (TREE_TYPE (type), 0, 0); ! 1359: break; ! 1360: ! 1361: case FUNCTION_TYPE: ! 1362: putc ('f', asmfile); ! 1363: CHARS (1); ! 1364: dbxout_type (TREE_TYPE (type), 0, 0); ! 1365: break; ! 1366: ! 1367: default: ! 1368: abort (); ! 1369: } ! 1370: } ! 1371: ! 1372: /* Print the value of integer constant C, in octal, ! 1373: handling double precision. */ ! 1374: ! 1375: static void ! 1376: print_int_cst_octal (c) ! 1377: tree c; ! 1378: { ! 1379: unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (c); ! 1380: unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (c); ! 1381: int excess = (3 - (HOST_BITS_PER_WIDE_INT % 3)); ! 1382: int width = TYPE_PRECISION (TREE_TYPE (c)); ! 1383: ! 1384: /* GDB wants constants with no extra leading "1" bits, so ! 1385: we need to remove any sign-extension that might be ! 1386: present. */ ! 1387: if (width == HOST_BITS_PER_WIDE_INT * 2) ! 1388: ; ! 1389: else if (width > HOST_BITS_PER_WIDE_INT) ! 1390: high &= (((HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT)) - 1); ! 1391: else if (width == HOST_BITS_PER_WIDE_INT) ! 1392: high = 0; ! 1393: else ! 1394: high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1); ! 1395: ! 1396: fprintf (asmfile, "0"); ! 1397: ! 1398: if (excess == 3) ! 1399: { ! 1400: print_octal (high, HOST_BITS_PER_WIDE_INT / 3); ! 1401: print_octal (low, HOST_BITS_PER_WIDE_INT / 3); ! 1402: } ! 1403: else ! 1404: { ! 1405: unsigned HOST_WIDE_INT beg = high >> excess; ! 1406: unsigned HOST_WIDE_INT middle ! 1407: = ((high & (((HOST_WIDE_INT) 1 << excess) - 1)) << (3 - excess) ! 1408: | (low >> (HOST_BITS_PER_WIDE_INT / 3 * 3))); ! 1409: unsigned HOST_WIDE_INT end ! 1410: = low & (((unsigned HOST_WIDE_INT) 1 ! 1411: << (HOST_BITS_PER_WIDE_INT / 3 * 3)) ! 1412: - 1); ! 1413: ! 1414: fprintf (asmfile, "%o%01o", beg, middle); ! 1415: print_octal (end, HOST_BITS_PER_WIDE_INT / 3); ! 1416: } ! 1417: } ! 1418: ! 1419: static void ! 1420: print_octal (value, digits) ! 1421: unsigned HOST_WIDE_INT value; ! 1422: int digits; ! 1423: { ! 1424: int i; ! 1425: ! 1426: for (i = digits - 1; i >= 0; i--) ! 1427: fprintf (asmfile, "%01o", ((value >> (3 * i)) & 7)); ! 1428: } ! 1429: ! 1430: /* Output the name of type TYPE, with no punctuation. ! 1431: Such names can be set up either by typedef declarations ! 1432: or by struct, enum and union tags. */ ! 1433: ! 1434: static void ! 1435: dbxout_type_name (type) ! 1436: register tree type; ! 1437: { ! 1438: tree t; ! 1439: if (TYPE_NAME (type) == 0) ! 1440: abort (); ! 1441: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE) ! 1442: { ! 1443: t = TYPE_NAME (type); ! 1444: } ! 1445: else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) ! 1446: { ! 1447: t = DECL_NAME (TYPE_NAME (type)); ! 1448: } ! 1449: else ! 1450: abort (); ! 1451: ! 1452: fprintf (asmfile, "%s", IDENTIFIER_POINTER (t)); ! 1453: CHARS (IDENTIFIER_LENGTH (t)); ! 1454: } ! 1455: ! 1456: /* Output a .stabs for the symbol defined by DECL, ! 1457: which must be a ..._DECL node in the normal namespace. ! 1458: It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL. ! 1459: LOCAL is nonzero if the scope is less than the entire file. */ ! 1460: ! 1461: void ! 1462: dbxout_symbol (decl, local) ! 1463: tree decl; ! 1464: int local; ! 1465: { ! 1466: int letter = 0; ! 1467: tree type = TREE_TYPE (decl); ! 1468: tree context = NULL_TREE; ! 1469: int regno = -1; ! 1470: ! 1471: /* Cast avoids warning in old compilers. */ ! 1472: current_sym_code = (STAB_CODE_TYPE) 0; ! 1473: current_sym_value = 0; ! 1474: current_sym_addr = 0; ! 1475: ! 1476: /* Ignore nameless syms, but don't ignore type tags. */ ! 1477: ! 1478: if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL) ! 1479: || DECL_IGNORED_P (decl)) ! 1480: return; ! 1481: ! 1482: dbxout_prepare_symbol (decl); ! 1483: ! 1484: /* The output will always start with the symbol name, ! 1485: so always count that in the length-output-so-far. */ ! 1486: ! 1487: if (DECL_NAME (decl) != 0) ! 1488: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl)); ! 1489: ! 1490: switch (TREE_CODE (decl)) ! 1491: { ! 1492: case CONST_DECL: ! 1493: /* Enum values are defined by defining the enum type. */ ! 1494: break; ! 1495: ! 1496: case FUNCTION_DECL: ! 1497: if (DECL_RTL (decl) == 0) ! 1498: return; ! 1499: if (DECL_EXTERNAL (decl)) ! 1500: break; ! 1501: /* Don't mention a nested function under its parent. */ ! 1502: context = decl_function_context (decl); ! 1503: if (context == current_function_decl) ! 1504: break; ! 1505: if (GET_CODE (DECL_RTL (decl)) != MEM ! 1506: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF) ! 1507: break; ! 1508: FORCE_TEXT; ! 1509: ! 1510: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, ! 1511: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), ! 1512: TREE_PUBLIC (decl) ? 'F' : 'f'); ! 1513: ! 1514: current_sym_code = N_FUN; ! 1515: current_sym_addr = XEXP (DECL_RTL (decl), 0); ! 1516: ! 1517: if (TREE_TYPE (type)) ! 1518: dbxout_type (TREE_TYPE (type), 0, 0); ! 1519: else ! 1520: dbxout_type (void_type_node, 0, 0); ! 1521: ! 1522: /* For a nested function, when that function is compiled, ! 1523: mention the containing function name ! 1524: as well as (since dbx wants it) our own assembler-name. */ ! 1525: if (context != 0) ! 1526: fprintf (asmfile, ",%s,%s", ! 1527: IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), ! 1528: IDENTIFIER_POINTER (DECL_NAME (context))); ! 1529: ! 1530: dbxout_finish_symbol (decl); ! 1531: break; ! 1532: ! 1533: case TYPE_DECL: ! 1534: #if 0 ! 1535: /* This seems all wrong. Outputting most kinds of types gives no name ! 1536: at all. A true definition gives no name; a cross-ref for a ! 1537: structure can give the tag name, but not a type name. ! 1538: It seems that no typedef name is defined by outputting a type. */ ! 1539: ! 1540: /* If this typedef name was defined by outputting the type, ! 1541: don't duplicate it. */ ! 1542: if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED ! 1543: && TYPE_NAME (TREE_TYPE (decl)) == decl) ! 1544: return; ! 1545: #endif ! 1546: /* Don't output the same typedef twice. ! 1547: And don't output what language-specific stuff doesn't want output. */ ! 1548: if (TREE_ASM_WRITTEN (decl) || DECL_IGNORED_P (decl)) ! 1549: return; ! 1550: ! 1551: FORCE_TEXT; ! 1552: ! 1553: { ! 1554: int tag_needed = 1; ! 1555: int did_output = 0; ! 1556: ! 1557: if (DECL_NAME (decl)) ! 1558: { ! 1559: /* Nonzero means we must output a tag as well as a typedef. */ ! 1560: tag_needed = 0; ! 1561: ! 1562: /* Handle the case of a C++ structure or union ! 1563: where the TYPE_NAME is a TYPE_DECL ! 1564: which gives both a typedef name and a tag. */ ! 1565: /* dbx requires the tag first and the typedef second. */ ! 1566: if ((TREE_CODE (type) == RECORD_TYPE ! 1567: || TREE_CODE (type) == UNION_TYPE ! 1568: || TREE_CODE (type) == QUAL_UNION_TYPE) ! 1569: && TYPE_NAME (type) == decl ! 1570: && !(use_gnu_debug_info_extensions && have_used_extensions) ! 1571: && !TREE_ASM_WRITTEN (TYPE_NAME (type)) ! 1572: /* Distinguish the implicit typedefs of C++ ! 1573: from explicit ones that might be found in C. */ ! 1574: && (!strcmp (lang_identify (), "cplusplus") ! 1575: /* The following line maybe unnecessary; ! 1576: in 2.6, try removing it. */ ! 1577: || DECL_SOURCE_LINE (decl) == 0)) ! 1578: { ! 1579: tree name = TYPE_NAME (type); ! 1580: if (TREE_CODE (name) == TYPE_DECL) ! 1581: name = DECL_NAME (name); ! 1582: ! 1583: current_sym_code = DBX_TYPE_DECL_STABS_CODE; ! 1584: current_sym_value = 0; ! 1585: current_sym_addr = 0; ! 1586: current_sym_nchars = 2 + IDENTIFIER_LENGTH (name); ! 1587: ! 1588: fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP, ! 1589: IDENTIFIER_POINTER (name)); ! 1590: dbxout_type (type, 1, 0); ! 1591: dbxout_finish_symbol (NULL_TREE); ! 1592: } ! 1593: ! 1594: /* Output typedef name. */ ! 1595: fprintf (asmfile, "%s \"%s:", ASM_STABS_OP, ! 1596: IDENTIFIER_POINTER (DECL_NAME (decl))); ! 1597: ! 1598: /* Short cut way to output a tag also. */ ! 1599: if ((TREE_CODE (type) == RECORD_TYPE ! 1600: || TREE_CODE (type) == UNION_TYPE ! 1601: || TREE_CODE (type) == QUAL_UNION_TYPE) ! 1602: && TYPE_NAME (type) == decl) ! 1603: { ! 1604: if (use_gnu_debug_info_extensions && have_used_extensions) ! 1605: { ! 1606: putc ('T', asmfile); ! 1607: TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1; ! 1608: } ! 1609: #if 0 /* Now we generate the tag for this case up above. */ ! 1610: else ! 1611: tag_needed = 1; ! 1612: #endif ! 1613: } ! 1614: ! 1615: putc ('t', asmfile); ! 1616: current_sym_code = DBX_TYPE_DECL_STABS_CODE; ! 1617: ! 1618: dbxout_type (type, 1, 0); ! 1619: dbxout_finish_symbol (decl); ! 1620: did_output = 1; ! 1621: } ! 1622: ! 1623: /* Don't output a tag if this is an incomplete type (TYPE_SIZE is ! 1624: zero). This prevents the sun4 Sun OS 4.x dbx from crashing. */ ! 1625: ! 1626: if (tag_needed && TYPE_NAME (type) != 0 && TYPE_SIZE (type) != 0 ! 1627: && !TREE_ASM_WRITTEN (TYPE_NAME (type))) ! 1628: { ! 1629: /* For a TYPE_DECL with no name, but the type has a name, ! 1630: output a tag. ! 1631: This is what represents `struct foo' with no typedef. */ ! 1632: /* In C++, the name of a type is the corresponding typedef. ! 1633: In C, it is an IDENTIFIER_NODE. */ ! 1634: tree name = TYPE_NAME (type); ! 1635: if (TREE_CODE (name) == TYPE_DECL) ! 1636: name = DECL_NAME (name); ! 1637: ! 1638: current_sym_code = DBX_TYPE_DECL_STABS_CODE; ! 1639: current_sym_value = 0; ! 1640: current_sym_addr = 0; ! 1641: current_sym_nchars = 2 + IDENTIFIER_LENGTH (name); ! 1642: ! 1643: fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP, ! 1644: IDENTIFIER_POINTER (name)); ! 1645: dbxout_type (type, 1, 0); ! 1646: dbxout_finish_symbol (NULL_TREE); ! 1647: did_output = 1; ! 1648: } ! 1649: ! 1650: /* If an enum type has no name, it cannot be referred to, ! 1651: but we must output it anyway, since the enumeration constants ! 1652: can be referred to. */ ! 1653: if (!did_output && TREE_CODE (type) == ENUMERAL_TYPE) ! 1654: { ! 1655: current_sym_code = DBX_TYPE_DECL_STABS_CODE; ! 1656: current_sym_value = 0; ! 1657: current_sym_addr = 0; ! 1658: current_sym_nchars = 2; ! 1659: ! 1660: /* Some debuggers fail when given NULL names, so give this a ! 1661: harmless name of ` '. */ ! 1662: fprintf (asmfile, "%s \" :T", ASM_STABS_OP); ! 1663: dbxout_type (type, 1, 0); ! 1664: dbxout_finish_symbol (NULL_TREE); ! 1665: } ! 1666: ! 1667: /* Prevent duplicate output of a typedef. */ ! 1668: TREE_ASM_WRITTEN (decl) = 1; ! 1669: break; ! 1670: } ! 1671: ! 1672: case PARM_DECL: ! 1673: /* Parm decls go in their own separate chains ! 1674: and are output by dbxout_reg_parms and dbxout_parms. */ ! 1675: abort (); ! 1676: ! 1677: case RESULT_DECL: ! 1678: /* Named return value, treat like a VAR_DECL. */ ! 1679: case VAR_DECL: ! 1680: if (DECL_RTL (decl) == 0) ! 1681: return; ! 1682: /* Don't mention a variable that is external. ! 1683: Let the file that defines it describe it. */ ! 1684: if (DECL_EXTERNAL (decl)) ! 1685: break; ! 1686: ! 1687: /* If the variable is really a constant ! 1688: and not written in memory, inform the debugger. */ ! 1689: if (TREE_STATIC (decl) && TREE_READONLY (decl) ! 1690: && DECL_INITIAL (decl) != 0 ! 1691: && ! TREE_ASM_WRITTEN (decl) ! 1692: && (DECL_FIELD_CONTEXT (decl) == NULL_TREE ! 1693: || TREE_CODE (DECL_FIELD_CONTEXT (decl)) == BLOCK)) ! 1694: { ! 1695: if (TREE_PUBLIC (decl) == 0) ! 1696: { ! 1697: /* The sun4 assembler does not grok this. */ ! 1698: char *name = IDENTIFIER_POINTER (DECL_NAME (decl)); ! 1699: if (TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE ! 1700: || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) ! 1701: { ! 1702: HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl)); ! 1703: #ifdef DBX_OUTPUT_CONSTANT_SYMBOL ! 1704: DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival); ! 1705: #else ! 1706: fprintf (asmfile, "%s \"%s:c=i%d\",0x%x,0,0,0\n", ! 1707: ASM_STABS_OP, name, ival, N_LSYM); ! 1708: #endif ! 1709: return; ! 1710: } ! 1711: else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE) ! 1712: { ! 1713: /* don't know how to do this yet. */ ! 1714: } ! 1715: break; ! 1716: } ! 1717: /* else it is something we handle like a normal variable. */ ! 1718: } ! 1719: ! 1720: DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); ! 1721: #ifdef LEAF_REG_REMAP ! 1722: if (leaf_function) ! 1723: leaf_renumber_regs_insn (DECL_RTL (decl)); ! 1724: #endif ! 1725: ! 1726: dbxout_symbol_location (decl, type, 0, DECL_RTL (decl)); ! 1727: } ! 1728: } ! 1729: ! 1730: /* Output the stab for DECL, a VAR_DECL, RESULT_DECL or PARM_DECL. ! 1731: Add SUFFIX to its name, if SUFFIX is not 0. ! 1732: Describe the variable as residing in HOME ! 1733: (usually HOME is DECL_RTL (DECL), but not always). */ ! 1734: ! 1735: static void ! 1736: dbxout_symbol_location (decl, type, suffix, home) ! 1737: tree decl, type; ! 1738: char *suffix; ! 1739: rtx home; ! 1740: { ! 1741: int letter = 0; ! 1742: int regno = -1; ! 1743: ! 1744: /* Don't mention a variable at all ! 1745: if it was completely optimized into nothingness. ! 1746: ! 1747: If the decl was from an inline function, then it's rtl ! 1748: is not identically the rtl that was used in this ! 1749: particular compilation. */ ! 1750: if (GET_CODE (home) == REG) ! 1751: { ! 1752: regno = REGNO (home); ! 1753: if (regno >= FIRST_PSEUDO_REGISTER) ! 1754: return; ! 1755: } ! 1756: else if (GET_CODE (home) == SUBREG) ! 1757: { ! 1758: rtx value = home; ! 1759: int offset = 0; ! 1760: while (GET_CODE (value) == SUBREG) ! 1761: { ! 1762: offset += SUBREG_WORD (value); ! 1763: value = SUBREG_REG (value); ! 1764: } ! 1765: if (GET_CODE (value) == REG) ! 1766: { ! 1767: regno = REGNO (value); ! 1768: if (regno >= FIRST_PSEUDO_REGISTER) ! 1769: return; ! 1770: regno += offset; ! 1771: } ! 1772: alter_subreg (home); ! 1773: } ! 1774: ! 1775: /* The kind-of-variable letter depends on where ! 1776: the variable is and on the scope of its name: ! 1777: G and N_GSYM for static storage and global scope, ! 1778: S for static storage and file scope, ! 1779: V for static storage and local scope, ! 1780: for those two, use N_LCSYM if data is in bss segment, ! 1781: N_STSYM if in data segment, N_FUN otherwise. ! 1782: (We used N_FUN originally, then changed to N_STSYM ! 1783: to please GDB. However, it seems that confused ld. ! 1784: Now GDB has been fixed to like N_FUN, says Kingdon.) ! 1785: no letter at all, and N_LSYM, for auto variable, ! 1786: r and N_RSYM for register variable. */ ! 1787: ! 1788: if (GET_CODE (home) == MEM ! 1789: && GET_CODE (XEXP (home, 0)) == SYMBOL_REF) ! 1790: { ! 1791: if (TREE_PUBLIC (decl)) ! 1792: { ! 1793: letter = 'G'; ! 1794: current_sym_code = N_GSYM; ! 1795: } ! 1796: else ! 1797: { ! 1798: current_sym_addr = XEXP (home, 0); ! 1799: ! 1800: letter = decl_function_context (decl) ? 'V' : 'S'; ! 1801: ! 1802: if (!DECL_INITIAL (decl)) ! 1803: current_sym_code = N_LCSYM; ! 1804: else if (DECL_IN_TEXT_SECTION (decl)) ! 1805: /* This is not quite right, but it's the closest ! 1806: of all the codes that Unix defines. */ ! 1807: current_sym_code = DBX_STATIC_CONST_VAR_CODE; ! 1808: else ! 1809: { ! 1810: /* Ultrix `as' seems to need this. */ ! 1811: #ifdef DBX_STATIC_STAB_DATA_SECTION ! 1812: data_section (); ! 1813: #endif ! 1814: current_sym_code = N_STSYM; ! 1815: } ! 1816: } ! 1817: } ! 1818: else if (regno >= 0) ! 1819: { ! 1820: letter = 'r'; ! 1821: current_sym_code = N_RSYM; ! 1822: current_sym_value = DBX_REGISTER_NUMBER (regno); ! 1823: } ! 1824: else if (GET_CODE (home) == MEM ! 1825: && (GET_CODE (XEXP (home, 0)) == MEM ! 1826: || (GET_CODE (XEXP (home, 0)) == REG ! 1827: && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM))) ! 1828: /* If the value is indirect by memory or by a register ! 1829: that isn't the frame pointer ! 1830: then it means the object is variable-sized and address through ! 1831: that register or stack slot. DBX has no way to represent this ! 1832: so all we can do is output the variable as a pointer. ! 1833: If it's not a parameter, ignore it. ! 1834: (VAR_DECLs like this can be made by integrate.c.) */ ! 1835: { ! 1836: if (GET_CODE (XEXP (home, 0)) == REG) ! 1837: { ! 1838: letter = 'r'; ! 1839: current_sym_code = N_RSYM; ! 1840: current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (home, 0))); ! 1841: } ! 1842: else ! 1843: { ! 1844: current_sym_code = N_LSYM; ! 1845: /* RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))). ! 1846: We want the value of that CONST_INT. */ ! 1847: current_sym_value ! 1848: = DEBUGGER_AUTO_OFFSET (XEXP (XEXP (home, 0), 0)); ! 1849: } ! 1850: ! 1851: /* Effectively do build_pointer_type, but don't cache this type, ! 1852: since it might be temporary whereas the type it points to ! 1853: might have been saved for inlining. */ ! 1854: /* Don't use REFERENCE_TYPE because dbx can't handle that. */ ! 1855: type = make_node (POINTER_TYPE); ! 1856: TREE_TYPE (type) = TREE_TYPE (decl); ! 1857: } ! 1858: else if (GET_CODE (home) == MEM ! 1859: && GET_CODE (XEXP (home, 0)) == REG) ! 1860: { ! 1861: current_sym_code = N_LSYM; ! 1862: current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0)); ! 1863: } ! 1864: else if (GET_CODE (home) == MEM ! 1865: && GET_CODE (XEXP (home, 0)) == PLUS ! 1866: && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT) ! 1867: { ! 1868: current_sym_code = N_LSYM; ! 1869: /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...))) ! 1870: We want the value of that CONST_INT. */ ! 1871: current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0)); ! 1872: } ! 1873: else if (GET_CODE (home) == MEM ! 1874: && GET_CODE (XEXP (home, 0)) == CONST) ! 1875: { ! 1876: /* Handle an obscure case which can arise when optimizing and ! 1877: when there are few available registers. (This is *always* ! 1878: the case for i386/i486 targets). The RTL looks like ! 1879: (MEM (CONST ...)) even though this variable is a local `auto' ! 1880: or a local `register' variable. In effect, what has happened ! 1881: is that the reload pass has seen that all assignments and ! 1882: references for one such a local variable can be replaced by ! 1883: equivalent assignments and references to some static storage ! 1884: variable, thereby avoiding the need for a register. In such ! 1885: cases we're forced to lie to debuggers and tell them that ! 1886: this variable was itself `static'. */ ! 1887: current_sym_code = N_LCSYM; ! 1888: letter = 'V'; ! 1889: current_sym_addr = XEXP (XEXP (home, 0), 0); ! 1890: } ! 1891: else if (GET_CODE (home) == CONCAT) ! 1892: { ! 1893: tree subtype = TREE_TYPE (type); ! 1894: ! 1895: /* If the variable's storage is in two parts, ! 1896: output each as a separate stab with a modified name. */ ! 1897: if (WORDS_BIG_ENDIAN) ! 1898: dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 0)); ! 1899: else ! 1900: dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0)); ! 1901: ! 1902: /* Cast avoids warning in old compilers. */ ! 1903: current_sym_code = (STAB_CODE_TYPE) 0; ! 1904: current_sym_value = 0; ! 1905: current_sym_addr = 0; ! 1906: dbxout_prepare_symbol (decl); ! 1907: ! 1908: if (WORDS_BIG_ENDIAN) ! 1909: dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 1)); ! 1910: else ! 1911: dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 1)); ! 1912: return; ! 1913: } ! 1914: else ! 1915: /* Address might be a MEM, when DECL is a variable-sized object. ! 1916: Or it might be const0_rtx, meaning previous passes ! 1917: want us to ignore this variable. */ ! 1918: return; ! 1919: ! 1920: /* Ok, start a symtab entry and output the variable name. */ ! 1921: FORCE_TEXT; ! 1922: ! 1923: #ifdef DBX_STATIC_BLOCK_START ! 1924: DBX_STATIC_BLOCK_START (asmfile, current_sym_code); ! 1925: #endif ! 1926: ! 1927: dbxout_symbol_name (decl, suffix, letter); ! 1928: dbxout_type (type, 0, 0); ! 1929: dbxout_finish_symbol (decl); ! 1930: ! 1931: #ifdef DBX_STATIC_BLOCK_END ! 1932: DBX_STATIC_BLOCK_END (asmfile, current_sym_code); ! 1933: #endif ! 1934: } ! 1935: ! 1936: /* Output the symbol name of DECL for a stabs, with suffix SUFFIX. ! 1937: Then output LETTER to indicate the kind of location the symbol has. */ ! 1938: ! 1939: static void ! 1940: dbxout_symbol_name (decl, suffix, letter) ! 1941: tree decl; ! 1942: char *suffix; ! 1943: int letter; ! 1944: { ! 1945: /* One slight hitch: if this is a VAR_DECL which is a static ! 1946: class member, we must put out the mangled name instead of the ! 1947: DECL_NAME. */ ! 1948: ! 1949: char *name; ! 1950: /* Note also that static member (variable) names DO NOT begin ! 1951: with underscores in .stabs directives. */ ! 1952: if (DECL_LANG_SPECIFIC (decl)) ! 1953: name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); ! 1954: else ! 1955: name = IDENTIFIER_POINTER (DECL_NAME (decl)); ! 1956: if (name == 0) ! 1957: name = "(anon)"; ! 1958: fprintf (asmfile, "%s \"%s%s:", ASM_STABS_OP, name, ! 1959: (suffix ? suffix : "")); ! 1960: ! 1961: if (letter) putc (letter, asmfile); ! 1962: } ! 1963: ! 1964: static void ! 1965: dbxout_prepare_symbol (decl) ! 1966: tree decl; ! 1967: { ! 1968: #ifdef WINNING_GDB ! 1969: char *filename = DECL_SOURCE_FILE (decl); ! 1970: ! 1971: dbxout_source_file (asmfile, filename); ! 1972: #endif ! 1973: } ! 1974: ! 1975: static void ! 1976: dbxout_finish_symbol (sym) ! 1977: tree sym; ! 1978: { ! 1979: #ifdef DBX_FINISH_SYMBOL ! 1980: DBX_FINISH_SYMBOL (sym); ! 1981: #else ! 1982: int line = 0; ! 1983: if (use_gnu_debug_info_extensions && sym != 0) ! 1984: line = DECL_SOURCE_LINE (sym); ! 1985: ! 1986: fprintf (asmfile, "\",%d,0,%d,", current_sym_code, line); ! 1987: if (current_sym_addr) ! 1988: output_addr_const (asmfile, current_sym_addr); ! 1989: else ! 1990: fprintf (asmfile, "%d", current_sym_value); ! 1991: putc ('\n', asmfile); ! 1992: #endif ! 1993: } ! 1994: ! 1995: /* Output definitions of all the decls in a chain. */ ! 1996: ! 1997: void ! 1998: dbxout_syms (syms) ! 1999: tree syms; ! 2000: { ! 2001: while (syms) ! 2002: { ! 2003: dbxout_symbol (syms, 1); ! 2004: syms = TREE_CHAIN (syms); ! 2005: } ! 2006: } ! 2007: ! 2008: /* The following two functions output definitions of function parameters. ! 2009: Each parameter gets a definition locating it in the parameter list. ! 2010: Each parameter that is a register variable gets a second definition ! 2011: locating it in the register. ! 2012: ! 2013: Printing or argument lists in gdb uses the definitions that ! 2014: locate in the parameter list. But reference to the variable in ! 2015: expressions uses preferentially the definition as a register. */ ! 2016: ! 2017: /* Output definitions, referring to storage in the parmlist, ! 2018: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */ ! 2019: ! 2020: void ! 2021: dbxout_parms (parms) ! 2022: tree parms; ! 2023: { ! 2024: for (; parms; parms = TREE_CHAIN (parms)) ! 2025: if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node) ! 2026: { ! 2027: dbxout_prepare_symbol (parms); ! 2028: ! 2029: /* Perform any necessary register eliminations on the parameter's rtl, ! 2030: so that the debugging output will be accurate. */ ! 2031: DECL_INCOMING_RTL (parms) ! 2032: = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); ! 2033: DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX); ! 2034: #ifdef LEAF_REG_REMAP ! 2035: if (leaf_function) ! 2036: { ! 2037: leaf_renumber_regs_insn (DECL_INCOMING_RTL (parms)); ! 2038: leaf_renumber_regs_insn (DECL_RTL (parms)); ! 2039: } ! 2040: #endif ! 2041: ! 2042: if (PARM_PASSED_IN_MEMORY (parms)) ! 2043: { ! 2044: rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0); ! 2045: ! 2046: /* ??? Here we assume that the parm address is indexed ! 2047: off the frame pointer or arg pointer. ! 2048: If that is not true, we produce meaningless results, ! 2049: but do not crash. */ ! 2050: if (GET_CODE (addr) == PLUS ! 2051: && GET_CODE (XEXP (addr, 1)) == CONST_INT) ! 2052: current_sym_value = INTVAL (XEXP (addr, 1)); ! 2053: else ! 2054: current_sym_value = 0; ! 2055: ! 2056: current_sym_code = N_PSYM; ! 2057: current_sym_addr = 0; ! 2058: ! 2059: FORCE_TEXT; ! 2060: if (DECL_NAME (parms)) ! 2061: { ! 2062: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms)); ! 2063: ! 2064: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, ! 2065: IDENTIFIER_POINTER (DECL_NAME (parms)), ! 2066: DBX_MEMPARM_STABS_LETTER); ! 2067: } ! 2068: else ! 2069: { ! 2070: current_sym_nchars = 8; ! 2071: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, ! 2072: DBX_MEMPARM_STABS_LETTER); ! 2073: } ! 2074: ! 2075: if (GET_CODE (DECL_RTL (parms)) == REG ! 2076: && REGNO (DECL_RTL (parms)) >= 0 ! 2077: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) ! 2078: dbxout_type (DECL_ARG_TYPE (parms), 0, 0); ! 2079: else ! 2080: { ! 2081: int original_value = current_sym_value; ! 2082: ! 2083: /* This is the case where the parm is passed as an int or double ! 2084: and it is converted to a char, short or float and stored back ! 2085: in the parmlist. In this case, describe the parm ! 2086: with the variable's declared type, and adjust the address ! 2087: if the least significant bytes (which we are using) are not ! 2088: the first ones. */ ! 2089: #if BYTES_BIG_ENDIAN ! 2090: if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) ! 2091: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) ! 2092: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); ! 2093: #endif ! 2094: ! 2095: if (GET_CODE (DECL_RTL (parms)) == MEM ! 2096: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS ! 2097: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT ! 2098: && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value) ! 2099: dbxout_type (TREE_TYPE (parms), 0, 0); ! 2100: else ! 2101: { ! 2102: current_sym_value = original_value; ! 2103: dbxout_type (DECL_ARG_TYPE (parms), 0, 0); ! 2104: } ! 2105: } ! 2106: current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr); ! 2107: dbxout_finish_symbol (parms); ! 2108: } ! 2109: else if (GET_CODE (DECL_RTL (parms)) == REG) ! 2110: { ! 2111: rtx best_rtl; ! 2112: char regparm_letter; ! 2113: tree parm_type; ! 2114: /* Parm passed in registers and lives in registers or nowhere. */ ! 2115: ! 2116: current_sym_code = DBX_REGPARM_STABS_CODE; ! 2117: regparm_letter = DBX_REGPARM_STABS_LETTER; ! 2118: current_sym_addr = 0; ! 2119: ! 2120: /* If parm lives in a register, use that register; ! 2121: pretend the parm was passed there. It would be more consistent ! 2122: to describe the register where the parm was passed, ! 2123: but in practice that register usually holds something else. ! 2124: ! 2125: If we use DECL_RTL, then we must use the declared type of ! 2126: the variable, not the type that it arrived in. */ ! 2127: if (REGNO (DECL_RTL (parms)) >= 0 ! 2128: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) ! 2129: { ! 2130: best_rtl = DECL_RTL (parms); ! 2131: parm_type = TREE_TYPE (parms); ! 2132: } ! 2133: /* If the parm lives nowhere, ! 2134: use the register where it was passed. */ ! 2135: else ! 2136: { ! 2137: best_rtl = DECL_INCOMING_RTL (parms); ! 2138: parm_type = DECL_ARG_TYPE (parms); ! 2139: } ! 2140: current_sym_value = DBX_REGISTER_NUMBER (REGNO (best_rtl)); ! 2141: ! 2142: FORCE_TEXT; ! 2143: if (DECL_NAME (parms)) ! 2144: { ! 2145: current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms)); ! 2146: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, ! 2147: IDENTIFIER_POINTER (DECL_NAME (parms)), ! 2148: regparm_letter); ! 2149: } ! 2150: else ! 2151: { ! 2152: current_sym_nchars = 8; ! 2153: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, ! 2154: regparm_letter); ! 2155: } ! 2156: ! 2157: dbxout_type (parm_type, 0, 0); ! 2158: dbxout_finish_symbol (parms); ! 2159: } ! 2160: else if (GET_CODE (DECL_RTL (parms)) == MEM ! 2161: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG ! 2162: && REGNO (XEXP (DECL_RTL (parms), 0)) != HARD_FRAME_POINTER_REGNUM ! 2163: && REGNO (XEXP (DECL_RTL (parms), 0)) != STACK_POINTER_REGNUM ! 2164: #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM ! 2165: && REGNO (XEXP (DECL_RTL (parms), 0)) != ARG_POINTER_REGNUM ! 2166: #endif ! 2167: ) ! 2168: { ! 2169: /* Parm was passed via invisible reference. ! 2170: That is, its address was passed in a register. ! 2171: Output it as if it lived in that register. ! 2172: The debugger will know from the type ! 2173: that it was actually passed by invisible reference. */ ! 2174: ! 2175: char regparm_letter; ! 2176: /* Parm passed in registers and lives in registers or nowhere. */ ! 2177: ! 2178: current_sym_code = DBX_REGPARM_STABS_CODE; ! 2179: regparm_letter = DBX_REGPARM_STABS_LETTER; ! 2180: ! 2181: /* DECL_RTL looks like (MEM (REG...). Get the register number. */ ! 2182: current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0)); ! 2183: current_sym_addr = 0; ! 2184: ! 2185: FORCE_TEXT; ! 2186: if (DECL_NAME (parms)) ! 2187: { ! 2188: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); ! 2189: ! 2190: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, ! 2191: IDENTIFIER_POINTER (DECL_NAME (parms)), ! 2192: DBX_REGPARM_STABS_LETTER); ! 2193: } ! 2194: else ! 2195: { ! 2196: current_sym_nchars = 8; ! 2197: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, ! 2198: DBX_REGPARM_STABS_LETTER); ! 2199: } ! 2200: ! 2201: dbxout_type (TREE_TYPE (parms), 0, 0); ! 2202: dbxout_finish_symbol (parms); ! 2203: } ! 2204: else if (GET_CODE (DECL_RTL (parms)) == MEM ! 2205: && XEXP (DECL_RTL (parms), 0) != const0_rtx ! 2206: /* ??? A constant address for a parm can happen ! 2207: when the reg it lives in is equiv to a constant in memory. ! 2208: Should make this not happen, after 2.4. */ ! 2209: && ! CONSTANT_P (XEXP (DECL_RTL (parms), 0))) ! 2210: { ! 2211: /* Parm was passed in registers but lives on the stack. */ ! 2212: ! 2213: current_sym_code = N_PSYM; ! 2214: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))), ! 2215: in which case we want the value of that CONST_INT, ! 2216: or (MEM (REG ...)) or (MEM (MEM ...)), ! 2217: in which case we use a value of zero. */ ! 2218: if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG ! 2219: || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM) ! 2220: current_sym_value = 0; ! 2221: else ! 2222: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)); ! 2223: current_sym_addr = 0; ! 2224: ! 2225: FORCE_TEXT; ! 2226: if (DECL_NAME (parms)) ! 2227: { ! 2228: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); ! 2229: ! 2230: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, ! 2231: IDENTIFIER_POINTER (DECL_NAME (parms)), ! 2232: DBX_MEMPARM_STABS_LETTER); ! 2233: } ! 2234: else ! 2235: { ! 2236: current_sym_nchars = 8; ! 2237: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, ! 2238: DBX_MEMPARM_STABS_LETTER); ! 2239: } ! 2240: ! 2241: current_sym_value ! 2242: = DEBUGGER_ARG_OFFSET (current_sym_value, ! 2243: XEXP (DECL_RTL (parms), 0)); ! 2244: dbxout_type (TREE_TYPE (parms), 0, 0); ! 2245: dbxout_finish_symbol (parms); ! 2246: } ! 2247: } ! 2248: } ! 2249: ! 2250: /* Output definitions for the places where parms live during the function, ! 2251: when different from where they were passed, when the parms were passed ! 2252: in memory. ! 2253: ! 2254: It is not useful to do this for parms passed in registers ! 2255: that live during the function in different registers, because it is ! 2256: impossible to look in the passed register for the passed value, ! 2257: so we use the within-the-function register to begin with. ! 2258: ! 2259: PARMS is a chain of PARM_DECL nodes. */ ! 2260: ! 2261: void ! 2262: dbxout_reg_parms (parms) ! 2263: tree parms; ! 2264: { ! 2265: for (; parms; parms = TREE_CHAIN (parms)) ! 2266: if (DECL_NAME (parms)) ! 2267: { ! 2268: dbxout_prepare_symbol (parms); ! 2269: ! 2270: /* Report parms that live in registers during the function ! 2271: but were passed in memory. */ ! 2272: if (GET_CODE (DECL_RTL (parms)) == REG ! 2273: && REGNO (DECL_RTL (parms)) >= 0 ! 2274: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER ! 2275: && PARM_PASSED_IN_MEMORY (parms)) ! 2276: dbxout_symbol_location (parms, TREE_TYPE (parms), ! 2277: 0, DECL_RTL (parms)); ! 2278: else if (GET_CODE (DECL_RTL (parms)) == CONCAT ! 2279: && PARM_PASSED_IN_MEMORY (parms)) ! 2280: dbxout_symbol_location (parms, TREE_TYPE (parms), ! 2281: 0, DECL_RTL (parms)); ! 2282: /* Report parms that live in memory but not where they were passed. */ ! 2283: else if (GET_CODE (DECL_RTL (parms)) == MEM ! 2284: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS ! 2285: && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT ! 2286: && PARM_PASSED_IN_MEMORY (parms) ! 2287: && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms))) ! 2288: { ! 2289: #if 0 /* ??? It is not clear yet what should replace this. */ ! 2290: int offset = DECL_OFFSET (parms) / BITS_PER_UNIT; ! 2291: /* A parm declared char is really passed as an int, ! 2292: so it occupies the least significant bytes. ! 2293: On a big-endian machine those are not the low-numbered ones. */ ! 2294: #if BYTES_BIG_ENDIAN ! 2295: if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms)) ! 2296: offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms))) ! 2297: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms)))); ! 2298: #endif ! 2299: if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...} ! 2300: #endif ! 2301: dbxout_symbol_location (parms, TREE_TYPE (parms), ! 2302: 0, DECL_RTL (parms)); ! 2303: } ! 2304: #if 0 ! 2305: else if (GET_CODE (DECL_RTL (parms)) == MEM ! 2306: && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG) ! 2307: { ! 2308: /* Parm was passed via invisible reference. ! 2309: That is, its address was passed in a register. ! 2310: Output it as if it lived in that register. ! 2311: The debugger will know from the type ! 2312: that it was actually passed by invisible reference. */ ! 2313: ! 2314: current_sym_code = N_RSYM; ! 2315: ! 2316: /* DECL_RTL looks like (MEM (REG...). Get the register number. */ ! 2317: current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0)); ! 2318: current_sym_addr = 0; ! 2319: ! 2320: FORCE_TEXT; ! 2321: if (DECL_NAME (parms)) ! 2322: { ! 2323: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms))); ! 2324: ! 2325: fprintf (asmfile, "%s \"%s:r", ASM_STABS_OP, ! 2326: IDENTIFIER_POINTER (DECL_NAME (parms))); ! 2327: } ! 2328: else ! 2329: { ! 2330: current_sym_nchars = 8; ! 2331: fprintf (asmfile, "%s \"(anon):r", ASM_STABS_OP); ! 2332: } ! 2333: ! 2334: dbxout_type (TREE_TYPE (parms), 0, 0); ! 2335: dbxout_finish_symbol (parms); ! 2336: } ! 2337: #endif ! 2338: } ! 2339: } ! 2340: ! 2341: /* Given a chain of ..._TYPE nodes (as come in a parameter list), ! 2342: output definitions of those names, in raw form */ ! 2343: ! 2344: void ! 2345: dbxout_args (args) ! 2346: tree args; ! 2347: { ! 2348: while (args) ! 2349: { ! 2350: putc (',', asmfile); ! 2351: dbxout_type (TREE_VALUE (args), 0, 0); ! 2352: CHARS (1); ! 2353: args = TREE_CHAIN (args); ! 2354: } ! 2355: } ! 2356: ! 2357: /* Given a chain of ..._TYPE nodes, ! 2358: find those which have typedef names and output those names. ! 2359: This is to ensure those types get output. */ ! 2360: ! 2361: void ! 2362: dbxout_types (types) ! 2363: register tree types; ! 2364: { ! 2365: while (types) ! 2366: { ! 2367: if (TYPE_NAME (types) ! 2368: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL ! 2369: && ! TREE_ASM_WRITTEN (TYPE_NAME (types))) ! 2370: dbxout_symbol (TYPE_NAME (types), 1); ! 2371: types = TREE_CHAIN (types); ! 2372: } ! 2373: } ! 2374: ! 2375: /* Output everything about a symbol block (a BLOCK node ! 2376: that represents a scope level), ! 2377: including recursive output of contained blocks. ! 2378: ! 2379: BLOCK is the BLOCK node. ! 2380: DEPTH is its depth within containing symbol blocks. ! 2381: ARGS is usually zero; but for the outermost block of the ! 2382: body of a function, it is a chain of PARM_DECLs for the function parameters. ! 2383: We output definitions of all the register parms ! 2384: as if they were local variables of that block. ! 2385: ! 2386: If -g1 was used, we count blocks just the same, but output nothing ! 2387: except for the outermost block. ! 2388: ! 2389: Actually, BLOCK may be several blocks chained together. ! 2390: We handle them all in sequence. */ ! 2391: ! 2392: static void ! 2393: dbxout_block (block, depth, args) ! 2394: register tree block; ! 2395: int depth; ! 2396: tree args; ! 2397: { ! 2398: int blocknum; ! 2399: ! 2400: while (block) ! 2401: { ! 2402: /* Ignore blocks never expanded or otherwise marked as real. */ ! 2403: if (TREE_USED (block)) ! 2404: { ! 2405: #ifndef DBX_LBRAC_FIRST ! 2406: /* In dbx format, the syms of a block come before the N_LBRAC. */ ! 2407: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) ! 2408: dbxout_syms (BLOCK_VARS (block)); ! 2409: if (args) ! 2410: dbxout_reg_parms (args); ! 2411: #endif ! 2412: ! 2413: /* Now output an N_LBRAC symbol to represent the beginning of ! 2414: the block. Use the block's tree-walk order to generate ! 2415: the assembler symbols LBBn and LBEn ! 2416: that final will define around the code in this block. */ ! 2417: if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE) ! 2418: { ! 2419: char buf[20]; ! 2420: blocknum = next_block_number++; ! 2421: ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum); ! 2422: ! 2423: if (BLOCK_HANDLER_BLOCK (block)) ! 2424: { ! 2425: /* A catch block. Must precede N_LBRAC. */ ! 2426: tree decl = BLOCK_VARS (block); ! 2427: while (decl) ! 2428: { ! 2429: #ifdef DBX_OUTPUT_CATCH ! 2430: DBX_OUTPUT_CATCH (asmfile, decl, buf); ! 2431: #else ! 2432: fprintf (asmfile, "%s \"%s:C1\",%d,0,0,", ASM_STABS_OP, ! 2433: IDENTIFIER_POINTER (DECL_NAME (decl)), N_CATCH); ! 2434: assemble_name (asmfile, buf); ! 2435: fprintf (asmfile, "\n"); ! 2436: #endif ! 2437: decl = TREE_CHAIN (decl); ! 2438: } ! 2439: } ! 2440: ! 2441: #ifdef DBX_OUTPUT_LBRAC ! 2442: DBX_OUTPUT_LBRAC (asmfile, buf); ! 2443: #else ! 2444: fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC); ! 2445: assemble_name (asmfile, buf); ! 2446: #if DBX_BLOCKS_FUNCTION_RELATIVE ! 2447: fputc ('-', asmfile); ! 2448: assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); ! 2449: #endif ! 2450: fprintf (asmfile, "\n"); ! 2451: #endif ! 2452: } ! 2453: else if (depth > 0) ! 2454: /* Count blocks the same way regardless of debug_info_level. */ ! 2455: next_block_number++; ! 2456: ! 2457: #ifdef DBX_LBRAC_FIRST ! 2458: /* On some weird machines, the syms of a block ! 2459: come after the N_LBRAC. */ ! 2460: if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0) ! 2461: dbxout_syms (BLOCK_VARS (block)); ! 2462: if (args) ! 2463: dbxout_reg_parms (args); ! 2464: #endif ! 2465: ! 2466: /* Output the subblocks. */ ! 2467: dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); ! 2468: ! 2469: /* Refer to the marker for the end of the block. */ ! 2470: if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE) ! 2471: { ! 2472: char buf[20]; ! 2473: ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum); ! 2474: #ifdef DBX_OUTPUT_RBRAC ! 2475: DBX_OUTPUT_RBRAC (asmfile, buf); ! 2476: #else ! 2477: fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC); ! 2478: assemble_name (asmfile, buf); ! 2479: #if DBX_BLOCKS_FUNCTION_RELATIVE ! 2480: fputc ('-', asmfile); ! 2481: assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); ! 2482: #endif ! 2483: fprintf (asmfile, "\n"); ! 2484: #endif ! 2485: } ! 2486: } ! 2487: block = BLOCK_CHAIN (block); ! 2488: } ! 2489: } ! 2490: ! 2491: /* Output the information about a function and its arguments and result. ! 2492: Usually this follows the function's code, ! 2493: but on some systems, it comes before. */ ! 2494: ! 2495: static void ! 2496: dbxout_really_begin_function (decl) ! 2497: tree decl; ! 2498: { ! 2499: dbxout_symbol (decl, 0); ! 2500: dbxout_parms (DECL_ARGUMENTS (decl)); ! 2501: if (DECL_NAME (DECL_RESULT (decl)) != 0) ! 2502: dbxout_symbol (DECL_RESULT (decl), 1); ! 2503: } ! 2504: ! 2505: /* Called at beginning of output of function definition. */ ! 2506: ! 2507: void ! 2508: dbxout_begin_function (decl) ! 2509: tree decl; ! 2510: { ! 2511: #ifdef DBX_FUNCTION_FIRST ! 2512: dbxout_really_begin_function (decl); ! 2513: #endif ! 2514: } ! 2515: ! 2516: /* Output dbx data for a function definition. ! 2517: This includes a definition of the function name itself (a symbol), ! 2518: definitions of the parameters (locating them in the parameter list) ! 2519: and then output the block that makes up the function's body ! 2520: (including all the auto variables of the function). */ ! 2521: ! 2522: void ! 2523: dbxout_function (decl) ! 2524: tree decl; ! 2525: { ! 2526: #ifndef DBX_FUNCTION_FIRST ! 2527: dbxout_really_begin_function (decl); ! 2528: #endif ! 2529: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl)); ! 2530: #ifdef DBX_OUTPUT_FUNCTION_END ! 2531: DBX_OUTPUT_FUNCTION_END (asmfile, decl); ! 2532: #endif ! 2533: } ! 2534: #endif /* DBX_DEBUGGING_INFO */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.