OSDN Git Service

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