OSDN Git Service

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