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