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