Annotation of gcc/sdbout.c, revision 1.1

1.1     ! root        1: /* Output sdb-format symbol table information from GNU compiler.
        !             2:    Copyright (C) 1988, 1992 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is free software; you can redistribute it and/or modify
        !             7: it under the terms of the GNU General Public License as published by
        !             8: the Free Software Foundation; either version 2, or (at your option)
        !             9: any later version.
        !            10: 
        !            11: GNU CC is distributed in the hope that it will be useful,
        !            12: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            14: GNU General Public License for more details.
        !            15: 
        !            16: You should have received a copy of the GNU General Public License
        !            17: along with GNU CC; see the file COPYING.  If not, write to
        !            18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            19: 
        !            20: /*  [email protected] says:
        !            21: I modified the struct.c example and have a nm of a .o resulting from the
        !            22: AT&T C compiler.  From the example below I would conclude the following:
        !            23: 
        !            24: 1. All .defs from structures are emitted as scanned.  The example below
        !            25:    clearly shows the symbol table entries for BoxRec2 are after the first
        !            26:    function.
        !            27: 
        !            28: 2. All functions and their locals (including statics) are emitted as scanned.
        !            29: 
        !            30: 3. All nested unnamed union and structure .defs must be emitted before
        !            31:    the structure in which they are nested.  The AT&T assembler is a
        !            32:    one pass beast as far as symbolics are concerned.
        !            33: 
        !            34: 4. All structure .defs are emitted before the typedefs that refer to them.
        !            35: 
        !            36: 5. All top level static and external variable definitions are moved to the
        !            37:    end of file with all top level statics occuring first before externs.
        !            38: 
        !            39: 6. All undefined references are at the end of the file.
        !            40: */
        !            41: 
        !            42: #include "config.h"
        !            43: 
        !            44: #ifdef SDB_DEBUGGING_INFO
        !            45: 
        !            46: #include "tree.h"
        !            47: #include "rtl.h"
        !            48: #include <stdio.h>
        !            49: #include "regs.h"
        !            50: #include "flags.h"
        !            51: #include "insn-config.h"
        !            52: #include "reload.h"
        !            53: 
        !            54: /* Mips systems use the SDB functions to dump out symbols, but
        !            55:    do not supply usable syms.h include files.  */
        !            56: #if defined(USG) && !defined(MIPS)
        !            57: #include <syms.h>
        !            58: /* Use T_INT if we don't have T_VOID.  */
        !            59: #ifndef T_VOID
        !            60: #define T_VOID T_INT
        !            61: #endif
        !            62: #else /* not USG, or MIPS */
        !            63: #include "gsyms.h"
        !            64: #endif /* not USG, or MIPS */
        !            65: 
        !            66: /* #include <storclass.h>  used to be this instead of syms.h.  */
        !            67: 
        !            68: /* 1 if PARM is passed to this function in memory.  */
        !            69: 
        !            70: #define PARM_PASSED_IN_MEMORY(PARM) \
        !            71:  (GET_CODE (DECL_INCOMING_RTL (PARM)) == MEM)
        !            72: 
        !            73: /* A C expression for the integer offset value of an automatic variable
        !            74:    (C_AUTO) having address X (an RTX).  */
        !            75: #ifndef DEBUGGER_AUTO_OFFSET
        !            76: #define DEBUGGER_AUTO_OFFSET(X) \
        !            77:   (GET_CODE (X) == PLUS ? INTVAL (XEXP (X, 1)) : 0)
        !            78: #endif
        !            79: 
        !            80: /* A C expression for the integer offset value of an argument (C_ARG)
        !            81:    having address X (an RTX).  The nominal offset is OFFSET.  */
        !            82: #ifndef DEBUGGER_ARG_OFFSET
        !            83: #define DEBUGGER_ARG_OFFSET(OFFSET, X) (OFFSET)
        !            84: #endif
        !            85: 
        !            86: /* Line number of beginning of current function, minus one.
        !            87:    Negative means not in a function or not using sdb.  */
        !            88: 
        !            89: int sdb_begin_function_line = -1;
        !            90: 
        !            91: /* Counter to generate unique "names" for nameless struct members.  */
        !            92: 
        !            93: static int unnamed_struct_number = 0;
        !            94: 
        !            95: extern FILE *asm_out_file;
        !            96: 
        !            97: extern tree current_function_decl;
        !            98: 
        !            99: void sdbout_init ();
        !           100: void sdbout_symbol ();
        !           101: void sdbout_types();
        !           102: 
        !           103: static void sdbout_typedefs ();
        !           104: static void sdbout_syms ();
        !           105: static void sdbout_one_type ();
        !           106: static void sdbout_queue_anonymous_type ();
        !           107: static void sdbout_dequeue_anonymous_type ();
        !           108: static int plain_type_1 ();
        !           109: 
        !           110: /* Define the default sizes for various types.  */
        !           111: 
        !           112: #ifndef CHAR_TYPE_SIZE
        !           113: #define CHAR_TYPE_SIZE BITS_PER_UNIT
        !           114: #endif
        !           115: 
        !           116: #ifndef SHORT_TYPE_SIZE
        !           117: #define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2))
        !           118: #endif
        !           119: 
        !           120: #ifndef INT_TYPE_SIZE
        !           121: #define INT_TYPE_SIZE BITS_PER_WORD
        !           122: #endif
        !           123: 
        !           124: #ifndef LONG_TYPE_SIZE
        !           125: #define LONG_TYPE_SIZE BITS_PER_WORD
        !           126: #endif
        !           127: 
        !           128: #ifndef LONG_LONG_TYPE_SIZE
        !           129: #define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2)
        !           130: #endif
        !           131: 
        !           132: #ifndef FLOAT_TYPE_SIZE
        !           133: #define FLOAT_TYPE_SIZE BITS_PER_WORD
        !           134: #endif
        !           135: 
        !           136: #ifndef DOUBLE_TYPE_SIZE
        !           137: #define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
        !           138: #endif
        !           139: 
        !           140: #ifndef LONG_DOUBLE_TYPE_SIZE
        !           141: #define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2)
        !           142: #endif
        !           143: 
        !           144: /* Random macros describing parts of SDB data.  */
        !           145: 
        !           146: /* Put something here if lines get too long */
        !           147: #define CONTIN
        !           148: 
        !           149: /* Default value of delimiter is ";".  */
        !           150: #ifndef SDB_DELIM
        !           151: #define SDB_DELIM      ";"
        !           152: #endif
        !           153: 
        !           154: /* Maximum number of dimensions the assembler will allow.  */
        !           155: #ifndef SDB_MAX_DIM
        !           156: #define SDB_MAX_DIM 4
        !           157: #endif
        !           158: 
        !           159: #ifndef PUT_SDB_SCL
        !           160: #define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d%s", (a), SDB_DELIM)
        !           161: #endif
        !           162: 
        !           163: #ifndef PUT_SDB_INT_VAL
        !           164: #define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\t.val\t%d%s", (a), SDB_DELIM)
        !           165: #endif
        !           166: 
        !           167: #ifndef PUT_SDB_VAL
        !           168: #define PUT_SDB_VAL(a)                         \
        !           169: ( fputs ("\t.val\t", asm_out_file),            \
        !           170:   output_addr_const (asm_out_file, (a)),       \
        !           171:   fprintf (asm_out_file, SDB_DELIM))
        !           172: #endif
        !           173: 
        !           174: #ifndef PUT_SDB_DEF
        !           175: #define PUT_SDB_DEF(a)                         \
        !           176: do { fprintf (asm_out_file, "\t.def\t");       \
        !           177:      ASM_OUTPUT_LABELREF (asm_out_file, a);    \
        !           178:      fprintf (asm_out_file, SDB_DELIM); } while (0)
        !           179: #endif
        !           180: 
        !           181: #ifndef PUT_SDB_PLAIN_DEF
        !           182: #define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s%s",a, SDB_DELIM)
        !           183: #endif
        !           184: 
        !           185: #ifndef PUT_SDB_ENDEF
        !           186: #define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file)
        !           187: #endif
        !           188: 
        !           189: #ifndef PUT_SDB_TYPE
        !           190: #define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o%s", a, SDB_DELIM)
        !           191: #endif
        !           192: 
        !           193: #ifndef PUT_SDB_SIZE
        !           194: #define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\t.size\t%d%s", a, SDB_DELIM)
        !           195: #endif
        !           196: 
        !           197: #ifndef PUT_SDB_START_DIM
        !           198: #define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t")
        !           199: #endif
        !           200: 
        !           201: #ifndef PUT_SDB_NEXT_DIM
        !           202: #define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
        !           203: #endif
        !           204: 
        !           205: #ifndef PUT_SDB_LAST_DIM
        !           206: #define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d%s", a, SDB_DELIM)
        !           207: #endif
        !           208: 
        !           209: #ifndef PUT_SDB_TAG
        !           210: #define PUT_SDB_TAG(a)                         \
        !           211: do { fprintf (asm_out_file, "\t.tag\t");       \
        !           212:      ASM_OUTPUT_LABELREF (asm_out_file, a);    \
        !           213:      fprintf (asm_out_file, SDB_DELIM); } while (0)
        !           214: #endif
        !           215: 
        !           216: #ifndef PUT_SDB_BLOCK_START
        !           217: #define PUT_SDB_BLOCK_START(LINE)              \
        !           218:   fprintf (asm_out_file,                       \
        !           219:           "\t.def\t.bb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n", \
        !           220:           SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
        !           221: #endif
        !           222: 
        !           223: #ifndef PUT_SDB_BLOCK_END
        !           224: #define PUT_SDB_BLOCK_END(LINE)                        \
        !           225:   fprintf (asm_out_file,                       \
        !           226:           "\t.def\t.eb%s\t.val\t.%s\t.scl\t100%s\t.line\t%d%s\t.endef\n",  \
        !           227:           SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
        !           228: #endif
        !           229: 
        !           230: #ifndef PUT_SDB_FUNCTION_START
        !           231: #define PUT_SDB_FUNCTION_START(LINE)           \
        !           232:   fprintf (asm_out_file,                       \
        !           233:           "\t.def\t.bf%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
        !           234:           SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
        !           235: #endif
        !           236: 
        !           237: #ifndef PUT_SDB_FUNCTION_END
        !           238: #define PUT_SDB_FUNCTION_END(LINE)             \
        !           239:   fprintf (asm_out_file,                       \
        !           240:           "\t.def\t.ef%s\t.val\t.%s\t.scl\t101%s\t.line\t%d%s\t.endef\n", \
        !           241:           SDB_DELIM, SDB_DELIM, SDB_DELIM, (LINE), SDB_DELIM)
        !           242: #endif
        !           243: 
        !           244: #ifndef PUT_SDB_EPILOGUE_END
        !           245: #define PUT_SDB_EPILOGUE_END(NAME)                     \
        !           246: do { fprintf (asm_out_file, "\t.def\t");               \
        !           247:      ASM_OUTPUT_LABELREF (asm_out_file, NAME);         \
        !           248:      fprintf (asm_out_file,                            \
        !           249:              "%s\t.val\t.%s\t.scl\t-1%s\t.endef\n",    \
        !           250:              SDB_DELIM, SDB_DELIM, SDB_DELIM); } while (0)
        !           251: #endif
        !           252: 
        !           253: #ifndef SDB_GENERATE_FAKE
        !           254: #define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
        !           255:   sprintf ((BUFFER), ".%dfake", (NUMBER));
        !           256: #endif
        !           257: 
        !           258: /* Return the sdb tag identifier string for TYPE
        !           259:    if TYPE has already been defined; otherwise return a null pointer.   */
        !           260: 
        !           261: #define KNOWN_TYPE_TAG(type) (char *)(TYPE_SYMTAB_ADDRESS (type))
        !           262: 
        !           263: /* Set the sdb tag identifier string for TYPE to NAME.  */
        !           264: 
        !           265: #define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
        !           266:   (TYPE_SYMTAB_ADDRESS (TYPE) = (int)(NAME))
        !           267: 
        !           268: /* Return the name (a string) of the struct, union or enum tag
        !           269:    described by the TREE_LIST node LINK.  This is 0 for an anonymous one.  */
        !           270: 
        !           271: #define TAG_NAME(link) \
        !           272:   (((link) && TREE_PURPOSE ((link)) \
        !           273:     && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \
        !           274:    ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0)
        !           275: 
        !           276: /* Ensure we don't output a negative line number.  */
        !           277: #define MAKE_LINE_SAFE(line)  \
        !           278:   if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1
        !           279: 
        !           280: /* Set up for SDB output at the start of compilation.  */
        !           281: 
        !           282: void
        !           283: sdbout_init (asm_file, input_file_name, syms)
        !           284:      FILE *asm_file;
        !           285:      char *input_file_name;
        !           286:      tree syms;
        !           287: {
        !           288: #if 0 /* Nothing need be output for the predefined types.  */
        !           289:   /* Get all permanent types that have typedef names,
        !           290:      and output them all, except for those already output.  */
        !           291: 
        !           292:   sdbout_typedefs (syms);
        !           293: #endif
        !           294: }
        !           295: 
        !           296: #if 0
        !           297: 
        !           298: /* return the tag identifier for type
        !           299:  */
        !           300: 
        !           301: char *
        !           302: tag_of_ru_type (type,link)
        !           303:      tree type,link;
        !           304: {
        !           305:   if (TYPE_SYMTAB_ADDRESS (type))
        !           306:     return (char *)TYPE_SYMTAB_ADDRESS (type);
        !           307:   if (link && TREE_PURPOSE (link)
        !           308:       && IDENTIFIER_POINTER (TREE_PURPOSE (link)))
        !           309:     TYPE_SYMTAB_ADDRESS (type)
        !           310:       = (int)IDENTIFIER_POINTER (TREE_PURPOSE (link));
        !           311:   else
        !           312:     return (char *) TYPE_SYMTAB_ADDRESS (type);
        !           313: }
        !           314: #endif
        !           315: 
        !           316: /* Return a unique string to name an anonymous type.  */
        !           317: 
        !           318: static char *
        !           319: gen_fake_label ()
        !           320: {
        !           321:   char label[10];
        !           322:   char *labelstr;
        !           323:   SDB_GENERATE_FAKE (label, unnamed_struct_number);
        !           324:   unnamed_struct_number++;
        !           325:   labelstr = (char *) permalloc (strlen (label) + 1);
        !           326:   strcpy (labelstr, label);
        !           327:   return labelstr;
        !           328: }
        !           329: 
        !           330: /* Return the number which describes TYPE for SDB.
        !           331:    For pointers, etc., this function is recursive.
        !           332:    Each record, union or enumeral type must already have had a
        !           333:    tag number output.  */
        !           334: 
        !           335: /* The number is given by d6d5d4d3d2d1bbbb
        !           336:    where bbbb is 4 bit basic type, and di indicate  one of notype,ptr,fn,array.
        !           337:    Thus, char *foo () has bbbb=T_CHAR
        !           338:                          d1=D_FCN
        !           339:                          d2=D_PTR
        !           340:  N_BTMASK=     017       1111     basic type field.
        !           341:  N_TSHIFT=       2                derived type shift
        !           342:  N_BTSHFT=       4                Basic type shift */
        !           343: 
        !           344: /* Produce the number that describes a pointer, function or array type.
        !           345:    PREV is the number describing the target, value or element type.
        !           346:    DT_type describes how to transform that type.  */
        !           347: #define PUSH_DERIVED_LEVEL(DT_type,PREV) \
        !           348:   ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK))
        !           349: 
        !           350: /* Number of elements used in sdb_dims.  */
        !           351: static int sdb_n_dims = 0;
        !           352: 
        !           353: /* Table of array dimensions of current type.  */
        !           354: static int sdb_dims[SDB_MAX_DIM];
        !           355: 
        !           356: /* Size of outermost array currently being processed.  */
        !           357: static int sdb_type_size = -1;
        !           358: 
        !           359: static int
        !           360: plain_type (type)
        !           361:      tree type;
        !           362: {
        !           363:   int val = plain_type_1 (type);
        !           364: 
        !           365:   /* If we have already saved up some array dimensions, print them now.  */
        !           366:   if (sdb_n_dims > 0)
        !           367:     {
        !           368:       int i;
        !           369:       PUT_SDB_START_DIM;
        !           370:       for (i = sdb_n_dims - 1; i > 0; i--)
        !           371:        PUT_SDB_NEXT_DIM (sdb_dims[i]);
        !           372:       PUT_SDB_LAST_DIM (sdb_dims[0]);
        !           373:       sdb_n_dims = 0;
        !           374: 
        !           375:       sdb_type_size = int_size_in_bytes (type);
        !           376:       /* Don't kill sdb if type is not laid out or has variable size.  */
        !           377:       if (sdb_type_size < 0)
        !           378:        sdb_type_size = 0;
        !           379:     }
        !           380:   /* If we have computed the size of an array containing this type,
        !           381:      print it now.  */
        !           382:   if (sdb_type_size >= 0)
        !           383:     {
        !           384:       PUT_SDB_SIZE (sdb_type_size);
        !           385:       sdb_type_size = -1;
        !           386:     }
        !           387:   return val;
        !           388: }
        !           389: 
        !           390: static void
        !           391: sdbout_record_type_name (type)
        !           392:      tree type;
        !           393: {
        !           394:   char *name = 0;
        !           395:   int no_name;
        !           396: 
        !           397:   if (KNOWN_TYPE_TAG (type))
        !           398:     return;
        !           399: 
        !           400:   if (TYPE_NAME (type) != 0)
        !           401:     {
        !           402:       tree t = 0;
        !           403:       /* Find the IDENTIFIER_NODE for the type name.  */
        !           404:       if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
        !           405:        {
        !           406:          t = TYPE_NAME (type);
        !           407:        }
        !           408: #if 1  /* As a temprary hack, use typedef names for C++ only.  */
        !           409:       else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
        !           410:               && TYPE_LANG_SPECIFIC (type))
        !           411:        {
        !           412:          t = DECL_NAME (TYPE_NAME (type));
        !           413:        }
        !           414: #endif
        !           415: 
        !           416:       /* Now get the name as a string, or invent one.  */
        !           417:       if (t != 0)
        !           418:        name = IDENTIFIER_POINTER (t);
        !           419:     }
        !           420: 
        !           421:   no_name = (name == 0 || *name == 0);
        !           422:   if (no_name)
        !           423:     name = gen_fake_label ();
        !           424: 
        !           425:   SET_KNOWN_TYPE_TAG (type, name);
        !           426: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !           427:   if (no_name)
        !           428:     sdbout_queue_anonymous_type (type);
        !           429: #endif
        !           430: }
        !           431: 
        !           432: static int
        !           433: plain_type_1 (type)
        !           434:      tree type;
        !           435: {
        !           436:   if (type == 0)
        !           437:     type = void_type_node;
        !           438:   if (type == error_mark_node)
        !           439:     type = integer_type_node;
        !           440:   type = TYPE_MAIN_VARIANT (type);
        !           441: 
        !           442:   switch (TREE_CODE (type))
        !           443:     {
        !           444:     case VOID_TYPE:
        !           445:       return T_VOID;
        !           446:     case INTEGER_TYPE:
        !           447:       {
        !           448:        int size = int_size_in_bytes (type) * BITS_PER_UNIT;
        !           449:        if (size == CHAR_TYPE_SIZE)
        !           450:          return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
        !           451:        if (size == SHORT_TYPE_SIZE)
        !           452:          return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
        !           453:        if (size == INT_TYPE_SIZE)
        !           454:          return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
        !           455:        return 0;
        !           456:       }
        !           457: 
        !           458:     case REAL_TYPE:
        !           459:       {
        !           460:        int size = int_size_in_bytes (type) * BITS_PER_UNIT;
        !           461:        if (size == FLOAT_TYPE_SIZE)
        !           462:          return T_FLOAT;
        !           463:        if (size == DOUBLE_TYPE_SIZE)
        !           464:          return T_DOUBLE;
        !           465:        return 0;
        !           466:       }
        !           467: 
        !           468:     case ARRAY_TYPE:
        !           469:       {
        !           470:        int m;
        !           471:        m = plain_type_1 (TREE_TYPE (type));
        !           472:        if (sdb_n_dims < SDB_MAX_DIM)
        !           473:          sdb_dims[sdb_n_dims++]
        !           474:            = (TYPE_DOMAIN (type)
        !           475:               ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1
        !           476:               : 0);
        !           477:        return PUSH_DERIVED_LEVEL (DT_ARY, m);
        !           478:       }
        !           479: 
        !           480:     case RECORD_TYPE:
        !           481:     case UNION_TYPE:
        !           482:     case ENUMERAL_TYPE:
        !           483:       {
        !           484:        char *tag;
        !           485: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !           486:        sdbout_record_type_name (type);
        !           487: #endif
        !           488: #ifndef SDB_ALLOW_UNKNOWN_REFERENCES
        !           489:        if ((TREE_ASM_WRITTEN (type) && KNOWN_TYPE_TAG (type) != 0)
        !           490: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !           491:            || TYPE_MODE (type) != VOIDmode
        !           492: #endif
        !           493:            )
        !           494: #endif
        !           495:          {
        !           496:            /* Output the referenced structure tag name
        !           497:               only if the .def has already been finished.
        !           498:               At least on 386, the Unix assembler
        !           499:               cannot handle forward references to tags.  */
        !           500:            /* But the 88100, it requires them, sigh... */
        !           501:            /* And the MIPS requires unknown refs as well... */
        !           502:            tag = KNOWN_TYPE_TAG (type);
        !           503:            PUT_SDB_TAG (tag);
        !           504:            /* These 3 lines used to follow the close brace.
        !           505:               However, a size of 0 without a tag implies a tag of 0,
        !           506:               so if we don't know a tag, we can't mention the size.  */
        !           507:            sdb_type_size = int_size_in_bytes (type);
        !           508:            if (sdb_type_size < 0)
        !           509:              sdb_type_size = 0;
        !           510:          }
        !           511:        return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
        !           512:                : (TREE_CODE (type) == UNION_TYPE) ? T_UNION
        !           513:                : T_ENUM);
        !           514:       }
        !           515:     case POINTER_TYPE:
        !           516:     case REFERENCE_TYPE:
        !           517:       {
        !           518:        int m = plain_type_1 (TREE_TYPE (type));
        !           519:        return PUSH_DERIVED_LEVEL (DT_PTR, m);
        !           520:       }
        !           521:     case FUNCTION_TYPE:
        !           522:     case METHOD_TYPE:
        !           523:       {
        !           524:        int m = plain_type_1 (TREE_TYPE (type));
        !           525:        return PUSH_DERIVED_LEVEL (DT_FCN, m);
        !           526:       }
        !           527:     default:
        !           528:       return 0;
        !           529:     }
        !           530: }
        !           531: 
        !           532: /* Output the symbols defined in block number DO_BLOCK.
        !           533:    Set NEXT_BLOCK_NUMBER to 0 before calling.
        !           534: 
        !           535:    This function works by walking the tree structure of blocks,
        !           536:    counting blocks until it finds the desired block.  */
        !           537: 
        !           538: static int do_block = 0;
        !           539: 
        !           540: static int next_block_number;
        !           541: 
        !           542: static void
        !           543: sdbout_block (block)
        !           544:      register tree block;
        !           545: {
        !           546:   while (block)
        !           547:     {
        !           548:       /* Ignore blocks never expanded or otherwise marked as real.  */
        !           549:       if (TREE_USED (block))
        !           550:        {
        !           551:          /* When we reach the specified block, output its symbols.  */
        !           552:          if (next_block_number == do_block)
        !           553:            {
        !           554:              sdbout_syms (BLOCK_VARS (block));
        !           555:            }
        !           556: 
        !           557:          /* If we are past the specified block, stop the scan.  */
        !           558:          if (next_block_number > do_block)
        !           559:            return;
        !           560: 
        !           561:          next_block_number++;
        !           562: 
        !           563:          /* Scan the blocks within this block.  */
        !           564:          sdbout_block (BLOCK_SUBBLOCKS (block));
        !           565:        }
        !           566: 
        !           567:       block = BLOCK_CHAIN (block);
        !           568:     }
        !           569: }
        !           570: 
        !           571: /* Call sdbout_symbol on each decl in the chain SYMS.  */
        !           572: 
        !           573: static void
        !           574: sdbout_syms (syms)
        !           575:      tree syms;
        !           576: {
        !           577:   while (syms)
        !           578:     {
        !           579:       if (TREE_CODE (syms) != LABEL_DECL)
        !           580:        sdbout_symbol (syms, 1);
        !           581:       syms = TREE_CHAIN (syms);
        !           582:     }
        !           583: }
        !           584: 
        !           585: /* Output SDB information for a symbol described by DECL.
        !           586:    LOCAL is nonzero if the symbol is not file-scope.  */
        !           587: 
        !           588: void
        !           589: sdbout_symbol (decl, local)
        !           590:      tree decl;
        !           591:      int local;
        !           592: {
        !           593:   int letter = 0;
        !           594:   tree type = TREE_TYPE (decl);
        !           595:   tree context = NULL_TREE;
        !           596:   rtx value;
        !           597:   int regno = -1;
        !           598:   char *name;
        !           599: 
        !           600:   sdbout_one_type (type);
        !           601: 
        !           602:   switch (TREE_CODE (decl))
        !           603:     {
        !           604:     case CONST_DECL:
        !           605:       /* Enum values are defined by defining the enum type.  */
        !           606:       return;
        !           607: 
        !           608:     case FUNCTION_DECL:
        !           609:       /* Don't mention a nested function under its parent.  */
        !           610:       context = decl_function_context (decl);
        !           611:       if (context == current_function_decl)
        !           612:        return;
        !           613:       if (TREE_EXTERNAL (decl))
        !           614:        return;
        !           615:       if (GET_CODE (DECL_RTL (decl)) != MEM
        !           616:          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
        !           617:        return;
        !           618:       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
        !           619:       PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
        !           620:       PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT);
        !           621:       break;
        !           622: 
        !           623:     case TYPE_DECL:
        !           624:       /* Done with tagged types.  */
        !           625:       if (DECL_NAME (decl) == 0)
        !           626:        return;
        !           627: 
        !           628:       /* Output typedef name.  */
        !           629:       PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
        !           630:       PUT_SDB_SCL (C_TPDEF);
        !           631:       break;
        !           632: 
        !           633:     case PARM_DECL:
        !           634:       /* Parm decls go in their own separate chains
        !           635:         and are output by sdbout_reg_parms and sdbout_parms.  */
        !           636:       abort ();
        !           637: 
        !           638:     case VAR_DECL:
        !           639:       /* Don't mention a variable that is external.
        !           640:         Let the file that defines it describe it.  */
        !           641:       if (TREE_EXTERNAL (decl))
        !           642:        return;
        !           643: 
        !           644:       /* If there was an error in the declaration, don't dump core
        !           645:         if there is no RTL associated with the variable doesn't
        !           646:         exist.  */
        !           647:       if (DECL_RTL (decl) == 0)
        !           648:        return;
        !           649: 
        !           650:       value = eliminate_regs (DECL_RTL (decl), 0, 0);
        !           651: 
        !           652:       /* Don't mention a variable at all
        !           653:         if it was completely optimized into nothingness.
        !           654: 
        !           655:         If DECL was from an inline function, then its rtl
        !           656:         is not identically the rtl that was used in this
        !           657:         particular compilation.  */
        !           658:       if (GET_CODE (value) == REG)
        !           659:        {
        !           660:          regno = REGNO (DECL_RTL (decl));
        !           661:          if (regno >= FIRST_PSEUDO_REGISTER)
        !           662:            regno = reg_renumber[REGNO (DECL_RTL (decl))];
        !           663:          if (regno < 0)
        !           664:            return;
        !           665:        }
        !           666:       else if (GET_CODE (DECL_RTL (decl)) == SUBREG)
        !           667:        {
        !           668:          int offset = 0;
        !           669:          while (GET_CODE (value) == SUBREG)
        !           670:            {
        !           671:              offset += SUBREG_WORD (value);
        !           672:              value = SUBREG_REG (value);
        !           673:            }
        !           674:          if (GET_CODE (value) == REG)
        !           675:            {
        !           676:              regno = REGNO (value);
        !           677:              if (regno >= FIRST_PSEUDO_REGISTER)
        !           678:                regno = reg_renumber[REGNO (value)];
        !           679:              if (regno >= 0)
        !           680:                regno += offset;
        !           681:            }
        !           682:        }
        !           683: 
        !           684:       /* Emit any structure, union, or enum type that has not been output.
        !           685:         This occurs for tag-less structs (et al) used to declare variables
        !           686:         within functions.  */
        !           687:       if (TREE_CODE (type) == ENUMERAL_TYPE
        !           688:          || TREE_CODE (type) == RECORD_TYPE
        !           689:          || TREE_CODE (type) == UNION_TYPE)
        !           690:        {
        !           691:          if (TYPE_SIZE (type) != 0             /* not a forward reference */
        !           692:              && KNOWN_TYPE_TAG (type) == 0)    /* not yet declared */
        !           693:            sdbout_one_type (type);
        !           694:        }
        !           695: 
        !           696:       /* Defer SDB information for top-level initialized variables! */
        !           697:       if (! local
        !           698:          && GET_CODE (value) == MEM
        !           699:          && DECL_INITIAL (decl))
        !           700:        return;
        !           701: 
        !           702:       /* Record the name for, starting a symtab entry.  */
        !           703:       name = IDENTIFIER_POINTER (DECL_NAME (decl));
        !           704: 
        !           705:       if (GET_CODE (value) == MEM
        !           706:          && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
        !           707:        {
        !           708:          PUT_SDB_DEF (name);
        !           709:          if (TREE_PUBLIC (decl))
        !           710:            {
        !           711:              PUT_SDB_VAL (XEXP (value, 0));
        !           712:               PUT_SDB_SCL (C_EXT);
        !           713:            }
        !           714:          else
        !           715:            {
        !           716:              PUT_SDB_VAL (XEXP (value, 0));
        !           717:               PUT_SDB_SCL (C_STAT);
        !           718:            }
        !           719:        }
        !           720:       else if (regno >= 0)
        !           721:        {
        !           722:          PUT_SDB_DEF (name);
        !           723:          PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (regno));
        !           724:          PUT_SDB_SCL (C_REG);
        !           725:        }
        !           726:       else if (GET_CODE (value) == MEM
        !           727:               && (GET_CODE (XEXP (value, 0)) == MEM
        !           728:                   || (GET_CODE (XEXP (value, 0)) == REG
        !           729:                       && REGNO (XEXP (value, 0)) != FRAME_POINTER_REGNUM
        !           730:                       && REGNO (XEXP (value, 0)) != STACK_POINTER_REGNUM)))
        !           731:        /* If the value is indirect by memory or by a register
        !           732:           that isn't the frame pointer
        !           733:           then it means the object is variable-sized and address through
        !           734:           that register or stack slot.  COFF has no way to represent this
        !           735:           so all we can do is output the variable as a pointer.  */
        !           736:        {
        !           737:          PUT_SDB_DEF (name);
        !           738:          if (GET_CODE (XEXP (value, 0)) == REG)
        !           739:            {
        !           740:              PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
        !           741:              PUT_SDB_SCL (C_REG);
        !           742:            }
        !           743:          else
        !           744:            {
        !           745:              /* DECL_RTL looks like (MEM (MEM (PLUS (REG...)
        !           746:                 (CONST_INT...)))).
        !           747:                 We want the value of that CONST_INT.  */
        !           748:              /* Encore compiler hates a newline in a macro arg, it seems.  */
        !           749:              PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
        !           750:                               (XEXP (XEXP (value, 0), 0)));
        !           751:              PUT_SDB_SCL (C_AUTO);
        !           752:            }
        !           753: 
        !           754:          type = build_pointer_type (TREE_TYPE (decl));
        !           755:        }
        !           756:       else if (GET_CODE (value) == MEM
        !           757:               && GET_CODE (XEXP (value, 0)) == PLUS
        !           758:               && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
        !           759:               && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT)
        !           760:        {
        !           761:          /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
        !           762:             We want the value of that CONST_INT.  */
        !           763:          PUT_SDB_DEF (name);
        !           764:          PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET (XEXP (value, 0)));
        !           765:          PUT_SDB_SCL (C_AUTO);
        !           766:        }
        !           767:       else
        !           768:        {
        !           769:          /* It is something we don't know how to represent for SDB.  */
        !           770:          return;
        !           771:        }
        !           772:       break;
        !           773:     }
        !           774:   PUT_SDB_TYPE (plain_type (type));
        !           775:   PUT_SDB_ENDEF;
        !           776: }
        !           777: 
        !           778: /* Output SDB information for a top-level initialized variable
        !           779:    that has been delayed.  */
        !           780: 
        !           781: void
        !           782: sdbout_toplevel_data (decl)
        !           783:      tree decl;
        !           784: {
        !           785:   tree type = TREE_TYPE (decl);
        !           786: 
        !           787:   if (! (TREE_CODE (decl) == VAR_DECL
        !           788:         && GET_CODE (DECL_RTL (decl)) == MEM
        !           789:         && DECL_INITIAL (decl)))
        !           790:     abort ();
        !           791: 
        !           792:   PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
        !           793:   PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
        !           794:   if (TREE_PUBLIC (decl))
        !           795:     {
        !           796:       PUT_SDB_SCL (C_EXT);
        !           797:     }
        !           798:   else
        !           799:     {
        !           800:       PUT_SDB_SCL (C_STAT);
        !           801:     }
        !           802:   PUT_SDB_TYPE (plain_type (type));
        !           803:   PUT_SDB_ENDEF;
        !           804: }
        !           805: 
        !           806: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !           807: 
        !           808: /* Machinery to record and output anonymous types. */
        !           809: 
        !           810: static tree anonymous_types;
        !           811: 
        !           812: static void
        !           813: sdbout_queue_anonymous_type (type)
        !           814:      tree type;
        !           815: {
        !           816:   anonymous_types = saveable_tree_cons (NULL_TREE, type, anonymous_types);
        !           817: }
        !           818: 
        !           819: static void
        !           820: sdbout_dequeue_anonymous_types ()
        !           821: {
        !           822:   register tree types, link;
        !           823: 
        !           824:   while (anonymous_types)
        !           825:     {
        !           826:       types = nreverse (anonymous_types);
        !           827:       anonymous_types = NULL_TREE;
        !           828: 
        !           829:       for (link = types; link; link = TREE_CHAIN (link))
        !           830:        {
        !           831:          register tree type = TREE_VALUE (link);
        !           832: 
        !           833:          if (! TREE_ASM_WRITTEN (type))
        !           834:            sdbout_one_type (type);
        !           835:        }
        !           836:     }
        !           837: }
        !           838: 
        !           839: #endif
        !           840: 
        !           841: /* Given a chain of ..._TYPE nodes, all of which have names,
        !           842:    output definitions of those names, as typedefs.  */
        !           843: 
        !           844: void
        !           845: sdbout_types (types)
        !           846:      register tree types;
        !           847: {
        !           848:   register tree link;
        !           849: 
        !           850:   for (link = types; link; link = TREE_CHAIN (link))
        !           851:     sdbout_one_type (link);
        !           852: 
        !           853: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !           854:   sdbout_dequeue_anonymous_types ();
        !           855: #endif
        !           856: }
        !           857: 
        !           858: static void
        !           859: sdbout_type (type)
        !           860:      tree type;
        !           861: {
        !           862:   register tree tem;
        !           863:   if (type == error_mark_node)
        !           864:     type = integer_type_node;
        !           865:   PUT_SDB_TYPE (plain_type (type));
        !           866: }
        !           867: 
        !           868: /* Output types of the fields of type TYPE, if they are structs.
        !           869: 
        !           870:    Formerly did not chase through pointer types, since that could be circular.
        !           871:    They must come before TYPE, since forward refs are not allowed.
        !           872:    Now [email protected] says to try them.  */
        !           873: 
        !           874: static void
        !           875: sdbout_field_types (type)
        !           876:      tree type;
        !           877: {
        !           878:   tree tail;
        !           879:   for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
        !           880:     if (TREE_CODE (TREE_TYPE (tail)) == POINTER_TYPE)
        !           881:       sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
        !           882:     else
        !           883:       sdbout_one_type (TREE_TYPE (tail));
        !           884: }
        !           885: 
        !           886: /* Use this to put out the top level defined record and union types
        !           887:    for later reference.  If this is a struct with a name, then put that
        !           888:    name out.  Other unnamed structs will have .xxfake labels generated so
        !           889:    that they may be referred to later.
        !           890:    The label will be stored in the KNOWN_TYPE_TAG slot of a type.
        !           891:    It may NOT be called recursively.  */
        !           892: 
        !           893: static void
        !           894: sdbout_one_type (type)
        !           895:      tree type;
        !           896: {
        !           897:   text_section ();
        !           898: 
        !           899:   switch (TREE_CODE (type))
        !           900:     {
        !           901:     case RECORD_TYPE:
        !           902:     case UNION_TYPE:
        !           903:     case ENUMERAL_TYPE:
        !           904:       type = TYPE_MAIN_VARIANT (type);
        !           905:       /* Don't output a type twice.  */
        !           906:       if (TREE_ASM_WRITTEN (type))
        !           907:        /* James said test TREE_ASM_BEING_WRITTEN here.  */
        !           908:        return;
        !           909: 
        !           910:       /* Output nothing if type is not yet defined.  */
        !           911:       if (TYPE_SIZE (type) == 0)
        !           912:        return;
        !           913: 
        !           914:       TREE_ASM_WRITTEN (type) = 1;
        !           915: #if 1
        !           916:       /* This is reputed to cause trouble with the following case,
        !           917:         but perhaps checking TYPE_SIZE above will fix it.
        !           918: 
        !           919:       /* Here is a test case:
        !           920: 
        !           921:        struct foo {
        !           922:          struct badstr *bbb;
        !           923:        } forwardref;
        !           924: 
        !           925:        typedef struct intermediate {
        !           926:          int aaaa;
        !           927:        } intermediate_ref;
        !           928: 
        !           929:        typedef struct badstr {
        !           930:          int ccccc;
        !           931:        } badtype;   */
        !           932: 
        !           933: #if 0
        !           934:       TREE_ASM_BEING_WRITTEN (type) = 1;
        !           935: #endif
        !           936:       /* This change, which ought to make better output,
        !           937:         used to make the COFF assembler unhappy.
        !           938:         Changes involving KNOWN_TYPE_TAG may fix the problem.  */
        !           939:       /* Before really doing anything, output types we want to refer to.  */
        !           940:       /* Note that in version 1 the following two lines
        !           941:         are not used if forward references are in use.  */
        !           942:       if (TREE_CODE (type) != ENUMERAL_TYPE)
        !           943:        sdbout_field_types (type);
        !           944: #if 0
        !           945:       TREE_ASM_WRITTEN (type) = 1;
        !           946: #endif
        !           947: #endif
        !           948: 
        !           949:       /* Output a structure type.  */
        !           950:       {
        !           951:        int size = int_size_in_bytes (type);
        !           952:        int member_scl;
        !           953:        tree tem;
        !           954:        int i, n_baseclasses = 0;
        !           955: 
        !           956:        /* Record the type tag, but not in its permanent place just yet.  */
        !           957:        sdbout_record_type_name (type);
        !           958: 
        !           959:        PUT_SDB_DEF (KNOWN_TYPE_TAG (type));
        !           960: 
        !           961:        switch (TREE_CODE (type))
        !           962:          {
        !           963:          case UNION_TYPE:
        !           964:            PUT_SDB_SCL (C_UNTAG);
        !           965:            PUT_SDB_TYPE (T_UNION);
        !           966:            member_scl = C_MOU;
        !           967:            break;
        !           968: 
        !           969:          case RECORD_TYPE:
        !           970:            PUT_SDB_SCL (C_STRTAG);
        !           971:            PUT_SDB_TYPE (T_STRUCT);
        !           972:            member_scl = C_MOS;
        !           973:            break;
        !           974: 
        !           975:          case ENUMERAL_TYPE:
        !           976:            PUT_SDB_SCL (C_ENTAG);
        !           977:            PUT_SDB_TYPE (T_ENUM);
        !           978:            member_scl = C_MOE;
        !           979:            break;
        !           980:          }
        !           981: 
        !           982:        PUT_SDB_SIZE (size);
        !           983:        PUT_SDB_ENDEF;
        !           984: 
        !           985:        /* Print out the base class information with fields
        !           986:           named after the types they hold.  */
        !           987:        if (TYPE_BINFO (type)
        !           988:            && TYPE_BINFO_BASETYPES (type))
        !           989:          n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
        !           990:        for (i = 0; i < n_baseclasses; i++)
        !           991:          {
        !           992:            tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
        !           993:            tree child_type = BINFO_TYPE (child);
        !           994:            tree child_type_name;
        !           995:            if (TYPE_NAME (child_type) == 0)
        !           996:              continue;
        !           997:            if (TREE_CODE (TYPE_NAME (child_type)) == IDENTIFIER_NODE)
        !           998:              child_type_name = TYPE_NAME (child_type);
        !           999:            else if (TREE_CODE (TYPE_NAME (child_type)) == TYPE_DECL)
        !          1000:              child_type_name = DECL_NAME (TYPE_NAME (child_type));
        !          1001:            else
        !          1002:              continue;
        !          1003: 
        !          1004:            CONTIN;
        !          1005:            PUT_SDB_DEF (IDENTIFIER_POINTER (child_type_name));
        !          1006:            PUT_SDB_INT_VAL (TREE_INT_CST_LOW (BINFO_OFFSET (child)));
        !          1007:            PUT_SDB_SCL (member_scl);
        !          1008:            sdbout_type (BINFO_TYPE (child));
        !          1009:            PUT_SDB_ENDEF;
        !          1010:          }
        !          1011: 
        !          1012:        /* output the individual fields */
        !          1013: 
        !          1014:        if (TREE_CODE (type) == ENUMERAL_TYPE)
        !          1015:          for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
        !          1016:            {
        !          1017:              PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
        !          1018:              PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem)));
        !          1019:              PUT_SDB_SCL (C_MOE);
        !          1020:              PUT_SDB_TYPE (T_MOE);
        !          1021:              PUT_SDB_ENDEF;
        !          1022:            }
        !          1023: 
        !          1024:        else                    /* record or union type */
        !          1025:          for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
        !          1026:            /* Output the name, type, position (in bits), size (in bits)
        !          1027:               of each field.  */
        !          1028: 
        !          1029:            /* Omit here the nameless fields that are used to skip bits.
        !          1030:               Also omit fields with variable size or position.
        !          1031:               Also omit non FIELD_DECL nodes that GNU C++ may put here.  */
        !          1032:            if (TREE_CODE (tem) == FIELD_DECL
        !          1033:                && DECL_NAME (tem) != 0
        !          1034:                && TREE_CODE (DECL_SIZE (tem)) == INTEGER_CST
        !          1035:                && TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
        !          1036:              {
        !          1037:                CONTIN;
        !          1038:                PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (tem)));
        !          1039:                if (DECL_BIT_FIELD_TYPE (tem))
        !          1040:                  {
        !          1041:                    PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
        !          1042:                    PUT_SDB_SCL (C_FIELD);
        !          1043:                    sdbout_type (DECL_BIT_FIELD_TYPE (tem));
        !          1044:                    PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem)));
        !          1045:                  }
        !          1046:                else
        !          1047:                  {
        !          1048:                    PUT_SDB_INT_VAL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem))
        !          1049:                                     / BITS_PER_UNIT);
        !          1050:                    PUT_SDB_SCL (member_scl);
        !          1051:                    sdbout_type (TREE_TYPE (tem));
        !          1052:                  }
        !          1053:                PUT_SDB_ENDEF;
        !          1054:              }
        !          1055:        /* output end of a structure,union, or enumeral definition */
        !          1056: 
        !          1057:        PUT_SDB_PLAIN_DEF ("eos");
        !          1058:        PUT_SDB_INT_VAL (size);
        !          1059:        PUT_SDB_SCL (C_EOS);
        !          1060:        PUT_SDB_TAG (KNOWN_TYPE_TAG (type));
        !          1061:        PUT_SDB_SIZE (size);
        !          1062:        PUT_SDB_ENDEF;
        !          1063:        break;
        !          1064:       }
        !          1065:     }
        !          1066: }
        !          1067: 
        !          1068: /* The following two functions output definitions of function parameters.
        !          1069:    Each parameter gets a definition locating it in the parameter list.
        !          1070:    Each parameter that is a register variable gets a second definition
        !          1071:    locating it in the register.
        !          1072: 
        !          1073:    Printing or argument lists in gdb uses the definitions that
        !          1074:    locate in the parameter list.  But reference to the variable in
        !          1075:    expressions uses preferentially the definition as a register.  */
        !          1076: 
        !          1077: /* Output definitions, referring to storage in the parmlist,
        !          1078:    of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */
        !          1079: 
        !          1080: static void
        !          1081: sdbout_parms (parms)
        !          1082:      tree parms;
        !          1083: {
        !          1084:   for (; parms; parms = TREE_CHAIN (parms))
        !          1085:     if (DECL_NAME (parms))
        !          1086:       {
        !          1087:        int current_sym_value = 0;
        !          1088:        char *name = IDENTIFIER_POINTER (DECL_NAME (parms));
        !          1089: 
        !          1090:        if (name == 0 || *name == 0)
        !          1091:          name = gen_fake_label ();
        !          1092: 
        !          1093:        /* Perform any necessary register eliminations on the parameter's rtl,
        !          1094:           so that the debugging output will be accurate.  */
        !          1095:        DECL_INCOMING_RTL (parms) =
        !          1096:          eliminate_regs (DECL_INCOMING_RTL (parms), 0, 0);
        !          1097:        DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, 0);
        !          1098: 
        !          1099:        if (PARM_PASSED_IN_MEMORY (parms))
        !          1100:          {
        !          1101:            rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
        !          1102:            tree type;
        !          1103: 
        !          1104:            /* ??? Here we assume that the parm address is indexed
        !          1105:               off the frame pointer or arg pointer.
        !          1106:               If that is not true, we produce meaningless results,
        !          1107:               but do not crash.  */
        !          1108:            if (GET_CODE (addr) == PLUS
        !          1109:                && GET_CODE (XEXP (addr, 1)) == CONST_INT)
        !          1110:              current_sym_value = INTVAL (XEXP (addr, 1));
        !          1111:            else
        !          1112:              current_sym_value = 0;
        !          1113: 
        !          1114:            if (GET_CODE (DECL_RTL (parms)) == REG
        !          1115:                && REGNO (DECL_RTL (parms)) >= 0
        !          1116:                && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
        !          1117:              type = DECL_ARG_TYPE (parms);
        !          1118:            else
        !          1119:              {
        !          1120:                int original_sym_value = current_sym_value;
        !          1121: 
        !          1122:                /* This is the case where the parm is passed as an int or
        !          1123:                   double and it is converted to a char, short or float
        !          1124:                   and stored back in the parmlist.  In this case, describe
        !          1125:                   the parm with the variable's declared type, and adjust
        !          1126:                   the address if the least significant bytes (which we are
        !          1127:                   using) are not the first ones.  */
        !          1128: #if BYTES_BIG_ENDIAN
        !          1129:                if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
        !          1130:                  current_sym_value +=
        !          1131:                    (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
        !          1132:                     - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
        !          1133: #endif
        !          1134:                if (GET_CODE (DECL_RTL (parms)) == MEM
        !          1135:                    && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
        !          1136:                    && (GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1))
        !          1137:                        == CONST_INT)
        !          1138:                    && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1))
        !          1139:                        == current_sym_value))
        !          1140:                  type = TREE_TYPE (parms);
        !          1141:                else
        !          1142:                  {
        !          1143:                    current_sym_value = original_sym_value;
        !          1144:                    type = DECL_ARG_TYPE (parms);
        !          1145:                  }
        !          1146:              }
        !          1147: 
        !          1148:            PUT_SDB_DEF (name);
        !          1149:            PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value, addr));
        !          1150:            PUT_SDB_SCL (C_ARG);
        !          1151:            PUT_SDB_TYPE (plain_type (type));
        !          1152:            PUT_SDB_ENDEF;
        !          1153:          }
        !          1154:        else if (GET_CODE (DECL_RTL (parms)) == REG)
        !          1155:          {
        !          1156:            rtx best_rtl;
        !          1157:            /* Parm passed in registers and lives in registers or nowhere.  */
        !          1158: 
        !          1159:            /* If parm lives in a register, use that register;
        !          1160:               pretend the parm was passed there.  It would be more consistent
        !          1161:               to describe the register where the parm was passed,
        !          1162:               but in practice that register usually holds something else.  */
        !          1163:            if (REGNO (DECL_RTL (parms)) >= 0
        !          1164:                && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
        !          1165:              best_rtl = DECL_RTL (parms);
        !          1166:            /* If the parm lives nowhere,
        !          1167:               use the register where it was passed.  */
        !          1168:            else
        !          1169:              best_rtl = DECL_INCOMING_RTL (parms);
        !          1170: 
        !          1171:            PUT_SDB_DEF (name);
        !          1172:            PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (best_rtl)));
        !          1173:            PUT_SDB_SCL (C_REGPARM);
        !          1174:            PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
        !          1175:            PUT_SDB_ENDEF;
        !          1176:          }
        !          1177:        else if (GET_CODE (DECL_RTL (parms)) == MEM
        !          1178:                 && XEXP (DECL_RTL (parms), 0) != const0_rtx)
        !          1179:          {
        !          1180:            /* Parm was passed in registers but lives on the stack.  */
        !          1181: 
        !          1182:            /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))),
        !          1183:               in which case we want the value of that CONST_INT,
        !          1184:               or (MEM (REG ...)) or (MEM (MEM ...)),
        !          1185:               in which case we use a value of zero.  */
        !          1186:            if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
        !          1187:                || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM)
        !          1188:              current_sym_value = 0;
        !          1189:            else
        !          1190:              current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
        !          1191: 
        !          1192:            /* Again, this assumes the offset is based on the arg pointer.  */
        !          1193:            PUT_SDB_DEF (name);
        !          1194:            PUT_SDB_INT_VAL (DEBUGGER_ARG_OFFSET (current_sym_value,
        !          1195:                                                  XEXP (DECL_RTL (parms), 0)));
        !          1196:            PUT_SDB_SCL (C_ARG);
        !          1197:            PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
        !          1198:            PUT_SDB_ENDEF;
        !          1199:          }
        !          1200:       }
        !          1201: }
        !          1202: 
        !          1203: /* Output definitions for the places where parms live during the function,
        !          1204:    when different from where they were passed, when the parms were passed
        !          1205:    in memory.
        !          1206: 
        !          1207:    It is not useful to do this for parms passed in registers
        !          1208:    that live during the function in different registers, because it is
        !          1209:    impossible to look in the passed register for the passed value,
        !          1210:    so we use the within-the-function register to begin with.
        !          1211: 
        !          1212:    PARMS is a chain of PARM_DECL nodes.  */
        !          1213: 
        !          1214: static void
        !          1215: sdbout_reg_parms (parms)
        !          1216:      tree parms;
        !          1217: {
        !          1218:   for (; parms; parms = TREE_CHAIN (parms))
        !          1219:     if (DECL_NAME (parms))
        !          1220:       {
        !          1221:        char *name = IDENTIFIER_POINTER (DECL_NAME (parms));
        !          1222: 
        !          1223:        /* Report parms that live in registers during the function
        !          1224:           but were passed in memory.  */
        !          1225:        if (GET_CODE (DECL_RTL (parms)) == REG
        !          1226:            && REGNO (DECL_RTL (parms)) >= 0
        !          1227:            && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
        !          1228:            && PARM_PASSED_IN_MEMORY (parms))
        !          1229:          {
        !          1230:            if (name == 0 || *name == 0)
        !          1231:              name = gen_fake_label ();
        !          1232:            PUT_SDB_DEF (name);
        !          1233:            PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
        !          1234:            PUT_SDB_SCL (C_REG);
        !          1235:            PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
        !          1236:            PUT_SDB_ENDEF;
        !          1237:          }
        !          1238:        /* Report parms that live in memory but not where they were passed.  */
        !          1239:        else if (GET_CODE (DECL_RTL (parms)) == MEM
        !          1240:                 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
        !          1241:                 && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
        !          1242:                 && PARM_PASSED_IN_MEMORY (parms)
        !          1243:                 && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms)))
        !          1244:          {
        !          1245: #if 0 /* ??? It is not clear yet what should replace this.  */
        !          1246:            int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
        !          1247:            /* A parm declared char is really passed as an int,
        !          1248:               so it occupies the least significant bytes.
        !          1249:               On a big-endian machine those are not the low-numbered ones.  */
        !          1250: #if BYTES_BIG_ENDIAN
        !          1251:            if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
        !          1252:              offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
        !          1253:                         - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
        !          1254: #endif
        !          1255:            if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
        !          1256: #endif
        !          1257:              {
        !          1258:                if (name == 0 || *name == 0)
        !          1259:                  name = gen_fake_label ();
        !          1260:                PUT_SDB_DEF (name);
        !          1261:                PUT_SDB_INT_VAL (DEBUGGER_AUTO_OFFSET
        !          1262:                                 (XEXP (DECL_RTL (parms), 0)));
        !          1263:                PUT_SDB_SCL (C_AUTO);
        !          1264:                PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
        !          1265:                PUT_SDB_ENDEF;
        !          1266:              }
        !          1267:          }
        !          1268:       }
        !          1269: }
        !          1270: 
        !          1271: /* Describe the beginning of an internal block within a function.
        !          1272:    Also output descriptions of variables defined in this block.
        !          1273: 
        !          1274:    N is the number of the block, by order of beginning, counting from 1,
        !          1275:    and not counting the outermost (function top-level) block.
        !          1276:    The blocks match the BLOCKs in DECL_INITIAL (current_function_decl),
        !          1277:    if the count starts at 0 for the outermost one.  */
        !          1278: 
        !          1279: void
        !          1280: sdbout_begin_block (file, line, n)
        !          1281:      FILE *file;
        !          1282:      int line;
        !          1283:      int n;
        !          1284: {
        !          1285:   tree decl = current_function_decl;
        !          1286:   MAKE_LINE_SAFE (line);
        !          1287:   PUT_SDB_BLOCK_START (line - sdb_begin_function_line);
        !          1288:   if (n == 1)
        !          1289:     {
        !          1290:       /* Include the outermost BLOCK's variables in block 1.  */
        !          1291:       next_block_number = 0;
        !          1292:       do_block = 0;
        !          1293:       sdbout_block (DECL_INITIAL (decl));
        !          1294:     }
        !          1295:   /* If -g1, suppress all the internal symbols of functions
        !          1296:      except for arguments.  */
        !          1297:   if (debug_info_level != DINFO_LEVEL_TERSE)
        !          1298:     {
        !          1299:       next_block_number = 0;
        !          1300:       do_block = n;
        !          1301:       sdbout_block (DECL_INITIAL (decl));
        !          1302:     }
        !          1303: 
        !          1304: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !          1305:   sdbout_dequeue_anonymous_types ();
        !          1306: #endif
        !          1307: }
        !          1308: 
        !          1309: /* Describe the end line-number of an internal block within a function.  */
        !          1310: 
        !          1311: void
        !          1312: sdbout_end_block (file, line)
        !          1313:      FILE *file;
        !          1314:      int line;
        !          1315: {
        !          1316:   MAKE_LINE_SAFE (line);
        !          1317:   PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
        !          1318: }
        !          1319: 
        !          1320: /* Output sdb info for the current function name.
        !          1321:    Called from assemble_start_function.  */
        !          1322: 
        !          1323: void
        !          1324: sdbout_mark_begin_function ()
        !          1325: {
        !          1326:   sdbout_symbol (current_function_decl, 0);
        !          1327: }
        !          1328: 
        !          1329: /* Called at beginning of function body (after prologue).
        !          1330:    Record the function's starting line number, so we can output
        !          1331:    relative line numbers for the other lines.
        !          1332:    Describe beginning of outermost block.
        !          1333:    Also describe the parameter list.  */
        !          1334: 
        !          1335: void
        !          1336: sdbout_begin_function (line)
        !          1337:      int line;
        !          1338: {
        !          1339:   sdb_begin_function_line = line - 1;
        !          1340:   PUT_SDB_FUNCTION_START (line);
        !          1341:   sdbout_parms (DECL_ARGUMENTS (current_function_decl));
        !          1342:   sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl));
        !          1343: }
        !          1344: 
        !          1345: /* Called at end of function (before epilogue).
        !          1346:    Describe end of outermost block.  */
        !          1347: 
        !          1348: void
        !          1349: sdbout_end_function (line)
        !          1350:      int line;
        !          1351: {
        !          1352: #ifdef SDB_ALLOW_FORWARD_REFERENCES
        !          1353:   sdbout_dequeue_anonymous_types ();
        !          1354: #endif
        !          1355: 
        !          1356:   MAKE_LINE_SAFE (line);
        !          1357:   PUT_SDB_FUNCTION_END (line - sdb_begin_function_line);
        !          1358: 
        !          1359:   /* Indicate we are between functions, for line-number output.  */
        !          1360:   sdb_begin_function_line = -1;
        !          1361: }
        !          1362: 
        !          1363: /* Output sdb info for the absolute end of a function.
        !          1364:    Called after the epilogue is output.  */
        !          1365: 
        !          1366: void
        !          1367: sdbout_end_epilogue ()
        !          1368: {
        !          1369:   char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (current_function_decl));
        !          1370:   PUT_SDB_EPILOGUE_END (name);
        !          1371: }
        !          1372: 
        !          1373: /* Output sdb info for the given label.  Called only if LABEL_NAME (insn)
        !          1374:    is present.  */
        !          1375: 
        !          1376: void
        !          1377: sdbout_label (insn)
        !          1378:      register rtx insn;
        !          1379: {
        !          1380:   PUT_SDB_DEF (LABEL_NAME (insn));
        !          1381:   PUT_SDB_VAL (insn);
        !          1382:   PUT_SDB_SCL (C_LABEL);
        !          1383:   PUT_SDB_TYPE (T_NULL);
        !          1384:   PUT_SDB_ENDEF;
        !          1385: }
        !          1386: 
        !          1387: #endif /* SDB_DEBUGGING_INFO */

unix.superglobalmegacorp.com

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