OSDN Git Service

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