1*22524Sdist /* 2*22524Sdist * Copyright (c) 1980 Regents of the University of California. 3*22524Sdist * All rights reserved. The Berkeley software License Agreement 4*22524Sdist * specifies the terms and conditions for redistribution. 5*22524Sdist */ 65527Slinton 7*22524Sdist #ifndef lint 8*22524Sdist static char sccsid[] = "@(#)predicates.c 5.1 (Berkeley) 06/06/85"; 9*22524Sdist #endif not lint 105527Slinton /* 115527Slinton * The basic tests on a symbol. 125527Slinton */ 135527Slinton 145527Slinton #include "defs.h" 155527Slinton #include "sym.h" 165527Slinton #include "symtab.h" 175564Slinton #include "btypes.h" 185527Slinton #include "classes.h" 195527Slinton #include "sym.rep" 205527Slinton 215527Slinton /* 225527Slinton * Test if a symbol is a parameter. This is true if there 235527Slinton * is a cycle from s->func to s via chain pointers. 245527Slinton */ 255527Slinton 265527Slinton BOOLEAN isparam(s) 275527Slinton SYM *s; 285527Slinton { 295885Slinton register SYM *t; 305527Slinton 315885Slinton for (t = s->func; t != NIL; t = t->chain) { 325885Slinton if (t == s) { 335885Slinton return(TRUE); 345527Slinton } 355885Slinton } 365885Slinton return(FALSE); 375527Slinton } 385527Slinton 395527Slinton /* 405527Slinton * Test if a symbol is a var parameter, i.e. has class REF. 415527Slinton */ 425527Slinton 435527Slinton BOOLEAN isvarparam(s) 445527Slinton SYM *s; 455527Slinton { 465885Slinton return (BOOLEAN) s->class == REF; 475527Slinton } 485527Slinton 495527Slinton /* 505885Slinton * Test if a symbol is a variable (actually any addressible quantity 515885Slinton * with do). 525885Slinton */ 535885Slinton 545885Slinton BOOLEAN isvariable(s) 555885Slinton SYM *s; 565885Slinton { 575885Slinton return s->class == VAR || s->class == FVAR || s->class == REF; 585885Slinton } 595885Slinton 605885Slinton /* 615527Slinton * Test if a symbol is a block, e.g. function, procedure, or the 625527Slinton * main program. 635527Slinton */ 645527Slinton 655527Slinton BOOLEAN isblock(s) 665527Slinton register SYM *s; 675527Slinton { 685885Slinton return(s->class == FUNC || s->class == PROC || s->class == PROG); 695527Slinton } 705527Slinton 715527Slinton /* 725527Slinton * Test if a symbol is builtin, that is, a predefined type or 735527Slinton * reserved word. 745527Slinton */ 755527Slinton 765527Slinton BOOLEAN isbuiltin(s) 775527Slinton SYM *s; 785527Slinton { 795885Slinton return(s->blkno == 0 && s->class != PROG && s->class != VAR); 805527Slinton } 815527Slinton 825527Slinton /* 835527Slinton * Compatible tests if two types are compatible. The issue 845527Slinton * is complicated a bit by ranges. 855527Slinton * 865527Slinton * Integers and reals are not compatible since they cannot always be mixed. 875527Slinton */ 885527Slinton 895527Slinton BOOLEAN compatible(t1, t2) 905527Slinton register SYM *t1, *t2; 915527Slinton { 926580Slinton register BOOLEAN b; 936580Slinton 946580Slinton if (isvariable(t1)) { 956580Slinton t1 = t1->type; 966580Slinton } 976580Slinton if (isvariable(t2)) { 986580Slinton t2 = t2->type; 996580Slinton } 1005885Slinton if (t1 == t2) { 1016580Slinton b = TRUE; 1026580Slinton } else { 1036580Slinton t1 = rtype(t1); 1046580Slinton t2 = rtype(t2); 1056580Slinton if (t1->type == t2->type) { 1066580Slinton if (t1->class == RANGE && t2->class == RANGE) { 1076580Slinton b = TRUE; 1086580Slinton } else if ((t1->class == SCAL || t1->class == CONST) && 1096580Slinton (t2->class == SCAL || t2->class == CONST)) { 1106580Slinton b = TRUE; 1116580Slinton } else if (t1->type == t_char && 1126580Slinton t1->class == ARRAY && t2->class == ARRAY) { 1136580Slinton b = TRUE; 1146580Slinton } else { 1156580Slinton b = FALSE; 1166580Slinton } 1176580Slinton /* 1186580Slinton * A kludge here for "nil". Should be handled better. 1196580Slinton * Opens a pandora's box for integer/pointer compatibility. 1206580Slinton */ 1216580Slinton } else if ((t1->class == RANGE && t2->class == PTR) || 1226580Slinton (t2->class == RANGE && t1->class == PTR)) { 1236580Slinton b = TRUE; 1246580Slinton } else { 1256580Slinton b = FALSE; 1265527Slinton } 1275885Slinton } 1286580Slinton return b; 1295527Slinton } 1305527Slinton 1315527Slinton /* 1325527Slinton * Predicate to test if a symbol should be printed. We don't print 1335527Slinton * files, for example, simply because there's no good way to do it. 1345527Slinton * The symbol must be within the given function. 1355527Slinton */ 1365527Slinton 1375527Slinton BOOLEAN should_print(s, f) 1385527Slinton SYM *s; 1395527Slinton SYM *f; 1405527Slinton { 1415885Slinton SYM *t; 1425527Slinton 1435885Slinton if (s->func != f || (s->class != VAR && s->class != FVAR)) { 1445885Slinton return(FALSE); 1455885Slinton } else if (s->chain != NIL) { 1465885Slinton return(FALSE); 1475885Slinton } else { 1485885Slinton t = rtype(s->type); 1495885Slinton if (t == NIL || t->class == FILET || t->class == SET) { 1505885Slinton return(FALSE); 1515527Slinton } else { 1525885Slinton return(TRUE); 1535527Slinton } 1545885Slinton } 1555527Slinton } 1565527Slinton 1575527Slinton /* 1585527Slinton * Test if the name of a symbol is uniquely defined or not. 1595527Slinton */ 1605527Slinton 1615527Slinton BOOLEAN isambiguous(s) 1625527Slinton SYM *s; 1635527Slinton { 1645885Slinton SYM *t; 1655527Slinton 1665885Slinton t = st_lookup(symtab, s->symbol); 1675885Slinton if (t == NIL) { 1685885Slinton panic("symbol name vanished"); 1695885Slinton } 1705885Slinton while (t != NIL && (s == t || !streq(t->symbol, s->symbol))) { 1715885Slinton t = t->next_sym; 1725885Slinton } 1735885Slinton return t != NIL; 1745527Slinton } 175