OSDN Git Service

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