OSDN Git Service

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