OSDN Git Service

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