OSDN Git Service

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