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