OSDN Git Service

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