|
|
1.1 root 1: /* Output dbx-format symbol table information from GNU compiler. 1.1.1.6 ! root 2: Copyright (C) 1987, 1988, 1992, 1993 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.2 root 135: char *getpwd (); 1.1 root 136: 137: /* Typical USG systems don't have stab.h, and they also have 138: no use for DBX-format debugging info. */ 139: 1.1.1.2 root 140: #if defined (DBX_DEBUGGING_INFO) || defined (XCOFF_DEBUGGING_INFO) 1.1 root 141: 142: #ifdef DEBUG_SYMS_TEXT 143: #define FORCE_TEXT text_section (); 144: #else 145: #define FORCE_TEXT 146: #endif 147: 1.1.1.2 root 148: #if defined (USG) || defined (NO_STAB_H) 1.1 root 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 (); 1.1.1.6 ! root 270: static void dbxout_symbol_name (); ! 271: static void dbxout_symbol_location (); 1.1 root 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: 1.1.1.2 root 301: /* Copy the filename (possibly preceded by the current working 1.1 root 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. */ 1.1.1.2 root 405: #ifndef DBX_WORKING_DIRECTORY /* Only some versions of DBX want this, 406: but GDB always does. */ 1.1.1.4 root 407: if (use_gnu_debug_info_extensions) 1.1.1.2 root 408: #endif 409: { 1.1.1.6 ! root 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) 1.1.1.2 root 417: { 1.1 root 418: #ifdef DBX_OUTPUT_MAIN_SOURCE_DIRECTORY 1.1.1.2 root 419: DBX_OUTPUT_MAIN_SOURCE_DIRECTORY (asmfile, cwd); 1.1 root 420: #else /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ 1.1.1.6 ! root 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]); 1.1 root 424: #endif /* no DBX_OUTPUT_MAIN_SOURCE_DIRECTORY */ 1.1.1.2 root 425: } 426: } 1.1 root 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. */ 1.1.1.6 ! root 436: fprintf (asmfile, "%s ", ASM_STABS_OP); ! 437: output_quoted_string (asmfile, input_file_name); ! 438: fprintf (asmfile, ",%d,0,0,%s\n", 1.1 root 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: 1.1.1.4 root 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: 1.1 root 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); 1.1.1.6 ! root 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]); 1.1 root 515: #endif 516: lastfile = filename; 517: } 518: } 519: 1.1.1.4 root 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: 1.1 root 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 1.1.1.4 root 566: dbxout_finish_symbol (NULL_TREE); 1.1 root 567: fprintf (asmfile, "%s \"", ASM_STABS_OP); 568: current_sym_nchars = 0; 569: } 570: 1.1.1.3 root 571: /* Subroutine of `dbxout_type'. Output the type fields of TYPE. 1.1 root 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; 1.1.1.4 root 580: /* Output the name, type, position (in bits), size (in bits) of each 581: field. */ 1.1 root 582: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem)) 583: { 1.1.1.4 root 584: /* For nameless subunions and subrecords, treat their fields as ours. */ 1.1 root 585: if (DECL_NAME (tem) == NULL_TREE 1.1.1.4 root 586: && (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE 1.1.1.5 root 587: || TREE_CODE (TREE_TYPE (tem)) == QUAL_UNION_TYPE 1.1.1.4 root 588: || TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE)) 1.1 root 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; 1.1.1.6 ! root 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; 1.1 root 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: 1.1.1.4 root 606: if (use_gnu_debug_info_extensions 1.1 root 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); 1.1.1.3 root 615: dbxout_type (DECL_FCONTEXT (tem), 0, 0); 1.1 root 616: fprintf (asmfile, ":"); 1.1.1.3 root 617: dbxout_type (TREE_TYPE (tem), 0, 0); 1.1 root 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: 1.1.1.4 root 626: if (use_gnu_debug_info_extensions 1.1 root 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) 1.1.1.3 root 641: : TREE_TYPE (tem), 0, 0); 1.1 root 642: 643: if (TREE_CODE (tem) == VAR_DECL) 644: { 1.1.1.4 root 645: if (TREE_STATIC (tem) && use_gnu_debug_info_extensions) 1.1 root 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: 1.1.1.3 root 669: /* Subroutine of `dbxout_type_methods'. Output debug info about the 1.1 root 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))); 1.1.1.3 root 709: dbxout_type (DECL_CONTEXT (decl), 0, 0); 1.1 root 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); 1.1.1.2 root 724: tree type_encoding; 1.1 root 725: register tree fndecl; 726: register tree last; 1.1.1.4 root 727: char formatted_type_identifier_length[16]; 1.1 root 728: register int type_identifier_length; 729: 730: if (methods == NULL_TREE) 731: return; 732: 1.1.1.3 root 733: type_encoding = DECL_NAME (TYPE_NAME (type)); 1.1.1.2 root 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: { 1.1.1.3 root 739: char *ptr = IDENTIFIER_POINTER (type_encoding); 1.1.1.4 root 740: /* This should use index. (mrs) */ 1.1.1.2 root 741: while (*ptr && *ptr != '<') ptr++; 742: if (*ptr != 0) 743: { 744: static int warned; 745: if (!warned) 746: { 747: warned = 1; 1.1.1.5 root 748: #ifdef HAVE_TEMPLATES 749: if (warn_template_debugging) 750: warning ("dbx info for template class methods not yet supported"); 751: #endif 1.1.1.2 root 752: } 753: return; 754: } 755: } 756: 1.1.1.3 root 757: type_identifier_length = IDENTIFIER_LENGTH (type_encoding); 1.1.1.2 root 758: 1.1.1.4 root 759: sprintf(formatted_type_identifier_length, "%d", type_identifier_length); 760: 1.1 root 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); 1.1.1.4 root 765: else 766: fndecl = TREE_VEC_ELT (methods, 1); 1.1 root 767: 768: while (fndecl) 769: { 770: tree name = DECL_NAME (fndecl); 1.1.1.3 root 771: int need_prefix = 1; 1.1 root 772: 1.1.1.3 root 773: /* Group together all the methods for the same operation. 774: These differ in the types of the arguments. */ 1.1 root 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: { 1.1.1.3 root 782: /* This is the "mangled" name of the method. 783: It encodes the argument types. */ 1.1 root 784: char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)); 1.1.1.3 root 785: int destructor = 0; 1.1 root 786: 787: CONTIN; 788: 789: last = fndecl; 1.1.1.3 root 790: 791: if (DECL_IGNORED_P (fndecl)) 792: continue; 793: 1.1 root 794: if (flag_minimal_debug) 795: { 1.1.1.3 root 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; 1.1.1.4 root 805: char *length_ptr = formatted_type_identifier_length; 1.1.1.3 root 806: /* Get past const and volatile qualifiers. */ 807: while (*method_name == 'C' || *method_name == 'V') 808: method_name++; 1.1.1.4 root 809: /* Skip digits for length of type_encoding. */ 810: while (*method_name == *length_ptr && *length_ptr) 811: length_ptr++, method_name++; 1.1.1.3 root 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; 1.1.1.4 root 823: char *length_ptr = formatted_type_identifier_length; 1.1.1.3 root 824: while (*ctor_name == 'C' || *ctor_name == 'V') 825: ctor_name++; 1.1.1.4 root 826: /* Skip digits for length of type_encoding. */ 827: while (*ctor_name == *length_ptr && *length_ptr) 828: length_ptr++, ctor_name++; 1.1.1.3 root 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: } 1.1 root 845: } 1.1.1.3 root 846: 847: dbxout_type (TREE_TYPE (fndecl), 0, destructor); 848: 1.1 root 849: dbxout_type_method_1 (fndecl, debug_name); 850: } 1.1.1.3 root 851: if (!need_prefix) 852: { 853: putc (';', asmfile); 854: CHARS (1); 855: } 1.1 root 856: } 857: } 1.1.1.5 root 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: } 1.1 root 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 1.1.1.3 root 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. */ 1.1 root 900: 901: static void 1.1.1.3 root 902: dbxout_type (type, full, show_arg_types) 1.1 root 903: tree type; 904: int full; 1.1.1.3 root 905: int show_arg_types; 1.1 root 906: { 907: register tree tem; 1.1.1.4 root 908: static int anonymous_type_number = 0; 1.1 root 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: 1.1.1.2 root 943: #ifdef DBX_TYPE_DEFINED 944: if (DBX_TYPE_DEFINED (type)) 945: return; 946: #endif 947: 1.1 root 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: 1.1.1.3 root 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) 1.1 root 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 1.1.1.5 root 974: || TREE_CODE (type) == QUAL_UNION_TYPE 1.1 root 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)); 1.1.1.6 ! root 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)) 1.1 root 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: } 1.1.1.5 root 1028: else /* Output other integer types as subranges of `int'. */ 1029: dbxout_range_type (type); 1.1 root 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), 1.1.1.5 root 1037: int_size_in_bytes (type)); 1.1 root 1038: CHARS (16); 1039: break; 1040: 1.1.1.4 root 1041: case CHAR_TYPE: 1.1.1.6 ! root 1042: if (use_gnu_debug_info_extensions) ! 1043: fprintf (asmfile, "@s%d;-20;", ! 1044: BITS_PER_UNIT * int_size_in_bytes (type)); ! 1045: else 1.1.1.4 root 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: 1.1.1.6 ! root 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,;"); 1.1.1.4 root 1059: CHARS (17); 1060: break; 1061: 1062: case FILE_TYPE: 1063: putc ('d', asmfile); 1064: CHARS (1); 1.1.1.5 root 1065: dbxout_type (TREE_TYPE (type), 0, 0); 1.1.1.4 root 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), 1.1.1.5 root 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: } 1.1.1.4 root 1098: break; 1099: 1100: case SET_TYPE: 1101: putc ('S', asmfile); 1102: CHARS (1); 1.1.1.6 ! root 1103: dbxout_type (TYPE_DOMAIN (type), 0, 0); 1.1.1.4 root 1104: break; 1105: 1.1 root 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. 1.1.1.5 root 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: } 1.1 root 1120: CHARS (17); 1.1.1.3 root 1121: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1122: break; 1123: 1124: case RECORD_TYPE: 1125: case UNION_TYPE: 1.1.1.5 root 1126: case QUAL_UNION_TYPE: 1.1 root 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. */ 1.1.1.2 root 1134: if ((TYPE_NAME (type) != 0 1.1.1.5 root 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. */ 1.1.1.2 root 1140: && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL 1141: && DECL_IGNORED_P (TYPE_NAME (type))) 1142: #endif 1143: && !full) 1.1.1.3 root 1144: || TYPE_SIZE (type) == 0 1145: /* No way in DBX fmt to describe a variable size. */ 1146: || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) 1.1 root 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); 1.1.1.2 root 1157: #if 0 /* This assertion is legitimately false in C++. */ 1.1 root 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 1.1.1.4 root 1164: if (TYPE_NAME (type) != 0) 1165: dbxout_type_name (type); 1166: else 1167: fprintf (asmfile, "$$%d", anonymous_type_number++); 1.1 root 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", 1.1.1.5 root 1175: int_size_in_bytes (type)); 1.1 root 1176: 1.1.1.4 root 1177: if (use_gnu_debug_info_extensions) 1.1 root 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); 1.1.1.4 root 1189: if (use_gnu_debug_info_extensions) 1.1 root 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); 1.1.1.3 root 1201: dbxout_type (BINFO_TYPE (child), 0, 0); 1.1 root 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); 1.1.1.3 root 1210: dbxout_type (BINFO_TYPE (child), full, 0); 1.1 root 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); 1.1.1.4 root 1223: if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE) 1.1 root 1224: { 1225: have_used_extensions = 1; 1226: dbxout_type_methods (type); 1227: } 1228: putc (';', asmfile); 1229: 1.1.1.4 root 1230: if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE 1.1 root 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); 1.1.1.3 root 1246: dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0); 1.1 root 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: } 1.1.1.3 root 1266: #ifdef DBX_OUTPUT_ENUM 1267: DBX_OUTPUT_ENUM (asmfile, type); 1268: #else 1.1 root 1269: putc ('e', asmfile); 1270: CHARS (1); 1271: for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem)) 1272: { 1.1.1.6 ! root 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))); 1.1 root 1285: if (TREE_CHAIN (tem) != 0) 1286: CONTIN; 1287: } 1288: putc (';', asmfile); 1289: CHARS (1); 1.1.1.3 root 1290: #endif 1.1 root 1291: break; 1292: 1293: case POINTER_TYPE: 1294: putc ('*', asmfile); 1295: CHARS (1); 1.1.1.3 root 1296: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1297: break; 1298: 1299: case METHOD_TYPE: 1.1.1.4 root 1300: if (use_gnu_debug_info_extensions) 1.1 root 1301: { 1302: have_used_extensions = 1; 1303: putc ('#', asmfile); 1304: CHARS (1); 1.1.1.3 root 1305: if (flag_minimal_debug && !show_arg_types) 1.1 root 1306: { 1.1.1.3 root 1307: /* Normally, just output the return type. 1308: The argument types are encoded in the method name. */ 1.1 root 1309: putc ('#', asmfile); 1.1.1.3 root 1310: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1311: putc (';', asmfile); 1312: CHARS (1); 1313: } 1314: else 1315: { 1.1.1.4 root 1316: /* When outputting destructors, we need to write 1.1.1.3 root 1317: the argument types out longhand. */ 1318: dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0); 1.1 root 1319: putc (',', asmfile); 1320: CHARS (1); 1.1.1.3 root 1321: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 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. */ 1.1.1.3 root 1330: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1331: } 1332: break; 1333: 1334: case OFFSET_TYPE: 1.1.1.4 root 1335: if (use_gnu_debug_info_extensions) 1.1 root 1336: { 1337: have_used_extensions = 1; 1338: putc ('@', asmfile); 1339: CHARS (1); 1.1.1.3 root 1340: dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0); 1.1 root 1341: putc (',', asmfile); 1342: CHARS (1); 1.1.1.3 root 1343: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1344: } 1345: else 1346: { 1347: /* Should print as an int, because it is really 1348: just an offset. */ 1.1.1.3 root 1349: dbxout_type (integer_type_node, 0, 0); 1.1 root 1350: } 1351: break; 1352: 1353: case REFERENCE_TYPE: 1.1.1.4 root 1354: if (use_gnu_debug_info_extensions) 1.1 root 1355: have_used_extensions = 1; 1.1.1.4 root 1356: putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile); 1.1 root 1357: CHARS (1); 1.1.1.3 root 1358: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1359: break; 1360: 1361: case FUNCTION_TYPE: 1362: putc ('f', asmfile); 1363: CHARS (1); 1.1.1.3 root 1364: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 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: { 1.1.1.4 root 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)); 1.1.1.6 ! root 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); 1.1 root 1395: 1396: fprintf (asmfile, "0"); 1397: 1398: if (excess == 3) 1399: { 1.1.1.4 root 1400: print_octal (high, HOST_BITS_PER_WIDE_INT / 3); 1401: print_octal (low, HOST_BITS_PER_WIDE_INT / 3); 1.1 root 1402: } 1403: else 1404: { 1.1.1.4 root 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 1.1.1.6 ! root 1410: = low & (((unsigned HOST_WIDE_INT) 1 ! 1411: << (HOST_BITS_PER_WIDE_INT / 3 * 3)) ! 1412: - 1); ! 1413: 1.1 root 1414: fprintf (asmfile, "%o%01o", beg, middle); 1.1.1.4 root 1415: print_octal (end, HOST_BITS_PER_WIDE_INT / 3); 1.1 root 1416: } 1417: } 1418: 1419: static void 1420: print_octal (value, digits) 1.1.1.4 root 1421: unsigned HOST_WIDE_INT value; 1.1 root 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; 1.1.1.4 root 1499: if (DECL_EXTERNAL (decl)) 1.1 root 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)) 1.1.1.3 root 1518: dbxout_type (TREE_TYPE (type), 0, 0); 1.1 root 1519: else 1.1.1.3 root 1520: dbxout_type (void_type_node, 0, 0); 1.1 root 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: 1.1.1.3 root 1553: { 1554: int tag_needed = 1; 1.1.1.4 root 1555: int did_output = 0; 1.1 root 1556: 1.1.1.3 root 1557: if (DECL_NAME (decl)) 1558: { 1559: /* Nonzero means we must output a tag as well as a typedef. */ 1560: tag_needed = 0; 1.1 root 1561: 1.1.1.3 root 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. */ 1.1.1.4 root 1565: /* dbx requires the tag first and the typedef second. */ 1.1.1.3 root 1566: if ((TREE_CODE (type) == RECORD_TYPE 1.1.1.5 root 1567: || TREE_CODE (type) == UNION_TYPE 1568: || TREE_CODE (type) == QUAL_UNION_TYPE) 1.1.1.3 root 1569: && TYPE_NAME (type) == decl 1.1.1.4 root 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. */ 1.1.1.6 ! root 1574: && (!strcmp (lang_identify (), "cplusplus") ! 1575: /* The following line maybe unnecessary; ! 1576: in 2.6, try removing it. */ ! 1577: || DECL_SOURCE_LINE (decl) == 0)) 1.1.1.3 root 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); 1.1.1.4 root 1591: dbxout_finish_symbol (NULL_TREE); 1.1.1.3 root 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 1.1.1.5 root 1600: || TREE_CODE (type) == UNION_TYPE 1601: || TREE_CODE (type) == QUAL_UNION_TYPE) 1.1.1.3 root 1602: && TYPE_NAME (type) == decl) 1603: { 1.1.1.4 root 1604: if (use_gnu_debug_info_extensions && have_used_extensions) 1.1.1.3 root 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); 1.1.1.4 root 1620: did_output = 1; 1.1.1.3 root 1621: } 1622: 1.1.1.5 root 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 1.1.1.3 root 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); 1.1.1.4 root 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); 1.1.1.3 root 1665: } 1666: 1667: /* Prevent duplicate output of a typedef. */ 1668: TREE_ASM_WRITTEN (decl) = 1; 1669: break; 1670: } 1.1 root 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. */ 1.1.1.4 root 1684: if (DECL_EXTERNAL (decl)) 1.1 root 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: { 1.1.1.4 root 1702: HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl)); 1.1 root 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: 1.1.1.5 root 1720: DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX); 1.1 root 1721: #ifdef LEAF_REG_REMAP 1722: if (leaf_function) 1723: leaf_renumber_regs_insn (DECL_RTL (decl)); 1724: #endif 1725: 1.1.1.6 ! root 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; 1.1 root 1743: 1.1.1.6 ! root 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) 1.1 root 1766: { 1.1.1.6 ! root 1767: regno = REGNO (value); 1.1 root 1768: if (regno >= FIRST_PSEUDO_REGISTER) 1.1.1.4 root 1769: return; 1.1.1.6 ! root 1770: regno += offset; 1.1 root 1771: } 1.1.1.6 ! root 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)) 1.1 root 1792: { 1.1.1.6 ! root 1793: letter = 'G'; ! 1794: current_sym_code = N_GSYM; 1.1 root 1795: } 1.1.1.6 ! root 1796: else ! 1797: { ! 1798: current_sym_addr = XEXP (home, 0); 1.1 root 1799: 1.1.1.6 ! root 1800: letter = decl_function_context (decl) ? 'V' : 'S'; 1.1 root 1801: 1.1.1.6 ! root 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; 1.1 root 1808: else 1809: { 1.1.1.6 ! root 1810: /* Ultrix `as' seems to need this. */ 1.1 root 1811: #ifdef DBX_STATIC_STAB_DATA_SECTION 1.1.1.6 ! root 1812: data_section (); 1.1 root 1813: #endif 1.1.1.6 ! root 1814: current_sym_code = N_STSYM; 1.1 root 1815: } 1816: } 1.1.1.6 ! root 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) 1.1 root 1837: { 1838: letter = 'r'; 1839: current_sym_code = N_RSYM; 1.1.1.6 ! root 1840: current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (home, 0))); 1.1 root 1841: } 1.1.1.6 ! root 1842: else 1.1 root 1843: { 1844: current_sym_code = N_LSYM; 1.1.1.6 ! root 1845: /* RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))). 1.1 root 1846: We want the value of that CONST_INT. */ 1.1.1.6 ! root 1847: current_sym_value ! 1848: = DEBUGGER_AUTO_OFFSET (XEXP (XEXP (home, 0), 0)); 1.1.1.2 root 1849: } 1.1.1.6 ! root 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)); 1.1 root 1899: else 1.1.1.6 ! root 1900: dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0)); 1.1 root 1901: 1.1.1.6 ! root 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; 1.1.1.2 root 1922: 1923: #ifdef DBX_STATIC_BLOCK_START 1.1.1.6 ! root 1924: DBX_STATIC_BLOCK_START (asmfile, current_sym_code); 1.1.1.2 root 1925: #endif 1926: 1.1.1.6 ! root 1927: dbxout_symbol_name (decl, suffix, letter); ! 1928: dbxout_type (type, 0, 0); ! 1929: dbxout_finish_symbol (decl); 1.1.1.2 root 1930: 1931: #ifdef DBX_STATIC_BLOCK_END 1.1.1.6 ! root 1932: DBX_STATIC_BLOCK_END (asmfile, current_sym_code); 1.1.1.2 root 1933: #endif 1.1.1.6 ! root 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); 1.1 root 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: { 1.1.1.2 root 1979: #ifdef DBX_FINISH_SYMBOL 1980: DBX_FINISH_SYMBOL (sym); 1981: #else 1.1 root 1982: int line = 0; 1.1.1.5 root 1983: if (use_gnu_debug_info_extensions && sym != 0) 1.1 root 1984: line = DECL_SOURCE_LINE (sym); 1.1.1.2 root 1985: 1.1 root 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); 1.1.1.2 root 1992: #endif 1.1 root 1993: } 1994: 1995: /* Output definitions of all the decls in a chain. */ 1996: 1.1.1.2 root 1997: void 1.1 root 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: 1.1.1.2 root 2020: void 1.1 root 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) 1.1.1.4 root 2032: = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX); 2033: DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX); 1.1 root 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: 1.1.1.3 root 2064: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, 2065: IDENTIFIER_POINTER (DECL_NAME (parms)), 2066: DBX_MEMPARM_STABS_LETTER); 1.1 root 2067: } 2068: else 2069: { 2070: current_sym_nchars = 8; 1.1.1.3 root 2071: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, 2072: DBX_MEMPARM_STABS_LETTER); 1.1 root 2073: } 2074: 2075: if (GET_CODE (DECL_RTL (parms)) == REG 2076: && REGNO (DECL_RTL (parms)) >= 0 2077: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) 1.1.1.3 root 2078: dbxout_type (DECL_ARG_TYPE (parms), 0, 0); 1.1 root 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) 1.1.1.3 root 2099: dbxout_type (TREE_TYPE (parms), 0, 0); 1.1 root 2100: else 2101: { 2102: current_sym_value = original_value; 1.1.1.3 root 2103: dbxout_type (DECL_ARG_TYPE (parms), 0, 0); 1.1 root 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; 1.1.1.2 root 2112: char regparm_letter; 1.1.1.6 ! root 2113: tree parm_type; 1.1 root 2114: /* Parm passed in registers and lives in registers or nowhere. */ 2115: 1.1.1.2 root 2116: current_sym_code = DBX_REGPARM_STABS_CODE; 2117: regparm_letter = DBX_REGPARM_STABS_LETTER; 1.1 root 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, 1.1.1.6 ! root 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. */ 1.1 root 2127: if (REGNO (DECL_RTL (parms)) >= 0 2128: && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER) 1.1.1.6 ! root 2129: { ! 2130: best_rtl = DECL_RTL (parms); ! 2131: parm_type = TREE_TYPE (parms); ! 2132: } 1.1 root 2133: /* If the parm lives nowhere, 2134: use the register where it was passed. */ 2135: else 1.1.1.6 ! root 2136: { ! 2137: best_rtl = DECL_INCOMING_RTL (parms); ! 2138: parm_type = DECL_ARG_TYPE (parms); ! 2139: } 1.1 root 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)); 1.1.1.2 root 2146: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, 2147: IDENTIFIER_POINTER (DECL_NAME (parms)), 2148: regparm_letter); 1.1 root 2149: } 2150: else 2151: { 2152: current_sym_nchars = 8; 1.1.1.2 root 2153: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, 2154: regparm_letter); 1.1 root 2155: } 2156: 1.1.1.6 ! root 2157: dbxout_type (parm_type, 0, 0); 1.1.1.3 root 2158: dbxout_finish_symbol (parms); 2159: } 2160: else if (GET_CODE (DECL_RTL (parms)) == MEM 1.1.1.6 ! root 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: ) 1.1.1.3 root 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); 1.1 root 2202: dbxout_finish_symbol (parms); 2203: } 2204: else if (GET_CODE (DECL_RTL (parms)) == MEM 1.1.1.5 root 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))) 1.1 root 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: 1.1.1.3 root 2230: fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP, 2231: IDENTIFIER_POINTER (DECL_NAME (parms)), 2232: DBX_MEMPARM_STABS_LETTER); 1.1 root 2233: } 2234: else 2235: { 2236: current_sym_nchars = 8; 1.1.1.3 root 2237: fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP, 2238: DBX_MEMPARM_STABS_LETTER); 1.1 root 2239: } 2240: 2241: current_sym_value 2242: = DEBUGGER_ARG_OFFSET (current_sym_value, 2243: XEXP (DECL_RTL (parms), 0)); 1.1.1.3 root 2244: dbxout_type (TREE_TYPE (parms), 0, 0); 1.1 root 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: 1.1.1.2 root 2261: void 1.1 root 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)) 1.1.1.6 ! root 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)); 1.1 root 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 1.1.1.6 ! root 2301: dbxout_symbol_location (parms, TREE_TYPE (parms), ! 2302: 0, DECL_RTL (parms)); 1.1 root 2303: } 1.1.1.4 root 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 1.1 root 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); 1.1.1.3 root 2351: dbxout_type (TREE_VALUE (args), 0, 0); 1.1 root 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: 1.1.1.3 root 2441: #ifdef DBX_OUTPUT_LBRAC 2442: DBX_OUTPUT_LBRAC (asmfile, buf); 2443: #else 1.1 root 2444: fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC); 2445: assemble_name (asmfile, buf); 1.1.1.4 root 2446: #if DBX_BLOCKS_FUNCTION_RELATIVE 2447: fputc ('-', asmfile); 1.1.1.5 root 2448: assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); 1.1.1.4 root 2449: #endif 1.1 root 2450: fprintf (asmfile, "\n"); 1.1.1.3 root 2451: #endif 1.1 root 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. */ 1.1.1.4 root 2467: dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE); 1.1 root 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); 1.1.1.3 root 2474: #ifdef DBX_OUTPUT_RBRAC 2475: DBX_OUTPUT_RBRAC (asmfile, buf); 2476: #else 1.1 root 2477: fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC); 2478: assemble_name (asmfile, buf); 1.1.1.4 root 2479: #if DBX_BLOCKS_FUNCTION_RELATIVE 2480: fputc ('-', asmfile); 1.1.1.5 root 2481: assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0)); 1.1.1.4 root 2482: #endif 1.1 root 2483: fprintf (asmfile, "\n"); 1.1.1.3 root 2484: #endif 1.1 root 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.