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