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