1*48093Sbostic /*- 2*48093Sbostic * Copyright (c) 1980 The Regents of the University of California. 3*48093Sbostic * All rights reserved. 4*48093Sbostic * 5*48093Sbostic * %sccs.include.redist.c% 622524Sdist */ 75527Slinton 822524Sdist #ifndef lint 9*48093Sbostic static char sccsid[] = "@(#)predicates.c 5.2 (Berkeley) 04/16/91"; 10*48093Sbostic #endif /* not lint */ 11*48093Sbostic 125527Slinton /* 135527Slinton * The basic tests on a symbol. 145527Slinton */ 155527Slinton 165527Slinton #include "defs.h" 175527Slinton #include "sym.h" 185527Slinton #include "symtab.h" 195564Slinton #include "btypes.h" 205527Slinton #include "classes.h" 215527Slinton #include "sym.rep" 225527Slinton 235527Slinton /* 245527Slinton * Test if a symbol is a parameter. This is true if there 255527Slinton * is a cycle from s->func to s via chain pointers. 265527Slinton */ 275527Slinton 285527Slinton BOOLEAN isparam(s) 295527Slinton SYM *s; 305527Slinton { 315885Slinton register SYM *t; 325527Slinton 335885Slinton for (t = s->func; t != NIL; t = t->chain) { 345885Slinton if (t == s) { 355885Slinton return(TRUE); 365527Slinton } 375885Slinton } 385885Slinton return(FALSE); 395527Slinton } 405527Slinton 415527Slinton /* 425527Slinton * Test if a symbol is a var parameter, i.e. has class REF. 435527Slinton */ 445527Slinton 455527Slinton BOOLEAN isvarparam(s) 465527Slinton SYM *s; 475527Slinton { 485885Slinton return (BOOLEAN) s->class == REF; 495527Slinton } 505527Slinton 515527Slinton /* 525885Slinton * Test if a symbol is a variable (actually any addressible quantity 535885Slinton * with do). 545885Slinton */ 555885Slinton 565885Slinton BOOLEAN isvariable(s) 575885Slinton SYM *s; 585885Slinton { 595885Slinton return s->class == VAR || s->class == FVAR || s->class == REF; 605885Slinton } 615885Slinton 625885Slinton /* 635527Slinton * Test if a symbol is a block, e.g. function, procedure, or the 645527Slinton * main program. 655527Slinton */ 665527Slinton 675527Slinton BOOLEAN isblock(s) 685527Slinton register SYM *s; 695527Slinton { 705885Slinton return(s->class == FUNC || s->class == PROC || s->class == PROG); 715527Slinton } 725527Slinton 735527Slinton /* 745527Slinton * Test if a symbol is builtin, that is, a predefined type or 755527Slinton * reserved word. 765527Slinton */ 775527Slinton 785527Slinton BOOLEAN isbuiltin(s) 795527Slinton SYM *s; 805527Slinton { 815885Slinton return(s->blkno == 0 && s->class != PROG && s->class != VAR); 825527Slinton } 835527Slinton 845527Slinton /* 855527Slinton * Compatible tests if two types are compatible. The issue 865527Slinton * is complicated a bit by ranges. 875527Slinton * 885527Slinton * Integers and reals are not compatible since they cannot always be mixed. 895527Slinton */ 905527Slinton 915527Slinton BOOLEAN compatible(t1, t2) 925527Slinton register SYM *t1, *t2; 935527Slinton { 946580Slinton register BOOLEAN b; 956580Slinton 966580Slinton if (isvariable(t1)) { 976580Slinton t1 = t1->type; 986580Slinton } 996580Slinton if (isvariable(t2)) { 1006580Slinton t2 = t2->type; 1016580Slinton } 1025885Slinton if (t1 == t2) { 1036580Slinton b = TRUE; 1046580Slinton } else { 1056580Slinton t1 = rtype(t1); 1066580Slinton t2 = rtype(t2); 1076580Slinton if (t1->type == t2->type) { 1086580Slinton if (t1->class == RANGE && t2->class == RANGE) { 1096580Slinton b = TRUE; 1106580Slinton } else if ((t1->class == SCAL || t1->class == CONST) && 1116580Slinton (t2->class == SCAL || t2->class == CONST)) { 1126580Slinton b = TRUE; 1136580Slinton } else if (t1->type == t_char && 1146580Slinton t1->class == ARRAY && t2->class == ARRAY) { 1156580Slinton b = TRUE; 1166580Slinton } else { 1176580Slinton b = FALSE; 1186580Slinton } 1196580Slinton /* 1206580Slinton * A kludge here for "nil". Should be handled better. 1216580Slinton * Opens a pandora's box for integer/pointer compatibility. 1226580Slinton */ 1236580Slinton } else if ((t1->class == RANGE && t2->class == PTR) || 1246580Slinton (t2->class == RANGE && t1->class == PTR)) { 1256580Slinton b = TRUE; 1266580Slinton } else { 1276580Slinton b = FALSE; 1285527Slinton } 1295885Slinton } 1306580Slinton return b; 1315527Slinton } 1325527Slinton 1335527Slinton /* 1345527Slinton * Predicate to test if a symbol should be printed. We don't print 1355527Slinton * files, for example, simply because there's no good way to do it. 1365527Slinton * The symbol must be within the given function. 1375527Slinton */ 1385527Slinton 1395527Slinton BOOLEAN should_print(s, f) 1405527Slinton SYM *s; 1415527Slinton SYM *f; 1425527Slinton { 1435885Slinton SYM *t; 1445527Slinton 1455885Slinton if (s->func != f || (s->class != VAR && s->class != FVAR)) { 1465885Slinton return(FALSE); 1475885Slinton } else if (s->chain != NIL) { 1485885Slinton return(FALSE); 1495885Slinton } else { 1505885Slinton t = rtype(s->type); 1515885Slinton if (t == NIL || t->class == FILET || t->class == SET) { 1525885Slinton return(FALSE); 1535527Slinton } else { 1545885Slinton return(TRUE); 1555527Slinton } 1565885Slinton } 1575527Slinton } 1585527Slinton 1595527Slinton /* 1605527Slinton * Test if the name of a symbol is uniquely defined or not. 1615527Slinton */ 1625527Slinton 1635527Slinton BOOLEAN isambiguous(s) 1645527Slinton SYM *s; 1655527Slinton { 1665885Slinton SYM *t; 1675527Slinton 1685885Slinton t = st_lookup(symtab, s->symbol); 1695885Slinton if (t == NIL) { 1705885Slinton panic("symbol name vanished"); 1715885Slinton } 1725885Slinton while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) { 1735885Slinton t = t->next_sym; 1745885Slinton } 1755885Slinton return t != NIL; 1765527Slinton } 177