Annotation of gcc/dbxout.c, revision 1.1.1.3

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.