OSDN Git Service

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