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