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