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