adding GNU dc ("desk calculator")
[unix-history] / gnu / usr.bin / gcc1 / cc1 / sdbout.c
CommitLineData
15637ed4
RG
1/* Output sdb-format symbol table information from GNU compiler.
2 Copyright (C) 1988 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20#define MAYBE
21
22#include "config.h"
23
24#ifdef SDB_DEBUGGING_INFO
25
26#include "tree.h"
27#include "rtl.h"
28#include <stdio.h>
29
30#if defined(USG) && !defined(MIPS_DEBUGGING_INFO)
31#include <syms.h>
32/* #include <storclass.h> used to be this instead of syms.h. */
33
34#else
35/* For cross compilation, use the portable defintions from the COFF
36 documentation. */
37
38#define C_EFCN -1
39#define C_NULL 0
40#define C_AUTO 1
41#define C_EXT 2
42#define C_STAT 3
43#define C_REG 4
44#define C_EXTDEF 5
45#define C_LABEL 6
46#define C_ULABEL 7
47#define C_MOS 8
48#define C_ARG 9
49#define C_STRTAG 10
50#define C_MOU 11
51#define C_UNTAG 12
52#define C_TPDEF 13
53#define C_USTATIC 14
54#define C_ENTAG 15
55#define C_MOE 16
56#define C_REGPARM 17
57#define C_FIELD 18
58#define C_BLOCK 100
59#define C_FCN 101
60#define C_EOS 102
61#define C_FILE 103
62
63#define C_LINE 104
64#define C_ALIAS 105
65#define C_HIDDEN 106
66
67#define T_NULL 0
68#define T_ARG 1
69#define T_CHAR 2
70#define T_SHORT 3
71#define T_INT 4
72#define T_LONG 5
73#define T_FLOAT 6
74#define T_DOUBLE 7
75#define T_STRUCT 8
76#define T_UNION 9
77#define T_ENUM 10
78#define T_MOE 11
79#define T_UCHAR 12
80#define T_USHORT 13
81#define T_UINT 14
82#define T_ULONG 15
83
84#define DT_NON 0
85#define DT_PTR 1
86#define DT_FCN 2
87#define DT_ARY 3
88
89#define N_BTMASK 017
90#define N_TMASK 060
91#define N_TMASK1 0300
92#define N_TMASK2 0360
93#define N_BTSHFT 4
94#define N_TSHIFT 2
95#endif
96
97/* Line number of beginning of current function, minus one.
98 Negative means not in a function or not using sdb. */
99
100int sdb_begin_function_line = -1;
101
102/* Counter to generate unique "names" for nameless struct members. */
103
104static int unnamed_struct_number = 0;
105
106extern FILE *asm_out_file;
107
108extern tree current_function_decl;
109
110void sdbout_init ();
111void sdbout_symbol ();
112void sdbout_tags();
113void sdbout_types();
114
115static void sdbout_syms ();
116static void sdbout_one_type ();
117static int plain_type_1 ();
118\f
119/* Random macros describing parts of SDB data. */
120
121/* Put something here if lines get too long */
122#define CONTIN
123
124/* Maximum number of dimensions the assembler will allow. */
125#ifndef SDB_MAX_DIM
126#define SDB_MAX_DIM 4
127#endif
128
129#ifndef PUT_SDB_SCL
130#define PUT_SDB_SCL(a) fprintf(asm_out_file, "\t.scl\t%d;", (a))
131#endif
132
133#ifndef PUT_SDB_INT_VAL
134#define PUT_SDB_INT_VAL(a) fprintf (asm_out_file, "\t.val\t%d;", (a))
135#endif
136
137#ifndef PUT_SDB_VAL
138#define PUT_SDB_VAL(a) \
139( fputs ("\t.val\t", asm_out_file), \
140 output_addr_const (asm_out_file, (a)), \
141 fputc (';', asm_out_file))
142#endif
143
144#ifndef PUT_SDB_DEF
145#define PUT_SDB_DEF(a) \
146do { fprintf (asm_out_file, "\t.def\t"); \
147 ASM_OUTPUT_LABELREF (asm_out_file, a); \
148 fprintf (asm_out_file, ";"); } while (0)
149#endif
150
151#ifndef PUT_SDB_PLAIN_DEF
152#define PUT_SDB_PLAIN_DEF(a) fprintf(asm_out_file,"\t.def\t.%s;",a)
153#endif
154
155#ifndef PUT_SDB_ENDEF
156#define PUT_SDB_ENDEF fputs("\t.endef\n", asm_out_file)
157#endif
158
159#ifndef PUT_SDB_TYPE
160#define PUT_SDB_TYPE(a) fprintf(asm_out_file, "\t.type\t0%o;", a)
161#endif
162
163#ifndef PUT_SDB_SIZE
164#define PUT_SDB_SIZE(a) fprintf(asm_out_file, "\t.size\t%d;", a)
165#endif
166
167#ifndef PUT_SDB_START_DIM
168#define PUT_SDB_START_DIM fprintf(asm_out_file, "\t.dim\t")
169#endif
170
171#ifndef PUT_SDB_NEXT_DIM
172#define PUT_SDB_NEXT_DIM(a) fprintf(asm_out_file, "%d,", a)
173#endif
174
175#ifndef PUT_SDB_LAST_DIM
176#define PUT_SDB_LAST_DIM(a) fprintf(asm_out_file, "%d;", a)
177#endif
178
179#ifndef PUT_SDB_TAG
180#define PUT_SDB_TAG(a) \
181do { fprintf (asm_out_file, "\t.tag\t"); \
182 ASM_OUTPUT_LABELREF (asm_out_file, a); \
183 fprintf (asm_out_file, ";"); } while (0)
184#endif
185
186#ifndef PUT_SDB_BLOCK_START
187#define PUT_SDB_BLOCK_START(LINE) \
188 fprintf (asm_out_file, \
189 "\t.def\t.bb;\t.val\t.;\t.scl\t100;\t.line\t%d;\t.endef\n", \
190 (LINE))
191#endif
192
193#ifndef PUT_SDB_BLOCK_END
194#define PUT_SDB_BLOCK_END(LINE) \
195 fprintf (asm_out_file, \
196 "\t.def\t.eb;.val\t.;\t.scl\t100;\t.line\t%d;\t.endef\n", \
197 (LINE))
198#endif
199
200#ifndef PUT_SDB_FUNCTION_START
201#define PUT_SDB_FUNCTION_START(LINE) \
202 fprintf (asm_out_file, \
203 "\t.def\t.bf;\t.val\t.;\t.scl\t101;\t.line\t%d;\t.endef\n", \
204 (LINE))
205#endif
206
207#ifndef PUT_SDB_FUNCTION_END
208#define PUT_SDB_FUNCTION_END(LINE) \
209 fprintf (asm_out_file, \
210 "\t.def\t.ef;\t.val\t.;\t.scl\t101;\t.line\t%d;\t.endef\n", \
211 (LINE))
212#endif
213
214#ifndef PUT_SDB_EPILOGUE_END
215#define PUT_SDB_EPILOGUE_END(NAME) \
216 fprintf (asm_out_file, \
217 "\t.def\t%s;\t.val\t.;\t.scl\t-1;\t.endef\n", \
218 (NAME))
219#endif
220
221#ifndef SDB_GENERATE_FAKE
222#define SDB_GENERATE_FAKE(BUFFER, NUMBER) \
223 sprintf ((BUFFER), ".%dfake", (NUMBER));
224#endif
225
226/* Return the sdb tag identifier string for TYPE
227 if TYPE has already been defined; otherwise return a null pointer. */
228
229#define KNOWN_TYPE_TAG(type) (char *)(TYPE_SYMTAB_ADDRESS (type))
230
231/* Set the sdb tag identifier string for TYPE to NAME. */
232
233#define SET_KNOWN_TYPE_TAG(TYPE, NAME) \
234 (TYPE_SYMTAB_ADDRESS (TYPE) = (int)(NAME))
235
236/* Return the name (a string) of the struct, union or enum tag
237 described by the TREE_LIST node LINK. This is 0 for an anonymous one. */
238
239#define TAG_NAME(link) \
240 (((link) && TREE_PURPOSE ((link)) \
241 && IDENTIFIER_POINTER (TREE_PURPOSE ((link)))) \
242 ? IDENTIFIER_POINTER (TREE_PURPOSE ((link))) : (char *) 0)
243
244/* Ensure we don't output a negative line number. */
245#define MAKE_LINE_SAFE(line) \
246 if (line <= sdb_begin_function_line) line = sdb_begin_function_line + 1
247\f
248/* Tell the assembler the source file name.
249 On systems that use SDB, this is done whether or not -g,
250 so it is called by ASM_FILE_START.
251
252 ASM_FILE is the assembler code output file,
253 INPUT_NAME is the name of the main input file. */
254
255void
256sdbout_filename (asm_file, input_name)
257 FILE *asm_file;
258 char *input_name;
259{
260 int len = strlen (input_name);
261 char *na = input_name + len;
262
263 /* NA gets INPUT_NAME sans directory names. */
264 while (na > input_name)
265 {
266 if (na[-1] == '/')
267 break;
268 na--;
269 }
270
271#ifdef ASM_OUTPUT_SOURCE_FILENAME
272 ASM_OUTPUT_SOURCE_FILENAME (asm_file, na);
273#else
274 fprintf (asm_file, "\t.file\t\"%s\"\n", na);
275#endif
276}
277
278/* Set up for SDB output at the start of compilation. */
279
280void
281sdbout_init ()
282{
283 /* Output all the initial permanent types. */
284 sdbout_types (nreverse (get_permanent_types ()));
285}
286
287#if 0
288
289/* return the tag identifier for type
290 */
291
292{
293char *
294tag_of_ru_type (type,link)
295 tree type,link;
296{
297 if (TYPE_SYMTAB_ADDRESS (type))
298 return (char *)TYPE_SYMTAB_ADDRESS (type);
299 if (link &&
300 TREE_PURPOSE (link)
301 && IDENTIFIER_POINTER (TREE_PURPOSE (link)))
302 TYPE_SYMTAB_ADDRESS (type) =
303 (int)IDENTIFIER_POINTER (TREE_PURPOSE (link));
304 else
305 return (char *) TYPE_SYMTAB_ADDRESS (type);
306}
307#endif
308
309/* Return a unique string to name an anonymous type. */
310
311static char *
312gen_fake_label ()
313{
314 char label[10];
315 char *labelstr;
316 SDB_GENERATE_FAKE (label, unnamed_struct_number);
317 unnamed_struct_number++;
318 labelstr = (char *) permalloc (strlen (label) + 1);
319 strcpy (labelstr, label);
320 return labelstr;
321}
322\f
323/* Return the number which describes TYPE for SDB.
324 For pointers, etc., this function is recursive.
325 Each record, union or enumeral type must already have had a
326 tag number output. */
327
328/* The number is given by d6d5d4d3d2d1bbbb
329 where bbbb is 4 bit basic type, and di indicate one of notype,ptr,fn,array.
330 Thus, char *foo () has bbbb=T_CHAR
331 d1=D_FCN
332 d2=D_PTR
333 N_BTMASK= 017 1111 basic type field.
334 N_TSHIFT= 2 derived type shift
335 N_BTSHFT= 4 Basic type shift */
336
337/* Produce the number that describes a pointer, function or array type.
338 PREV is the number describing the target, value or element type.
339 DT_type describes how to transform that type. */
340#define PUSH_DERIVED_LEVEL(DT_type,PREV) \
341 ((((PREV)&~N_BTMASK)<<N_TSHIFT)|(DT_type<<N_BTSHFT)|(PREV&N_BTMASK))
342
343/* Number of elements used in sdb_dims. */
344static int sdb_n_dims = 0;
345
346/* Table of array dimensions of current type. */
347static int sdb_dims[SDB_MAX_DIM];
348
349/* Size of outermost array currently being processed. */
350static int sdb_type_size = -1;
351
352static int
353plain_type (type)
354 tree type;
355{
356 int val = plain_type_1 (type);
357
358 /* If we have already saved up some array dimensions, print them now. */
359 if (sdb_n_dims > 0)
360 {
361 int i;
362 PUT_SDB_START_DIM;
363 for (i = sdb_n_dims - 1; i > 0; i--)
364 PUT_SDB_NEXT_DIM (sdb_dims[i]);
365 PUT_SDB_LAST_DIM (sdb_dims[0]);
366 sdb_n_dims = 0;
367
368 sdb_type_size = int_size_in_bytes (type);
369 /* Don't kill sdb if type is not laid out or has variable size. */
370 if (sdb_type_size < 0)
371 sdb_type_size = 0;
372 }
373 /* If we have computed the size of an array containing this type,
374 print it now. */
375 if (sdb_type_size >= 0)
376 {
377 PUT_SDB_SIZE (sdb_type_size);
378 sdb_type_size = -1;
379 }
380 return val;
381}
382
383static void
384sdbout_record_type_name (type)
385 tree type;
386{
387 char *name = 0;
388
389 if (KNOWN_TYPE_TAG (type))
390 return;
391
392 if (TYPE_NAME (type) != 0)
393 {
394 tree t = 0;
395 /* Find the IDENTIFIER_NODE for the type name. */
396 if (TREE_CODE (TYPE_NAME (type)) == IDENTIFIER_NODE)
397 {
398 t = TYPE_NAME (type);
399 }
400 else if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL)
401 {
402 t = DECL_NAME (TYPE_NAME (type));
403 }
404
405 /* Now get the name as a string, or invent one. */
406 if (t != 0)
407 name = IDENTIFIER_POINTER (t);
408 }
409
410 if (name == 0)
411 name = gen_fake_label ();
412
413 SET_KNOWN_TYPE_TAG (type, name);
414}
415
416static int
417plain_type_1 (type)
418 tree type;
419{
420 if (type == 0)
421 type = void_type_node;
422 if (type == error_mark_node)
423 type = integer_type_node;
424 type = TYPE_MAIN_VARIANT (type);
425
426 switch (TREE_CODE (type))
427 {
428 case VOID_TYPE:
429 return T_INT;
430 case INTEGER_TYPE:
431 switch (int_size_in_bytes (type))
432 {
433 case 4:
434 return (TREE_UNSIGNED (type) ? T_UINT : T_INT);
435 case 1:
436 return (TREE_UNSIGNED (type) ? T_UCHAR : T_CHAR);
437 case 2:
438 return (TREE_UNSIGNED (type) ? T_USHORT : T_SHORT);
439 default:
440 return 0;
441 }
442 case REAL_TYPE:
443 switch (int_size_in_bytes (type))
444 {
445 case 4:
446 return T_FLOAT;
447 default:
448 return T_DOUBLE;
449 }
450
451 case ARRAY_TYPE:
452 {
453 int m;
454 m = plain_type_1 (TREE_TYPE (type));
455 if (sdb_n_dims < SDB_MAX_DIM)
456 sdb_dims[sdb_n_dims++]
457 = (TYPE_DOMAIN (type)
458 ? TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (type))) + 1
459 : 0);
460 return PUSH_DERIVED_LEVEL (DT_ARY, m);
461 }
462
463 case RECORD_TYPE:
464 case UNION_TYPE:
465 case ENUMERAL_TYPE:
466 {
467 char *tag;
468 sdbout_record_type_name (type);
469 if (TREE_ASM_WRITTEN (type)
470#ifdef MAYBE
471 && KNOWN_TYPE_TAG (type)
472#endif
473 )
474 {
475 /* Output the referenced structure tag name
476 only if the .def has already been output.
477 At least on 386, the Unix assembler
478 cannot handle forward references to tags. */
479 tag = KNOWN_TYPE_TAG (type);
480 PUT_SDB_TAG (tag);
481 }
482 sdb_type_size = int_size_in_bytes (type);
483 if (sdb_type_size < 0)
484 sdb_type_size = 0;
485 return ((TREE_CODE (type) == RECORD_TYPE) ? T_STRUCT
486 : (TREE_CODE (type) == UNION_TYPE) ? T_UNION
487 : T_ENUM);
488 }
489 case POINTER_TYPE:
490 case REFERENCE_TYPE:
491 {
492 int m = plain_type_1 (TREE_TYPE (type));
493 return PUSH_DERIVED_LEVEL (DT_PTR, m);
494 }
495 case FUNCTION_TYPE:
496 case METHOD_TYPE:
497 {
498 int m = plain_type_1 (TREE_TYPE (type));
499 return PUSH_DERIVED_LEVEL (DT_FCN, m);
500 }
501 default:
502 return 0;
503 }
504}
505\f
506/* Output the symbols defined in block number DO_BLOCK.
507 Set NEXT_BLOCK_NUMBER to 0 before calling.
508
509 This function works by walking the tree structure,
510 counting blocks, until it finds the desired block. */
511
512static int do_block = 0;
513
514static int next_block_number;
515
516static void
517sdbout_block (stmt)
518 register tree stmt;
519{
520 while (stmt)
521 {
522 switch (TREE_CODE (stmt))
523 {
524 case COMPOUND_STMT:
525 case LOOP_STMT:
526 sdbout_block (STMT_BODY (stmt));
527 break;
528
529 case IF_STMT:
530 sdbout_block (STMT_THEN (stmt));
531 sdbout_block (STMT_ELSE (stmt));
532 break;
533
534 case LET_STMT:
535 /* Ignore LET_STMTs for blocks never really used to make RTL. */
536 if (! TREE_USED (stmt))
537 break;
538 /* When we reach the specified block, output its symbols. */
539 if (next_block_number == do_block)
540 {
541 sdbout_tags (STMT_TYPE_TAGS (stmt));
542 sdbout_syms (STMT_VARS (stmt));
543 }
544
545 /* If we are past the specified block, stop the scan. */
546 if (next_block_number > do_block)
547 return;
548
549 next_block_number++;
550
551 /* Scan the blocks within this block. */
552 sdbout_block (STMT_SUBBLOCKS (stmt));
553 }
554 stmt = TREE_CHAIN (stmt);
555 }
556}
557\f
558/* Call sdbout_symbol on each decl in the chain SYMS. */
559
560static void
561sdbout_syms (syms)
562 tree syms;
563{
564 while (syms)
565 {
566 sdbout_symbol (syms, 1);
567 syms = TREE_CHAIN (syms);
568 }
569}
570
571/* Output SDB information for a symbol described by DECL.
572 LOCAL is nonzero if the symbol is not file-scope. */
573
574void
575sdbout_symbol (decl, local)
576 tree decl;
577 int local;
578{
579 int letter = 0;
580 tree type = TREE_TYPE (decl);
581 rtx value;
582
583 /* If global, first output all types and all
584 struct, enum and union tags that have been created
585 and not yet output. */
586
587 if (local == 0)
588 {
589 sdbout_tags (gettags ());
590 sdbout_types (nreverse (get_permanent_types ()));
591 }
592
593#ifdef MAYBE
594 sdbout_one_type (type);
595#endif
596
597 switch (TREE_CODE (decl))
598 {
599 case CONST_DECL:
600 /* Enum values are defined by defining the enum type. */
601 return;
602
603 case FUNCTION_DECL:
604 if (TREE_EXTERNAL (decl))
605 return;
606 if (GET_CODE (DECL_RTL (decl)) != MEM
607 || GET_CODE (XEXP (DECL_RTL (decl), 0)) != SYMBOL_REF)
608 return;
609 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
610 PUT_SDB_VAL (XEXP (DECL_RTL (decl), 0));
611 PUT_SDB_SCL (TREE_PUBLIC (decl) ? C_EXT : C_STAT);
612 break;
613
614 case TYPE_DECL:
615 /* Output typedef name. */
616 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
617 PUT_SDB_SCL (C_TPDEF);
618 break;
619
620 case PARM_DECL:
621 /* Parm decls go in their own separate chains
622 and are output by sdbout_reg_parms and sdbout_parms. */
623 abort ();
624
625 case VAR_DECL:
626 /* Don't mention a variable that is external.
627 Let the file that defines it describe it. */
628 if (TREE_EXTERNAL (decl))
629 return;
630
631 value = DECL_RTL (decl);
632
633 /* Don't mention a variable at all
634 if it was completely optimized into nothingness. */
635 if (GET_CODE (value) == REG
636 && (REGNO (value) < 0
637 || REGNO (value) >= FIRST_PSEUDO_REGISTER))
638 return;
639
640 /* Ok, start a symtab entry and output the variable name. */
641 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (decl)));
642
643 if (GET_CODE (value) == MEM
644 && GET_CODE (XEXP (value, 0)) == SYMBOL_REF)
645 {
646 if (TREE_PUBLIC (decl))
647 {
648 PUT_SDB_VAL (XEXP (value, 0));
649 PUT_SDB_SCL (C_EXT);
650 }
651 else
652 {
653 PUT_SDB_VAL (XEXP (value, 0));
654 PUT_SDB_SCL (C_STAT);
655 }
656 }
657 else if (GET_CODE (value) == REG)
658 {
659 PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (value)));
660 PUT_SDB_SCL (C_REG);
661 }
662 else if (GET_CODE (value) == SUBREG)
663 {
664 int offset = 0;
665 while (GET_CODE (value) == SUBREG)
666 {
667 offset += SUBREG_WORD (value);
668 value = SUBREG_REG (value);
669 }
670 PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (value) + offset));
671 PUT_SDB_SCL (C_REG);
672 }
673 else if (GET_CODE (value) == MEM
674 && (GET_CODE (XEXP (value, 0)) == MEM
675 || (GET_CODE (XEXP (value, 0)) == REG
676 && REGNO (XEXP (value, 0)) != FRAME_POINTER_REGNUM)))
677 /* If the value is indirect by memory or by a register
678 that isn't the frame pointer
679 then it means the object is variable-sized and address through
680 that register or stack slot. DBX has no way to represent this
681 so all we can do is output the variable as a pointer. */
682 {
683 if (GET_CODE (XEXP (value, 0)) == REG)
684 {
685 PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (XEXP (value, 0))));
686 PUT_SDB_SCL (C_REG);
687 }
688 else
689 {
690 /* DECL_RTL looks like (MEM (MEM (PLUS (REG...)
691 (CONST_INT...)))).
692 We want the value of that CONST_INT. */
693 /* Encore compiler hates a newline in a macro arg, it seems. */
694 PUT_SDB_INT_VAL (INTVAL (XEXP (XEXP (XEXP (value, 0), 0), 1)));
695 PUT_SDB_SCL (C_AUTO);
696 }
697
698 type = build_pointer_type (TREE_TYPE (decl));
699 }
700 else if (GET_CODE (value) == MEM
701 && GET_CODE (XEXP (value, 0)) == PLUS
702 && GET_CODE (XEXP (XEXP (value, 0), 0)) == REG
703 && GET_CODE (XEXP (XEXP (value, 0), 1)) == CONST_INT)
704 {
705 /* DECL_RTL looks like (MEM (PLUS (REG...) (CONST_INT...))).
706 We want the value of that CONST_INT. */
707 PUT_SDB_INT_VAL (INTVAL (XEXP (XEXP (value, 0), 1)));
708 PUT_SDB_SCL (C_AUTO);
709 }
710 else
711 {
712 /* It is something we don't know how to represent for SDB. */
713 }
714 break;
715 }
716 PUT_SDB_TYPE (plain_type (type));
717 PUT_SDB_ENDEF;
718}
719\f
720/* Given a list of TREE_LIST nodes that point at types,
721 output those types for SDB.
722 We must check to include those that have been mentioned already with
723 only a cross-reference. */
724
725void
726sdbout_tags (tags)
727 tree tags;
728{
729 register tree link;
730
731 for (link = tags; link; link = TREE_CHAIN (link))
732 {
733 register tree type = TREE_VALUE (link);
734
735 if (TREE_PURPOSE (link) != 0
736 && TYPE_SIZE (type) != 0)
737 sdbout_one_type (type);
738 }
739}
740
741/* Given a chain of ..._TYPE nodes, all of which have names,
742 output definitions of those names, as typedefs. */
743
744void
745sdbout_types (types)
746 register tree types;
747{
748 register tree link;
749
750 for (link = types; link; link = TREE_CHAIN (link))
751 sdbout_one_type (link);
752}
753
754static void
755sdbout_type (type)
756 tree type;
757{
758 register tree tem;
759 if (type == error_mark_node)
760 type = integer_type_node;
761 PUT_SDB_TYPE (plain_type (type));
762}
763
764/* Output types of the fields of type TYPE, if they are structs.
765 Formerly did not chase through pointer types, since that could be circular.
766 They must come before TYPE, since forward refs are not allowed.
767 Now james@bigtex.cactus.org says to try them. */
768
769static void
770sdbout_field_types (type)
771 tree type;
772{
773 tree tail;
774 for (tail = TYPE_FIELDS (type); tail; tail = TREE_CHAIN (tail))
775 {
776#ifdef MAYBE
777 if (TREE_CODE (TREE_TYPE (tail)) == POINTER_TYPE)
778 sdbout_one_type (TREE_TYPE (TREE_TYPE (tail)));
779 else
780#endif
781 sdbout_one_type (TREE_TYPE (tail));
782 }
783}
784
785/* Use this to put out the top level defined record and union types
786 for later reference. If this is a struct with a name, then put that
787 name out. Other unnamed structs will have .xxfake labels generated so
788 that they may be referred to later.
789 The label will be stored in the KNOWN_TYPE_TAG slot of a type.
790 It may NOT be called recursively. */
791
792static void
793sdbout_one_type (type)
794 tree type;
795{
796 text_section ();
797
798 switch (TREE_CODE (type))
799 {
800 case RECORD_TYPE:
801 case UNION_TYPE:
802 case ENUMERAL_TYPE:
803 type = TYPE_MAIN_VARIANT (type);
804 /* Don't output a type twice. */
805 if (TREE_ASM_WRITTEN (type))
806 return;
807
808 /* Output nothing if type is not yet defined. */
809 if (TYPE_SIZE (type) == 0)
810 return;
811
812 TREE_ASM_WRITTEN (type) = 1;
813#ifndef MAYBE
814 /* Before really doing anything, output types we want to refer to. */
815 if (TREE_CODE (type) != ENUMERAL_TYPE)
816 sdbout_field_types (type);
817#endif
818
819 sdbout_record_type_name (type);
820
821 /* Output a structure type. */
822 {
823 int size = int_size_in_bytes (type);
824 int member_scl;
825 tree tem;
826
827 PUT_SDB_DEF (KNOWN_TYPE_TAG (type));
828
829 switch (TREE_CODE (type))
830 {
831 case UNION_TYPE:
832 PUT_SDB_SCL (C_UNTAG);
833 PUT_SDB_TYPE (T_UNION);
834 member_scl = C_MOU;
835 break;
836
837 case RECORD_TYPE:
838 PUT_SDB_SCL (C_STRTAG);
839 PUT_SDB_TYPE (T_STRUCT);
840 member_scl = C_MOS;
841 break;
842
843 case ENUMERAL_TYPE:
844 PUT_SDB_SCL (C_ENTAG);
845 PUT_SDB_TYPE (T_ENUM);
846 member_scl = C_MOE;
847 break;
848 }
849
850 PUT_SDB_SIZE (size);
851 PUT_SDB_ENDEF;
852
853 /* output the individual fields */
854
855 if (TREE_CODE (type) == ENUMERAL_TYPE)
856 for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
857 {
858 PUT_SDB_DEF (IDENTIFIER_POINTER (TREE_PURPOSE (tem)));
859 PUT_SDB_INT_VAL (TREE_INT_CST_LOW (TREE_VALUE (tem)));
860 PUT_SDB_SCL (C_MOE);
861 PUT_SDB_TYPE (T_MOE);
862 PUT_SDB_ENDEF;
863 }
864
865 else /* record or union type */
866 for (tem = TYPE_FIELDS (type); tem; tem = TREE_CHAIN (tem))
867 /* Output the name, type, position (in bits), size (in bits)
868 of each field. */
869 /* Omit here the nameless fields that are used to skip bits. */
870 if (DECL_NAME (tem) != 0)
871 {
872 CONTIN;
873 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (tem)));
874 if (TREE_PACKED (tem))
875 {
876 PUT_SDB_INT_VAL (DECL_OFFSET (tem));
877 PUT_SDB_SCL (C_FIELD);
878 sdbout_type (TREE_TYPE (tem));
879 PUT_SDB_SIZE (TREE_INT_CST_LOW (DECL_SIZE (tem))
880 * DECL_SIZE_UNIT (tem));
881 }
882 else
883 {
884 PUT_SDB_INT_VAL (DECL_OFFSET (tem) / BITS_PER_UNIT);
885 PUT_SDB_SCL (member_scl);
886 sdbout_type (TREE_TYPE (tem));
887 }
888 PUT_SDB_ENDEF;
889 }
890 /* output end of a structure,union, or enumeral definition */
891
892 PUT_SDB_PLAIN_DEF ("eos");
893 PUT_SDB_INT_VAL (size);
894 PUT_SDB_SCL (C_EOS);
895 PUT_SDB_TAG (KNOWN_TYPE_TAG (type));
896 PUT_SDB_SIZE (size);
897 PUT_SDB_ENDEF;
898 break;
899 }
900 }
901}
902\f
903/* Output definitions of all parameters, referring when possible to the
904 place where the parameters were passed rather than the copies used
905 within the function. This is done as part of starting the function.
906 PARMS is a chain of PARM_DECL nodes. */
907
908static void
909sdbout_parms (parms1)
910 tree parms1;
911{
912 tree type;
913 tree parms;
914
915 for (parms = parms1; parms; parms = TREE_CHAIN (parms))
916 {
917 int current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
918
919 if (DECL_NAME (parms))
920 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (parms)));
921 else
922 PUT_SDB_DEF (gen_fake_label ());
923
924 if (GET_CODE (DECL_RTL (parms)) == REG
925 && REGNO (DECL_RTL (parms)) >= 0
926 && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
927 type = DECL_ARG_TYPE (parms);
928 else
929 {
930 /* This is the case where the parm is passed as an int or double
931 and it is converted to a char, short or float and stored back
932 in the parmlist. In this case, describe the parm
933 with the variable's declared type, and adjust the address
934 if the least significant bytes (which we are using) are not
935 the first ones. */
936#ifdef BYTES_BIG_ENDIAN
937 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
938 current_sym_value +=
939 (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
940 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
941#endif
942 if (GET_CODE (DECL_RTL (parms)) == MEM
943 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
944 && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT
945 && (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1))
946 == current_sym_value))
947 type = TREE_TYPE (parms);
948 else
949 {
950 current_sym_value = DECL_OFFSET (parms) / BITS_PER_UNIT;
951 type = DECL_ARG_TYPE (parms);
952 }
953 }
954
955 PUT_SDB_INT_VAL (current_sym_value);
956 PUT_SDB_SCL (C_ARG);
957 PUT_SDB_TYPE (plain_type (type));
958 PUT_SDB_ENDEF;
959 }
960}
961
962/* Output definitions, referring to registers,
963 of all the parms in PARMS which are stored in registers during the function.
964 PARMS is a chain of PARM_DECL nodes.
965 This is done as part of starting the function. */
966
967static void
968sdbout_reg_parms (parms)
969 tree parms;
970{
971 while (parms)
972 {
973 if (GET_CODE (DECL_RTL (parms)) == REG
974 && REGNO (DECL_RTL (parms)) >= 0
975 && REGNO (DECL_RTL (parms)) < FIRST_PSEUDO_REGISTER)
976 {
977 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (parms)));
978 PUT_SDB_INT_VAL (DBX_REGISTER_NUMBER (REGNO (DECL_RTL (parms))));
979 PUT_SDB_SCL (C_REG);
980 PUT_SDB_TYPE (plain_type (TREE_TYPE (parms), 0));
981 PUT_SDB_ENDEF;
982 }
983 else if (GET_CODE (DECL_RTL (parms)) == MEM
984 && GET_CODE (XEXP (DECL_RTL (parms), 0)) == PLUS
985 && GET_CODE (XEXP (XEXP (DECL_RTL (parms), 0), 1)) == CONST_INT)
986 {
987 int offset = DECL_OFFSET (parms) / BITS_PER_UNIT;
988 /* A parm declared char is really passed as an int,
989 so it occupies the least significant bytes.
990 On a big-endian machine those are not the low-numbered ones. */
991#ifdef BYTES_BIG_ENDIAN
992 if (TREE_TYPE (parms) != DECL_ARG_TYPE (parms))
993 offset += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parms)))
994 - GET_MODE_SIZE (GET_MODE (DECL_RTL (parms))));
995#endif
996 if (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)) != offset)
997 {
998 PUT_SDB_DEF (IDENTIFIER_POINTER (DECL_NAME (parms)));
999 PUT_SDB_INT_VAL (INTVAL (XEXP (XEXP (DECL_RTL (parms), 0), 1)));
1000 PUT_SDB_SCL (C_AUTO);
1001 PUT_SDB_TYPE (plain_type (TREE_TYPE (parms)));
1002 PUT_SDB_ENDEF;
1003 }
1004 }
1005 parms = TREE_CHAIN (parms);
1006 }
1007}
1008\f
1009/* Describe the beginning of an internal block within a function.
1010 Also output descriptions of variables defined in this block.
1011
1012 N is the number of the block, by order of beginning, counting from 1,
1013 and not counting the outermost (function top-level) block.
1014 The blocks match the LET_STMTS in DECL_INITIAL (current_function_decl),
1015 if the count starts at 0 for the outermost one. */
1016
1017void
1018sdbout_begin_block (file, line, n)
1019 FILE *file;
1020 int line;
1021 int n;
1022{
1023 tree decl = current_function_decl;
1024 MAKE_LINE_SAFE (line);
1025 PUT_SDB_BLOCK_START (line - sdb_begin_function_line);
1026 if (n == 1)
1027 {
1028 /* Include the outermost LET_STMT's variables in block 1. */
1029 next_block_number = 0;
1030 do_block = 0;
1031 sdbout_block (DECL_INITIAL (decl));
1032 }
1033 next_block_number = 0;
1034 do_block = n;
1035 sdbout_block (DECL_INITIAL (decl));
1036}
1037
1038/* Describe the end line-number of an internal block within a function. */
1039
1040void
1041sdbout_end_block (file, line)
1042 FILE *file;
1043 int line;
1044{
1045 MAKE_LINE_SAFE (line);
1046 PUT_SDB_BLOCK_END (line - sdb_begin_function_line);
1047}
1048
1049/* Output sdb info for the current function name.
1050 Called from assemble_function. */
1051
1052void
1053sdbout_mark_begin_function ()
1054{
1055 sdbout_symbol (current_function_decl, 0);
1056}
1057
1058/* Called at beginning of function body (after prologue).
1059 Record the function's starting line number, so we can output
1060 relative line numbers for the other lines.
1061 Describe beginning of outermost block.
1062 Also describe the parameter list. */
1063
1064void
1065sdbout_begin_function (line)
1066 int line;
1067{
1068 sdb_begin_function_line = line - 1;
1069 PUT_SDB_FUNCTION_START (line);
1070 sdbout_parms (DECL_ARGUMENTS (current_function_decl));
1071 sdbout_reg_parms (DECL_ARGUMENTS (current_function_decl));
1072}
1073
1074/* Called at end of function (before epilogue).
1075 Describe end of outermost block. */
1076
1077void
1078sdbout_end_function (line)
1079 int line;
1080{
1081 MAKE_LINE_SAFE (line);
1082 PUT_SDB_FUNCTION_END (line - sdb_begin_function_line);
1083
1084 /* Indicate we are between functions, for line-number output. */
1085 sdb_begin_function_line = -1;
1086}
1087
1088/* Output sdb info for the absolute end of a function.
1089 Called after the epilogue is output. */
1090
1091void
1092sdbout_end_epilogue ()
1093{
1094 char *name = IDENTIFIER_POINTER (DECL_NAME (current_function_decl));
1095 PUT_SDB_EPILOGUE_END (name);
1096}
1097
1098#endif /* SDB_DEBUGGING_INFO */