xref: /csrg-svn/old/dbx/c.c (revision 16624)
1 /* Copyright (c) 1982 Regents of the University of California */
2 
3 static	char sccsid[] = "@(#)c.c	1.8 (Berkeley) 06/23/84";
4 
5 /*
6  * C-dependent symbol routines.
7  */
8 
9 #include "defs.h"
10 #include "symbols.h"
11 #include "printsym.h"
12 #include "languages.h"
13 #include "c.h"
14 #include "tree.h"
15 #include "eval.h"
16 #include "operators.h"
17 #include "mappings.h"
18 #include "process.h"
19 #include "runtime.h"
20 #include "machine.h"
21 
22 #ifndef public
23 # include "tree.h"
24 #endif
25 
26 #define isdouble(range) ( \
27     range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \
28 )
29 
30 #define isrange(t, name) (t->class == RANGE and istypename(t->type, name))
31 
32 private Language langC;
33 
34 /*
35  * Initialize C language information.
36  */
37 
38 public c_init()
39 {
40     langC = language_define("c", ".c");
41     language_setop(langC, L_PRINTDECL, c_printdecl);
42     language_setop(langC, L_PRINTVAL, c_printval);
43     language_setop(langC, L_TYPEMATCH, c_typematch);
44     language_setop(langC, L_BUILDAREF, c_buildaref);
45     language_setop(langC, L_EVALAREF, c_evalaref);
46     language_setop(langC, L_MODINIT, c_modinit);
47     language_setop(langC, L_HASMODULES, c_hasmodules);
48     language_setop(langC, L_PASSADDR, c_passaddr);
49 }
50 
51 /*
52  * Test if two types are compatible.
53  */
54 
55 public Boolean c_typematch(type1, type2)
56 Symbol type1, type2;
57 {
58     Boolean b;
59     register Symbol t1, t2, tmp;
60 
61     t1 = type1;
62     t2 = type2;
63     if (t1 == t2) {
64 	b = true;
65     } else {
66 	t1 = rtype(t1);
67 	t2 = rtype(t2);
68 	if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) {
69 	    tmp = t1;
70 	    t1 = t2;
71 	    t2 = tmp;
72 	}
73 	b = (Boolean) (
74 	    (
75 		isrange(t1, "int") and
76 		(t2 == t_int->type or t2 == t_char->type)
77 	    ) or (
78 		isrange(t1, "char") and
79 		(t2 == t_char->type or t2 == t_int->type)
80 	    ) or (
81 		t1->class == RANGE and isdouble(t1) and t2 == t_real->type
82 	    ) or (
83 		t1->type == t2->type and (
84 		    (t1->class == t2->class) or
85 		    (t1->class == SCAL and t2->class == CONST) or
86 		    (t1->class == CONST and t2->class == SCAL)
87 		)
88 	    ) or (
89 		t1->class == PTR and c_typematch(t1->type, t_char) and
90 		t2->class == ARRAY and c_typematch(t2->type, t_char) and
91 		t2->language == primlang
92 	    )
93 	);
94     }
95     return b;
96 }
97 
98 /*
99  * Decide if a field is a bit field.
100  */
101 
102 private Boolean isbitfield(s)
103 register Symbol s;
104 {
105     Boolean b;
106     register Integer off, len;
107     register Symbol t;
108 
109     off = s->symvalue.field.offset;
110     len = s->symvalue.field.length;
111     if ((off mod BITSPERBYTE) != 0 or (len mod BITSPERBYTE) != 0) {
112 	b = true;
113     } else {
114 	t = rtype(s->type);
115 	b = (Boolean)
116 	    (t->class == SCAL and len != (sizeof(int)*BITSPERBYTE) or
117 	    len != (size(t)*BITSPERBYTE)
118 	);
119     }
120     return b;
121 }
122 
123 /*
124  * Print out the declaration of a C variable.
125  */
126 
127 public c_printdecl(s)
128 Symbol s;
129 {
130     printdecl(s, 0);
131 }
132 
133 private printdecl(s, indent)
134 register Symbol s;
135 Integer indent;
136 {
137     register Symbol t;
138     Boolean semicolon, newline;
139 
140     semicolon = true;
141     newline = true;
142     if (indent > 0) {
143 	printf("%*c", indent, ' ');
144     }
145     if (s->class == TYPE) {
146 	printf("typedef ");
147     }
148     switch (s->class) {
149 	case CONST:
150 	    if (s->type->class == SCAL) {
151 		printf("(enumeration constant, ord %ld)",
152 		    s->symvalue.iconval);
153 	    } else {
154 		printf("const %s = ", symname(s));
155 		printval(s);
156 	    }
157 	    break;
158 
159 	case TYPE:
160 	case VAR:
161 	    if (s->class != TYPE) {
162 		if (s->level == 1 and s->block != program) {
163 		    printf("static ");
164 		} else if (s->level < 0) {
165 		    printf("register ");
166 		}
167 	    }
168 	    if (s->type->class == ARRAY) {
169 		printtype(s->type, s->type->type, indent);
170 		t = rtype(s->type->chain);
171 		assert(t->class == RANGE);
172 		printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
173 	    } else {
174 		printtype(s, s->type, indent);
175 		if (s->type->class != PTR) {
176 		    printf(" ");
177 		}
178 		printf("%s", symname(s));
179 	    }
180 	    break;
181 
182 	case FIELD:
183 	    if (s->type->class == ARRAY) {
184 		printtype(s->type, s->type->type, indent);
185 		t = rtype(s->type->chain);
186 		assert(t->class == RANGE);
187 		printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1);
188 	    } else {
189 		printtype(s, s->type, indent);
190 		if (s->type->class != PTR) {
191 		    printf(" ");
192 		}
193 		printf("%s", symname(s));
194 	    }
195 	    if (isbitfield(s)) {
196 		printf(" : %d", s->symvalue.field.length);
197 	    }
198 	    break;
199 
200 	case TAG:
201 	    if (s->type == nil) {
202 		findtype(s);
203 		if (s->type == nil) {
204 		    error("unexpected missing type information");
205 		}
206 	    }
207 	    printtype(s, s->type, indent);
208 	    break;
209 
210 	case RANGE:
211 	case ARRAY:
212 	case RECORD:
213 	case VARNT:
214 	case PTR:
215 	    semicolon = false;
216 	    printtype(s, s, indent);
217 	    break;
218 
219 	case PROC:
220 	    semicolon = false;
221 	    printf("%s", symname(s));
222 	    c_listparams(s);
223 	    newline = false;
224 	    break;
225 
226 	case FUNC:
227 	    semicolon = false;
228 	    if (not istypename(s->type, "void")) {
229 		printtype(s, s->type, indent);
230 		printf(" ");
231 	    }
232 	    printf("%s", symname(s));
233 	    c_listparams(s);
234 	    newline = false;
235 	    break;
236 
237 	case MODULE:
238 	    semicolon = false;
239 	    printf("source file \"%s.c\"", symname(s));
240 	    break;
241 
242 	case PROG:
243 	    semicolon = false;
244 	    printf("executable file \"%s\"", symname(s));
245 	    break;
246 
247 	default:
248 	    error("class %s in c_printdecl", classname(s));
249     }
250     if (semicolon) {
251 	putchar(';');
252     }
253     if (newline) {
254 	putchar('\n');
255     }
256 }
257 
258 /*
259  * Recursive whiz-bang procedure to print the type portion
260  * of a declaration.
261  *
262  * The symbol associated with the type is passed to allow
263  * searching for type names without getting "type blah = blah".
264  */
265 
266 private printtype(s, t, indent)
267 Symbol s;
268 Symbol t;
269 Integer indent;
270 {
271     register Symbol i;
272     long r0, r1;
273     register String p;
274 
275     checkref(s);
276     checkref(t);
277     switch (t->class) {
278 	case VAR:
279 	case CONST:
280 	case PROC:
281 	    panic("printtype: class %s", classname(t));
282 	    break;
283 
284 	case ARRAY:
285 	    printf("array[");
286 	    i = t->chain;
287 	    if (i != nil) {
288 		for (;;) {
289 		    printtype(i, i, indent);
290 		    i = i->chain;
291 		    if (i == nil) {
292 			break;
293 		    }
294 		    printf(", ");
295 		}
296 	    }
297 	    printf("] of ");
298 	    printtype(t, t->type, indent);
299 	    break;
300 
301 	case RECORD:
302 	case VARNT:
303 	    printf("%s ", c_classname(t));
304 	    if (s->name != nil and s->class == TAG) {
305 		p = symname(s);
306 		if (p[0] == '$' and p[1] == '$') {
307 		    printf("%s ", &p[2]);
308 		} else {
309 		    printf("%s ", p);
310 		}
311 	    }
312 	    printf("{\n", t->class == RECORD ? "struct" : "union");
313 	    for (i = t->chain; i != nil; i = i->chain) {
314 		assert(i->class == FIELD);
315 		printdecl(i, indent+4);
316 	    }
317 	    if (indent > 0) {
318 		printf("%*c", indent, ' ');
319 	    }
320 	    printf("}");
321 	    break;
322 
323 	case RANGE:
324 	    r0 = t->symvalue.rangev.lower;
325 	    r1 = t->symvalue.rangev.upper;
326 	    if (istypename(t->type, "char")) {
327 		if (r0 < 0x20 or r0 > 0x7e) {
328 		    printf("%ld..", r0);
329 		} else {
330 		    printf("'%c'..", (char) r0);
331 		}
332 		if (r1 < 0x20 or r1 > 0x7e) {
333 		    printf("\\%lo", r1);
334 		} else {
335 		    printf("'%c'", (char) r1);
336 		}
337 	    } else if (r0 > 0 and r1 == 0) {
338 		printf("%ld byte real", r0);
339 	    } else if (r0 >= 0) {
340 		printf("%lu..%lu", r0, r1);
341 	    } else {
342 		printf("%ld..%ld", r0, r1);
343 	    }
344 	    break;
345 
346 	case PTR:
347 	    printtype(t, t->type, indent);
348 	    if (t->type->class != PTR) {
349 		printf(" ");
350 	    }
351 	    printf("*");
352 	    break;
353 
354 	case FUNC:
355 	case FFUNC:
356 	    printtype(t, t->type, indent);
357 	    printf("()");
358 	    break;
359 
360 	case TYPE:
361 	    if (t->name != nil) {
362 		printname(stdout, t);
363 	    } else {
364 		printtype(t, t->type, indent);
365 	    }
366 	    break;
367 
368 	case TYPEREF:
369 	    printf("@%s", symname(t));
370 	    break;
371 
372 	case SCAL:
373 	    printf("enum ");
374 	    if (s->name != nil and s->class == TAG) {
375 		printf("%s ", symname(s));
376 	    }
377 	    printf("{ ");
378 	    i = t->chain;
379 	    if (i != nil) {
380 		for (;;) {
381 		    printf("%s", symname(i));
382 		    i = i->chain;
383 		if (i == nil) break;
384 		    printf(", ");
385 		}
386 	    }
387 	    printf(" }");
388 	    break;
389 
390 	case TAG:
391 	    if (t->type == nil) {
392 		printf("unresolved tag %s", symname(t));
393 	    } else {
394 		i = rtype(t->type);
395 		printf("%s %s", c_classname(i), symname(t));
396 	    }
397 	    break;
398 
399 	default:
400 	    printf("(class %d)", t->class);
401 	    break;
402     }
403 }
404 
405 /*
406  * List the parameters of a procedure or function.
407  * No attempt is made to combine like types.
408  */
409 
410 public c_listparams(s)
411 Symbol s;
412 {
413     register Symbol t;
414 
415     putchar('(');
416     for (t = s->chain; t != nil; t = t->chain) {
417 	printf("%s", symname(t));
418 	if (t->chain != nil) {
419 	    printf(", ");
420 	}
421     }
422     putchar(')');
423     if (s->chain != nil) {
424 	printf("\n");
425 	for (t = s->chain; t != nil; t = t->chain) {
426 	    if (t->class != VAR) {
427 		panic("unexpected class %d for parameter", t->class);
428 	    }
429 	    printdecl(t, 0);
430 	}
431     } else {
432 	putchar('\n');
433     }
434 }
435 
436 /*
437  * Print out the value on the top of the expression stack
438  * in the format for the type of the given symbol.
439  */
440 
441 public c_printval(s)
442 Symbol s;
443 {
444     register Symbol t;
445     register Address a;
446     integer i, len;
447 
448     switch (s->class) {
449 	case CONST:
450 	case TYPE:
451 	case VAR:
452 	case REF:
453 	case FVAR:
454 	case TAG:
455 	    c_printval(s->type);
456 	    break;
457 
458 	case FIELD:
459 	    if (isbitfield(s)) {
460 		i = 0;
461 		popn(size(s), &i);
462 		i >>= (s->symvalue.field.offset mod BITSPERBYTE);
463 		i &= ((1 << s->symvalue.field.length) - 1);
464 		t = rtype(s->type);
465 		if (t->class == SCAL) {
466 		    printenum(i, t);
467 		} else {
468 		    printrange(i, t);
469 		}
470 	    } else {
471 		c_printval(s->type);
472 	    }
473 	    break;
474 
475 	case ARRAY:
476 	    t = rtype(s->type);
477 	    if ((t->class == RANGE and istypename(t->type, "char")) or
478 		t == t_char->type
479 	    ) {
480 		len = size(s);
481 		sp -= len;
482 		printf("\"%.*s\"", len, sp);
483 	    } else {
484 		printarray(s);
485 	    }
486 	    break;
487 
488 	case RECORD:
489 	    c_printstruct(s);
490 	    break;
491 
492 	case RANGE:
493 	    if (istypename(s->type, "boolean")) {
494 		printrange(popsmall(s), s);
495 	    } else if (istypename(s->type, "char")) {
496 		printrange(pop(char), s);
497 	    } else if (isdouble(s)) {
498 		switch (s->symvalue.rangev.lower) {
499 		    case sizeof(float):
500 			prtreal(pop(float));
501 			break;
502 
503 		    case sizeof(double):
504 			prtreal(pop(double));
505 			break;
506 
507 		    default:
508 			panic("bad real size %d", t->symvalue.rangev.lower);
509 			break;
510 		}
511 	    } else {
512 		printrange(popsmall(s), s);
513 	    }
514 	    break;
515 
516 	case PTR:
517 	    t = rtype(s->type);
518 	    a = pop(Address);
519 	    if (a == 0) {
520 		printf("(nil)");
521 	    } else if (t->class == RANGE and istypename(t->type, "char")) {
522 		printstring(a);
523 	    } else {
524 		printf("0x%x", a);
525 	    }
526 	    break;
527 
528 	case SCAL:
529 	    i = pop(Integer);
530 	    printenum(i, s);
531 	    break;
532 
533 	default:
534 	    if (ord(s->class) > ord(TYPEREF)) {
535 		panic("printval: bad class %d", ord(s->class));
536 	    }
537 	    sp -= size(s);
538 	    printf("[%s]", c_classname(s));
539 	    break;
540     }
541 }
542 
543 /*
544  * Print out a C structure.
545  */
546 
547 private c_printstruct(s)
548 Symbol s;
549 {
550     register Symbol f;
551     register Stack *savesp;
552     register Integer n, off, len;
553 
554     sp -= size(s);
555     savesp = sp;
556     printf("(");
557     f = s->chain;
558     for (;;) {
559 	off = f->symvalue.field.offset;
560 	len = f->symvalue.field.length;
561 	n = (off + len + BITSPERBYTE - 1) div BITSPERBYTE;
562 	sp += n;
563 	printf("%s = ", symname(f));
564 	c_printval(f);
565 	sp = savesp;
566 	f = f->chain;
567     if (f == nil) break;
568 	printf(", ");
569     }
570     printf(")");
571 }
572 
573 /*
574  * Print out a range type (integer, char, or boolean).
575  */
576 
577 private printrange(i, t)
578 Integer i;
579 register Symbol t;
580 {
581     if (istypename(t->type, "boolean")) {
582 	printf(((Boolean) i) == true ? "true" : "false");
583     } else if (istypename(t->type, "char")) {
584 	putchar('\'');
585 	printchar(i);
586 	putchar('\'');
587     } else if (t->symvalue.rangev.lower >= 0) {
588 	printf("%lu", i);
589     } else {
590 	printf("%ld", i);
591     }
592 }
593 
594 /*
595  * Print out a null-terminated string (pointer to char)
596  * starting at the given address.
597  */
598 
599 private printstring(addr)
600 Address addr;
601 {
602     register Address a;
603     register Integer i, len;
604     register Boolean endofstring;
605     union {
606 	char ch[sizeof(Word)];
607 	int word;
608     } u;
609 
610     putchar('"');
611     a = addr;
612     endofstring = false;
613     while (not endofstring) {
614 	dread(&u, a, sizeof(u));
615 	i = 0;
616 	do {
617 	    if (u.ch[i] == '\0') {
618 		endofstring = true;
619 	    } else {
620 		printchar(u.ch[i]);
621 	    }
622 	    ++i;
623 	} while (i < sizeof(Word) and not endofstring);
624 	a += sizeof(Word);
625     }
626     putchar('"');
627 }
628 
629 /*
630  * Print out an enumerated value by finding the corresponding
631  * name in the enumeration list.
632  */
633 
634 private printenum(i, t)
635 Integer i;
636 Symbol t;
637 {
638     register Symbol e;
639 
640     e = t->chain;
641     while (e != nil and e->symvalue.iconval != i) {
642 	e = e->chain;
643     }
644     if (e != nil) {
645 	printf("%s", symname(e));
646     } else {
647 	printf("%d", i);
648     }
649 }
650 
651 /*
652  * Return the C name for the particular class of a symbol.
653  */
654 
655 public String c_classname(s)
656 Symbol s;
657 {
658     String str;
659 
660     switch (s->class) {
661 	case RECORD:
662 	    str = "struct";
663 	    break;
664 
665 	case VARNT:
666 	    str = "union";
667 	    break;
668 
669 	case SCAL:
670 	    str = "enum";
671 	    break;
672 
673 	default:
674 	    str = classname(s);
675     }
676     return str;
677 }
678 public Node c_buildaref(a, slist)
679 Node a, slist;
680 {
681     register Symbol t;
682     register Node p;
683     Symbol etype, atype, eltype;
684     Node esub, r;
685 
686     r = a;
687     t = rtype(a->nodetype);
688     eltype = t->type;
689     if (t->class == PTR) {
690 	p = slist->value.arg[0];
691 	if (not compatible(p->nodetype, t_int)) {
692 	    beginerrmsg();
693 	    fprintf(stderr, "bad type for subscript of ");
694 	    prtree(stderr, a);
695 	    enderrmsg();
696 	}
697 	r = build(O_MUL, p, build(O_LCON, (long) size(eltype)));
698 	r = build(O_ADD, build(O_RVAL, a), r);
699 	r->nodetype = eltype;
700     } else if (t->class != ARRAY) {
701 	beginerrmsg();
702 	prtree(stderr, a);
703 	fprintf(stderr, " is not an array");
704 	enderrmsg();
705     } else {
706 	p = slist;
707 	t = t->chain;
708 	for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) {
709 	    esub = p->value.arg[0];
710 	    etype = rtype(esub->nodetype);
711 	    atype = rtype(t);
712 	    if (not compatible(atype, etype)) {
713 		beginerrmsg();
714 		fprintf(stderr, "subscript ");
715 		prtree(stderr, esub);
716 		fprintf(stderr, " is the wrong type");
717 		enderrmsg();
718 	    }
719 	    r = build(O_INDEX, r, esub);
720 	    r->nodetype = eltype;
721 	}
722 	if (p != nil or t != nil) {
723 	    beginerrmsg();
724 	    if (p != nil) {
725 		fprintf(stderr, "too many subscripts for ");
726 	    } else {
727 		fprintf(stderr, "not enough subscripts for ");
728 	    }
729 	    prtree(stderr, a);
730 	    enderrmsg();
731 	}
732     }
733     return r;
734 }
735 
736 /*
737  * Evaluate a subscript index.
738  */
739 
740 public int c_evalaref(s, i)
741 Symbol s;
742 long i;
743 {
744     long lb, ub;
745 
746     s = rtype(s)->chain;
747     lb = s->symvalue.rangev.lower;
748     ub = s->symvalue.rangev.upper;
749     if (i < lb or i > ub) {
750 	error("subscript out of range");
751     }
752     return (i - lb);
753 }
754 
755 /*
756  * Initialize typetable information.
757  */
758 
759 public c_modinit (typetable)
760 Symbol typetable[];
761 {
762     /* nothing right now */
763 }
764 
765 public boolean c_hasmodules ()
766 {
767     return false;
768 }
769 
770 public boolean c_passaddr (param, exprtype)
771 Symbol param, exprtype;
772 {
773     boolean b;
774     Symbol t;
775 
776     t = rtype(exprtype);
777     b = (boolean) (t->class == ARRAY);
778     return b;
779 }
780