1*5526Slinton /* Copyright (c) 1982 Regents of the University of California */ 2*5526Slinton 3*5526Slinton static char sccsid[] = "@(#)attributes.c 1.1 01/18/82"; 4*5526Slinton 5*5526Slinton /* 6*5526Slinton * Functions to return the attributes of a symbol. 7*5526Slinton */ 8*5526Slinton 9*5526Slinton #include "defs.h" 10*5526Slinton #include "sym.h" 11*5526Slinton #include "process.h" 12*5526Slinton #include "btypes.h" 13*5526Slinton #include "classes.h" 14*5526Slinton #include "sym.rep" 15*5526Slinton 16*5526Slinton char *name(s) 17*5526Slinton SYM *s; 18*5526Slinton { 19*5526Slinton return s->symbol; 20*5526Slinton } 21*5526Slinton 22*5526Slinton int toknum(s) 23*5526Slinton SYM *s; 24*5526Slinton { 25*5526Slinton return s->symvalue.token.toknum; 26*5526Slinton } 27*5526Slinton 28*5526Slinton int tokval(s) 29*5526Slinton SYM *s; 30*5526Slinton { 31*5526Slinton return s->symvalue.token.tokval; 32*5526Slinton } 33*5526Slinton 34*5526Slinton ADDRESS codeloc(f) 35*5526Slinton SYM *f; 36*5526Slinton { 37*5526Slinton if (f == NIL) { 38*5526Slinton panic("codeloc: nil symbol"); 39*5526Slinton } 40*5526Slinton if (!isblock(f)) { 41*5526Slinton panic("codeloc: %s is not a block", f->symbol); 42*5526Slinton } 43*5526Slinton return f->symvalue.funcv.codeloc; 44*5526Slinton } 45*5526Slinton 46*5526Slinton /* 47*5526Slinton * Rtype returns the "reduced type" given a variable. 48*5526Slinton * The idea is to remove type names so we can check the class. 49*5526Slinton */ 50*5526Slinton 51*5526Slinton SYM *rtype(t) 52*5526Slinton register SYM *t; 53*5526Slinton { 54*5526Slinton while (t->class == TYPE) { 55*5526Slinton t = t->type; 56*5526Slinton } 57*5526Slinton return t; 58*5526Slinton } 59*5526Slinton 60*5526Slinton /* 61*5526Slinton * Return the SYM that contains the given SYM. 62*5526Slinton */ 63*5526Slinton 64*5526Slinton SYM *container(s) 65*5526Slinton SYM *s; 66*5526Slinton { 67*5526Slinton return s->func; 68*5526Slinton } 69*5526Slinton 70*5526Slinton /* 71*5526Slinton * Return a pointer to the string for the name of the class that 72*5526Slinton * the given symbol belongs to. 73*5526Slinton */ 74*5526Slinton 75*5526Slinton LOCAL char *clname[] = { 76*5526Slinton "bad use", "constant", "type", "variable", "array", "fileptr", 77*5526Slinton "record", "field", "procedure", "function", "funcvar", 78*5526Slinton "ref", "pointer", "file", "set", "range", "label", "withptr", 79*5526Slinton "scalar", "string", "program", "improper", "variant", 80*5526Slinton "procparam", "funcparam", 81*5526Slinton }; 82*5526Slinton 83*5526Slinton char *classname(s) 84*5526Slinton SYM *s; 85*5526Slinton { 86*5526Slinton return clname[s->class]; 87*5526Slinton } 88*5526Slinton 89*5526Slinton /* 90*5526Slinton * size finds the size in bytes of the given type 91*5526Slinton */ 92*5526Slinton 93*5526Slinton #define MINCHAR -128 94*5526Slinton #define MAXCHAR 127 95*5526Slinton #define MINSHORT -32768 96*5526Slinton #define MAXSHORT 32767 97*5526Slinton 98*5526Slinton int size(t) 99*5526Slinton register SYM *t; 100*5526Slinton { 101*5526Slinton long lower, upper; 102*5526Slinton 103*5526Slinton t = rtype(t); 104*5526Slinton if (t == t_real) { 105*5526Slinton return sizeof(double); 106*5526Slinton } 107*5526Slinton switch(t->class) { 108*5526Slinton case RANGE: 109*5526Slinton lower = t->symvalue.rangev.lower; 110*5526Slinton upper = t->symvalue.rangev.upper; 111*5526Slinton if (lower >= MINCHAR && upper <= MAXCHAR) { 112*5526Slinton return sizeof(char); 113*5526Slinton } else if (lower >= MINSHORT && upper <= MAXSHORT) { 114*5526Slinton return sizeof(short); 115*5526Slinton } else { 116*5526Slinton return sizeof(long); 117*5526Slinton } 118*5526Slinton /* NOTREACHED */ 119*5526Slinton 120*5526Slinton case ARRAY: { 121*5526Slinton register int nel, elsize; 122*5526Slinton register SYM *s; 123*5526Slinton 124*5526Slinton elsize = size(t->type); 125*5526Slinton nel = 1; 126*5526Slinton for (t = t->chain; t != NIL; t = t->chain) { 127*5526Slinton s = rtype(t); 128*5526Slinton lower = s->symvalue.rangev.lower; 129*5526Slinton upper = s->symvalue.rangev.upper; 130*5526Slinton nel *= (upper-lower+1); 131*5526Slinton } 132*5526Slinton return nel*elsize; 133*5526Slinton } 134*5526Slinton 135*5526Slinton case CONST: 136*5526Slinton case VAR: 137*5526Slinton case FVAR: 138*5526Slinton case FIELD: 139*5526Slinton return size(t->type); 140*5526Slinton 141*5526Slinton case RECORD: 142*5526Slinton return t->symvalue.offset; 143*5526Slinton 144*5526Slinton case PTR: 145*5526Slinton case REF: 146*5526Slinton case FILET: 147*5526Slinton return sizeof(int); 148*5526Slinton 149*5526Slinton case SCAL: 150*5526Slinton if (t->symvalue.iconval > 255) { 151*5526Slinton return sizeof(short); 152*5526Slinton } else { 153*5526Slinton return sizeof(char); 154*5526Slinton } 155*5526Slinton /* NOTREACHED */ 156*5526Slinton 157*5526Slinton case FPROC: 158*5526Slinton case FFUNC: 159*5526Slinton return sizeof(ADDRESS *); 160*5526Slinton 161*5526Slinton default: 162*5526Slinton if (t->class < BADUSE || t->class > FFUNC) { 163*5526Slinton panic("size: bad class (%d)", t->class); 164*5526Slinton } else { 165*5526Slinton error("improper operation on a %s", classname(t)); 166*5526Slinton } 167*5526Slinton /* NOTREACHED */ 168*5526Slinton } 169*5526Slinton } 170