OSDN Git Service

(dbxout_type): The "base type" of a SET_TYPE is its DOMAIN_TYPE, not
[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       /* For nameless subunions and subrecords, treat their fields as ours.  */
585       if (DECL_NAME (tem) == NULL_TREE
586           && (TREE_CODE (TREE_TYPE (tem)) == UNION_TYPE
587               || TREE_CODE (TREE_TYPE (tem)) == QUAL_UNION_TYPE
588               || TREE_CODE (TREE_TYPE (tem)) == RECORD_TYPE))
589         dbxout_type_fields (TREE_TYPE (tem));
590       /* Omit here local type decls until we know how to support them.  */
591       else if (TREE_CODE (tem) == TYPE_DECL)
592         continue;
593       /* Omit fields whose position or size are variable.  */
594       else if (TREE_CODE (tem) == FIELD_DECL
595                && (TREE_CODE (DECL_FIELD_BITPOS (tem)) != INTEGER_CST
596                    || TREE_CODE (DECL_SIZE (tem)) != INTEGER_CST))
597         continue;
598       /* Omit here the nameless fields that are used to skip bits.  */
599       else if (DECL_NAME (tem) != 0 && TREE_CODE (tem) != CONST_DECL)
600         {
601           /* Continue the line if necessary,
602              but not before the first field.  */
603           if (tem != TYPE_FIELDS (type))
604             CONTIN;
605
606           if (use_gnu_debug_info_extensions
607               && flag_minimal_debug
608               && TREE_CODE (tem) == FIELD_DECL
609               && DECL_VIRTUAL_P (tem)
610               && DECL_ASSEMBLER_NAME (tem))
611             {
612               have_used_extensions = 1;
613               CHARS (3 + IDENTIFIER_LENGTH (DECL_NAME (TYPE_NAME (DECL_FCONTEXT (tem)))));
614               fputs (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem)), asmfile);
615               dbxout_type (DECL_FCONTEXT (tem), 0, 0);
616               fprintf (asmfile, ":");
617               dbxout_type (TREE_TYPE (tem), 0, 0);
618               fprintf (asmfile, ",%d;",
619                        TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)));
620               continue;
621             }
622
623           fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
624           CHARS (2 + IDENTIFIER_LENGTH (DECL_NAME (tem)));
625
626           if (use_gnu_debug_info_extensions
627               && (TREE_PRIVATE (tem) || TREE_PROTECTED (tem)
628                   || TREE_CODE (tem) != FIELD_DECL))
629             {
630               have_used_extensions = 1;
631               putc ('/', asmfile);
632               putc ((TREE_PRIVATE (tem) ? '0'
633                      : TREE_PROTECTED (tem) ? '1' : '2'),
634                     asmfile);
635               CHARS (2);
636             }
637
638           dbxout_type ((TREE_CODE (tem) == FIELD_DECL
639                         && DECL_BIT_FIELD_TYPE (tem))
640                        ? DECL_BIT_FIELD_TYPE (tem)
641                        : TREE_TYPE (tem), 0, 0);
642
643           if (TREE_CODE (tem) == VAR_DECL)
644             {
645               if (TREE_STATIC (tem) && use_gnu_debug_info_extensions)
646                 {
647                   char *name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (tem));
648                   have_used_extensions = 1;
649                   fprintf (asmfile, ":%s;", name);
650                   CHARS (strlen (name));
651                 }
652               else
653                 {
654                   /* If TEM is non-static, GDB won't understand it.  */
655                   fprintf (asmfile, ",0,0;");
656                 }
657             }
658           else if (TREE_CODE (DECL_FIELD_BITPOS (tem)) == INTEGER_CST)
659             {
660               fprintf (asmfile, ",%d,%d;",
661                        TREE_INT_CST_LOW (DECL_FIELD_BITPOS (tem)),
662                        TREE_INT_CST_LOW (DECL_SIZE (tem)));
663             }
664           CHARS (23);
665         }
666     }
667 }
668 \f
669 /* Subroutine of `dbxout_type_methods'.  Output debug info about the
670    method described DECL.  DEBUG_NAME is an encoding of the method's
671    type signature.  ??? We may be able to do without DEBUG_NAME altogether
672    now.  */
673
674 static void
675 dbxout_type_method_1 (decl, debug_name)
676      tree decl;
677      char *debug_name;
678 {
679   tree firstarg = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (decl)));
680   char c1 = 'A', c2;
681
682   if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE)
683     c2 = '?';
684   else /* it's a METHOD_TYPE.  */
685     {
686       /* A for normal functions.
687          B for `const' member functions.
688          C for `volatile' member functions.
689          D for `const volatile' member functions.  */
690       if (TYPE_READONLY (TREE_TYPE (firstarg)))
691         c1 += 1;
692       if (TYPE_VOLATILE (TREE_TYPE (firstarg)))
693         c1 += 2;
694
695       if (DECL_VINDEX (decl))
696         c2 = '*';
697       else
698         c2 = '.';
699     }
700
701   fprintf (asmfile, ":%s;%c%c%c", debug_name,
702            TREE_PRIVATE (decl) ? '0' : TREE_PROTECTED (decl) ? '1' : '2', c1, c2);
703   CHARS (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (decl)) + 6
704          - (debug_name - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
705   if (DECL_VINDEX (decl))
706     {
707       fprintf (asmfile, "%d;",
708                TREE_INT_CST_LOW (DECL_VINDEX (decl)));
709       dbxout_type (DECL_CONTEXT (decl), 0, 0);
710       fprintf (asmfile, ";");
711       CHARS (8);
712     }
713 }
714 \f
715 /* Subroutine of `dbxout_type'.  Output debug info about the methods defined
716    in TYPE.  */
717
718 static void
719 dbxout_type_methods (type)
720      register tree type;
721 {
722   /* C++: put out the method names and their parameter lists */
723   tree methods = TYPE_METHODS (type);
724   tree type_encoding;
725   register tree fndecl;
726   register tree last;
727   char formatted_type_identifier_length[16];
728   register int type_identifier_length;
729
730   if (methods == NULL_TREE)
731     return;
732
733   type_encoding = DECL_NAME (TYPE_NAME (type));
734
735   /* C++: Template classes break some assumptions made by this code about
736      the class names, constructor names, and encodings for assembler
737      label names.  For now, disable output of dbx info for them.  */
738   {
739     char *ptr = IDENTIFIER_POINTER (type_encoding);
740     /* This should use index.  (mrs) */
741     while (*ptr && *ptr != '<') ptr++;
742     if (*ptr != 0)
743       {
744         static int warned;
745         if (!warned)
746           {
747             warned = 1;
748 #ifdef HAVE_TEMPLATES
749             if (warn_template_debugging)
750               warning ("dbx info for template class methods not yet supported");
751 #endif
752           }
753         return;
754       }
755   }
756
757   type_identifier_length = IDENTIFIER_LENGTH (type_encoding);
758
759   sprintf(formatted_type_identifier_length, "%d", type_identifier_length);
760
761   if (TREE_CODE (methods) == FUNCTION_DECL)
762     fndecl = methods;
763   else if (TREE_VEC_ELT (methods, 0) != NULL_TREE)
764     fndecl = TREE_VEC_ELT (methods, 0);
765   else
766     fndecl = TREE_VEC_ELT (methods, 1);
767
768   while (fndecl)
769     {
770       tree name = DECL_NAME (fndecl);
771       int need_prefix = 1;
772
773       /* Group together all the methods for the same operation.
774          These differ in the types of the arguments.  */
775       for (last = NULL_TREE;
776            fndecl && (last == NULL_TREE || DECL_NAME (fndecl) == DECL_NAME (last));
777            fndecl = TREE_CHAIN (fndecl))
778         /* Output the name of the field (after overloading), as
779            well as the name of the field before overloading, along
780            with its parameter list */
781         {
782           /* This is the "mangled" name of the method.
783              It encodes the argument types.  */
784           char *debug_name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl));
785           int destructor = 0;
786
787           CONTIN;
788
789           last = fndecl;
790
791           if (DECL_IGNORED_P (fndecl))
792             continue;
793
794           if (flag_minimal_debug)
795             {
796               /* Detect ordinary methods because their mangled names
797                  start with the operation name.  */
798               if (!strncmp (IDENTIFIER_POINTER (name), debug_name,
799                             IDENTIFIER_LENGTH (name)))
800                 {
801                   debug_name += IDENTIFIER_LENGTH (name);
802                   if (debug_name[0] == '_' && debug_name[1] == '_')
803                     {
804                       char *method_name = debug_name + 2;
805                       char *length_ptr = formatted_type_identifier_length;
806                       /* Get past const and volatile qualifiers.  */
807                       while (*method_name == 'C' || *method_name == 'V')
808                         method_name++;
809                       /* Skip digits for length of type_encoding. */
810                       while (*method_name == *length_ptr && *length_ptr)
811                           length_ptr++, method_name++;
812                       if (! strncmp (method_name,
813                                      IDENTIFIER_POINTER (type_encoding),
814                                      type_identifier_length))
815                         method_name += type_identifier_length;
816                       debug_name = method_name;
817                     }
818                 }
819               /* Detect constructors by their style of name mangling.  */
820               else if (debug_name[0] == '_' && debug_name[1] == '_')
821                 {
822                   char *ctor_name = debug_name + 2;
823                   char *length_ptr = formatted_type_identifier_length;
824                   while (*ctor_name == 'C' || *ctor_name == 'V')
825                     ctor_name++;
826                   /* Skip digits for length of type_encoding. */
827                   while (*ctor_name == *length_ptr && *length_ptr)
828                       length_ptr++, ctor_name++;
829                   if (!strncmp (IDENTIFIER_POINTER (type_encoding), ctor_name,
830                                 type_identifier_length))
831                     debug_name = ctor_name + type_identifier_length;
832                 }
833               /* The other alternative is a destructor.  */
834               else
835                 destructor = 1;
836
837               /* Output the operation name just once, for the first method
838                  that we output.  */
839               if (need_prefix)
840                 {
841                   fprintf (asmfile, "%s::", IDENTIFIER_POINTER (name));
842                   CHARS (IDENTIFIER_LENGTH (name) + 2);
843                   need_prefix = 0;
844                 }
845             }
846
847           dbxout_type (TREE_TYPE (fndecl), 0, destructor);
848
849           dbxout_type_method_1 (fndecl, debug_name);
850         }
851       if (!need_prefix)
852         {
853           putc (';', asmfile);
854           CHARS (1);
855         }
856     }
857 }
858
859 /* Emit a "range" type specification, which has the form:
860    "r<index type>;<lower bound>;<upper bound>;".
861    TYPE is an INTEGER_TYPE. */
862
863 static void
864 dbxout_range_type (type)
865      tree type;
866 {
867   fprintf (asmfile, "r");
868   if (TREE_TYPE (type) && TREE_CODE (TREE_TYPE(type)) != INTEGER_TYPE)
869     dbxout_type (TREE_TYPE (type), 0, 0);
870   else
871     {
872       /* This used to say `r1' and we used to take care
873          to make sure that `int' was type number 1.  */
874       fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (integer_type_node));
875     }
876   if (TREE_CODE (TYPE_MIN_VALUE (type)) == INTEGER_CST)
877     fprintf (asmfile, ";%d", 
878              TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)));
879   else
880     fprintf (asmfile, ";0");
881   if (TREE_CODE (TYPE_MAX_VALUE (type)) == INTEGER_CST)
882     fprintf (asmfile, ";%d;", 
883              TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
884   else
885     fprintf (asmfile, ";-1;");
886 }
887 \f
888 /* Output a reference to a type.  If the type has not yet been
889    described in the dbx output, output its definition now.
890    For a type already defined, just refer to its definition
891    using the type number.
892
893    If FULL is nonzero, and the type has been described only with
894    a forward-reference, output the definition now.
895    If FULL is zero in this case, just refer to the forward-reference
896    using the number previously allocated.
897
898    If SHOW_ARG_TYPES is nonzero, we output a description of the argument
899    types for a METHOD_TYPE.  */
900
901 static void
902 dbxout_type (type, full, show_arg_types)
903      tree type;
904      int full;
905      int show_arg_types;
906 {
907   register tree tem;
908   static int anonymous_type_number = 0;
909
910   /* If there was an input error and we don't really have a type,
911      avoid crashing and write something that is at least valid
912      by assuming `int'.  */
913   if (type == error_mark_node)
914     type = integer_type_node;
915   else
916     {
917       type = TYPE_MAIN_VARIANT (type);
918       if (TYPE_NAME (type)
919           && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
920           && DECL_IGNORED_P (TYPE_NAME (type)))
921         full = 0;
922     }
923
924   if (TYPE_SYMTAB_ADDRESS (type) == 0)
925     {
926       /* Type has no dbx number assigned.  Assign next available number.  */
927       TYPE_SYMTAB_ADDRESS (type) = next_type_number++;
928
929       /* Make sure type vector is long enough to record about this type.  */
930
931       if (next_type_number == typevec_len)
932         {
933           typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]);
934           bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]);
935           typevec_len *= 2;
936         }
937     }
938
939   /* Output the number of this type, to refer to it.  */
940   fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
941   CHARS (3);
942
943 #ifdef DBX_TYPE_DEFINED
944   if (DBX_TYPE_DEFINED (type))
945     return;
946 #endif
947
948   /* If this type's definition has been output or is now being output,
949      that is all.  */
950
951   switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
952     {
953     case TYPE_UNSEEN:
954       break;
955     case TYPE_XREF:
956       /* If we have already had a cross reference,
957          and either that's all we want or that's the best we could do,
958          don't repeat the cross reference.
959          Sun dbx crashes if we do.  */
960       if (! full || TYPE_SIZE (type) == 0
961           /* No way in DBX fmt to describe a variable size.  */
962           || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
963         return;
964       break;
965     case TYPE_DEFINED:
966       return;
967     }
968
969 #ifdef DBX_NO_XREFS
970   /* For systems where dbx output does not allow the `=xsNAME:' syntax,
971      leave the type-number completely undefined rather than output
972      a cross-reference.  */
973   if (TREE_CODE (type) == RECORD_TYPE || TREE_CODE (type) == UNION_TYPE
974       || TREE_CODE (type) == QUAL_UNION_TYPE
975       || TREE_CODE (type) == ENUMERAL_TYPE)
976
977     if ((TYPE_NAME (type) != 0 && !full)
978         || TYPE_SIZE (type) == 0)
979       {
980         typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
981         return;
982       }
983 #endif
984
985   /* Output a definition now.  */
986
987   fprintf (asmfile, "=");
988   CHARS (1);
989
990   /* Mark it as defined, so that if it is self-referent
991      we will not get into an infinite recursion of definitions.  */
992
993   typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
994
995   switch (TREE_CODE (type))
996     {
997     case VOID_TYPE:
998     case LANG_TYPE:
999       /* For a void type, just define it as itself; ie, "5=5".
1000          This makes us consider it defined
1001          without saying what it is.  The debugger will make it
1002          a void type when the reference is seen, and nothing will
1003          ever override that default.  */
1004       fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
1005       CHARS (3);
1006       break;
1007
1008     case INTEGER_TYPE:
1009       if (type == char_type_node && ! TREE_UNSIGNED (type))
1010         /* Output the type `char' as a subrange of itself!
1011            I don't understand this definition, just copied it
1012            from the output of pcc.
1013            This used to use `r2' explicitly and we used to
1014            take care to make sure that `char' was type number 2.  */
1015         fprintf (asmfile, "r%d;0;127;", TYPE_SYMTAB_ADDRESS (type));
1016       else if (use_gnu_debug_info_extensions
1017                && (TYPE_PRECISION (type) > TYPE_PRECISION (integer_type_node)
1018                    || TYPE_PRECISION (type) > HOST_BITS_PER_WIDE_INT))
1019         {
1020           /* This used to say `r1' and we used to take care
1021              to make sure that `int' was type number 1.  */
1022           fprintf (asmfile, "r%d;", TYPE_SYMTAB_ADDRESS (integer_type_node));
1023           print_int_cst_octal (TYPE_MIN_VALUE (type));
1024           fprintf (asmfile, ";");
1025           print_int_cst_octal (TYPE_MAX_VALUE (type));
1026           fprintf (asmfile, ";");
1027         }
1028       else /* Output other integer types as subranges of `int'.  */
1029         dbxout_range_type (type);
1030       CHARS (25);
1031       break;
1032
1033     case REAL_TYPE:
1034       /* This used to say `r1' and we used to take care
1035          to make sure that `int' was type number 1.  */
1036       fprintf (asmfile, "r%d;%d;0;", TYPE_SYMTAB_ADDRESS (integer_type_node),
1037                int_size_in_bytes (type));
1038       CHARS (16);
1039       break;
1040
1041     case CHAR_TYPE:
1042       if (use_gnu_debug_info_extensions)
1043         fprintf (asmfile, "@s%d;-20;",
1044                  BITS_PER_UNIT * int_size_in_bytes (type));
1045       else
1046         /* Output the type `char' as a subrange of itself.
1047            That is what pcc seems to do.  */
1048       fprintf (asmfile, "r%d;0;%d;", TYPE_SYMTAB_ADDRESS (char_type_node),
1049                TREE_UNSIGNED (type) ? 255 : 127);
1050       CHARS (9);
1051       break;
1052
1053     case BOOLEAN_TYPE:
1054       if (use_gnu_debug_info_extensions)
1055         fprintf (asmfile, "@s%d;-16;",
1056                  BITS_PER_UNIT * int_size_in_bytes (type));
1057       else /* Define as enumeral type (False, True) */
1058         fprintf (asmfile, "eFalse:0,True:1,;");
1059       CHARS (17);
1060       break;
1061
1062     case FILE_TYPE:
1063       putc ('d', asmfile);
1064       CHARS (1);
1065       dbxout_type (TREE_TYPE (type), 0, 0);
1066       break;
1067
1068     case COMPLEX_TYPE:
1069       /* Differs from the REAL_TYPE by its new data type number */
1070
1071       if (TREE_CODE (TREE_TYPE (type)) == REAL_TYPE)
1072         {
1073           fprintf (asmfile, "r%d;%d;0;",
1074                    TYPE_SYMTAB_ADDRESS (type),
1075                    int_size_in_bytes (TREE_TYPE (type)));
1076           CHARS (15);           /* The number is probably incorrect here.  */
1077         }
1078       else
1079         {
1080           /* Output a complex integer type as a structure,
1081              pending some other way to do it.  */
1082           fprintf (asmfile, "s%d", int_size_in_bytes (type));
1083
1084           fprintf (asmfile, "real:");
1085           CHARS (10);
1086           dbxout_type (TREE_TYPE (type), 0, 0);
1087           fprintf (asmfile, ",%d,%d;",
1088                    0, TYPE_PRECISION (TREE_TYPE (type)));
1089           CHARS (8);
1090           fprintf (asmfile, "imag:");
1091           CHARS (5);
1092           dbxout_type (TREE_TYPE (type), 0, 0);
1093           fprintf (asmfile, ",%d,%d;;",
1094                    TYPE_PRECISION (TREE_TYPE (type)),
1095                    TYPE_PRECISION (TREE_TYPE (type)));
1096           CHARS (9);
1097         }
1098       break;
1099
1100     case SET_TYPE:
1101       putc ('S', asmfile);
1102       CHARS (1);
1103       dbxout_type (TYPE_DOMAIN (type), 0, 0);
1104       break;
1105
1106     case ARRAY_TYPE:
1107       /* Output "a" followed by a range type definition
1108          for the index type of the array
1109          followed by a reference to the target-type.
1110          ar1;0;N;M for a C array of type M and size N+1.  */
1111       tem = TYPE_DOMAIN (type);
1112       if (tem == NULL)
1113         fprintf (asmfile, "ar%d;0;-1;",
1114                  TYPE_SYMTAB_ADDRESS (integer_type_node));
1115       else
1116         {
1117           fprintf (asmfile, "a");
1118           dbxout_range_type (tem);
1119         }
1120       CHARS (17);
1121       dbxout_type (TREE_TYPE (type), 0, 0);
1122       break;
1123
1124     case RECORD_TYPE:
1125     case UNION_TYPE:
1126     case QUAL_UNION_TYPE:
1127       {
1128         int i, n_baseclasses = 0;
1129
1130         if (TYPE_BINFO (type) != 0 && TYPE_BINFO_BASETYPES (type) != 0)
1131           n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type));
1132
1133         /* Output a structure type.  */
1134         if ((TYPE_NAME (type) != 0
1135              /* Long ago, Tiemann said this creates output that "confuses GDB".
1136                 In April 93, mrs@cygnus.com said there is no such problem.
1137                 The type decls made automatically by struct specifiers
1138                 are marked with DECL_IGNORED_P in C++.  */
1139 #if 0 /* This creates output for anonymous classes which confuses GDB. */
1140              && ! (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1141                    && DECL_IGNORED_P (TYPE_NAME (type)))
1142 #endif
1143              && !full)
1144             || TYPE_SIZE (type) == 0
1145             /* No way in DBX fmt to describe a variable size.  */
1146             || TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST)
1147           {
1148             /* If the type is just a cross reference, output one
1149                and mark the type as partially described.
1150                If it later becomes defined, we will output
1151                its real definition.
1152                If the type has a name, don't nest its definition within
1153                another type's definition; instead, output an xref
1154                and let the definition come when the name is defined.  */
1155             fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
1156             CHARS (3);
1157 #if 0 /* This assertion is legitimately false in C++.  */
1158             /* We shouldn't be outputting a reference to a type before its
1159                definition unless the type has a tag name.
1160                A typedef name without a tag name should be impossible.  */
1161             if (TREE_CODE (TYPE_NAME (type)) != IDENTIFIER_NODE)
1162               abort ();
1163 #endif
1164             if (TYPE_NAME (type) != 0)
1165               dbxout_type_name (type);
1166             else
1167               fprintf (asmfile, "$$%d", anonymous_type_number++);
1168             fprintf (asmfile, ":");
1169             typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
1170             break;
1171           }
1172
1173         /* Identify record or union, and print its size.  */
1174         fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
1175                  int_size_in_bytes (type));
1176
1177         if (use_gnu_debug_info_extensions)
1178           {
1179             if (n_baseclasses)
1180               {
1181                 have_used_extensions = 1;
1182                 fprintf (asmfile, "!%d,", n_baseclasses);
1183                 CHARS (8);
1184               }
1185           }
1186         for (i = 0; i < n_baseclasses; i++)
1187           {
1188             tree child = TREE_VEC_ELT (BINFO_BASETYPES (TYPE_BINFO (type)), i);
1189             if (use_gnu_debug_info_extensions)
1190               {
1191                 have_used_extensions = 1;
1192                 putc (TREE_VIA_VIRTUAL (child) ? '1'
1193                       : '0',
1194                       asmfile);
1195                 putc (TREE_VIA_PUBLIC (child) ? '2'
1196                       : '0',
1197                       asmfile);
1198                 fprintf (asmfile, "%d,",
1199                          TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT);
1200                 CHARS (15);
1201                 dbxout_type (BINFO_TYPE (child), 0, 0);
1202                 putc (';', asmfile);
1203               }
1204             else
1205               {
1206                 /* Print out the base class information with fields
1207                    which have the same names at the types they hold.  */
1208                 dbxout_type_name (BINFO_TYPE (child));
1209                 putc (':', asmfile);
1210                 dbxout_type (BINFO_TYPE (child), full, 0);
1211                 fprintf (asmfile, ",%d,%d;",
1212                          TREE_INT_CST_LOW (BINFO_OFFSET (child)) * BITS_PER_UNIT,
1213                          TREE_INT_CST_LOW (DECL_SIZE (TYPE_NAME (BINFO_TYPE (child)))) * BITS_PER_UNIT);
1214                 CHARS (20);
1215               }
1216           }
1217       }
1218
1219       CHARS (11);
1220
1221       /* Write out the field declarations.  */
1222       dbxout_type_fields (type);
1223       if (use_gnu_debug_info_extensions && TYPE_METHODS (type) != NULL_TREE)
1224         {
1225           have_used_extensions = 1;
1226           dbxout_type_methods (type);
1227         }
1228       putc (';', asmfile);
1229
1230       if (use_gnu_debug_info_extensions && TREE_CODE (type) == RECORD_TYPE
1231           /* Avoid the ~ if we don't really need it--it confuses dbx.  */
1232           && TYPE_VFIELD (type))
1233         {
1234           have_used_extensions = 1;
1235
1236           /* Tell GDB+ that it may keep reading.  */
1237           putc ('~', asmfile);
1238
1239           /* We need to write out info about what field this class
1240              uses as its "main" vtable pointer field, because if this
1241              field is inherited from a base class, GDB cannot necessarily
1242              figure out which field it's using in time.  */
1243           if (TYPE_VFIELD (type))
1244             {
1245               putc ('%', asmfile);
1246               dbxout_type (DECL_FCONTEXT (TYPE_VFIELD (type)), 0, 0);
1247             }
1248           putc (';', asmfile);
1249           CHARS (3);
1250         }
1251       break;
1252
1253     case ENUMERAL_TYPE:
1254       if ((TYPE_NAME (type) != 0 && !full
1255            && (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL
1256                && ! DECL_IGNORED_P (TYPE_NAME (type))))
1257           || TYPE_SIZE (type) == 0)
1258         {
1259           fprintf (asmfile, "xe");
1260           CHARS (3);
1261           dbxout_type_name (type);
1262           typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
1263           fprintf (asmfile, ":");
1264           return;
1265         }
1266 #ifdef DBX_OUTPUT_ENUM
1267       DBX_OUTPUT_ENUM (asmfile, type);
1268 #else
1269       putc ('e', asmfile);
1270       CHARS (1);
1271       for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
1272         {
1273           fprintf (asmfile, "%s:", IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
1274           if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == 0)
1275             fprintf (asmfile, "%lu",
1276                      (unsigned long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
1277           else if (TREE_INT_CST_HIGH (TREE_VALUE (tem)) == -1
1278                    && TREE_INT_CST_LOW (TREE_VALUE (tem)) < 0)
1279             fprintf (asmfile, "%ld",
1280                      (long) TREE_INT_CST_LOW (TREE_VALUE (tem)));
1281           else
1282             print_int_cst_octal (TREE_VALUE (tem));
1283           fprintf (asmfile, ",");
1284           CHARS (20 + IDENTIFIER_LENGTH (TREE_PURPOSE (tem)));
1285           if (TREE_CHAIN (tem) != 0)
1286             CONTIN;
1287         }
1288       putc (';', asmfile);
1289       CHARS (1);
1290 #endif
1291       break;
1292
1293     case POINTER_TYPE:
1294       putc ('*', asmfile);
1295       CHARS (1);
1296       dbxout_type (TREE_TYPE (type), 0, 0);
1297       break;
1298
1299     case METHOD_TYPE:
1300       if (use_gnu_debug_info_extensions)
1301         {
1302           have_used_extensions = 1;
1303           putc ('#', asmfile);
1304           CHARS (1);
1305           if (flag_minimal_debug && !show_arg_types)
1306             {
1307               /* Normally, just output the return type.
1308                  The argument types are encoded in the method name.  */
1309               putc ('#', asmfile);
1310               dbxout_type (TREE_TYPE (type), 0, 0);
1311               putc (';', asmfile);
1312               CHARS (1);
1313             }
1314           else
1315             {
1316               /* When outputting destructors, we need to write
1317                  the argument types out longhand.  */
1318               dbxout_type (TYPE_METHOD_BASETYPE (type), 0, 0);
1319               putc (',', asmfile);
1320               CHARS (1);
1321               dbxout_type (TREE_TYPE (type), 0, 0);
1322               dbxout_args (TYPE_ARG_TYPES (type));
1323               putc (';', asmfile);
1324               CHARS (1);
1325             }
1326         }
1327       else
1328         {
1329           /* Treat it as a function type.  */
1330           dbxout_type (TREE_TYPE (type), 0, 0);
1331         }
1332       break;
1333
1334     case OFFSET_TYPE:
1335       if (use_gnu_debug_info_extensions)
1336         {
1337           have_used_extensions = 1;
1338           putc ('@', asmfile);
1339           CHARS (1);
1340           dbxout_type (TYPE_OFFSET_BASETYPE (type), 0, 0);
1341           putc (',', asmfile);
1342           CHARS (1);
1343           dbxout_type (TREE_TYPE (type), 0, 0);
1344         }
1345       else
1346         {
1347           /* Should print as an int, because it is really
1348              just an offset.  */
1349           dbxout_type (integer_type_node, 0, 0);
1350         }
1351       break;
1352
1353     case REFERENCE_TYPE:
1354       if (use_gnu_debug_info_extensions)
1355         have_used_extensions = 1;
1356       putc (use_gnu_debug_info_extensions ? '&' : '*', asmfile);
1357       CHARS (1);
1358       dbxout_type (TREE_TYPE (type), 0, 0);
1359       break;
1360
1361     case FUNCTION_TYPE:
1362       putc ('f', asmfile);
1363       CHARS (1);
1364       dbxout_type (TREE_TYPE (type), 0, 0);
1365       break;
1366
1367     default:
1368       abort ();
1369     }
1370 }
1371
1372 /* Print the value of integer constant C, in octal,
1373    handling double precision.  */
1374
1375 static void
1376 print_int_cst_octal (c)
1377      tree c;
1378 {
1379   unsigned HOST_WIDE_INT high = TREE_INT_CST_HIGH (c);
1380   unsigned HOST_WIDE_INT low = TREE_INT_CST_LOW (c);
1381   int excess = (3 - (HOST_BITS_PER_WIDE_INT % 3));
1382   int width = TYPE_PRECISION (TREE_TYPE (c));
1383
1384   /* GDB wants constants with no extra leading "1" bits, so
1385      we need to remove any sign-extension that might be
1386      present.  */
1387   if (width == HOST_BITS_PER_WIDE_INT * 2)
1388     ;
1389   else if (width > HOST_BITS_PER_WIDE_INT)
1390     high &= (((HOST_WIDE_INT) 1 << (width - HOST_BITS_PER_WIDE_INT)) - 1);
1391   else if (width == HOST_BITS_PER_WIDE_INT)
1392     high = 0;
1393   else
1394     high = 0, low &= (((HOST_WIDE_INT) 1 << width) - 1);
1395
1396   fprintf (asmfile, "0");
1397
1398   if (excess == 3)
1399     {
1400       print_octal (high, HOST_BITS_PER_WIDE_INT / 3);
1401       print_octal (low, HOST_BITS_PER_WIDE_INT / 3);
1402     }
1403   else
1404     {
1405       unsigned HOST_WIDE_INT beg = high >> excess;
1406       unsigned HOST_WIDE_INT middle
1407         = ((high & (((HOST_WIDE_INT) 1 << excess) - 1)) << (3 - excess)
1408            | (low >> (HOST_BITS_PER_WIDE_INT / 3 * 3)));
1409       unsigned HOST_WIDE_INT end
1410         = low & (((unsigned HOST_WIDE_INT) 1
1411                   << (HOST_BITS_PER_WIDE_INT / 3 * 3))
1412                  - 1);
1413
1414       fprintf (asmfile, "%o%01o", beg, middle);
1415       print_octal (end, HOST_BITS_PER_WIDE_INT / 3);
1416     }
1417 }
1418
1419 static void
1420 print_octal (value, digits)
1421      unsigned HOST_WIDE_INT value;
1422      int digits;
1423 {
1424   int i;
1425
1426   for (i = digits - 1; i >= 0; i--)
1427     fprintf (asmfile, "%01o", ((value >> (3 * i)) & 7));
1428 }
1429
1430 /* Output the name of type TYPE, with no punctuation.
1431    Such names can be set up either by typedef declarations
1432    or by struct, enum and union tags.  */
1433
1434 static void
1435 dbxout_type_name (type)
1436      register tree type;
1437 {
1438   tree t;
1439   if (TYPE_NAME (type) == 0)
1440     abort ();
1441   if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
1442     {
1443       t = TYPE_NAME (type);
1444     }
1445   else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
1446     {
1447       t = DECL_NAME (TYPE_NAME (type));
1448     }
1449   else
1450     abort ();
1451
1452   fprintf (asmfile, "%s", IDENTIFIER_POINTER (t));
1453   CHARS (IDENTIFIER_LENGTH (t));
1454 }
1455 \f
1456 /* Output a .stabs for the symbol defined by DECL,
1457    which must be a ..._DECL node in the normal namespace.
1458    It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
1459    LOCAL is nonzero if the scope is less than the entire file.  */
1460
1461 void
1462 dbxout_symbol (decl, local)
1463      tree decl;
1464      int local;
1465 {
1466   int letter = 0;
1467   tree type = TREE_TYPE (decl);
1468   tree context = NULL_TREE;
1469   int regno = -1;
1470
1471   /* Cast avoids warning in old compilers.  */
1472   current_sym_code = (STAB_CODE_TYPE) 0;
1473   current_sym_value = 0;
1474   current_sym_addr = 0;
1475
1476   /* Ignore nameless syms, but don't ignore type tags.  */
1477
1478   if ((DECL_NAME (decl) == 0 && TREE_CODE (decl) != TYPE_DECL)
1479       || DECL_IGNORED_P (decl))
1480     return;
1481
1482   dbxout_prepare_symbol (decl);
1483
1484   /* The output will always start with the symbol name,
1485      so always count that in the length-output-so-far.  */
1486
1487   if (DECL_NAME (decl) != 0)
1488     current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (decl));
1489
1490   switch (TREE_CODE (decl))
1491     {
1492     case CONST_DECL:
1493       /* Enum values are defined by defining the enum type.  */
1494       break;
1495
1496     case FUNCTION_DECL:
1497       if (DECL_RTL (decl) == 0)
1498         return;
1499       if (DECL_EXTERNAL (decl))
1500         break;
1501       /* Don't mention a nested function under its parent.  */
1502       context = decl_function_context (decl);
1503       if (context == current_function_decl)
1504         break;
1505       if (GET_CODE (DECL_RTL (decl)) != MEM
1506           || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
1507         break;
1508       FORCE_TEXT;
1509
1510       fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
1511                IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
1512                TREE_PUBLIC (decl) ? 'F' : 'f');
1513
1514       current_sym_code = N_FUN;
1515       current_sym_addr = XEXP (DECL_RTL (decl), 0);
1516
1517       if (TREE_TYPE (type))
1518         dbxout_type (TREE_TYPE (type), 0, 0);
1519       else
1520         dbxout_type (void_type_node, 0, 0);
1521
1522       /* For a nested function, when that function is compiled,
1523          mention the containing function name
1524          as well as (since dbx wants it) our own assembler-name.  */
1525       if (context != 0)
1526         fprintf (asmfile, ",%s,%s",
1527                  IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
1528                  IDENTIFIER_POINTER (DECL_NAME (context)));
1529
1530       dbxout_finish_symbol (decl);
1531       break;
1532
1533     case TYPE_DECL:
1534 #if 0
1535       /* This seems all wrong.  Outputting most kinds of types gives no name
1536          at all.  A true definition gives no name; a cross-ref for a
1537          structure can give the tag name, but not a type name.
1538          It seems that no typedef name is defined by outputting a type.  */
1539
1540       /* If this typedef name was defined by outputting the type,
1541          don't duplicate it.  */
1542       if (typevec[TYPE_SYMTAB_ADDRESS (type)] == TYPE_DEFINED
1543           && TYPE_NAME (TREE_TYPE (decl)) == decl)
1544         return;
1545 #endif
1546       /* Don't output the same typedef twice.
1547          And don't output what language-specific stuff doesn't want output.  */
1548       if (TREE_ASM_WRITTEN (decl) || DECL_IGNORED_P (decl))
1549         return;
1550
1551       FORCE_TEXT;
1552
1553       {
1554         int tag_needed = 1;
1555         int did_output = 0;
1556
1557         if (DECL_NAME (decl))
1558           {
1559             /* Nonzero means we must output a tag as well as a typedef.  */
1560             tag_needed = 0;
1561
1562             /* Handle the case of a C++ structure or union
1563                where the TYPE_NAME is a TYPE_DECL
1564                which gives both a typedef name and a tag.  */
1565             /* dbx requires the tag first and the typedef second.  */
1566             if ((TREE_CODE (type) == RECORD_TYPE
1567                  || TREE_CODE (type) == UNION_TYPE
1568                  || TREE_CODE (type) == QUAL_UNION_TYPE)
1569                 && TYPE_NAME (type) == decl
1570                 && !(use_gnu_debug_info_extensions && have_used_extensions)
1571                 && !TREE_ASM_WRITTEN (TYPE_NAME (type))
1572                 /* Distinguish the implicit typedefs of C++
1573                    from explicit ones that might be found in C.  */
1574                 && (!strcmp (lang_identify (), "cplusplus") 
1575                     /* The following line maybe unnecessary;
1576                        in 2.6, try removing it.  */
1577                     || DECL_SOURCE_LINE (decl) == 0))
1578               {
1579                 tree name = TYPE_NAME (type);
1580                 if (TREE_CODE (name) == TYPE_DECL)
1581                   name = DECL_NAME (name);
1582
1583                 current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1584                 current_sym_value = 0;
1585                 current_sym_addr = 0;
1586                 current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);
1587
1588                 fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,
1589                          IDENTIFIER_POINTER (name));
1590                 dbxout_type (type, 1, 0);
1591                 dbxout_finish_symbol (NULL_TREE);
1592               }
1593
1594             /* Output typedef name.  */
1595             fprintf (asmfile, "%s \"%s:", ASM_STABS_OP,
1596                      IDENTIFIER_POINTER (DECL_NAME (decl)));
1597
1598             /* Short cut way to output a tag also.  */
1599             if ((TREE_CODE (type) == RECORD_TYPE
1600                  || TREE_CODE (type) == UNION_TYPE
1601                  || TREE_CODE (type) == QUAL_UNION_TYPE)
1602                 && TYPE_NAME (type) == decl)
1603               {
1604                 if (use_gnu_debug_info_extensions && have_used_extensions)
1605                   {
1606                     putc ('T', asmfile);
1607                     TREE_ASM_WRITTEN (TYPE_NAME (type)) = 1;
1608                   }
1609 #if 0 /* Now we generate the tag for this case up above.  */
1610                 else
1611                   tag_needed = 1;
1612 #endif
1613               }
1614
1615             putc ('t', asmfile);
1616             current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1617
1618             dbxout_type (type, 1, 0);
1619             dbxout_finish_symbol (decl);
1620             did_output = 1;
1621           }
1622
1623         /* Don't output a tag if this is an incomplete type (TYPE_SIZE is
1624            zero).  This prevents the sun4 Sun OS 4.x dbx from crashing.  */ 
1625
1626         if (tag_needed && TYPE_NAME (type) != 0 && TYPE_SIZE (type) != 0
1627             && !TREE_ASM_WRITTEN (TYPE_NAME (type)))
1628           {
1629             /* For a TYPE_DECL with no name, but the type has a name,
1630                output a tag.
1631                This is what represents `struct foo' with no typedef.  */
1632             /* In C++, the name of a type is the corresponding typedef.
1633                In C, it is an IDENTIFIER_NODE.  */
1634             tree name = TYPE_NAME (type);
1635             if (TREE_CODE (name) == TYPE_DECL)
1636               name = DECL_NAME (name);
1637
1638             current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1639             current_sym_value = 0;
1640             current_sym_addr = 0;
1641             current_sym_nchars = 2 + IDENTIFIER_LENGTH (name);
1642
1643             fprintf (asmfile, "%s \"%s:T", ASM_STABS_OP,
1644                      IDENTIFIER_POINTER (name));
1645             dbxout_type (type, 1, 0);
1646             dbxout_finish_symbol (NULL_TREE);
1647             did_output = 1;
1648           }
1649
1650         /* If an enum type has no name, it cannot be referred to,
1651            but we must output it anyway, since the enumeration constants
1652            can be referred to.  */
1653         if (!did_output && TREE_CODE (type) == ENUMERAL_TYPE)
1654           {
1655             current_sym_code = DBX_TYPE_DECL_STABS_CODE;
1656             current_sym_value = 0;
1657             current_sym_addr = 0;
1658             current_sym_nchars = 2;
1659
1660             /* Some debuggers fail when given NULL names, so give this a
1661                harmless name of ` '.  */
1662             fprintf (asmfile, "%s \" :T", ASM_STABS_OP);
1663             dbxout_type (type, 1, 0);
1664             dbxout_finish_symbol (NULL_TREE);
1665           }
1666
1667         /* Prevent duplicate output of a typedef.  */
1668         TREE_ASM_WRITTEN (decl) = 1;
1669         break;
1670       }
1671
1672     case PARM_DECL:
1673       /* Parm decls go in their own separate chains
1674          and are output by dbxout_reg_parms and dbxout_parms.  */
1675       abort ();
1676
1677     case RESULT_DECL:
1678       /* Named return value, treat like a VAR_DECL.  */
1679     case VAR_DECL:
1680       if (DECL_RTL (decl) == 0)
1681         return;
1682       /* Don't mention a variable that is external.
1683          Let the file that defines it describe it.  */
1684       if (DECL_EXTERNAL (decl))
1685         break;
1686
1687       /* If the variable is really a constant
1688          and not written in memory, inform the debugger.  */
1689       if (TREE_STATIC (decl) && TREE_READONLY (decl)
1690           && DECL_INITIAL (decl) != 0
1691           && ! TREE_ASM_WRITTEN (decl)
1692           && (DECL_FIELD_CONTEXT (decl) == NULL_TREE
1693               || TREE_CODE (DECL_FIELD_CONTEXT (decl)) == BLOCK))
1694         {
1695           if (TREE_PUBLIC (decl) == 0)
1696             {
1697               /* The sun4 assembler does not grok this.  */
1698               char *name = IDENTIFIER_POINTER (DECL_NAME (decl));
1699               if (TREE_CODE (TREE_TYPE (decl)) == INTEGER_TYPE
1700                   || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE)
1701                 {
1702                   HOST_WIDE_INT ival = TREE_INT_CST_LOW (DECL_INITIAL (decl));
1703 #ifdef DBX_OUTPUT_CONSTANT_SYMBOL
1704                   DBX_OUTPUT_CONSTANT_SYMBOL (asmfile, name, ival);
1705 #else
1706                   fprintf (asmfile, "%s \"%s:c=i%d\",0x%x,0,0,0\n",
1707                            ASM_STABS_OP, name, ival, N_LSYM);
1708 #endif
1709                   return;
1710                 }
1711               else if (TREE_CODE (TREE_TYPE (decl)) == REAL_TYPE)
1712                 {
1713                   /* don't know how to do this yet.  */
1714                 }
1715               break;
1716             }
1717           /* else it is something we handle like a normal variable.  */
1718         }
1719
1720       DECL_RTL (decl) = eliminate_regs (DECL_RTL (decl), 0, NULL_RTX);
1721 #ifdef LEAF_REG_REMAP
1722       if (leaf_function)
1723         leaf_renumber_regs_insn (DECL_RTL (decl));
1724 #endif
1725
1726       dbxout_symbol_location (decl, type, 0, DECL_RTL (decl));
1727     }
1728 }
1729 \f
1730 /* Output the stab for DECL, a VAR_DECL, RESULT_DECL or PARM_DECL.
1731    Add SUFFIX to its name, if SUFFIX is not 0.
1732    Describe the variable as residing in HOME
1733    (usually HOME is DECL_RTL (DECL), but not always).  */
1734
1735 static void
1736 dbxout_symbol_location (decl, type, suffix, home)
1737      tree decl, type;
1738      char *suffix;
1739      rtx home;
1740 {
1741   int letter = 0;
1742   int regno = -1;
1743
1744   /* Don't mention a variable at all
1745      if it was completely optimized into nothingness.
1746      
1747      If the decl was from an inline function, then it's rtl
1748      is not identically the rtl that was used in this
1749      particular compilation.  */
1750   if (GET_CODE (home) == REG)
1751     {
1752       regno = REGNO (home);
1753       if (regno >= FIRST_PSEUDO_REGISTER)
1754         return;
1755     }
1756   else if (GET_CODE (home) == SUBREG)
1757     {
1758       rtx value = home;
1759       int offset = 0;
1760       while (GET_CODE (value) == SUBREG)
1761         {
1762           offset += SUBREG_WORD (value);
1763           value = SUBREG_REG (value);
1764         }
1765       if (GET_CODE (value) == REG)
1766         {
1767           regno = REGNO (value);
1768           if (regno >= FIRST_PSEUDO_REGISTER)
1769             return;
1770           regno += offset;
1771         }
1772       alter_subreg (home);
1773     }
1774
1775   /* The kind-of-variable letter depends on where
1776      the variable is and on the scope of its name:
1777      G and N_GSYM for static storage and global scope,
1778      S for static storage and file scope,
1779      V for static storage and local scope,
1780      for those two, use N_LCSYM if data is in bss segment,
1781      N_STSYM if in data segment, N_FUN otherwise.
1782      (We used N_FUN originally, then changed to N_STSYM
1783      to please GDB.  However, it seems that confused ld.
1784      Now GDB has been fixed to like N_FUN, says Kingdon.)
1785      no letter at all, and N_LSYM, for auto variable,
1786      r and N_RSYM for register variable.  */
1787
1788   if (GET_CODE (home) == MEM
1789       && GET_CODE (XEXP (home, 0)) == SYMBOL_REF)
1790     {
1791       if (TREE_PUBLIC (decl))
1792         {
1793           letter = 'G';
1794           current_sym_code = N_GSYM;
1795         }
1796       else
1797         {
1798           current_sym_addr = XEXP (home, 0);
1799
1800           letter = decl_function_context (decl) ? 'V' : 'S';
1801
1802           if (!DECL_INITIAL (decl))
1803             current_sym_code = N_LCSYM;
1804           else if (DECL_IN_TEXT_SECTION (decl))
1805             /* This is not quite right, but it's the closest
1806                of all the codes that Unix defines.  */
1807             current_sym_code = DBX_STATIC_CONST_VAR_CODE;
1808           else
1809             {
1810               /* Ultrix `as' seems to need this.  */
1811 #ifdef DBX_STATIC_STAB_DATA_SECTION
1812               data_section ();
1813 #endif
1814               current_sym_code = N_STSYM;
1815             }
1816         }
1817     }
1818   else if (regno >= 0)
1819     {
1820       letter = 'r';
1821       current_sym_code = N_RSYM;
1822       current_sym_value = DBX_REGISTER_NUMBER (regno);
1823     }
1824   else if (GET_CODE (home) == MEM
1825            && (GET_CODE (XEXP (home, 0)) == MEM
1826                || (GET_CODE (XEXP (home, 0)) == REG
1827                    && REGNO (XEXP (home, 0)) != HARD_FRAME_POINTER_REGNUM)))
1828     /* If the value is indirect by memory or by a register
1829        that isn't the frame pointer
1830        then it means the object is variable-sized and address through
1831        that register or stack slot.  DBX has no way to represent this
1832        so all we can do is output the variable as a pointer.
1833        If it's not a parameter, ignore it.
1834        (VAR_DECLs like this can be made by integrate.c.)  */
1835     {
1836       if (GET_CODE (XEXP (home, 0)) == REG)
1837         {
1838           letter = 'r';
1839           current_sym_code = N_RSYM;
1840           current_sym_value = DBX_REGISTER_NUMBER (REGNO (XEXP (home, 0)));
1841         }
1842       else
1843         {
1844           current_sym_code = N_LSYM;
1845           /* RTL looks like (MEM (MEM (PLUS (REG...) (CONST_INT...)))).
1846              We want the value of that CONST_INT.  */
1847           current_sym_value
1848             = DEBUGGER_AUTO_OFFSET (XEXP (XEXP (home, 0), 0));
1849         }
1850
1851       /* Effectively do build_pointer_type, but don't cache this type,
1852          since it might be temporary whereas the type it points to
1853          might have been saved for inlining.  */
1854       /* Don't use REFERENCE_TYPE because dbx can't handle that.  */
1855       type = make_node (POINTER_TYPE);
1856       TREE_TYPE (type) = TREE_TYPE (decl);
1857     }
1858   else if (GET_CODE (home) == MEM
1859            && GET_CODE (XEXP (home, 0)) == REG)
1860     {
1861       current_sym_code = N_LSYM;
1862       current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0));
1863     }
1864   else if (GET_CODE (home) == MEM
1865            && GET_CODE (XEXP (home, 0)) == PLUS
1866            && GET_CODE (XEXP (XEXP (home, 0), 1)) == CONST_INT)
1867     {
1868       current_sym_code = N_LSYM;
1869       /* RTL looks like (MEM (PLUS (REG...) (CONST_INT...)))
1870          We want the value of that CONST_INT.  */
1871       current_sym_value = DEBUGGER_AUTO_OFFSET (XEXP (home, 0));
1872     }
1873   else if (GET_CODE (home) == MEM
1874            && GET_CODE (XEXP (home, 0)) == CONST)
1875     {
1876       /* Handle an obscure case which can arise when optimizing and
1877          when there are few available registers.  (This is *always*
1878          the case for i386/i486 targets).  The RTL looks like
1879          (MEM (CONST ...)) even though this variable is a local `auto'
1880          or a local `register' variable.  In effect, what has happened
1881          is that the reload pass has seen that all assignments and
1882          references for one such a local variable can be replaced by
1883          equivalent assignments and references to some static storage
1884          variable, thereby avoiding the need for a register.  In such
1885          cases we're forced to lie to debuggers and tell them that
1886          this variable was itself `static'.  */
1887       current_sym_code = N_LCSYM;
1888       letter = 'V';
1889       current_sym_addr = XEXP (XEXP (home, 0), 0);
1890     }
1891   else if (GET_CODE (home) == CONCAT)
1892     {
1893       tree subtype = TREE_TYPE (type);
1894
1895       /* If the variable's storage is in two parts,
1896          output each as a separate stab with a modified name.  */
1897       if (WORDS_BIG_ENDIAN)
1898         dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 0));
1899       else
1900         dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 0));
1901
1902       /* Cast avoids warning in old compilers.  */
1903       current_sym_code = (STAB_CODE_TYPE) 0;
1904       current_sym_value = 0;
1905       current_sym_addr = 0;
1906       dbxout_prepare_symbol (decl);
1907
1908       if (WORDS_BIG_ENDIAN)
1909         dbxout_symbol_location (decl, subtype, "$real", XEXP (home, 1));
1910       else
1911         dbxout_symbol_location (decl, subtype, "$imag", XEXP (home, 1));
1912       return;
1913     }
1914   else
1915     /* Address might be a MEM, when DECL is a variable-sized object.
1916        Or it might be const0_rtx, meaning previous passes
1917        want us to ignore this variable.  */
1918     return;
1919
1920   /* Ok, start a symtab entry and output the variable name.  */
1921   FORCE_TEXT;
1922
1923 #ifdef DBX_STATIC_BLOCK_START
1924   DBX_STATIC_BLOCK_START (asmfile, current_sym_code);
1925 #endif
1926
1927   dbxout_symbol_name (decl, suffix, letter);
1928   dbxout_type (type, 0, 0);
1929   dbxout_finish_symbol (decl);
1930
1931 #ifdef DBX_STATIC_BLOCK_END
1932   DBX_STATIC_BLOCK_END (asmfile, current_sym_code);
1933 #endif
1934 }
1935 \f
1936 /* Output the symbol name of DECL for a stabs, with suffix SUFFIX.
1937    Then output LETTER to indicate the kind of location the symbol has.  */
1938
1939 static void
1940 dbxout_symbol_name (decl, suffix, letter)
1941      tree decl;
1942      char *suffix;
1943      int letter;
1944 {
1945   /* One slight hitch: if this is a VAR_DECL which is a static
1946      class member, we must put out the mangled name instead of the
1947      DECL_NAME.  */
1948
1949   char *name;
1950   /* Note also that static member (variable) names DO NOT begin
1951      with underscores in .stabs directives.  */
1952   if (DECL_LANG_SPECIFIC (decl))
1953     name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl));
1954   else
1955     name = IDENTIFIER_POINTER (DECL_NAME (decl));
1956   if (name == 0)
1957     name = "(anon)";
1958   fprintf (asmfile, "%s \"%s%s:", ASM_STABS_OP, name,
1959            (suffix ? suffix : ""));
1960
1961   if (letter) putc (letter, asmfile);
1962 }
1963
1964 static void
1965 dbxout_prepare_symbol (decl)
1966      tree decl;
1967 {
1968 #ifdef WINNING_GDB
1969   char *filename = DECL_SOURCE_FILE (decl);
1970
1971   dbxout_source_file (asmfile, filename);
1972 #endif
1973 }
1974
1975 static void
1976 dbxout_finish_symbol (sym)
1977      tree sym;
1978 {
1979 #ifdef DBX_FINISH_SYMBOL
1980   DBX_FINISH_SYMBOL (sym);
1981 #else
1982   int line = 0;
1983   if (use_gnu_debug_info_extensions && sym != 0)
1984     line = DECL_SOURCE_LINE (sym);
1985
1986   fprintf (asmfile, "\",%d,0,%d,", current_sym_code, line);
1987   if (current_sym_addr)
1988     output_addr_const (asmfile, current_sym_addr);
1989   else
1990     fprintf (asmfile, "%d", current_sym_value);
1991   putc ('\n', asmfile);
1992 #endif
1993 }
1994
1995 /* Output definitions of all the decls in a chain.  */
1996
1997 void
1998 dbxout_syms (syms)
1999      tree syms;
2000 {
2001   while (syms)
2002     {
2003       dbxout_symbol (syms, 1);
2004       syms = TREE_CHAIN (syms);
2005     }
2006 }
2007 \f
2008 /* The following two functions output definitions of function parameters.
2009    Each parameter gets a definition locating it in the parameter list.
2010    Each parameter that is a register variable gets a second definition
2011    locating it in the register.
2012
2013    Printing or argument lists in gdb uses the definitions that
2014    locate in the parameter list.  But reference to the variable in
2015    expressions uses preferentially the definition as a register.  */
2016
2017 /* Output definitions, referring to storage in the parmlist,
2018    of all the parms in PARMS, which is a chain of PARM_DECL nodes.  */
2019
2020 void
2021 dbxout_parms (parms)
2022      tree parms;
2023 {
2024   for (; parms; parms = TREE_CHAIN (parms))
2025     if (DECL_NAME (parms) && TREE_TYPE (parms) != error_mark_node)
2026       {
2027         dbxout_prepare_symbol (parms);
2028
2029         /* Perform any necessary register eliminations on the parameter's rtl,
2030            so that the debugging output will be accurate.  */
2031         DECL_INCOMING_RTL (parms)
2032           = eliminate_regs (DECL_INCOMING_RTL (parms), 0, NULL_RTX);
2033         DECL_RTL (parms) = eliminate_regs (DECL_RTL (parms), 0, NULL_RTX);
2034 #ifdef LEAF_REG_REMAP
2035         if (leaf_function)
2036           {
2037             leaf_renumber_regs_insn (DECL_INCOMING_RTL (parms));
2038             leaf_renumber_regs_insn (DECL_RTL (parms));
2039           }
2040 #endif
2041
2042         if (PARM_PASSED_IN_MEMORY (parms))
2043           {
2044             rtx addr = XEXP (DECL_INCOMING_RTL (parms), 0);
2045
2046             /* ??? Here we assume that the parm address is indexed
2047                off the frame pointer or arg pointer.
2048                If that is not true, we produce meaningless results,
2049                but do not crash.  */
2050             if (GET_CODE (addr) == PLUS
2051                 && GET_CODE (XEXP (addr, 1)) == CONST_INT)
2052               current_sym_value = INTVAL (XEXP (addr, 1));
2053             else
2054               current_sym_value = 0;
2055
2056             current_sym_code = N_PSYM;
2057             current_sym_addr = 0;
2058
2059             FORCE_TEXT;
2060             if (DECL_NAME (parms))
2061               {
2062                 current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
2063
2064                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2065                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2066                          DBX_MEMPARM_STABS_LETTER);
2067               }
2068             else
2069               {
2070                 current_sym_nchars = 8;
2071                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2072                          DBX_MEMPARM_STABS_LETTER);
2073               }
2074
2075             if (GET_CODE (DECL_RTL (parms)) == REG
2076                 && REGNO (DECL_RTL (parms)) >= 0
2077                 && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
2078               dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
2079             else
2080               {
2081                 int original_value = current_sym_value;
2082
2083                 /* This is the case where the parm is passed as an int or double
2084                    and it is converted to a char, short or float and stored back
2085                    in the parmlist.  In this case, describe the parm
2086                    with the variable's declared type, and adjust the address
2087                    if the least significant bytes (which we are using) are not
2088                    the first ones.  */
2089 #if BYTES_BIG_ENDIAN
2090                 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
2091                   current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
2092                                         - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
2093 #endif
2094
2095                 if (GET_CODE (DECL_RTL (parms)) == MEM
2096                     && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
2097                     && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
2098                     && INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == current_sym_value)
2099                   dbxout_type (TREE_TYPE (parms), 0, 0);
2100                 else
2101                   {
2102                     current_sym_value = original_value;
2103                     dbxout_type (DECL_ARG_TYPE (parms), 0, 0);
2104                   }
2105               }
2106             current_sym_value = DEBUGGER_ARG_OFFSET (current_sym_value, addr);
2107             dbxout_finish_symbol (parms);
2108           }
2109         else if (GET_CODE (DECL_RTL (parms)) == REG)
2110           {
2111             rtx best_rtl;
2112             char regparm_letter;
2113             tree parm_type;
2114             /* Parm passed in registers and lives in registers or nowhere.  */
2115
2116             current_sym_code = DBX_REGPARM_STABS_CODE;
2117             regparm_letter = DBX_REGPARM_STABS_LETTER;
2118             current_sym_addr = 0;
2119
2120             /* If parm lives in a register, use that register;
2121                pretend the parm was passed there.  It would be more consistent
2122                to describe the register where the parm was passed,
2123                but in practice that register usually holds something else.
2124
2125                If we use DECL_RTL, then we must use the declared type of
2126                the variable, not the type that it arrived in.  */
2127             if (REGNO (DECL_RTL (parms)) >= 0
2128                 && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
2129               {
2130                 best_rtl = DECL_RTL (parms);
2131                 parm_type = TREE_TYPE (parms);
2132               }
2133             /* If the parm lives nowhere,
2134                use the register where it was passed.  */
2135             else
2136               {
2137                 best_rtl = DECL_INCOMING_RTL (parms);
2138                 parm_type = DECL_ARG_TYPE (parms);
2139               }
2140             current_sym_value = DBX_REGISTER_NUMBER (REGNO (best_rtl));
2141
2142             FORCE_TEXT;
2143             if (DECL_NAME (parms))
2144               {
2145                 current_sym_nchars = 2 + IDENTIFIER_LENGTH (DECL_NAME (parms));
2146                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2147                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2148                          regparm_letter);
2149               }
2150             else
2151               {
2152                 current_sym_nchars = 8;
2153                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2154                          regparm_letter);
2155               }
2156
2157             dbxout_type (parm_type, 0, 0);
2158             dbxout_finish_symbol (parms);
2159           }
2160         else if (GET_CODE (DECL_RTL (parms)) == MEM
2161                  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
2162                  && REGNO (XEXP (DECL_RTL (parms), 0)) != HARD_FRAME_POINTER_REGNUM
2163                  && REGNO (XEXP (DECL_RTL (parms), 0)) != STACK_POINTER_REGNUM
2164 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
2165                  && REGNO (XEXP (DECL_RTL (parms), 0)) != ARG_POINTER_REGNUM
2166 #endif
2167                  )
2168           {
2169             /* Parm was passed via invisible reference.
2170                That is, its address was passed in a register.
2171                Output it as if it lived in that register.
2172                The debugger will know from the type
2173                that it was actually passed by invisible reference.  */
2174
2175             char regparm_letter;
2176             /* Parm passed in registers and lives in registers or nowhere.  */
2177
2178             current_sym_code = DBX_REGPARM_STABS_CODE;
2179             regparm_letter = DBX_REGPARM_STABS_LETTER;
2180
2181             /* DECL_RTL looks like (MEM (REG...).  Get the register number.  */
2182             current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0));
2183             current_sym_addr = 0;
2184
2185             FORCE_TEXT;
2186             if (DECL_NAME (parms))
2187               {
2188                 current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
2189
2190                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2191                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2192                          DBX_REGPARM_STABS_LETTER);
2193               }
2194             else
2195               {
2196                 current_sym_nchars = 8;
2197                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2198                          DBX_REGPARM_STABS_LETTER);
2199               }
2200
2201             dbxout_type (TREE_TYPE (parms), 0, 0);
2202             dbxout_finish_symbol (parms);
2203           }
2204         else if (GET_CODE (DECL_RTL (parms)) == MEM
2205                  && XEXP (DECL_RTL (parms), 0) != const0_rtx
2206                  /* ??? A constant address for a parm can happen
2207                     when the reg it lives in is equiv to a constant in memory.
2208                     Should make this not happen, after 2.4.  */
2209                  && ! CONSTANT_P (XEXP (DECL_RTL (parms), 0)))
2210           {
2211             /* Parm was passed in registers but lives on the stack.  */
2212
2213             current_sym_code = N_PSYM;
2214             /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))),
2215                in which case we want the value of that CONST_INT,
2216                or (MEM (REG ...)) or (MEM (MEM ...)),
2217                in which case we use a value of zero.  */
2218             if (GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG
2219                 || GET_CODE (XEXP (DECL_RTL (parms), 0)) == MEM)
2220               current_sym_value = 0;
2221             else
2222               current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1));
2223             current_sym_addr = 0;
2224
2225             FORCE_TEXT;
2226             if (DECL_NAME (parms))
2227               {
2228                 current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
2229
2230                 fprintf (asmfile, "%s \"%s:%c", ASM_STABS_OP,
2231                          IDENTIFIER_POINTER (DECL_NAME (parms)),
2232                          DBX_MEMPARM_STABS_LETTER);
2233               }
2234             else
2235               {
2236                 current_sym_nchars = 8;
2237                 fprintf (asmfile, "%s \"(anon):%c", ASM_STABS_OP,
2238                 DBX_MEMPARM_STABS_LETTER);
2239               }
2240
2241             current_sym_value
2242               = DEBUGGER_ARG_OFFSET (current_sym_value,
2243                                      XEXP (DECL_RTL (parms), 0));
2244             dbxout_type (TREE_TYPE (parms), 0, 0);
2245             dbxout_finish_symbol (parms);
2246           }
2247       }
2248 }
2249
2250 /* Output definitions for the places where parms live during the function,
2251    when different from where they were passed, when the parms were passed
2252    in memory.
2253
2254    It is not useful to do this for parms passed in registers
2255    that live during the function in different registers, because it is
2256    impossible to look in the passed register for the passed value,
2257    so we use the within-the-function register to begin with.
2258
2259    PARMS is a chain of PARM_DECL nodes.  */
2260
2261 void
2262 dbxout_reg_parms (parms)
2263      tree parms;
2264 {
2265   for (; parms; parms = TREE_CHAIN (parms))
2266     if (DECL_NAME (parms))
2267       {
2268         dbxout_prepare_symbol (parms);
2269
2270         /* Report parms that live in registers during the function
2271            but were passed in memory.  */
2272         if (GET_CODE (DECL_RTL (parms)) == REG
2273             && REGNO (DECL_RTL (parms)) >= 0
2274             && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER
2275             && PARM_PASSED_IN_MEMORY (parms))
2276           dbxout_symbol_location (parms, TREE_TYPE (parms),
2277                                   0, DECL_RTL (parms));
2278         else if (GET_CODE (DECL_RTL (parms)) == CONCAT
2279                  && PARM_PASSED_IN_MEMORY (parms))
2280           dbxout_symbol_location (parms, TREE_TYPE (parms),
2281                                   0, DECL_RTL (parms));
2282         /* Report parms that live in memory but not where they were passed.  */
2283         else if (GET_CODE (DECL_RTL (parms)) == MEM
2284                  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
2285                  && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
2286                  && PARM_PASSED_IN_MEMORY (parms)
2287                  && ! rtx_equal_p (DECL_RTL (parms), DECL_INCOMING_RTL (parms)))
2288           {
2289 #if 0 /* ??? It is not clear yet what should replace this.  */
2290             int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
2291             /* A parm declared char is really passed as an int,
2292                so it occupies the least significant bytes.
2293                On a big-endian machine those are not the low-numbered ones.  */
2294 #if BYTES_BIG_ENDIAN
2295             if (offset != -1 && TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
2296               offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
2297                          - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
2298 #endif
2299             if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset) {...}
2300 #endif
2301             dbxout_symbol_location (parms, TREE_TYPE (parms),
2302                                     0, DECL_RTL (parms));
2303           }
2304 #if 0
2305         else if (GET_CODE (DECL_RTL (parms)) == MEM
2306                  && GET_CODE (XEXP (DECL_RTL (parms), 0)) == REG)
2307           {
2308             /* Parm was passed via invisible reference.
2309                That is, its address was passed in a register.
2310                Output it as if it lived in that register.
2311                The debugger will know from the type
2312                that it was actually passed by invisible reference.  */
2313
2314             current_sym_code = N_RSYM;
2315
2316             /* DECL_RTL looks like (MEM (REG...).  Get the register number.  */
2317             current_sym_value = REGNO (XEXP (DECL_RTL (parms), 0));
2318             current_sym_addr = 0;
2319
2320             FORCE_TEXT;
2321             if (DECL_NAME (parms))
2322               {
2323                 current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
2324
2325                 fprintf (asmfile, "%s \"%s:r", ASM_STABS_OP,
2326                          IDENTIFIER_POINTER (DECL_NAME (parms)));
2327               }
2328             else
2329               {
2330                 current_sym_nchars = 8;
2331                 fprintf (asmfile, "%s \"(anon):r", ASM_STABS_OP);
2332               }
2333
2334             dbxout_type (TREE_TYPE (parms), 0, 0);
2335             dbxout_finish_symbol (parms);
2336           }
2337 #endif
2338       }
2339 }
2340 \f
2341 /* Given a chain of ..._TYPE nodes (as come in a parameter list),
2342    output definitions of those names, in raw form */
2343
2344 void
2345 dbxout_args (args)
2346      tree args;
2347 {
2348   while (args)
2349     {
2350       putc (',', asmfile);
2351       dbxout_type (TREE_VALUE (args), 0, 0);
2352       CHARS (1);
2353       args = TREE_CHAIN (args);
2354     }
2355 }
2356 \f
2357 /* Given a chain of ..._TYPE nodes,
2358    find those which have typedef names and output those names.
2359    This is to ensure those types get output.  */
2360
2361 void
2362 dbxout_types (types)
2363      register tree types;
2364 {
2365   while (types)
2366     {
2367       if (TYPE_NAME (types)
2368           && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL
2369           && ! TREE_ASM_WRITTEN (TYPE_NAME (types)))
2370         dbxout_symbol (TYPE_NAME (types), 1);
2371       types = TREE_CHAIN (types);
2372     }
2373 }
2374 \f
2375 /* Output everything about a symbol block (a BLOCK node
2376    that represents a scope level),
2377    including recursive output of contained blocks.
2378
2379    BLOCK is the BLOCK node.
2380    DEPTH is its depth within containing symbol blocks.
2381    ARGS is usually zero; but for the outermost block of the
2382    body of a function, it is a chain of PARM_DECLs for the function parameters.
2383    We output definitions of all the register parms
2384    as if they were local variables of that block.
2385
2386    If -g1 was used, we count blocks just the same, but output nothing
2387    except for the outermost block.
2388
2389    Actually, BLOCK may be several blocks chained together.
2390    We handle them all in sequence.  */
2391
2392 static void
2393 dbxout_block (block, depth, args)
2394      register tree block;
2395      int depth;
2396      tree args;
2397 {
2398   int blocknum;
2399
2400   while (block)
2401     {
2402       /* Ignore blocks never expanded or otherwise marked as real.  */
2403       if (TREE_USED (block))
2404         {
2405 #ifndef DBX_LBRAC_FIRST
2406           /* In dbx format, the syms of a block come before the N_LBRAC.  */
2407           if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
2408             dbxout_syms (BLOCK_VARS (block));
2409           if (args)
2410             dbxout_reg_parms (args);
2411 #endif
2412
2413           /* Now output an N_LBRAC symbol to represent the beginning of
2414              the block.  Use the block's tree-walk order to generate
2415              the assembler symbols LBBn and LBEn
2416              that final will define around the code in this block.  */
2417           if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE)
2418             {
2419               char buf[20];
2420               blocknum = next_block_number++;
2421               ASM_GENERATE_INTERNAL_LABEL (buf, "LBB", blocknum);
2422
2423               if (BLOCK_HANDLER_BLOCK (block))
2424                 {
2425                   /* A catch block.  Must precede N_LBRAC.  */
2426                   tree decl = BLOCK_VARS (block);
2427                   while (decl)
2428                     {
2429 #ifdef DBX_OUTPUT_CATCH
2430                       DBX_OUTPUT_CATCH (asmfile, decl, buf);
2431 #else
2432                       fprintf (asmfile, "%s \"%s:C1\",%d,0,0,", ASM_STABS_OP,
2433                                IDENTIFIER_POINTER (DECL_NAME (decl)), N_CATCH);
2434                       assemble_name (asmfile, buf);
2435                       fprintf (asmfile, "\n");
2436 #endif
2437                       decl = TREE_CHAIN (decl);
2438                     }
2439                 }
2440
2441 #ifdef DBX_OUTPUT_LBRAC
2442               DBX_OUTPUT_LBRAC (asmfile, buf);
2443 #else
2444               fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_LBRAC);
2445               assemble_name (asmfile, buf);
2446 #if DBX_BLOCKS_FUNCTION_RELATIVE
2447               fputc ('-', asmfile);
2448               assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2449 #endif
2450               fprintf (asmfile, "\n");
2451 #endif
2452             }
2453           else if (depth > 0)
2454             /* Count blocks the same way regardless of debug_info_level.  */
2455             next_block_number++;
2456
2457 #ifdef DBX_LBRAC_FIRST
2458           /* On some weird machines, the syms of a block
2459              come after the N_LBRAC.  */
2460           if (debug_info_level != DINFO_LEVEL_TERSE || depth == 0)
2461             dbxout_syms (BLOCK_VARS (block));
2462           if (args)
2463             dbxout_reg_parms (args);
2464 #endif
2465
2466           /* Output the subblocks.  */
2467           dbxout_block (BLOCK_SUBBLOCKS (block), depth + 1, NULL_TREE);
2468
2469           /* Refer to the marker for the end of the block.  */
2470           if (depth > 0 && debug_info_level != DINFO_LEVEL_TERSE)
2471             {
2472               char buf[20];
2473               ASM_GENERATE_INTERNAL_LABEL (buf, "LBE", blocknum);
2474 #ifdef DBX_OUTPUT_RBRAC
2475               DBX_OUTPUT_RBRAC (asmfile, buf);
2476 #else
2477               fprintf (asmfile, "%s %d,0,0,", ASM_STABN_OP, N_RBRAC);
2478               assemble_name (asmfile, buf);
2479 #if DBX_BLOCKS_FUNCTION_RELATIVE
2480               fputc ('-', asmfile);
2481               assemble_name (asmfile, XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0));
2482 #endif
2483               fprintf (asmfile, "\n");
2484 #endif
2485             }
2486         }
2487       block = BLOCK_CHAIN (block);
2488     }
2489 }
2490
2491 /* Output the information about a function and its arguments and result.
2492    Usually this follows the function's code,
2493    but on some systems, it comes before.  */
2494
2495 static void
2496 dbxout_really_begin_function (decl)
2497      tree decl;
2498 {
2499   dbxout_symbol (decl, 0);
2500   dbxout_parms (DECL_ARGUMENTS (decl));
2501   if (DECL_NAME (DECL_RESULT (decl)) != 0)
2502     dbxout_symbol (DECL_RESULT (decl), 1);
2503 }
2504
2505 /* Called at beginning of output of function definition.  */
2506
2507 void
2508 dbxout_begin_function (decl)
2509      tree decl;
2510 {
2511 #ifdef DBX_FUNCTION_FIRST
2512   dbxout_really_begin_function (decl);
2513 #endif
2514 }
2515
2516 /* Output dbx data for a function definition.
2517    This includes a definition of the function name itself (a symbol),
2518    definitions of the parameters (locating them in the parameter list)
2519    and then output the block that makes up the function's body
2520    (including all the auto variables of the function).  */
2521
2522 void
2523 dbxout_function (decl)
2524      tree decl;
2525 {
2526 #ifndef DBX_FUNCTION_FIRST
2527   dbxout_really_begin_function (decl);
2528 #endif
2529   dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
2530 #ifdef DBX_OUTPUT_FUNCTION_END
2531   DBX_OUTPUT_FUNCTION_END (asmfile, decl);
2532 #endif
2533 }
2534 #endif /* DBX_DEBUGGING_INFO */