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