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