19659Slinton /* Copyright (c) 1982 Regents of the University of California */ 29659Slinton 3*16606Ssam static char sccsid[] = "@(#)c.c 1.6 8/5/83"; 49659Slinton 5*16606Ssam static char rcsid[] = "$Header: c.c,v 1.3 84/03/27 10:19:40 linton Exp $"; 6*16606Ssam 79659Slinton /* 89659Slinton * C-dependent symbol routines. 99659Slinton */ 109659Slinton 119659Slinton #include "defs.h" 129659Slinton #include "symbols.h" 139659Slinton #include "printsym.h" 149659Slinton #include "languages.h" 159659Slinton #include "c.h" 169659Slinton #include "tree.h" 179659Slinton #include "eval.h" 189659Slinton #include "operators.h" 199659Slinton #include "mappings.h" 209659Slinton #include "process.h" 219659Slinton #include "runtime.h" 229659Slinton #include "machine.h" 239659Slinton 2412559Scsvaf #ifndef public 2512559Scsvaf # include "tree.h" 2612559Scsvaf #endif 2712559Scsvaf 289659Slinton #define isdouble(range) ( \ 299659Slinton range->symvalue.rangev.upper == 0 and range->symvalue.rangev.lower > 0 \ 309659Slinton ) 319659Slinton 329659Slinton #define isrange(t, name) (t->class == RANGE and istypename(t->type, name)) 339659Slinton 34*16606Ssam private Language langC; 35*16606Ssam 369659Slinton /* 379659Slinton * Initialize C language information. 389659Slinton */ 399659Slinton 409659Slinton public c_init() 419659Slinton { 42*16606Ssam langC = language_define("c", ".c"); 43*16606Ssam language_setop(langC, L_PRINTDECL, c_printdecl); 44*16606Ssam language_setop(langC, L_PRINTVAL, c_printval); 45*16606Ssam language_setop(langC, L_TYPEMATCH, c_typematch); 46*16606Ssam language_setop(langC, L_BUILDAREF, c_buildaref); 47*16606Ssam language_setop(langC, L_EVALAREF, c_evalaref); 48*16606Ssam language_setop(langC, L_MODINIT, c_modinit); 49*16606Ssam language_setop(langC, L_HASMODULES, c_hasmodules); 50*16606Ssam language_setop(langC, L_PASSADDR, c_passaddr); 519659Slinton } 529659Slinton 539659Slinton /* 549659Slinton * Test if two types are compatible. 559659Slinton */ 569659Slinton 579659Slinton public Boolean c_typematch(type1, type2) 589659Slinton Symbol type1, type2; 599659Slinton { 609659Slinton Boolean b; 619659Slinton register Symbol t1, t2, tmp; 629659Slinton 639659Slinton t1 = type1; 649659Slinton t2 = type2; 659659Slinton if (t1 == t2) { 669659Slinton b = true; 679659Slinton } else { 689659Slinton t1 = rtype(t1); 699659Slinton t2 = rtype(t2); 70*16606Ssam if (t1 == t_char->type or t1 == t_int->type or t1 == t_real->type) { 719659Slinton tmp = t1; 729659Slinton t1 = t2; 739659Slinton t2 = tmp; 749659Slinton } 759659Slinton b = (Boolean) ( 769659Slinton ( 779659Slinton isrange(t1, "int") and 78*16606Ssam (t2 == t_int->type or t2 == t_char->type) 799659Slinton ) or ( 809659Slinton isrange(t1, "char") and 81*16606Ssam (t2 == t_char->type or t2 == t_int->type) 829659Slinton ) or ( 83*16606Ssam t1->class == RANGE and isdouble(t1) and t2 == t_real->type 8413839Slinton ) or ( 859659Slinton t1->type == t2->type and ( 869659Slinton (t1->class == t2->class) or 879659Slinton (t1->class == SCAL and t2->class == CONST) or 889659Slinton (t1->class == CONST and t2->class == SCAL) 899659Slinton ) 90*16606Ssam ) or ( 91*16606Ssam t1->class == PTR and c_typematch(t1->type, t_char) and 92*16606Ssam t2->class == ARRAY and c_typematch(t2->type, t_char) and 93*16606Ssam t2->language == primlang 949659Slinton ) 959659Slinton ); 969659Slinton } 979659Slinton return b; 989659Slinton } 999659Slinton 1009659Slinton /* 1019659Slinton * Decide if a field is a bit field. 1029659Slinton */ 1039659Slinton 1049659Slinton private Boolean isbitfield(s) 1059659Slinton register Symbol s; 1069659Slinton { 1079659Slinton Boolean b; 1089659Slinton register Integer off, len; 1099659Slinton register Symbol t; 1109659Slinton 1119659Slinton off = s->symvalue.field.offset; 1129659Slinton len = s->symvalue.field.length; 1139659Slinton if ((off mod BITSPERBYTE) != 0 or (len mod BITSPERBYTE) != 0) { 1149659Slinton b = true; 1159659Slinton } else { 1169659Slinton t = rtype(s->type); 1179659Slinton b = (Boolean) 1189659Slinton (t->class == SCAL and len != (sizeof(int)*BITSPERBYTE) or 1199659Slinton len != (size(t)*BITSPERBYTE) 1209659Slinton ); 1219659Slinton } 1229659Slinton return b; 1239659Slinton } 1249659Slinton 1259659Slinton /* 1269659Slinton * Print out the declaration of a C variable. 1279659Slinton */ 1289659Slinton 1299659Slinton public c_printdecl(s) 1309659Slinton Symbol s; 1319659Slinton { 1329659Slinton printdecl(s, 0); 1339659Slinton } 1349659Slinton 1359659Slinton private printdecl(s, indent) 1369659Slinton register Symbol s; 1379659Slinton Integer indent; 1389659Slinton { 1399659Slinton register Symbol t; 1409659Slinton Boolean semicolon, newline; 1419659Slinton 1429659Slinton semicolon = true; 1439659Slinton newline = true; 1449659Slinton if (indent > 0) { 1459659Slinton printf("%*c", indent, ' '); 1469659Slinton } 1479659Slinton if (s->class == TYPE) { 1489659Slinton printf("typedef "); 1499659Slinton } 1509659Slinton switch (s->class) { 1519659Slinton case CONST: 1529659Slinton if (s->type->class == SCAL) { 1539659Slinton printf("(enumeration constant, ord %ld)", 1549659Slinton s->symvalue.iconval); 1559659Slinton } else { 1569659Slinton printf("const %s = ", symname(s)); 1579659Slinton printval(s); 1589659Slinton } 1599659Slinton break; 1609659Slinton 1619659Slinton case TYPE: 1629659Slinton case VAR: 1639659Slinton if (s->class != TYPE) { 164*16606Ssam if (s->level == 1 and s->block != program) { 1659659Slinton printf("static "); 1669659Slinton } else if (s->level < 0) { 1679659Slinton printf("register "); 1689659Slinton } 1699659Slinton } 1709659Slinton if (s->type->class == ARRAY) { 1719659Slinton printtype(s->type, s->type->type, indent); 1729659Slinton t = rtype(s->type->chain); 1739659Slinton assert(t->class == RANGE); 1749659Slinton printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1); 1759659Slinton } else { 1769659Slinton printtype(s, s->type, indent); 1779659Slinton if (s->type->class != PTR) { 1789659Slinton printf(" "); 1799659Slinton } 1809659Slinton printf("%s", symname(s)); 1819659Slinton } 1829659Slinton break; 1839659Slinton 1849659Slinton case FIELD: 1859659Slinton if (s->type->class == ARRAY) { 1869659Slinton printtype(s->type, s->type->type, indent); 1879659Slinton t = rtype(s->type->chain); 1889659Slinton assert(t->class == RANGE); 1899659Slinton printf(" %s[%d]", symname(s), t->symvalue.rangev.upper + 1); 1909659Slinton } else { 1919659Slinton printtype(s, s->type, indent); 1929659Slinton if (s->type->class != PTR) { 1939659Slinton printf(" "); 1949659Slinton } 1959659Slinton printf("%s", symname(s)); 1969659Slinton } 1979659Slinton if (isbitfield(s)) { 1989659Slinton printf(" : %d", s->symvalue.field.length); 1999659Slinton } 2009659Slinton break; 2019659Slinton 2029659Slinton case TAG: 2039659Slinton if (s->type == nil) { 2049659Slinton findtype(s); 2059659Slinton if (s->type == nil) { 2069659Slinton error("unexpected missing type information"); 2079659Slinton } 2089659Slinton } 2099659Slinton printtype(s, s->type, indent); 2109659Slinton break; 2119659Slinton 2129659Slinton case RANGE: 2139659Slinton case ARRAY: 2149659Slinton case RECORD: 2159659Slinton case VARNT: 2169659Slinton case PTR: 2179659Slinton semicolon = false; 2189659Slinton printtype(s, s, indent); 2199659Slinton break; 2209659Slinton 2219659Slinton case PROC: 2229659Slinton semicolon = false; 2239659Slinton printf("%s", symname(s)); 2249659Slinton c_listparams(s); 2259659Slinton newline = false; 2269659Slinton break; 2279659Slinton 2289659Slinton case FUNC: 2299659Slinton semicolon = false; 2309659Slinton if (not istypename(s->type, "void")) { 2319659Slinton printtype(s, s->type, indent); 2329659Slinton printf(" "); 2339659Slinton } 2349659Slinton printf("%s", symname(s)); 2359659Slinton c_listparams(s); 2369659Slinton newline = false; 2379659Slinton break; 2389659Slinton 2399659Slinton case MODULE: 2409659Slinton semicolon = false; 2419659Slinton printf("source file \"%s.c\"", symname(s)); 2429659Slinton break; 2439659Slinton 2449659Slinton case PROG: 2459659Slinton semicolon = false; 2469659Slinton printf("executable file \"%s\"", symname(s)); 2479659Slinton break; 2489659Slinton 2499659Slinton default: 2509659Slinton error("class %s in c_printdecl", classname(s)); 2519659Slinton } 2529659Slinton if (semicolon) { 2539659Slinton putchar(';'); 2549659Slinton } 2559659Slinton if (newline) { 2569659Slinton putchar('\n'); 2579659Slinton } 2589659Slinton } 2599659Slinton 2609659Slinton /* 2619659Slinton * Recursive whiz-bang procedure to print the type portion 2629659Slinton * of a declaration. 2639659Slinton * 2649659Slinton * The symbol associated with the type is passed to allow 2659659Slinton * searching for type names without getting "type blah = blah". 2669659Slinton */ 2679659Slinton 2689659Slinton private printtype(s, t, indent) 2699659Slinton Symbol s; 2709659Slinton Symbol t; 2719659Slinton Integer indent; 2729659Slinton { 2739659Slinton register Symbol i; 2749659Slinton long r0, r1; 2759659Slinton register String p; 2769659Slinton 2779659Slinton checkref(s); 2789659Slinton checkref(t); 2799659Slinton switch (t->class) { 2809659Slinton case VAR: 2819659Slinton case CONST: 2829659Slinton case PROC: 2839659Slinton panic("printtype: class %s", classname(t)); 2849659Slinton break; 2859659Slinton 2869659Slinton case ARRAY: 2879659Slinton printf("array["); 2889659Slinton i = t->chain; 2899659Slinton if (i != nil) { 2909659Slinton for (;;) { 2919659Slinton printtype(i, i, indent); 2929659Slinton i = i->chain; 2939659Slinton if (i == nil) { 2949659Slinton break; 2959659Slinton } 2969659Slinton printf(", "); 2979659Slinton } 2989659Slinton } 2999659Slinton printf("] of "); 3009659Slinton printtype(t, t->type, indent); 3019659Slinton break; 3029659Slinton 3039659Slinton case RECORD: 3049659Slinton case VARNT: 3059659Slinton printf("%s ", c_classname(t)); 3069659Slinton if (s->name != nil and s->class == TAG) { 3079659Slinton p = symname(s); 3089659Slinton if (p[0] == '$' and p[1] == '$') { 3099659Slinton printf("%s ", &p[2]); 3109659Slinton } else { 3119659Slinton printf("%s ", p); 3129659Slinton } 3139659Slinton } 3149659Slinton printf("{\n", t->class == RECORD ? "struct" : "union"); 3159659Slinton for (i = t->chain; i != nil; i = i->chain) { 3169659Slinton assert(i->class == FIELD); 3179659Slinton printdecl(i, indent+4); 3189659Slinton } 3199659Slinton if (indent > 0) { 3209659Slinton printf("%*c", indent, ' '); 3219659Slinton } 3229659Slinton printf("}"); 3239659Slinton break; 3249659Slinton 3259659Slinton case RANGE: 3269659Slinton r0 = t->symvalue.rangev.lower; 3279659Slinton r1 = t->symvalue.rangev.upper; 3289659Slinton if (istypename(t->type, "char")) { 3299659Slinton if (r0 < 0x20 or r0 > 0x7e) { 3309659Slinton printf("%ld..", r0); 3319659Slinton } else { 3329659Slinton printf("'%c'..", (char) r0); 3339659Slinton } 3349659Slinton if (r1 < 0x20 or r1 > 0x7e) { 3359659Slinton printf("\\%lo", r1); 3369659Slinton } else { 3379659Slinton printf("'%c'", (char) r1); 3389659Slinton } 3399659Slinton } else if (r0 > 0 and r1 == 0) { 3409659Slinton printf("%ld byte real", r0); 3419659Slinton } else if (r0 >= 0) { 3429659Slinton printf("%lu..%lu", r0, r1); 3439659Slinton } else { 3449659Slinton printf("%ld..%ld", r0, r1); 3459659Slinton } 3469659Slinton break; 3479659Slinton 3489659Slinton case PTR: 3499659Slinton printtype(t, t->type, indent); 3509659Slinton if (t->type->class != PTR) { 3519659Slinton printf(" "); 3529659Slinton } 3539659Slinton printf("*"); 3549659Slinton break; 3559659Slinton 3569659Slinton case FUNC: 357*16606Ssam case FFUNC: 3589659Slinton printtype(t, t->type, indent); 3599659Slinton printf("()"); 3609659Slinton break; 3619659Slinton 3629659Slinton case TYPE: 3639659Slinton if (t->name != nil) { 364*16606Ssam printname(stdout, t); 3659659Slinton } else { 3669659Slinton printtype(t, t->type, indent); 3679659Slinton } 3689659Slinton break; 3699659Slinton 3709659Slinton case TYPEREF: 3719659Slinton printf("@%s", symname(t)); 3729659Slinton break; 3739659Slinton 3749659Slinton case SCAL: 3759659Slinton printf("enum "); 3769659Slinton if (s->name != nil and s->class == TAG) { 3779659Slinton printf("%s ", symname(s)); 3789659Slinton } 3799659Slinton printf("{ "); 3809659Slinton i = t->chain; 3819659Slinton if (i != nil) { 3829659Slinton for (;;) { 3839659Slinton printf("%s", symname(i)); 3849659Slinton i = i->chain; 3859659Slinton if (i == nil) break; 3869659Slinton printf(", "); 3879659Slinton } 3889659Slinton } 3899659Slinton printf(" }"); 3909659Slinton break; 3919659Slinton 3929659Slinton case TAG: 3939659Slinton if (t->type == nil) { 3949659Slinton printf("unresolved tag %s", symname(t)); 3959659Slinton } else { 3969659Slinton i = rtype(t->type); 3979659Slinton printf("%s %s", c_classname(i), symname(t)); 3989659Slinton } 3999659Slinton break; 4009659Slinton 4019659Slinton default: 4029659Slinton printf("(class %d)", t->class); 4039659Slinton break; 4049659Slinton } 4059659Slinton } 4069659Slinton 4079659Slinton /* 4089659Slinton * List the parameters of a procedure or function. 4099659Slinton * No attempt is made to combine like types. 4109659Slinton */ 4119659Slinton 4129659Slinton public c_listparams(s) 4139659Slinton Symbol s; 4149659Slinton { 4159659Slinton register Symbol t; 4169659Slinton 4179659Slinton putchar('('); 4189659Slinton for (t = s->chain; t != nil; t = t->chain) { 4199659Slinton printf("%s", symname(t)); 4209659Slinton if (t->chain != nil) { 4219659Slinton printf(", "); 4229659Slinton } 4239659Slinton } 4249659Slinton putchar(')'); 4259659Slinton if (s->chain != nil) { 4269659Slinton printf("\n"); 4279659Slinton for (t = s->chain; t != nil; t = t->chain) { 4289659Slinton if (t->class != VAR) { 4299659Slinton panic("unexpected class %d for parameter", t->class); 4309659Slinton } 4319659Slinton printdecl(t, 0); 4329659Slinton } 4339659Slinton } else { 4349659Slinton putchar('\n'); 4359659Slinton } 4369659Slinton } 4379659Slinton 4389659Slinton /* 4399659Slinton * Print out the value on the top of the expression stack 4409659Slinton * in the format for the type of the given symbol. 4419659Slinton */ 4429659Slinton 4439659Slinton public c_printval(s) 4449659Slinton Symbol s; 4459659Slinton { 4469659Slinton register Symbol t; 4479659Slinton register Address a; 448*16606Ssam integer i, len; 4499659Slinton 4509659Slinton switch (s->class) { 4519659Slinton case CONST: 4529659Slinton case TYPE: 4539659Slinton case VAR: 4549659Slinton case REF: 4559659Slinton case FVAR: 4569659Slinton case TAG: 4579659Slinton c_printval(s->type); 4589659Slinton break; 4599659Slinton 4609659Slinton case FIELD: 4619659Slinton if (isbitfield(s)) { 462*16606Ssam i = 0; 463*16606Ssam popn(size(s), &i); 4649659Slinton i >>= (s->symvalue.field.offset mod BITSPERBYTE); 465*16606Ssam i &= ((1 << s->symvalue.field.length) - 1); 4669659Slinton t = rtype(s->type); 4679659Slinton if (t->class == SCAL) { 4689659Slinton printenum(i, t); 4699659Slinton } else { 4709659Slinton printrange(i, t); 4719659Slinton } 4729659Slinton } else { 4739659Slinton c_printval(s->type); 4749659Slinton } 4759659Slinton break; 4769659Slinton 4779659Slinton case ARRAY: 4789659Slinton t = rtype(s->type); 479*16606Ssam if ((t->class == RANGE and istypename(t->type, "char")) or 480*16606Ssam t == t_char->type 481*16606Ssam ) { 4829659Slinton len = size(s); 4839659Slinton sp -= len; 4849659Slinton printf("\"%.*s\"", len, sp); 4859659Slinton } else { 4869659Slinton printarray(s); 4879659Slinton } 4889659Slinton break; 4899659Slinton 4909659Slinton case RECORD: 4919659Slinton c_printstruct(s); 4929659Slinton break; 4939659Slinton 4949659Slinton case RANGE: 4959659Slinton if (istypename(s->type, "boolean")) { 4969659Slinton printrange(popsmall(s), s); 4979659Slinton } else if (istypename(s->type, "char")) { 4989659Slinton printrange(pop(char), s); 4999659Slinton } else if (isdouble(s)) { 5009659Slinton switch (s->symvalue.rangev.lower) { 5019659Slinton case sizeof(float): 5029659Slinton prtreal(pop(float)); 5039659Slinton break; 5049659Slinton 5059659Slinton case sizeof(double): 5069659Slinton prtreal(pop(double)); 5079659Slinton break; 5089659Slinton 5099659Slinton default: 5109659Slinton panic("bad real size %d", t->symvalue.rangev.lower); 5119659Slinton break; 5129659Slinton } 5139659Slinton } else { 5149659Slinton printrange(popsmall(s), s); 5159659Slinton } 5169659Slinton break; 5179659Slinton 5189659Slinton case PTR: 5199659Slinton t = rtype(s->type); 5209659Slinton a = pop(Address); 5219659Slinton if (a == 0) { 5229659Slinton printf("(nil)"); 5239659Slinton } else if (t->class == RANGE and istypename(t->type, "char")) { 5249659Slinton printstring(a); 5259659Slinton } else { 5269659Slinton printf("0x%x", a); 5279659Slinton } 5289659Slinton break; 5299659Slinton 5309659Slinton case SCAL: 5319659Slinton i = pop(Integer); 5329659Slinton printenum(i, s); 5339659Slinton break; 5349659Slinton 5359659Slinton default: 5369659Slinton if (ord(s->class) > ord(TYPEREF)) { 5379659Slinton panic("printval: bad class %d", ord(s->class)); 5389659Slinton } 53914382Slinton sp -= size(s); 540*16606Ssam printf("[%s]", c_classname(s)); 54114382Slinton break; 5429659Slinton } 5439659Slinton } 5449659Slinton 5459659Slinton /* 5469659Slinton * Print out a C structure. 5479659Slinton */ 5489659Slinton 5499659Slinton private c_printstruct(s) 5509659Slinton Symbol s; 5519659Slinton { 5529659Slinton register Symbol f; 5539659Slinton register Stack *savesp; 5549659Slinton register Integer n, off, len; 5559659Slinton 5569659Slinton sp -= size(s); 5579659Slinton savesp = sp; 5589659Slinton printf("("); 5599659Slinton f = s->chain; 5609659Slinton for (;;) { 5619659Slinton off = f->symvalue.field.offset; 5629659Slinton len = f->symvalue.field.length; 563*16606Ssam n = (off + len + BITSPERBYTE - 1) div BITSPERBYTE; 5649659Slinton sp += n; 5659659Slinton printf("%s = ", symname(f)); 5669659Slinton c_printval(f); 5679659Slinton sp = savesp; 5689659Slinton f = f->chain; 5699659Slinton if (f == nil) break; 5709659Slinton printf(", "); 5719659Slinton } 5729659Slinton printf(")"); 5739659Slinton } 5749659Slinton 5759659Slinton /* 5769659Slinton * Print out a range type (integer, char, or boolean). 5779659Slinton */ 5789659Slinton 5799659Slinton private printrange(i, t) 5809659Slinton Integer i; 5819659Slinton register Symbol t; 5829659Slinton { 5839659Slinton if (istypename(t->type, "boolean")) { 5849659Slinton printf(((Boolean) i) == true ? "true" : "false"); 5859659Slinton } else if (istypename(t->type, "char")) { 5869659Slinton putchar('\''); 5879659Slinton printchar(i); 5889659Slinton putchar('\''); 5899659Slinton } else if (t->symvalue.rangev.lower >= 0) { 5909659Slinton printf("%lu", i); 5919659Slinton } else { 5929659Slinton printf("%ld", i); 5939659Slinton } 5949659Slinton } 5959659Slinton 5969659Slinton /* 5979659Slinton * Print out a null-terminated string (pointer to char) 5989659Slinton * starting at the given address. 5999659Slinton */ 6009659Slinton 6019659Slinton private printstring(addr) 6029659Slinton Address addr; 6039659Slinton { 6049659Slinton register Address a; 6059659Slinton register Integer i, len; 6069659Slinton register Boolean endofstring; 6079659Slinton union { 6089659Slinton char ch[sizeof(Word)]; 6099659Slinton int word; 6109659Slinton } u; 6119659Slinton 6129659Slinton putchar('"'); 6139659Slinton a = addr; 6149659Slinton endofstring = false; 6159659Slinton while (not endofstring) { 6169659Slinton dread(&u, a, sizeof(u)); 6179659Slinton i = 0; 6189659Slinton do { 6199659Slinton if (u.ch[i] == '\0') { 6209659Slinton endofstring = true; 6219659Slinton } else { 6229659Slinton printchar(u.ch[i]); 6239659Slinton } 6249659Slinton ++i; 6259659Slinton } while (i < sizeof(Word) and not endofstring); 6269659Slinton a += sizeof(Word); 6279659Slinton } 6289659Slinton putchar('"'); 6299659Slinton } 6309659Slinton 6319659Slinton /* 6329659Slinton * Print out an enumerated value by finding the corresponding 6339659Slinton * name in the enumeration list. 6349659Slinton */ 6359659Slinton 6369659Slinton private printenum(i, t) 6379659Slinton Integer i; 6389659Slinton Symbol t; 6399659Slinton { 6409659Slinton register Symbol e; 6419659Slinton 6429659Slinton e = t->chain; 6439659Slinton while (e != nil and e->symvalue.iconval != i) { 6449659Slinton e = e->chain; 6459659Slinton } 6469659Slinton if (e != nil) { 6479659Slinton printf("%s", symname(e)); 6489659Slinton } else { 6499659Slinton printf("%d", i); 6509659Slinton } 6519659Slinton } 6529659Slinton 6539659Slinton /* 6549659Slinton * Return the C name for the particular class of a symbol. 6559659Slinton */ 6569659Slinton 6579659Slinton public String c_classname(s) 6589659Slinton Symbol s; 6599659Slinton { 6609659Slinton String str; 6619659Slinton 6629659Slinton switch (s->class) { 6639659Slinton case RECORD: 6649659Slinton str = "struct"; 6659659Slinton break; 6669659Slinton 6679659Slinton case VARNT: 6689659Slinton str = "union"; 6699659Slinton break; 6709659Slinton 6719659Slinton case SCAL: 6729659Slinton str = "enum"; 6739659Slinton break; 6749659Slinton 6759659Slinton default: 6769659Slinton str = classname(s); 6779659Slinton } 6789659Slinton return str; 6799659Slinton } 68012533Scsvaf public Node c_buildaref(a, slist) 68112533Scsvaf Node a, slist; 68212533Scsvaf { 68312533Scsvaf register Symbol t; 68412533Scsvaf register Node p; 68512533Scsvaf Symbol etype, atype, eltype; 68612533Scsvaf Node esub, r; 68712533Scsvaf 68812533Scsvaf r = a; 68912533Scsvaf t = rtype(a->nodetype); 69012533Scsvaf eltype = t->type; 69112533Scsvaf if (t->class == PTR) { 69212533Scsvaf p = slist->value.arg[0]; 69312533Scsvaf if (not compatible(p->nodetype, t_int)) { 69412533Scsvaf beginerrmsg(); 69512533Scsvaf fprintf(stderr, "bad type for subscript of "); 69612533Scsvaf prtree(stderr, a); 69712533Scsvaf enderrmsg(); 69812533Scsvaf } 69912533Scsvaf r = build(O_MUL, p, build(O_LCON, (long) size(eltype))); 70012533Scsvaf r = build(O_ADD, build(O_RVAL, a), r); 70112533Scsvaf r->nodetype = eltype; 70212533Scsvaf } else if (t->class != ARRAY) { 70312533Scsvaf beginerrmsg(); 70412533Scsvaf prtree(stderr, a); 70512533Scsvaf fprintf(stderr, " is not an array"); 70612533Scsvaf enderrmsg(); 70712533Scsvaf } else { 70812533Scsvaf p = slist; 70912533Scsvaf t = t->chain; 71012533Scsvaf for (; p != nil and t != nil; p = p->value.arg[1], t = t->chain) { 71112533Scsvaf esub = p->value.arg[0]; 71212533Scsvaf etype = rtype(esub->nodetype); 71312533Scsvaf atype = rtype(t); 71412533Scsvaf if (not compatible(atype, etype)) { 71512533Scsvaf beginerrmsg(); 71612533Scsvaf fprintf(stderr, "subscript "); 71712533Scsvaf prtree(stderr, esub); 71812533Scsvaf fprintf(stderr, " is the wrong type"); 71912533Scsvaf enderrmsg(); 72012533Scsvaf } 72112533Scsvaf r = build(O_INDEX, r, esub); 72212533Scsvaf r->nodetype = eltype; 72312533Scsvaf } 72412533Scsvaf if (p != nil or t != nil) { 72512533Scsvaf beginerrmsg(); 72612533Scsvaf if (p != nil) { 72712533Scsvaf fprintf(stderr, "too many subscripts for "); 72812533Scsvaf } else { 72912533Scsvaf fprintf(stderr, "not enough subscripts for "); 73012533Scsvaf } 73112533Scsvaf prtree(stderr, a); 73212533Scsvaf enderrmsg(); 73312533Scsvaf } 73412533Scsvaf } 73512533Scsvaf return r; 73612533Scsvaf } 73712533Scsvaf 73812533Scsvaf /* 73912533Scsvaf * Evaluate a subscript index. 74012533Scsvaf */ 74112533Scsvaf 74212533Scsvaf public int c_evalaref(s, i) 74312533Scsvaf Symbol s; 74412533Scsvaf long i; 74512533Scsvaf { 74612533Scsvaf long lb, ub; 74712533Scsvaf 74812533Scsvaf s = rtype(s)->chain; 74912533Scsvaf lb = s->symvalue.rangev.lower; 75012533Scsvaf ub = s->symvalue.rangev.upper; 75112533Scsvaf if (i < lb or i > ub) { 75212533Scsvaf error("subscript out of range"); 75312533Scsvaf } 75412533Scsvaf return (i - lb); 75512533Scsvaf } 756*16606Ssam 757*16606Ssam /* 758*16606Ssam * Initialize typetable information. 759*16606Ssam */ 760*16606Ssam 761*16606Ssam public c_modinit (typetable) 762*16606Ssam Symbol typetable[]; 763*16606Ssam { 764*16606Ssam /* nothing right now */ 765*16606Ssam } 766*16606Ssam 767*16606Ssam public boolean c_hasmodules () 768*16606Ssam { 769*16606Ssam return false; 770*16606Ssam } 771*16606Ssam 772*16606Ssam public boolean c_passaddr (param, exprtype) 773*16606Ssam Symbol param, exprtype; 774*16606Ssam { 775*16606Ssam boolean b; 776*16606Ssam Symbol t; 777*16606Ssam 778*16606Ssam t = rtype(exprtype); 779*16606Ssam b = (boolean) (t->class == ARRAY); 780*16606Ssam return b; 781*16606Ssam } 782