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