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