148093Sbostic /*-
2*62147Sbostic  * Copyright (c) 1980, 1993
3*62147Sbostic  *	The Regents of the University of California.  All rights reserved.
448093Sbostic  *
548093Sbostic  * %sccs.include.redist.c%
622523Sdist  */
75526Slinton 
822523Sdist #ifndef lint
9*62147Sbostic static char sccsid[] = "@(#)attributes.c	8.1 (Berkeley) 06/06/93";
1048093Sbostic #endif /* not lint */
115526Slinton 
125526Slinton /*
135526Slinton  * Functions to return the attributes of a symbol.
145526Slinton  */
155526Slinton 
165526Slinton #include "defs.h"
175526Slinton #include "sym.h"
185526Slinton #include "process.h"
195526Slinton #include "btypes.h"
205526Slinton #include "classes.h"
215526Slinton #include "sym.rep"
225526Slinton 
name(s)235526Slinton char *name(s)
245526Slinton SYM *s;
255526Slinton {
265526Slinton 	return s->symbol;
275526Slinton }
285526Slinton 
toknum(s)295526Slinton int toknum(s)
305526Slinton SYM *s;
315526Slinton {
325526Slinton 	return s->symvalue.token.toknum;
335526Slinton }
345526Slinton 
tokval(s)355526Slinton int tokval(s)
365526Slinton SYM *s;
375526Slinton {
385526Slinton 	return s->symvalue.token.tokval;
395526Slinton }
405526Slinton 
codeloc(f)415526Slinton ADDRESS codeloc(f)
425526Slinton SYM *f;
435526Slinton {
445526Slinton 	if (f == NIL) {
455526Slinton 		panic("codeloc: nil symbol");
465526Slinton 	}
475526Slinton 	if (!isblock(f)) {
485526Slinton 		panic("codeloc: %s is not a block", f->symbol);
495526Slinton 	}
505526Slinton 	return f->symvalue.funcv.codeloc;
515526Slinton }
525526Slinton 
535526Slinton /*
545526Slinton  * Rtype returns the "reduced type" given a variable.
555526Slinton  * The idea is to remove type names so we can check the class.
565526Slinton  */
575526Slinton 
rtype(t)585526Slinton SYM *rtype(t)
595526Slinton register SYM *t;
605526Slinton {
615526Slinton 	while (t->class == TYPE) {
625526Slinton 		t = t->type;
635526Slinton 	}
645526Slinton 	return t;
655526Slinton }
665526Slinton 
675526Slinton /*
685526Slinton  * Return the SYM that contains the given SYM.
695526Slinton  */
705526Slinton 
container(s)715526Slinton SYM *container(s)
725526Slinton SYM *s;
735526Slinton {
745526Slinton 	return s->func;
755526Slinton }
765526Slinton 
775526Slinton /*
785526Slinton  * Return a pointer to the string for the name of the class that
795526Slinton  * the given symbol belongs to.
805526Slinton  */
815526Slinton 
825526Slinton LOCAL char *clname[] = {
835526Slinton 	"bad use", "constant", "type", "variable", "array", "fileptr",
845526Slinton 	"record", "field", "procedure", "function", "funcvar",
855526Slinton 	"ref", "pointer", "file", "set", "range", "label", "withptr",
865526Slinton 	"scalar", "string", "program", "improper", "variant",
875526Slinton 	"procparam", "funcparam",
885526Slinton };
895526Slinton 
classname(s)905526Slinton char *classname(s)
915526Slinton SYM *s;
925526Slinton {
935526Slinton 	return clname[s->class];
945526Slinton }
955526Slinton 
965526Slinton /*
975526Slinton  * size finds the size in bytes of the given type
985526Slinton  */
995526Slinton 
1005526Slinton #define MINCHAR -128
1015526Slinton #define MAXCHAR 127
1025526Slinton #define MINSHORT -32768
1035526Slinton #define MAXSHORT 32767
1045526Slinton 
size(t)1055526Slinton int size(t)
1065526Slinton register SYM *t;
1075526Slinton {
1085526Slinton 	long lower, upper;
1095526Slinton 
1105526Slinton 	t = rtype(t);
1115526Slinton 	if (t == t_real) {
1125526Slinton 		return sizeof(double);
1135526Slinton 	}
1145526Slinton 	switch(t->class) {
1155526Slinton 		case RANGE:
1165526Slinton 			lower = t->symvalue.rangev.lower;
1175526Slinton 			upper = t->symvalue.rangev.upper;
1185526Slinton 			if (lower >= MINCHAR && upper <= MAXCHAR) {
1195526Slinton 				return sizeof(char);
1205526Slinton 			} else if (lower >= MINSHORT && upper <= MAXSHORT) {
1215526Slinton 				return sizeof(short);
1225526Slinton 			} else {
1235526Slinton 				return sizeof(long);
1245526Slinton 			}
1255526Slinton 			/* NOTREACHED */
1265526Slinton 
1275526Slinton 		case ARRAY: {
1285526Slinton 			register int nel, elsize;
1295526Slinton 			register SYM *s;
1305526Slinton 
1315526Slinton 			elsize = size(t->type);
1325526Slinton 			nel = 1;
1335526Slinton 			for (t = t->chain; t != NIL; t = t->chain) {
1345526Slinton 				s = rtype(t);
1355526Slinton 				lower = s->symvalue.rangev.lower;
1365526Slinton 				upper = s->symvalue.rangev.upper;
1375526Slinton 				nel *= (upper-lower+1);
1385526Slinton 			}
1395526Slinton 			return nel*elsize;
1405526Slinton 		}
1415526Slinton 
1425526Slinton 		case CONST:
1435526Slinton 		case VAR:
1445526Slinton 		case FVAR:
1455526Slinton 		case FIELD:
1465526Slinton 			return size(t->type);
1475526Slinton 
1485526Slinton 		case RECORD:
1495526Slinton 			return t->symvalue.offset;
1505526Slinton 
1515526Slinton 		case PTR:
1525526Slinton 		case REF:
1535526Slinton 		case FILET:
1545526Slinton 			return sizeof(int);
1555526Slinton 
1565526Slinton 		case SCAL:
1575526Slinton 			if (t->symvalue.iconval > 255) {
1585526Slinton 				return sizeof(short);
1595526Slinton 			} else {
1605526Slinton 				return sizeof(char);
1615526Slinton 			}
1625526Slinton 			/* NOTREACHED */
1635526Slinton 
1645526Slinton 		case FPROC:
1655526Slinton 		case FFUNC:
1665526Slinton 			return sizeof(ADDRESS *);
1675526Slinton 
1685526Slinton 		default:
1695526Slinton 			if (t->class < BADUSE || t->class > FFUNC) {
1705526Slinton 				panic("size: bad class (%d)", t->class);
1715526Slinton 			} else {
1725526Slinton 				error("improper operation on a %s", classname(t));
1735526Slinton 			}
1745526Slinton 			/* NOTREACHED */
1755526Slinton 	}
1765526Slinton }
177