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

1.1     ! root        1: /* This file contains code written by Ron Guilmette ([email protected]) for
        !             2:    Network Computing Devices, August, September, October, November 1990.
        !             3: 
        !             4:    Output Dwarf format symbol table information from the GNU C compiler.
        !             5:    Copyright (C) 1992, 1993 Free Software Foundation, Inc.
        !             6: 
        !             7: This file is part of GNU CC.
        !             8: 
        !             9: GNU CC is free software; you can redistribute it and/or modify
        !            10: it under the terms of the GNU General Public License as published by
        !            11: the Free Software Foundation; either version 2, or (at your option)
        !            12: any later version.
        !            13: 
        !            14: GNU CC is distributed in the hope that it will be useful,
        !            15: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            17: GNU General Public License for more details.
        !            18: 
        !            19: You should have received a copy of the GNU General Public License
        !            20: along with GNU CC; see the file COPYING.  If not, write to
        !            21: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            22: 
        !            23: #include "config.h"
        !            24: 
        !            25: #ifdef DWARF_DEBUGGING_INFO
        !            26: #include <stdio.h>
        !            27: #include "dwarf.h"
        !            28: #include "tree.h"
        !            29: #include "flags.h"
        !            30: #include "rtl.h"
        !            31: #include "hard-reg-set.h"
        !            32: #include "insn-config.h"
        !            33: #include "reload.h"
        !            34: #include "output.h"
        !            35: #include "defaults.h"
        !            36: 
        !            37: #ifndef DWARF_VERSION
        !            38: #define DWARF_VERSION 1
        !            39: #endif
        !            40: 
        !            41: /* #define NDEBUG 1 */
        !            42: #include "assert.h"
        !            43: 
        !            44: #if defined(DWARF_TIMESTAMPS)
        !            45: #if defined(POSIX)
        !            46: #include <time.h>
        !            47: #else /* !defined(POSIX) */
        !            48: #include <sys/types.h>
        !            49: #if defined(__STDC__)
        !            50: extern time_t time (time_t *);
        !            51: #else /* !defined(__STDC__) */
        !            52: extern time_t time ();
        !            53: #endif /* !defined(__STDC__) */
        !            54: #endif /* !defined(POSIX) */
        !            55: #endif /* defined(DWARF_TIMESTAMPS) */
        !            56: 
        !            57: extern char *getpwd ();
        !            58: 
        !            59: extern char *index ();
        !            60: extern char *rindex ();
        !            61: 
        !            62: /* IMPORTANT NOTE: Please see the file README.DWARF for important details
        !            63:    regarding the GNU implementation of Dwarf.  */
        !            64: 
        !            65: /* NOTE: In the comments in this file, many references are made to
        !            66:    so called "Debugging Information Entries".  For the sake of brevity,
        !            67:    this term is abbreviated to `DIE' throughout the remainder of this
        !            68:    file.  */
        !            69: 
        !            70: /* Note that the implementation of C++ support herein is (as yet) unfinished.
        !            71:    If you want to try to complete it, more power to you.  */
        !            72: 
        !            73: #if defined(__GNUC__) && (NDEBUG == 1)
        !            74: #define inline static inline
        !            75: #else
        !            76: #define inline static
        !            77: #endif
        !            78: 
        !            79: /* How to start an assembler comment.  */
        !            80: #ifndef ASM_COMMENT_START
        !            81: #define ASM_COMMENT_START ";#"
        !            82: #endif
        !            83: 
        !            84: /* How to print out a register name.  */
        !            85: #ifndef PRINT_REG
        !            86: #define PRINT_REG(RTX, CODE, FILE) \
        !            87:   fprintf ((FILE), "%s", reg_names[REGNO (RTX)])
        !            88: #endif
        !            89: 
        !            90: /* Define a macro which returns non-zero for any tagged type which is
        !            91:    used (directly or indirectly) in the specification of either some
        !            92:    function's return type or some formal parameter of some function.
        !            93:    We use this macro when we are operating in "terse" mode to help us
        !            94:    know what tagged types have to be represented in Dwarf (even in
        !            95:    terse mode) and which ones don't.
        !            96: 
        !            97:    A flag bit with this meaning really should be a part of the normal
        !            98:    GCC ..._TYPE nodes, but at the moment, there is no such bit defined
        !            99:    for these nodes.  For now, we have to just fake it.  It it safe for
        !           100:    us to simply return zero for all complete tagged types (which will
        !           101:    get forced out anyway if they were used in the specification of some
        !           102:    formal or return type) and non-zero for all incomplete tagged types.
        !           103: */
        !           104: 
        !           105: #define TYPE_USED_FOR_FUNCTION(tagged_type) (TYPE_SIZE (tagged_type) == 0)
        !           106: 
        !           107: extern int flag_traditional;
        !           108: extern char *version_string;
        !           109: extern char *language_string;
        !           110: 
        !           111: /* Maximum size (in bytes) of an artificially generated label. */
        !           112: 
        !           113: #define MAX_ARTIFICIAL_LABEL_BYTES     30
        !           114: 
        !           115: /* Make sure we know the sizes of the various types dwarf can describe.
        !           116:    These are only defaults.  If the sizes are different for your target,
        !           117:    you should override these values by defining the appropriate symbols
        !           118:    in your tm.h file.  */
        !           119: 
        !           120: #ifndef CHAR_TYPE_SIZE
        !           121: #define CHAR_TYPE_SIZE BITS_PER_UNIT
        !           122: #endif
        !           123: 
        !           124: #ifndef SHORT_TYPE_SIZE
        !           125: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * 2)
        !           126: #endif
        !           127: 
        !           128: #ifndef INT_TYPE_SIZE
        !           129: #define INT_TYPE_SIZE BITS_PER_WORD
        !           130: #endif
        !           131: 
        !           132: #ifndef LONG_TYPE_SIZE
        !           133: #define LONG_TYPE_SIZE BITS_PER_WORD
        !           134: #endif
        !           135: 
        !           136: #ifndef LONG_LONG_TYPE_SIZE
        !           137: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
        !           138: #endif
        !           139: 
        !           140: #ifndef WCHAR_TYPE_SIZE
        !           141: #define WCHAR_TYPE_SIZE INT_TYPE_SIZE
        !           142: #endif
        !           143: 
        !           144: #ifndef WCHAR_UNSIGNED
        !           145: #define WCHAR_UNSIGNED 0
        !           146: #endif
        !           147: 
        !           148: #ifndef FLOAT_TYPE_SIZE
        !           149: #define FLOAT_TYPE_SIZE BITS_PER_WORD
        !           150: #endif
        !           151: 
        !           152: #ifndef DOUBLE_TYPE_SIZE
        !           153: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
        !           154: #endif
        !           155: 
        !           156: #ifndef LONG_DOUBLE_TYPE_SIZE
        !           157: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
        !           158: #endif
        !           159: 
        !           160: /* Structure to keep track of source filenames.  */
        !           161: 
        !           162: struct filename_entry {
        !           163:   unsigned     number;
        !           164:   char *       name;
        !           165: };
        !           166: 
        !           167: typedef struct filename_entry filename_entry;
        !           168: 
        !           169: /* Pointer to an array of elements, each one having the structure above. */
        !           170: 
        !           171: static filename_entry *filename_table;
        !           172: 
        !           173: /* Total number of entries in the table (i.e. array) pointed to by
        !           174:    `filename_table'.  This is the *total* and includes both used and
        !           175:    unused slots.  */
        !           176: 
        !           177: static unsigned ft_entries_allocated;
        !           178: 
        !           179: /* Number of entries in the filename_table which are actually in use.  */
        !           180: 
        !           181: static unsigned ft_entries;
        !           182: 
        !           183: /* Size (in elements) of increments by which we may expand the filename
        !           184:    table.  Actually, a single hunk of space of this size should be enough
        !           185:    for most typical programs.   */
        !           186: 
        !           187: #define FT_ENTRIES_INCREMENT 64
        !           188: 
        !           189: /* Local pointer to the name of the main input file.  Initialized in
        !           190:    dwarfout_init.  */
        !           191: 
        !           192: static char *primary_filename;
        !           193: 
        !           194: /* Pointer to the most recent filename for which we produced some line info.  */
        !           195: 
        !           196: static char *last_filename;
        !           197: 
        !           198: /* For Dwarf output, we must assign lexical-blocks id numbers
        !           199:    in the order in which their beginnings are encountered.
        !           200:    We output Dwarf debugging info that refers to the beginnings
        !           201:    and ends of the ranges of code for each lexical block with
        !           202:    assembler labels ..Bn and ..Bn.e, where n is the block number.
        !           203:    The labels themselves are generated in final.c, which assigns
        !           204:    numbers to the blocks in the same way.  */
        !           205: 
        !           206: static unsigned next_block_number = 2;
        !           207: 
        !           208: /* Counter to generate unique names for DIEs. */
        !           209: 
        !           210: static unsigned next_unused_dienum = 1;
        !           211: 
        !           212: /* Number of the DIE which is currently being generated.  */
        !           213: 
        !           214: static unsigned current_dienum;
        !           215: 
        !           216: /* Number to use for the special "pubname" label on the next DIE which
        !           217:    represents a function or data object defined in this compilation
        !           218:    unit which has "extern" linkage.  */
        !           219: 
        !           220: static next_pubname_number = 0;
        !           221: 
        !           222: #define NEXT_DIE_NUM pending_sibling_stack[pending_siblings-1]
        !           223: 
        !           224: /* Pointer to a dynamically allocated list of pre-reserved and still
        !           225:    pending sibling DIE numbers.         Note that this list will grow as needed.  */
        !           226: 
        !           227: static unsigned *pending_sibling_stack;
        !           228: 
        !           229: /* Counter to keep track of the number of pre-reserved and still pending
        !           230:    sibling DIE numbers.         */
        !           231: 
        !           232: static unsigned pending_siblings;
        !           233: 
        !           234: /* The currently allocated size of the above list (expressed in number of
        !           235:    list elements).  */
        !           236: 
        !           237: static unsigned pending_siblings_allocated;
        !           238: 
        !           239: /* Size (in elements) of increments by which we may expand the pending
        !           240:    sibling stack.  Actually, a single hunk of space of this size should
        !           241:    be enough for most typical programs.         */
        !           242: 
        !           243: #define PENDING_SIBLINGS_INCREMENT 64
        !           244: 
        !           245: /* Non-zero if we are performing our file-scope finalization pass and if
        !           246:    we should force out Dwarf descriptions of any and all file-scope
        !           247:    tagged types which are still incomplete types.  */
        !           248: 
        !           249: static int finalizing = 0;
        !           250: 
        !           251: /* A pointer to the base of a list of pending types which we haven't
        !           252:    generated DIEs for yet, but which we will have to come back to
        !           253:    later on.  */
        !           254: 
        !           255: static tree *pending_types_list;
        !           256: 
        !           257: /* Number of elements currently allocated for the pending_types_list.  */
        !           258: 
        !           259: static unsigned pending_types_allocated;
        !           260: 
        !           261: /* Number of elements of pending_types_list currently in use.  */
        !           262: 
        !           263: static unsigned pending_types;
        !           264: 
        !           265: /* Size (in elements) of increments by which we may expand the pending
        !           266:    types list.  Actually, a single hunk of space of this size should
        !           267:    be enough for most typical programs.         */
        !           268: 
        !           269: #define PENDING_TYPES_INCREMENT 64
        !           270: 
        !           271: /* Pointer to an artificial RECORD_TYPE which we create in dwarfout_init.
        !           272:    This is used in a hack to help us get the DIEs describing types of
        !           273:    formal parameters to come *after* all of the DIEs describing the formal
        !           274:    parameters themselves.  That's necessary in order to be compatible
        !           275:    with what the brain-damaged svr4 SDB debugger requires.  */
        !           276: 
        !           277: static tree fake_containing_scope;
        !           278: 
        !           279: /* The number of the current function definition that we are generating
        !           280:    debugging information for.  These numbers range from 1 up to the maximum
        !           281:    number of function definitions contained within the current compilation
        !           282:    unit.  These numbers are used to create unique labels for various things
        !           283:    contained within various function definitions.  */
        !           284: 
        !           285: static unsigned current_funcdef_number = 1;
        !           286: 
        !           287: /* A pointer to the ..._DECL node which we have most recently been working
        !           288:    on.  We keep this around just in case something about it looks screwy
        !           289:    and we want to tell the user what the source coordinates for the actual
        !           290:    declaration are.  */
        !           291: 
        !           292: static tree dwarf_last_decl;
        !           293: 
        !           294: /* Forward declarations for functions defined in this file.  */
        !           295: 
        !           296: static void output_type ();
        !           297: static void type_attribute ();
        !           298: static void output_decls_for_scope ();
        !           299: static void output_decl ();
        !           300: static unsigned lookup_filename ();
        !           301: 
        !           302: /* Definitions of defaults for assembler-dependent names of various
        !           303:    pseudo-ops and section names.
        !           304: 
        !           305:    Theses may be overridden in your tm.h file (if necessary) for your
        !           306:    particular assembler.  The default values provided here correspond to
        !           307:    what is expected by "standard" AT&T System V.4 assemblers.  */
        !           308: 
        !           309: #ifndef FILE_ASM_OP
        !           310: #define FILE_ASM_OP            ".file"
        !           311: #endif
        !           312: #ifndef VERSION_ASM_OP
        !           313: #define VERSION_ASM_OP         ".version"
        !           314: #endif
        !           315: #ifndef UNALIGNED_SHORT_ASM_OP
        !           316: #define UNALIGNED_SHORT_ASM_OP ".2byte"
        !           317: #endif
        !           318: #ifndef UNALIGNED_INT_ASM_OP
        !           319: #define UNALIGNED_INT_ASM_OP   ".4byte"
        !           320: #endif
        !           321: #ifndef ASM_BYTE_OP
        !           322: #define ASM_BYTE_OP            ".byte"
        !           323: #endif
        !           324: #ifndef SET_ASM_OP
        !           325: #define SET_ASM_OP             ".set"
        !           326: #endif
        !           327: 
        !           328: /* Pseudo-ops for pushing the current section onto the section stack (and
        !           329:    simultaneously changing to a new section) and for poping back to the
        !           330:    section we were in immediately before this one.  Note that most svr4
        !           331:    assemblers only maintain a one level stack... you can push all the
        !           332:    sections you want, but you can only pop out one level.  (The sparc
        !           333:    svr4 assembler is an exception to this general rule.)  That's
        !           334:    OK because we only use at most one level of the section stack herein.  */
        !           335: 
        !           336: #ifndef PUSHSECTION_ASM_OP
        !           337: #define PUSHSECTION_ASM_OP     ".section"
        !           338: #endif
        !           339: #ifndef POPSECTION_ASM_OP
        !           340: #define POPSECTION_ASM_OP      ".previous"
        !           341: #endif
        !           342: 
        !           343: /* The default format used by the ASM_OUTPUT_PUSH_SECTION macro (see below)
        !           344:    to print the PUSHSECTION_ASM_OP and the section name.  The default here
        !           345:    works for almost all svr4 assemblers, except for the sparc, where the
        !           346:    section name must be enclosed in double quotes.  (See sparcv4.h.)  */
        !           347: 
        !           348: #ifndef PUSHSECTION_FORMAT
        !           349: #define PUSHSECTION_FORMAT     "%s\t%s\n"
        !           350: #endif
        !           351: 
        !           352: #ifndef DEBUG_SECTION
        !           353: #define DEBUG_SECTION          ".debug"
        !           354: #endif
        !           355: #ifndef LINE_SECTION
        !           356: #define LINE_SECTION           ".line"
        !           357: #endif
        !           358: #ifndef SFNAMES_SECTION
        !           359: #define SFNAMES_SECTION                ".debug_sfnames"
        !           360: #endif
        !           361: #ifndef SRCINFO_SECTION
        !           362: #define SRCINFO_SECTION                ".debug_srcinfo"
        !           363: #endif
        !           364: #ifndef MACINFO_SECTION
        !           365: #define MACINFO_SECTION                ".debug_macinfo"
        !           366: #endif
        !           367: #ifndef PUBNAMES_SECTION
        !           368: #define PUBNAMES_SECTION       ".debug_pubnames"
        !           369: #endif
        !           370: #ifndef ARANGES_SECTION
        !           371: #define ARANGES_SECTION                ".debug_aranges"
        !           372: #endif
        !           373: #ifndef TEXT_SECTION
        !           374: #define TEXT_SECTION           ".text"
        !           375: #endif
        !           376: #ifndef DATA_SECTION
        !           377: #define DATA_SECTION           ".data"
        !           378: #endif
        !           379: #ifndef DATA1_SECTION
        !           380: #define DATA1_SECTION          ".data1"
        !           381: #endif
        !           382: #ifndef RODATA_SECTION
        !           383: #define RODATA_SECTION         ".rodata"
        !           384: #endif
        !           385: #ifndef RODATA1_SECTION
        !           386: #define RODATA1_SECTION                ".rodata1"
        !           387: #endif
        !           388: #ifndef BSS_SECTION
        !           389: #define BSS_SECTION            ".bss"
        !           390: #endif
        !           391: 
        !           392: /* Definitions of defaults for formats and names of various special
        !           393:    (artificial) labels which may be generated within this file (when
        !           394:    the -g options is used and DWARF_DEBUGGING_INFO is in effect.
        !           395: 
        !           396:    If necessary, these may be overridden from within your tm.h file,
        !           397:    but typically, you should never need to override these.
        !           398: 
        !           399:    These labels have been hacked (temporarily) so that they all begin with
        !           400:    a `.L' sequence so as to appease the stock sparc/svr4 assembler and the
        !           401:    stock m88k/svr4 assembler, both of which need to see .L at the start of
        !           402:    a label in order to prevent that label from going into the linker symbol
        !           403:    table).  When I get time, I'll have to fix this the right way so that we
        !           404:    will use ASM_GENERATE_INTERNAL_LABEL and ASM_OUTPUT_INTERNAL_LABEL herein,
        !           405:    but that will require a rather massive set of changes.  For the moment,
        !           406:    the following definitions out to produce the right results for all svr4
        !           407:    and svr3 assemblers. -- rfg
        !           408: */
        !           409: 
        !           410: #ifndef TEXT_BEGIN_LABEL
        !           411: #define TEXT_BEGIN_LABEL       ".L_text_b"
        !           412: #endif
        !           413: #ifndef TEXT_END_LABEL
        !           414: #define TEXT_END_LABEL         ".L_text_e"
        !           415: #endif
        !           416: 
        !           417: #ifndef DATA_BEGIN_LABEL
        !           418: #define DATA_BEGIN_LABEL       ".L_data_b"
        !           419: #endif
        !           420: #ifndef DATA_END_LABEL
        !           421: #define DATA_END_LABEL         ".L_data_e"
        !           422: #endif
        !           423: 
        !           424: #ifndef DATA1_BEGIN_LABEL
        !           425: #define DATA1_BEGIN_LABEL      ".L_data1_b"
        !           426: #endif
        !           427: #ifndef DATA1_END_LABEL
        !           428: #define DATA1_END_LABEL                ".L_data1_e"
        !           429: #endif
        !           430: 
        !           431: #ifndef RODATA_BEGIN_LABEL
        !           432: #define RODATA_BEGIN_LABEL     ".L_rodata_b"
        !           433: #endif
        !           434: #ifndef RODATA_END_LABEL
        !           435: #define RODATA_END_LABEL       ".L_rodata_e"
        !           436: #endif
        !           437: 
        !           438: #ifndef RODATA1_BEGIN_LABEL
        !           439: #define RODATA1_BEGIN_LABEL    ".L_rodata1_b"
        !           440: #endif
        !           441: #ifndef RODATA1_END_LABEL
        !           442: #define RODATA1_END_LABEL      ".L_rodata1_e"
        !           443: #endif
        !           444: 
        !           445: #ifndef BSS_BEGIN_LABEL
        !           446: #define BSS_BEGIN_LABEL                ".L_bss_b"
        !           447: #endif
        !           448: #ifndef BSS_END_LABEL
        !           449: #define BSS_END_LABEL          ".L_bss_e"
        !           450: #endif
        !           451: 
        !           452: #ifndef LINE_BEGIN_LABEL
        !           453: #define LINE_BEGIN_LABEL       ".L_line_b"
        !           454: #endif
        !           455: #ifndef LINE_LAST_ENTRY_LABEL
        !           456: #define LINE_LAST_ENTRY_LABEL  ".L_line_last"
        !           457: #endif
        !           458: #ifndef LINE_END_LABEL
        !           459: #define LINE_END_LABEL         ".L_line_e"
        !           460: #endif
        !           461: 
        !           462: #ifndef DEBUG_BEGIN_LABEL
        !           463: #define DEBUG_BEGIN_LABEL      ".L_debug_b"
        !           464: #endif
        !           465: #ifndef SFNAMES_BEGIN_LABEL
        !           466: #define SFNAMES_BEGIN_LABEL    ".L_sfnames_b"
        !           467: #endif
        !           468: #ifndef SRCINFO_BEGIN_LABEL
        !           469: #define SRCINFO_BEGIN_LABEL    ".L_srcinfo_b"
        !           470: #endif
        !           471: #ifndef MACINFO_BEGIN_LABEL
        !           472: #define MACINFO_BEGIN_LABEL    ".L_macinfo_b"
        !           473: #endif
        !           474: 
        !           475: #ifndef DIE_BEGIN_LABEL_FMT
        !           476: #define DIE_BEGIN_LABEL_FMT    ".L_D%u"
        !           477: #endif
        !           478: #ifndef DIE_END_LABEL_FMT
        !           479: #define DIE_END_LABEL_FMT      ".L_D%u_e"
        !           480: #endif
        !           481: #ifndef PUB_DIE_LABEL_FMT
        !           482: #define PUB_DIE_LABEL_FMT      ".L_P%u"
        !           483: #endif
        !           484: #ifndef INSN_LABEL_FMT
        !           485: #define INSN_LABEL_FMT         ".L_I%u_%u"
        !           486: #endif
        !           487: #ifndef BLOCK_BEGIN_LABEL_FMT
        !           488: #define BLOCK_BEGIN_LABEL_FMT  ".L_B%u"
        !           489: #endif
        !           490: #ifndef BLOCK_END_LABEL_FMT
        !           491: #define BLOCK_END_LABEL_FMT    ".L_B%u_e"
        !           492: #endif
        !           493: #ifndef SS_BEGIN_LABEL_FMT
        !           494: #define SS_BEGIN_LABEL_FMT     ".L_s%u"
        !           495: #endif
        !           496: #ifndef SS_END_LABEL_FMT
        !           497: #define SS_END_LABEL_FMT       ".L_s%u_e"
        !           498: #endif
        !           499: #ifndef EE_BEGIN_LABEL_FMT
        !           500: #define EE_BEGIN_LABEL_FMT     ".L_e%u"
        !           501: #endif
        !           502: #ifndef EE_END_LABEL_FMT
        !           503: #define EE_END_LABEL_FMT       ".L_e%u_e"
        !           504: #endif
        !           505: #ifndef MT_BEGIN_LABEL_FMT
        !           506: #define MT_BEGIN_LABEL_FMT     ".L_t%u"
        !           507: #endif
        !           508: #ifndef MT_END_LABEL_FMT
        !           509: #define MT_END_LABEL_FMT       ".L_t%u_e"
        !           510: #endif
        !           511: #ifndef LOC_BEGIN_LABEL_FMT
        !           512: #define LOC_BEGIN_LABEL_FMT    ".L_l%u"
        !           513: #endif
        !           514: #ifndef LOC_END_LABEL_FMT
        !           515: #define LOC_END_LABEL_FMT      ".L_l%u_e"
        !           516: #endif
        !           517: #ifndef BOUND_BEGIN_LABEL_FMT
        !           518: #define BOUND_BEGIN_LABEL_FMT  ".L_b%u_%u_%c"
        !           519: #endif
        !           520: #ifndef BOUND_END_LABEL_FMT
        !           521: #define BOUND_END_LABEL_FMT    ".L_b%u_%u_%c_e"
        !           522: #endif
        !           523: #ifndef DERIV_BEGIN_LABEL_FMT
        !           524: #define DERIV_BEGIN_LABEL_FMT  ".L_d%u"
        !           525: #endif
        !           526: #ifndef DERIV_END_LABEL_FMT
        !           527: #define DERIV_END_LABEL_FMT    ".L_d%u_e"
        !           528: #endif
        !           529: #ifndef SL_BEGIN_LABEL_FMT
        !           530: #define SL_BEGIN_LABEL_FMT     ".L_sl%u"
        !           531: #endif
        !           532: #ifndef SL_END_LABEL_FMT
        !           533: #define SL_END_LABEL_FMT       ".L_sl%u_e"
        !           534: #endif
        !           535: #ifndef BODY_BEGIN_LABEL_FMT
        !           536: #define BODY_BEGIN_LABEL_FMT   ".L_b%u"
        !           537: #endif
        !           538: #ifndef BODY_END_LABEL_FMT
        !           539: #define BODY_END_LABEL_FMT     ".L_b%u_e"
        !           540: #endif
        !           541: #ifndef FUNC_END_LABEL_FMT
        !           542: #define FUNC_END_LABEL_FMT     ".L_f%u_e"
        !           543: #endif
        !           544: #ifndef TYPE_NAME_FMT
        !           545: #define TYPE_NAME_FMT          ".L_T%u"
        !           546: #endif
        !           547: #ifndef DECL_NAME_FMT
        !           548: #define DECL_NAME_FMT          ".L_E%u"
        !           549: #endif
        !           550: #ifndef LINE_CODE_LABEL_FMT
        !           551: #define LINE_CODE_LABEL_FMT    ".L_LC%u"
        !           552: #endif
        !           553: #ifndef SFNAMES_ENTRY_LABEL_FMT
        !           554: #define SFNAMES_ENTRY_LABEL_FMT        ".L_F%u"
        !           555: #endif
        !           556: #ifndef LINE_ENTRY_LABEL_FMT
        !           557: #define LINE_ENTRY_LABEL_FMT   ".L_LE%u"
        !           558: #endif
        !           559: 
        !           560: /* Definitions of defaults for various types of primitive assembly language
        !           561:    output operations.
        !           562: 
        !           563:    If necessary, these may be overridden from within your tm.h file,
        !           564:    but typically, you shouldn't need to override these.  One known
        !           565:    exception is ASM_OUTPUT_DEF which has to be different for stock
        !           566:    sparc/svr4 assemblers.
        !           567: */
        !           568: 
        !           569: #ifndef ASM_OUTPUT_PUSH_SECTION
        !           570: #define ASM_OUTPUT_PUSH_SECTION(FILE, SECTION) \
        !           571:   fprintf ((FILE), PUSHSECTION_FORMAT, PUSHSECTION_ASM_OP, SECTION)
        !           572: #endif
        !           573: 
        !           574: #ifndef ASM_OUTPUT_POP_SECTION
        !           575: #define ASM_OUTPUT_POP_SECTION(FILE) \
        !           576:   fprintf ((FILE), "\t%s\n", POPSECTION_ASM_OP)
        !           577: #endif
        !           578: 
        !           579: #ifndef ASM_OUTPUT_SOURCE_FILENAME
        !           580: #define ASM_OUTPUT_SOURCE_FILENAME(FILE,NAME) \
        !           581:   do { fprintf (FILE, "\t%s\t", FILE_ASM_OP);                          \
        !           582:        output_quoted_string (FILE, NAME);                              \
        !           583:        fputc ('\n', FILE);                                             \
        !           584:   } while (0)
        !           585: #endif
        !           586: 
        !           587: #ifndef ASM_OUTPUT_DEF
        !           588: #define ASM_OUTPUT_DEF(FILE,LABEL1,LABEL2)                             \
        !           589:  do {  fprintf ((FILE), "\t%s\t", SET_ASM_OP);                         \
        !           590:        assemble_name (FILE, LABEL1);                                   \
        !           591:        fprintf (FILE, ",");                                            \
        !           592:        assemble_name (FILE, LABEL2);                                   \
        !           593:        fprintf (FILE, "\n");                                           \
        !           594:   } while (0)
        !           595: #endif
        !           596: 
        !           597: #ifndef ASM_OUTPUT_DWARF_DELTA2
        !           598: #define ASM_OUTPUT_DWARF_DELTA2(FILE,LABEL1,LABEL2)                    \
        !           599:  do {  fprintf ((FILE), "\t%s\t", UNALIGNED_SHORT_ASM_OP);             \
        !           600:        assemble_name (FILE, LABEL1);                                   \
        !           601:        fprintf (FILE, "-");                                            \
        !           602:        assemble_name (FILE, LABEL2);                                   \
        !           603:        fprintf (FILE, "\n");                                           \
        !           604:   } while (0)
        !           605: #endif
        !           606: 
        !           607: #ifndef ASM_OUTPUT_DWARF_DELTA4
        !           608: #define ASM_OUTPUT_DWARF_DELTA4(FILE,LABEL1,LABEL2)                    \
        !           609:  do {  fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP);               \
        !           610:        assemble_name (FILE, LABEL1);                                   \
        !           611:        fprintf (FILE, "-");                                            \
        !           612:        assemble_name (FILE, LABEL2);                                   \
        !           613:        fprintf (FILE, "\n");                                           \
        !           614:   } while (0)
        !           615: #endif
        !           616: 
        !           617: #ifndef ASM_OUTPUT_DWARF_TAG
        !           618: #define ASM_OUTPUT_DWARF_TAG(FILE,TAG)                                 \
        !           619:   do {                                                                 \
        !           620:     fprintf ((FILE), "\t%s\t0x%x",                                     \
        !           621:                     UNALIGNED_SHORT_ASM_OP, (unsigned) TAG);           \
        !           622:     if (flag_verbose_asm)                                              \
        !           623:       fprintf ((FILE), "\t%s %s",                                      \
        !           624:                       ASM_COMMENT_START, dwarf_tag_name (TAG));        \
        !           625:     fputc ('\n', (FILE));                                              \
        !           626:   } while (0)
        !           627: #endif
        !           628: 
        !           629: #ifndef ASM_OUTPUT_DWARF_ATTRIBUTE
        !           630: #define ASM_OUTPUT_DWARF_ATTRIBUTE(FILE,ATTR)                          \
        !           631:   do {                                                                 \
        !           632:     fprintf ((FILE), "\t%s\t0x%x",                                     \
        !           633:                     UNALIGNED_SHORT_ASM_OP, (unsigned) ATTR);          \
        !           634:     if (flag_verbose_asm)                                              \
        !           635:       fprintf ((FILE), "\t%s %s",                                      \
        !           636:                       ASM_COMMENT_START, dwarf_attr_name (ATTR));      \
        !           637:     fputc ('\n', (FILE));                                              \
        !           638:   } while (0)
        !           639: #endif
        !           640: 
        !           641: #ifndef ASM_OUTPUT_DWARF_STACK_OP
        !           642: #define ASM_OUTPUT_DWARF_STACK_OP(FILE,OP)                             \
        !           643:   do {                                                                 \
        !           644:     fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) OP);                \
        !           645:     if (flag_verbose_asm)                                              \
        !           646:       fprintf ((FILE), "\t%s %s",                                      \
        !           647:                       ASM_COMMENT_START, dwarf_stack_op_name (OP));    \
        !           648:     fputc ('\n', (FILE));                                              \
        !           649:   } while (0)
        !           650: #endif
        !           651: 
        !           652: #ifndef ASM_OUTPUT_DWARF_FUND_TYPE
        !           653: #define ASM_OUTPUT_DWARF_FUND_TYPE(FILE,FT)                            \
        !           654:   do {                                                                 \
        !           655:     fprintf ((FILE), "\t%s\t0x%x",                                     \
        !           656:                     UNALIGNED_SHORT_ASM_OP, (unsigned) FT);            \
        !           657:     if (flag_verbose_asm)                                              \
        !           658:       fprintf ((FILE), "\t%s %s",                                      \
        !           659:                       ASM_COMMENT_START, dwarf_fund_type_name (FT));   \
        !           660:     fputc ('\n', (FILE));                                              \
        !           661:   } while (0)
        !           662: #endif
        !           663: 
        !           664: #ifndef ASM_OUTPUT_DWARF_FMT_BYTE
        !           665: #define ASM_OUTPUT_DWARF_FMT_BYTE(FILE,FMT)                            \
        !           666:   do {                                                                 \
        !           667:     fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) FMT);       \
        !           668:     if (flag_verbose_asm)                                              \
        !           669:       fprintf ((FILE), "\t%s %s",                                      \
        !           670:                       ASM_COMMENT_START, dwarf_fmt_byte_name (FMT));   \
        !           671:     fputc ('\n', (FILE));                                              \
        !           672:   } while (0)
        !           673: #endif
        !           674: 
        !           675: #ifndef ASM_OUTPUT_DWARF_TYPE_MODIFIER
        !           676: #define ASM_OUTPUT_DWARF_TYPE_MODIFIER(FILE,MOD)                       \
        !           677:   do {                                                                 \
        !           678:     fprintf ((FILE), "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) MOD);       \
        !           679:     if (flag_verbose_asm)                                              \
        !           680:       fprintf ((FILE), "\t%s %s",                                      \
        !           681:                       ASM_COMMENT_START, dwarf_typemod_name (MOD));    \
        !           682:     fputc ('\n', (FILE));                                              \
        !           683:   } while (0)
        !           684: #endif
        !           685: 
        !           686: #ifndef ASM_OUTPUT_DWARF_ADDR
        !           687: #define ASM_OUTPUT_DWARF_ADDR(FILE,LABEL)                              \
        !           688:  do {  fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP);               \
        !           689:        assemble_name (FILE, LABEL);                                    \
        !           690:        fprintf (FILE, "\n");                                           \
        !           691:   } while (0)
        !           692: #endif
        !           693: 
        !           694: #ifndef ASM_OUTPUT_DWARF_ADDR_CONST
        !           695: #define ASM_OUTPUT_DWARF_ADDR_CONST(FILE,RTX)                          \
        !           696:   do {                                                                 \
        !           697:     fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP);                  \
        !           698:     output_addr_const ((FILE), (RTX));                                 \
        !           699:     fputc ('\n', (FILE));                                              \
        !           700:   } while (0)
        !           701: #endif
        !           702: 
        !           703: #ifndef ASM_OUTPUT_DWARF_REF
        !           704: #define ASM_OUTPUT_DWARF_REF(FILE,LABEL)                               \
        !           705:  do {  fprintf ((FILE), "\t%s\t", UNALIGNED_INT_ASM_OP);               \
        !           706:        assemble_name (FILE, LABEL);                                    \
        !           707:        fprintf (FILE, "\n");                                           \
        !           708:   } while (0)
        !           709: #endif
        !           710: 
        !           711: #ifndef ASM_OUTPUT_DWARF_DATA1
        !           712: #define ASM_OUTPUT_DWARF_DATA1(FILE,VALUE) \
        !           713:   fprintf ((FILE), "\t%s\t0x%x\n", ASM_BYTE_OP, VALUE)
        !           714: #endif
        !           715: 
        !           716: #ifndef ASM_OUTPUT_DWARF_DATA2
        !           717: #define ASM_OUTPUT_DWARF_DATA2(FILE,VALUE) \
        !           718:   fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_SHORT_ASM_OP, (unsigned) VALUE)
        !           719: #endif
        !           720: 
        !           721: #ifndef ASM_OUTPUT_DWARF_DATA4
        !           722: #define ASM_OUTPUT_DWARF_DATA4(FILE,VALUE) \
        !           723:   fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, (unsigned) VALUE)
        !           724: #endif
        !           725: 
        !           726: #ifndef ASM_OUTPUT_DWARF_DATA8
        !           727: #define ASM_OUTPUT_DWARF_DATA8(FILE,HIGH_VALUE,LOW_VALUE)              \
        !           728:   do {                                                                 \
        !           729:     if (WORDS_BIG_ENDIAN)                                              \
        !           730:       {                                                                        \
        !           731:        fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \
        !           732:        fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\
        !           733:       }                                                                        \
        !           734:     else                                                               \
        !           735:       {                                                                        \
        !           736:        fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, LOW_VALUE);\
        !           737:        fprintf ((FILE), "\t%s\t0x%x\n", UNALIGNED_INT_ASM_OP, HIGH_VALUE); \
        !           738:       }                                                                        \
        !           739:   } while (0)
        !           740: #endif
        !           741: 
        !           742: #ifndef ASM_OUTPUT_DWARF_STRING
        !           743: #define ASM_OUTPUT_DWARF_STRING(FILE,P) \
        !           744:   ASM_OUTPUT_ASCII ((FILE), P, strlen (P)+1)
        !           745: #endif
        !           746: 
        !           747: /************************ general utility functions **************************/
        !           748: 
        !           749: inline char *
        !           750: xstrdup (s)
        !           751:      register char *s;
        !           752: {
        !           753:   register char *p = (char *) xmalloc (strlen (s) + 1);
        !           754: 
        !           755:   strcpy (p, s);
        !           756:   return p;
        !           757: }
        !           758: 
        !           759: inline int
        !           760: is_pseudo_reg (rtl)
        !           761:      register rtx rtl;
        !           762: {
        !           763:   return (((GET_CODE (rtl) == REG) && (REGNO (rtl) >= FIRST_PSEUDO_REGISTER))
        !           764:           || ((GET_CODE (rtl) == SUBREG)
        !           765:              && (REGNO (XEXP (rtl, 0)) >= FIRST_PSEUDO_REGISTER)));
        !           766: }
        !           767: 
        !           768: inline tree
        !           769: type_main_variant (type)
        !           770:      register tree type;
        !           771: {
        !           772:   type = TYPE_MAIN_VARIANT (type);
        !           773: 
        !           774:   /* There really should be only one main variant among any group of variants
        !           775:      of a given type (and all of the MAIN_VARIANT values for all members of
        !           776:      the group should point to that one type) but sometimes the C front-end
        !           777:      messes this up for array types, so we work around that bug here.  */
        !           778: 
        !           779:   if (TREE_CODE (type) == ARRAY_TYPE)
        !           780:     {
        !           781:       while (type != TYPE_MAIN_VARIANT (type))
        !           782:         type = TYPE_MAIN_VARIANT (type);
        !           783:     }
        !           784: 
        !           785:   return type;
        !           786: }
        !           787: 
        !           788: /* Return non-zero if the given type node represents a tagged type.  */
        !           789: 
        !           790: inline int
        !           791: is_tagged_type (type)
        !           792:      register tree type;
        !           793: {
        !           794:   register enum tree_code code = TREE_CODE (type);
        !           795: 
        !           796:   return (code == RECORD_TYPE || code == UNION_TYPE
        !           797:          || code == QUAL_UNION_TYPE || code == ENUMERAL_TYPE);
        !           798: }
        !           799: 
        !           800: static char *
        !           801: dwarf_tag_name (tag)
        !           802:      register unsigned tag;
        !           803: {
        !           804:   switch (tag)
        !           805:     {
        !           806:     case TAG_padding:                  return "TAG_padding";
        !           807:     case TAG_array_type:               return "TAG_array_type";
        !           808:     case TAG_class_type:               return "TAG_class_type";
        !           809:     case TAG_entry_point:              return "TAG_entry_point";
        !           810:     case TAG_enumeration_type:         return "TAG_enumeration_type";
        !           811:     case TAG_formal_parameter:         return "TAG_formal_parameter";
        !           812:     case TAG_global_subroutine:                return "TAG_global_subroutine";
        !           813:     case TAG_global_variable:          return "TAG_global_variable";
        !           814:     case TAG_label:                    return "TAG_label";
        !           815:     case TAG_lexical_block:            return "TAG_lexical_block";
        !           816:     case TAG_local_variable:           return "TAG_local_variable";
        !           817:     case TAG_member:                   return "TAG_member";
        !           818:     case TAG_pointer_type:             return "TAG_pointer_type";
        !           819:     case TAG_reference_type:           return "TAG_reference_type";
        !           820:     case TAG_compile_unit:             return "TAG_compile_unit";
        !           821:     case TAG_string_type:              return "TAG_string_type";
        !           822:     case TAG_structure_type:           return "TAG_structure_type";
        !           823:     case TAG_subroutine:               return "TAG_subroutine";
        !           824:     case TAG_subroutine_type:          return "TAG_subroutine_type";
        !           825:     case TAG_typedef:                  return "TAG_typedef";
        !           826:     case TAG_union_type:               return "TAG_union_type";
        !           827:     case TAG_unspecified_parameters:   return "TAG_unspecified_parameters";
        !           828:     case TAG_variant:                  return "TAG_variant";
        !           829:     case TAG_common_block:             return "TAG_common_block";
        !           830:     case TAG_common_inclusion:         return "TAG_common_inclusion";
        !           831:     case TAG_inheritance:              return "TAG_inheritance";
        !           832:     case TAG_inlined_subroutine:       return "TAG_inlined_subroutine";
        !           833:     case TAG_module:                   return "TAG_module";
        !           834:     case TAG_ptr_to_member_type:       return "TAG_ptr_to_member_type";
        !           835:     case TAG_set_type:                 return "TAG_set_type";
        !           836:     case TAG_subrange_type:            return "TAG_subrange_type";
        !           837:     case TAG_with_stmt:                        return "TAG_with_stmt";
        !           838: 
        !           839:     /* GNU extensions.  */
        !           840: 
        !           841:     case TAG_format_label:             return "TAG_format_label";
        !           842:     case TAG_namelist:                 return "TAG_namelist";
        !           843:     case TAG_function_template:                return "TAG_function_template";
        !           844:     case TAG_class_template:           return "TAG_class_template";
        !           845: 
        !           846:     default:                           return "TAG_<unknown>";
        !           847:     }
        !           848: }
        !           849: 
        !           850: static char *
        !           851: dwarf_attr_name (attr)
        !           852:      register unsigned attr;
        !           853: {
        !           854:   switch (attr)
        !           855:     {
        !           856:     case AT_sibling:                   return "AT_sibling";
        !           857:     case AT_location:                  return "AT_location";
        !           858:     case AT_name:                      return "AT_name";
        !           859:     case AT_fund_type:                 return "AT_fund_type";
        !           860:     case AT_mod_fund_type:             return "AT_mod_fund_type";
        !           861:     case AT_user_def_type:             return "AT_user_def_type";
        !           862:     case AT_mod_u_d_type:              return "AT_mod_u_d_type";
        !           863:     case AT_ordering:                  return "AT_ordering";
        !           864:     case AT_subscr_data:               return "AT_subscr_data";
        !           865:     case AT_byte_size:                 return "AT_byte_size";
        !           866:     case AT_bit_offset:                        return "AT_bit_offset";
        !           867:     case AT_bit_size:                  return "AT_bit_size";
        !           868:     case AT_element_list:              return "AT_element_list";
        !           869:     case AT_stmt_list:                 return "AT_stmt_list";
        !           870:     case AT_low_pc:                    return "AT_low_pc";
        !           871:     case AT_high_pc:                   return "AT_high_pc";
        !           872:     case AT_language:                  return "AT_language";
        !           873:     case AT_member:                    return "AT_member";
        !           874:     case AT_discr:                     return "AT_discr";
        !           875:     case AT_discr_value:               return "AT_discr_value";
        !           876:     case AT_string_length:             return "AT_string_length";
        !           877:     case AT_common_reference:          return "AT_common_reference";
        !           878:     case AT_comp_dir:                  return "AT_comp_dir";
        !           879:     case AT_const_value_string:                return "AT_const_value_string";
        !           880:     case AT_const_value_data2:         return "AT_const_value_data2";
        !           881:     case AT_const_value_data4:         return "AT_const_value_data4";
        !           882:     case AT_const_value_data8:         return "AT_const_value_data8";
        !           883:     case AT_const_value_block2:                return "AT_const_value_block2";
        !           884:     case AT_const_value_block4:                return "AT_const_value_block4";
        !           885:     case AT_containing_type:           return "AT_containing_type";
        !           886:     case AT_default_value_addr:                return "AT_default_value_addr";
        !           887:     case AT_default_value_data2:       return "AT_default_value_data2";
        !           888:     case AT_default_value_data4:       return "AT_default_value_data4";
        !           889:     case AT_default_value_data8:       return "AT_default_value_data8";
        !           890:     case AT_default_value_string:      return "AT_default_value_string";
        !           891:     case AT_friends:                   return "AT_friends";
        !           892:     case AT_inline:                    return "AT_inline";
        !           893:     case AT_is_optional:               return "AT_is_optional";
        !           894:     case AT_lower_bound_ref:           return "AT_lower_bound_ref";
        !           895:     case AT_lower_bound_data2:         return "AT_lower_bound_data2";
        !           896:     case AT_lower_bound_data4:         return "AT_lower_bound_data4";
        !           897:     case AT_lower_bound_data8:         return "AT_lower_bound_data8";
        !           898:     case AT_private:                   return "AT_private";
        !           899:     case AT_producer:                  return "AT_producer";
        !           900:     case AT_program:                   return "AT_program";
        !           901:     case AT_protected:                 return "AT_protected";
        !           902:     case AT_prototyped:                        return "AT_prototyped";
        !           903:     case AT_public:                    return "AT_public";
        !           904:     case AT_pure_virtual:              return "AT_pure_virtual";
        !           905:     case AT_return_addr:               return "AT_return_addr";
        !           906:     case AT_abstract_origin:           return "AT_abstract_origin";
        !           907:     case AT_start_scope:               return "AT_start_scope";
        !           908:     case AT_stride_size:               return "AT_stride_size";
        !           909:     case AT_upper_bound_ref:           return "AT_upper_bound_ref";
        !           910:     case AT_upper_bound_data2:         return "AT_upper_bound_data2";
        !           911:     case AT_upper_bound_data4:         return "AT_upper_bound_data4";
        !           912:     case AT_upper_bound_data8:         return "AT_upper_bound_data8";
        !           913:     case AT_virtual:                   return "AT_virtual";
        !           914: 
        !           915:     /* GNU extensions */
        !           916: 
        !           917:     case AT_sf_names:                  return "AT_sf_names";
        !           918:     case AT_src_info:                  return "AT_src_info";
        !           919:     case AT_mac_info:                  return "AT_mac_info";
        !           920:     case AT_src_coords:                        return "AT_src_coords";
        !           921:     case AT_body_begin:                        return "AT_body_begin";
        !           922:     case AT_body_end:                  return "AT_body_end";
        !           923: 
        !           924:     default:                           return "AT_<unknown>";
        !           925:     }
        !           926: }
        !           927: 
        !           928: static char *
        !           929: dwarf_stack_op_name (op)
        !           930:      register unsigned op;
        !           931: {
        !           932:   switch (op)
        !           933:     {
        !           934:     case OP_REG:               return "OP_REG";
        !           935:     case OP_BASEREG:           return "OP_BASEREG";
        !           936:     case OP_ADDR:              return "OP_ADDR";
        !           937:     case OP_CONST:             return "OP_CONST";
        !           938:     case OP_DEREF2:            return "OP_DEREF2";
        !           939:     case OP_DEREF4:            return "OP_DEREF4";
        !           940:     case OP_ADD:               return "OP_ADD";
        !           941:     default:                   return "OP_<unknown>";
        !           942:     }
        !           943: }
        !           944: 
        !           945: static char *
        !           946: dwarf_typemod_name (mod)
        !           947:      register unsigned mod;
        !           948: {
        !           949:   switch (mod)
        !           950:     {
        !           951:     case MOD_pointer_to:       return "MOD_pointer_to";
        !           952:     case MOD_reference_to:     return "MOD_reference_to";
        !           953:     case MOD_const:            return "MOD_const";
        !           954:     case MOD_volatile:         return "MOD_volatile";
        !           955:     default:                   return "MOD_<unknown>";
        !           956:     }
        !           957: }
        !           958: 
        !           959: static char *
        !           960: dwarf_fmt_byte_name (fmt)
        !           961:      register unsigned fmt;
        !           962: {
        !           963:   switch (fmt)
        !           964:     {
        !           965:     case FMT_FT_C_C:   return "FMT_FT_C_C";
        !           966:     case FMT_FT_C_X:   return "FMT_FT_C_X";
        !           967:     case FMT_FT_X_C:   return "FMT_FT_X_C";
        !           968:     case FMT_FT_X_X:   return "FMT_FT_X_X";
        !           969:     case FMT_UT_C_C:   return "FMT_UT_C_C";
        !           970:     case FMT_UT_C_X:   return "FMT_UT_C_X";
        !           971:     case FMT_UT_X_C:   return "FMT_UT_X_C";
        !           972:     case FMT_UT_X_X:   return "FMT_UT_X_X";
        !           973:     case FMT_ET:       return "FMT_ET";
        !           974:     default:           return "FMT_<unknown>";
        !           975:     }
        !           976: }
        !           977: static char *
        !           978: dwarf_fund_type_name (ft)
        !           979:      register unsigned ft;
        !           980: {
        !           981:   switch (ft)
        !           982:     {
        !           983:     case FT_char:              return "FT_char";
        !           984:     case FT_signed_char:       return "FT_signed_char";
        !           985:     case FT_unsigned_char:     return "FT_unsigned_char";
        !           986:     case FT_short:             return "FT_short";
        !           987:     case FT_signed_short:      return "FT_signed_short";
        !           988:     case FT_unsigned_short:    return "FT_unsigned_short";
        !           989:     case FT_integer:           return "FT_integer";
        !           990:     case FT_signed_integer:    return "FT_signed_integer";
        !           991:     case FT_unsigned_integer:  return "FT_unsigned_integer";
        !           992:     case FT_long:              return "FT_long";
        !           993:     case FT_signed_long:       return "FT_signed_long";
        !           994:     case FT_unsigned_long:     return "FT_unsigned_long";
        !           995:     case FT_pointer:           return "FT_pointer";
        !           996:     case FT_float:             return "FT_float";
        !           997:     case FT_dbl_prec_float:    return "FT_dbl_prec_float";
        !           998:     case FT_ext_prec_float:    return "FT_ext_prec_float";
        !           999:     case FT_complex:           return "FT_complex";
        !          1000:     case FT_dbl_prec_complex:  return "FT_dbl_prec_complex";
        !          1001:     case FT_void:              return "FT_void";
        !          1002:     case FT_boolean:           return "FT_boolean";
        !          1003:     case FT_ext_prec_complex:  return "FT_ext_prec_complex";
        !          1004:     case FT_label:             return "FT_label";
        !          1005: 
        !          1006:     /* GNU extensions.  */
        !          1007: 
        !          1008:     case FT_long_long:         return "FT_long_long";
        !          1009:     case FT_signed_long_long:  return "FT_signed_long_long";
        !          1010:     case FT_unsigned_long_long: return "FT_unsigned_long_long";
        !          1011: 
        !          1012:     case FT_int8:              return "FT_int8";
        !          1013:     case FT_signed_int8:       return "FT_signed_int8";
        !          1014:     case FT_unsigned_int8:     return "FT_unsigned_int8";
        !          1015:     case FT_int16:             return "FT_int16";
        !          1016:     case FT_signed_int16:      return "FT_signed_int16";
        !          1017:     case FT_unsigned_int16:    return "FT_unsigned_int16";
        !          1018:     case FT_int32:             return "FT_int32";
        !          1019:     case FT_signed_int32:      return "FT_signed_int32";
        !          1020:     case FT_unsigned_int32:    return "FT_unsigned_int32";
        !          1021:     case FT_int64:             return "FT_int64";
        !          1022:     case FT_signed_int64:      return "FT_signed_int64";
        !          1023:     case FT_unsigned_int64:    return "FT_signed_int64";
        !          1024: 
        !          1025:     case FT_real32:            return "FT_real32";
        !          1026:     case FT_real64:            return "FT_real64";
        !          1027:     case FT_real96:            return "FT_real96";
        !          1028:     case FT_real128:           return "FT_real128";
        !          1029: 
        !          1030:     default:                   return "FT_<unknown>";
        !          1031:     }
        !          1032: }
        !          1033: 
        !          1034: /* Determine the "ultimate origin" of a decl.  The decl may be an
        !          1035:    inlined instance of an inlined instance of a decl which is local
        !          1036:    to an inline function, so we have to trace all of the way back
        !          1037:    through the origin chain to find out what sort of node actually
        !          1038:    served as the original seed for the given block.  */
        !          1039: 
        !          1040: static tree
        !          1041: decl_ultimate_origin (decl)
        !          1042:      register tree decl;
        !          1043: {
        !          1044:   register tree immediate_origin = DECL_ABSTRACT_ORIGIN (decl);
        !          1045: 
        !          1046:   if (immediate_origin == NULL)
        !          1047:     return NULL;
        !          1048:   else
        !          1049:     {
        !          1050:       register tree ret_val;
        !          1051:       register tree lookahead = immediate_origin;
        !          1052: 
        !          1053:       do
        !          1054:        {
        !          1055:          ret_val = lookahead;
        !          1056:          lookahead = DECL_ABSTRACT_ORIGIN (ret_val);
        !          1057:        }
        !          1058:       while (lookahead != NULL && lookahead != ret_val);
        !          1059:       return ret_val;
        !          1060:     }
        !          1061: }
        !          1062: 
        !          1063: /* Determine the "ultimate origin" of a block.  The block may be an
        !          1064:    inlined instance of an inlined instance of a block which is local
        !          1065:    to an inline function, so we have to trace all of the way back
        !          1066:    through the origin chain to find out what sort of node actually
        !          1067:    served as the original seed for the given block.  */
        !          1068: 
        !          1069: static tree
        !          1070: block_ultimate_origin (block)
        !          1071:      register tree block;
        !          1072: {
        !          1073:   register tree immediate_origin = BLOCK_ABSTRACT_ORIGIN (block);
        !          1074: 
        !          1075:   if (immediate_origin == NULL)
        !          1076:     return NULL;
        !          1077:   else
        !          1078:     {
        !          1079:       register tree ret_val;
        !          1080:       register tree lookahead = immediate_origin;
        !          1081: 
        !          1082:       do
        !          1083:        {
        !          1084:          ret_val = lookahead;
        !          1085:          lookahead = (TREE_CODE (ret_val) == BLOCK)
        !          1086:                       ? BLOCK_ABSTRACT_ORIGIN (ret_val)
        !          1087:                       : NULL;
        !          1088:        }
        !          1089:       while (lookahead != NULL && lookahead != ret_val);
        !          1090:       return ret_val;
        !          1091:     }
        !          1092: }
        !          1093: 
        !          1094: static void
        !          1095: output_unsigned_leb128 (value)
        !          1096:      register unsigned long value;
        !          1097: {
        !          1098:   register unsigned long orig_value = value;
        !          1099: 
        !          1100:   do
        !          1101:     {
        !          1102:       register unsigned byte = (value & 0x7f);
        !          1103: 
        !          1104:       value >>= 7;
        !          1105:       if (value != 0)  /* more bytes to follow */
        !          1106:        byte |= 0x80;
        !          1107:       fprintf (asm_out_file, "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) byte);
        !          1108:       if (flag_verbose_asm && value == 0)
        !          1109:        fprintf (asm_out_file, "\t%s ULEB128 number - value = %u",
        !          1110:                 ASM_COMMENT_START, orig_value);
        !          1111:       fputc ('\n', asm_out_file);
        !          1112:     }
        !          1113:   while (value != 0);
        !          1114: }
        !          1115: 
        !          1116: static void
        !          1117: output_signed_leb128 (value)
        !          1118:      register long value;
        !          1119: {
        !          1120:   register long orig_value = value;
        !          1121:   register int negative = (value < 0);
        !          1122:   register int more;
        !          1123: 
        !          1124:   do
        !          1125:     {
        !          1126:       register unsigned byte = (value & 0x7f);
        !          1127: 
        !          1128:       value >>= 7;
        !          1129:       if (negative)
        !          1130:        value |= 0xfe000000;  /* manually sign extend */
        !          1131:       if (((value == 0) && ((byte & 0x40) == 0))
        !          1132:           || ((value == -1) && ((byte & 0x40) == 1)))
        !          1133:        more = 0;
        !          1134:       else
        !          1135:        {
        !          1136:          byte |= 0x80;
        !          1137:          more = 1;
        !          1138:        }
        !          1139:       fprintf (asm_out_file, "\t%s\t0x%x", ASM_BYTE_OP, (unsigned) byte);
        !          1140:       if (flag_verbose_asm && more == 0)
        !          1141:        fprintf (asm_out_file, "\t%s SLEB128 number - value = %d",
        !          1142:                 ASM_COMMENT_START, orig_value);
        !          1143:       fputc ('\n', asm_out_file);
        !          1144:     }
        !          1145:   while (more);
        !          1146: }
        !          1147: 
        !          1148: /**************** utility functions for attribute functions ******************/
        !          1149: 
        !          1150: /* Given a pointer to a BLOCK node return non-zero if (and only if) the
        !          1151:    node in question represents the outermost pair of curly braces (i.e.
        !          1152:    the "body block") of a function or method.
        !          1153: 
        !          1154:    For any BLOCK node representing a "body block" of a function or method,
        !          1155:    the BLOCK_SUPERCONTEXT of the node will point to another BLOCK node
        !          1156:    which represents the outermost (function) scope for the function or
        !          1157:    method (i.e. the one which includes the formal parameters).  The
        !          1158:    BLOCK_SUPERCONTEXT of *that* node in turn will point to the relevant
        !          1159:    FUNCTION_DECL node.
        !          1160: */
        !          1161: 
        !          1162: inline int
        !          1163: is_body_block (stmt)
        !          1164:      register tree stmt;
        !          1165: {
        !          1166:   if (TREE_CODE (stmt) == BLOCK)
        !          1167:     {
        !          1168:       register tree parent = BLOCK_SUPERCONTEXT (stmt);
        !          1169: 
        !          1170:       if (TREE_CODE (parent) == BLOCK)
        !          1171:        {
        !          1172:          register tree grandparent = BLOCK_SUPERCONTEXT (parent);
        !          1173: 
        !          1174:          if (TREE_CODE (grandparent) == FUNCTION_DECL)
        !          1175:            return 1;
        !          1176:        }
        !          1177:     }
        !          1178:   return 0;
        !          1179: }
        !          1180: 
        !          1181: /* Given a pointer to a tree node for some type, return a Dwarf fundamental
        !          1182:    type code for the given type.
        !          1183: 
        !          1184:    This routine must only be called for GCC type nodes that correspond to
        !          1185:    Dwarf fundamental types.
        !          1186: 
        !          1187:    The current Dwarf draft specification calls for Dwarf fundamental types
        !          1188:    to accurately reflect the fact that a given type was either a "plain"
        !          1189:    integral type or an explicitly "signed" integral type.  Unfortunately,
        !          1190:    we can't always do this, because GCC may already have thrown away the
        !          1191:    information about the precise way in which the type was originally
        !          1192:    specified, as in:
        !          1193: 
        !          1194:        typedef signed int my_type;
        !          1195: 
        !          1196:        struct s { my_type f; };
        !          1197: 
        !          1198:    Since we may be stuck here without enought information to do exactly
        !          1199:    what is called for in the Dwarf draft specification, we do the best
        !          1200:    that we can under the circumstances and always use the "plain" integral
        !          1201:    fundamental type codes for int, short, and long types.  That's probably
        !          1202:    good enough.  The additional accuracy called for in the current DWARF
        !          1203:    draft specification is probably never even useful in practice.  */
        !          1204: 
        !          1205: static int
        !          1206: fundamental_type_code (type)
        !          1207:      register tree type;
        !          1208: {
        !          1209:   if (TREE_CODE (type) == ERROR_MARK)
        !          1210:     return 0;
        !          1211: 
        !          1212:   switch (TREE_CODE (type))
        !          1213:     {
        !          1214:       case ERROR_MARK:
        !          1215:        return FT_void;
        !          1216: 
        !          1217:       case VOID_TYPE:
        !          1218:        return FT_void;
        !          1219: 
        !          1220:       case INTEGER_TYPE:
        !          1221:        /* Carefully distinguish all the standard types of C,
        !          1222:           without messing up if the language is not C.
        !          1223:           Note that we check only for the names that contain spaces;
        !          1224:           other names might occur by coincidence in other languages.  */
        !          1225:        if (TYPE_NAME (type) != 0
        !          1226:            && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
        !          1227:            && DECL_NAME (TYPE_NAME (type)) != 0
        !          1228:            && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
        !          1229:          {
        !          1230:            char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
        !          1231: 
        !          1232:            if (!strcmp (name, "unsigned char"))
        !          1233:              return FT_unsigned_char;
        !          1234:            if (!strcmp (name, "signed char"))
        !          1235:              return FT_signed_char;
        !          1236:            if (!strcmp (name, "unsigned int"))
        !          1237:              return FT_unsigned_integer;
        !          1238:            if (!strcmp (name, "short int"))
        !          1239:              return FT_short;
        !          1240:            if (!strcmp (name, "short unsigned int"))
        !          1241:              return FT_unsigned_short;
        !          1242:            if (!strcmp (name, "long int"))
        !          1243:              return FT_long;
        !          1244:            if (!strcmp (name, "long unsigned int"))
        !          1245:              return FT_unsigned_long;
        !          1246:            if (!strcmp (name, "long long int"))
        !          1247:              return FT_long_long;              /* Not grok'ed by svr4 SDB */
        !          1248:            if (!strcmp (name, "long long unsigned int"))
        !          1249:              return FT_unsigned_long_long;     /* Not grok'ed by svr4 SDB */
        !          1250:          }
        !          1251: 
        !          1252:        /* Most integer types will be sorted out above, however, for the
        !          1253:           sake of special `array index' integer types, the following code
        !          1254:           is also provided.  */
        !          1255: 
        !          1256:        if (TYPE_PRECISION (type) == INT_TYPE_SIZE)
        !          1257:          return (TREE_UNSIGNED (type) ? FT_unsigned_integer : FT_integer);
        !          1258: 
        !          1259:        if (TYPE_PRECISION (type) == LONG_TYPE_SIZE)
        !          1260:          return (TREE_UNSIGNED (type) ? FT_unsigned_long : FT_long);
        !          1261: 
        !          1262:        if (TYPE_PRECISION (type) == LONG_LONG_TYPE_SIZE)
        !          1263:          return (TREE_UNSIGNED (type) ? FT_unsigned_long_long : FT_long_long);
        !          1264: 
        !          1265:        if (TYPE_PRECISION (type) == SHORT_TYPE_SIZE)
        !          1266:          return (TREE_UNSIGNED (type) ? FT_unsigned_short : FT_short);
        !          1267: 
        !          1268:        if (TYPE_PRECISION (type) == CHAR_TYPE_SIZE)
        !          1269:          return (TREE_UNSIGNED (type) ? FT_unsigned_char : FT_char);
        !          1270: 
        !          1271:        abort ();
        !          1272: 
        !          1273:       case REAL_TYPE:
        !          1274:        /* Carefully distinguish all the standard types of C,
        !          1275:           without messing up if the language is not C.  */
        !          1276:        if (TYPE_NAME (type) != 0
        !          1277:            && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
        !          1278:            && DECL_NAME (TYPE_NAME (type)) != 0
        !          1279:            && TREE_CODE (DECL_NAME (TYPE_NAME (type))) == IDENTIFIER_NODE)
        !          1280:          {
        !          1281:            char *name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
        !          1282: 
        !          1283:            /* Note that here we can run afowl of a serious bug in "classic"
        !          1284:               svr4 SDB debuggers.  They don't seem to understand the
        !          1285:               FT_ext_prec_float type (even though they should).  */
        !          1286: 
        !          1287:            if (!strcmp (name, "long double"))
        !          1288:              return FT_ext_prec_float;
        !          1289:          }
        !          1290: 
        !          1291:        if (TYPE_PRECISION (type) == DOUBLE_TYPE_SIZE)
        !          1292:          return FT_dbl_prec_float;
        !          1293:        if (TYPE_PRECISION (type) == FLOAT_TYPE_SIZE)
        !          1294:          return FT_float;
        !          1295: 
        !          1296:        /* Note that here we can run afowl of a serious bug in "classic"
        !          1297:           svr4 SDB debuggers.  They don't seem to understand the
        !          1298:           FT_ext_prec_float type (even though they should).  */
        !          1299: 
        !          1300:        if (TYPE_PRECISION (type) == LONG_DOUBLE_TYPE_SIZE)
        !          1301:          return FT_ext_prec_float;
        !          1302:        abort ();
        !          1303: 
        !          1304:       case COMPLEX_TYPE:
        !          1305:        return FT_complex;      /* GNU FORTRAN COMPLEX type.  */
        !          1306: 
        !          1307:       case CHAR_TYPE:
        !          1308:        return FT_char;         /* GNU Pascal CHAR type.  Not used in C.  */
        !          1309: 
        !          1310:       case BOOLEAN_TYPE:
        !          1311:        return FT_boolean;      /* GNU FORTRAN BOOLEAN type.  */
        !          1312: 
        !          1313:       default:
        !          1314:        abort ();       /* No other TREE_CODEs are Dwarf fundamental types.  */
        !          1315:     }
        !          1316:   return 0;
        !          1317: }
        !          1318: 
        !          1319: /* Given a pointer to an arbitrary ..._TYPE tree node, return a pointer to
        !          1320:    the Dwarf "root" type for the given input type.  The Dwarf "root" type
        !          1321:    of a given type is generally the same as the given type, except that if
        !          1322:    the given type is a pointer or reference type, then the root type of
        !          1323:    the given type is the root type of the "basis" type for the pointer or
        !          1324:    reference type.  (This definition of the "root" type is recursive.)
        !          1325:    Also, the root type of a `const' qualified type or a `volatile'
        !          1326:    qualified type is the root type of the given type without the
        !          1327:    qualifiers.  */
        !          1328: 
        !          1329: static tree
        !          1330: root_type (type)
        !          1331:      register tree type;
        !          1332: {
        !          1333:   if (TREE_CODE (type) == ERROR_MARK)
        !          1334:     return error_mark_node;
        !          1335: 
        !          1336:   switch (TREE_CODE (type))
        !          1337:     {
        !          1338:       case ERROR_MARK:
        !          1339:        return error_mark_node;
        !          1340: 
        !          1341:       case POINTER_TYPE:
        !          1342:       case REFERENCE_TYPE:
        !          1343:        return type_main_variant (root_type (TREE_TYPE (type)));
        !          1344: 
        !          1345:       default:
        !          1346:        return type_main_variant (type);
        !          1347:     }
        !          1348: }
        !          1349: 
        !          1350: /* Given a pointer to an arbitrary ..._TYPE tree node, write out a sequence
        !          1351:    of zero or more Dwarf "type-modifier" bytes applicable to the type. */
        !          1352: 
        !          1353: static void
        !          1354: write_modifier_bytes (type, decl_const, decl_volatile)
        !          1355:      register tree type;
        !          1356:      register int decl_const;
        !          1357:      register int decl_volatile;
        !          1358: {
        !          1359:   if (TREE_CODE (type) == ERROR_MARK)
        !          1360:     return;
        !          1361: 
        !          1362:   if (TYPE_READONLY (type) || decl_const)
        !          1363:     ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_const);
        !          1364:   if (TYPE_VOLATILE (type) || decl_volatile)
        !          1365:     ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_volatile);
        !          1366:   switch (TREE_CODE (type))
        !          1367:     {
        !          1368:       case POINTER_TYPE:
        !          1369:        ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_pointer_to);
        !          1370:        write_modifier_bytes (TREE_TYPE (type), 0, 0);
        !          1371:        return;
        !          1372: 
        !          1373:       case REFERENCE_TYPE:
        !          1374:        ASM_OUTPUT_DWARF_TYPE_MODIFIER (asm_out_file, MOD_reference_to);
        !          1375:        write_modifier_bytes (TREE_TYPE (type), 0, 0);
        !          1376:        return;
        !          1377: 
        !          1378:       case ERROR_MARK:
        !          1379:       default:
        !          1380:        return;
        !          1381:     }
        !          1382: }
        !          1383: 
        !          1384: /* Given a pointer to an arbitrary ..._TYPE tree node, return non-zero if the
        !          1385:    given input type is a Dwarf "fundamental" type.  Otherwise return zero.  */
        !          1386: 
        !          1387: inline int
        !          1388: type_is_fundamental (type)
        !          1389:      register tree type;
        !          1390: {
        !          1391:   switch (TREE_CODE (type))
        !          1392:     {
        !          1393:       case ERROR_MARK:
        !          1394:       case VOID_TYPE:
        !          1395:       case INTEGER_TYPE:
        !          1396:       case REAL_TYPE:
        !          1397:       case COMPLEX_TYPE:
        !          1398:       case BOOLEAN_TYPE:
        !          1399:       case CHAR_TYPE:
        !          1400:        return 1;
        !          1401: 
        !          1402:       case SET_TYPE:
        !          1403:       case ARRAY_TYPE:
        !          1404:       case RECORD_TYPE:
        !          1405:       case UNION_TYPE:
        !          1406:       case QUAL_UNION_TYPE:
        !          1407:       case ENUMERAL_TYPE:
        !          1408:       case FUNCTION_TYPE:
        !          1409:       case METHOD_TYPE:
        !          1410:       case POINTER_TYPE:
        !          1411:       case REFERENCE_TYPE:
        !          1412:       case STRING_TYPE:
        !          1413:       case FILE_TYPE:
        !          1414:       case OFFSET_TYPE:
        !          1415:       case LANG_TYPE:
        !          1416:        return 0;
        !          1417: 
        !          1418:       default:
        !          1419:        abort ();
        !          1420:     }
        !          1421:   return 0;
        !          1422: }
        !          1423: 
        !          1424: /* Given a pointer to some ..._DECL tree node, generate an assembly language
        !          1425:    equate directive which will associate a symbolic name with the current DIE.
        !          1426: 
        !          1427:    The name used is an artificial label generated from the DECL_UID number
        !          1428:    associated with the given decl node.  The name it gets equated to is the
        !          1429:    symbolic label that we (previously) output at the start of the DIE that
        !          1430:    we are currently generating.
        !          1431: 
        !          1432:    Calling this function while generating some "decl related" form of DIE
        !          1433:    makes it possible to later refer to the DIE which represents the given
        !          1434:    decl simply by re-generating the symbolic name from the ..._DECL node's
        !          1435:    UID number. */
        !          1436: 
        !          1437: static void
        !          1438: equate_decl_number_to_die_number (decl)
        !          1439:      register tree decl;
        !          1440: {
        !          1441:   /* In the case where we are generating a DIE for some ..._DECL node
        !          1442:      which represents either some inline function declaration or some
        !          1443:      entity declared within an inline function declaration/definition,
        !          1444:      setup a symbolic name for the current DIE so that we have a name
        !          1445:      for this DIE that we can easily refer to later on within
        !          1446:      AT_abstract_origin attributes.  */
        !          1447: 
        !          1448:   char decl_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1449:   char die_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1450: 
        !          1451:   sprintf (decl_label, DECL_NAME_FMT, DECL_UID (decl));
        !          1452:   sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum);
        !          1453:   ASM_OUTPUT_DEF (asm_out_file, decl_label, die_label);
        !          1454: }
        !          1455: 
        !          1456: /* Given a pointer to some ..._TYPE tree node, generate an assembly language
        !          1457:    equate directive which will associate a symbolic name with the current DIE.
        !          1458: 
        !          1459:    The name used is an artificial label generated from the TYPE_UID number
        !          1460:    associated with the given type node.  The name it gets equated to is the
        !          1461:    symbolic label that we (previously) output at the start of the DIE that
        !          1462:    we are currently generating.
        !          1463: 
        !          1464:    Calling this function while generating some "type related" form of DIE
        !          1465:    makes it easy to later refer to the DIE which represents the given type
        !          1466:    simply by re-generating the alternative name from the ..._TYPE node's
        !          1467:    UID number. */
        !          1468: 
        !          1469: inline void
        !          1470: equate_type_number_to_die_number (type)
        !          1471:      register tree type;
        !          1472: {
        !          1473:   char type_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1474:   char die_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1475: 
        !          1476:   /* We are generating a DIE to represent the main variant of this type
        !          1477:      (i.e the type without any const or volatile qualifiers) so in order
        !          1478:      to get the equate to come out right, we need to get the main variant
        !          1479:      itself here.  */
        !          1480: 
        !          1481:   type = type_main_variant (type);
        !          1482: 
        !          1483:   sprintf (type_label, TYPE_NAME_FMT, TYPE_UID (type));
        !          1484:   sprintf (die_label, DIE_BEGIN_LABEL_FMT, current_dienum);
        !          1485:   ASM_OUTPUT_DEF (asm_out_file, type_label, die_label);
        !          1486: }
        !          1487: 
        !          1488: static void
        !          1489: output_reg_number (rtl)
        !          1490:      register rtx rtl;
        !          1491: {
        !          1492:   register unsigned regno = REGNO (rtl);
        !          1493: 
        !          1494:   if (regno >= FIRST_PSEUDO_REGISTER)
        !          1495:     {
        !          1496:       warning_with_decl (dwarf_last_decl, "internal regno botch: regno = %d\n",
        !          1497:                         regno);
        !          1498:       regno = 0;
        !          1499:     }
        !          1500:   fprintf (asm_out_file, "\t%s\t0x%x",
        !          1501:           UNALIGNED_INT_ASM_OP, DBX_REGISTER_NUMBER (regno));
        !          1502:   if (flag_verbose_asm)
        !          1503:     {
        !          1504:       fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START);
        !          1505:       PRINT_REG (rtl, 0, asm_out_file);
        !          1506:     }
        !          1507:   fputc ('\n', asm_out_file);
        !          1508: }
        !          1509: 
        !          1510: /* The following routine is a nice and simple transducer.  It converts the
        !          1511:    RTL for a variable or parameter (resident in memory) into an equivalent
        !          1512:    Dwarf representation of a mechanism for getting the address of that same
        !          1513:    variable onto the top of a hypothetical "address evaluation" stack.
        !          1514: 
        !          1515:    When creating memory location descriptors, we are effectively trans-
        !          1516:    forming the RTL for a memory-resident object into its Dwarf postfix
        !          1517:    expression equivalent.  This routine just recursively descends an
        !          1518:    RTL tree, turning it into Dwarf postfix code as it goes.  */
        !          1519: 
        !          1520: static void
        !          1521: output_mem_loc_descriptor (rtl)
        !          1522:       register rtx rtl;
        !          1523: {
        !          1524:   /* Note that for a dynamically sized array, the location we will
        !          1525:      generate a description of here will be the lowest numbered location
        !          1526:      which is actually within the array.  That's *not* necessarily the
        !          1527:      same as the zeroth element of the array.  */
        !          1528: 
        !          1529:   switch (GET_CODE (rtl))
        !          1530:     {
        !          1531:       case SUBREG:
        !          1532: 
        !          1533:        /* The case of a subreg may arise when we have a local (register)
        !          1534:           variable or a formal (register) parameter which doesn't quite
        !          1535:           fill up an entire register.  For now, just assume that it is
        !          1536:           legitimate to make the Dwarf info refer to the whole register
        !          1537:           which contains the given subreg.  */
        !          1538: 
        !          1539:        rtl = XEXP (rtl, 0);
        !          1540:        /* Drop thru.  */
        !          1541: 
        !          1542:       case REG:
        !          1543: 
        !          1544:        /* Whenever a register number forms a part of the description of
        !          1545:           the method for calculating the (dynamic) address of a memory
        !          1546:           resident object, DWARF rules require the register number to
        !          1547:           be referred to as a "base register".  This distinction is not
        !          1548:           based in any way upon what category of register the hardware
        !          1549:           believes the given register belongs to.  This is strictly
        !          1550:           DWARF terminology we're dealing with here.
        !          1551: 
        !          1552:           Note that in cases where the location of a memory-resident data
        !          1553:           object could be expressed as:
        !          1554: 
        !          1555:                    OP_ADD (OP_BASEREG (basereg), OP_CONST (0))
        !          1556: 
        !          1557:           the actual DWARF location descriptor that we generate may just
        !          1558:           be OP_BASEREG (basereg).  This may look deceptively like the
        !          1559:           object in question was allocated to a register (rather than
        !          1560:           in memory) so DWARF consumers need to be aware of the subtle
        !          1561:           distinction between OP_REG and OP_BASEREG.  */
        !          1562: 
        !          1563:        ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_BASEREG);
        !          1564:        output_reg_number (rtl);
        !          1565:        break;
        !          1566: 
        !          1567:       case MEM:
        !          1568:        output_mem_loc_descriptor (XEXP (rtl, 0));
        !          1569:        ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_DEREF4);
        !          1570:        break;
        !          1571: 
        !          1572:       case CONST:
        !          1573:       case SYMBOL_REF:
        !          1574:        ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADDR);
        !          1575:        ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl);
        !          1576:        break;
        !          1577: 
        !          1578:       case PLUS:
        !          1579:        output_mem_loc_descriptor (XEXP (rtl, 0));
        !          1580:        output_mem_loc_descriptor (XEXP (rtl, 1));
        !          1581:        ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD);
        !          1582:        break;
        !          1583: 
        !          1584:       case CONST_INT:
        !          1585:        ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST);
        !          1586:        ASM_OUTPUT_DWARF_DATA4 (asm_out_file, INTVAL (rtl));
        !          1587:        break;
        !          1588: 
        !          1589:       default:
        !          1590:        abort ();
        !          1591:     }
        !          1592: }
        !          1593: 
        !          1594: /* Output a proper Dwarf location descriptor for a variable or parameter
        !          1595:    which is either allocated in a register or in a memory location.  For
        !          1596:    a register, we just generate an OP_REG and the register number.  For a
        !          1597:    memory location we provide a Dwarf postfix expression describing how to
        !          1598:    generate the (dynamic) address of the object onto the address stack.  */
        !          1599: 
        !          1600: static void
        !          1601: output_loc_descriptor (rtl)
        !          1602:      register rtx rtl;
        !          1603: {
        !          1604:   switch (GET_CODE (rtl))
        !          1605:     {
        !          1606:     case SUBREG:
        !          1607: 
        !          1608:        /* The case of a subreg may arise when we have a local (register)
        !          1609:           variable or a formal (register) parameter which doesn't quite
        !          1610:           fill up an entire register.  For now, just assume that it is
        !          1611:           legitimate to make the Dwarf info refer to the whole register
        !          1612:           which contains the given subreg.  */
        !          1613: 
        !          1614:        rtl = XEXP (rtl, 0);
        !          1615:        /* Drop thru.  */
        !          1616: 
        !          1617:     case REG:
        !          1618:        ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_REG);
        !          1619:        output_reg_number (rtl);
        !          1620:        break;
        !          1621: 
        !          1622:     case MEM:
        !          1623:       output_mem_loc_descriptor (XEXP (rtl, 0));
        !          1624:       break;
        !          1625: 
        !          1626:     default:
        !          1627:       abort ();                /* Should never happen */
        !          1628:     }
        !          1629: }
        !          1630: 
        !          1631: /* Given a tree node describing an array bound (either lower or upper)
        !          1632:    output a representation for that bound.  */
        !          1633: 
        !          1634: static void
        !          1635: output_bound_representation (bound, dim_num, u_or_l)
        !          1636:      register tree bound;
        !          1637:      register unsigned dim_num; /* For multi-dimensional arrays.  */
        !          1638:      register char u_or_l;     /* Designates upper or lower bound.  */
        !          1639: {
        !          1640:   switch (TREE_CODE (bound))
        !          1641:     {
        !          1642: 
        !          1643:       case ERROR_MARK:
        !          1644:        return;
        !          1645: 
        !          1646:       /* All fixed-bounds are represented by INTEGER_CST nodes.         */
        !          1647: 
        !          1648:       case INTEGER_CST:
        !          1649:        ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
        !          1650:                                (unsigned) TREE_INT_CST_LOW (bound));
        !          1651:        break;
        !          1652: 
        !          1653:       /* Dynamic bounds may be represented by NOP_EXPR nodes containing
        !          1654:         SAVE_EXPR nodes.  */
        !          1655: 
        !          1656:       case NOP_EXPR:
        !          1657:        bound = TREE_OPERAND (bound, 0);
        !          1658:        /* ... fall thru... */
        !          1659: 
        !          1660:       case SAVE_EXPR:
        !          1661:        {
        !          1662:          char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1663:          char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1664: 
        !          1665:          sprintf (begin_label, BOUND_BEGIN_LABEL_FMT,
        !          1666:                                current_dienum, dim_num, u_or_l);
        !          1667: 
        !          1668:          sprintf (end_label,   BOUND_END_LABEL_FMT,
        !          1669:                                current_dienum, dim_num, u_or_l);
        !          1670: 
        !          1671:          ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          1672:          ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          1673: 
        !          1674:          /* If we are working on a bound for a dynamic dimension in C,
        !          1675:             the dynamic dimension in question had better have a static
        !          1676:             (zero) lower bound and a dynamic *upper* bound.  */
        !          1677: 
        !          1678:          if (u_or_l != 'u')
        !          1679:            abort ();
        !          1680: 
        !          1681:          /* If optimization is turned on, the SAVE_EXPRs that describe
        !          1682:             how to access the upper bound values are essentially bogus.
        !          1683:             They only describe (at best) how to get at these values at
        !          1684:             the points in the generated code right after they have just
        !          1685:             been computed.  Worse yet, in the typical case, the upper
        !          1686:             bound values will not even *be* computed in the optimized
        !          1687:             code, so these SAVE_EXPRs are entirely bogus.
        !          1688: 
        !          1689:             In order to compensate for this fact, we check here to see
        !          1690:             if optimization is enabled, and if so, we effectively create
        !          1691:             an empty location description for the (unknown and unknowable)
        !          1692:             upper bound.
        !          1693: 
        !          1694:             This should not cause too much trouble for existing (stupid?)
        !          1695:             debuggers because they have to deal with empty upper bounds
        !          1696:             location descriptions anyway in order to be able to deal with
        !          1697:             incomplete array types.
        !          1698: 
        !          1699:             Of course an intelligent debugger (GDB?) should be able to
        !          1700:             comprehend that a missing upper bound specification in a
        !          1701:             array type used for a storage class `auto' local array variable
        !          1702:             indicates that the upper bound is both unknown (at compile-
        !          1703:             time) and unknowable (at run-time) due to optimization.
        !          1704:          */
        !          1705: 
        !          1706:          if (! optimize)
        !          1707:            output_loc_descriptor
        !          1708:              (eliminate_regs (SAVE_EXPR_RTL (bound), 0, NULL_RTX));
        !          1709: 
        !          1710:          ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          1711:        }
        !          1712:        break;
        !          1713: 
        !          1714:       default:
        !          1715:        abort ();
        !          1716:     }
        !          1717: }
        !          1718: 
        !          1719: /* Recursive function to output a sequence of value/name pairs for
        !          1720:    enumeration constants in reversed order.  This is called from
        !          1721:    enumeration_type_die.  */
        !          1722: 
        !          1723: static void
        !          1724: output_enumeral_list (link)
        !          1725:      register tree link;
        !          1726: {
        !          1727:   if (link)
        !          1728:     {
        !          1729:       output_enumeral_list (TREE_CHAIN (link));
        !          1730:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
        !          1731:                              (unsigned) TREE_INT_CST_LOW (TREE_VALUE (link)));
        !          1732:       ASM_OUTPUT_DWARF_STRING (asm_out_file,
        !          1733:                               IDENTIFIER_POINTER (TREE_PURPOSE (link)));
        !          1734:     }
        !          1735: }
        !          1736: 
        !          1737: /* Given an unsigned value, round it up to the lowest multiple of `boundary'
        !          1738:    which is not less than the value itself.  */
        !          1739: 
        !          1740: inline unsigned
        !          1741: ceiling (value, boundary)
        !          1742:      register unsigned value;
        !          1743:      register unsigned boundary;
        !          1744: {
        !          1745:   return (((value + boundary - 1) / boundary) * boundary);
        !          1746: }
        !          1747: 
        !          1748: /* Given a pointer to what is assumed to be a FIELD_DECL node, return a
        !          1749:    pointer to the declared type for the relevant field variable, or return
        !          1750:    `integer_type_node' if the given node turns out to be an ERROR_MARK node.  */
        !          1751: 
        !          1752: inline tree
        !          1753: field_type (decl)
        !          1754:      register tree decl;
        !          1755: {
        !          1756:   register tree type;
        !          1757: 
        !          1758:   if (TREE_CODE (decl) == ERROR_MARK)
        !          1759:     return integer_type_node;
        !          1760: 
        !          1761:   type = DECL_BIT_FIELD_TYPE (decl);
        !          1762:   if (type == NULL)
        !          1763:     type = TREE_TYPE (decl);
        !          1764:   return type;
        !          1765: }
        !          1766: 
        !          1767: /* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
        !          1768:    node, return the alignment in bits for the type, or else return
        !          1769:    BITS_PER_WORD if the node actually turns out to be an ERROR_MARK node.  */
        !          1770: 
        !          1771: inline unsigned
        !          1772: simple_type_align_in_bits (type)
        !          1773:      register tree type;
        !          1774: {
        !          1775:   return (TREE_CODE (type) != ERROR_MARK) ? TYPE_ALIGN (type) : BITS_PER_WORD;
        !          1776: }
        !          1777: 
        !          1778: /* Given a pointer to a tree node, assumed to be some kind of a ..._TYPE
        !          1779:    node, return the size in bits for the type if it is a constant, or
        !          1780:    else return the alignment for the type if the type's size is not
        !          1781:    constant, or else return BITS_PER_WORD if the type actually turns out
        !          1782:    to be an ERROR_MARK node.  */
        !          1783: 
        !          1784: inline unsigned
        !          1785: simple_type_size_in_bits (type)
        !          1786:      register tree type;
        !          1787: {
        !          1788:   if (TREE_CODE (type) == ERROR_MARK)
        !          1789:     return BITS_PER_WORD;
        !          1790:   else
        !          1791:     {
        !          1792:       register tree type_size_tree = TYPE_SIZE (type);
        !          1793: 
        !          1794:       if (TREE_CODE (type_size_tree) != INTEGER_CST)
        !          1795:        return TYPE_ALIGN (type);
        !          1796: 
        !          1797:       return (unsigned) TREE_INT_CST_LOW (type_size_tree);
        !          1798:     }
        !          1799: }
        !          1800: 
        !          1801: /* Given a pointer to what is assumed to be a FIELD_DECL node, compute and
        !          1802:    return the byte offset of the lowest addressed byte of the "containing
        !          1803:    object" for the given FIELD_DECL, or return 0 if we are unable to deter-
        !          1804:    mine what that offset is, either because the argument turns out to be a
        !          1805:    pointer to an ERROR_MARK node, or because the offset is actually variable.
        !          1806:    (We can't handle the latter case just yet.)  */
        !          1807: 
        !          1808: static unsigned
        !          1809: field_byte_offset (decl)
        !          1810:      register tree decl;
        !          1811: {
        !          1812:   register unsigned type_align_in_bytes;
        !          1813:   register unsigned type_align_in_bits;
        !          1814:   register unsigned type_size_in_bits;
        !          1815:   register unsigned object_offset_in_align_units;
        !          1816:   register unsigned object_offset_in_bits;
        !          1817:   register unsigned object_offset_in_bytes;
        !          1818:   register tree type;
        !          1819:   register tree bitpos_tree;
        !          1820:   register tree field_size_tree;
        !          1821:   register unsigned bitpos_int;
        !          1822:   register unsigned deepest_bitpos;
        !          1823:   register unsigned field_size_in_bits;
        !          1824: 
        !          1825:   if (TREE_CODE (decl) == ERROR_MARK)
        !          1826:     return 0;
        !          1827: 
        !          1828:   if (TREE_CODE (decl) != FIELD_DECL)
        !          1829:     abort ();
        !          1830: 
        !          1831:   type = field_type (decl);
        !          1832: 
        !          1833:   bitpos_tree = DECL_FIELD_BITPOS (decl);
        !          1834:   field_size_tree = DECL_SIZE (decl);
        !          1835: 
        !          1836:   /* We cannot yet cope with fields whose positions or sizes are variable,
        !          1837:      so for now, when we see such things, we simply return 0.  Someday,
        !          1838:      we may be able to handle such cases, but it will be damn difficult.  */
        !          1839: 
        !          1840:   if (TREE_CODE (bitpos_tree) != INTEGER_CST)
        !          1841:     return 0;
        !          1842:   bitpos_int = (unsigned) TREE_INT_CST_LOW (bitpos_tree);
        !          1843: 
        !          1844:   if (TREE_CODE (field_size_tree) != INTEGER_CST)
        !          1845:     return 0;
        !          1846:   field_size_in_bits = (unsigned) TREE_INT_CST_LOW (field_size_tree);
        !          1847: 
        !          1848:   type_size_in_bits = simple_type_size_in_bits (type);
        !          1849: 
        !          1850:   type_align_in_bits = simple_type_align_in_bits (type);
        !          1851:   type_align_in_bytes = type_align_in_bits / BITS_PER_UNIT;
        !          1852: 
        !          1853:   /* Note that the GCC front-end doesn't make any attempt to keep track
        !          1854:      of the starting bit offset (relative to the start of the containing
        !          1855:      structure type) of the hypothetical "containing object" for a bit-
        !          1856:      field.  Thus, when computing the byte offset value for the start of
        !          1857:      the "containing object" of a bit-field, we must deduce this infor-
        !          1858:      mation on our own.
        !          1859: 
        !          1860:      This can be rather tricky to do in some cases.  For example, handling
        !          1861:      the following structure type definition when compiling for an i386/i486
        !          1862:      target (which only aligns long long's to 32-bit boundaries) can be very
        !          1863:      tricky:
        !          1864: 
        !          1865:                struct S {
        !          1866:                        int             field1;
        !          1867:                        long long       field2:31;
        !          1868:                };
        !          1869: 
        !          1870:      Fortunately, there is a simple rule-of-thumb which can be used in such
        !          1871:      cases.  When compiling for an i386/i486, GCC will allocate 8 bytes for
        !          1872:      the structure shown above.  It decides to do this based upon one simple
        !          1873:      rule for bit-field allocation.  Quite simply, GCC allocates each "con-
        !          1874:      taining object" for each bit-field at the first (i.e. lowest addressed)
        !          1875:      legitimate alignment boundary (based upon the required minimum alignment
        !          1876:      for the declared type of the field) which it can possibly use, subject
        !          1877:      to the condition that there is still enough available space remaining
        !          1878:      in the containing object (when allocated at the selected point) to
        !          1879:      fully accommodate all of the bits of the bit-field itself.
        !          1880: 
        !          1881:      This simple rule makes it obvious why GCC allocates 8 bytes for each
        !          1882:      object of the structure type shown above.  When looking for a place to
        !          1883:      allocate the "containing object" for `field2', the compiler simply tries
        !          1884:      to allocate a 64-bit "containing object" at each successive 32-bit
        !          1885:      boundary (starting at zero) until it finds a place to allocate that 64-
        !          1886:      bit field such that at least 31 contiguous (and previously unallocated)
        !          1887:      bits remain within that selected 64 bit field.  (As it turns out, for
        !          1888:      the example above, the compiler finds that it is OK to allocate the
        !          1889:      "containing object" 64-bit field at bit-offset zero within the
        !          1890:      structure type.)
        !          1891: 
        !          1892:      Here we attempt to work backwards from the limited set of facts we're
        !          1893:      given, and we try to deduce from those facts, where GCC must have
        !          1894:      believed that the containing object started (within the structure type).
        !          1895: 
        !          1896:      The value we deduce is then used (by the callers of this routine) to
        !          1897:      generate AT_location and AT_bit_offset attributes for fields (both
        !          1898:      bit-fields and, in the case of AT_location, regular fields as well).
        !          1899:   */
        !          1900: 
        !          1901:   /* Figure out the bit-distance from the start of the structure to the
        !          1902:      "deepest" bit of the bit-field.  */
        !          1903:   deepest_bitpos = bitpos_int + field_size_in_bits;
        !          1904: 
        !          1905:   /* This is the tricky part.  Use some fancy footwork to deduce where the
        !          1906:      lowest addressed bit of the containing object must be.  */
        !          1907:   object_offset_in_bits
        !          1908:     = ceiling (deepest_bitpos, type_align_in_bits) - type_size_in_bits;
        !          1909: 
        !          1910:   /* Compute the offset of the containing object in "alignment units".  */
        !          1911:   object_offset_in_align_units = object_offset_in_bits / type_align_in_bits;
        !          1912: 
        !          1913:   /* Compute the offset of the containing object in bytes.  */
        !          1914:   object_offset_in_bytes = object_offset_in_align_units * type_align_in_bytes;
        !          1915: 
        !          1916:   return object_offset_in_bytes;
        !          1917: }
        !          1918: 
        !          1919: /****************************** attributes *********************************/
        !          1920: 
        !          1921: /* The following routines are responsible for writing out the various types
        !          1922:    of Dwarf attributes (and any following data bytes associated with them).
        !          1923:    These routines are listed in order based on the numerical codes of their
        !          1924:    associated attributes.  */
        !          1925: 
        !          1926: /* Generate an AT_sibling attribute.  */
        !          1927: 
        !          1928: inline void
        !          1929: sibling_attribute ()
        !          1930: {
        !          1931:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1932: 
        !          1933:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_sibling);
        !          1934:   sprintf (label, DIE_BEGIN_LABEL_FMT, NEXT_DIE_NUM);
        !          1935:   ASM_OUTPUT_DWARF_REF (asm_out_file, label);
        !          1936: }
        !          1937: 
        !          1938: /* Output the form of location attributes suitable for whole variables and
        !          1939:    whole parameters.  Note that the location attributes for struct fields
        !          1940:    are generated by the routine `data_member_location_attribute' below.  */
        !          1941: 
        !          1942: static void
        !          1943: location_attribute (rtl)
        !          1944:      register rtx rtl;
        !          1945: {
        !          1946:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1947:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          1948: 
        !          1949:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location);
        !          1950:   sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum);
        !          1951:   sprintf (end_label, LOC_END_LABEL_FMT, current_dienum);
        !          1952:   ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          1953:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          1954: 
        !          1955:   /* Handle a special case.  If we are about to output a location descriptor
        !          1956:      for a variable or parameter which has been optimized out of existence,
        !          1957:      don't do that.  Instead we output a zero-length location descriptor
        !          1958:      value as part of the location attribute.
        !          1959: 
        !          1960:      A variable which has been optimized out of existence will have a
        !          1961:      DECL_RTL value which denotes a pseudo-reg.
        !          1962: 
        !          1963:      Currently, in some rare cases, variables can have DECL_RTL values
        !          1964:      which look like (MEM (REG pseudo-reg#)).  These cases are due to
        !          1965:      bugs elsewhere in the compiler.  We treat such cases
        !          1966:      as if the variable(s) in question had been optimized out of existence.
        !          1967: 
        !          1968:      Note that in all cases where we wish to express the fact that a
        !          1969:      variable has been optimized out of existence, we do not simply
        !          1970:      suppress the generation of the entire location attribute because
        !          1971:      the absence of a location attribute in certain kinds of DIEs is
        !          1972:      used to indicate something else entirely... i.e. that the DIE
        !          1973:      represents an object declaration, but not a definition.  So sayeth
        !          1974:      the PLSIG.
        !          1975:   */
        !          1976: 
        !          1977:   if (! is_pseudo_reg (rtl)
        !          1978:       && (GET_CODE (rtl) != MEM || ! is_pseudo_reg (XEXP (rtl, 0))))
        !          1979:     output_loc_descriptor (eliminate_regs (rtl, 0, NULL_RTX));
        !          1980: 
        !          1981:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          1982: }
        !          1983: 
        !          1984: /* Output the specialized form of location attribute used for data members
        !          1985:    of struct and union types.
        !          1986: 
        !          1987:    In the special case of a FIELD_DECL node which represents a bit-field,
        !          1988:    the "offset" part of this special location descriptor must indicate the
        !          1989:    distance in bytes from the lowest-addressed byte of the containing
        !          1990:    struct or union type to the lowest-addressed byte of the "containing
        !          1991:    object" for the bit-field.  (See the `field_byte_offset' function above.)
        !          1992: 
        !          1993:    For any given bit-field, the "containing object" is a hypothetical
        !          1994:    object (of some integral or enum type) within which the given bit-field
        !          1995:    lives.  The type of this hypothetical "containing object" is always the
        !          1996:    same as the declared type of the individual bit-field itself (for GCC
        !          1997:    anyway... the DWARF spec doesn't actually mandate this).
        !          1998: 
        !          1999:    Note that it is the size (in bytes) of the hypothetical "containing
        !          2000:    object" which will be given in the AT_byte_size attribute for this
        !          2001:    bit-field.  (See the `byte_size_attribute' function below.)  It is
        !          2002:    also used when calculating the value of the AT_bit_offset attribute.
        !          2003:    (See the `bit_offset_attribute' function below.)
        !          2004: */
        !          2005: 
        !          2006: static void
        !          2007: data_member_location_attribute (decl)
        !          2008:      register tree decl;
        !          2009: {
        !          2010:   register unsigned object_offset_in_bytes = field_byte_offset (decl);
        !          2011:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2012:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2013: 
        !          2014:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_location);
        !          2015:   sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum);
        !          2016:   sprintf (end_label, LOC_END_LABEL_FMT, current_dienum);
        !          2017:   ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          2018:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2019:   ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_CONST);
        !          2020:   ASM_OUTPUT_DWARF_DATA4 (asm_out_file, object_offset_in_bytes);
        !          2021:   ASM_OUTPUT_DWARF_STACK_OP (asm_out_file, OP_ADD);
        !          2022:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2023: }
        !          2024: 
        !          2025: /* Output an AT_const_value attribute for a variable or a parameter which
        !          2026:    does not have a "location" either in memory or in a register.  These
        !          2027:    things can arise in GNU C when a constant is passed as an actual
        !          2028:    parameter to an inlined function.  They can also arise in C++ where
        !          2029:    declared constants do not necessarily get memory "homes".  */
        !          2030: 
        !          2031: static void
        !          2032: const_value_attribute (rtl)
        !          2033:      register rtx rtl;
        !          2034: {
        !          2035:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2036:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2037: 
        !          2038:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_const_value_block4);
        !          2039:   sprintf (begin_label, LOC_BEGIN_LABEL_FMT, current_dienum);
        !          2040:   sprintf (end_label, LOC_END_LABEL_FMT, current_dienum);
        !          2041:   ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label);
        !          2042:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2043: 
        !          2044:   switch (GET_CODE (rtl))
        !          2045:     {
        !          2046:       case CONST_INT:
        !          2047:        /* Note that a CONST_INT rtx could represent either an integer or
        !          2048:           a floating-point constant.  A CONST_INT is used whenever the
        !          2049:           constant will fit into a single word.  In all such cases, the
        !          2050:           original mode of the constant value is wiped out, and the
        !          2051:           CONST_INT rtx is assigned VOIDmode.  Since we no longer have
        !          2052:           precise mode information for these constants, we always just
        !          2053:           output them using 4 bytes.  */
        !          2054: 
        !          2055:        ASM_OUTPUT_DWARF_DATA4 (asm_out_file, (unsigned) INTVAL (rtl));
        !          2056:        break;
        !          2057: 
        !          2058:       case CONST_DOUBLE:
        !          2059:        /* Note that a CONST_DOUBLE rtx could represent either an integer
        !          2060:           or a floating-point constant.  A CONST_DOUBLE is used whenever
        !          2061:           the constant requires more than one word in order to be adequately
        !          2062:           represented.  In all such cases, the original mode of the constant
        !          2063:           value is preserved as the mode of the CONST_DOUBLE rtx, but for
        !          2064:           simplicity we always just output CONST_DOUBLEs using 8 bytes.  */
        !          2065: 
        !          2066:        ASM_OUTPUT_DWARF_DATA8 (asm_out_file,
        !          2067:                                (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (rtl),
        !          2068:                                (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (rtl));
        !          2069:        break;
        !          2070: 
        !          2071:       case CONST_STRING:
        !          2072:        ASM_OUTPUT_DWARF_STRING (asm_out_file, XSTR (rtl, 0));
        !          2073:        break;
        !          2074: 
        !          2075:       case SYMBOL_REF:
        !          2076:       case LABEL_REF:
        !          2077:       case CONST:
        !          2078:        ASM_OUTPUT_DWARF_ADDR_CONST (asm_out_file, rtl);
        !          2079:        break;
        !          2080: 
        !          2081:       case PLUS:
        !          2082:        /* In cases where an inlined instance of an inline function is passed
        !          2083:           the address of an `auto' variable (which is local to the caller)
        !          2084:           we can get a situation where the DECL_RTL of the artificial
        !          2085:           local variable (for the inlining) which acts as a stand-in for
        !          2086:           the corresponding formal parameter (of the inline function)
        !          2087:           will look like (plus:SI (reg:SI FRAME_PTR) (const_int ...)).
        !          2088:           This is not exactly a compile-time constant expression, but it
        !          2089:           isn't the address of the (artificial) local variable either.
        !          2090:           Rather, it represents the *value* which the artificial local
        !          2091:           variable always has during its lifetime.  We currently have no
        !          2092:           way to represent such quasi-constant values in Dwarf, so for now
        !          2093:           we just punt and generate an AT_const_value attribute with form
        !          2094:           FORM_BLOCK4 and a length of zero.  */
        !          2095:        break;
        !          2096: 
        !          2097:       default:
        !          2098:        abort ();  /* No other kinds of rtx should be possible here.  */
        !          2099:     }
        !          2100: 
        !          2101:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2102: }
        !          2103: 
        !          2104: /* Generate *either* an AT_location attribute or else an AT_const_value
        !          2105:    data attribute for a variable or a parameter.  We generate the
        !          2106:    AT_const_value attribute only in those cases where the given
        !          2107:    variable or parameter does not have a true "location" either in
        !          2108:    memory or in a register.  This can happen (for example) when a
        !          2109:    constant is passed as an actual argument in a call to an inline
        !          2110:    function.  (It's possible that these things can crop up in other
        !          2111:    ways also.)  Note that one type of constant value which can be
        !          2112:    passed into an inlined function is a constant pointer.  This can
        !          2113:    happen for example if an actual argument in an inlined function
        !          2114:    call evaluates to a compile-time constant address.  */
        !          2115: 
        !          2116: static void
        !          2117: location_or_const_value_attribute (decl)
        !          2118:      register tree decl;
        !          2119: {
        !          2120:   register rtx rtl;
        !          2121: 
        !          2122:   if (TREE_CODE (decl) == ERROR_MARK)
        !          2123:     return;
        !          2124: 
        !          2125:   if ((TREE_CODE (decl) != VAR_DECL) && (TREE_CODE (decl) != PARM_DECL))
        !          2126:     {
        !          2127:       /* Should never happen.  */
        !          2128:       abort ();
        !          2129:       return;
        !          2130:     }
        !          2131: 
        !          2132:   /* Here we have to decide where we are going to say the parameter "lives"
        !          2133:      (as far as the debugger is concerned).  We only have a couple of choices.
        !          2134:      GCC provides us with DECL_RTL and with DECL_INCOMING_RTL.  DECL_RTL
        !          2135:      normally indicates where the parameter lives during most of the activa-
        !          2136:      tion of the function.  If optimization is enabled however, this could
        !          2137:      be either NULL or else a pseudo-reg.  Both of those cases indicate that
        !          2138:      the parameter doesn't really live anywhere (as far as the code generation
        !          2139:      parts of GCC are concerned) during most of the function's activation.
        !          2140:      That will happen (for example) if the parameter is never referenced
        !          2141:      within the function.
        !          2142: 
        !          2143:      We could just generate a location descriptor here for all non-NULL
        !          2144:      non-pseudo values of DECL_RTL and ignore all of the rest, but we can
        !          2145:      be a little nicer than that if we also consider DECL_INCOMING_RTL in
        !          2146:      cases where DECL_RTL is NULL or is a pseudo-reg.
        !          2147: 
        !          2148:      Note however that we can only get away with using DECL_INCOMING_RTL as
        !          2149:      a backup substitute for DECL_RTL in certain limited cases.  In cases
        !          2150:      where DECL_ARG_TYPE(decl) indicates the same type as TREE_TYPE(decl)
        !          2151:      we can be sure that the parameter was passed using the same type as it
        !          2152:      is declared to have within the function, and that its DECL_INCOMING_RTL
        !          2153:      points us to a place where a value of that type is passed.  In cases
        !          2154:      where DECL_ARG_TYPE(decl) and TREE_TYPE(decl) are different types
        !          2155:      however, we cannot (in general) use DECL_INCOMING_RTL as a backup
        !          2156:      substitute for DECL_RTL because in these cases, DECL_INCOMING_RTL
        !          2157:      points us to a value of some type which is *different* from the type
        !          2158:      of the parameter itself.  Thus, if we tried to use DECL_INCOMING_RTL
        !          2159:      to generate a location attribute in such cases, the debugger would
        !          2160:      end up (for example) trying to fetch a `float' from a place which
        !          2161:      actually contains the first part of a `double'.  That would lead to
        !          2162:      really incorrect and confusing output at debug-time, and we don't
        !          2163:      want that now do we?
        !          2164: 
        !          2165:      So in general, we DO NOT use DECL_INCOMING_RTL as a backup for DECL_RTL
        !          2166:      in cases where DECL_ARG_TYPE(decl) != TREE_TYPE(decl).  There are a
        !          2167:      couple of cute exceptions however.  On little-endian machines we can
        !          2168:      get away with using DECL_INCOMING_RTL even when DECL_ARG_TYPE(decl) is
        !          2169:      not the same as TREE_TYPE(decl) but only when DECL_ARG_TYPE(decl) is
        !          2170:      an integral type which is smaller than TREE_TYPE(decl).  These cases
        !          2171:      arise when (on a little-endian machine) a non-prototyped function has
        !          2172:      a parameter declared to be of type `short' or `char'.  In such cases,
        !          2173:      TREE_TYPE(decl) will be `short' or `char', DECL_ARG_TYPE(decl) will be
        !          2174:      `int', and DECL_INCOMING_RTL will point to the lowest-order byte of the
        !          2175:      passed `int' value.  If the debugger then uses that address to fetch a
        !          2176:      `short' or a `char' (on a little-endian machine) the result will be the
        !          2177:      correct data, so we allow for such exceptional cases below.
        !          2178: 
        !          2179:      Note that our goal here is to describe the place where the given formal
        !          2180:      parameter lives during most of the function's activation (i.e. between
        !          2181:      the end of the prologue and the start of the epilogue).  We'll do that
        !          2182:      as best as we can.  Note however that if the given formal parameter is
        !          2183:      modified sometime during the execution of the function, then a stack
        !          2184:      backtrace (at debug-time) will show the function as having been called
        !          2185:      with the *new* value rather than the value which was originally passed
        !          2186:      in.  This happens rarely enough that it is not a major problem, but it
        !          2187:      *is* a problem, and I'd like to fix it.  A future version of dwarfout.c
        !          2188:      may generate two additional attributes for any given TAG_formal_parameter
        !          2189:      DIE which will describe the "passed type" and the "passed location" for
        !          2190:      the given formal parameter in addition to the attributes we now generate
        !          2191:      to indicate the "declared type" and the "active location" for each
        !          2192:      parameter.  This additional set of attributes could be used by debuggers
        !          2193:      for stack backtraces.
        !          2194: 
        !          2195:      Separately, note that sometimes DECL_RTL can be NULL and DECL_INCOMING_RTL
        !          2196:      can be NULL also.  This happens (for example) for inlined-instances of
        !          2197:      inline function formal parameters which are never referenced.  This really
        !          2198:      shouldn't be happening.  All PARM_DECL nodes should get valid non-NULL
        !          2199:      DECL_INCOMING_RTL values, but integrate.c doesn't currently generate
        !          2200:      these values for inlined instances of inline function parameters, so
        !          2201:      when we see such cases, we are just SOL (shit-out-of-luck) for the time
        !          2202:      being (until integrate.c gets fixed).
        !          2203:   */
        !          2204: 
        !          2205:   /* Use DECL_RTL as the "location" unless we find something better.  */
        !          2206:   rtl = DECL_RTL (decl);
        !          2207: 
        !          2208:   if (TREE_CODE (decl) == PARM_DECL)
        !          2209:     if (rtl == NULL_RTX || is_pseudo_reg (rtl))
        !          2210:       {
        !          2211:        /* This decl represents a formal parameter which was optimized out.  */
        !          2212:         register tree declared_type = type_main_variant (TREE_TYPE (decl));
        !          2213:         register tree passed_type = type_main_variant (DECL_ARG_TYPE (decl));
        !          2214: 
        !          2215:        /* Note that DECL_INCOMING_RTL may be NULL in here, but we handle
        !          2216:           *all* cases where (rtl == NULL_RTX) just below.  */
        !          2217: 
        !          2218:        if (declared_type == passed_type)
        !          2219:          rtl = DECL_INCOMING_RTL (decl);
        !          2220: #if (BYTES_BIG_ENDIAN == 0)
        !          2221:        else
        !          2222:          if (TREE_CODE (declared_type) == INTEGER_TYPE)
        !          2223:            if (TYPE_SIZE (declared_type) <= TYPE_SIZE (passed_type))
        !          2224:              rtl = DECL_INCOMING_RTL (decl);
        !          2225: #endif /* (BYTES_BIG_ENDIAN == 0) */
        !          2226:       }
        !          2227: 
        !          2228:   if (rtl == NULL_RTX)
        !          2229:     return;
        !          2230: 
        !          2231:   switch (GET_CODE (rtl))
        !          2232:     {
        !          2233:     case CONST_INT:
        !          2234:     case CONST_DOUBLE:
        !          2235:     case CONST_STRING:
        !          2236:     case SYMBOL_REF:
        !          2237:     case LABEL_REF:
        !          2238:     case CONST:
        !          2239:     case PLUS: /* DECL_RTL could be (plus (reg ...) (const_int ...)) */
        !          2240:       const_value_attribute (rtl);
        !          2241:       break;
        !          2242: 
        !          2243:     case MEM:
        !          2244:     case REG:
        !          2245:     case SUBREG:
        !          2246:       location_attribute (rtl);
        !          2247:       break;
        !          2248: 
        !          2249:     default:
        !          2250:       abort ();                /* Should never happen.  */
        !          2251:     }
        !          2252: }
        !          2253: 
        !          2254: /* Generate an AT_name attribute given some string value to be included as
        !          2255:    the value of the attribute. */
        !          2256: 
        !          2257: inline void
        !          2258: name_attribute (name_string)
        !          2259:      register char *name_string;
        !          2260: {
        !          2261:   if (name_string && *name_string)
        !          2262:     {
        !          2263:       ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_name);
        !          2264:       ASM_OUTPUT_DWARF_STRING (asm_out_file, name_string);
        !          2265:     }
        !          2266: }
        !          2267: 
        !          2268: inline void
        !          2269: fund_type_attribute (ft_code)
        !          2270:      register unsigned ft_code;
        !          2271: {
        !          2272:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_fund_type);
        !          2273:   ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, ft_code);
        !          2274: }
        !          2275: 
        !          2276: static void
        !          2277: mod_fund_type_attribute (type, decl_const, decl_volatile)
        !          2278:      register tree type;
        !          2279:      register int decl_const;
        !          2280:      register int decl_volatile;
        !          2281: {
        !          2282:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2283:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2284: 
        !          2285:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mod_fund_type);
        !          2286:   sprintf (begin_label, MT_BEGIN_LABEL_FMT, current_dienum);
        !          2287:   sprintf (end_label, MT_END_LABEL_FMT, current_dienum);
        !          2288:   ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          2289:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2290:   write_modifier_bytes (type, decl_const, decl_volatile);
        !          2291:   ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file,
        !          2292:                              fundamental_type_code (root_type (type)));
        !          2293:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2294: }
        !          2295: 
        !          2296: inline void
        !          2297: user_def_type_attribute (type)
        !          2298:      register tree type;
        !          2299: {
        !          2300:   char ud_type_name[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2301: 
        !          2302:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_user_def_type);
        !          2303:   sprintf (ud_type_name, TYPE_NAME_FMT, TYPE_UID (type));
        !          2304:   ASM_OUTPUT_DWARF_REF (asm_out_file, ud_type_name);
        !          2305: }
        !          2306: 
        !          2307: static void
        !          2308: mod_u_d_type_attribute (type, decl_const, decl_volatile)
        !          2309:      register tree type;
        !          2310:      register int decl_const;
        !          2311:      register int decl_volatile;
        !          2312: {
        !          2313:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2314:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2315:   char ud_type_name[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2316: 
        !          2317:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mod_u_d_type);
        !          2318:   sprintf (begin_label, MT_BEGIN_LABEL_FMT, current_dienum);
        !          2319:   sprintf (end_label, MT_END_LABEL_FMT, current_dienum);
        !          2320:   ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          2321:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2322:   write_modifier_bytes (type, decl_const, decl_volatile);
        !          2323:   sprintf (ud_type_name, TYPE_NAME_FMT, TYPE_UID (root_type (type)));
        !          2324:   ASM_OUTPUT_DWARF_REF (asm_out_file, ud_type_name);
        !          2325:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2326: }
        !          2327: 
        !          2328: #ifdef USE_ORDERING_ATTRIBUTE
        !          2329: inline void
        !          2330: ordering_attribute (ordering)
        !          2331:      register unsigned ordering;
        !          2332: {
        !          2333:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_ordering);
        !          2334:   ASM_OUTPUT_DWARF_DATA2 (asm_out_file, ordering);
        !          2335: }
        !          2336: #endif /* defined(USE_ORDERING_ATTRIBUTE) */
        !          2337: 
        !          2338: /* Note that the block of subscript information for an array type also
        !          2339:    includes information about the element type of type given array type.  */
        !          2340: 
        !          2341: static void
        !          2342: subscript_data_attribute (type)
        !          2343:      register tree type;
        !          2344: {
        !          2345:   register unsigned dimension_number;
        !          2346:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2347:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2348: 
        !          2349:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_subscr_data);
        !          2350:   sprintf (begin_label, SS_BEGIN_LABEL_FMT, current_dienum);
        !          2351:   sprintf (end_label, SS_END_LABEL_FMT, current_dienum);
        !          2352:   ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          2353:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2354: 
        !          2355:   /* The GNU compilers represent multidimensional array types as sequences
        !          2356:      of one dimensional array types whose element types are themselves array
        !          2357:      types.  Here we squish that down, so that each multidimensional array
        !          2358:      type gets only one array_type DIE in the Dwarf debugging info.  The
        !          2359:      draft Dwarf specification say that we are allowed to do this kind
        !          2360:      of compression in C (because there is no difference between an
        !          2361:      array or arrays and a multidimensional array in C) but for other
        !          2362:      source languages (e.g. Ada) we probably shouldn't do this.  */
        !          2363: 
        !          2364:   for (dimension_number = 0;
        !          2365:        TREE_CODE (type) == ARRAY_TYPE;
        !          2366:        type = TREE_TYPE (type), dimension_number++)
        !          2367:     {
        !          2368:       register tree domain = TYPE_DOMAIN (type);
        !          2369: 
        !          2370:       /* Arrays come in three flavors. Unspecified bounds, fixed
        !          2371:         bounds, and (in GNU C only) variable bounds.  Handle all
        !          2372:         three forms here.  */
        !          2373: 
        !          2374:       if (domain)
        !          2375:        {
        !          2376:          /* We have an array type with specified bounds.  */
        !          2377: 
        !          2378:          register tree lower = TYPE_MIN_VALUE (domain);
        !          2379:          register tree upper = TYPE_MAX_VALUE (domain);
        !          2380: 
        !          2381:          /* Handle only fundamental types as index types for now.  */
        !          2382: 
        !          2383:          if (! type_is_fundamental (domain))
        !          2384:            abort ();
        !          2385: 
        !          2386:          /* Output the representation format byte for this dimension. */
        !          2387: 
        !          2388:          ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file,
        !          2389:                                  FMT_CODE (1,
        !          2390:                                            TREE_CODE (lower) == INTEGER_CST,
        !          2391:                                            TREE_CODE (upper) == INTEGER_CST));
        !          2392: 
        !          2393:          /* Output the index type for this dimension.  */
        !          2394: 
        !          2395:          ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file,
        !          2396:                                      fundamental_type_code (domain));
        !          2397: 
        !          2398:          /* Output the representation for the lower bound.  */
        !          2399: 
        !          2400:          output_bound_representation (lower, dimension_number, 'l');
        !          2401: 
        !          2402:          /* Output the representation for the upper bound.  */
        !          2403: 
        !          2404:          output_bound_representation (upper, dimension_number, 'u');
        !          2405:        }
        !          2406:       else
        !          2407:        {
        !          2408:          /* We have an array type with an unspecified length.  For C and
        !          2409:             C++ we can assume that this really means that (a) the index
        !          2410:             type is an integral type, and (b) the lower bound is zero.
        !          2411:             Note that Dwarf defines the representation of an unspecified
        !          2412:             (upper) bound as being a zero-length location description.  */
        !          2413: 
        !          2414:          /* Output the array-bounds format byte.  */
        !          2415: 
        !          2416:          ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, FMT_FT_C_X);
        !          2417: 
        !          2418:          /* Output the (assumed) index type.  */
        !          2419: 
        !          2420:          ASM_OUTPUT_DWARF_FUND_TYPE (asm_out_file, FT_integer);
        !          2421: 
        !          2422:          /* Output the (assumed) lower bound (constant) value.  */
        !          2423: 
        !          2424:          ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
        !          2425: 
        !          2426:          /* Output the (empty) location description for the upper bound.  */
        !          2427: 
        !          2428:          ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0);
        !          2429:        }
        !          2430:     }
        !          2431: 
        !          2432:   /* Output the prefix byte that says that the element type is comming up.  */
        !          2433: 
        !          2434:   ASM_OUTPUT_DWARF_FMT_BYTE (asm_out_file, FMT_ET);
        !          2435: 
        !          2436:   /* Output a representation of the type of the elements of this array type.  */
        !          2437: 
        !          2438:   type_attribute (type, 0, 0);
        !          2439: 
        !          2440:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2441: }
        !          2442: 
        !          2443: static void
        !          2444: byte_size_attribute (tree_node)
        !          2445:      register tree tree_node;
        !          2446: {
        !          2447:   register unsigned size;
        !          2448: 
        !          2449:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_byte_size);
        !          2450:   switch (TREE_CODE (tree_node))
        !          2451:     {
        !          2452:       case ERROR_MARK:
        !          2453:        size = 0;
        !          2454:        break;
        !          2455: 
        !          2456:       case ENUMERAL_TYPE:
        !          2457:       case RECORD_TYPE:
        !          2458:       case UNION_TYPE:
        !          2459:       case QUAL_UNION_TYPE:
        !          2460:        size = int_size_in_bytes (tree_node);
        !          2461:        break;
        !          2462: 
        !          2463:       case FIELD_DECL:
        !          2464:        /* For a data member of a struct or union, the AT_byte_size is
        !          2465:           generally given as the number of bytes normally allocated for
        !          2466:           an object of the *declared* type of the member itself.  This
        !          2467:           is true even for bit-fields.  */
        !          2468:        size = simple_type_size_in_bits (field_type (tree_node))
        !          2469:               / BITS_PER_UNIT;
        !          2470:        break;
        !          2471: 
        !          2472:       default:
        !          2473:        abort ();
        !          2474:     }
        !          2475: 
        !          2476:   /* Note that `size' might be -1 when we get to this point.  If it
        !          2477:      is, that indicates that the byte size of the entity in question
        !          2478:      is variable.  We have no good way of expressing this fact in Dwarf
        !          2479:      at the present time, so just let the -1 pass on through.  */
        !          2480: 
        !          2481:   ASM_OUTPUT_DWARF_DATA4 (asm_out_file, size);
        !          2482: }
        !          2483: 
        !          2484: /* For a FIELD_DECL node which represents a bit-field, output an attribute
        !          2485:    which specifies the distance in bits from the highest order bit of the
        !          2486:    "containing object" for the bit-field to the highest order bit of the
        !          2487:    bit-field itself.
        !          2488: 
        !          2489:    For any given bit-field, the "containing object" is a hypothetical
        !          2490:    object (of some integral or enum type) within which the given bit-field
        !          2491:    lives.  The type of this hypothetical "containing object" is always the
        !          2492:    same as the declared type of the individual bit-field itself.
        !          2493: 
        !          2494:    The determination of the exact location of the "containing object" for
        !          2495:    a bit-field is rather complicated.  It's handled by the `field_byte_offset'
        !          2496:    function (above).
        !          2497: 
        !          2498:    Note that it is the size (in bytes) of the hypothetical "containing
        !          2499:    object" which will be given in the AT_byte_size attribute for this
        !          2500:    bit-field.  (See `byte_size_attribute' above.)
        !          2501: */
        !          2502: 
        !          2503: inline void
        !          2504: bit_offset_attribute (decl)
        !          2505:     register tree decl;
        !          2506: {
        !          2507:   register unsigned object_offset_in_bytes = field_byte_offset (decl);
        !          2508:   register tree type = DECL_BIT_FIELD_TYPE (decl);
        !          2509:   register tree bitpos_tree = DECL_FIELD_BITPOS (decl);
        !          2510:   register unsigned bitpos_int;
        !          2511:   register unsigned highest_order_object_bit_offset;
        !          2512:   register unsigned highest_order_field_bit_offset;
        !          2513:   register unsigned bit_offset;
        !          2514: 
        !          2515:   assert (TREE_CODE (decl) == FIELD_DECL);     /* Must be a field.  */
        !          2516:   assert (type);                               /* Must be a bit field.  */
        !          2517: 
        !          2518:   /* We can't yet handle bit-fields whose offsets are variable, so if we
        !          2519:      encounter such things, just return without generating any attribute
        !          2520:      whatsoever.  */
        !          2521: 
        !          2522:   if (TREE_CODE (bitpos_tree) != INTEGER_CST)
        !          2523:     return;
        !          2524:   bitpos_int = (unsigned) TREE_INT_CST_LOW (bitpos_tree);
        !          2525: 
        !          2526:   /* Note that the bit offset is always the distance (in bits) from the
        !          2527:      highest-order bit of the "containing object" to the highest-order
        !          2528:      bit of the bit-field itself.  Since the "high-order end" of any
        !          2529:      object or field is different on big-endian and little-endian machines,
        !          2530:      the computation below must take account of these differences.  */
        !          2531: 
        !          2532:   highest_order_object_bit_offset = object_offset_in_bytes * BITS_PER_UNIT;
        !          2533:   highest_order_field_bit_offset = bitpos_int;
        !          2534: 
        !          2535: #if (BYTES_BIG_ENDIAN == 0)
        !          2536:   highest_order_field_bit_offset
        !          2537:     += (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl));
        !          2538: 
        !          2539:   highest_order_object_bit_offset += simple_type_size_in_bits (type);
        !          2540: #endif /* (BYTES_BIG_ENDIAN == 0) */
        !          2541: 
        !          2542:   bit_offset =
        !          2543: #if (BYTES_BIG_ENDIAN == 0)
        !          2544:          highest_order_object_bit_offset - highest_order_field_bit_offset;
        !          2545: #else /* (BYTES_BIG_ENDIAN != 0) */
        !          2546:          highest_order_field_bit_offset - highest_order_object_bit_offset;
        !          2547: #endif /* (BYTES_BIG_ENDIAN != 0) */
        !          2548: 
        !          2549:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_offset);
        !          2550:   ASM_OUTPUT_DWARF_DATA2 (asm_out_file, bit_offset);
        !          2551: }
        !          2552: 
        !          2553: /* For a FIELD_DECL node which represents a bit field, output an attribute
        !          2554:    which specifies the length in bits of the given field.  */
        !          2555: 
        !          2556: inline void
        !          2557: bit_size_attribute (decl)
        !          2558:     register tree decl;
        !          2559: {
        !          2560:   assert (TREE_CODE (decl) == FIELD_DECL);     /* Must be a field.  */
        !          2561:   assert (DECL_BIT_FIELD_TYPE (decl));         /* Must be a bit field.  */
        !          2562: 
        !          2563:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_bit_size);
        !          2564:   ASM_OUTPUT_DWARF_DATA4 (asm_out_file,
        !          2565:                          (unsigned) TREE_INT_CST_LOW (DECL_SIZE (decl)));
        !          2566: }
        !          2567: 
        !          2568: /* The following routine outputs the `element_list' attribute for enumeration
        !          2569:    type DIEs.  The element_lits attribute includes the names and values of
        !          2570:    all of the enumeration constants associated with the given enumeration
        !          2571:    type.  */
        !          2572: 
        !          2573: inline void
        !          2574: element_list_attribute (element)
        !          2575:      register tree element;
        !          2576: {
        !          2577:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2578:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2579: 
        !          2580:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_element_list);
        !          2581:   sprintf (begin_label, EE_BEGIN_LABEL_FMT, current_dienum);
        !          2582:   sprintf (end_label, EE_END_LABEL_FMT, current_dienum);
        !          2583:   ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label);
        !          2584:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2585: 
        !          2586:   /* Here we output a list of value/name pairs for each enumeration constant
        !          2587:      defined for this enumeration type (as required), but we do it in REVERSE
        !          2588:      order.  The order is the one required by the draft #5 Dwarf specification
        !          2589:      published by the UI/PLSIG.  */
        !          2590: 
        !          2591:   output_enumeral_list (element);   /* Recursively output the whole list.  */
        !          2592: 
        !          2593:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2594: }
        !          2595: 
        !          2596: /* Generate an AT_stmt_list attribute. These are normally present only in
        !          2597:    DIEs with a TAG_compile_unit tag.  */
        !          2598: 
        !          2599: inline void
        !          2600: stmt_list_attribute (label)
        !          2601:     register char *label;
        !          2602: {
        !          2603:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_stmt_list);
        !          2604:   /* Don't use ASM_OUTPUT_DWARF_DATA4 here.  */
        !          2605:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
        !          2606: }
        !          2607: 
        !          2608: /* Generate an AT_low_pc attribute for a label DIE, a lexical_block DIE or
        !          2609:    for a subroutine DIE.  */
        !          2610: 
        !          2611: inline void
        !          2612: low_pc_attribute (asm_low_label)
        !          2613:      register char *asm_low_label;
        !          2614: {
        !          2615:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_low_pc);
        !          2616:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_low_label);
        !          2617: }
        !          2618: 
        !          2619: /* Generate an AT_high_pc attribute for a lexical_block DIE or for a
        !          2620:    subroutine DIE.  */
        !          2621: 
        !          2622: inline void
        !          2623: high_pc_attribute (asm_high_label)
        !          2624:     register char *asm_high_label;
        !          2625: {
        !          2626:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_high_pc);
        !          2627:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_high_label);
        !          2628: }
        !          2629: 
        !          2630: /* Generate an AT_body_begin attribute for a subroutine DIE.  */
        !          2631: 
        !          2632: inline void
        !          2633: body_begin_attribute (asm_begin_label)
        !          2634:      register char *asm_begin_label;
        !          2635: {
        !          2636:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_body_begin);
        !          2637:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_begin_label);
        !          2638: }
        !          2639: 
        !          2640: /* Generate an AT_body_end attribute for a subroutine DIE.  */
        !          2641: 
        !          2642: inline void
        !          2643: body_end_attribute (asm_end_label)
        !          2644:      register char *asm_end_label;
        !          2645: {
        !          2646:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_body_end);
        !          2647:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, asm_end_label);
        !          2648: }
        !          2649: 
        !          2650: /* Generate an AT_language attribute given a LANG value.  These attributes
        !          2651:    are used only within TAG_compile_unit DIEs.  */
        !          2652: 
        !          2653: inline void
        !          2654: language_attribute (language_code)
        !          2655:      register unsigned language_code;
        !          2656: {
        !          2657:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_language);
        !          2658:   ASM_OUTPUT_DWARF_DATA4 (asm_out_file, language_code);
        !          2659: }
        !          2660: 
        !          2661: inline void
        !          2662: member_attribute (context)
        !          2663:     register tree context;
        !          2664: {
        !          2665:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2666: 
        !          2667:   /* Generate this attribute only for members in C++.  */
        !          2668: 
        !          2669:   if (context != NULL && is_tagged_type (context))
        !          2670:     {
        !          2671:       ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_member);
        !          2672:       sprintf (label, TYPE_NAME_FMT, TYPE_UID (context));
        !          2673:       ASM_OUTPUT_DWARF_REF (asm_out_file, label);
        !          2674:     }
        !          2675: }
        !          2676: 
        !          2677: inline void
        !          2678: string_length_attribute (upper_bound)
        !          2679:      register tree upper_bound;
        !          2680: {
        !          2681:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2682:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2683: 
        !          2684:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_string_length);
        !          2685:   sprintf (begin_label, SL_BEGIN_LABEL_FMT, current_dienum);
        !          2686:   sprintf (end_label, SL_END_LABEL_FMT, current_dienum);
        !          2687:   ASM_OUTPUT_DWARF_DELTA2 (asm_out_file, end_label, begin_label);
        !          2688:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          2689:   output_bound_representation (upper_bound, 0, 'u');
        !          2690:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          2691: }
        !          2692: 
        !          2693: inline void
        !          2694: comp_dir_attribute (dirname)
        !          2695:      register char *dirname;
        !          2696: {
        !          2697:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_comp_dir);
        !          2698:   ASM_OUTPUT_DWARF_STRING (asm_out_file, dirname);
        !          2699: }
        !          2700: 
        !          2701: inline void
        !          2702: sf_names_attribute (sf_names_start_label)
        !          2703:      register char *sf_names_start_label;
        !          2704: {
        !          2705:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_sf_names);
        !          2706:   /* Don't use ASM_OUTPUT_DWARF_DATA4 here.  */
        !          2707:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, sf_names_start_label);
        !          2708: }
        !          2709: 
        !          2710: inline void
        !          2711: src_info_attribute (src_info_start_label)
        !          2712:      register char *src_info_start_label;
        !          2713: {
        !          2714:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_src_info);
        !          2715:   /* Don't use ASM_OUTPUT_DWARF_DATA4 here.  */
        !          2716:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, src_info_start_label);
        !          2717: }
        !          2718: 
        !          2719: inline void
        !          2720: mac_info_attribute (mac_info_start_label)
        !          2721:      register char *mac_info_start_label;
        !          2722: {
        !          2723:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_mac_info);
        !          2724:   /* Don't use ASM_OUTPUT_DWARF_DATA4 here.  */
        !          2725:   ASM_OUTPUT_DWARF_ADDR (asm_out_file, mac_info_start_label);
        !          2726: }
        !          2727: 
        !          2728: inline void
        !          2729: prototyped_attribute (func_type)
        !          2730:      register tree func_type;
        !          2731: {
        !          2732:   if ((strcmp (language_string, "GNU C") == 0)
        !          2733:       && (TYPE_ARG_TYPES (func_type) != NULL))
        !          2734:     {
        !          2735:       ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_prototyped);
        !          2736:       ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
        !          2737:     }
        !          2738: }
        !          2739: 
        !          2740: inline void
        !          2741: producer_attribute (producer)
        !          2742:      register char *producer;
        !          2743: {
        !          2744:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_producer);
        !          2745:   ASM_OUTPUT_DWARF_STRING (asm_out_file, producer);
        !          2746: }
        !          2747: 
        !          2748: inline void
        !          2749: inline_attribute (decl)
        !          2750:      register tree decl;
        !          2751: {
        !          2752:   if (DECL_INLINE (decl))
        !          2753:     {
        !          2754:       ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_inline);
        !          2755:       ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
        !          2756:     }
        !          2757: }
        !          2758: 
        !          2759: inline void
        !          2760: containing_type_attribute (containing_type)
        !          2761:      register tree containing_type;
        !          2762: {
        !          2763:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2764: 
        !          2765:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_containing_type);
        !          2766:   sprintf (label, TYPE_NAME_FMT, TYPE_UID (containing_type));
        !          2767:   ASM_OUTPUT_DWARF_REF (asm_out_file, label);
        !          2768: }
        !          2769: 
        !          2770: inline void
        !          2771: abstract_origin_attribute (origin)
        !          2772:      register tree origin;
        !          2773: {
        !          2774:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          2775: 
        !          2776:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_abstract_origin);
        !          2777:   switch (TREE_CODE_CLASS (TREE_CODE (origin)))
        !          2778:     {
        !          2779:     case 'd':
        !          2780:       sprintf (label, DECL_NAME_FMT, DECL_UID (origin));
        !          2781:       break;
        !          2782: 
        !          2783:     case 't':
        !          2784:       sprintf (label, TYPE_NAME_FMT, TYPE_UID (origin));
        !          2785:       break;
        !          2786: 
        !          2787:     default:
        !          2788:       abort ();                /* Should never happen.  */
        !          2789: 
        !          2790:     }
        !          2791:   ASM_OUTPUT_DWARF_REF (asm_out_file, label);
        !          2792: }
        !          2793: 
        !          2794: #ifdef DWARF_DECL_COORDINATES
        !          2795: inline void
        !          2796: src_coords_attribute (src_fileno, src_lineno)
        !          2797:      register unsigned src_fileno;
        !          2798:      register unsigned src_lineno;
        !          2799: {
        !          2800:   ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_src_coords);
        !          2801:   ASM_OUTPUT_DWARF_DATA2 (asm_out_file, src_fileno);
        !          2802:   ASM_OUTPUT_DWARF_DATA2 (asm_out_file, src_lineno);
        !          2803: }
        !          2804: #endif /* defined(DWARF_DECL_COORDINATES) */
        !          2805: 
        !          2806: inline void
        !          2807: pure_or_virtual_attribute (func_decl)
        !          2808:      register tree func_decl;
        !          2809: {
        !          2810:   if (DECL_VIRTUAL_P (func_decl))
        !          2811:     {
        !          2812: #if 0 /* DECL_ABSTRACT_VIRTUAL_P is C++-specific.  */
        !          2813:       if (DECL_ABSTRACT_VIRTUAL_P (func_decl))
        !          2814:         ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_pure_virtual);
        !          2815:       else
        !          2816: #endif
        !          2817:         ASM_OUTPUT_DWARF_ATTRIBUTE (asm_out_file, AT_virtual);
        !          2818:       ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
        !          2819:     }
        !          2820: }
        !          2821: 
        !          2822: /************************* end of attributes *****************************/
        !          2823: 
        !          2824: /********************* utility routines for DIEs *************************/
        !          2825: 
        !          2826: /* Output an AT_name attribute and an AT_src_coords attribute for the
        !          2827:    given decl, but only if it actually has a name.  */
        !          2828: 
        !          2829: static void
        !          2830: name_and_src_coords_attributes (decl)
        !          2831:     register tree decl;
        !          2832: {
        !          2833:   register tree decl_name = DECL_NAME (decl);
        !          2834: 
        !          2835:   if (decl_name && IDENTIFIER_POINTER (decl_name))
        !          2836:     {
        !          2837:       name_attribute (IDENTIFIER_POINTER (decl_name));
        !          2838: #ifdef DWARF_DECL_COORDINATES
        !          2839:       {
        !          2840:        register unsigned file_index;
        !          2841: 
        !          2842:        /* This is annoying, but we have to pop out of the .debug section
        !          2843:           for a moment while we call `lookup_filename' because calling it
        !          2844:           may cause a temporary switch into the .debug_sfnames section and
        !          2845:           most svr4 assemblers are not smart enough be be able to nest
        !          2846:           section switches to any depth greater than one.  Note that we
        !          2847:           also can't skirt this issue by delaying all output to the
        !          2848:           .debug_sfnames section unit the end of compilation because that
        !          2849:           would cause us to have inter-section forward references and
        !          2850:           Fred Fish sez that m68k/svr4 assemblers botch those.  */
        !          2851: 
        !          2852:        ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          2853:        file_index = lookup_filename (DECL_SOURCE_FILE (decl));
        !          2854:        ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION);
        !          2855: 
        !          2856:         src_coords_attribute (file_index, DECL_SOURCE_LINE (decl));
        !          2857:       }
        !          2858: #endif /* defined(DWARF_DECL_COORDINATES) */
        !          2859:     }
        !          2860: }
        !          2861: 
        !          2862: /* Many forms of DIEs contain a "type description" part.  The following
        !          2863:    routine writes out these "type descriptor" parts.  */
        !          2864: 
        !          2865: static void
        !          2866: type_attribute (type, decl_const, decl_volatile)
        !          2867:      register tree type;
        !          2868:      register int decl_const;
        !          2869:      register int decl_volatile;
        !          2870: {
        !          2871:   register enum tree_code code = TREE_CODE (type);
        !          2872:   register int root_type_modified;
        !          2873: 
        !          2874:   if (TREE_CODE (type) == ERROR_MARK)
        !          2875:     return;
        !          2876: 
        !          2877:   /* Handle a special case.  For functions whose return type is void,
        !          2878:      we generate *no* type attribute.  (Note that no object may have
        !          2879:      type `void', so this only applies to function return types.  */
        !          2880: 
        !          2881:   if (TREE_CODE (type) == VOID_TYPE)
        !          2882:     return;
        !          2883: 
        !          2884:   root_type_modified = (code == POINTER_TYPE || code == REFERENCE_TYPE
        !          2885:                        || decl_const || decl_volatile
        !          2886:                        || TYPE_READONLY (type) || TYPE_VOLATILE (type));
        !          2887: 
        !          2888:   if (type_is_fundamental (root_type (type)))
        !          2889:     if (root_type_modified)
        !          2890:        mod_fund_type_attribute (type, decl_const, decl_volatile);
        !          2891:     else
        !          2892:        fund_type_attribute (fundamental_type_code (type));
        !          2893:   else
        !          2894:     if (root_type_modified)
        !          2895:        mod_u_d_type_attribute (type, decl_const, decl_volatile);
        !          2896:     else
        !          2897:        /* We have to get the type_main_variant here (and pass that to the
        !          2898:           `user_def_type_attribute' routine) because the ..._TYPE node we
        !          2899:           have might simply be a *copy* of some original type node (where
        !          2900:           the copy was created to help us keep track of typedef names)
        !          2901:           and that copy might have a different TYPE_UID from the original
        !          2902:           ..._TYPE node.  (Note that when `equate_type_number_to_die_number'
        !          2903:           is labeling a given type DIE for future reference, it always and
        !          2904:           only creates labels for DIEs representing *main variants*, and it
        !          2905:           never even knows about non-main-variants.)  */
        !          2906:        user_def_type_attribute (type_main_variant (type));
        !          2907: }
        !          2908: 
        !          2909: /* Given a tree pointer to a struct, class, union, or enum type node, return
        !          2910:    a pointer to the (string) tag name for the given type, or zero if the
        !          2911:    type was declared without a tag.  */
        !          2912: 
        !          2913: static char *
        !          2914: type_tag (type)
        !          2915:      register tree type;
        !          2916: {
        !          2917:   register char *name = 0;
        !          2918: 
        !          2919:   if (TYPE_NAME (type) != 0)
        !          2920:     {
        !          2921:       register tree t = 0;
        !          2922: 
        !          2923:       /* Find the IDENTIFIER_NODE for the type name.  */
        !          2924:       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
        !          2925:        t = TYPE_NAME (type);
        !          2926: #if 0
        !          2927:       /* The g++ front end makes the TYPE_NAME of *each* tagged type point
        !          2928:         to a TYPE_DECL node, regardless of whether or not a `typedef' was
        !          2929:         involved.  This is distinctly different from what the gcc front-end
        !          2930:         does.  It always makes the TYPE_NAME for each tagged type be either
        !          2931:         NULL (signifying an anonymous tagged type) or else a pointer to an
        !          2932:         IDENTIFIER_NODE.  Obviously, we would like to generate correct Dwarf
        !          2933:         for both C and C++, but given this inconsistency in the TREE
        !          2934:         representation of tagged types for C and C++ in the GNU front-ends,
        !          2935:         we cannot support both languages correctly unless we introduce some
        !          2936:         front-end specific code here, and rms objects to that, so we can
        !          2937:         only generate correct Dwarf for one of these two languages.  C is
        !          2938:         more important, so for now we'll do the right thing for C and let
        !          2939:         g++ go fish.  */
        !          2940: 
        !          2941:       else
        !          2942:        if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
        !          2943:          t = DECL_NAME (TYPE_NAME (type));
        !          2944: #endif
        !          2945:       /* Now get the name as a string, or invent one.  */
        !          2946:       if (t != 0)
        !          2947:        name = IDENTIFIER_POINTER (t);
        !          2948:     }
        !          2949: 
        !          2950:   return (name == 0 || *name == '\0') ? 0 : name;
        !          2951: }
        !          2952: 
        !          2953: inline void
        !          2954: dienum_push ()
        !          2955: {
        !          2956:   /* Start by checking if the pending_sibling_stack needs to be expanded.
        !          2957:      If necessary, expand it.  */
        !          2958: 
        !          2959:   if (pending_siblings == pending_siblings_allocated)
        !          2960:     {
        !          2961:       pending_siblings_allocated += PENDING_SIBLINGS_INCREMENT;
        !          2962:       pending_sibling_stack
        !          2963:        = (unsigned *) xrealloc (pending_sibling_stack,
        !          2964:                                 pending_siblings_allocated * sizeof(unsigned));
        !          2965:     }
        !          2966: 
        !          2967:   pending_siblings++;
        !          2968:   NEXT_DIE_NUM = next_unused_dienum++;
        !          2969: }
        !          2970: 
        !          2971: /* Pop the sibling stack so that the most recently pushed DIEnum becomes the
        !          2972:    NEXT_DIE_NUM.  */
        !          2973: 
        !          2974: inline void
        !          2975: dienum_pop ()
        !          2976: {
        !          2977:   pending_siblings--;
        !          2978: }
        !          2979: 
        !          2980: inline tree
        !          2981: member_declared_type (member)
        !          2982:      register tree member;
        !          2983: {
        !          2984:   return (DECL_BIT_FIELD_TYPE (member))
        !          2985:           ? DECL_BIT_FIELD_TYPE (member)
        !          2986:           : TREE_TYPE (member);
        !          2987: }
        !          2988: 
        !          2989: /* Get the function's label, as described by its RTL.
        !          2990:    This may be different from the DECL_NAME name used
        !          2991:    in the source file.  */
        !          2992: 
        !          2993: static char *
        !          2994: function_start_label (decl)
        !          2995:     register tree decl;
        !          2996: {
        !          2997:   rtx x;
        !          2998:   char *fnname;
        !          2999: 
        !          3000:   x = DECL_RTL (decl);
        !          3001:   if (GET_CODE (x) != MEM)
        !          3002:     abort ();
        !          3003:   x = XEXP (x, 0);
        !          3004:   if (GET_CODE (x) != SYMBOL_REF)
        !          3005:               abort ();
        !          3006:   fnname = XSTR (x, 0);
        !          3007:   return fnname;
        !          3008: }
        !          3009: 
        !          3010: 
        !          3011: /******************************* DIEs ************************************/
        !          3012: 
        !          3013: /* Output routines for individual types of DIEs.  */
        !          3014: 
        !          3015: /* Note that every type of DIE (except a null DIE) gets a sibling.  */
        !          3016: 
        !          3017: static void
        !          3018: output_array_type_die (arg)
        !          3019:      register void *arg;
        !          3020: {
        !          3021:   register tree type = arg;
        !          3022: 
        !          3023:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_array_type);
        !          3024:   sibling_attribute ();
        !          3025:   equate_type_number_to_die_number (type);
        !          3026:   member_attribute (TYPE_CONTEXT (type));
        !          3027: 
        !          3028:   /* I believe that we can default the array ordering.  SDB will probably
        !          3029:      do the right things even if AT_ordering is not present.  It's not
        !          3030:      even an issue until we start to get into multidimensional arrays
        !          3031:      anyway.  If SDB is ever caught doing the Wrong Thing for multi-
        !          3032:      dimensional arrays, then we'll have to put the AT_ordering attribute
        !          3033:      back in.  (But if and when we find out that we need to put these in,
        !          3034:      we will only do so for multidimensional arrays.  After all, we don't
        !          3035:      want to waste space in the .debug section now do we?)  */
        !          3036: 
        !          3037: #ifdef USE_ORDERING_ATTRIBUTE
        !          3038:   ordering_attribute (ORD_row_major);
        !          3039: #endif /* defined(USE_ORDERING_ATTRIBUTE) */
        !          3040: 
        !          3041:   subscript_data_attribute (type);
        !          3042: }
        !          3043: 
        !          3044: static void
        !          3045: output_set_type_die (arg)
        !          3046:      register void *arg;
        !          3047: {
        !          3048:   register tree type = arg;
        !          3049: 
        !          3050:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_set_type);
        !          3051:   sibling_attribute ();
        !          3052:   equate_type_number_to_die_number (type);
        !          3053:   member_attribute (TYPE_CONTEXT (type));
        !          3054:   type_attribute (TREE_TYPE (type), 0, 0);
        !          3055: }
        !          3056: 
        !          3057: #if 0
        !          3058: /* Implement this when there is a GNU FORTRAN or GNU Ada front end.  */
        !          3059: static void
        !          3060: output_entry_point_die (arg)
        !          3061:      register void *arg;
        !          3062: {
        !          3063:   register tree decl = arg;
        !          3064:   register tree origin = decl_ultimate_origin (decl);
        !          3065: 
        !          3066:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_entry_point);
        !          3067:   sibling_attribute ();
        !          3068:   dienum_push ();
        !          3069:   if (origin != NULL)
        !          3070:     abstract_origin_attribute (origin);
        !          3071:   else
        !          3072:     {
        !          3073:       name_and_src_coords_attributes (decl);
        !          3074:       member_attribute (DECL_CONTEXT (decl));
        !          3075:       type_attribute (TREE_TYPE (TREE_TYPE (decl)), 0, 0);
        !          3076:     }
        !          3077:   if (DECL_ABSTRACT (decl))
        !          3078:     equate_decl_number_to_die_number (decl);
        !          3079:   else
        !          3080:     low_pc_attribute (function_start_label (decl));
        !          3081: }
        !          3082: #endif
        !          3083: 
        !          3084: /* Output a DIE to represent an inlined instance of an enumeration type.  */
        !          3085: 
        !          3086: static void
        !          3087: output_inlined_enumeration_type_die (arg)
        !          3088:      register void *arg;
        !          3089: {
        !          3090:   register tree type = arg;
        !          3091: 
        !          3092:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_enumeration_type);
        !          3093:   sibling_attribute ();
        !          3094:   assert (TREE_ASM_WRITTEN (type));
        !          3095:   abstract_origin_attribute (type);
        !          3096: }
        !          3097: 
        !          3098: /* Output a DIE to represent an inlined instance of a structure type.  */
        !          3099: 
        !          3100: static void
        !          3101: output_inlined_structure_type_die (arg)
        !          3102:      register void *arg;
        !          3103: {
        !          3104:   register tree type = arg;
        !          3105: 
        !          3106:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_structure_type);
        !          3107:   sibling_attribute ();
        !          3108:   assert (TREE_ASM_WRITTEN (type));
        !          3109:   abstract_origin_attribute (type);
        !          3110: }
        !          3111: 
        !          3112: /* Output a DIE to represent an inlined instance of a union type.  */
        !          3113: 
        !          3114: static void
        !          3115: output_inlined_union_type_die (arg)
        !          3116:      register void *arg;
        !          3117: {
        !          3118:   register tree type = arg;
        !          3119: 
        !          3120:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_union_type);
        !          3121:   sibling_attribute ();
        !          3122:   assert (TREE_ASM_WRITTEN (type));
        !          3123:   abstract_origin_attribute (type);
        !          3124: }
        !          3125: 
        !          3126: /* Output a DIE to represent an enumeration type.  Note that these DIEs
        !          3127:    include all of the information about the enumeration values also.
        !          3128:    This information is encoded into the element_list attribute.         */
        !          3129: 
        !          3130: static void
        !          3131: output_enumeration_type_die (arg)
        !          3132:      register void *arg;
        !          3133: {
        !          3134:   register tree type = arg;
        !          3135: 
        !          3136:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_enumeration_type);
        !          3137:   sibling_attribute ();
        !          3138:   equate_type_number_to_die_number (type);
        !          3139:   name_attribute (type_tag (type));
        !          3140:   member_attribute (TYPE_CONTEXT (type));
        !          3141: 
        !          3142:   /* Handle a GNU C/C++ extension, i.e. incomplete enum types.  If the
        !          3143:      given enum type is incomplete, do not generate the AT_byte_size
        !          3144:      attribute or the AT_element_list attribute.  */
        !          3145: 
        !          3146:   if (TYPE_SIZE (type))
        !          3147:     {
        !          3148:       byte_size_attribute (type);
        !          3149:       element_list_attribute (TYPE_FIELDS (type));
        !          3150:     }
        !          3151: }
        !          3152: 
        !          3153: /* Output a DIE to represent either a real live formal parameter decl or
        !          3154:    to represent just the type of some formal parameter position in some
        !          3155:    function type.
        !          3156: 
        !          3157:    Note that this routine is a bit unusual because its argument may be
        !          3158:    a ..._DECL node (i.e. either a PARM_DECL or perhaps a VAR_DECL which
        !          3159:    represents an inlining of some PARM_DECL) or else some sort of a
        !          3160:    ..._TYPE node.  If it's the former then this function is being called
        !          3161:    to output a DIE to represent a formal parameter object (or some inlining
        !          3162:    thereof).  If it's the latter, then this function is only being called
        !          3163:    to output a TAG_formal_parameter DIE to stand as a placeholder for some
        !          3164:    formal argument type of some subprogram type.  */
        !          3165: 
        !          3166: static void
        !          3167: output_formal_parameter_die (arg)
        !          3168:      register void *arg;
        !          3169: {
        !          3170:   register tree node = arg;
        !          3171: 
        !          3172:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_formal_parameter);
        !          3173:   sibling_attribute ();
        !          3174: 
        !          3175:   switch (TREE_CODE_CLASS (TREE_CODE (node)))
        !          3176:     {
        !          3177:     case 'd':  /* We were called with some kind of a ..._DECL node.  */
        !          3178:       {
        !          3179:        register tree origin = decl_ultimate_origin (node);
        !          3180: 
        !          3181:        if (origin != NULL)
        !          3182:          abstract_origin_attribute (origin);
        !          3183:        else
        !          3184:          {
        !          3185:            name_and_src_coords_attributes (node);
        !          3186:            type_attribute (TREE_TYPE (node),
        !          3187:                            TREE_READONLY (node), TREE_THIS_VOLATILE (node));
        !          3188:          }
        !          3189:        if (DECL_ABSTRACT (node))
        !          3190:          equate_decl_number_to_die_number (node);
        !          3191:        else
        !          3192:          location_or_const_value_attribute (node);
        !          3193:       }
        !          3194:       break;
        !          3195: 
        !          3196:     case 't':  /* We were called with some kind of a ..._TYPE node.  */
        !          3197:       type_attribute (node, 0, 0);
        !          3198:       break;
        !          3199: 
        !          3200:     default:
        !          3201:       abort ();        /* Should never happen.  */
        !          3202:     }
        !          3203: }
        !          3204: 
        !          3205: /* Output a DIE to represent a declared function (either file-scope
        !          3206:    or block-local) which has "external linkage" (according to ANSI-C).  */
        !          3207: 
        !          3208: static void
        !          3209: output_global_subroutine_die (arg)
        !          3210:      register void *arg;
        !          3211: {
        !          3212:   register tree decl = arg;
        !          3213:   register tree origin = decl_ultimate_origin (decl);
        !          3214: 
        !          3215:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_subroutine);
        !          3216:   sibling_attribute ();
        !          3217:   dienum_push ();
        !          3218:   if (origin != NULL)
        !          3219:     abstract_origin_attribute (origin);
        !          3220:   else
        !          3221:     {
        !          3222:       register tree type = TREE_TYPE (decl);
        !          3223: 
        !          3224:       name_and_src_coords_attributes (decl);
        !          3225:       inline_attribute (decl);
        !          3226:       prototyped_attribute (type);
        !          3227:       member_attribute (DECL_CONTEXT (decl));
        !          3228:       type_attribute (TREE_TYPE (type), 0, 0);
        !          3229:       pure_or_virtual_attribute (decl);
        !          3230:     }
        !          3231:   if (DECL_ABSTRACT (decl))
        !          3232:     equate_decl_number_to_die_number (decl);
        !          3233:   else
        !          3234:     {
        !          3235:       if (! DECL_EXTERNAL (decl))
        !          3236:        {
        !          3237:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3238: 
        !          3239:          low_pc_attribute (function_start_label (decl));
        !          3240:          sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number);
        !          3241:          high_pc_attribute (label);
        !          3242:          sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number);
        !          3243:          body_begin_attribute (label);
        !          3244:          sprintf (label, BODY_END_LABEL_FMT, current_funcdef_number);
        !          3245:          body_end_attribute (label);
        !          3246:        }
        !          3247:     }
        !          3248: }
        !          3249: 
        !          3250: /* Output a DIE to represent a declared data object (either file-scope
        !          3251:    or block-local) which has "external linkage" (according to ANSI-C).  */
        !          3252: 
        !          3253: static void
        !          3254: output_global_variable_die (arg)
        !          3255:      register void *arg;
        !          3256: {
        !          3257:   register tree decl = arg;
        !          3258:   register tree origin = decl_ultimate_origin (decl);
        !          3259: 
        !          3260:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_global_variable);
        !          3261:   sibling_attribute ();
        !          3262:   if (origin != NULL)
        !          3263:     abstract_origin_attribute (origin);
        !          3264:   else
        !          3265:     {
        !          3266:       name_and_src_coords_attributes (decl);
        !          3267:       member_attribute (DECL_CONTEXT (decl));
        !          3268:       type_attribute (TREE_TYPE (decl),
        !          3269:                      TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
        !          3270:     }
        !          3271:   if (DECL_ABSTRACT (decl))
        !          3272:     equate_decl_number_to_die_number (decl);
        !          3273:   else
        !          3274:     {
        !          3275:       if (!DECL_EXTERNAL (decl))
        !          3276:        location_or_const_value_attribute (decl);
        !          3277:     }
        !          3278: }
        !          3279: 
        !          3280: static void
        !          3281: output_label_die (arg)
        !          3282:      register void *arg;
        !          3283: {
        !          3284:   register tree decl = arg;
        !          3285:   register tree origin = decl_ultimate_origin (decl);
        !          3286: 
        !          3287:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_label);
        !          3288:   sibling_attribute ();
        !          3289:   if (origin != NULL)
        !          3290:     abstract_origin_attribute (origin);
        !          3291:   else
        !          3292:     name_and_src_coords_attributes (decl);
        !          3293:   if (DECL_ABSTRACT (decl))
        !          3294:     equate_decl_number_to_die_number (decl);
        !          3295:   else
        !          3296:     {
        !          3297:       register rtx insn = DECL_RTL (decl);
        !          3298: 
        !          3299:       if (GET_CODE (insn) == CODE_LABEL)
        !          3300:        {
        !          3301:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3302: 
        !          3303:          /* When optimization is enabled (via -O) some parts of the compiler
        !          3304:             (e.g. jump.c and cse.c) may try to delete CODE_LABEL insns which
        !          3305:             represent source-level labels which were explicitly declared by
        !          3306:             the user.  This really shouldn't be happening though, so catch
        !          3307:             it if it ever does happen.  */
        !          3308: 
        !          3309:          if (INSN_DELETED_P (insn))
        !          3310:            abort ();   /* Should never happen.  */
        !          3311: 
        !          3312:          sprintf (label, INSN_LABEL_FMT, current_funcdef_number,
        !          3313:                                          (unsigned) INSN_UID (insn));
        !          3314:          low_pc_attribute (label);
        !          3315:        }
        !          3316:     }
        !          3317: }
        !          3318: 
        !          3319: static void
        !          3320: output_lexical_block_die (arg)
        !          3321:      register void *arg;
        !          3322: {
        !          3323:   register tree stmt = arg;
        !          3324: 
        !          3325:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_lexical_block);
        !          3326:   sibling_attribute ();
        !          3327:   dienum_push ();
        !          3328:   if (! BLOCK_ABSTRACT (stmt))
        !          3329:     {
        !          3330:       char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3331:       char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3332: 
        !          3333:       sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number);
        !          3334:       low_pc_attribute (begin_label);
        !          3335:       sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number);
        !          3336:       high_pc_attribute (end_label);
        !          3337:     }
        !          3338: }
        !          3339: 
        !          3340: static void
        !          3341: output_inlined_subroutine_die (arg)
        !          3342:      register void *arg;
        !          3343: {
        !          3344:   register tree stmt = arg;
        !          3345: 
        !          3346:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_inlined_subroutine);
        !          3347:   sibling_attribute ();
        !          3348:   dienum_push ();
        !          3349:   abstract_origin_attribute (block_ultimate_origin (stmt));
        !          3350:   if (! BLOCK_ABSTRACT (stmt))
        !          3351:     {
        !          3352:       char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3353:       char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3354: 
        !          3355:       sprintf (begin_label, BLOCK_BEGIN_LABEL_FMT, next_block_number);
        !          3356:       low_pc_attribute (begin_label);
        !          3357:       sprintf (end_label, BLOCK_END_LABEL_FMT, next_block_number);
        !          3358:       high_pc_attribute (end_label);
        !          3359:     }
        !          3360: }
        !          3361: 
        !          3362: /* Output a DIE to represent a declared data object (either file-scope
        !          3363:    or block-local) which has "internal linkage" (according to ANSI-C).  */
        !          3364: 
        !          3365: static void
        !          3366: output_local_variable_die (arg)
        !          3367:      register void *arg;
        !          3368: {
        !          3369:   register tree decl = arg;
        !          3370:   register tree origin = decl_ultimate_origin (decl);
        !          3371: 
        !          3372:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_local_variable);
        !          3373:   sibling_attribute ();
        !          3374:   if (origin != NULL)
        !          3375:     abstract_origin_attribute (origin);
        !          3376:   else
        !          3377:     {
        !          3378:       name_and_src_coords_attributes (decl);
        !          3379:       member_attribute (DECL_CONTEXT (decl));
        !          3380:       type_attribute (TREE_TYPE (decl),
        !          3381:                      TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
        !          3382:     }
        !          3383:   if (DECL_ABSTRACT (decl))
        !          3384:     equate_decl_number_to_die_number (decl);
        !          3385:   else
        !          3386:     location_or_const_value_attribute (decl);
        !          3387: }
        !          3388: 
        !          3389: static void
        !          3390: output_member_die (arg)
        !          3391:      register void *arg;
        !          3392: {
        !          3393:   register tree decl = arg;
        !          3394: 
        !          3395:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_member);
        !          3396:   sibling_attribute ();
        !          3397:   name_and_src_coords_attributes (decl);
        !          3398:   member_attribute (DECL_CONTEXT (decl));
        !          3399:   type_attribute (member_declared_type (decl),
        !          3400:                  TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
        !          3401:   if (DECL_BIT_FIELD_TYPE (decl))      /* If this is a bit field... */
        !          3402:     {
        !          3403:       byte_size_attribute (decl);
        !          3404:       bit_size_attribute (decl);
        !          3405:       bit_offset_attribute (decl);
        !          3406:     }
        !          3407:   data_member_location_attribute (decl);
        !          3408: }
        !          3409: 
        !          3410: #if 0
        !          3411: /* Don't generate either pointer_type DIEs or reference_type DIEs.  Use
        !          3412:    modified types instead.
        !          3413: 
        !          3414:    We keep this code here just in case these types of DIEs may be needed
        !          3415:    to represent certain things in other languages (e.g. Pascal) someday.
        !          3416: */
        !          3417: 
        !          3418: static void
        !          3419: output_pointer_type_die (arg)
        !          3420:      register void *arg;
        !          3421: {
        !          3422:   register tree type = arg;
        !          3423: 
        !          3424:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_pointer_type);
        !          3425:   sibling_attribute ();
        !          3426:   equate_type_number_to_die_number (type);
        !          3427:   member_attribute (TYPE_CONTEXT (type));
        !          3428:   type_attribute (TREE_TYPE (type), 0, 0);
        !          3429: }
        !          3430: 
        !          3431: static void
        !          3432: output_reference_type_die (arg)
        !          3433:      register void *arg;
        !          3434: {
        !          3435:   register tree type = arg;
        !          3436: 
        !          3437:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_reference_type);
        !          3438:   sibling_attribute ();
        !          3439:   equate_type_number_to_die_number (type);
        !          3440:   member_attribute (TYPE_CONTEXT (type));
        !          3441:   type_attribute (TREE_TYPE (type), 0, 0);
        !          3442: }
        !          3443: #endif
        !          3444: 
        !          3445: static void
        !          3446: output_ptr_to_mbr_type_die (arg)
        !          3447:      register void *arg;
        !          3448: {
        !          3449:   register tree type = arg;
        !          3450: 
        !          3451:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_ptr_to_member_type);
        !          3452:   sibling_attribute ();
        !          3453:   equate_type_number_to_die_number (type);
        !          3454:   member_attribute (TYPE_CONTEXT (type));
        !          3455:   containing_type_attribute (TYPE_OFFSET_BASETYPE (type));
        !          3456:   type_attribute (TREE_TYPE (type), 0, 0);
        !          3457: }
        !          3458: 
        !          3459: static void
        !          3460: output_compile_unit_die (arg)
        !          3461:      register void *arg;
        !          3462: {
        !          3463:   register char *main_input_filename = arg;
        !          3464: 
        !          3465:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_compile_unit);
        !          3466:   sibling_attribute ();
        !          3467:   dienum_push ();
        !          3468:   name_attribute (main_input_filename);
        !          3469: 
        !          3470:   {
        !          3471:     char producer[250];
        !          3472: 
        !          3473:     sprintf (producer, "%s %s", language_string, version_string);
        !          3474:     producer_attribute (producer);
        !          3475:   }
        !          3476: 
        !          3477:   if (strcmp (language_string, "GNU C++") == 0)
        !          3478:     language_attribute (LANG_C_PLUS_PLUS);
        !          3479:   else if (strcmp (language_string, "GNU Ada") == 0)
        !          3480:     language_attribute (LANG_ADA83);
        !          3481:   else if (flag_traditional)
        !          3482:     language_attribute (LANG_C);
        !          3483:   else
        !          3484:     language_attribute (LANG_C89);
        !          3485:   low_pc_attribute (TEXT_BEGIN_LABEL);
        !          3486:   high_pc_attribute (TEXT_END_LABEL);
        !          3487:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          3488:     stmt_list_attribute (LINE_BEGIN_LABEL);
        !          3489:   last_filename = xstrdup (main_input_filename);
        !          3490: 
        !          3491:   {
        !          3492:     char *wd = getpwd ();
        !          3493:     if (wd)
        !          3494:       comp_dir_attribute (wd);
        !          3495:   }
        !          3496: 
        !          3497:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          3498:     {
        !          3499:       sf_names_attribute (SFNAMES_BEGIN_LABEL);
        !          3500:       src_info_attribute (SRCINFO_BEGIN_LABEL);
        !          3501:       if (debug_info_level >= DINFO_LEVEL_VERBOSE)
        !          3502:         mac_info_attribute (MACINFO_BEGIN_LABEL);
        !          3503:     }
        !          3504: }
        !          3505: 
        !          3506: static void
        !          3507: output_string_type_die (arg)
        !          3508:      register void *arg;
        !          3509: {
        !          3510:   register tree type = arg;
        !          3511: 
        !          3512:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_string_type);
        !          3513:   sibling_attribute ();
        !          3514:   member_attribute (TYPE_CONTEXT (type));
        !          3515: 
        !          3516:   /* Fudge the string length attribute for now.  */
        !          3517: 
        !          3518:   string_length_attribute (TYPE_MAX_VALUE (TYPE_DOMAIN (type)));
        !          3519: }
        !          3520: 
        !          3521: static void
        !          3522: output_structure_type_die (arg)
        !          3523:      register void *arg;
        !          3524: {
        !          3525:   register tree type = arg;
        !          3526: 
        !          3527:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_structure_type);
        !          3528:   sibling_attribute ();
        !          3529:   equate_type_number_to_die_number (type);
        !          3530:   name_attribute (type_tag (type));
        !          3531:   member_attribute (TYPE_CONTEXT (type));
        !          3532: 
        !          3533:   /* If this type has been completed, then give it a byte_size attribute
        !          3534:      and prepare to give a list of members.  Otherwise, don't do either of
        !          3535:      these things.  In the latter case, we will not be generating a list
        !          3536:      of members (since we don't have any idea what they might be for an
        !          3537:      incomplete type). */
        !          3538: 
        !          3539:   if (TYPE_SIZE (type))
        !          3540:     {
        !          3541:       dienum_push ();
        !          3542:       byte_size_attribute (type);
        !          3543:     }
        !          3544: }
        !          3545: 
        !          3546: /* Output a DIE to represent a declared function (either file-scope
        !          3547:    or block-local) which has "internal linkage" (according to ANSI-C).  */
        !          3548: 
        !          3549: static void
        !          3550: output_local_subroutine_die (arg)
        !          3551:      register void *arg;
        !          3552: {
        !          3553:   register tree decl = arg;
        !          3554:   register tree origin = decl_ultimate_origin (decl);
        !          3555: 
        !          3556:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine);
        !          3557:   sibling_attribute ();
        !          3558:   dienum_push ();
        !          3559:   if (origin != NULL)
        !          3560:     abstract_origin_attribute (origin);
        !          3561:   else
        !          3562:     {
        !          3563:       register tree type = TREE_TYPE (decl);
        !          3564: 
        !          3565:       name_and_src_coords_attributes (decl);
        !          3566:       inline_attribute (decl);
        !          3567:       prototyped_attribute (type);
        !          3568:       member_attribute (DECL_CONTEXT (decl));
        !          3569:       type_attribute (TREE_TYPE (type), 0, 0);
        !          3570:       pure_or_virtual_attribute (decl);
        !          3571:     }
        !          3572:   if (DECL_ABSTRACT (decl))
        !          3573:     equate_decl_number_to_die_number (decl);
        !          3574:   else
        !          3575:     {
        !          3576:       /* Avoid getting screwed up in cases where a function was declared
        !          3577:         static but where no definition was ever given for it.  */
        !          3578: 
        !          3579:       if (TREE_ASM_WRITTEN (decl))
        !          3580:        {
        !          3581:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3582:          low_pc_attribute (function_start_label (decl));
        !          3583:          sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number);
        !          3584:          high_pc_attribute (label);
        !          3585:          sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number);
        !          3586:          body_begin_attribute (label);
        !          3587:          sprintf (label, BODY_END_LABEL_FMT, current_funcdef_number);
        !          3588:          body_end_attribute (label);
        !          3589:        }
        !          3590:     }
        !          3591: }
        !          3592: 
        !          3593: static void
        !          3594: output_subroutine_type_die (arg)
        !          3595:      register void *arg;
        !          3596: {
        !          3597:   register tree type = arg;
        !          3598:   register tree return_type = TREE_TYPE (type);
        !          3599: 
        !          3600:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_subroutine_type);
        !          3601:   sibling_attribute ();
        !          3602:   dienum_push ();
        !          3603:   equate_type_number_to_die_number (type);
        !          3604:   prototyped_attribute (type);
        !          3605:   member_attribute (TYPE_CONTEXT (type));
        !          3606:   type_attribute (return_type, 0, 0);
        !          3607: }
        !          3608: 
        !          3609: static void
        !          3610: output_typedef_die (arg)
        !          3611:      register void *arg;
        !          3612: {
        !          3613:   register tree decl = arg;
        !          3614:   register tree origin = decl_ultimate_origin (decl);
        !          3615: 
        !          3616:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_typedef);
        !          3617:   sibling_attribute ();
        !          3618:   if (origin != NULL)
        !          3619:     abstract_origin_attribute (origin);
        !          3620:   else
        !          3621:     {
        !          3622:       name_and_src_coords_attributes (decl);
        !          3623:       member_attribute (DECL_CONTEXT (decl));
        !          3624:       type_attribute (TREE_TYPE (decl),
        !          3625:                      TREE_READONLY (decl), TREE_THIS_VOLATILE (decl));
        !          3626:     }
        !          3627:   if (DECL_ABSTRACT (decl))
        !          3628:     equate_decl_number_to_die_number (decl);
        !          3629: }
        !          3630: 
        !          3631: static void
        !          3632: output_union_type_die (arg)
        !          3633:      register void *arg;
        !          3634: {
        !          3635:   register tree type = arg;
        !          3636: 
        !          3637:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_union_type);
        !          3638:   sibling_attribute ();
        !          3639:   equate_type_number_to_die_number (type);
        !          3640:   name_attribute (type_tag (type));
        !          3641:   member_attribute (TYPE_CONTEXT (type));
        !          3642: 
        !          3643:   /* If this type has been completed, then give it a byte_size attribute
        !          3644:      and prepare to give a list of members.  Otherwise, don't do either of
        !          3645:      these things.  In the latter case, we will not be generating a list
        !          3646:      of members (since we don't have any idea what they might be for an
        !          3647:      incomplete type). */
        !          3648: 
        !          3649:   if (TYPE_SIZE (type))
        !          3650:     {
        !          3651:       dienum_push ();
        !          3652:       byte_size_attribute (type);
        !          3653:     }
        !          3654: }
        !          3655: 
        !          3656: /* Generate a special type of DIE used as a stand-in for a trailing ellipsis
        !          3657:    at the end of an (ANSI prototyped) formal parameters list.  */
        !          3658: 
        !          3659: static void
        !          3660: output_unspecified_parameters_die (arg)
        !          3661:      register void *arg;
        !          3662: {
        !          3663:   register tree decl_or_type = arg;
        !          3664: 
        !          3665:   ASM_OUTPUT_DWARF_TAG (asm_out_file, TAG_unspecified_parameters);
        !          3666:   sibling_attribute ();
        !          3667: 
        !          3668:   /* This kludge is here only for the sake of being compatible with what
        !          3669:      the USL CI5 C compiler does.  The specification of Dwarf Version 1
        !          3670:      doesn't say that TAG_unspecified_parameters DIEs should contain any
        !          3671:      attributes other than the AT_sibling attribute, but they are certainly
        !          3672:      allowed to contain additional attributes, and the CI5 compiler
        !          3673:      generates AT_name, AT_fund_type, and AT_location attributes within
        !          3674:      TAG_unspecified_parameters DIEs which appear in the child lists for
        !          3675:      DIEs representing function definitions, so we do likewise here.  */
        !          3676: 
        !          3677:   if (TREE_CODE (decl_or_type) == FUNCTION_DECL && DECL_INITIAL (decl_or_type))
        !          3678:     {
        !          3679:       name_attribute ("...");
        !          3680:       fund_type_attribute (FT_pointer);
        !          3681:       /* location_attribute (?); */
        !          3682:     }
        !          3683: }
        !          3684: 
        !          3685: static void
        !          3686: output_padded_null_die (arg)
        !          3687:      register void *arg;
        !          3688: {
        !          3689:   ASM_OUTPUT_ALIGN (asm_out_file, 2);  /* 2**2 == 4 */
        !          3690: }
        !          3691: 
        !          3692: /*************************** end of DIEs *********************************/
        !          3693: 
        !          3694: /* Generate some type of DIE.  This routine generates the generic outer
        !          3695:    wrapper stuff which goes around all types of DIE's (regardless of their
        !          3696:    TAGs.  All forms of DIEs start with a DIE-specific label, followed by a
        !          3697:    DIE-length word, followed by the guts of the DIE itself.  After the guts
        !          3698:    of the DIE, there must always be a terminator label for the DIE.  */
        !          3699: 
        !          3700: static void
        !          3701: output_die (die_specific_output_function, param)
        !          3702:      register void (*die_specific_output_function)();
        !          3703:      register void *param;
        !          3704: {
        !          3705:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3706:   char end_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3707: 
        !          3708:   current_dienum = NEXT_DIE_NUM;
        !          3709:   NEXT_DIE_NUM = next_unused_dienum;
        !          3710: 
        !          3711:   sprintf (begin_label, DIE_BEGIN_LABEL_FMT, current_dienum);
        !          3712:   sprintf (end_label, DIE_END_LABEL_FMT, current_dienum);
        !          3713: 
        !          3714:   /* Write a label which will act as the name for the start of this DIE.  */
        !          3715: 
        !          3716:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          3717: 
        !          3718:   /* Write the DIE-length word.         */
        !          3719: 
        !          3720:   ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, end_label, begin_label);
        !          3721: 
        !          3722:   /* Fill in the guts of the DIE.  */
        !          3723: 
        !          3724:   next_unused_dienum++;
        !          3725:   die_specific_output_function (param);
        !          3726: 
        !          3727:   /* Write a label which will act as the name for the end of this DIE. */
        !          3728: 
        !          3729:   ASM_OUTPUT_LABEL (asm_out_file, end_label);
        !          3730: }
        !          3731: 
        !          3732: static void
        !          3733: end_sibling_chain ()
        !          3734: {
        !          3735:   char begin_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          3736: 
        !          3737:   current_dienum = NEXT_DIE_NUM;
        !          3738:   NEXT_DIE_NUM = next_unused_dienum;
        !          3739: 
        !          3740:   sprintf (begin_label, DIE_BEGIN_LABEL_FMT, current_dienum);
        !          3741: 
        !          3742:   /* Write a label which will act as the name for the start of this DIE.  */
        !          3743: 
        !          3744:   ASM_OUTPUT_LABEL (asm_out_file, begin_label);
        !          3745: 
        !          3746:   /* Write the DIE-length word.         */
        !          3747: 
        !          3748:   ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 4);
        !          3749: 
        !          3750:   dienum_pop ();
        !          3751: }
        !          3752: 
        !          3753: /* Generate a list of nameless TAG_formal_parameter DIEs (and perhaps a
        !          3754:    TAG_unspecified_parameters DIE) to represent the types of the formal
        !          3755:    parameters as specified in some function type specification (except
        !          3756:    for those which appear as part of a function *definition*).
        !          3757: 
        !          3758:    Note that we must be careful here to output all of the parameter DIEs
        !          3759:    *before* we output any DIEs needed to represent the types of the formal
        !          3760:    parameters.  This keeps svr4 SDB happy because it (incorrectly) thinks
        !          3761:    that the first non-parameter DIE it sees ends the formal parameter list.
        !          3762: */
        !          3763: 
        !          3764: static void
        !          3765: output_formal_types (function_or_method_type)
        !          3766:      register tree function_or_method_type;
        !          3767: {
        !          3768:   register tree link;
        !          3769:   register tree formal_type = NULL;
        !          3770:   register tree first_parm_type = TYPE_ARG_TYPES (function_or_method_type);
        !          3771: 
        !          3772:   /* In the case where we are generating a formal types list for a C++
        !          3773:      non-static member function type, skip over the first thing on the
        !          3774:      TYPE_ARG_TYPES list because it only represents the type of the
        !          3775:      hidden `this pointer'.  The debugger should be able to figure
        !          3776:      out (without being explicitly told) that this non-static member
        !          3777:      function type takes a `this pointer' and should be able to figure
        !          3778:      what the type of that hidden parameter is from the AT_member
        !          3779:      attribute of the parent TAG_subroutine_type DIE.  */
        !          3780: 
        !          3781:   if (TREE_CODE (function_or_method_type) == METHOD_TYPE)
        !          3782:     first_parm_type = TREE_CHAIN (first_parm_type);
        !          3783: 
        !          3784:   /* Make our first pass over the list of formal parameter types and output
        !          3785:      a TAG_formal_parameter DIE for each one.  */
        !          3786: 
        !          3787:   for (link = first_parm_type; link; link = TREE_CHAIN (link))
        !          3788:     {
        !          3789:       formal_type = TREE_VALUE (link);
        !          3790:       if (formal_type == void_type_node)
        !          3791:        break;
        !          3792: 
        !          3793:       /* Output a (nameless) DIE to represent the formal parameter itself.  */
        !          3794: 
        !          3795:       output_die (output_formal_parameter_die, formal_type);
        !          3796:     }
        !          3797: 
        !          3798:   /* If this function type has an ellipsis, add a TAG_unspecified_parameters
        !          3799:      DIE to the end of the parameter list.  */
        !          3800: 
        !          3801:   if (formal_type != void_type_node)
        !          3802:     output_die (output_unspecified_parameters_die, function_or_method_type);
        !          3803: 
        !          3804:   /* Make our second (and final) pass over the list of formal parameter types
        !          3805:      and output DIEs to represent those types (as necessary).  */
        !          3806: 
        !          3807:   for (link = TYPE_ARG_TYPES (function_or_method_type);
        !          3808:        link;
        !          3809:        link = TREE_CHAIN (link))
        !          3810:     {
        !          3811:       formal_type = TREE_VALUE (link);
        !          3812:       if (formal_type == void_type_node)
        !          3813:        break;
        !          3814: 
        !          3815:       output_type (formal_type, function_or_method_type);
        !          3816:     }
        !          3817: }
        !          3818: 
        !          3819: /* Remember a type in the pending_types_list.  */
        !          3820: 
        !          3821: static void
        !          3822: pend_type (type)
        !          3823:      register tree type;
        !          3824: {
        !          3825:   if (pending_types == pending_types_allocated)
        !          3826:     {
        !          3827:       pending_types_allocated += PENDING_TYPES_INCREMENT;
        !          3828:       pending_types_list
        !          3829:        = (tree *) xrealloc (pending_types_list,
        !          3830:                             sizeof (tree) * pending_types_allocated);
        !          3831:     }
        !          3832:   pending_types_list[pending_types++] = type;
        !          3833: 
        !          3834:   /* Mark the pending type as having been output already (even though
        !          3835:      it hasn't been).  This prevents the type from being added to the
        !          3836:      pending_types_list more than once.  */
        !          3837: 
        !          3838:   TREE_ASM_WRITTEN (type) = 1;
        !          3839: }
        !          3840: 
        !          3841: /* Return non-zero if it is legitimate to output DIEs to represent a
        !          3842:    given type while we are generating the list of child DIEs for some
        !          3843:    DIE (e.g. a function or lexical block DIE) associated with a given scope.
        !          3844: 
        !          3845:    See the comments within the function for a description of when it is
        !          3846:    considered legitimate to output DIEs for various kinds of types.
        !          3847: 
        !          3848:    Note that TYPE_CONTEXT(type) may be NULL (to indicate global scope)
        !          3849:    or it may point to a BLOCK node (for types local to a block), or to a
        !          3850:    FUNCTION_DECL node (for types local to the heading of some function
        !          3851:    definition), or to a FUNCTION_TYPE node (for types local to the
        !          3852:    prototyped parameter list of a function type specification), or to a
        !          3853:    RECORD_TYPE, UNION_TYPE, or QUAL_UNION_TYPE node
        !          3854:    (in the case of C++ nested types).
        !          3855: 
        !          3856:    The `scope' parameter should likewise be NULL or should point to a
        !          3857:    BLOCK node, a FUNCTION_DECL node, a FUNCTION_TYPE node, a RECORD_TYPE
        !          3858:    node, a UNION_TYPE node, or a QUAL_UNION_TYPE node.
        !          3859: 
        !          3860:    This function is used only for deciding when to "pend" and when to
        !          3861:    "un-pend" types to/from the pending_types_list.
        !          3862: 
        !          3863:    Note that we sometimes make use of this "type pending" feature in a
        !          3864:    rather twisted way to temporarily delay the production of DIEs for the
        !          3865:    types of formal parameters.  (We do this just to make svr4 SDB happy.)
        !          3866:    It order to delay the production of DIEs representing types of formal
        !          3867:    parameters, callers of this function supply `fake_containing_scope' as
        !          3868:    the `scope' parameter to this function.  Given that fake_containing_scope
        !          3869:    is a tagged type which is *not* the containing scope for *any* other type,
        !          3870:    the desired effect is achieved, i.e. output of DIEs representing types
        !          3871:    is temporarily suspended, and any type DIEs which would have otherwise
        !          3872:    been output are instead placed onto the pending_types_list.  Later on,
        !          3873:    we force these (temporarily pended) types to be output simply by calling
        !          3874:    `output_pending_types_for_scope' with an actual argument equal to the
        !          3875:    true scope of the types we temporarily pended.
        !          3876: */
        !          3877: 
        !          3878: inline int
        !          3879: type_ok_for_scope (type, scope)
        !          3880:     register tree type;
        !          3881:     register tree scope;
        !          3882: {
        !          3883:   /* Tagged types (i.e. struct, union, and enum types) must always be
        !          3884:      output only in the scopes where they actually belong (or else the
        !          3885:      scoping of their own tag names and the scoping of their member
        !          3886:      names will be incorrect).  Non-tagged-types on the other hand can
        !          3887:      generally be output anywhere, except that svr4 SDB really doesn't
        !          3888:      want to see them nested within struct or union types, so here we
        !          3889:      say it is always OK to immediately output any such a (non-tagged)
        !          3890:      type, so long as we are not within such a context.  Note that the
        !          3891:      only kinds of non-tagged types which we will be dealing with here
        !          3892:      (for C and C++ anyway) will be array types and function types.  */
        !          3893: 
        !          3894:   return is_tagged_type (type)
        !          3895:         ? (TYPE_CONTEXT (type) == scope)
        !          3896:         : (scope == NULL_TREE || ! is_tagged_type (scope));
        !          3897: }
        !          3898: 
        !          3899: /* Output any pending types (from the pending_types list) which we can output
        !          3900:    now (taking into account the scope that we are working on now).
        !          3901: 
        !          3902:    For each type output, remove the given type from the pending_types_list
        !          3903:    *before* we try to output it.
        !          3904: 
        !          3905:    Note that we have to process the list in beginning-to-end order,
        !          3906:    because the call made here to output_type may cause yet more types
        !          3907:    to be added to the end of the list, and we may have to output some
        !          3908:    of them too.
        !          3909: */
        !          3910: 
        !          3911: static void
        !          3912: output_pending_types_for_scope (containing_scope)
        !          3913:      register tree containing_scope;
        !          3914: {
        !          3915:   register unsigned i;
        !          3916: 
        !          3917:   for (i = 0; i < pending_types; )
        !          3918:     {
        !          3919:       register tree type = pending_types_list[i];
        !          3920: 
        !          3921:       if (type_ok_for_scope (type, containing_scope))
        !          3922:        {
        !          3923:          register tree *mover;
        !          3924:          register tree *limit;
        !          3925: 
        !          3926:          pending_types--;
        !          3927:          limit = &pending_types_list[pending_types];
        !          3928:          for (mover = &pending_types_list[i]; mover < limit; mover++)
        !          3929:            *mover = *(mover+1);
        !          3930: 
        !          3931:          /* Un-mark the type as having been output already (because it
        !          3932:             hasn't been, really).  Then call output_type to generate a
        !          3933:             Dwarf representation of it.  */
        !          3934: 
        !          3935:          TREE_ASM_WRITTEN (type) = 0;
        !          3936:          output_type (type, containing_scope);
        !          3937: 
        !          3938:          /* Don't increment the loop counter in this case because we
        !          3939:             have shifted all of the subsequent pending types down one
        !          3940:             element in the pending_types_list array.  */
        !          3941:        }
        !          3942:       else
        !          3943:        i++;
        !          3944:     }
        !          3945: }
        !          3946: 
        !          3947: static void
        !          3948: output_type (type, containing_scope)
        !          3949:      register tree type;
        !          3950:      register tree containing_scope;
        !          3951: {
        !          3952:   if (type == 0 || type == error_mark_node)
        !          3953:     return;
        !          3954: 
        !          3955:   /* We are going to output a DIE to represent the unqualified version of
        !          3956:      of this type (i.e. without any const or volatile qualifiers) so get
        !          3957:      the main variant (i.e. the unqualified version) of this type now.  */
        !          3958: 
        !          3959:   type = type_main_variant (type);
        !          3960: 
        !          3961:   if (TREE_ASM_WRITTEN (type))
        !          3962:     return;
        !          3963: 
        !          3964:   /* Don't generate any DIEs for this type now unless it is OK to do so
        !          3965:      (based upon what `type_ok_for_scope' tells us).  */
        !          3966: 
        !          3967:   if (! type_ok_for_scope (type, containing_scope))
        !          3968:     {
        !          3969:       pend_type (type);
        !          3970:       return;
        !          3971:     }
        !          3972: 
        !          3973:   switch (TREE_CODE (type))
        !          3974:     {
        !          3975:       case ERROR_MARK:
        !          3976:        break;
        !          3977: 
        !          3978:       case POINTER_TYPE:
        !          3979:       case REFERENCE_TYPE:
        !          3980:        /* For these types, all that is required is that we output a DIE
        !          3981:           (or a set of DIEs) to represent the "basis" type.  */
        !          3982:        output_type (TREE_TYPE (type), containing_scope);
        !          3983:        break;
        !          3984: 
        !          3985:       case OFFSET_TYPE:
        !          3986:        /* This code is used for C++ pointer-to-data-member types.  */
        !          3987:        /* Output a description of the relevant class type.  */
        !          3988:        output_type (TYPE_OFFSET_BASETYPE (type), containing_scope);
        !          3989:        /* Output a description of the type of the object pointed to.  */
        !          3990:        output_type (TREE_TYPE (type), containing_scope);
        !          3991:        /* Now output a DIE to represent this pointer-to-data-member type
        !          3992:           itself.  */
        !          3993:        output_die (output_ptr_to_mbr_type_die, type);
        !          3994:        break;
        !          3995: 
        !          3996:       case SET_TYPE:
        !          3997:        output_type (TYPE_DOMAIN (type), containing_scope);
        !          3998:        output_die (output_set_type_die, type);
        !          3999:        break;
        !          4000: 
        !          4001:       case FILE_TYPE:
        !          4002:        output_type (TREE_TYPE (type), containing_scope);
        !          4003:        abort ();       /* No way to represent these in Dwarf yet!  */
        !          4004:        break;
        !          4005: 
        !          4006:       case STRING_TYPE:
        !          4007:        output_type (TREE_TYPE (type), containing_scope);
        !          4008:        output_die (output_string_type_die, type);
        !          4009:        break;
        !          4010: 
        !          4011:       case FUNCTION_TYPE:
        !          4012:        /* Force out return type (in case it wasn't forced out already).  */
        !          4013:        output_type (TREE_TYPE (type), containing_scope);
        !          4014:        output_die (output_subroutine_type_die, type);
        !          4015:        output_formal_types (type);
        !          4016:        end_sibling_chain ();
        !          4017:        break;
        !          4018: 
        !          4019:       case METHOD_TYPE:
        !          4020:        /* Force out return type (in case it wasn't forced out already).  */
        !          4021:        output_type (TREE_TYPE (type), containing_scope);
        !          4022:        output_die (output_subroutine_type_die, type);
        !          4023:        output_formal_types (type);
        !          4024:        end_sibling_chain ();
        !          4025:        break;
        !          4026: 
        !          4027:       case ARRAY_TYPE:
        !          4028:        {
        !          4029:          register tree element_type;
        !          4030: 
        !          4031:          element_type = TREE_TYPE (type);
        !          4032:          while (TREE_CODE (element_type) == ARRAY_TYPE)
        !          4033:            element_type = TREE_TYPE (element_type);
        !          4034: 
        !          4035:          output_type (element_type, containing_scope);
        !          4036:          output_die (output_array_type_die, type);
        !          4037:        }
        !          4038:        break;
        !          4039: 
        !          4040:       case ENUMERAL_TYPE:
        !          4041:       case RECORD_TYPE:
        !          4042:       case UNION_TYPE:
        !          4043:       case QUAL_UNION_TYPE:
        !          4044: 
        !          4045:        /* For a non-file-scope tagged type, we can always go ahead and
        !          4046:           output a Dwarf description of this type right now, even if
        !          4047:           the type in question is still incomplete, because if this
        !          4048:           local type *was* ever completed anywhere within its scope,
        !          4049:           that complete definition would already have been attached to
        !          4050:           this RECORD_TYPE, UNION_TYPE, QUAL_UNION_TYPE or ENUMERAL_TYPE
        !          4051:           node by the time we reach this point.  That's true because of the
        !          4052:           way the front-end does its processing of file-scope declarations (of
        !          4053:           functions and class types) within which other types might be
        !          4054:           nested.  The C and C++ front-ends always gobble up such "local
        !          4055:           scope" things en-mass before they try to output *any* debugging
        !          4056:           information for any of the stuff contained inside them and thus,
        !          4057:           we get the benefit here of what is (in effect) a pre-resolution
        !          4058:           of forward references to tagged types in local scopes.
        !          4059: 
        !          4060:           Note however that for file-scope tagged types we cannot assume
        !          4061:           that such pre-resolution of forward references has taken place.
        !          4062:           A given file-scope tagged type may appear to be incomplete when
        !          4063:           we reach this point, but it may yet be given a full definition
        !          4064:           (at file-scope) later on during compilation.  In order to avoid
        !          4065:           generating a premature (and possibly incorrect) set of Dwarf
        !          4066:           DIEs for such (as yet incomplete) file-scope tagged types, we
        !          4067:           generate nothing at all for as-yet incomplete file-scope tagged
        !          4068:           types here unless we are making our special "finalization" pass
        !          4069:           for file-scope things at the very end of compilation.  At that
        !          4070:           time, we will certainly know as much about each file-scope tagged
        !          4071:           type as we are ever going to know, so at that point in time, we
        !          4072:           can safely generate correct Dwarf descriptions for these file-
        !          4073:           scope tagged types.
        !          4074:        */
        !          4075: 
        !          4076:        if (TYPE_SIZE (type) == 0 && TYPE_CONTEXT (type) == NULL && !finalizing)
        !          4077:          return;       /* EARLY EXIT!  Avoid setting TREE_ASM_WRITTEN.  */
        !          4078: 
        !          4079:        /* Prevent infinite recursion in cases where the type of some
        !          4080:           member of this type is expressed in terms of this type itself.  */
        !          4081: 
        !          4082:        TREE_ASM_WRITTEN (type) = 1;
        !          4083: 
        !          4084:        /* Output a DIE to represent the tagged type itself.  */
        !          4085: 
        !          4086:        switch (TREE_CODE (type))
        !          4087:          {
        !          4088:          case ENUMERAL_TYPE:
        !          4089:            output_die (output_enumeration_type_die, type);
        !          4090:            return;  /* a special case -- nothing left to do so just return */
        !          4091: 
        !          4092:          case RECORD_TYPE:
        !          4093:            output_die (output_structure_type_die, type);
        !          4094:            break;
        !          4095: 
        !          4096:          case UNION_TYPE:
        !          4097:          case QUAL_UNION_TYPE:
        !          4098:            output_die (output_union_type_die, type);
        !          4099:            break;
        !          4100: 
        !          4101:          default:
        !          4102:            abort ();   /* Should never happen.  */
        !          4103:          }
        !          4104: 
        !          4105:        /* If this is not an incomplete type, output descriptions of
        !          4106:           each of its members.
        !          4107: 
        !          4108:           Note that as we output the DIEs necessary to represent the
        !          4109:           members of this record or union type, we will also be trying
        !          4110:           to output DIEs to represent the *types* of those members.
        !          4111:           However the `output_type' function (above) will specifically
        !          4112:           avoid generating type DIEs for member types *within* the list
        !          4113:           of member DIEs for this (containing) type execpt for those
        !          4114:           types (of members) which are explicitly marked as also being
        !          4115:           members of this (containing) type themselves.  The g++ front-
        !          4116:           end can force any given type to be treated as a member of some
        !          4117:           other (containing) type by setting the TYPE_CONTEXT of the
        !          4118:           given (member) type to point to the TREE node representing the
        !          4119:           appropriate (containing) type.
        !          4120:        */
        !          4121: 
        !          4122:        if (TYPE_SIZE (type))
        !          4123:          {
        !          4124:            {
        !          4125:              register tree normal_member;
        !          4126: 
        !          4127:              /* First output info about the data members and type members.  */
        !          4128: 
        !          4129:              for (normal_member = TYPE_FIELDS (type);
        !          4130:                   normal_member;
        !          4131:                   normal_member = TREE_CHAIN (normal_member))
        !          4132:                output_decl (normal_member, type);
        !          4133:            }
        !          4134: 
        !          4135:            {
        !          4136:              register tree vec_base;
        !          4137: 
        !          4138:              /* Now output info about the function members (if any).  */
        !          4139: 
        !          4140:              vec_base = TYPE_METHODS (type);
        !          4141:              if (vec_base)
        !          4142:                {
        !          4143:                  register tree first_func_member = TREE_VEC_ELT (vec_base, 0);
        !          4144:                  register tree func_member;
        !          4145: 
        !          4146:                  /* This isn't documented, but the first element of the
        !          4147:                     vector of member functions can be NULL in cases where
        !          4148:                     the class type in question didn't have either a
        !          4149:                     constructor or a destructor declared for it.  We have
        !          4150:                     to make allowances for that here.  */
        !          4151: 
        !          4152:                  if (first_func_member == NULL)
        !          4153:                    first_func_member = TREE_VEC_ELT (vec_base, 1);
        !          4154: 
        !          4155:                  for (func_member = first_func_member;
        !          4156:                       func_member;
        !          4157:                       func_member = TREE_CHAIN (func_member))
        !          4158:                    output_decl (func_member, type);
        !          4159:                }
        !          4160:            }
        !          4161: 
        !          4162:            /* RECORD_TYPEs, UNION_TYPEs, and QUAL_UNION_TYPEs are themselves
        !          4163:               scopes (at least in C++) so we must now output any nested
        !          4164:               pending types which are local just to this type.  */
        !          4165: 
        !          4166:            output_pending_types_for_scope (type);
        !          4167: 
        !          4168:            end_sibling_chain ();       /* Terminate member chain.  */
        !          4169:          }
        !          4170: 
        !          4171:        break;
        !          4172: 
        !          4173:       case VOID_TYPE:
        !          4174:       case INTEGER_TYPE:
        !          4175:       case REAL_TYPE:
        !          4176:       case COMPLEX_TYPE:
        !          4177:       case BOOLEAN_TYPE:
        !          4178:       case CHAR_TYPE:
        !          4179:        break;          /* No DIEs needed for fundamental types.  */
        !          4180: 
        !          4181:       case LANG_TYPE:  /* No Dwarf representation currently defined.  */
        !          4182:        break;
        !          4183: 
        !          4184:       default:
        !          4185:        abort ();
        !          4186:     }
        !          4187: 
        !          4188:   TREE_ASM_WRITTEN (type) = 1;
        !          4189: }
        !          4190: 
        !          4191: static void
        !          4192: output_tagged_type_instantiation (type)
        !          4193:      register tree type;
        !          4194: {
        !          4195:   if (type == 0 || type == error_mark_node)
        !          4196:     return;
        !          4197: 
        !          4198:   /* We are going to output a DIE to represent the unqualified version of
        !          4199:      of this type (i.e. without any const or volatile qualifiers) so make
        !          4200:      sure that we have the main variant (i.e. the unqualified version) of
        !          4201:      this type now.  */
        !          4202: 
        !          4203:   assert (type == type_main_variant (type));
        !          4204: 
        !          4205:   assert (TREE_ASM_WRITTEN (type));
        !          4206: 
        !          4207:   switch (TREE_CODE (type))
        !          4208:     {
        !          4209:       case ERROR_MARK:
        !          4210:        break;
        !          4211: 
        !          4212:       case ENUMERAL_TYPE:
        !          4213:        output_die (output_inlined_enumeration_type_die, type);
        !          4214:        break;
        !          4215: 
        !          4216:       case RECORD_TYPE:
        !          4217:        output_die (output_inlined_structure_type_die, type);
        !          4218:        break;
        !          4219: 
        !          4220:       case UNION_TYPE:
        !          4221:       case QUAL_UNION_TYPE:
        !          4222:        output_die (output_inlined_union_type_die, type);
        !          4223:        break;
        !          4224: 
        !          4225:       default:
        !          4226:        abort ();       /* Should never happen.  */
        !          4227:     }
        !          4228: }
        !          4229: 
        !          4230: /* Output a TAG_lexical_block DIE followed by DIEs to represent all of
        !          4231:    the things which are local to the given block.  */
        !          4232: 
        !          4233: static void
        !          4234: output_block (stmt)
        !          4235:     register tree stmt;
        !          4236: {
        !          4237:   register int must_output_die = 0;
        !          4238:   register tree origin;
        !          4239:   register enum tree_code origin_code;
        !          4240: 
        !          4241:   /* Ignore blocks never really used to make RTL.  */
        !          4242: 
        !          4243:   if (! stmt || ! TREE_USED (stmt))
        !          4244:     return;
        !          4245: 
        !          4246:   /* Determine the "ultimate origin" of this block.  This block may be an
        !          4247:      inlined instance of an inlined instance of inline function, so we
        !          4248:      have to trace all of the way back through the origin chain to find
        !          4249:      out what sort of node actually served as the original seed for the
        !          4250:      creation of the current block.  */
        !          4251: 
        !          4252:   origin = block_ultimate_origin (stmt);
        !          4253:   origin_code = (origin != NULL) ? TREE_CODE (origin) : ERROR_MARK;
        !          4254: 
        !          4255:   /* Determine if we need to output any Dwarf DIEs at all to represent this
        !          4256:      block.  */
        !          4257: 
        !          4258:   if (origin_code == FUNCTION_DECL)
        !          4259:     /* The outer scopes for inlinings *must* always be represented.  We
        !          4260:        generate TAG_inlined_subroutine DIEs for them.  (See below.)  */
        !          4261:     must_output_die = 1;
        !          4262:   else
        !          4263:     {
        !          4264:       /* In the case where the current block represents an inlining of the
        !          4265:         "body block" of an inline function, we must *NOT* output any DIE
        !          4266:         for this block because we have already output a DIE to represent
        !          4267:         the whole inlined function scope and the "body block" of any
        !          4268:         function doesn't really represent a different scope according to
        !          4269:         ANSI C rules.  So we check here to make sure that this block does
        !          4270:         not represent a "body block inlining" before trying to set the
        !          4271:         `must_output_die' flag.  */
        !          4272: 
        !          4273:       if (origin == NULL || ! is_body_block (origin))
        !          4274:        {
        !          4275:          /* Determine if this block directly contains any "significant"
        !          4276:             local declarations which we will need to output DIEs for.  */
        !          4277: 
        !          4278:          if (debug_info_level > DINFO_LEVEL_TERSE)
        !          4279:            /* We are not in terse mode so *any* local declaration counts
        !          4280:               as being a "significant" one.  */
        !          4281:            must_output_die = (BLOCK_VARS (stmt) != NULL);
        !          4282:          else
        !          4283:            {
        !          4284:              register tree decl;
        !          4285: 
        !          4286:              /* We are in terse mode, so only local (nested) function
        !          4287:                 definitions count as "significant" local declarations.  */
        !          4288: 
        !          4289:              for (decl = BLOCK_VARS (stmt); decl; decl = TREE_CHAIN (decl))
        !          4290:                if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl))
        !          4291:                  {
        !          4292:                    must_output_die = 1;
        !          4293:                    break;
        !          4294:                  }
        !          4295:            }
        !          4296:        }
        !          4297:     }
        !          4298: 
        !          4299:   /* It would be a waste of space to generate a Dwarf TAG_lexical_block
        !          4300:      DIE for any block which contains no significant local declarations
        !          4301:      at all.  Rather, in such cases we just call `output_decls_for_scope'
        !          4302:      so that any needed Dwarf info for any sub-blocks will get properly
        !          4303:      generated.  Note that in terse mode, our definition of what constitutes
        !          4304:      a "significant" local declaration gets restricted to include only
        !          4305:      inlined function instances and local (nested) function definitions.  */
        !          4306: 
        !          4307:   if (must_output_die)
        !          4308:     {
        !          4309:       output_die ((origin_code == FUNCTION_DECL)
        !          4310:                    ? output_inlined_subroutine_die
        !          4311:                    : output_lexical_block_die,
        !          4312:                  stmt);
        !          4313:       output_decls_for_scope (stmt);
        !          4314:       end_sibling_chain ();
        !          4315:     }
        !          4316:   else
        !          4317:     output_decls_for_scope (stmt);
        !          4318: }
        !          4319: 
        !          4320: /* Output all of the decls declared within a given scope (also called
        !          4321:    a `binding contour') and (recursively) all of it's sub-blocks.  */
        !          4322: 
        !          4323: static void
        !          4324: output_decls_for_scope (stmt)
        !          4325:      register tree stmt;
        !          4326: {
        !          4327:   /* Ignore blocks never really used to make RTL.  */
        !          4328: 
        !          4329:   if (! stmt || ! TREE_USED (stmt))
        !          4330:     return;
        !          4331: 
        !          4332:   if (! BLOCK_ABSTRACT (stmt))
        !          4333:     next_block_number++;
        !          4334: 
        !          4335:   /* Output the DIEs to represent all of the data objects, functions,
        !          4336:      typedefs, and tagged types declared directly within this block
        !          4337:      but not within any nested sub-blocks.  */
        !          4338: 
        !          4339:   {
        !          4340:     register tree decl;
        !          4341: 
        !          4342:     for (decl = BLOCK_VARS (stmt); decl; decl = TREE_CHAIN (decl))
        !          4343:       output_decl (decl, stmt);
        !          4344:   }
        !          4345: 
        !          4346:   output_pending_types_for_scope (stmt);
        !          4347: 
        !          4348:   /* Output the DIEs to represent all sub-blocks (and the items declared
        !          4349:      therein) of this block.    */
        !          4350: 
        !          4351:   {
        !          4352:     register tree subblocks;
        !          4353: 
        !          4354:     for (subblocks = BLOCK_SUBBLOCKS (stmt);
        !          4355:          subblocks;
        !          4356:          subblocks = BLOCK_CHAIN (subblocks))
        !          4357:       output_block (subblocks);
        !          4358:   }
        !          4359: }
        !          4360: 
        !          4361: /* Output Dwarf .debug information for a decl described by DECL.  */
        !          4362: 
        !          4363: static void
        !          4364: output_decl (decl, containing_scope)
        !          4365:      register tree decl;
        !          4366:      register tree containing_scope;
        !          4367: {
        !          4368:   /* Make a note of the decl node we are going to be working on.  We may
        !          4369:      need to give the user the source coordinates of where it appeared in
        !          4370:      case we notice (later on) that something about it looks screwy.  */
        !          4371: 
        !          4372:   dwarf_last_decl = decl;
        !          4373: 
        !          4374:   if (TREE_CODE (decl) == ERROR_MARK)
        !          4375:     return;
        !          4376: 
        !          4377:   /* If this ..._DECL node is marked to be ignored, then ignore it.
        !          4378:      But don't ignore a function definition, since that would screw
        !          4379:      up our count of blocks, and that it turn will completely screw up the
        !          4380:      the labels we will reference in subsequent AT_low_pc and AT_high_pc
        !          4381:      attributes (for subsequent blocks).  */
        !          4382: 
        !          4383:   if (DECL_IGNORED_P (decl) && TREE_CODE (decl) != FUNCTION_DECL)
        !          4384:     return;
        !          4385: 
        !          4386:   switch (TREE_CODE (decl))
        !          4387:     {
        !          4388:     case CONST_DECL:
        !          4389:       /* The individual enumerators of an enum type get output when we
        !          4390:         output the Dwarf representation of the relevant enum type itself.  */
        !          4391:       break;
        !          4392: 
        !          4393:     case FUNCTION_DECL:
        !          4394:       /* If we are in terse mode, don't output any DIEs to represent
        !          4395:         mere function declarations.  Also, if we are conforming
        !          4396:         to the DWARF version 1 specification, don't output DIEs for
        !          4397:         mere function declarations.  */
        !          4398: 
        !          4399:       if (DECL_INITIAL (decl) == NULL_TREE)
        !          4400: #if (DWARF_VERSION > 1)
        !          4401:        if (debug_info_level <= DINFO_LEVEL_TERSE)
        !          4402: #endif
        !          4403:          break;
        !          4404: 
        !          4405:       /* Before we describe the FUNCTION_DECL itself, make sure that we
        !          4406:         have described its return type.  */
        !          4407: 
        !          4408:       output_type (TREE_TYPE (TREE_TYPE (decl)), containing_scope);
        !          4409: 
        !          4410:       /* If the following DIE will represent a function definition for a
        !          4411:         function with "extern" linkage, output a special "pubnames" DIE
        !          4412:         label just ahead of the actual DIE.  A reference to this label
        !          4413:         was already generated in the .debug_pubnames section sub-entry
        !          4414:         for this function definition.  */
        !          4415: 
        !          4416:       if (TREE_PUBLIC (decl))
        !          4417:        {
        !          4418:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4419: 
        !          4420:          sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number++);
        !          4421:          ASM_OUTPUT_LABEL (asm_out_file, label);
        !          4422:        }
        !          4423: 
        !          4424:       /* Now output a DIE to represent the function itself.  */
        !          4425: 
        !          4426:       output_die (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl)
        !          4427:                                ? output_global_subroutine_die
        !          4428:                                : output_local_subroutine_die,
        !          4429:                  decl);
        !          4430: 
        !          4431:       /* Now output descriptions of the arguments for this function.
        !          4432:         This gets (unnecessarily?) complex because of the fact that
        !          4433:         the DECL_ARGUMENT list for a FUNCTION_DECL doesn't indicate
        !          4434:         cases where there was a trailing `...' at the end of the formal
        !          4435:         parameter list.  In order to find out if there was a trailing
        !          4436:         ellipsis or not, we must instead look at the type associated
        !          4437:         with the FUNCTION_DECL.  This will be a node of type FUNCTION_TYPE.
        !          4438:         If the chain of type nodes hanging off of this FUNCTION_TYPE node
        !          4439:         ends with a void_type_node then there should *not* be an ellipsis
        !          4440:         at the end.  */
        !          4441: 
        !          4442:       /* In the case where we are describing a mere function declaration, all
        !          4443:         we need to do here (and all we *can* do here) is to describe
        !          4444:         the *types* of its formal parameters.  */
        !          4445: 
        !          4446:       if (DECL_INITIAL (decl) == NULL_TREE)
        !          4447:        output_formal_types (TREE_TYPE (decl));
        !          4448:       else
        !          4449:        {
        !          4450:          register tree arg_decls = DECL_ARGUMENTS (decl);
        !          4451: 
        !          4452:          {
        !          4453:            register tree last_arg;
        !          4454: 
        !          4455:            last_arg = (arg_decls && TREE_CODE (arg_decls) != ERROR_MARK)
        !          4456:                        ? tree_last (arg_decls)
        !          4457:                        : NULL;
        !          4458: 
        !          4459:            /* Generate DIEs to represent all known formal parameters, but
        !          4460:               don't do it if this looks like a varargs function.  A given
        !          4461:               function is considered to be a varargs function if (and only
        !          4462:               if) its last named argument is named `__builtin_va_alist'.  */
        !          4463: 
        !          4464:            if (! last_arg
        !          4465:                || ! DECL_NAME (last_arg)
        !          4466:                || strcmp (IDENTIFIER_POINTER (DECL_NAME (last_arg)),
        !          4467:                           "__builtin_va_alist"))
        !          4468:              {
        !          4469:                register tree parm;
        !          4470: 
        !          4471:                /* WARNING!  Kludge zone ahead!  Here we have a special
        !          4472:                   hack for svr4 SDB compatibility.  Instead of passing the
        !          4473:                   current FUNCTION_DECL node as the second parameter (i.e.
        !          4474:                   the `containing_scope' parameter) to `output_decl' (as
        !          4475:                   we ought to) we instead pass a pointer to our own private
        !          4476:                   fake_containing_scope node.  That node is a RECORD_TYPE
        !          4477:                   node which NO OTHER TYPE may ever actually be a member of.
        !          4478: 
        !          4479:                   This pointer will ultimately get passed into `output_type'
        !          4480:                   as its `containing_scope' parameter.  `Output_type' will
        !          4481:                   then perform its part in the hack... i.e. it will pend
        !          4482:                   the type of the formal parameter onto the pending_types
        !          4483:                   list.  Later on, when we are done generating the whole
        !          4484:                   sequence of formal parameter DIEs for this function
        !          4485:                   definition, we will un-pend all previously pended types
        !          4486:                   of formal parameters for this function definition.
        !          4487: 
        !          4488:                   This whole kludge prevents any type DIEs from being
        !          4489:                   mixed in with the formal parameter DIEs.  That's good
        !          4490:                   because svr4 SDB believes that the list of formal
        !          4491:                   parameter DIEs for a function ends wherever the first
        !          4492:                   non-formal-parameter DIE appears.  Thus, we have to
        !          4493:                   keep the formal parameter DIEs segregated.  They must
        !          4494:                   all appear (consecutively) at the start of the list of
        !          4495:                   children for the DIE representing the function definition.
        !          4496:                   Then (and only then) may we output any additional DIEs
        !          4497:                   needed to represent the types of these formal parameters.
        !          4498:                */
        !          4499: 
        !          4500:                for (parm = arg_decls; parm; parm = TREE_CHAIN (parm))
        !          4501:                  if (TREE_CODE (parm) == PARM_DECL)
        !          4502:                    output_decl (parm, fake_containing_scope);
        !          4503: 
        !          4504:                /* Now that we have finished generating all of the DIEs to
        !          4505:                   represent the formal parameters themselves, force out
        !          4506:                   any DIEs needed to represent their types.  We do this
        !          4507:                   simply by un-pending all previously pended types which
        !          4508:                   can legitimately go into the chain of children DIEs for
        !          4509:                   the current FUNCTION_DECL.  */
        !          4510: 
        !          4511:                output_pending_types_for_scope (decl);
        !          4512:              }
        !          4513:          }
        !          4514: 
        !          4515:          /* Now try to decide if we should put an ellipsis at the end. */
        !          4516: 
        !          4517:          {
        !          4518:            register int has_ellipsis = TRUE;   /* default assumption */
        !          4519:            register tree fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl));
        !          4520: 
        !          4521:            if (fn_arg_types)
        !          4522:              {
        !          4523:                /* This function declaration/definition was prototyped.  */
        !          4524: 
        !          4525:                /* If the list of formal argument types ends with a
        !          4526:                   void_type_node, then the formals list did *not* end
        !          4527:                   with an ellipsis.  */
        !          4528: 
        !          4529:                if (TREE_VALUE (tree_last (fn_arg_types)) == void_type_node)
        !          4530:                  has_ellipsis = FALSE;
        !          4531:              }
        !          4532:            else
        !          4533:              {
        !          4534:                /* This function declaration/definition was not prototyped.  */
        !          4535: 
        !          4536:                /* Note that all non-prototyped function *declarations* are
        !          4537:                   assumed to represent varargs functions (until proven
        !          4538:                   otherwise).  */
        !          4539: 
        !          4540:                if (DECL_INITIAL (decl)) /* if this is a func definition */
        !          4541:                  {
        !          4542:                    if (!arg_decls)
        !          4543:                      has_ellipsis = FALSE; /* no args == (void) */
        !          4544:                    else
        !          4545:                      {
        !          4546:                        /* For a non-prototyped function definition which
        !          4547:                           declares one or more formal parameters, if the name
        !          4548:                           of the first formal parameter is *not*
        !          4549:                           __builtin_va_alist then we must assume that this
        !          4550:                           is *not* a varargs function.  */
        !          4551: 
        !          4552:                        if (DECL_NAME (arg_decls)
        !          4553:                          && strcmp (IDENTIFIER_POINTER (DECL_NAME (arg_decls)),
        !          4554:                                     "__builtin_va_alist"))
        !          4555:                          has_ellipsis = FALSE;
        !          4556:                      }
        !          4557:                  }
        !          4558:              }
        !          4559: 
        !          4560:            if (has_ellipsis)
        !          4561:              output_die (output_unspecified_parameters_die, decl);
        !          4562:          }
        !          4563:        }
        !          4564: 
        !          4565:       /* Output Dwarf info for all of the stuff within the body of the
        !          4566:         function (if it has one - it may be just a declaration).  */
        !          4567: 
        !          4568:       {
        !          4569:        register tree outer_scope = DECL_INITIAL (decl);
        !          4570: 
        !          4571:        if (outer_scope && TREE_CODE (outer_scope) != ERROR_MARK)
        !          4572:          {
        !          4573:            /* Note that here, `outer_scope' is a pointer to the outermost
        !          4574:               BLOCK node created to represent a function.
        !          4575:               This outermost BLOCK actually represents the outermost
        !          4576:               binding contour for the function, i.e. the contour in which
        !          4577:               the function's formal parameters and labels get declared.
        !          4578: 
        !          4579:               Curiously, it appears that the front end doesn't actually
        !          4580:               put the PARM_DECL nodes for the current function onto the
        !          4581:               BLOCK_VARS list for this outer scope.  (They are strung
        !          4582:               off of the DECL_ARGUMENTS list for the function instead.)
        !          4583:               The BLOCK_VARS list for the `outer_scope' does provide us
        !          4584:               with a list of the LABEL_DECL nodes for the function however,
        !          4585:               and we output DWARF info for those here.
        !          4586: 
        !          4587:               Just within the `outer_scope' there will be another BLOCK
        !          4588:               node representing the function's outermost pair of curly
        !          4589:               braces.  We musn't generate a lexical_block DIE for this
        !          4590:               outermost pair of curly braces because that is not really an
        !          4591:               independent scope according to ANSI C rules.  Rather, it is
        !          4592:               the same scope in which the parameters were declared.  */
        !          4593: 
        !          4594:            {
        !          4595:              register tree label;
        !          4596: 
        !          4597:              for (label = BLOCK_VARS (outer_scope);
        !          4598:                   label;
        !          4599:                   label = TREE_CHAIN (label))
        !          4600:                output_decl (label, outer_scope);
        !          4601:            }
        !          4602: 
        !          4603:            /* Note here that `BLOCK_SUBBLOCKS (outer_scope)' points to a
        !          4604:               list of BLOCK nodes which is always only one element long.
        !          4605:               That one element represents the outermost pair of curley
        !          4606:               braces for the function body.  */
        !          4607: 
        !          4608:            output_decls_for_scope (BLOCK_SUBBLOCKS (outer_scope));
        !          4609: 
        !          4610:            /* Finally, force out any pending types which are local to the
        !          4611:               outermost block of this function definition.  These will
        !          4612:               all have a TYPE_CONTEXT which points to the FUNCTION_DECL
        !          4613:               node itself.  */
        !          4614: 
        !          4615:            output_pending_types_for_scope (decl);
        !          4616:          }
        !          4617:       }
        !          4618: 
        !          4619:       /* Generate a terminator for the list of stuff `owned' by this
        !          4620:         function.  */
        !          4621: 
        !          4622:       end_sibling_chain ();
        !          4623: 
        !          4624:       break;
        !          4625: 
        !          4626:     case TYPE_DECL:
        !          4627:       /* If we are in terse mode, don't generate any DIEs to represent
        !          4628:         any actual typedefs.  Note that even when we are in terse mode,
        !          4629:         we must still output DIEs to represent those tagged types which
        !          4630:         are used (directly or indirectly) in the specification of either
        !          4631:         a return type or a formal parameter type of some function.  */
        !          4632: 
        !          4633:       if (debug_info_level <= DINFO_LEVEL_TERSE)
        !          4634:        if (DECL_NAME (decl) != NULL
        !          4635:            || ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl)))
        !          4636:           return;
        !          4637: 
        !          4638:       /* In the special case of a null-named TYPE_DECL node (representing
        !          4639:         the declaration of some type tag), if the given TYPE_DECL is
        !          4640:         marked as having been instantiated from some other (original)
        !          4641:         TYPE_DECL node (e.g. one which was generated within the original
        !          4642:         definition of an inline function) we have to generate a special
        !          4643:         (abbreviated) TAG_structure_type, TAG_union_type, or
        !          4644:         TAG_enumeration-type DIE here.  */
        !          4645: 
        !          4646:       if (! DECL_NAME (decl) && DECL_ABSTRACT_ORIGIN (decl))
        !          4647:        {
        !          4648:          output_tagged_type_instantiation (TREE_TYPE (decl));
        !          4649:          return;
        !          4650:        }
        !          4651: 
        !          4652:       output_type (TREE_TYPE (decl), containing_scope);
        !          4653: 
        !          4654:       /* Note that unlike the gcc front end (which generates a NULL named
        !          4655:         TYPE_DECL node for each complete tagged type, each array type,
        !          4656:         and each function type node created) the g++ front end generates
        !          4657:         a *named* TYPE_DECL node for each tagged type node created.
        !          4658:         Unfortunately, these g++ TYPE_DECL nodes cause us to output many
        !          4659:         superfluous and unnecessary TAG_typedef DIEs here.  When g++ is
        !          4660:         fixed to stop generating these superfluous named TYPE_DECL nodes,
        !          4661:         the superfluous TAG_typedef DIEs will likewise cease.  */
        !          4662: 
        !          4663:       if (DECL_NAME (decl))
        !          4664:        /* Output a DIE to represent the typedef itself.  */
        !          4665:        output_die (output_typedef_die, decl);
        !          4666:       break;
        !          4667: 
        !          4668:     case LABEL_DECL:
        !          4669:       if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          4670:        output_die (output_label_die, decl);
        !          4671:       break;
        !          4672: 
        !          4673:     case VAR_DECL:
        !          4674:       /* If we are conforming to the DWARF version 1 specification, don't
        !          4675:         generated any DIEs to represent mere external object declarations.  */
        !          4676: 
        !          4677: #if (DWARF_VERSION <= 1)
        !          4678:       if (DECL_EXTERNAL (decl) && ! TREE_PUBLIC (decl))
        !          4679:        break;
        !          4680: #endif
        !          4681: 
        !          4682:       /* If we are in terse mode, don't generate any DIEs to represent
        !          4683:         any variable declarations or definitions.  */
        !          4684: 
        !          4685:       if (debug_info_level <= DINFO_LEVEL_TERSE)
        !          4686:         break;
        !          4687: 
        !          4688:       /* Output any DIEs that are needed to specify the type of this data
        !          4689:         object.  */
        !          4690: 
        !          4691:       output_type (TREE_TYPE (decl), containing_scope);
        !          4692: 
        !          4693:       /* If the following DIE will represent a data object definition for a
        !          4694:         data object with "extern" linkage, output a special "pubnames" DIE
        !          4695:         label just ahead of the actual DIE.  A reference to this label
        !          4696:         was already generated in the .debug_pubnames section sub-entry
        !          4697:         for this data object definition.  */
        !          4698: 
        !          4699:       if (TREE_PUBLIC (decl) && ! DECL_ABSTRACT (decl))
        !          4700:        {
        !          4701:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4702: 
        !          4703:          sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number++);
        !          4704:          ASM_OUTPUT_LABEL (asm_out_file, label);
        !          4705:        }
        !          4706: 
        !          4707:       /* Now output the DIE to represent the data object itself.  This gets
        !          4708:         complicated because of the possibility that the VAR_DECL really
        !          4709:         represents an inlined instance of a formal parameter for an inline
        !          4710:         function.  */
        !          4711: 
        !          4712:       {
        !          4713:         register void (*func) ();
        !          4714:        register tree origin = decl_ultimate_origin (decl);
        !          4715: 
        !          4716:        if (origin != NULL && TREE_CODE (origin) == PARM_DECL)
        !          4717:          func = output_formal_parameter_die;
        !          4718:        else
        !          4719:          {
        !          4720:            if (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
        !          4721:              func = output_global_variable_die;
        !          4722:            else
        !          4723:              func = output_local_variable_die;
        !          4724:          }
        !          4725:        output_die (func, decl);
        !          4726:       }
        !          4727:       break;
        !          4728: 
        !          4729:     case FIELD_DECL:
        !          4730:       /* Ignore the nameless fields that are used to skip bits.  */
        !          4731:       if (DECL_NAME (decl) != 0)
        !          4732:        {
        !          4733:          output_type (member_declared_type (decl), containing_scope);
        !          4734:           output_die (output_member_die, decl);
        !          4735:        }
        !          4736:       break;
        !          4737: 
        !          4738:     case PARM_DECL:
        !          4739:      /* Force out the type of this formal, if it was not forced out yet.
        !          4740:        Note that here we can run afowl of a bug in "classic" svr4 SDB.
        !          4741:        It should be able to grok the presence of type DIEs within a list
        !          4742:        of TAG_formal_parameter DIEs, but it doesn't.  */
        !          4743: 
        !          4744:       output_type (TREE_TYPE (decl), containing_scope);
        !          4745:       output_die (output_formal_parameter_die, decl);
        !          4746:       break;
        !          4747: 
        !          4748:     default:
        !          4749:       abort ();
        !          4750:     }
        !          4751: }
        !          4752: 
        !          4753: void
        !          4754: dwarfout_file_scope_decl (decl, set_finalizing)
        !          4755:      register tree decl;
        !          4756:      register int set_finalizing;
        !          4757: {
        !          4758:   if (TREE_CODE (decl) == ERROR_MARK)
        !          4759:     return;
        !          4760: 
        !          4761:   /* If this ..._DECL node is marked to be ignored, then ignore it.  We
        !          4762:      gotta hope that the node in question doesn't represent a function
        !          4763:      definition.  If it does, then totally ignoring it is bound to screw
        !          4764:      up our count of blocks, and that it turn will completely screw up the
        !          4765:      the labels we will reference in subsequent AT_low_pc and AT_high_pc
        !          4766:      attributes (for subsequent blocks).  (It's too bad that BLOCK nodes
        !          4767:      don't carry their own sequence numbers with them!)  */
        !          4768: 
        !          4769:   if (DECL_IGNORED_P (decl))
        !          4770:     {
        !          4771:       if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) != NULL)
        !          4772:        abort ();
        !          4773:       return;
        !          4774:     }
        !          4775: 
        !          4776:   switch (TREE_CODE (decl))
        !          4777:     {
        !          4778:     case FUNCTION_DECL:
        !          4779: 
        !          4780:       /* Ignore this FUNCTION_DECL if it refers to a builtin declaration of
        !          4781:         a builtin function.  Explicit programmer-supplied declarations of
        !          4782:         these same functions should NOT be ignored however.  */
        !          4783: 
        !          4784:       if (DECL_EXTERNAL (decl) && DECL_FUNCTION_CODE (decl))
        !          4785:         return;
        !          4786: 
        !          4787:       /* What we would really like to do here is to filter out all mere
        !          4788:         file-scope declarations of file-scope functions which are never
        !          4789:         referenced later within this translation unit (and keep all of
        !          4790:         ones that *are* referenced later on) but we aren't clarvoiant,
        !          4791:         so we have no idea which functions will be referenced in the
        !          4792:         future (i.e. later on within the current translation unit).
        !          4793:         So here we just ignore all file-scope function declarations
        !          4794:         which are not also definitions.  If and when the debugger needs
        !          4795:         to know something about these funcstion, it wil have to hunt
        !          4796:         around and find the DWARF information associated with the
        !          4797:         *definition* of the function.
        !          4798: 
        !          4799:         Note that we can't just check `DECL_EXTERNAL' to find out which
        !          4800:         FUNCTION_DECL nodes represent definitions and which ones represent
        !          4801:         mere declarations.  We have to check `DECL_INITIAL' instead.  That's
        !          4802:         because the C front-end supports some weird semantics for "extern
        !          4803:         inline" function definitions.  These can get inlined within the
        !          4804:         current translation unit (an thus, we need to generate DWARF info
        !          4805:         for their abstract instances so that the DWARF info for the
        !          4806:         concrete inlined instances can have something to refer to) but
        !          4807:         the compiler never generates any out-of-lines instances of such
        !          4808:         things (despite the fact that they *are* definitions).  The
        !          4809:         important point is that the C front-end marks these "extern inline"
        !          4810:         functions as DECL_EXTERNAL, but we need to generate DWARf for them
        !          4811:         anyway.
        !          4812: 
        !          4813:         Note that the C++ front-end also plays some similar games for inline
        !          4814:         function definitions appearing within include files which also
        !          4815:         contain `#pragma interface' pragmas.  */
        !          4816: 
        !          4817:       if (DECL_INITIAL (decl) == NULL_TREE)
        !          4818:        return;
        !          4819: 
        !          4820:       if (TREE_PUBLIC (decl)
        !          4821:          && ! DECL_EXTERNAL (decl)
        !          4822:          && ! DECL_ABSTRACT (decl))
        !          4823:        {
        !          4824:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4825: 
        !          4826:          /* Output a .debug_pubnames entry for a public function
        !          4827:             defined in this compilation unit.  */
        !          4828: 
        !          4829:          fputc ('\n', asm_out_file);
        !          4830:          ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
        !          4831:          sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number);
        !          4832:          ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
        !          4833:          ASM_OUTPUT_DWARF_STRING (asm_out_file,
        !          4834:                                   IDENTIFIER_POINTER (DECL_NAME (decl)));
        !          4835:          ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          4836:        }
        !          4837: 
        !          4838:       break;
        !          4839: 
        !          4840:     case VAR_DECL:
        !          4841: 
        !          4842:       /* Ignore this VAR_DECL if it refers to a file-scope extern data
        !          4843:         object declaration and if the declaration was never even
        !          4844:         referenced from within this entire compilation unit.  We
        !          4845:         suppress these DIEs in order to save space in the .debug section
        !          4846:         (by eliminating entries which are probably useless).  Note that
        !          4847:         we must not suppress block-local extern declarations (whether
        !          4848:         used or not) because that would screw-up the debugger's name
        !          4849:         lookup mechanism and cause it to miss things which really ought
        !          4850:         to be in scope at a given point.  */
        !          4851: 
        !          4852:       if (DECL_EXTERNAL (decl) && !TREE_USED (decl))
        !          4853:        return;
        !          4854: 
        !          4855:       if (TREE_PUBLIC (decl)
        !          4856:          && ! DECL_EXTERNAL (decl)
        !          4857:          && GET_CODE (DECL_RTL (decl)) == MEM
        !          4858:          && ! DECL_ABSTRACT (decl))
        !          4859:        {
        !          4860:          char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4861: 
        !          4862:          if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          4863:            {
        !          4864:              /* Output a .debug_pubnames entry for a public variable
        !          4865:                 defined in this compilation unit.  */
        !          4866: 
        !          4867:              fputc ('\n', asm_out_file);
        !          4868:              ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
        !          4869:              sprintf (label, PUB_DIE_LABEL_FMT, next_pubname_number);
        !          4870:              ASM_OUTPUT_DWARF_ADDR (asm_out_file, label);
        !          4871:              ASM_OUTPUT_DWARF_STRING (asm_out_file,
        !          4872:                                       IDENTIFIER_POINTER (DECL_NAME (decl)));
        !          4873:              ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          4874:            }
        !          4875: 
        !          4876:          if (DECL_INITIAL (decl) == NULL)
        !          4877:            {
        !          4878:              /* Output a .debug_aranges entry for a public variable
        !          4879:                 which is tentatively defined in this compilation unit.  */
        !          4880: 
        !          4881:              fputc ('\n', asm_out_file);
        !          4882:              ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
        !          4883:              ASM_OUTPUT_DWARF_ADDR (asm_out_file,
        !          4884:                              IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
        !          4885:              ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 
        !          4886:                        (unsigned) int_size_in_bytes (TREE_TYPE (decl)));
        !          4887:              ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          4888:            }
        !          4889:        }
        !          4890: 
        !          4891:       /* If we are in terse mode, don't generate any DIEs to represent
        !          4892:         any variable declarations or definitions.  */
        !          4893: 
        !          4894:       if (debug_info_level <= DINFO_LEVEL_TERSE)
        !          4895:         return;
        !          4896: 
        !          4897:       break;
        !          4898: 
        !          4899:     case TYPE_DECL:
        !          4900:       /* Don't bother trying to generate any DIEs to represent any of the
        !          4901:         normal built-in types for the language we are compiling, except
        !          4902:         in cases where the types in question are *not* DWARF fundamental
        !          4903:         types.  We make an exception in the case of non-fundamental types
        !          4904:         for the sake of objective C (and perhaps C++) because the GNU
        !          4905:         front-ends for these languages may in fact create certain "built-in"
        !          4906:         types which are (for example) RECORD_TYPEs.  In such cases, we
        !          4907:         really need to output these (non-fundamental) types because other
        !          4908:         DIEs may contain references to them.  */
        !          4909: 
        !          4910:       if (DECL_SOURCE_LINE (decl) == 0
        !          4911:          && type_is_fundamental (TREE_TYPE (decl)))
        !          4912:        return;
        !          4913: 
        !          4914:       /* If we are in terse mode, don't generate any DIEs to represent
        !          4915:         any actual typedefs.  Note that even when we are in terse mode,
        !          4916:         we must still output DIEs to represent those tagged types which
        !          4917:         are used (directly or indirectly) in the specification of either
        !          4918:         a return type or a formal parameter type of some function.  */
        !          4919: 
        !          4920:       if (debug_info_level <= DINFO_LEVEL_TERSE)
        !          4921:        if (DECL_NAME (decl) != NULL
        !          4922:            || ! TYPE_USED_FOR_FUNCTION (TREE_TYPE (decl)))
        !          4923:           return;
        !          4924: 
        !          4925:       break;
        !          4926: 
        !          4927:     default:
        !          4928:       return;
        !          4929:     }
        !          4930: 
        !          4931:   fputc ('\n', asm_out_file);
        !          4932:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION);
        !          4933:   finalizing = set_finalizing;
        !          4934:   output_decl (decl, NULL_TREE);
        !          4935: 
        !          4936:   /* NOTE:  The call above to `output_decl' may have caused one or more
        !          4937:      file-scope named types (i.e. tagged types) to be placed onto the
        !          4938:      pending_types_list.  We have to get those types off of that list
        !          4939:      at some point, and this is the perfect time to do it.  If we didn't
        !          4940:      take them off now, they might still be on the list when cc1 finally
        !          4941:      exits.  That might be OK if it weren't for the fact that when we put
        !          4942:      types onto the pending_types_list, we set the TREE_ASM_WRITTEN flag
        !          4943:      for these types, and that causes them never to be output unless
        !          4944:      `output_pending_types_for_scope' takes them off of the list and un-sets
        !          4945:      their TREE_ASM_WRITTEN flags.  */
        !          4946: 
        !          4947:   output_pending_types_for_scope (NULL_TREE);
        !          4948: 
        !          4949:   /* The above call should have totally emptied the pending_types_list.  */
        !          4950: 
        !          4951:   assert (pending_types == 0);
        !          4952: 
        !          4953:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          4954: 
        !          4955:   if (TREE_CODE (decl) == FUNCTION_DECL && DECL_INITIAL (decl) != NULL)
        !          4956:     current_funcdef_number++;
        !          4957: }
        !          4958: 
        !          4959: /* Output a marker (i.e. a label) for the beginning of the generated code
        !          4960:    for a lexical block.         */
        !          4961: 
        !          4962: void
        !          4963: dwarfout_begin_block (blocknum)
        !          4964:      register unsigned blocknum;
        !          4965: {
        !          4966:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4967: 
        !          4968:   text_section ();
        !          4969:   sprintf (label, BLOCK_BEGIN_LABEL_FMT, blocknum);
        !          4970:   ASM_OUTPUT_LABEL (asm_out_file, label);
        !          4971: }
        !          4972: 
        !          4973: /* Output a marker (i.e. a label) for the end of the generated code
        !          4974:    for a lexical block.         */
        !          4975: 
        !          4976: void
        !          4977: dwarfout_end_block (blocknum)
        !          4978:      register unsigned blocknum;
        !          4979: {
        !          4980:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4981: 
        !          4982:   text_section ();
        !          4983:   sprintf (label, BLOCK_END_LABEL_FMT, blocknum);
        !          4984:   ASM_OUTPUT_LABEL (asm_out_file, label);
        !          4985: }
        !          4986: 
        !          4987: /* Output a marker (i.e. a label) at a point in the assembly code which
        !          4988:    corresponds to a given source level label.  */
        !          4989: 
        !          4990: void
        !          4991: dwarfout_label (insn)
        !          4992:      register rtx insn;
        !          4993: {
        !          4994:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          4995:     {
        !          4996:       char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          4997: 
        !          4998:       text_section ();
        !          4999:       sprintf (label, INSN_LABEL_FMT, current_funcdef_number,
        !          5000:                                      (unsigned) INSN_UID (insn));
        !          5001:       ASM_OUTPUT_LABEL (asm_out_file, label);
        !          5002:     }
        !          5003: }
        !          5004: 
        !          5005: /* Output a marker (i.e. a label) for the point in the generated code where
        !          5006:    the real body of the function begins (after parameters have been moved
        !          5007:    to their home locations).  */
        !          5008: 
        !          5009: void
        !          5010: dwarfout_begin_function ()
        !          5011: {
        !          5012:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5013: 
        !          5014:   text_section ();
        !          5015:   sprintf (label, BODY_BEGIN_LABEL_FMT, current_funcdef_number);
        !          5016:   ASM_OUTPUT_LABEL (asm_out_file, label);
        !          5017: }
        !          5018: 
        !          5019: /* Output a marker (i.e. a label) for the point in the generated code where
        !          5020:    the real body of the function ends (just before the epilogue code).  */
        !          5021: 
        !          5022: void
        !          5023: dwarfout_end_function ()
        !          5024: {
        !          5025:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5026: 
        !          5027:   text_section ();
        !          5028:   sprintf (label, BODY_END_LABEL_FMT, current_funcdef_number);
        !          5029:   ASM_OUTPUT_LABEL (asm_out_file, label);
        !          5030: }
        !          5031: 
        !          5032: /* Output a marker (i.e. a label) for the absolute end of the generated code
        !          5033:    for a function definition.  This gets called *after* the epilogue code
        !          5034:    has been generated. */
        !          5035: 
        !          5036: void
        !          5037: dwarfout_end_epilogue ()
        !          5038: {
        !          5039:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5040: 
        !          5041:   /* Output a label to mark the endpoint of the code generated for this
        !          5042:      function. */
        !          5043: 
        !          5044:   sprintf (label, FUNC_END_LABEL_FMT, current_funcdef_number);
        !          5045:   ASM_OUTPUT_LABEL (asm_out_file, label);
        !          5046: }
        !          5047: 
        !          5048: static void
        !          5049: shuffle_filename_entry (new_zeroth)
        !          5050:      register filename_entry *new_zeroth;
        !          5051: {
        !          5052:   filename_entry temp_entry;
        !          5053:   register filename_entry *limit_p;
        !          5054:   register filename_entry *move_p;
        !          5055: 
        !          5056:   if (new_zeroth == &filename_table[0])
        !          5057:     return;
        !          5058: 
        !          5059:   temp_entry = *new_zeroth;
        !          5060: 
        !          5061:   /* Shift entries up in the table to make room at [0].  */
        !          5062: 
        !          5063:   limit_p = &filename_table[0];
        !          5064:   for (move_p = new_zeroth; move_p > limit_p; move_p--)
        !          5065:     *move_p = *(move_p-1);
        !          5066: 
        !          5067:   /* Install the found entry at [0].  */
        !          5068: 
        !          5069:   filename_table[0] = temp_entry;
        !          5070: }
        !          5071: 
        !          5072: /* Create a new (string) entry for the .debug_sfnames section.  */
        !          5073: 
        !          5074: static void
        !          5075: generate_new_sfname_entry ()
        !          5076: {
        !          5077:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5078: 
        !          5079:   fputc ('\n', asm_out_file);
        !          5080:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION);
        !          5081:   sprintf (label, SFNAMES_ENTRY_LABEL_FMT, filename_table[0].number);
        !          5082:   ASM_OUTPUT_LABEL (asm_out_file, label);
        !          5083:   ASM_OUTPUT_DWARF_STRING (asm_out_file,
        !          5084:                           filename_table[0].name
        !          5085:                             ? filename_table[0].name
        !          5086:                             : "");
        !          5087:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5088: }
        !          5089: 
        !          5090: /* Lookup a filename (in the list of filenames that we know about here in
        !          5091:    dwarfout.c) and return its "index".  The index of each (known) filename
        !          5092:    is just a unique number which is associated with only that one filename.
        !          5093:    We need such numbers for the sake of generating labels (in the
        !          5094:    .debug_sfnames section) and references to those unique labels (in the
        !          5095:    .debug_srcinfo and .debug_macinfo sections).
        !          5096: 
        !          5097:    If the filename given as an argument is not found in our current list,
        !          5098:    add it to the list and assign it the next available unique index number.
        !          5099: 
        !          5100:    Whatever we do (i.e. whether we find a pre-existing filename or add a new
        !          5101:    one), we shuffle the filename found (or added) up to the zeroth entry of
        !          5102:    our list of filenames (which is always searched linearly).  We do this so
        !          5103:    as to optimize the most common case for these filename lookups within
        !          5104:    dwarfout.c.  The most common case by far is the case where we call
        !          5105:    lookup_filename to lookup the very same filename that we did a lookup
        !          5106:    on the last time we called lookup_filename.  We make sure that this
        !          5107:    common case is fast because such cases will constitute 99.9% of the
        !          5108:    lookups we ever do (in practice).
        !          5109: 
        !          5110:    If we add a new filename entry to our table, we go ahead and generate
        !          5111:    the corresponding entry in the .debug_sfnames section right away.
        !          5112:    Doing so allows us to avoid tickling an assembler bug (present in some
        !          5113:    m68k assemblers) which yields assembly-time errors in cases where the
        !          5114:    difference of two label addresses is taken and where the two labels
        !          5115:    are in a section *other* than the one where the difference is being
        !          5116:    calculated, and where at least one of the two symbol references is a
        !          5117:    forward reference.  (This bug could be tickled by our .debug_srcinfo
        !          5118:    entries if we don't output their corresponding .debug_sfnames entries
        !          5119:    before them.)
        !          5120: */
        !          5121: 
        !          5122: static unsigned
        !          5123: lookup_filename (file_name)
        !          5124:      char *file_name;
        !          5125: {
        !          5126:   register filename_entry *search_p;
        !          5127:   register filename_entry *limit_p = &filename_table[ft_entries];
        !          5128: 
        !          5129:   for (search_p = filename_table; search_p < limit_p; search_p++)
        !          5130:     if (!strcmp (file_name, search_p->name))
        !          5131:       {
        !          5132:        /* When we get here, we have found the filename that we were
        !          5133:           looking for in the filename_table.  Now we want to make sure
        !          5134:           that it gets moved to the zero'th entry in the table (if it
        !          5135:           is not already there) so that subsequent attempts to find the
        !          5136:           same filename will find it as quickly as possible.  */
        !          5137: 
        !          5138:        shuffle_filename_entry (search_p);
        !          5139:         return filename_table[0].number;
        !          5140:       }
        !          5141: 
        !          5142:   /* We come here whenever we have a new filename which is not registered
        !          5143:      in the current table.  Here we add it to the table.  */
        !          5144: 
        !          5145:   /* Prepare to add a new table entry by making sure there is enough space
        !          5146:      in the table to do so.  If not, expand the current table.  */
        !          5147: 
        !          5148:   if (ft_entries == ft_entries_allocated)
        !          5149:     {
        !          5150:       ft_entries_allocated += FT_ENTRIES_INCREMENT;
        !          5151:       filename_table
        !          5152:        = (filename_entry *)
        !          5153:          xrealloc (filename_table,
        !          5154:                    ft_entries_allocated * sizeof (filename_entry));
        !          5155:     }
        !          5156: 
        !          5157:   /* Initially, add the new entry at the end of the filename table.  */
        !          5158: 
        !          5159:   filename_table[ft_entries].number = ft_entries;
        !          5160:   filename_table[ft_entries].name = xstrdup (file_name);
        !          5161: 
        !          5162:   /* Shuffle the new entry into filename_table[0].  */
        !          5163: 
        !          5164:   shuffle_filename_entry (&filename_table[ft_entries]);
        !          5165: 
        !          5166:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          5167:     generate_new_sfname_entry ();
        !          5168: 
        !          5169:   ft_entries++;
        !          5170:   return filename_table[0].number;
        !          5171: }
        !          5172: 
        !          5173: static void
        !          5174: generate_srcinfo_entry (line_entry_num, files_entry_num)
        !          5175:      unsigned line_entry_num;
        !          5176:      unsigned files_entry_num;
        !          5177: {
        !          5178:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5179: 
        !          5180:   fputc ('\n', asm_out_file);
        !          5181:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION);
        !          5182:   sprintf (label, LINE_ENTRY_LABEL_FMT, line_entry_num);
        !          5183:   ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, LINE_BEGIN_LABEL);
        !          5184:   sprintf (label, SFNAMES_ENTRY_LABEL_FMT, files_entry_num);
        !          5185:   ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, SFNAMES_BEGIN_LABEL);
        !          5186:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5187: }
        !          5188: 
        !          5189: void
        !          5190: dwarfout_line (filename, line)
        !          5191:      register char *filename;
        !          5192:      register unsigned line;
        !          5193: {
        !          5194:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          5195:     {
        !          5196:       char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5197:       static unsigned last_line_entry_num = 0;
        !          5198:       static unsigned prev_file_entry_num = (unsigned) -1;
        !          5199:       register unsigned this_file_entry_num = lookup_filename (filename);
        !          5200: 
        !          5201:       text_section ();
        !          5202:       sprintf (label, LINE_CODE_LABEL_FMT, ++last_line_entry_num);
        !          5203:       ASM_OUTPUT_LABEL (asm_out_file, label);
        !          5204: 
        !          5205:       fputc ('\n', asm_out_file);
        !          5206:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
        !          5207: 
        !          5208:       if (this_file_entry_num != prev_file_entry_num)
        !          5209:         {
        !          5210:           char line_entry_label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5211: 
        !          5212:           sprintf (line_entry_label, LINE_ENTRY_LABEL_FMT, last_line_entry_num);
        !          5213:           ASM_OUTPUT_LABEL (asm_out_file, line_entry_label);
        !          5214:         }
        !          5215: 
        !          5216:       {
        !          5217:         register char *tail = rindex (filename, '/');
        !          5218: 
        !          5219:         if (tail != NULL)
        !          5220:           filename = tail;
        !          5221:       }
        !          5222: 
        !          5223:       fprintf (asm_out_file, "\t%s\t%u\t%s %s:%u\n",
        !          5224:               UNALIGNED_INT_ASM_OP, line, ASM_COMMENT_START,
        !          5225:               filename, line);
        !          5226:       ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0xffff);
        !          5227:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, label, TEXT_BEGIN_LABEL);
        !          5228:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5229: 
        !          5230:       if (this_file_entry_num != prev_file_entry_num)
        !          5231:         generate_srcinfo_entry (last_line_entry_num, this_file_entry_num);
        !          5232:       prev_file_entry_num = this_file_entry_num;
        !          5233:     }
        !          5234: }
        !          5235: 
        !          5236: /* Generate an entry in the .debug_macinfo section.  */
        !          5237: 
        !          5238: static void
        !          5239: generate_macinfo_entry (type_and_offset, string)
        !          5240:      register char *type_and_offset;
        !          5241:      register char *string;
        !          5242: {
        !          5243:   fputc ('\n', asm_out_file);
        !          5244:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
        !          5245:   fprintf (asm_out_file, "\t%s\t%s\n", UNALIGNED_INT_ASM_OP, type_and_offset);
        !          5246:   ASM_OUTPUT_DWARF_STRING (asm_out_file, string);
        !          5247:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5248: }
        !          5249: 
        !          5250: void
        !          5251: dwarfout_start_new_source_file (filename)
        !          5252:      register char *filename;
        !          5253: {
        !          5254:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5255:   char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*3];
        !          5256: 
        !          5257:   sprintf (label, SFNAMES_ENTRY_LABEL_FMT, lookup_filename (filename));
        !          5258:   sprintf (type_and_offset, "0x%08x+%s-%s",
        !          5259:           ((unsigned) MACINFO_start << 24), label, SFNAMES_BEGIN_LABEL);
        !          5260:   generate_macinfo_entry (type_and_offset, "");
        !          5261: }
        !          5262: 
        !          5263: void
        !          5264: dwarfout_resume_previous_source_file (lineno)
        !          5265:      register unsigned lineno;
        !          5266: {
        !          5267:   char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2];
        !          5268: 
        !          5269:   sprintf (type_and_offset, "0x%08x+%u",
        !          5270:           ((unsigned) MACINFO_resume << 24), lineno);
        !          5271:   generate_macinfo_entry (type_and_offset, "");
        !          5272: }
        !          5273: 
        !          5274: /* Called from check_newline in c-parse.y.  The `buffer' parameter
        !          5275:    contains the tail part of the directive line, i.e. the part which
        !          5276:    is past the initial whitespace, #, whitespace, directive-name,
        !          5277:    whitespace part.  */
        !          5278: 
        !          5279: void
        !          5280: dwarfout_define (lineno, buffer)
        !          5281:      register unsigned lineno;
        !          5282:      register char *buffer;
        !          5283: {
        !          5284:   static int initialized = 0;
        !          5285:   char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2];
        !          5286: 
        !          5287:   if (!initialized)
        !          5288:     {
        !          5289:       dwarfout_start_new_source_file (primary_filename);
        !          5290:       initialized = 1;
        !          5291:     }
        !          5292:   sprintf (type_and_offset, "0x%08x+%u",
        !          5293:           ((unsigned) MACINFO_define << 24), lineno);
        !          5294:   generate_macinfo_entry (type_and_offset, buffer);
        !          5295: }
        !          5296: 
        !          5297: /* Called from check_newline in c-parse.y.  The `buffer' parameter
        !          5298:    contains the tail part of the directive line, i.e. the part which
        !          5299:    is past the initial whitespace, #, whitespace, directive-name,
        !          5300:    whitespace part.  */
        !          5301: 
        !          5302: void
        !          5303: dwarfout_undef (lineno, buffer)
        !          5304:      register unsigned lineno;
        !          5305:      register char *buffer;
        !          5306: {
        !          5307:   char type_and_offset[MAX_ARTIFICIAL_LABEL_BYTES*2];
        !          5308: 
        !          5309:   sprintf (type_and_offset, "0x%08x+%u",
        !          5310:           ((unsigned) MACINFO_undef << 24), lineno);
        !          5311:   generate_macinfo_entry (type_and_offset, buffer);
        !          5312: }
        !          5313: 
        !          5314: /* Set up for Dwarf output at the start of compilation.         */
        !          5315: 
        !          5316: void
        !          5317: dwarfout_init (asm_out_file, main_input_filename)
        !          5318:      register FILE *asm_out_file;
        !          5319:      register char *main_input_filename;
        !          5320: {
        !          5321:   /* Remember the name of the primary input file.  */
        !          5322: 
        !          5323:   primary_filename = main_input_filename;
        !          5324: 
        !          5325:   /* Allocate the initial hunk of the pending_sibling_stack.  */
        !          5326: 
        !          5327:   pending_sibling_stack
        !          5328:     = (unsigned *)
        !          5329:        xmalloc (PENDING_SIBLINGS_INCREMENT * sizeof (unsigned));
        !          5330:   pending_siblings_allocated = PENDING_SIBLINGS_INCREMENT;
        !          5331:   pending_siblings = 1;
        !          5332: 
        !          5333:   /* Allocate the initial hunk of the filename_table.  */
        !          5334: 
        !          5335:   filename_table
        !          5336:     = (filename_entry *)
        !          5337:        xmalloc (FT_ENTRIES_INCREMENT * sizeof (filename_entry));
        !          5338:   ft_entries_allocated = FT_ENTRIES_INCREMENT;
        !          5339:   ft_entries = 0;
        !          5340: 
        !          5341:   /* Allocate the initial hunk of the pending_types_list.  */
        !          5342: 
        !          5343:   pending_types_list
        !          5344:     = (tree *) xmalloc (PENDING_TYPES_INCREMENT * sizeof (tree));
        !          5345:   pending_types_allocated = PENDING_TYPES_INCREMENT;
        !          5346:   pending_types = 0;
        !          5347: 
        !          5348:   /* Create an artificial RECORD_TYPE node which we can use in our hack
        !          5349:      to get the DIEs representing types of formal parameters to come out
        !          5350:      only *after* the DIEs for the formal parameters themselves.  */
        !          5351: 
        !          5352:   fake_containing_scope = make_node (RECORD_TYPE);
        !          5353: 
        !          5354:   /* Output a starting label for the .text section.  */
        !          5355: 
        !          5356:   fputc ('\n', asm_out_file);
        !          5357:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION);
        !          5358:   ASM_OUTPUT_LABEL (asm_out_file, TEXT_BEGIN_LABEL);
        !          5359:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5360: 
        !          5361:   /* Output a starting label for the .data section.  */
        !          5362: 
        !          5363:   fputc ('\n', asm_out_file);
        !          5364:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION);
        !          5365:   ASM_OUTPUT_LABEL (asm_out_file, DATA_BEGIN_LABEL);
        !          5366:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5367: 
        !          5368: #if 0 /* GNU C doesn't currently use .data1.  */
        !          5369:   /* Output a starting label for the .data1 section.  */
        !          5370: 
        !          5371:   fputc ('\n', asm_out_file);
        !          5372:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION);
        !          5373:   ASM_OUTPUT_LABEL (asm_out_file, DATA1_BEGIN_LABEL);
        !          5374:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5375: #endif
        !          5376: 
        !          5377:   /* Output a starting label for the .rodata section.  */
        !          5378: 
        !          5379:   fputc ('\n', asm_out_file);
        !          5380:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION);
        !          5381:   ASM_OUTPUT_LABEL (asm_out_file, RODATA_BEGIN_LABEL);
        !          5382:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5383: 
        !          5384: #if 0 /* GNU C doesn't currently use .rodata1.  */
        !          5385:   /* Output a starting label for the .rodata1 section.  */
        !          5386: 
        !          5387:   fputc ('\n', asm_out_file);
        !          5388:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION);
        !          5389:   ASM_OUTPUT_LABEL (asm_out_file, RODATA1_BEGIN_LABEL);
        !          5390:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5391: #endif
        !          5392: 
        !          5393:   /* Output a starting label for the .bss section.  */
        !          5394: 
        !          5395:   fputc ('\n', asm_out_file);
        !          5396:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION);
        !          5397:   ASM_OUTPUT_LABEL (asm_out_file, BSS_BEGIN_LABEL);
        !          5398:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5399: 
        !          5400:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          5401:     {
        !          5402:       /* Output a starting label and an initial (compilation directory)
        !          5403:         entry for the .debug_sfnames section.  The starting label will be
        !          5404:         referenced by the initial entry in the .debug_srcinfo section.  */
        !          5405:     
        !          5406:       fputc ('\n', asm_out_file);
        !          5407:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, SFNAMES_SECTION);
        !          5408:       ASM_OUTPUT_LABEL (asm_out_file, SFNAMES_BEGIN_LABEL);
        !          5409:       {
        !          5410:        register char *pwd;
        !          5411:        register unsigned len;
        !          5412:        register char *dirname;
        !          5413: 
        !          5414:        pwd = getpwd ();
        !          5415:        if (!pwd)
        !          5416:          pfatal_with_name ("getpwd");
        !          5417:        len = strlen (pwd);
        !          5418:        dirname = (char *) xmalloc (len + 2);
        !          5419:     
        !          5420:        strcpy (dirname, pwd);
        !          5421:        strcpy (dirname + len, "/");
        !          5422:         ASM_OUTPUT_DWARF_STRING (asm_out_file, dirname);
        !          5423:         free (dirname);
        !          5424:       }
        !          5425:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5426:     
        !          5427:       if (debug_info_level >= DINFO_LEVEL_VERBOSE)
        !          5428:        {
        !          5429:           /* Output a starting label for the .debug_macinfo section.  This
        !          5430:             label will be referenced by the AT_mac_info attribute in the
        !          5431:             TAG_compile_unit DIE.  */
        !          5432:         
        !          5433:           fputc ('\n', asm_out_file);
        !          5434:           ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
        !          5435:           ASM_OUTPUT_LABEL (asm_out_file, MACINFO_BEGIN_LABEL);
        !          5436:           ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5437:        }
        !          5438: 
        !          5439:       /* Generate the initial entry for the .line section.  */
        !          5440:     
        !          5441:       fputc ('\n', asm_out_file);
        !          5442:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
        !          5443:       ASM_OUTPUT_LABEL (asm_out_file, LINE_BEGIN_LABEL);
        !          5444:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, LINE_END_LABEL, LINE_BEGIN_LABEL);
        !          5445:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL);
        !          5446:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5447:     
        !          5448:       /* Generate the initial entry for the .debug_srcinfo section.  */
        !          5449:     
        !          5450:       fputc ('\n', asm_out_file);
        !          5451:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION);
        !          5452:       ASM_OUTPUT_LABEL (asm_out_file, SRCINFO_BEGIN_LABEL);
        !          5453:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, LINE_BEGIN_LABEL);
        !          5454:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, SFNAMES_BEGIN_LABEL);
        !          5455:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL);
        !          5456:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_END_LABEL);
        !          5457: #ifdef DWARF_TIMESTAMPS
        !          5458:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, time (NULL));
        !          5459: #else
        !          5460:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1);
        !          5461: #endif
        !          5462:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5463:     
        !          5464:       /* Generate the initial entry for the .debug_pubnames section.  */
        !          5465:     
        !          5466:       fputc ('\n', asm_out_file);
        !          5467:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
        !          5468:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL);
        !          5469:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5470:     
        !          5471:       /* Generate the initial entry for the .debug_aranges section.  */
        !          5472:     
        !          5473:       fputc ('\n', asm_out_file);
        !          5474:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
        !          5475:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, DEBUG_BEGIN_LABEL);
        !          5476:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5477:     }
        !          5478: 
        !          5479:   /* Setup first DIE number == 1.  */
        !          5480:   NEXT_DIE_NUM = next_unused_dienum++;
        !          5481: 
        !          5482:   /* Generate the initial DIE for the .debug section.  Note that the
        !          5483:      (string) value given in the AT_name attribute of the TAG_compile_unit
        !          5484:      DIE will (typically) be a relative pathname and that this pathname
        !          5485:      should be taken as being relative to the directory from which the
        !          5486:      compiler was invoked when the given (base) source file was compiled.  */
        !          5487: 
        !          5488:   fputc ('\n', asm_out_file);
        !          5489:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION);
        !          5490:   ASM_OUTPUT_LABEL (asm_out_file, DEBUG_BEGIN_LABEL);
        !          5491:   output_die (output_compile_unit_die, main_input_filename);
        !          5492:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5493: 
        !          5494:   fputc ('\n', asm_out_file);
        !          5495: }
        !          5496: 
        !          5497: /* Output stuff that dwarf requires at the end of every file.  */
        !          5498: 
        !          5499: void
        !          5500: dwarfout_finish ()
        !          5501: {
        !          5502:   char label[MAX_ARTIFICIAL_LABEL_BYTES];
        !          5503: 
        !          5504:   fputc ('\n', asm_out_file);
        !          5505:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DEBUG_SECTION);
        !          5506: 
        !          5507:   /* Mark the end of the chain of siblings which represent all file-scope
        !          5508:      declarations in this compilation unit.  */
        !          5509: 
        !          5510:   /* The (null) DIE which represents the terminator for the (sibling linked)
        !          5511:      list of file-scope items is *special*.  Normally, we would just call
        !          5512:      end_sibling_chain at this point in order to output a word with the
        !          5513:      value `4' and that word would act as the terminator for the list of
        !          5514:      DIEs describing file-scope items.  Unfortunately, if we were to simply
        !          5515:      do that, the label that would follow this DIE in the .debug section
        !          5516:      (i.e. `..D2') would *not* be properly aligned (as it must be on some
        !          5517:      machines) to a 4 byte boundary.
        !          5518: 
        !          5519:      In order to force the label `..D2' to get aligned to a 4 byte boundary,
        !          5520:      the trick used is to insert extra (otherwise useless) padding bytes
        !          5521:      into the (null) DIE that we know must precede the ..D2 label in the
        !          5522:      .debug section.  The amount of padding required can be anywhere between
        !          5523:      0 and 3 bytes.  The length word at the start of this DIE (i.e. the one
        !          5524:      with the padding) would normally contain the value 4, but now it will
        !          5525:      also have to include the padding bytes, so it will instead have some
        !          5526:      value in the range 4..7.
        !          5527: 
        !          5528:      Fortunately, the rules of Dwarf say that any DIE whose length word
        !          5529:      contains *any* value less than 8 should be treated as a null DIE, so
        !          5530:      this trick works out nicely.  Clever, eh?  Don't give me any credit
        !          5531:      (or blame).  I didn't think of this scheme.  I just conformed to it.
        !          5532:   */
        !          5533: 
        !          5534:   output_die (output_padded_null_die, (void *)0);
        !          5535:   dienum_pop ();
        !          5536: 
        !          5537:   sprintf (label, DIE_BEGIN_LABEL_FMT, NEXT_DIE_NUM);
        !          5538:   ASM_OUTPUT_LABEL (asm_out_file, label);      /* should be ..D2 */
        !          5539:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5540: 
        !          5541:   /* Output a terminator label for the .text section.  */
        !          5542: 
        !          5543:   fputc ('\n', asm_out_file);
        !          5544:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, TEXT_SECTION);
        !          5545:   ASM_OUTPUT_LABEL (asm_out_file, TEXT_END_LABEL);
        !          5546:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5547: 
        !          5548:   /* Output a terminator label for the .data section.  */
        !          5549: 
        !          5550:   fputc ('\n', asm_out_file);
        !          5551:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA_SECTION);
        !          5552:   ASM_OUTPUT_LABEL (asm_out_file, DATA_END_LABEL);
        !          5553:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5554: 
        !          5555: #if 0 /* GNU C doesn't currently use .data1.  */
        !          5556:   /* Output a terminator label for the .data1 section.  */
        !          5557: 
        !          5558:   fputc ('\n', asm_out_file);
        !          5559:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, DATA1_SECTION);
        !          5560:   ASM_OUTPUT_LABEL (asm_out_file, DATA1_END_LABEL);
        !          5561:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5562: #endif
        !          5563: 
        !          5564:   /* Output a terminator label for the .rodata section.  */
        !          5565: 
        !          5566:   fputc ('\n', asm_out_file);
        !          5567:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA_SECTION);
        !          5568:   ASM_OUTPUT_LABEL (asm_out_file, RODATA_END_LABEL);
        !          5569:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5570: 
        !          5571: #if 0 /* GNU C doesn't currently use .rodata1.  */
        !          5572:   /* Output a terminator label for the .rodata1 section.  */
        !          5573: 
        !          5574:   fputc ('\n', asm_out_file);
        !          5575:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, RODATA1_SECTION);
        !          5576:   ASM_OUTPUT_LABEL (asm_out_file, RODATA1_END_LABEL);
        !          5577:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5578: #endif
        !          5579: 
        !          5580:   /* Output a terminator label for the .bss section.  */
        !          5581: 
        !          5582:   fputc ('\n', asm_out_file);
        !          5583:   ASM_OUTPUT_PUSH_SECTION (asm_out_file, BSS_SECTION);
        !          5584:   ASM_OUTPUT_LABEL (asm_out_file, BSS_END_LABEL);
        !          5585:   ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5586: 
        !          5587:   if (debug_info_level >= DINFO_LEVEL_NORMAL)
        !          5588:     {
        !          5589:       /* Output a terminating entry for the .line section.  */
        !          5590:     
        !          5591:       fputc ('\n', asm_out_file);
        !          5592:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, LINE_SECTION);
        !          5593:       ASM_OUTPUT_LABEL (asm_out_file, LINE_LAST_ENTRY_LABEL);
        !          5594:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
        !          5595:       ASM_OUTPUT_DWARF_DATA2 (asm_out_file, 0xffff);
        !          5596:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL);
        !          5597:       ASM_OUTPUT_LABEL (asm_out_file, LINE_END_LABEL);
        !          5598:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5599:     
        !          5600:       /* Output a terminating entry for the .debug_srcinfo section.  */
        !          5601:     
        !          5602:       fputc ('\n', asm_out_file);
        !          5603:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, SRCINFO_SECTION);
        !          5604:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file,
        !          5605:                               LINE_LAST_ENTRY_LABEL, LINE_BEGIN_LABEL);
        !          5606:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, -1);
        !          5607:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5608: 
        !          5609:       if (debug_info_level >= DINFO_LEVEL_VERBOSE)
        !          5610:        {
        !          5611:          /* Output terminating entries for the .debug_macinfo section.  */
        !          5612:        
        !          5613:          dwarfout_resume_previous_source_file (0);
        !          5614: 
        !          5615:          fputc ('\n', asm_out_file);
        !          5616:          ASM_OUTPUT_PUSH_SECTION (asm_out_file, MACINFO_SECTION);
        !          5617:          ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
        !          5618:          ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
        !          5619:          ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5620:        }
        !          5621:     
        !          5622:       /* Generate the terminating entry for the .debug_pubnames section.  */
        !          5623:     
        !          5624:       fputc ('\n', asm_out_file);
        !          5625:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, PUBNAMES_SECTION);
        !          5626:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
        !          5627:       ASM_OUTPUT_DWARF_STRING (asm_out_file, "");
        !          5628:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5629:     
        !          5630:       /* Generate the terminating entries for the .debug_aranges section.
        !          5631: 
        !          5632:         Note that we want to do this only *after* we have output the end
        !          5633:         labels (for the various program sections) which we are going to
        !          5634:         refer to here.  This allows us to work around a bug in the m68k
        !          5635:         svr4 assembler.  That assembler gives bogus assembly-time errors
        !          5636:         if (within any given section) you try to take the difference of
        !          5637:         two relocatable symbols, both of which are located within some
        !          5638:         other section, and if one (or both?) of the symbols involved is
        !          5639:         being forward-referenced.  By generating the .debug_aranges
        !          5640:         entries at this late point in the assembly output, we skirt the
        !          5641:         issue simply by avoiding forward-references.
        !          5642:       */
        !          5643:     
        !          5644:       fputc ('\n', asm_out_file);
        !          5645:       ASM_OUTPUT_PUSH_SECTION (asm_out_file, ARANGES_SECTION);
        !          5646: 
        !          5647:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, TEXT_BEGIN_LABEL);
        !          5648:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, TEXT_END_LABEL, TEXT_BEGIN_LABEL);
        !          5649: 
        !          5650:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, DATA_BEGIN_LABEL);
        !          5651:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, DATA_END_LABEL, DATA_BEGIN_LABEL);
        !          5652: 
        !          5653: #if 0 /* GNU C doesn't currently use .data1.  */
        !          5654:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, DATA1_BEGIN_LABEL);
        !          5655:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, DATA1_END_LABEL,
        !          5656:                                             DATA1_BEGIN_LABEL);
        !          5657: #endif
        !          5658: 
        !          5659:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, RODATA_BEGIN_LABEL);
        !          5660:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, RODATA_END_LABEL,
        !          5661:                                             RODATA_BEGIN_LABEL);
        !          5662: 
        !          5663: #if 0 /* GNU C doesn't currently use .rodata1.  */
        !          5664:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, RODATA1_BEGIN_LABEL);
        !          5665:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, RODATA1_END_LABEL,
        !          5666:                                             RODATA1_BEGIN_LABEL);
        !          5667: #endif
        !          5668: 
        !          5669:       ASM_OUTPUT_DWARF_ADDR (asm_out_file, BSS_BEGIN_LABEL);
        !          5670:       ASM_OUTPUT_DWARF_DELTA4 (asm_out_file, BSS_END_LABEL, BSS_BEGIN_LABEL);
        !          5671: 
        !          5672:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
        !          5673:       ASM_OUTPUT_DWARF_DATA4 (asm_out_file, 0);
        !          5674: 
        !          5675:       ASM_OUTPUT_POP_SECTION (asm_out_file);
        !          5676:     }
        !          5677: }
        !          5678: 
        !          5679: #endif /* DWARF_DEBUGGING_INFO */

unix.superglobalmegacorp.com

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