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