OSDN Git Service

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