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