OSDN Git Service

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