OSDN Git Service

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