OSDN Git Service

Cast pointer operands to bzero, bcopy, and bcmp to (char *).
[pf3gnuchains/gcc-fork.git] / gcc / dbxout.c
1 /* Output dbx-format symbol table information from GNU compiler.
2    Copyright (C) 1987, 1988, 1992, 1993, 1994 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 ((char *) 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           && TYPE_DECL_SUPPRESS_DEBUG (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           int len = typevec_len * 2 * sizeof typevec[0];
944
945           typevec = (enum typestatus *) xrealloc (typevec, len);
946           bzero ((char *) (typevec + typevec_len), len);
947           typevec_len *= 2;
948         }
949     }
950
951   /* Output the number of this type, to refer to it.  */
952   fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
953   CHARS (3);
954
955 #ifdef DBX_TYPE_DEFINED
956   if (DBX_TYPE_DEFINED (type))
957     return;
958 #endif
959
960   /* If this type's definition has been output or is now being output,
961      that is all.  */
962
963   switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
964     {
965     case TYPE_UNSEEN:
966       break;
967     case TYPE_XREF:
968       /* If we have already had a cross reference,
969          and either that's all we want or that's the best we could do,
970          don't repeat the cross reference.
971          Sun dbx crashes if we do.  */
972       if (! full || TYPE_SIZE (type) == 0
973           /* No way in DBX fmt to describe a variable size.  */
974           || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
975         return;
976       break;
977     case TYPE_DEFINED:
978       return;
979     }
980
981 #ifdef DBX_NO_XREFS
982   /* For systems where dbx output does not allow the `=xsNAME:' syntax,
983      leave the type-number completely undefined rather than output
984      a cross-reference.  If we have already used GNU debug info extensions,
985      then it is OK to output a cross reference.  This is necessary to get
986      proper C++ debug output.  */
987   if ((TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
988        || TREE_CODE (type) == QUAL_UNION_TYPE
989        || TREE_CODE (type) == ENUMERAL_TYPE)
990       && ! use_gnu_debug_info_extensions)
991     /* We must use the same test here as we use twice below when deciding
992        whether to emit a cross-reference.  */
993     if ((TYPE_NAME (type) != 0
994          && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
995                && DECL_IGNORED_P (TYPE_NAME (type)))
996          && !full)
997         || TYPE_SIZE (type) == 0
998         /* No way in DBX fmt to describe a variable size.  */
999         || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
1000       {
1001         typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
1002         return;
1003       }
1004 #endif
1005
1006   /* Output a definition now.  */
1007
1008   fprintf (asmfile, "=");
1009   CHARS (1);
1010
1011   /* Mark it as defined, so that if it is self-referent
1012      we will not get into an infinite recursion of definitions.  */
1013
1014   typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
1015
1016   switch (TREE_CODE (type))
1017     {
1018     case VOID_TYPE:
1019     case LANG_TYPE:
1020       /* For a void type, just define it as itself; ie, "5=5".
1021          This makes us consider it defined
1022          without saying what it is.  The debugger will make it
1023          a void type when the reference is seen, and nothing will
1024          ever override that default.  */
1025       fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
1026       CHARS (3);
1027       break;
1028
1029     case INTEGER_TYPE:
1030       if (type == char_type_node && ! TREE_UNSIGNED (type))
1031         /* Output the type `char' as a subrange of itself!
1032            I don't understand this definition, just copied it
1033            from the output of pcc.
1034            This used to use `r2' explicitly and we used to
1035            take care to make sure that `char' was type number 2.  */
1036         fprintf (asmfile, "r%d;0;127;", TYPE_SYMTAB_ADDRESS (type));
1037       else if (use_gnu_debug_info_extensions
1038                && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
1039                    || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT))
1040         {
1041           /* This used to say `r1' and we used to take care
1042              to make sure that `int' was type number 1.  */
1043           fprintf (asmfile, "r%d;", TYPE_SYMTAB_ADDRESS (integer_type_node));
1044           print_int_cst_octal (TYPE_MIN_VALUE (type));
1045           fprintf (asmfile, ";");
1046           print_int_cst_octal (TYPE_MAX_VALUE (type));
1047           fprintf (asmfile, ";");
1048         }
1049       else /* Output other integer types as subranges of `int'.  */
1050         dbxout_range_type (type);
1051       CHARS (25);
1052       break;
1053
1054     case REAL_TYPE:
1055       /* This used to say `r1' and we used to take care
1056          to make sure that `int' was type number 1.  */
1057       fprintf (asmfile, "r%d;%d;0;", TYPE_SYMTAB_ADDRESS (integer_type_node),
1058                int_size_in_bytes (type));
1059       CHARS (16);
1060       break;
1061
1062     case CHAR_TYPE:
1063       if (use_gnu_debug_info_extensions)
1064         fprintf (asmfile, "@s%d;-20;",
1065                  BITS_PER_UNIT * int_size_in_bytes (type));
1066       else
1067         /* Output the type `char' as a subrange of itself.
1068            That is what pcc seems to do.  */
1069       fprintf (asmfile, "r%d;0;%d;", TYPE_SYMTAB_ADDRESS (char_type_node),
1070                TREE_UNSIGNED (type) ? 255 : 127);
1071       CHARS (9);
1072       break;
1073
1074     case BOOLEAN_TYPE:
1075       if (use_gnu_debug_info_extensions)
1076         fprintf (asmfile, "@s%d;-16;",
1077                  BITS_PER_UNIT * int_size_in_bytes (type));
1078       else /* Define as enumeral type (False, True) */
1079         fprintf (asmfile, "eFalse:0,True:1,;");
1080       CHARS (17);
1081       break;
1082
1083     case FILE_TYPE:
1084       putc ('d', asmfile);
1085       CHARS (1);
1086       dbxout_type (TREE_TYPE (type), 0, 0);
1087       break;
1088
1089     case COMPLEX_TYPE:
1090       /* Differs from the REAL_TYPE by its new data type number */
1091
1092       if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
1093         {
1094           fprintf (asmfile, "r%d;%d;0;",
1095                    TYPE_SYMTAB_ADDRESS (type),
1096                    int_size_in_bytes (TREE_TYPE (type)));
1097           CHARS (15);           /* The number is probably incorrect here.  */
1098         }
1099       else
1100         {
1101           /* Output a complex integer type as a structure,
1102              pending some other way to do it.  */
1103           fprintf (asmfile, "s%d", int_size_in_bytes (type));
1104
1105           fprintf (asmfile, "real:");
1106           CHARS (10);
1107           dbxout_type (TREE_TYPE (type), 0, 0);
1108           fprintf (asmfile, ",%d,%d;",
1109                    0, TYPE_PRECISION (TREE_TYPE (type)));
1110           CHARS (8);
1111           fprintf (asmfile, "imag:");
1112           CHARS (5);
1113           dbxout_type (TREE_TYPE (type), 0, 0);
1114           fprintf (asmfile, ",%d,%d;;",
1115                    TYPE_PRECISION (TREE_TYPE (type)),
1116                    TYPE_PRECISION (TREE_TYPE (type)));
1117           CHARS (9);
1118         }
1119       break;
1120
1121     case SET_TYPE:
1122       if (use_gnu_debug_info_extensions)
1123         {
1124           have_used_extensions = 1;
1125           fprintf (asmfile, "@s%d;",
1126                    BITS_PER_UNIT * int_size_in_bytes (type));
1127           /* Check if a bitstring type, which in Chill is
1128              different from a [power]set. */
1129           if (TYPE_STRING_FLAG (type))
1130             fprintf (asmfile, "@S;");
1131         }
1132       putc ('S', asmfile);
1133       CHARS (1);
1134       dbxout_type (TYPE_DOMAIN (type), 0, 0);
1135       break;
1136
1137     case ARRAY_TYPE:
1138       /* Output "a" followed by a range type definition
1139          for the index type of the array
1140          followed by a reference to the target-type.
1141          ar1;0;N;M for a C array of type M and size N+1.  */
1142       /* Check if a character string type, which in Chill is
1143          different from an array of characters. */
1144       if (TYPE_STRING_FLAG (type) && use_gnu_debug_info_extensions)
1145         {
1146           have_used_extensions = 1;
1147           fprintf (asmfile, "@S;");
1148         }
1149       tem = TYPE_DOMAIN (type);
1150       if (tem == NULL)
1151         fprintf (asmfile, "ar%d;0;-1;",
1152                  TYPE_SYMTAB_ADDRESS (integer_type_node));
1153       else
1154         {
1155           fprintf (asmfile, "a");
1156           dbxout_range_type (tem);
1157         }
1158       CHARS (17);
1159       dbxout_type (TREE_TYPE (type), 0, 0);
1160       break;
1161
1162     case RECORD_TYPE:
1163     case UNION_TYPE:
1164     case QUAL_UNION_TYPE:
1165       {
1166         int i, n_baseclasses = 0;
1167
1168         if (TYPE_BINFO (type) != 0 && TYPE_BINFO_BASETYPES (type) != 0)
1169           n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
1170
1171         /* Output a structure type.  We must use the same test here as we
1172            use in the DBX_NO_XREFS case above.  */
1173         if ((TYPE_NAME (type) != 0
1174              && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1175                    && DECL_IGNORED_P (TYPE_NAME (type)))
1176              && !full)
1177             || TYPE_SIZE (type) == 0
1178             /* No way in DBX fmt to describe a variable size.  */
1179             || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
1180           {
1181             /* If the type is just a cross reference, output one
1182                and mark the type as partially described.
1183                If it later becomes defined, we will output
1184                its real definition.
1185                If the type has a name, don't nest its definition within
1186                another type's definition; instead, output an xref
1187                and let the definition come when the name is defined.  */
1188             fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
1189             CHARS (3);
1190 #if 0 /* This assertion is legitimately false in C++.  */
1191             /* We shouldn't be outputting a reference to a type before its
1192                definition unless the type has a tag name.
1193                A typedef name without a tag name should be impossible.  */
1194             if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE)
1195               abort ();
1196 #endif
1197             if (TYPE_NAME (type) != 0)
1198               dbxout_type_name (type);
1199             else
1200               fprintf (asmfile, "$$%d", anonymous_type_number++);
1201             fprintf (asmfile, ":");
1202             typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
1203             break;
1204           }
1205
1206         /* Identify record or union, and print its size.  */
1207         fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
1208                  int_size_in_bytes (type));
1209
1210         if (use_gnu_debug_info_extensions)
1211           {
1212             if (n_baseclasses)
1213               {
1214                 have_used_extensions = 1;
1215                 fprintf (asmfile, "!%d,", n_baseclasses);
1216                 CHARS (8);
1217               }
1218           }
1219         for (i = 0; i < n_baseclasses; i++)
1220           {
1221             tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
1222             if (use_gnu_debug_info_extensions)
1223               {
1224                 have_used_extensions = 1;
1225                 putc (TREE_VIA_VIRTUAL (child) ? '1'
1226                       : '0',
1227                       asmfile);
1228                 putc (TREE_VIA_PUBLIC (child) ? '2'
1229                       : '0',
1230                       asmfile);
1231                 fprintf (asmfile, "%d,",
1232                          TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);
1233                 CHARS (15);
1234                 dbxout_type (BINFO_TYPE (child), 0, 0);
1235                 putc (';', asmfile);
1236               }
1237             else
1238               {
1239                 /* Print out the base class information with fields
1240                    which have the same names at the types they hold.  */
1241                 dbxout_type_name (BINFO_TYPE (child));
1242                 putc (':', asmfile);
1243                 dbxout_type (BINFO_TYPE (child), full, 0);
1244                 fprintf (asmfile, ",%d,%d;",
1245                          TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT,
1246                          TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT);
1247                 CHARS (20);
1248               }
1249           }
1250       }
1251
1252       CHARS (11);
1253
1254       /* Write out the field declarations.  */
1255       dbxout_type_fields (type);
1256       if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE)
1257         {
1258           have_used_extensions = 1;
1259           dbxout_type_methods (type);
1260         }
1261       putc (';', asmfile);
1262
1263       if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE
1264           /* Avoid the ~ if we don't really need it--it confuses dbx.  */
1265           && TYPE_VFIELD (type))
1266         {
1267           have_used_extensions = 1;
1268
1269           /* Tell GDB+ that it may keep reading.  */
1270           putc ('~', asmfile);
1271
1272           /* We need to write out info about what field this class
1273              uses as its "main" vtable pointer field, because if this
1274              field is inherited from a base class, GDB cannot necessarily
1275              figure out which field it's using in time.  */
1276           if (TYPE_VFIELD (type))
1277             {
1278               putc ('%', asmfile);
1279               dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0);
1280             }
1281           putc (';', asmfile);
1282           CHARS (3);
1283         }
1284       break;
1285
1286     case ENUMERAL_TYPE:
1287       /* We must use the same test here as we use in the DBX_NO_XREFS case
1288          above.  We simplify it a bit since an enum will never have a variable
1289          size.  */
1290       if ((TYPE_NAME (type) != 0
1291            && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1292                  && DECL_IGNORED_P (TYPE_NAME (type)))
1293            && !full)
1294           || TYPE_SIZE (type) == 0)
1295         {
1296           fprintf (asmfile, "xe");
1297           CHARS (3);
1298           dbxout_type_name (type);
1299           typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
1300           fprintf (asmfile, ":");
1301           return;
1302         }
1303 #ifdef DBX_OUTPUT_ENUM
1304       DBX_OUTPUT_ENUM (asmfile, type);
1305 #else
1306       if (use_gnu_debug_info_extensions
1307           && TYPE_PRECISION (type) != TYPE_PRECISION (integer_type_node))
1308         fprintf (asmfile, "@s%d;", TYPE_PRECISION (type));
1309       putc ('e', asmfile);
1310       CHARS (1);
1311       for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
1312         {
1313           fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
1314           if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0)
1315             fprintf (asmfile, "%lu",
1316                      (unsigned long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
1317           else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1
1318                    && TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0)
1319             fprintf (asmfile, "%ld",
1320                      (long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
1321           else
1322             print_int_cst_octal (TREE_VALUE (tem));
1323           fprintf (asmfile, ",");
1324           CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));
1325           if (TREE_CHAIN (tem) != 0)
1326             CONTIN;
1327         }
1328       putc (';', asmfile);
1329       CHARS (1);
1330 #endif
1331       break;
1332
1333     case POINTER_TYPE:
1334       putc ('*', asmfile);
1335       CHARS (1);
1336       dbxout_type (TREE_TYPE (type), 0, 0);
1337       break;
1338
1339     case METHOD_TYPE:
1340       if (use_gnu_debug_info_extensions)
1341         {
1342           have_used_extensions = 1;
1343           putc ('#', asmfile);
1344           CHARS (1);
1345           if (flag_minimal_debug && !show_arg_types)
1346             {
1347               /* Normally, just output the return type.
1348                  The argument types are encoded in the method name.  */
1349               putc ('#', asmfile);
1350               dbxout_type (TREE_TYPE (type), 0, 0);
1351               putc (';', asmfile);
1352               CHARS (1);
1353             }
1354           else
1355             {
1356               /* When outputting destructors, we need to write
1357                  the argument types out longhand.  */
1358               dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0);
1359               putc (',', asmfile);
1360               CHARS (1);
1361               dbxout_type (TREE_TYPE (type), 0, 0);
1362               dbxout_args (TYPE_ARG_TYPES (type));
1363               putc (';', asmfile);
1364               CHARS (1);
1365             }
1366         }
1367       else
1368         {
1369           /* Treat it as a function type.  */
1370           dbxout_type (TREE_TYPE (type), 0, 0);
1371         }
1372       break;
1373
1374     case OFFSET_TYPE:
1375       if (use_gnu_debug_info_extensions)
1376         {
1377           have_used_extensions = 1;
1378           putc ('@', asmfile);
1379           CHARS (1);
1380           dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0);
1381           putc (',', asmfile);
1382           CHARS (1);
1383           dbxout_type (TREE_TYPE (type), 0, 0);
1384         }
1385       else
1386         {
1387           /* Should print as an int, because it is really
1388              just an offset.  */
1389           dbxout_type (integer_type_node, 0, 0);
1390         }
1391       break;
1392
1393     case REFERENCE_TYPE:
1394       if (use_gnu_debug_info_extensions)
1395         have_used_extensions = 1;
1396       putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile);
1397       CHARS (1);
1398       dbxout_type (TREE_TYPE (type), 0, 0);
1399       break;
1400
1401     case FUNCTION_TYPE:
1402       putc ('f', asmfile);
1403       CHARS (1);
1404       dbxout_type (TREE_TYPE (type), 0, 0);
1405       break;
1406
1407     default:
1408       abort ();
1409     }
1410 }
1411
1412 /* Print the value of integer constant C, in octal,
1413    handling double precision.  */
1414
1415 static void
1416 print_int_cst_octal (c)
1417      tree c;
1418 {
1419   unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (c);
1420   unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (c);
1421   int excess = (3 - (HOST_BITS_PER_WIDE_INT % 3));
1422   int width = TYPE_PRECISION (TREE_TYPE (c));
1423
1424   /* GDB wants constants with no extra leading "1" bits, so
1425      we need to remove any sign-extension that might be
1426      present.  */
1427   if (width == HOST_BITS_PER_WIDE_INT * 2)
1428     ;
1429   else if (width > HOST_BITS_PER_WIDE_INT)
1430     high &= (((HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT)) - 1);
1431   else if (width == HOST_BITS_PER_WIDE_INT)
1432     high = 0;
1433   else
1434     high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1);
1435
1436   fprintf (asmfile, "0");
1437
1438   if (excess == 3)
1439     {
1440       print_octal (high, HOST_BITS_PER_WIDE_INT / 3);
1441       print_octal (low, HOST_BITS_PER_WIDE_INT / 3);
1442     }
1443   else
1444     {
1445       unsigned HOST_WIDE_INT beg = high >> excess;
1446       unsigned HOST_WIDE_INT middle
1447         = ((high & (((HOST_WIDE_INT) 1 << excess) - 1)) << (3 - excess)
1448            | (low >> (HOST_BITS_PER_WIDE_INT / 3 * 3)));
1449       unsigned HOST_WIDE_INT end
1450         = low & (((unsigned HOST_WIDE_INT) 1
1451                   << (HOST_BITS_PER_WIDE_INT / 3 * 3))
1452                  - 1);
1453
1454       fprintf (asmfile, "%o%01o", beg, middle);
1455       print_octal (end, HOST_BITS_PER_WIDE_INT / 3);
1456     }
1457 }
1458
1459 static void
1460 print_octal (value, digits)
1461      unsigned HOST_WIDE_INT value;
1462      int digits;
1463 {
1464   int i;
1465
1466   for (i = digits - 1; i >= 0; i--)
1467     fprintf (asmfile, "%01o", ((value >> (3 * i)) & 7));
1468 }
1469
1470 /* Output the name of type TYPE, with no punctuation.
1471    Such names can be set up either by typedef declarations
1472    or by struct, enum and union tags.  */
1473
1474 static void
1475 dbxout_type_name (type)
1476      register tree type;
1477 {
1478   tree t;
1479   if (TYPE_NAME (type) == 0)
1480     abort ();
1481   if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
1482     {
1483       t = TYPE_NAME (type);
1484     }
1485   else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
1486     {
1487       t = DECL_NAME (TYPE_NAME (type));
1488     }
1489   else
1490     abort ();
1491
1492   fprintf (asmfile, "%s", IDENTIFIER_POINTER (t));
1493   CHARS (IDENTIFIER_LENGTH (t));
1494 }
1495 \f
1496 /* Output a .stabs for the symbol defined by DECL,
1497    which must be a ..._DECL node in the normal namespace.
1498    It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
1499    LOCAL is nonzero if the scope is less than the entire file.  */
1500
1501 void
1502 dbxout_symbol (decl, local)
1503      tree decl;
1504      int local;
1505 {
1506   tree type = TREE_TYPE (decl);
1507   tree context = NULL_TREE;
1508
1509   /* Cast avoids warning in old compilers.  */
1510   current_sym_code = (STAB_CODE_TYPE) 0;
1511   current_sym_value = 0;
1512   current_sym_addr = 0;
1513
1514   /* Ignore nameless syms, but don't ignore type tags.  */
1515
1516   if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL)
1517       || DECL_IGNORED_P (decl))
1518     return;
1519
1520   dbxout_prepare_symbol (decl);
1521
1522   /* The output will always start with the symbol name,
1523      so always count that in the length-output-so-far.  */
1524
1525   if (DECL_NAME (decl) != 0)
1526     current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl));
1527
1528   switch (TREE_CODE (decl))
1529     {
1530     case CONST_DECL:
1531       /* Enum values are defined by defining the enum type.  */
1532       break;
1533
1534     case FUNCTION_DECL:
1535       if (DECL_RTL (decl) == 0)
1536         return;
1537       if (DECL_EXTERNAL (decl))
1538         break;
1539       /* Don't mention a nested function under its parent.  */
1540       context = decl_function_context (decl);
1541       if (context == current_function_decl)
1542         break;
1543       if (GET_CODE (DECL_RTL (decl)) != MEM
1544           || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
1545         break;
1546       FORCE_TEXT;
1547
1548       fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
1549                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
1550                TREE_PUBLIC (decl) ? 'F' : 'f');
1551
1552       current_sym_code = N_FUN;
1553       current_sym_addr = XEXP (DECL_RTL (decl), 0);
1554
1555       if (TREE_TYPE (type))
1556         dbxout_type (TREE_TYPE (type), 0, 0);
1557       else
1558         dbxout_type (void_type_node, 0, 0);
1559
1560       /* For a nested function, when that function is compiled,
1561          mention the containing function name
1562          as well as (since dbx wants it) our own assembler-name.  */
1563       if (context != 0)
1564         fprintf (asmfile, ",%s,%s",
1565                  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
1566                  IDENTIFIER_POINTER (DECL_NAME (context)));
1567
1568       dbxout_finish_symbol (decl);
1569       break;
1570
1571     case TYPE_DECL:
1572 #if 0
1573       /* This seems all wrong.  Outputting most kinds of types gives no name
1574          at all.  A true definition gives no name; a cross-ref for a
1575          structure can give the tag name, but not a type name.
1576          It seems that no typedef name is defined by outputting a type.  */
1577
1578       /* If this typedef name was defined by outputting the type,
1579          don't duplicate it.  */
1580       if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED
1581           && TYPE_NAME (TREE_TYPE (decl)) == decl)
1582         return;
1583 #endif
1584       /* Don't output the same typedef twice.
1585          And don't output what language-specific stuff doesn't want output.  */
1586       if (TREE_ASM_WRITTEN (decl) || DECL_IGNORED_P (decl))
1587         return;
1588
1589       FORCE_TEXT;
1590
1591       {
1592         int tag_needed = 1;
1593         int did_output = 0;
1594
1595         if (DECL_NAME (decl))
1596           {
1597             /* Nonzero means we must output a tag as well as a typedef.  */
1598             tag_needed = 0;
1599
1600             /* Handle the case of a C++ structure or union
1601                where the TYPE_NAME is a TYPE_DECL
1602                which gives both a typedef name and a tag.  */
1603             /* dbx requires the tag first and the typedef second.  */
1604             if ((TREE_CODE (type) == RECORD_TYPE
1605                  || TREE_CODE (type) == UNION_TYPE
1606                  || TREE_CODE (type) == QUAL_UNION_TYPE)
1607                 && TYPE_NAME (type) == decl
1608                 && !(use_gnu_debug_info_extensions && have_used_extensions)
1609                 && !TREE_ASM_WRITTEN (TYPE_NAME (type))
1610                 /* Distinguish the implicit typedefs of C++
1611                    from explicit ones that might be found in C.  */
1612                 && (!strcmp (lang_identify (), "cplusplus") 
1613                     /* The following line maybe unnecessary;
1614                        in 2.6, try removing it.  */
1615                     || DECL_SOURCE_LINE (decl) == 0))
1616               {
1617                 tree name = TYPE_NAME (type);
1618                 if (TREE_CODE (name) == TYPE_DECL)
1619                   name = DECL_NAME (name);
1620
1621                 current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1622                 current_sym_value = 0;
1623                 current_sym_addr = 0;
1624                 current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);
1625
1626                 fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,
1627                          IDENTIFIER_POINTER (name));
1628                 dbxout_type (type, 1, 0);
1629                 dbxout_finish_symbol (NULL_TREE);
1630               }
1631
1632             /* Output typedef name.  */
1633             fprintf (asmfile, "%s \"%s:", ASM_STABS_OP,
1634                      IDENTIFIER_POINTER (DECL_NAME (decl)));
1635
1636             /* Short cut way to output a tag also.  */
1637             if ((TREE_CODE (type) == RECORD_TYPE
1638                  || TREE_CODE (type) == UNION_TYPE
1639                  || TREE_CODE (type) == QUAL_UNION_TYPE)
1640                 && TYPE_NAME (type) == decl)
1641               {
1642                 if (use_gnu_debug_info_extensions && have_used_extensions)
1643                   {
1644                     putc ('T', asmfile);
1645                     TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;
1646                   }
1647 #if 0 /* Now we generate the tag for this case up above.  */
1648                 else
1649                   tag_needed = 1;
1650 #endif
1651               }
1652
1653             putc ('t', asmfile);
1654             current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1655
1656             dbxout_type (type, 1, 0);
1657             dbxout_finish_symbol (decl);
1658             did_output = 1;
1659           }
1660
1661         /* Don't output a tag if this is an incomplete type (TYPE_SIZE is
1662            zero).  This prevents the sun4 Sun OS 4.x dbx from crashing.  */ 
1663
1664         if (tag_needed && TYPE_NAME (type) != 0 && TYPE_SIZE (type) != 0
1665             && !TREE_ASM_WRITTEN (TYPE_NAME (type)))
1666           {
1667             /* For a TYPE_DECL with no name, but the type has a name,
1668                output a tag.
1669                This is what represents `struct foo' with no typedef.  */
1670             /* In C++, the name of a type is the corresponding typedef.
1671                In C, it is an IDENTIFIER_NODE.  */
1672             tree name = TYPE_NAME (type);
1673             if (TREE_CODE (name) == TYPE_DECL)
1674               name = DECL_NAME (name);
1675
1676             current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1677             current_sym_value = 0;
1678             current_sym_addr = 0;
1679             current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);
1680
1681             fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,
1682                      IDENTIFIER_POINTER (name));
1683             dbxout_type (type, 1, 0);
1684             dbxout_finish_symbol (NULL_TREE);
1685             did_output = 1;
1686           }
1687
1688         /* If an enum type has no name, it cannot be referred to,
1689            but we must output it anyway, since the enumeration constants
1690            can be referred to.  */
1691         if (!did_output && TREE_CODE (type) == ENUMERAL_TYPE)
1692           {
1693             current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1694             current_sym_value = 0;
1695             current_sym_addr = 0;
1696             current_sym_nchars = 2;
1697
1698             /* Some debuggers fail when given NULL names, so give this a
1699                harmless name of ` '.  */
1700             fprintf (asmfile, "%s \" :T", ASM_STABS_OP);
1701             dbxout_type (type, 1, 0);
1702             dbxout_finish_symbol (NULL_TREE);
1703           }
1704
1705         /* Prevent duplicate output of a typedef.  */
1706         TREE_ASM_WRITTEN (decl) = 1;
1707         break;
1708       }
1709
1710     case PARM_DECL:
1711       /* Parm decls go in their own separate chains
1712          and are output by dbxout_reg_parms and dbxout_parms.  */
1713       abort ();
1714
1715     case RESULT_DECL:
1716       /* Named return value, treat like a VAR_DECL.  */
1717     case VAR_DECL:
1718       if (DECL_RTL (decl) == 0)
1719         return;
1720       /* Don't mention a variable that is external.
1721          Let the file that defines it describe it.  */
1722       if (DECL_EXTERNAL (decl))
1723         break;
1724
1725       /* If the variable is really a constant
1726          and not written in memory, inform the debugger.  */
1727       if (TREE_STATIC (decl) && TREE_READONLY (decl)
1728           && DECL_INITIAL (decl) != 0
1729           && ! TREE_ASM_WRITTEN (decl)
1730           && (DECL_FIELD_CONTEXT (decl) == NULL_TREE
1731               || TREE_CODE (DECL_FIELD_CONTEXT (decl)) == BLOCK))
1732         {
1733           if (TREE_PUBLIC (decl) == 0)
1734             {
1735               /* The sun4 assembler does not grok this.  */
1736               char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1737               if (TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE
1738                   || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
1739                 {
1740                   HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl));
1741 #ifdef DBX_OUTPUT_CONSTANT_SYMBOL
1742                   DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival);
1743 #else
1744                   fprintf (asmfile, "%s \"%s:c=i%d\",0x%x,0,0,0\n",
1745                            ASM_STABS_OP, name, ival, N_LSYM);
1746 #endif
1747                   return;
1748                 }
1749               else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)
1750                 {
1751                   /* don't know how to do this yet.  */
1752                 }
1753               break;
1754             }
1755           /* else it is something we handle like a normal variable.  */
1756         }
1757
1758       DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
1759 #ifdef LEAF_REG_REMAP
1760       if (leaf_function)
1761         leaf_renumber_regs_insn (DECL_RTL (decl));
1762 #endif
1763
1764       dbxout_symbol_location (decl, type, 0, DECL_RTL (decl));
1765     }
1766 }
1767 \f
1768 /* Output the stab for DECL, a VAR_DECL, RESULT_DECL or PARM_DECL.
1769    Add SUFFIX to its name, if SUFFIX is not 0.
1770    Describe the variable as residing in HOME
1771    (usually HOME is DECL_RTL (DECL), but not always).  */
1772
1773 static void
1774 dbxout_symbol_location (decl, type, suffix, home)
1775      tree decl, type;
1776      char *suffix;
1777      rtx home;
1778 {
1779   int letter = 0;
1780   int regno = -1;
1781
1782   /* Don't mention a variable at all
1783      if it was completely optimized into nothingness.
1784      
1785      If the decl was from an inline function, then it's rtl
1786      is not identically the rtl that was used in this
1787      particular compilation.  */
1788   if (GET_CODE (home) == REG)
1789     {
1790       regno = REGNO (home);
1791       if (regno >= FIRST_PSEUDO_REGISTER)
1792         return;
1793     }
1794   else if (GET_CODE (home) == SUBREG)
1795     {
1796       rtx value = home;
1797       int offset = 0;
1798       while (GET_CODE (value) == SUBREG)
1799         {
1800           offset += SUBREG_WORD (value);
1801           value = SUBREG_REG (value);
1802         }
1803       if (GET_CODE (value) == REG)
1804         {
1805           regno = REGNO (value);
1806           if (regno >= FIRST_PSEUDO_REGISTER)
1807             return;
1808           regno += offset;
1809         }
1810       alter_subreg (home);
1811     }
1812
1813   /* The kind-of-variable letter depends on where
1814      the variable is and on the scope of its name:
1815      G and N_GSYM for static storage and global scope,
1816      S for static storage and file scope,
1817      V for static storage and local scope,
1818      for those two, use N_LCSYM if data is in bss segment,
1819      N_STSYM if in data segment, N_FUN otherwise.
1820      (We used N_FUN originally, then changed to N_STSYM
1821      to please GDB.  However, it seems that confused ld.
1822      Now GDB has been fixed to like N_FUN, says Kingdon.)
1823      no letter at all, and N_LSYM, for auto variable,
1824      r and N_RSYM for register variable.  */
1825
1826   if (GET_CODE (home) == MEM
1827       && GET_CODE (XEXP (home, 0)) == SYMBOL_REF)
1828     {
1829       if (TREE_PUBLIC (decl))
1830         {
1831           letter = 'G';
1832           current_sym_code = N_GSYM;
1833         }
1834       else
1835         {
1836           current_sym_addr = XEXP (home, 0);
1837
1838           letter = decl_function_context (decl) ? 'V' : 'S';
1839
1840           if (!DECL_INITIAL (decl))
1841             current_sym_code = N_LCSYM;
1842           else if (DECL_IN_TEXT_SECTION (decl))
1843             /* This is not quite right, but it's the closest
1844                of all the codes that Unix defines.  */
1845             current_sym_code = DBX_STATIC_CONST_VAR_CODE;
1846           else
1847             {
1848               /* Ultrix `as' seems to need this.  */
1849 #ifdef DBX_STATIC_STAB_DATA_SECTION
1850               data_section ();
1851 #endif
1852               current_sym_code = N_STSYM;
1853             }
1854         }
1855     }
1856   else if (regno >= 0)
1857     {
1858       letter = 'r';
1859       current_sym_code = N_RSYM;
1860       current_sym_value = DBX_REGISTER_NUMBER (regno);
1861     }
1862   else if (GET_CODE (home) == MEM
1863            && (GET_CODE (XEXP (home, 0)) == MEM
1864                || (GET_CODE (XEXP (home, 0)) == REG
1865                    && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM)))
1866     /* If the value is indirect by memory or by a register
1867        that isn't the frame pointer
1868        then it means the object is variable-sized and address through
1869        that register or stack slot.  DBX has no way to represent this
1870        so all we can do is output the variable as a pointer.
1871        If it's not a parameter, ignore it.
1872        (VAR_DECLs like this can be made by integrate.c.)  */
1873     {
1874       if (GET_CODE (XEXP (home, 0)) == REG)
1875         {
1876           letter = 'r';
1877           current_sym_code = N_RSYM;
1878           current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (home, 0)));
1879         }
1880       else
1881         {
1882           current_sym_code = N_LSYM;
1883           /* RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).
1884              We want the value of that CONST_INT.  */
1885           current_sym_value
1886             = DEBUGGER_AUTO_OFFSET (XEXP (XEXP (home, 0), 0));
1887         }
1888
1889       /* Effectively do build_pointer_type, but don't cache this type,
1890          since it might be temporary whereas the type it points to
1891          might have been saved for inlining.  */
1892       /* Don't use REFERENCE_TYPE because dbx can't handle that.  */
1893       type = make_node (POINTER_TYPE);
1894       TREE_TYPE (type) = TREE_TYPE (decl);
1895     }
1896   else if (GET_CODE (home) == MEM
1897            && GET_CODE (XEXP (home, 0)) == REG)
1898     {
1899       current_sym_code = N_LSYM;
1900       current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0));
1901     }
1902   else if (GET_CODE (home) == MEM
1903            && GET_CODE (XEXP (home, 0)) == PLUS
1904            && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT)
1905     {
1906       current_sym_code = N_LSYM;
1907       /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
1908          We want the value of that CONST_INT.  */
1909       current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0));
1910     }
1911   else if (GET_CODE (home) == MEM
1912            && GET_CODE (XEXP (home, 0)) == CONST)
1913     {
1914       /* Handle an obscure case which can arise when optimizing and
1915          when there are few available registers.  (This is *always*
1916          the case for i386/i486 targets).  The RTL looks like
1917          (MEM (CONST ...)) even though this variable is a local `auto'
1918          or a local `register' variable.  In effect, what has happened
1919          is that the reload pass has seen that all assignments and
1920          references for one such a local variable can be replaced by
1921          equivalent assignments and references to some static storage
1922          variable, thereby avoiding the need for a register.  In such
1923          cases we're forced to lie to debuggers and tell them that
1924          this variable was itself `static'.  */
1925       current_sym_code = N_LCSYM;
1926       letter = 'V';
1927       current_sym_addr = XEXP (XEXP (home, 0), 0);
1928     }
1929   else if (GET_CODE (home) == CONCAT)
1930     {
1931       tree subtype = TREE_TYPE (type);
1932
1933       /* If the variable's storage is in two parts,
1934          output each as a separate stab with a modified name.  */
1935       if (WORDS_BIG_ENDIAN)
1936         dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 0));
1937       else
1938         dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0));
1939
1940       /* Cast avoids warning in old compilers.  */
1941       current_sym_code = (STAB_CODE_TYPE) 0;
1942       current_sym_value = 0;
1943       current_sym_addr = 0;
1944       dbxout_prepare_symbol (decl);
1945
1946       if (WORDS_BIG_ENDIAN)
1947         dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 1));
1948       else
1949         dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 1));
1950       return;
1951     }
1952   else
1953     /* Address might be a MEM, when DECL is a variable-sized object.
1954        Or it might be const0_rtx, meaning previous passes
1955        want us to ignore this variable.  */
1956     return;
1957
1958   /* Ok, start a symtab entry and output the variable name.  */
1959   FORCE_TEXT;
1960
1961 #ifdef DBX_STATIC_BLOCK_START
1962   DBX_STATIC_BLOCK_START (asmfile, current_sym_code);
1963 #endif
1964
1965   dbxout_symbol_name (decl, suffix, letter);
1966   dbxout_type (type, 0, 0);
1967   dbxout_finish_symbol (decl);
1968
1969 #ifdef DBX_STATIC_BLOCK_END
1970   DBX_STATIC_BLOCK_END (asmfile, current_sym_code);
1971 #endif
1972 }
1973 \f
1974 /* Output the symbol name of DECL for a stabs, with suffix SUFFIX.
1975    Then output LETTER to indicate the kind of location the symbol has.  */
1976
1977 static void
1978 dbxout_symbol_name (decl, suffix, letter)
1979      tree decl;
1980      char *suffix;
1981      int letter;
1982 {
1983   /* One slight hitch: if this is a VAR_DECL which is a static
1984      class member, we must put out the mangled name instead of the
1985      DECL_NAME.  */
1986
1987   char *name;
1988   /* Note also that static member (variable) names DO NOT begin
1989      with underscores in .stabs directives.  */
1990   if (DECL_LANG_SPECIFIC (decl))
1991     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1992   else
1993     name = IDENTIFIER_POINTER (DECL_NAME (decl));
1994   if (name == 0)
1995     name = "(anon)";
1996   fprintf (asmfile, "%s \"%s%s:", ASM_STABS_OP, name,
1997            (suffix ? suffix : ""));
1998
1999   if (letter) putc (letter, asmfile);
2000 }
2001
2002 static void
2003 dbxout_prepare_symbol (decl)
2004      tree decl;
2005 {
2006 #ifdef WINNING_GDB
2007   char *filename = DECL_SOURCE_FILE (decl);
2008
2009   dbxout_source_file (asmfile, filename);
2010 #endif
2011 }
2012
2013 static void
2014 dbxout_finish_symbol (sym)
2015      tree sym;
2016 {
2017 #ifdef DBX_FINISH_SYMBOL
2018   DBX_FINISH_SYMBOL (sym);
2019 #else
2020   int line = 0;
2021   if (use_gnu_debug_info_extensions && sym != 0)
2022     line = DECL_SOURCE_LINE (sym);
2023
2024   fprintf (asmfile, "\",%d,0,%d,", current_sym_code, line);
2025   if (current_sym_addr)
2026     output_addr_const (asmfile, current_sym_addr);
2027   else
2028     fprintf (asmfile, "%d", current_sym_value);
2029   putc ('\n', asmfile);
2030 #endif
2031 }
2032
2033 /* Output definitions of all the decls in a chain.  */
2034
2035 void
2036 dbxout_syms (syms)
2037      tree syms;
2038 {
2039   while (syms)
2040     {
2041       dbxout_symbol (syms, 1);
2042       syms = TREE_CHAIN (syms);
2043     }
2044 }
2045 \f
2046 /* The following two functions output definitions of function parameters.
2047    Each parameter gets a definition locating it in the parameter list.
2048    Each parameter that is a register variable gets a second definition
2049    locating it in the register.
2050
2051    Printing or argument lists in gdb uses the definitions that
2052    locate in the parameter list.  But reference to the variable in
2053    expressions uses preferentially the definition as a register.  */
2054
2055 /* Output definitions, referring to storage in the parmlist,
2056    of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */
2057
2058 void
2059 dbxout_parms (parms)
2060      tree parms;
2061 {
2062   for (; parms; parms = TREE_CHAIN (parms))
2063     if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
2064       {
2065         dbxout_prepare_symbol (parms);
2066
2067         /* Perform any necessary register eliminations on the parameter's rtl,
2068            so that the debugging output will be accurate.  */
2069         DECL_INCOMING_RTL (parms)
2070           = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
2071         DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
2072 #ifdef LEAF_REG_REMAP
2073         if (leaf_function)
2074           {
2075             leaf_renumber_regs_insn (DECL_INCOMING_RTL (parms));
2076             leaf_renumber_regs_insn (DECL_RTL (parms));
2077           }
2078 #endif
2079
2080         if (PARM_PASSED_IN_MEMORY (parms))
2081           {
2082             rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
2083
2084             /* ??? Here we assume that the parm address is indexed
2085                off the frame pointer or arg pointer.
2086                If that is not true, we produce meaningless results,
2087                but do not crash.  */
2088             if (GET_CODE (addr) == PLUS
2089                 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2090               current_sym_value = INTVAL (XEXP (addr, 1));
2091             else
2092               current_sym_value = 0;
2093
2094             current_sym_code = N_PSYM;
2095             current_sym_addr = 0;
2096
2097             FORCE_TEXT;
2098             if (DECL_NAME (parms))
2099               {
2100                 current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
2101
2102                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2103                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2104                          DBX_MEMPARM_STABS_LETTER);
2105               }
2106             else
2107               {
2108                 current_sym_nchars = 8;
2109                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2110                          DBX_MEMPARM_STABS_LETTER);
2111               }
2112
2113             if (GET_CODE (DECL_RTL (parms)) == REG
2114                 && REGNO (DECL_RTL (parms)) >= 0
2115                 && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
2116               dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
2117             else
2118               {
2119                 int original_value = current_sym_value;
2120
2121                 /* This is the case where the parm is passed as an int or double
2122                    and it is converted to a char, short or float and stored back
2123                    in the parmlist.  In this case, describe the parm
2124                    with the variable's declared type, and adjust the address
2125                    if the least significant bytes (which we are using) are not
2126                    the first ones.  */
2127 #if BYTES_BIG_ENDIAN
2128                 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
2129                   current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
2130                                         - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
2131 #endif
2132
2133                 if (GET_CODE (DECL_RTL (parms)) == MEM
2134                     && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
2135                     && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
2136                     && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)
2137                   dbxout_type (TREE_TYPE (parms), 0, 0);
2138                 else
2139                   {
2140                     current_sym_value = original_value;
2141                     dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
2142                   }
2143               }
2144             current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr);
2145             dbxout_finish_symbol (parms);
2146           }
2147         else if (GET_CODE (DECL_RTL (parms)) == REG)
2148           {
2149             rtx best_rtl;
2150             char regparm_letter;
2151             tree parm_type;
2152             /* Parm passed in registers and lives in registers or nowhere.  */
2153
2154             current_sym_code = DBX_REGPARM_STABS_CODE;
2155             regparm_letter = DBX_REGPARM_STABS_LETTER;
2156             current_sym_addr = 0;
2157
2158             /* If parm lives in a register, use that register;
2159                pretend the parm was passed there.  It would be more consistent
2160                to describe the register where the parm was passed,
2161                but in practice that register usually holds something else.
2162
2163                If we use DECL_RTL, then we must use the declared type of
2164                the variable, not the type that it arrived in.  */
2165             if (REGNO (DECL_RTL (parms)) >= 0
2166                 && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
2167               {
2168                 best_rtl = DECL_RTL (parms);
2169                 parm_type = TREE_TYPE (parms);
2170               }
2171             /* If the parm lives nowhere, use the register where it was
2172                passed.  It is also better to use the declared type here.  */
2173             else
2174               {
2175                 best_rtl = DECL_INCOMING_RTL (parms);
2176                 parm_type = TREE_TYPE (parms);
2177               }
2178             current_sym_value = DBX_REGISTER_NUMBER (REGNO (best_rtl));
2179
2180             FORCE_TEXT;
2181             if (DECL_NAME (parms))
2182               {
2183                 current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
2184                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2185                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2186                          regparm_letter);
2187               }
2188             else
2189               {
2190                 current_sym_nchars = 8;
2191                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2192                          regparm_letter);
2193               }
2194
2195             dbxout_type (parm_type, 0, 0);
2196             dbxout_finish_symbol (parms);
2197           }
2198         else if (GET_CODE (DECL_RTL (parms)) == MEM
2199                  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
2200                  && REGNO (XEXP (DECL_RTL (parms), 0)) != HARD_FRAME_POINTER_REGNUM
2201                  && REGNO (XEXP (DECL_RTL (parms), 0)) != STACK_POINTER_REGNUM
2202 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
2203                  && REGNO (XEXP (DECL_RTL (parms), 0)) != ARG_POINTER_REGNUM
2204 #endif
2205                  )
2206           {
2207             /* Parm was passed via invisible reference.
2208                That is, its address was passed in a register.
2209                Output it as if it lived in that register.
2210                The debugger will know from the type
2211                that it was actually passed by invisible reference.  */
2212
2213             char regparm_letter;
2214             /* Parm passed in registers and lives in registers or nowhere.  */
2215
2216             current_sym_code = DBX_REGPARM_STABS_CODE;
2217             regparm_letter = DBX_REGPARM_STABS_LETTER;
2218
2219             /* DECL_RTL looks like (MEM (REG...).  Get the register number.
2220                If it is an unallocated pseudo-reg, then use the register where
2221                it was passed instead.  */
2222             if (REGNO (XEXP (DECL_RTL (parms), 0)) >= 0
2223                 && REGNO (XEXP (DECL_RTL (parms), 0)) < FIRST_PSEUDO_REGISTER)
2224               current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0));
2225             else
2226               current_sym_value = REGNO (DECL_INCOMING_RTL (parms));
2227
2228             current_sym_addr = 0;
2229
2230             FORCE_TEXT;
2231             if (DECL_NAME (parms))
2232               {
2233                 current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
2234
2235                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2236                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2237                          DBX_REGPARM_STABS_LETTER);
2238               }
2239             else
2240               {
2241                 current_sym_nchars = 8;
2242                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2243                          DBX_REGPARM_STABS_LETTER);
2244               }
2245
2246             dbxout_type (TREE_TYPE (parms), 0, 0);
2247             dbxout_finish_symbol (parms);
2248           }
2249         else if (GET_CODE (DECL_RTL (parms)) == MEM
2250                  && XEXP (DECL_RTL (parms), 0) != const0_rtx
2251                  /* ??? A constant address for a parm can happen
2252                     when the reg it lives in is equiv to a constant in memory.
2253                     Should make this not happen, after 2.4.  */
2254                  && ! CONSTANT_P (XEXP (DECL_RTL (parms), 0)))
2255           {
2256             /* Parm was passed in registers but lives on the stack.  */
2257
2258             current_sym_code = N_PSYM;
2259             /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))),
2260                in which case we want the value of that CONST_INT,
2261                or (MEM (REG ...)) or (MEM (MEM ...)),
2262                in which case we use a value of zero.  */
2263             if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
2264                 || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM)
2265               current_sym_value = 0;
2266             else
2267               current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
2268             current_sym_addr = 0;
2269
2270             FORCE_TEXT;
2271             if (DECL_NAME (parms))
2272               {
2273                 current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
2274
2275                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2276                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2277                          DBX_MEMPARM_STABS_LETTER);
2278               }
2279             else
2280               {
2281                 current_sym_nchars = 8;
2282                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2283                 DBX_MEMPARM_STABS_LETTER);
2284               }
2285
2286             current_sym_value
2287               = DEBUGGER_ARG_OFFSET (current_sym_value,
2288                                      XEXP (DECL_RTL (parms), 0));
2289             dbxout_type (TREE_TYPE (parms), 0, 0);
2290             dbxout_finish_symbol (parms);
2291           }
2292       }
2293 }
2294
2295 /* Output definitions for the places where parms live during the function,
2296    when different from where they were passed, when the parms were passed
2297    in memory.
2298
2299    It is not useful to do this for parms passed in registers
2300    that live during the function in different registers, because it is
2301    impossible to look in the passed register for the passed value,
2302    so we use the within-the-function register to begin with.
2303
2304    PARMS is a chain of PARM_DECL nodes.  */
2305
2306 void
2307 dbxout_reg_parms (parms)
2308      tree parms;
2309 {
2310   for (; parms; parms = TREE_CHAIN (parms))
2311     if (DECL_NAME (parms))
2312       {
2313         dbxout_prepare_symbol (parms);
2314
2315         /* Report parms that live in registers during the function
2316            but were passed in memory.  */
2317         if (GET_CODE (DECL_RTL (parms)) == REG
2318             && REGNO (DECL_RTL (parms)) >= 0
2319             && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
2320             && PARM_PASSED_IN_MEMORY (parms))
2321           dbxout_symbol_location (parms, TREE_TYPE (parms),
2322                                   0, DECL_RTL (parms));
2323         else if (GET_CODE (DECL_RTL (parms)) == CONCAT
2324                  && PARM_PASSED_IN_MEMORY (parms))
2325           dbxout_symbol_location (parms, TREE_TYPE (parms),
2326                                   0, DECL_RTL (parms));
2327         /* Report parms that live in memory but not where they were passed.  */
2328         else if (GET_CODE (DECL_RTL (parms)) == MEM
2329                  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
2330                  && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
2331                  && PARM_PASSED_IN_MEMORY (parms)
2332                  && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms)))
2333           {
2334 #if 0 /* ??? It is not clear yet what should replace this.  */
2335             int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
2336             /* A parm declared char is really passed as an int,
2337                so it occupies the least significant bytes.
2338                On a big-endian machine those are not the low-numbered ones.  */
2339 #if BYTES_BIG_ENDIAN
2340             if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
2341               offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
2342                          - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
2343 #endif
2344             if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
2345 #endif
2346             dbxout_symbol_location (parms, TREE_TYPE (parms),
2347                                     0, DECL_RTL (parms));
2348           }
2349 #if 0
2350         else if (GET_CODE (DECL_RTL (parms)) == MEM
2351                  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG)
2352           {
2353             /* Parm was passed via invisible reference.
2354                That is, its address was passed in a register.
2355                Output it as if it lived in that register.
2356                The debugger will know from the type
2357                that it was actually passed by invisible reference.  */
2358
2359             current_sym_code = N_RSYM;
2360
2361             /* DECL_RTL looks like (MEM (REG...).  Get the register number.  */
2362             current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0));
2363             current_sym_addr = 0;
2364
2365             FORCE_TEXT;
2366             if (DECL_NAME (parms))
2367               {
2368                 current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
2369
2370                 fprintf (asmfile, "%s \"%s:r", ASM_STABS_OP,
2371                          IDENTIFIER_POINTER (DECL_NAME (parms)));
2372               }
2373             else
2374               {
2375                 current_sym_nchars = 8;
2376                 fprintf (asmfile, "%s \"(anon):r", ASM_STABS_OP);
2377               }
2378
2379             dbxout_type (TREE_TYPE (parms), 0, 0);
2380             dbxout_finish_symbol (parms);
2381           }
2382 #endif
2383       }
2384 }
2385 \f
2386 /* Given a chain of ..._TYPE nodes (as come in a parameter list),
2387    output definitions of those names, in raw form */
2388
2389 void
2390 dbxout_args (args)
2391      tree args;
2392 {
2393   while (args)
2394     {
2395       putc (',', asmfile);
2396       dbxout_type (TREE_VALUE (args), 0, 0);
2397       CHARS (1);
2398       args = TREE_CHAIN (args);
2399     }
2400 }
2401 \f
2402 /* Given a chain of ..._TYPE nodes,
2403    find those which have typedef names and output those names.
2404    This is to ensure those types get output.  */
2405
2406 void
2407 dbxout_types (types)
2408      register tree types;
2409 {
2410   while (types)
2411     {
2412       if (TYPE_NAME (types)
2413           && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL
2414           && ! TREE_ASM_WRITTEN (TYPE_NAME (types)))
2415         dbxout_symbol (TYPE_NAME (types), 1);
2416       types = TREE_CHAIN (types);
2417     }
2418 }
2419 \f
2420 /* Output everything about a symbol block (a BLOCK node
2421    that represents a scope level),
2422    including recursive output of contained blocks.
2423
2424    BLOCK is the BLOCK node.
2425    DEPTH is its depth within containing symbol blocks.
2426    ARGS is usually zero; but for the outermost block of the
2427    body of a function, it is a chain of PARM_DECLs for the function parameters.
2428    We output definitions of all the register parms
2429    as if they were local variables of that block.
2430
2431    If -g1 was used, we count blocks just the same, but output nothing
2432    except for the outermost block.
2433
2434    Actually, BLOCK may be several blocks chained together.
2435    We handle them all in sequence.  */
2436
2437 static void
2438 dbxout_block (block, depth, args)
2439      register tree block;
2440      int depth;
2441      tree args;
2442 {
2443   int blocknum;
2444
2445   while (block)
2446     {
2447       /* Ignore blocks never expanded or otherwise marked as real.  */
2448       if (TREE_USED (block))
2449         {
2450 #ifndef DBX_LBRAC_FIRST
2451           /* In dbx format, the syms of a block come before the N_LBRAC.  */
2452           if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
2453             dbxout_syms (BLOCK_VARS (block));
2454           if (args)
2455             dbxout_reg_parms (args);
2456 #endif
2457
2458           /* Now output an N_LBRAC symbol to represent the beginning of
2459              the block.  Use the block's tree-walk order to generate
2460              the assembler symbols LBBn and LBEn
2461              that final will define around the code in this block.  */
2462           if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE)
2463             {
2464               char buf[20];
2465               blocknum = next_block_number++;
2466               ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);
2467
2468               if (BLOCK_HANDLER_BLOCK (block))
2469                 {
2470                   /* A catch block.  Must precede N_LBRAC.  */
2471                   tree decl = BLOCK_VARS (block);
2472                   while (decl)
2473                     {
2474 #ifdef DBX_OUTPUT_CATCH
2475                       DBX_OUTPUT_CATCH (asmfile, decl, buf);
2476 #else
2477                       fprintf (asmfile, "%s \"%s:C1\",%d,0,0,", ASM_STABS_OP,
2478                                IDENTIFIER_POINTER (DECL_NAME (decl)), N_CATCH);
2479                       assemble_name (asmfile, buf);
2480                       fprintf (asmfile, "\n");
2481 #endif
2482                       decl = TREE_CHAIN (decl);
2483                     }
2484                 }
2485
2486 #ifdef DBX_OUTPUT_LBRAC
2487               DBX_OUTPUT_LBRAC (asmfile, buf);
2488 #else
2489               fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);
2490               assemble_name (asmfile, buf);
2491 #if DBX_BLOCKS_FUNCTION_RELATIVE
2492               fputc ('-', asmfile);
2493               assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2494 #endif
2495               fprintf (asmfile, "\n");
2496 #endif
2497             }
2498           else if (depth > 0)
2499             /* Count blocks the same way regardless of debug_info_level.  */
2500             next_block_number++;
2501
2502 #ifdef DBX_LBRAC_FIRST
2503           /* On some weird machines, the syms of a block
2504              come after the N_LBRAC.  */
2505           if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
2506             dbxout_syms (BLOCK_VARS (block));
2507           if (args)
2508             dbxout_reg_parms (args);
2509 #endif
2510
2511           /* Output the subblocks.  */
2512           dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
2513
2514           /* Refer to the marker for the end of the block.  */
2515           if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE)
2516             {
2517               char buf[20];
2518               ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum);
2519 #ifdef DBX_OUTPUT_RBRAC
2520               DBX_OUTPUT_RBRAC (asmfile, buf);
2521 #else
2522               fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);
2523               assemble_name (asmfile, buf);
2524 #if DBX_BLOCKS_FUNCTION_RELATIVE
2525               fputc ('-', asmfile);
2526               assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2527 #endif
2528               fprintf (asmfile, "\n");
2529 #endif
2530             }
2531         }
2532       block = BLOCK_CHAIN (block);
2533     }
2534 }
2535
2536 /* Output the information about a function and its arguments and result.
2537    Usually this follows the function's code,
2538    but on some systems, it comes before.  */
2539
2540 static void
2541 dbxout_really_begin_function (decl)
2542      tree decl;
2543 {
2544   dbxout_symbol (decl, 0);
2545   dbxout_parms (DECL_ARGUMENTS (decl));
2546   if (DECL_NAME (DECL_RESULT (decl)) != 0)
2547     dbxout_symbol (DECL_RESULT (decl), 1);
2548 }
2549
2550 /* Called at beginning of output of function definition.  */
2551
2552 void
2553 dbxout_begin_function (decl)
2554      tree decl;
2555 {
2556 #ifdef DBX_FUNCTION_FIRST
2557   dbxout_really_begin_function (decl);
2558 #endif
2559 }
2560
2561 /* Output dbx data for a function definition.
2562    This includes a definition of the function name itself (a symbol),
2563    definitions of the parameters (locating them in the parameter list)
2564    and then output the block that makes up the function's body
2565    (including all the auto variables of the function).  */
2566
2567 void
2568 dbxout_function (decl)
2569      tree decl;
2570 {
2571 #ifndef DBX_FUNCTION_FIRST
2572   dbxout_really_begin_function (decl);
2573 #endif
2574   dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
2575 #ifdef DBX_OUTPUT_FUNCTION_END
2576   DBX_OUTPUT_FUNCTION_END (asmfile, decl);
2577 #endif
2578 }
2579 #endif /* DBX_DEBUGGING_INFO */