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