OSDN Git Service

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