|
|
1.1 root 1: /* Output dbx-format symbol table information from GNU compiler.
2: Copyright (C) 1987 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is distributed in the hope that it will be useful,
7: but WITHOUT ANY WARRANTY. No author or distributor
8: accepts responsibility to anyone for the consequences of using it
9: or for whether it serves any particular purpose or works at all,
10: unless he says so in writing. Refer to the GNU CC General Public
11: License for full details.
12:
13: Everyone is granted permission to copy, modify and redistribute
14: GNU CC, but only under the conditions described in the
15: GNU CC General Public License. A copy of this license is
16: supposed to have been given to you along with GNU CC so you
17: can know your rights and responsibilities. It should be in a
18: file named COPYING. Among other things, the copyright notice
19: and this notice must be preserved on all copies. */
20:
21:
22: /* Output dbx-format symbol table data.
23: This consists of many symbol table entries, each of them
24: a .stabs assembler pseudo-op with four operands:
25: a "name" which is really a description of one symbol and its type,
26: a "code", which is a symbol defined in stab.h whose name starts with N_,
27: an unused operand always 0,
28: and a "value" which is an address or an offset.
29: The name is enclosed in doublequote characters.
30:
31: Each function, variable, typedef, and structure tag
32: has a symbol table entry to define it.
33: The beginning and end of each level of name scoping within
34: a function are also marked by special symbol table entries.
35:
36: The "name" consists of the symbol name, a colon, a kind-of-symbol letter,
37: and a data type number. The data type number may be followed by
38: "=" and a type definition; normally this will happen the first time
39: the type number is mentioned. The type definition may refer to
40: other types by number, and those type numbers may be followed
41: by "=" and nested definitions.
42:
43: This can make the "name" quite long.
44: When a name is more than 80 characters, we split the .stabs pseudo-op
45: into two .stabs pseudo-ops, both sharing the same "code" and "value".
46: The first one is marked as continued with a double-backslash at the
47: end of its "name".
48:
49: The kind-of-symbol letter distinguished function names from global
50: variables from file-scope variables from parameters from auto
51: variables in memory from typedef names from register variables.
52: See `dbxout_symbol'.
53:
54: The "code" is mostly redundant with the kind-of-symbol letter
55: that goes in the "name", but not entirely: for symbols located
56: in static storage, the "code" says which segment the address is in,
57: which controls how it is relocated.
58:
59: The "value" for a symbol in static storage
60: is the core address of the symbol (actually, the assembler
61: label for the symbol). For a symbol located in a stack slot
62: it is the stack offset; for one in a register, the register number.
63: For a typedef symbol, it is zero.
64:
65: For more on data type definitions, see `dbxout_type'. */
66:
67: #include "config.h"
68: #include "tree.h"
69: #include "rtl.h"
70: #include "c-tree.h"
71: #include <stdio.h>
72: #include <stab.h>
73:
74: /* Stream for writing to assembler file. */
75:
76: static FILE *asmfile;
77:
78: enum typestatus {TYPE_UNSEEN, TYPE_XREF, TYPE_DEFINED};
79:
80: /* Vector recording the status of describing C data types.
81: When we first notice a data type (a tree node),
82: we assign it a number using next_type_number.
83: That is its index in this vector.
84: The vector element says whether we have yet output
85: the definition of the type. TYPE_XREF says we have
86: output it as a cross-reference only. */
87:
88: enum typestatus *typevec;
89:
90: /* Number of elements of space allocated in `typevec'. */
91:
92: static int typevec_len;
93:
94: /* In dbx output, each type gets a unique number.
95: This is the number for the next type output.
96: The number, once assigned, is in the TYPE_SYMTAB_ADDRESS field. */
97:
98: static int next_type_number;
99:
100: /* In dbx output, we must assign symbol-blocks id numbers
101: in the order in which their beginnings are encountered.
102: We output debugging info that refers to the beginning and
103: end of the ranges of code in each block
104: with assembler labels LBBn and LBEn, where n is the block number.
105: The labels are generated in final, which assigns numbers to the
106: blocks in the same way. */
107:
108: static int next_block_number;
109:
110: /* These variables are for dbxout_symbol to communicate to
111: dbxout_finish_symbol.
112: current_sym_code is the symbol-type-code, a symbol N_... define in stab.h.
113: current_sym_value and current_sym_addr are two ways to address the
114: value to store in the symtab entry.
115: current_sym_addr if nonzero represents the value as an rtx.
116: If that is zero, current_sym_value is used. This is used
117: when the value is an offset (such as for auto variables,
118: register variables and parms). */
119:
120: static int current_sym_code;
121: static int current_sym_value;
122: static rtx current_sym_addr;
123:
124: /* Number of chars of symbol-description generated so far for the
125: current symbol. Used by CHARS and CONTIN. */
126:
127: static int current_sym_nchars;
128:
129: /* Report having output N chars of the current symbol-description. */
130:
131: #define CHARS(N) (current_sym_nchars += (N))
132:
133: /* Break the current symbol-description, generating a continuation,
134: if it has become long. */
135:
136: #define CONTIN \
137: do {if (current_sym_nchars > 80) dbxout_continue ();} while (0)
138:
139: void dbxout_types ();
140: void dbxout_tags ();
141: static void dbxout_type_name ();
142: static void dbxout_type ();
143: static void dbxout_type_def ();
144: static void dbxout_finish_symbol ();
145: static void dbxout_continue ();
146:
147: /* At the beginning of compilation, start writing the symbol table.
148: Initialize `typevec' and output the standard data types of C. */
149:
150: void
151: dbxout_init (asm_file, input_file_name)
152: FILE *asm_file;
153: char *input_file_name;
154: {
155: asmfile = asm_file;
156:
157: typevec_len = 100;
158: typevec = (enum typestatus *) xmalloc (typevec_len * sizeof typevec[0]);
159: bzero (typevec, typevec_len * sizeof typevec[0]);
160:
161: fprintf (asmfile,
162: "Ltext:\t.stabs \"%s\",%d,0,0,Ltext\n",
163: input_filename, N_SO);
164:
165: next_type_number = 1;
166: next_block_number = 2;
167:
168: /* Make sure that types `int' and `char' have numbers 1 and 2.
169: Definitions of other integer types will refer to those numbers. */
170:
171: dbxout_type_def (integer_type_node);
172: dbxout_type_def (char_type_node);
173:
174: /* Get all permanent types not yet gotten
175: and output them. */
176:
177: dbxout_types (get_permanent_types ());
178: }
179:
180: /* Continue a symbol-description that gets too big.
181: End one symbol table entry with a double-backslash
182: and start a new one, eventually producing something like
183: .stabs "start......\\",code,0,value
184: .stabs "...rest",code,0,value */
185:
186: static void
187: dbxout_continue ()
188: {
189: fprintf (asmfile, "\\\\");
190: dbxout_finish_symbol ();
191: fprintf (asmfile, ".stabs \"");
192: current_sym_nchars = 0;
193: }
194:
195: /* Output a reference to a type. If the type has not yet been
196: described in the dbx output, output its definition now.
197: For a type already defined, just refer to its definition
198: using the type number.
199:
200: If FULL is nonzero, and the type has been described only with
201: a forward-reference, output the definition now.
202: If FULL is zero in this case, just refer to the forward-reference
203: using the number previously allocated. */
204:
205: static void
206: dbxout_type (type, full)
207: tree type;
208: int full;
209: {
210: register tree tem;
211:
212: if (TYPE_SYMTAB_ADDRESS (type) == 0)
213: {
214: /* Type has no dbx number assigned. Assign next available number. */
215: TYPE_SYMTAB_ADDRESS (type) = next_type_number++;
216:
217: /* Make sure type vector is long enough to record about this type. */
218:
219: if (next_type_number == typevec_len)
220: {
221: typevec = (enum typestatus *) xrealloc (typevec, typevec_len * 2 * sizeof typevec[0]);
222: bzero (typevec + typevec_len, typevec_len * sizeof typevec[0]);
223: typevec_len *= 2;
224: }
225: }
226:
227: /* Output the number of this type, to refer to it. */
228: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
229: CHARS (3);
230:
231: /* If this type's definition has been output or is now being output,
232: that is all. */
233:
234: switch (typevec[TYPE_SYMTAB_ADDRESS (type)])
235: {
236: case TYPE_UNSEEN:
237: break;
238: case TYPE_XREF:
239: if (! full)
240: return;
241: break;
242: case TYPE_DEFINED:
243: return;
244: }
245:
246: /* Output a definition now. */
247:
248: fprintf (asmfile, "=");
249: CHARS (1);
250:
251: /* Mark it as defined, so that if it is self-referent
252: we will not get into an infinite recursion of definitions. */
253:
254: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
255:
256: switch (TREE_CODE (type))
257: {
258: case VOID_TYPE:
259: /* For a void type, just define it as itself; ie, "5=5".
260: This makes us consider it defined
261: without saying what it is. The debugger will make it
262: a void type when the reference is seen, and nothing will
263: ever override that default. */
264: fprintf (asmfile, "%d", TYPE_SYMTAB_ADDRESS (type));
265: CHARS (3);
266: break;
267:
268: case INTEGER_TYPE:
269: if (type == char_type_node)
270: /* Output the type `char' as a subrange of itself!
271: I don't understand this definition, just copied it
272: from the output of pcc. */
273: fprintf (asmfile, "r2;0;127;");
274: else
275: /* Output other integer types as subranges of `int'. */
276: fprintf (asmfile, "r1;%d;%d;",
277: TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)),
278: TREE_INT_CST_LOW (TYPE_MAX_VALUE (type)));
279: CHARS (25);
280: break;
281:
282: case REAL_TYPE:
283: /* This must be magic. */
284: fprintf (asmfile, "r1;%d;0;",
285: TREE_INT_CST_LOW (size_in_bytes (type)));
286: CHARS (16);
287: break;
288:
289: case ARRAY_TYPE:
290: /* Output "a" followed by a range type definition
291: for the index type of the array
292: followed by a reference to the target-type.
293: ar1;0;N;M for an array of type M and size N. */
294: fprintf (asmfile, "ar1;0;%d;",
295: TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))));
296: CHARS (17);
297: dbxout_type (TREE_TYPE (type), 0);
298: break;
299:
300: case RECORD_TYPE:
301: case UNION_TYPE:
302: /* Output a structure type. */
303: if ((TYPE_NAME (type) != 0 && !full)
304: || TYPE_SIZE (type) == 0)
305: {
306: /* If the type is just a cross reference, output one
307: and mark the type as partially described.
308: If it later becomes defined, we will output
309: its real definition. */
310: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "xs" : "xu");
311: CHARS (3);
312: dbxout_type_name (type);
313: fprintf (asmfile, ":");
314: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
315: break;
316: }
317: tem = size_in_bytes (type);
318: fprintf (asmfile, (TREE_CODE (type) == RECORD_TYPE) ? "s%d" : "u%d",
319: TREE_INT_CST_LOW (tem));
320: CHARS (11);
321: for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
322: /* Output the name, type, position (in bits), size (in bits)
323: of each field. */
324: /* Omit here the nameless fields that are used to skip bits. */
325: if (DECL_NAME (tem) != 0)
326: {
327: CONTIN;
328: fprintf (asmfile, "%s:", IDENTIFIER_POINTER (DECL_NAME (tem)));
329: CHARS (1 + strlen (IDENTIFIER_POINTER (DECL_NAME (tem))));
330: dbxout_type (TREE_TYPE (tem), 0);
331: fprintf (asmfile, ",%d,%d;", DECL_OFFSET (tem),
332: TREE_INT_CST_LOW (DECL_SIZE (tem)) * DECL_SIZE_UNIT (tem));
333: CHARS (23);
334: }
335: putc (';', asmfile);
336: CHARS (1);
337: break;
338:
339: case ENUMERAL_TYPE:
340: if ((TYPE_NAME (type) != 0 && !full)
341: || TYPE_SIZE (type) == 0)
342: {
343: fprintf (asmfile, "xe");
344: CHARS (3);
345: dbxout_type_name (type);
346: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_XREF;
347: fprintf (asmfile, ":");
348: return;
349: }
350: putc ('e', asmfile);
351: CHARS (1);
352: for (tem = TYPE_VALUES (type); tem; tem = TREE_CHAIN (tem))
353: {
354: fprintf (asmfile, "%s:%d,", IDENTIFIER_POINTER (TREE_PURPOSE (tem)),
355: TREE_INT_CST_LOW (TREE_VALUE (tem)));
356: CHARS (11 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (tem))));
357: if (TREE_CHAIN (tem) != 0)
358: CONTIN;
359: }
360: putc (';', asmfile);
361: CHARS (1);
362: break;
363:
364: case POINTER_TYPE:
365: putc ('*', asmfile);
366: CHARS (1);
367: dbxout_type (TREE_TYPE (type), 0);
368: break;
369:
370: case FUNCTION_TYPE:
371: putc ('f', asmfile);
372: CHARS (1);
373: dbxout_type (TREE_TYPE (type), 0);
374: break;
375: }
376: }
377:
378: /* Output the name of type TYPE, with no punctuation.
379: Such names can be set up either by typedef declarations
380: or by struct, enum and union tags. */
381:
382: static void
383: dbxout_type_name (type)
384: register tree type;
385: {
386: register char *name;
387: if (TYPE_NAME (type) == 0)
388: abort ();
389: if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
390: name = IDENTIFIER_POINTER (TYPE_NAME (type));
391: else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
392: name = IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type)));
393: else
394: abort ();
395:
396: fprintf (asmfile, "%s", name);
397: CHARS (strlen (name));
398: }
399:
400: /* Output a .stabs for the symbol defined by DECL,
401: which must be a ..._DECL node in the normal namespace.
402: It may be a CONST_DECL, a FUNCTION_DECL, a PARM_DECL or a VAR_DECL.
403: LOCAL is nonzero if the scope is less than the entire file. */
404:
405: void
406: dbxout_symbol (decl, local)
407: tree decl;
408: int local;
409: {
410: int symcode;
411: int letter;
412:
413: /* If global, first output all types and all
414: struct, enum and union tags that have been created
415: and not yet output. */
416:
417: if (local == 0)
418: {
419: dbxout_tags (gettags ());
420: dbxout_types (get_permanent_types ());
421: }
422:
423: current_sym_code = 0;
424: current_sym_value = 0;
425: current_sym_addr = 0;
426:
427: /* The output will always start with the symbol name,
428: so count that always in the length-output-so-far. */
429:
430: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (decl)));
431:
432: switch (TREE_CODE (decl))
433: {
434: case CONST_DECL:
435: /* Enum values are defined by defining the enum type. */
436: break;
437:
438: case FUNCTION_DECL:
439: if (TREE_EXTERNAL (decl))
440: break;
441: if (GET_CODE (DECL_RTL (decl)) != MEM
442: || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
443: break;
444: fprintf (asmfile, ".stabs \"%s:%c",
445: IDENTIFIER_POINTER (DECL_NAME (decl)),
446: TREE_PUBLIC (decl) ? 'F' : 'f');
447:
448: current_sym_code = N_FUN;
449: current_sym_addr = XEXP (DECL_RTL (decl), 0);
450:
451: if (TREE_TYPE (TREE_TYPE (decl)))
452: dbxout_type (TREE_TYPE (TREE_TYPE (decl)), 0);
453: else
454: dbxout_type (void_type_node, 0);
455: dbxout_finish_symbol ();
456: break;
457:
458: case TYPE_DECL:
459: /* Output typedef name. */
460: fprintf (asmfile, ".stabs \"%s:t",
461: IDENTIFIER_POINTER (DECL_NAME (decl)));
462:
463: current_sym_code = N_LSYM;
464:
465: dbxout_type (TREE_TYPE (decl), 0);
466: dbxout_finish_symbol ();
467: break;
468:
469: case PARM_DECL:
470: /* Parm decls go in their own separate chains
471: and are output by dbxout_reg_parms and dbxout_parms. */
472: abort ();
473:
474: case VAR_DECL:
475: /* Don't mention a variable that is external.
476: Let the file that defines it describe it. */
477: if (TREE_EXTERNAL (decl))
478: break;
479:
480: /* Don't mention a variable at all
481: if it was completely optimized into nothingness. */
482: if (GET_CODE (DECL_RTL (decl)) == REG
483: && REGNO (DECL_RTL (decl)) == -1)
484: break;
485:
486: /* Ok, start a symtab entry and output the variable name. */
487: fprintf (asmfile, ".stabs \"%s:",
488: IDENTIFIER_POINTER (DECL_NAME (decl)));
489:
490: /* The kind-of-variable letter depends on where
491: the variable is and on the scope of its name:
492: G and N_GSYM for static storage and global scope,
493: S for static storage and file scope,
494: v for static storage and local scope,
495: for those two, use N_LCSYM if data is in bss segment,
496: N_STSYM if it is in data segment, or N_FUN if in text segment.
497: no letter at all, and N_LSYM, for auto variable,
498: r and N_RSYM for register variable. */
499:
500: if (GET_CODE (DECL_RTL (decl)) == MEM
501: && GET_CODE (XEXP (DECL_RTL (decl), 0)) == SYMBOL_REF)
502: {
503: if (TREE_PUBLIC (decl))
504: {
505: letter = 'G';
506: current_sym_code = N_GSYM;
507: }
508: else
509: {
510: current_sym_addr = XEXP (DECL_RTL (decl), 0);
511:
512: letter = TREE_PERMANENT (decl) ? 'S' : 'v';
513:
514: if (!DECL_INITIAL (decl))
515: current_sym_code = N_LCSYM;
516: else if (TREE_READONLY (decl) && ! TREE_VOLATILE (decl))
517: /* This is not quite right, but it's the closest
518: of all the codes that Unix defines. */
519: current_sym_code = N_FUN;
520: else
521: current_sym_code = N_STSYM;
522: }
523: putc (letter, asmfile);
524: dbxout_type (TREE_TYPE (decl), 0);
525: dbxout_finish_symbol ();
526: }
527: else
528: {
529: if (GET_CODE (DECL_RTL (decl)) == REG)
530: {
531: letter = 'r';
532: current_sym_code = N_RSYM;
533: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (decl)));
534: }
535: else
536: {
537: letter = 0;
538: current_sym_code = N_LSYM;
539: /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
540: We want the value of that CONST_INT. */
541: current_sym_value = INTVAL (XEXP (XEXP (DECL_RTL (decl), 0), 1));
542: }
543: if (letter) putc (letter, asmfile);
544: dbxout_type (TREE_TYPE (decl), 0);
545: dbxout_finish_symbol ();
546: }
547: break;
548: }
549: }
550:
551: static void
552: dbxout_finish_symbol ()
553: {
554: fprintf (asmfile, "\",%d,0,0,", current_sym_code);
555: if (current_sym_addr)
556: output_addr_const (asmfile, current_sym_addr);
557: else
558: fprintf (asmfile, "%d", current_sym_value);
559: putc ('\n', asmfile);
560: }
561:
562: /* Output definitions of all the decls in a chain. */
563:
564: static void
565: dbxout_syms (syms)
566: tree syms;
567: {
568: while (syms)
569: {
570: dbxout_symbol (syms, 1);
571: syms = TREE_CHAIN (syms);
572: }
573: }
574:
575: /* The following two functions output definitions of function parameters.
576: Each parameter gets a definition locating it in the parameter list.
577: Each parameter that is a register variable gets a second definition
578: locating it in the register.
579:
580: Printing or argument lists in gdb uses the definitions that
581: locate in the parameter list. But reference to the variable in
582: expressions uses preferentially the definition as a register. */
583:
584: /* Output definitions, referring to storage in the parmlist,
585: of all the parms in PARMS, which is a chain of PARM_DECL nodes. */
586:
587: static void
588: dbxout_parms (parms)
589: tree parms;
590: {
591: for (; parms; parms = TREE_CHAIN (parms))
592: {
593: current_sym_code = N_PSYM;
594: current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
595: /* A parm declared char is really passed as an int,
596: so it occupies the least significant bytes.
597: On a big-endian machine those are not the low-numbered ones. */
598: #ifdef BYTES_BIG_ENDIAN
599: current_sym_value += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
600: - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
601: #endif
602: current_sym_addr = 0;
603: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
604:
605: fprintf (asmfile, ".stabs \"%s:p",
606: IDENTIFIER_POINTER (DECL_NAME (parms)));
607: dbxout_type (TREE_TYPE (parms), 0);
608: dbxout_finish_symbol ();
609: }
610: }
611:
612: /* Output definitions, referring to registers,
613: of all the parms in PARMS which are stored in registers during the function.
614: PARMS is a chain of PARM_DECL nodes. */
615:
616: static void
617: dbxout_reg_parms (parms)
618: tree parms;
619: {
620: while (parms)
621: {
622: if (GET_CODE (DECL_RTL (parms)) == REG
623: && REGNO (DECL_RTL (parms)) >= 0)
624: {
625: current_sym_code = N_RSYM;
626: current_sym_value = DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms)));
627: current_sym_addr = 0;
628: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (parms)));
629: fprintf (asmfile, ".stabs \"%s:r",
630: IDENTIFIER_POINTER (DECL_NAME (parms)));
631: dbxout_type (TREE_TYPE (parms), 0);
632: dbxout_finish_symbol ();
633: }
634: parms = TREE_CHAIN (parms);
635: }
636: }
637:
638: /* Given a chain of ..._TYPE nodes, all of which have names,
639: output definitions of those names, as typedefs. */
640:
641: void
642: dbxout_types (types)
643: register tree types;
644: {
645: while (types)
646: {
647: if (TYPE_NAME (types)
648: && TREE_CODE (TYPE_NAME (types)) == TYPE_DECL)
649: dbxout_type_def (types);
650: types = TREE_CHAIN (types);
651: }
652: }
653:
654: /* Output a definition of a typedef name.
655: It works much like any other kind of symbol definition. */
656:
657: static void
658: dbxout_type_def (type)
659: tree type;
660: {
661: current_sym_code = N_LSYM;
662: current_sym_value = 0;
663: current_sym_addr = 0;
664: current_sym_nchars = 0;
665: current_sym_nchars
666: = 2 + strlen (IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
667:
668: fprintf (asmfile, ".stabs \"%s:t",
669: IDENTIFIER_POINTER (DECL_NAME (TYPE_NAME (type))));
670: dbxout_type (type, 1);
671: dbxout_finish_symbol ();
672: }
673:
674: /* Output the tags (struct, union and enum definitions with names) for a block,
675: given a list of them (a chain of TREE_LIST nodes) in TAGS.
676: We must check to include those that have been mentioned already with
677: only a cross-reference. */
678:
679: void
680: dbxout_tags (tags)
681: tree tags;
682: {
683: register tree link;
684: for (link = tags; link; link = TREE_CHAIN (link))
685: {
686: register tree type = TREE_VALUE (link);
687: if (TREE_PURPOSE (link) != 0
688: && (TYPE_SYMTAB_ADDRESS (type) == 0
689: || (typevec[TYPE_SYMTAB_ADDRESS (type)] != TYPE_DEFINED))
690: && TYPE_SIZE (type) != 0)
691: {
692: current_sym_code = N_LSYM;
693: current_sym_value = 0;
694: current_sym_addr = 0;
695: current_sym_nchars = 2 + strlen (IDENTIFIER_POINTER (TREE_PURPOSE (link)));
696:
697: fprintf (asmfile, ".stabs \"%s:T",
698: IDENTIFIER_POINTER (TREE_PURPOSE (link)));
699: dbxout_type (type, 1);
700: dbxout_finish_symbol ();
701: typevec[TYPE_SYMTAB_ADDRESS (type)] = TYPE_DEFINED;
702: }
703: }
704: }
705:
706: /* Output everything about a symbol block (that is to say, a LET_STMT node
707: that represents a scope level),
708: including recursive output of contained blocks.
709:
710: STMT is the LET_STMT node.
711: DEPTH is its depth within containing symbol blocks.
712: ARGS is usually zero; but for the outermost block of the
713: body of a function, it is a chain of PARM_DECLs for the function parameters.
714: We output definitions of all the register parms
715: as if they were local variables of that block.
716:
717: Actually, STMT may be several statements chained together.
718: We handle them all in sequence. */
719:
720: static void
721: dbxout_block (stmt, depth, args)
722: register tree stmt;
723: int depth;
724: {
725: int blocknum;
726:
727: while (stmt)
728: {
729: switch (TREE_CODE (stmt))
730: {
731: case COMPOUND_STMT:
732: case LOOP_STMT:
733: dbxout_block (STMT_BODY (stmt), depth, 0);
734: break;
735:
736: case IF_STMT:
737: dbxout_block (STMT_THEN (stmt), depth, 0);
738: dbxout_block (STMT_ELSE (stmt), depth, 0);
739: break;
740:
741: case LET_STMT:
742: /* In dbx format, the syms of a block come before the N_LBRAC. */
743: dbxout_tags (STMT_TYPE_TAGS (stmt));
744: dbxout_syms (STMT_VARS (stmt), 1);
745: if (args)
746: dbxout_reg_parms (args);
747:
748: /* Now output an N_LBRAC symbol to represent the beginning of
749: the block. Use the block's tree-walk order to generate
750: the assembler symbols LBBn and LBEn
751: that final will define around the code in this block. */
752: if (depth > 0)
753: {
754: blocknum = next_block_number++;
755: fprintf (asmfile, ".stabn %d,0,0,LBB%d\n", N_LBRAC, blocknum);
756: }
757:
758: /* Output the interior of the block. */
759: dbxout_block (STMT_BODY (stmt), depth + 1, 0);
760:
761: /* Refer to the marker for the end of the block. */
762: if (depth > 0)
763: fprintf (asmfile, ".stabn %d,0,0,LBE%d\n", N_RBRAC, blocknum);
764: }
765: stmt = TREE_CHAIN (stmt);
766: }
767: }
768:
769: /* Output dbx data for a function definition.
770: This includes a definition of the function name itself (a symbol),
771: definitions of the parameters (locating them in the parameter list)
772: and then output the block that makes up the function's body
773: (including all the auto variables of the function). */
774:
775: void
776: dbxout_function (decl)
777: tree decl;
778: {
779: dbxout_symbol (decl, 0);
780: dbxout_parms (DECL_ARGUMENTS (decl));
781: dbxout_block (DECL_INITIAL (decl), 0, DECL_ARGUMENTS (decl));
782: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.