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