Annotation of gcc/dbxout.c, revision 1.1

1.1     ! root        1: /* Output dbx-format symbol table information from GNU compiler.
        !             2:    Copyright (C) 1987 Free Software Foundation, Inc.
        !             3: 
        !             4: This file is part of GNU CC.
        !             5: 
        !             6: GNU CC is distributed in the hope that it will be useful,
        !             7: but WITHOUT ANY WARRANTY.  No author or distributor
        !             8: accepts responsibility to anyone for the consequences of using it
        !             9: or for whether it serves any particular purpose or works at all,
        !            10: unless he says so in writing.  Refer to the GNU CC General Public
        !            11: License for full details.
        !            12: 
        !            13: Everyone is granted permission to copy, modify and redistribute
        !            14: GNU CC, but only under the conditions described in the
        !            15: GNU CC General Public License.   A copy of this license is
        !            16: supposed to have been given to you along with GNU CC so you
        !            17: can know your rights and responsibilities.  It should be in a
        !            18: file named COPYING.  Among other things, the copyright notice
        !            19: and this notice must be preserved on all copies.  */
        !            20: 
        !            21: 
        !            22: /* Output dbx-format symbol table data.
        !            23:    This consists of many symbol table entries, each of them
        !            24:    a .stabs assembler pseudo-op with four operands:
        !            25:    a "name" which is really a description of one symbol and its type,
        !            26:    a "code", which is a symbol defined in stab.h whose name starts with N_,
        !            27:    an unused operand always 0,
        !            28:    and a "value" which is an address or an offset.
        !            29:    The name is enclosed in doublequote characters.
        !            30: 
        !            31:    Each function, variable, typedef, and structure tag
        !            32:    has a symbol table entry to define it.
        !            33:    The beginning and end of each level of name scoping within
        !            34:    a function are also marked by special symbol table entries.
        !            35: 
        !            36:    The "name" consists of the symbol name, a colon, a kind-of-symbol letter,
        !            37:    and a data type number.  The data type number may be followed by
        !            38:    "=" and a type definition; normally this will happen the first time
        !            39:    the type number is mentioned.  The type definition may refer to
        !            40:    other types by number, and those type numbers may be followed
        !            41:    by "=" and nested definitions.
        !            42: 
        !            43:    This can make the "name" quite long.
        !            44:    When a name is more than 80 characters, we split the .stabs pseudo-op
        !            45:    into two .stabs pseudo-ops, both sharing the same "code" and "value".
        !            46:    The first one is marked as continued with a double-backslash at the
        !            47:    end of its "name".
        !            48: 
        !            49:    The kind-of-symbol letter distinguished function names from global
        !            50:    variables from file-scope variables from parameters from auto
        !            51:    variables in memory from typedef names from register variables.
        !            52:    See `dbxout_symbol'.
        !            53: 
        !            54:    The "code" is mostly redundant with the kind-of-symbol letter
        !            55:    that goes in the "name", but not entirely: for symbols located
        !            56:    in static storage, the "code" says which segment the address is in,
        !            57:    which controls how it is relocated.
        !            58: 
        !            59:    The "value" for a symbol in static storage
        !            60:    is the core address of the symbol (actually, the assembler
        !            61:    label for the symbol).  For a symbol located in a stack slot
        !            62:    it is the stack offset; for one in a register, the register number.
        !            63:    For a typedef symbol, it is zero.
        !            64: 
        !            65:    For more on data type definitions, see `dbxout_type'.  */
        !            66: 
        !            67: #include "config.h"
        !            68: #include "tree.h"
        !            69: #include "rtl.h"
        !            70: #include "c-tree.h"
        !            71: #include <stdio.h>
        !            72: #include <stab.h>
        !            73: 
        !            74: /* Stream for writing to assembler file.  */
        !            75: 
        !            76: static FILE *asmfile;
        !            77: 
        !            78: enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
        !            79: 
        !            80: /* Vector recording the status of describing C data types.
        !            81:    When we first notice a data type (a tree node),
        !            82:    we assign it a number using next_type_number.
        !            83:    That is its index in this vector.
        !            84:    The vector element says whether we have yet output
        !            85:    the definition of the type.  TYPE_XREF says we have
        !            86:    output it as a cross-reference only.  */
        !            87: 
        !            88: enum typestatus *typevec;
        !            89: 
        !            90: /* Number of elements of space allocated in `typevec'.  */
        !            91: 
        !            92: static int typevec_len;
        !            93: 
        !            94: /* In dbx output, each type gets a unique number.
        !            95:    This is the number for the next type output.
        !            96:    The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field.  */
        !            97: 
        !            98: static int next_type_number;
        !            99: 
        !           100: /* In dbx output, we must assign symbol-blocks id numbers
        !           101:    in the order in which their beginnings are encountered.
        !           102:    We output debugging info that refers to the beginning and
        !           103:    end of the ranges of code in each block
        !           104:    with assembler labels LBBn and LBEn, where n is the block number.
        !           105:    The labels are generated in final, which assigns numbers to the
        !           106:    blocks in the same way.  */
        !           107: 
        !           108: static int next_block_number;
        !           109: 
        !           110: /* These variables are for dbxout_symbol to communicate to
        !           111:    dbxout_finish_symbol.
        !           112:    current_sym_code is the symbol-type-code, a symbol N_... define in stab.h.
        !           113:    current_sym_value and current_sym_addr are two ways to address the
        !           114:    value to store in the symtab entry.
        !           115:    current_sym_addr if nonzero represents the value as an rtx.
        !           116:    If that is zero, current_sym_value is used.  This is used
        !           117:    when the value is an offset (such as for auto variables,
        !           118:    register variables and parms).  */
        !           119: 
        !           120: static int current_sym_code;
        !           121: static int current_sym_value;
        !           122: static rtx current_sym_addr;
        !           123: 
        !           124: /* Number of chars of symbol-description generated so far for the
        !           125:    current symbol.  Used by CHARS and CONTIN.  */
        !           126: 
        !           127: static int current_sym_nchars;
        !           128: 
        !           129: /* Report having output N chars of the current symbol-description.  */
        !           130: 
        !           131: #define CHARS(N) (current_sym_nchars += (N))
        !           132: 
        !           133: /* Break the current symbol-description, generating a continuation,
        !           134:    if it has become long.  */
        !           135: 
        !           136: #define CONTIN  \
        !           137:   do {if (current_sym_nchars > 80) dbxout_continue ();} while (0)
        !           138: 
        !           139: void dbxout_types ();
        !           140: void dbxout_tags ();
        !           141: static void dbxout_type_name ();
        !           142: static void dbxout_type ();
        !           143: static void dbxout_type_def ();
        !           144: static void dbxout_finish_symbol ();
        !           145: static void dbxout_continue ();
        !           146: 
        !           147: /* At the beginning of compilation, start writing the symbol table.
        !           148:    Initialize `typevec' and output the standard data types of C.  */
        !           149: 
        !           150: void
        !           151: dbxout_init (asm_file, input_file_name)
        !           152:      FILE *asm_file;
        !           153:      char *input_file_name;
        !           154: {
        !           155:   asmfile = asm_file;
        !           156: 
        !           157:   typevec_len = 100;
        !           158:   typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]);
        !           159:   bzero (typevec, typevec_len * sizeof typevec[0]);
        !           160:   
        !           161:   fprintf (asmfile,
        !           162:           "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n",
        !           163:           input_filename, N_SO);
        !           164: 
        !           165:   next_type_number = 1;
        !           166:   next_block_number = 2;
        !           167: 
        !           168:   /* Make sure that types `int' and `char' have numbers 1 and 2.
        !           169:      Definitions of other integer types will refer to those numbers.  */
        !           170: 
        !           171:   dbxout_type_def (integer_type_node);
        !           172:   dbxout_type_def (char_type_node);
        !           173: 
        !           174:   /* Get all permanent types not yet gotten
        !           175:      and output them.  */
        !           176: 
        !           177:   dbxout_types (get_permanent_types ());
        !           178: }
        !           179: 
        !           180: /* Continue a symbol-description that gets too big.
        !           181:    End one symbol table entry with a double-backslash
        !           182:    and start a new one, eventually producing something like
        !           183:    .stabs "start......\\",code,0,value
        !           184:    .stabs "...rest",code,0,value   */
        !           185: 
        !           186: static void
        !           187: dbxout_continue ()
        !           188: {
        !           189:   fprintf (asmfile, "\\\\");
        !           190:   dbxout_finish_symbol ();
        !           191:   fprintf (asmfile, ".stabs \"");
        !           192:   current_sym_nchars = 0;
        !           193: }
        !           194: 
        !           195: /* Output a reference to a type.  If the type has not yet been
        !           196:    described in the dbx output, output its definition now.
        !           197:    For a type already defined, just refer to its definition
        !           198:    using the type number.
        !           199: 
        !           200:    If FULL is nonzero, and the type has been described only with
        !           201:    a forward-reference, output the definition now.
        !           202:    If FULL is zero in this case, just refer to the forward-reference
        !           203:    using the number previously allocated.  */
        !           204: 
        !           205: static void
        !           206: dbxout_type (type, full)
        !           207:      tree type;
        !           208:      int full;
        !           209: {
        !           210:   register tree tem;
        !           211: 
        !           212:   if (TYPE_SYMTAB_ADDRESS (type) == 0)
        !           213:     {
        !           214:       /* Type has no dbx number assigned.  Assign next available number.  */
        !           215:       TYPE_SYMTAB_ADDRESS (type) = next_type_number++;
        !           216: 
        !           217:       /* Make sure type vector is long enough to record about this type.  */
        !           218: 
        !           219:       if (next_type_number == typevec_len)
        !           220:        {
        !           221:          typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]);
        !           222:          bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]);
        !           223:          typevec_len *= 2;
        !           224:        }
        !           225:     }
        !           226: 
        !           227:   /* Output the number of this type, to refer to it.  */
        !           228:   fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
        !           229:   CHARS (3);
        !           230: 
        !           231:   /* If this type's definition has been output or is now being output,
        !           232:      that is all.  */
        !           233: 
        !           234:   switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
        !           235:     {
        !           236:     case TYPE_UNSEEN:
        !           237:       break;
        !           238:     case TYPE_XREF:
        !           239:       if (! full)
        !           240:        return;
        !           241:       break;
        !           242:     case TYPE_DEFINED:
        !           243:       return;
        !           244:     }
        !           245: 
        !           246:   /* Output a definition now.  */
        !           247: 
        !           248:   fprintf (asmfile, "=");
        !           249:   CHARS (1);
        !           250: 
        !           251:   /* Mark it as defined, so that if it is self-referent
        !           252:      we will not get into an infinite recursion of definitions.  */
        !           253: 
        !           254:   typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
        !           255: 
        !           256:   switch (TREE_CODE (type))
        !           257:     {
        !           258:     case VOID_TYPE:
        !           259:       /* For a void type, just define it as itself; ie, "5=5".
        !           260:         This makes us consider it defined
        !           261:         without saying what it is.  The debugger will make it
        !           262:         a void type when the reference is seen, and nothing will
        !           263:         ever override that default.  */
        !           264:       fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
        !           265:       CHARS (3);
        !           266:       break;
        !           267: 
        !           268:     case INTEGER_TYPE:
        !           269:       if (type == char_type_node)
        !           270:        /* Output the type `char' as a subrange of itself!
        !           271:           I don't understand this definition, just copied it
        !           272:           from the output of pcc.  */
        !           273:        fprintf (asmfile, "r2;0;127;");
        !           274:       else
        !           275:        /* Output other integer types as subranges of `int'.  */
        !           276:        fprintf (asmfile, "r1;%d;%d;",
        !           277:                 TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)),
        !           278:                 TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
        !           279:       CHARS (25);
        !           280:       break;
        !           281: 
        !           282:     case REAL_TYPE:
        !           283:       /* This must be magic.  */
        !           284:       fprintf (asmfile, "r1;%d;0;",
        !           285:               TREE_INT_CST_LOW (size_in_bytes (type)));
        !           286:       CHARS (16);
        !           287:       break;
        !           288: 
        !           289:     case ARRAY_TYPE:
        !           290:       /* Output "a" followed by a range type definition
        !           291:         for the index type of the array
        !           292:         followed by a reference to the target-type.
        !           293:         ar1;0;N;M for an array of type M and size N.  */
        !           294:       fprintf (asmfile, "ar1;0;%d;",
        !           295:               TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
        !           296:       CHARS (17);
        !           297:       dbxout_type (TREE_TYPE (type), 0);
        !           298:       break;
        !           299: 
        !           300:     case RECORD_TYPE:
        !           301:     case UNION_TYPE:
        !           302:       /* Output a structure type.  */
        !           303:       if ((TYPE_NAME (type) != 0 && !full)
        !           304:          || TYPE_SIZE (type) == 0)
        !           305:        {
        !           306:          /* If the type is just a cross reference, output one
        !           307:             and mark the type as partially described.
        !           308:             If it later becomes defined, we will output
        !           309:             its real definition.  */
        !           310:          fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
        !           311:          CHARS (3);
        !           312:          dbxout_type_name (type);
        !           313:          fprintf (asmfile, ":");
        !           314:          typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
        !           315:          break;
        !           316:        }
        !           317:       tem = size_in_bytes (type);
        !           318:       fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
        !           319:               TREE_INT_CST_LOW (tem));
        !           320:       CHARS (11);
        !           321:       for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
        !           322:        /* Output the name, type, position (in bits), size (in bits)
        !           323:           of each field.  */
        !           324:        /* Omit here the nameless fields that are used to skip bits.  */
        !           325:        if (DECL_NAME (tem) != 0)
        !           326:          {
        !           327:            CONTIN;
        !           328:            fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
        !           329:            CHARS (1 + strlen (IDENTIFIER_POINTER (DECL_NAME (tem))));
        !           330:            dbxout_type (TREE_TYPE (tem), 0);
        !           331:            fprintf (asmfile, ",%d,%d;", DECL_OFFSET (tem),
        !           332:                     TREE_INT_CST_LOW (DECL_SIZE (tem)) * DECL_SIZE_UNIT (tem));
        !           333:            CHARS (23);
        !           334:          }
        !           335:       putc (';', asmfile);
        !           336:       CHARS (1);
        !           337:       break;
        !           338: 
        !           339:     case ENUMERAL_TYPE:
        !           340:       if ((TYPE_NAME (type) != 0 && !full)
        !           341:          || TYPE_SIZE (type) == 0)
        !           342:        {
        !           343:          fprintf (asmfile, "xe");
        !           344:          CHARS (3);
        !           345:          dbxout_type_name (type);
        !           346:          typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
        !           347:          fprintf (asmfile, ":");
        !           348:          return;
        !           349:        }
        !           350:       putc ('e', asmfile);
        !           351:       CHARS (1);
        !           352:       for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
        !           353:        {
        !           354:          fprintf (asmfile, "%s:%d,", IDENTIFIER_POINTER (TREE_PURPOSE (tem)),
        !           355:                   TREE_INT_CST_LOW (TREE_VALUE (tem)));
        !           356:          CHARS (11 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (tem))));
        !           357:          if (TREE_CHAIN (tem) != 0)
        !           358:            CONTIN;
        !           359:        }
        !           360:       putc (';', asmfile);
        !           361:       CHARS (1);
        !           362:       break;
        !           363: 
        !           364:     case POINTER_TYPE:
        !           365:       putc ('*', asmfile);
        !           366:       CHARS (1);
        !           367:       dbxout_type (TREE_TYPE (type), 0);
        !           368:       break;
        !           369: 
        !           370:     case FUNCTION_TYPE:
        !           371:       putc ('f', asmfile);
        !           372:       CHARS (1);
        !           373:       dbxout_type (TREE_TYPE (type), 0);
        !           374:       break;
        !           375:     }
        !           376: }
        !           377: 
        !           378: /* Output the name of type TYPE, with no punctuation.
        !           379:    Such names can be set up either by typedef declarations
        !           380:    or by struct, enum and union tags.  */
        !           381: 
        !           382: static void
        !           383: dbxout_type_name (type)
        !           384:      register tree type;
        !           385: {
        !           386:   register char *name;
        !           387:   if (TYPE_NAME (type) == 0)
        !           388:     abort ();
        !           389:   if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
        !           390:     name = IDENTIFIER_POINTER (TYPE_NAME (type));
        !           391:   else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
        !           392:     name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
        !           393:   else
        !           394:     abort ();
        !           395: 
        !           396:   fprintf (asmfile, "%s", name);
        !           397:   CHARS (strlen (name));
        !           398: }
        !           399: 
        !           400: /* Output a .stabs for the symbol defined by DECL,
        !           401:    which must be a ..._DECL node in the normal namespace.
        !           402:    It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
        !           403:    LOCAL is nonzero if the scope is less than the entire file.  */
        !           404: 
        !           405: void
        !           406: dbxout_symbol (decl, local)
        !           407:      tree decl;
        !           408:      int local;
        !           409: {
        !           410:   int symcode;
        !           411:   int letter;
        !           412: 
        !           413:   /* If global, first output all types and all
        !           414:      struct, enum and union tags that have been created
        !           415:      and not yet output.  */
        !           416: 
        !           417:   if (local == 0)
        !           418:     {
        !           419:       dbxout_tags (gettags ());
        !           420:       dbxout_types (get_permanent_types ());
        !           421:     }
        !           422: 
        !           423:   current_sym_code = 0;
        !           424:   current_sym_value = 0;
        !           425:   current_sym_addr = 0;
        !           426: 
        !           427:   /* The output will always start with the symbol name,
        !           428:      so count that always in the length-output-so-far.  */
        !           429: 
        !           430:   current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (decl)));
        !           431: 
        !           432:   switch (TREE_CODE (decl))
        !           433:     {
        !           434:     case CONST_DECL:
        !           435:       /* Enum values are defined by defining the enum type.  */
        !           436:       break;
        !           437: 
        !           438:     case FUNCTION_DECL:
        !           439:       if (TREE_EXTERNAL (decl))
        !           440:        break;
        !           441:       if (GET_CODE (DECL_RTL (decl)) != MEM
        !           442:          || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
        !           443:        break;
        !           444:       fprintf (asmfile, ".stabs \"%s:%c",
        !           445:               IDENTIFIER_POINTER (DECL_NAME (decl)),
        !           446:               TREE_PUBLIC (decl) ? 'F' : 'f');
        !           447: 
        !           448:       current_sym_code = N_FUN;
        !           449:       current_sym_addr = XEXP (DECL_RTL (decl), 0);
        !           450: 
        !           451:       if (TREE_TYPE (TREE_TYPE (decl)))
        !           452:        dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0);
        !           453:       else
        !           454:        dbxout_type (void_type_node, 0);
        !           455:       dbxout_finish_symbol ();
        !           456:       break;
        !           457: 
        !           458:     case TYPE_DECL:
        !           459:       /* Output typedef name.  */
        !           460:       fprintf (asmfile, ".stabs \"%s:t",
        !           461:               IDENTIFIER_POINTER (DECL_NAME (decl)));
        !           462: 
        !           463:       current_sym_code = N_LSYM;
        !           464: 
        !           465:       dbxout_type (TREE_TYPE (decl), 0);
        !           466:       dbxout_finish_symbol ();
        !           467:       break;
        !           468:       
        !           469:     case PARM_DECL:
        !           470:       /* Parm decls go in their own separate chains
        !           471:         and are output by dbxout_reg_parms and dbxout_parms.  */
        !           472:       abort ();
        !           473: 
        !           474:     case VAR_DECL:
        !           475:       /* Don't mention a variable that is external.
        !           476:         Let the file that defines it describe it.  */
        !           477:       if (TREE_EXTERNAL (decl))
        !           478:        break;
        !           479: 
        !           480:       /* Don't mention a variable at all
        !           481:         if it was completely optimized into nothingness.  */
        !           482:       if (GET_CODE (DECL_RTL (decl)) == REG
        !           483:          && REGNO (DECL_RTL (decl)) == -1)
        !           484:        break;
        !           485: 
        !           486:       /* Ok, start a symtab entry and output the variable name.  */
        !           487:       fprintf (asmfile, ".stabs \"%s:",
        !           488:               IDENTIFIER_POINTER (DECL_NAME (decl)));
        !           489:       
        !           490:       /* The kind-of-variable letter depends on where
        !           491:         the variable is and on the scope of its name:
        !           492:         G and N_GSYM for static storage and global scope,
        !           493:         S for static storage and file scope,
        !           494:         v for static storage and local scope,
        !           495:            for those two, use N_LCSYM if data is in bss segment,
        !           496:            N_STSYM if it is in data segment, or N_FUN if in text segment.
        !           497:         no letter at all, and N_LSYM, for auto variable,
        !           498:         r and N_RSYM for register variable.  */
        !           499: 
        !           500:       if (GET_CODE (DECL_RTL (decl)) == MEM
        !           501:          && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
        !           502:        {
        !           503:          if (TREE_PUBLIC (decl))
        !           504:            {
        !           505:              letter = 'G';
        !           506:              current_sym_code = N_GSYM;
        !           507:            }
        !           508:          else
        !           509:            {
        !           510:              current_sym_addr = XEXP (DECL_RTL (decl), 0);
        !           511: 
        !           512:              letter = TREE_PERMANENT (decl) ? 'S' : 'v';
        !           513: 
        !           514:              if (!DECL_INITIAL (decl))
        !           515:                current_sym_code = N_LCSYM;
        !           516:              else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
        !           517:                /* This is not quite right, but it's the closest
        !           518:                   of all the codes that Unix defines.  */
        !           519:                current_sym_code = N_FUN;
        !           520:              else
        !           521:                current_sym_code = N_STSYM;
        !           522:            }
        !           523:          putc (letter, asmfile);
        !           524:          dbxout_type (TREE_TYPE (decl), 0);
        !           525:          dbxout_finish_symbol ();
        !           526:        }
        !           527:       else
        !           528:        {
        !           529:          if (GET_CODE (DECL_RTL (decl)) == REG)
        !           530:            {
        !           531:              letter = 'r';
        !           532:              current_sym_code = N_RSYM;
        !           533:              current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));
        !           534:            }
        !           535:          else
        !           536:            {
        !           537:              letter = 0;
        !           538:              current_sym_code = N_LSYM;
        !           539:              /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
        !           540:                 We want the value of that CONST_INT.  */
        !           541:              current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));
        !           542:            }
        !           543:          if (letter) putc (letter, asmfile);
        !           544:          dbxout_type (TREE_TYPE (decl), 0);
        !           545:          dbxout_finish_symbol ();
        !           546:        }
        !           547:       break;
        !           548:     }
        !           549: }
        !           550: 
        !           551: static void
        !           552: dbxout_finish_symbol ()
        !           553: {
        !           554:   fprintf (asmfile, "\",%d,0,0,", current_sym_code);
        !           555:   if (current_sym_addr)
        !           556:     output_addr_const (asmfile, current_sym_addr);
        !           557:   else
        !           558:     fprintf (asmfile, "%d", current_sym_value);
        !           559:   putc ('\n', asmfile);
        !           560: }
        !           561: 
        !           562: /* Output definitions of all the decls in a chain.  */
        !           563: 
        !           564: static void
        !           565: dbxout_syms (syms)
        !           566:      tree syms;
        !           567: {
        !           568:   while (syms)
        !           569:     {
        !           570:       dbxout_symbol (syms, 1);
        !           571:       syms = TREE_CHAIN (syms);
        !           572:     }
        !           573: }
        !           574: 
        !           575: /* The following two functions output definitions of function parameters.
        !           576:    Each parameter gets a definition locating it in the parameter list.
        !           577:    Each parameter that is a register variable gets a second definition
        !           578:    locating it in the register.
        !           579: 
        !           580:    Printing or argument lists in gdb uses the definitions that
        !           581:    locate in the parameter list.  But reference to the variable in
        !           582:    expressions uses preferentially the definition as a register.  */
        !           583: 
        !           584: /* Output definitions, referring to storage in the parmlist,
        !           585:    of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */
        !           586: 
        !           587: static void
        !           588: dbxout_parms (parms)
        !           589:      tree parms;
        !           590: {
        !           591:   for (; parms; parms = TREE_CHAIN (parms))
        !           592:     {
        !           593:       current_sym_code = N_PSYM;
        !           594:       current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
        !           595:       /* A parm declared char is really passed as an int,
        !           596:         so it occupies the least significant bytes.
        !           597:         On a big-endian machine those are not the low-numbered ones.  */
        !           598: #ifdef BYTES_BIG_ENDIAN
        !           599:       current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
        !           600:                            - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
        !           601: #endif
        !           602:       current_sym_addr = 0;
        !           603:       current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
        !           604: 
        !           605:       fprintf (asmfile, ".stabs \"%s:p",
        !           606:               IDENTIFIER_POINTER (DECL_NAME (parms)));
        !           607:       dbxout_type (TREE_TYPE (parms), 0);
        !           608:       dbxout_finish_symbol ();
        !           609:     }
        !           610: }
        !           611: 
        !           612: /* Output definitions, referring to registers,
        !           613:    of all the parms in PARMS which are stored in registers during the function.
        !           614:    PARMS is a chain of PARM_DECL nodes.  */
        !           615: 
        !           616: static void
        !           617: dbxout_reg_parms (parms)
        !           618:      tree parms;
        !           619: {
        !           620:   while (parms)
        !           621:     {
        !           622:       if (GET_CODE (DECL_RTL (parms)) == REG
        !           623:          && REGNO (DECL_RTL (parms)) >= 0)
        !           624:        {
        !           625:          current_sym_code = N_RSYM;
        !           626:          current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
        !           627:          current_sym_addr = 0;
        !           628:          current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
        !           629:          fprintf (asmfile, ".stabs \"%s:r",
        !           630:                   IDENTIFIER_POINTER (DECL_NAME (parms)));
        !           631:          dbxout_type (TREE_TYPE (parms), 0);
        !           632:          dbxout_finish_symbol ();
        !           633:        }
        !           634:       parms = TREE_CHAIN (parms);
        !           635:     }
        !           636: }
        !           637: 
        !           638: /* Given a chain of ..._TYPE nodes, all of which have names,
        !           639:    output definitions of those names, as typedefs.  */
        !           640: 
        !           641: void
        !           642: dbxout_types (types)
        !           643:      register tree types;
        !           644: {
        !           645:   while (types)
        !           646:     {
        !           647:       if (TYPE_NAME (types)
        !           648:          && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL)
        !           649:        dbxout_type_def (types);
        !           650:       types = TREE_CHAIN (types);
        !           651:     }
        !           652: }
        !           653: 
        !           654: /* Output a definition of a typedef name.
        !           655:    It works much like any other kind of symbol definition.  */
        !           656: 
        !           657: static void
        !           658: dbxout_type_def (type)
        !           659:      tree type;
        !           660: {
        !           661:   current_sym_code = N_LSYM;
        !           662:   current_sym_value = 0;
        !           663:   current_sym_addr = 0;
        !           664:   current_sym_nchars = 0;
        !           665:   current_sym_nchars
        !           666:     = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
        !           667: 
        !           668:   fprintf (asmfile, ".stabs \"%s:t",
        !           669:           IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
        !           670:   dbxout_type (type, 1);
        !           671:   dbxout_finish_symbol ();
        !           672: }
        !           673: 
        !           674: /* Output the tags (struct, union and enum definitions with names) for a block,
        !           675:    given a list of them (a chain of TREE_LIST nodes) in TAGS.
        !           676:    We must check to include those that have been mentioned already with
        !           677:    only a cross-reference.  */
        !           678: 
        !           679: void
        !           680: dbxout_tags (tags)
        !           681:      tree tags;
        !           682: {
        !           683:   register tree link;
        !           684:   for (link = tags; link; link = TREE_CHAIN (link))
        !           685:     {
        !           686:       register tree type = TREE_VALUE (link);
        !           687:       if (TREE_PURPOSE (link) != 0
        !           688:          && (TYPE_SYMTAB_ADDRESS (type) == 0
        !           689:              || (typevec[TYPE_SYMTAB_ADDRESS (type)] != TYPE_DEFINED))
        !           690:          && TYPE_SIZE (type) != 0)
        !           691:        {
        !           692:          current_sym_code = N_LSYM;
        !           693:          current_sym_value = 0;
        !           694:          current_sym_addr = 0;
        !           695:          current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (link)));
        !           696: 
        !           697:          fprintf (asmfile, ".stabs \"%s:T",
        !           698:                   IDENTIFIER_POINTER (TREE_PURPOSE (link)));
        !           699:          dbxout_type (type, 1);
        !           700:          dbxout_finish_symbol ();
        !           701:          typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
        !           702:        }
        !           703:     }
        !           704: }
        !           705: 
        !           706: /* Output everything about a symbol block (that is to say, a LET_STMT node
        !           707:    that represents a scope level),
        !           708:    including recursive output of contained blocks.
        !           709: 
        !           710:    STMT is the LET_STMT node.
        !           711:    DEPTH is its depth within containing symbol blocks.
        !           712:    ARGS is usually zero; but for the outermost block of the
        !           713:    body of a function, it is a chain of PARM_DECLs for the function parameters.
        !           714:    We output definitions of all the register parms
        !           715:    as if they were local variables of that block.
        !           716: 
        !           717:    Actually, STMT may be several statements chained together.
        !           718:    We handle them all in sequence.  */
        !           719: 
        !           720: static void
        !           721: dbxout_block (stmt, depth, args)
        !           722:      register tree stmt;
        !           723:      int depth;
        !           724: {
        !           725:   int blocknum;
        !           726: 
        !           727:   while (stmt)
        !           728:     {
        !           729:       switch (TREE_CODE (stmt))
        !           730:        {
        !           731:        case COMPOUND_STMT:
        !           732:        case LOOP_STMT:
        !           733:          dbxout_block (STMT_BODY (stmt), depth, 0);
        !           734:          break;
        !           735: 
        !           736:        case IF_STMT:
        !           737:          dbxout_block (STMT_THEN (stmt), depth, 0);
        !           738:          dbxout_block (STMT_ELSE (stmt), depth, 0);
        !           739:          break;
        !           740: 
        !           741:        case LET_STMT:
        !           742:          /* In dbx format, the syms of a block come before the N_LBRAC.  */
        !           743:          dbxout_tags (STMT_TYPE_TAGS (stmt));
        !           744:          dbxout_syms (STMT_VARS (stmt), 1);
        !           745:          if (args)
        !           746:            dbxout_reg_parms (args);
        !           747: 
        !           748:          /* Now output an N_LBRAC symbol to represent the beginning of
        !           749:             the block.  Use the block's tree-walk order to generate
        !           750:             the assembler symbols LBBn and LBEn
        !           751:             that final will define around the code in this block.  */
        !           752:          if (depth > 0)
        !           753:            {
        !           754:              blocknum = next_block_number++;
        !           755:              fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum);
        !           756:            }
        !           757: 
        !           758:          /* Output the interior of the block.  */
        !           759:          dbxout_block (STMT_BODY (stmt), depth + 1, 0);
        !           760: 
        !           761:          /* Refer to the marker for the end of the block.  */
        !           762:          if (depth > 0)
        !           763:            fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum);
        !           764:        }
        !           765:       stmt = TREE_CHAIN (stmt);
        !           766:     }
        !           767: }
        !           768: 
        !           769: /* Output dbx data for a function definition.
        !           770:    This includes a definition of the function name itself (a symbol),
        !           771:    definitions of the parameters (locating them in the parameter list)
        !           772:    and then output the block that makes up the function's body
        !           773:    (including all the auto variables of the function).  */
        !           774: 
        !           775: void
        !           776: dbxout_function (decl)
        !           777:      tree decl;
        !           778: {
        !           779:   dbxout_symbol (decl, 0);
        !           780:   dbxout_parms (DECL_ARGUMENTS (decl));
        !           781:   dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
        !           782: }

unix.superglobalmegacorp.com

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