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