|
|
1.1 ! root 1: /* ! 2: * The routines in this file deal with the declaration of names. ! 3: * The declaration stuff is done here; the parsing is done elsewhere. ! 4: */ ! 5: #ifdef vax ! 6: #include "INC$LIB:cc0.h" ! 7: #else ! 8: #include "cc0.h" ! 9: #endif ! 10: ! 11: /* ! 12: * This array maps function and parameter types ! 13: * into their defined interface types. ! 14: * fixtype() below knows about this table; ! 15: * if it changes, fixtype() might change too. ! 16: */ ! 17: static char xtype[] = { ! 18: T_NONE, /* T_NONE, */ ! 19: T_INT, T_UINT, /* T_CHAR, T_UCHAR, */ ! 20: T_INT, T_UINT, /* T_SHORT, T_USHORT, */ ! 21: T_INT, T_UINT, /* T_INT, T_UINT, */ ! 22: T_PTR, /* T_PTR, */ ! 23: T_LONG, T_ULONG, /* T_LONG, T_ULONG, */ ! 24: T_DOUBLE, T_DOUBLE, /* T_FLOAT, T_DOUBLE, */ ! 25: T_VOID, /* T_VOID, */ ! 26: T_STRUCT, T_FSTRUCT, /* T_STRUCT, T_FSTRUCT, */ ! 27: T_UNION, T_FUNION, /* T_UNION, T_FUNION, */ ! 28: T_INT, T_INT /* T_ENUM, T_FENUM */ ! 29: }; ! 30: ! 31: /* ! 32: * Declare a variable 'sp' with class 'c', type 't' and structure info 'ip'. ! 33: * Many checks are made here for redeclarations and funny things. ! 34: * For objects of class 'C_MOE', 'x1' is the enumeration value. ! 35: * For objects of class 'C_MOS' and 'C_MOU', ! 36: * 'x1' is the field width in bits and 'x2' is the long offset in bits. ! 37: * 'ronlyf' passes both 'readonly' and 'alien' modifiers. ! 38: */ ! 39: SYM * ! 40: declare(sp, c, t, ndp, ip, ronlyf, x1, x2) ! 41: register SYM *sp; ! 42: DIM *ndp; ! 43: INFO *ip; ! 44: unsigned long x2; ! 45: { ! 46: register DIM *dp, *xdp; ! 47: int af, ff, rf; ! 48: int oc, ot; ! 49: unsigned long value; ! 50: unsigned offs; ! 51: ! 52: /* ! 53: * Demote some function definitions to references. ! 54: * Adjust the return type of functions returning char, short or float. ! 55: * If the s_level is wrong, due to missing "extern", check ! 56: * for redeclaration. ! 57: */ ! 58: if (ndp!=NULL && ndp->d_type==D_FUNC) { ! 59: if (c==C_AUTO || c==C_PAUTO || c==C_SIN ! 60: || ((c==C_GDEF || c==C_SEX) && (s==SEMI || s==COMMA))) ! 61: c = C_GREF; ! 62: if (ndp->d_dp==NULL && ((ronlyf&S_ALIEN)==0 || t==T_FLOAT)) ! 63: t = fixtype(t, sp, "function"); ! 64: if (sp->s_level > LL_EXT) ! 65: sp = fixlevel(sp); ! 66: } ! 67: /* ! 68: * Make certain that the declarator is not ! 69: * forbidden by the semantics of C. The declaration ! 70: * reader allows anything that exhibits correct ! 71: * syntax through. ! 72: */ ! 73: if (c!=C_TYPE && t==T_VOID && !isfunction(ndp)) { ! 74: cerror("illegal use of \"void\" type"); ! 75: t = T_INT; ! 76: } ! 77: af = ff = rf = 0; ! 78: for (dp=ndp; dp!=NULL; dp=dp->d_dp) { ! 79: switch (dp->d_type) { ! 80: ! 81: case D_ARRAY: ! 82: if (ff != 0) ! 83: cerror("function cannot return an array"); ! 84: if ((xdp = dp->d_dp) != NULL /* [10][] */ ! 85: && xdp->d_type == D_ARRAY ! 86: && xdp->d_bound == 0) ! 87: cerror("bad flexible array declaration"); ! 88: af = 1; ! 89: ff = 0; ! 90: break; ! 91: ! 92: case D_FUNC: ! 93: if (ff != 0) ! 94: cerror("function cannot return a function"); ! 95: else if (af != 0) ! 96: cerror("cannot declare array of functions"); ! 97: af = 0; ! 98: ff = 1; ! 99: break; ! 100: ! 101: case D_PTR: ! 102: af = ff = 0; ! 103: } ! 104: } ! 105: if (ff!=0 && istruct(t)) ! 106: notbook(); ! 107: /* ! 108: * Check for redeclarations. ! 109: * If the old is "C_ARG" (a function parameter), ! 110: * then just about any combination is ok. ! 111: * The types are adjusted in consideration of the passing rules. ! 112: * Other redeclarations are typechecked. ! 113: */ ! 114: ot = sp->s_type; ! 115: oc = sp->s_class; ! 116: if (oc == C_ARG) { ! 117: dp = ndp; ! 118: if (dp == NULL || isfunction(dp)) { ! 119: t = fixtype(t, sp, "parameter"); ! 120: if (istruct(t)) ! 121: notbook(); ! 122: } else if (dp->d_type == D_ARRAY) { ! 123: dp->d_type = D_PTR; ! 124: dp->d_bound = 0; ! 125: } else if (dp->d_type != D_PTR) ! 126: cerror("functions cannot be parameters"); ! 127: } else if (c==C_PAUTO || c==C_PREG) { ! 128: cerror("identifier \"%s\" is not a parameter", sp->s_id); ! 129: c = C_AUTO; ! 130: } else if ((c==C_AUTO || c==C_REG) ! 131: && ndp!=NULL && ndp->d_type==D_ARRAY && ndp->d_bound==0) { ! 132: cerror("cannot declare flexible automatic array"); ! 133: } else if (ot!=T_NONE && ot!=t && !ismemb(oc)) { ! 134: ++rf; ! 135: } else if (oc == C_CXT) { ! 136: if (ndp == NULL || ndp->d_type != D_FUNC || ronlyf != 0) ! 137: ++rf; ! 138: } else if (oc==C_MOE && c==C_MOE) { ! 139: if (sp->s_value != x1) ! 140: ++rf; ! 141: } else if (ismemb(oc) && ismemb(c)) { ! 142: value = x2/NBPBYTE; ! 143: offs = x2%NBPBYTE; ! 144: if (doalign(t) && x1 != 0 && (value&1) != 0) { ! 145: --value; ! 146: offs += 8; ! 147: } ! 148: if (x1 != sp->s_width ! 149: || value != sp->s_value ! 150: || offs != sp->s_offset) ! 151: ++rf; ! 152: } else if (isdefn(oc) && isdefn(c)) { ! 153: if (oc!=C_GREF && c!=C_GREF) ! 154: ++rf; ! 155: else if (c == C_GREF) ! 156: c = oc; ! 157: } else if (oc != C_NONE) ! 158: ++rf; ! 159: if (oc != C_NONE && (sp->s_flag&ronlyf) != ronlyf) ! 160: ++rf; ! 161: sp->s_class = c; ! 162: sp->s_type = t; ! 163: dropdim(sp->s_dp); ! 164: sp->s_dp = ndp; ! 165: sp->s_dline = line; ! 166: sp->s_flag |= ronlyf; ! 167: if ((ronlyf&S_ALIEN) != 0) { ! 168: if ( ! isdefn(c) || ndp==NULL || ndp->d_type!=D_FUNC) ! 169: cerror("inappropriate \"alien\" modifier"); ! 170: sp->s_seg = SALIEN; ! 171: } ! 172: if (istag(oc) || ot==T_STRUCT || ot==T_UNION || ot==T_ENUM) { ! 173: dropinfo(sp->s_ip); ! 174: sp->s_ip = NULL; ! 175: } ! 176: if (istag(c) || t>T_DOUBLE) { ! 177: sp->s_ip = ip; ! 178: if (istag(c) || t==T_STRUCT || t==T_UNION || t==T_ENUM) ! 179: ++ip->i_refc; ! 180: } ! 181: if (istag(c)) ! 182: backplug(sp); ! 183: if (c == C_MOE) ! 184: sp->s_value = x1; ! 185: if (ismemb(c)) { ! 186: value = x2/NBPBYTE; ! 187: offs = x2%NBPBYTE; ! 188: if (doalign(t) && x1 != 0 && (value&1) != 0) { ! 189: --value; ! 190: offs += 8; ! 191: } ! 192: if (value > MAXMEMB) ! 193: cerror("member \"%s\" is not addressable", sp->s_id); ! 194: sp->s_width = x1; ! 195: sp->s_value = value; ! 196: sp->s_offset = offs; ! 197: } ! 198: if (rf != 0) ! 199: cerror("identifier \"%s\" is being redeclared", sp->s_id); ! 200: return(sp); ! 201: } ! 202: ! 203: /* ! 204: * Decrement reference count of a ! 205: * structure info. block. ! 206: * Free it if the block is now an ! 207: * unreferenced one. ! 208: */ ! 209: dropinfo(ip) ! 210: register INFO *ip; ! 211: { ! 212: if (ip!=NULL && --ip->i_refc==0) ! 213: free((char *) ip); ! 214: } ! 215: ! 216: /* ! 217: * Test if a storage class is a global ! 218: * storage class. ! 219: */ ! 220: isdefn(c) ! 221: register int c; ! 222: { ! 223: if (c==C_GDEF || c==C_GREF || c==C_SEX || c==C_SIN) ! 224: return (1); ! 225: return (0); ! 226: } ! 227: ! 228: /* ! 229: * Test if a type is one of the structure ! 230: * like types. ! 231: */ ! 232: istruct(t) ! 233: { ! 234: if (t>=T_STRUCT && t<=T_FUNION) ! 235: return (1); ! 236: return (0); ! 237: } ! 238: ! 239: /* ! 240: * Test for tag classes. ! 241: */ ! 242: istag(c) ! 243: register int c; ! 244: { ! 245: if (c==C_STAG || c==C_UTAG || c==C_ETAG) ! 246: return (1); ! 247: return (0); ! 248: } ! 249: ! 250: /* ! 251: * Test for one of the type definition classes. ! 252: */ ! 253: istype(c) ! 254: register int c; ! 255: { ! 256: if (c==C_STAG || c==C_UTAG || c==C_ETAG || c==C_TYPE) ! 257: return (1); ! 258: return (0); ! 259: } ! 260: ! 261: /* ! 262: * Test for member classes. ! 263: */ ! 264: ismemb(c) ! 265: register int c; ! 266: { ! 267: if (c==C_MOS || c==C_MOU) ! 268: return (1); ! 269: return (0); ! 270: } ! 271: ! 272: /* ! 273: * Examine a "DIM" chain to see if it describes a function. ! 274: */ ! 275: isfunction(dp) ! 276: register DIM *dp; ! 277: { ! 278: register int n; ! 279: ! 280: for (n = 0; dp!=NULL; dp = dp->d_dp) ! 281: n = (dp->d_type == D_FUNC); ! 282: return (n); ! 283: } ! 284: ! 285: /* ! 286: * Given a type t, return the adjusted type xtype[t]. ! 287: * Issue a "type adjusted" warning for dangerous cases. ! 288: * This does not determine "dangerous" rigorously, ! 289: * rather it uses facts about the values in xtype[] above; ! 290: * the only cases in which xtype[t]!=t are ! 291: * char->int, uchar->uint, short->int, ushort->uint, float->double. ! 292: */ ! 293: fixtype(t, sp, s) ! 294: register int t; ! 295: SYM *sp; ! 296: char *s; ! 297: { ! 298: register int xt; ! 299: char *ntype; ! 300: ! 301: xt = xtype[t]; ! 302: if (xt != t && mysizes[xt] != mysizes[t]) { ! 303: switch(xt) { ! 304: case T_INT: ! 305: ntype = "int"; ! 306: break; ! 307: case T_UINT: ! 308: ntype = "unsigned int"; ! 309: break; ! 310: case T_DOUBLE: ! 311: ntype = "double"; ! 312: break; ! 313: } ! 314: if (isvariant(VWIDEN)) ! 315: cwarn("type of %s \"%s\" adjusted to %s", s, sp->s_id, ntype); ! 316: } ! 317: return(xt); ! 318: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.