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