Annotation of GNUtools/cc/dbxout.c, revision 1.1

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

unix.superglobalmegacorp.com

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