source: trunk/third/gcc/dbxout.c @ 8834

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