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