Annotation of gcc/dbxout.c, revision 1.1

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