| 1 | /* $Id: trees.c,v 1.272.2.1 2011/03/01 17:39:28 ragge Exp $ */
|
|---|
| 2 | /*
|
|---|
| 3 | * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
|
|---|
| 4 | * All rights reserved.
|
|---|
| 5 | *
|
|---|
| 6 | * Redistribution and use in source and binary forms, with or without
|
|---|
| 7 | * modification, are permitted provided that the following conditions
|
|---|
| 8 | * are met:
|
|---|
| 9 | * 1. Redistributions of source code must retain the above copyright
|
|---|
| 10 | * notice, this list of conditions and the following disclaimer.
|
|---|
| 11 | * 2. Redistributions in binary form must reproduce the above copyright
|
|---|
| 12 | * notice, this list of conditions and the following disclaimer in the
|
|---|
| 13 | * documentation and/or other materials provided with the distribution.
|
|---|
| 14 | * 3. The name of the author may not be used to endorse or promote products
|
|---|
| 15 | * derived from this software without specific prior written permission
|
|---|
| 16 | *
|
|---|
| 17 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|---|
| 18 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|---|
| 19 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|---|
| 20 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|---|
| 21 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|---|
| 22 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|---|
| 23 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|---|
| 24 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|---|
| 25 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|---|
| 26 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|---|
| 27 | */
|
|---|
| 28 |
|
|---|
| 29 | /*
|
|---|
| 30 | * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
|
|---|
| 31 | *
|
|---|
| 32 | * Redistribution and use in source and binary forms, with or without
|
|---|
| 33 | * modification, are permitted provided that the following conditions
|
|---|
| 34 | * are met:
|
|---|
| 35 | *
|
|---|
| 36 | * Redistributions of source code and documentation must retain the above
|
|---|
| 37 | * copyright notice, this list of conditions and the following disclaimer.
|
|---|
| 38 | * Redistributions in binary form must reproduce the above copyright
|
|---|
| 39 | * notice, this list of conditionsand the following disclaimer in the
|
|---|
| 40 | * documentation and/or other materials provided with the distribution.
|
|---|
| 41 | * All advertising materials mentioning features or use of this software
|
|---|
| 42 | * must display the following acknowledgement:
|
|---|
| 43 | * This product includes software developed or owned by Caldera
|
|---|
| 44 | * International, Inc.
|
|---|
| 45 | * Neither the name of Caldera International, Inc. nor the names of other
|
|---|
| 46 | * contributors may be used to endorse or promote products derived from
|
|---|
| 47 | * this software without specific prior written permission.
|
|---|
| 48 | *
|
|---|
| 49 | * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
|
|---|
| 50 | * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
|
|---|
| 51 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|---|
| 52 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|---|
| 53 | * DISCLAIMED. IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
|
|---|
| 54 | * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|---|
| 55 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|---|
| 56 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|---|
| 57 | * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
|
|---|
| 58 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
|---|
| 59 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|---|
| 60 | * POSSIBILITY OF SUCH DAMAGE.
|
|---|
| 61 | */
|
|---|
| 62 | /*
|
|---|
| 63 | * Some of the changes from 32V include:
|
|---|
| 64 | * - Understand "void" as type.
|
|---|
| 65 | * - Handle enums as ints everywhere.
|
|---|
| 66 | * - Convert some C-specific ops into branches.
|
|---|
| 67 | */
|
|---|
| 68 |
|
|---|
| 69 | # include "pass1.h"
|
|---|
| 70 | # include "pass2.h"
|
|---|
| 71 |
|
|---|
| 72 | # include <stdarg.h>
|
|---|
| 73 | # include <string.h>
|
|---|
| 74 |
|
|---|
| 75 | /* standard macros conflict with identifiers in this file */
|
|---|
| 76 | #ifdef true
|
|---|
| 77 | #undef true
|
|---|
| 78 | #undef false
|
|---|
| 79 | #endif
|
|---|
| 80 |
|
|---|
| 81 | static void chkpun(NODE *p);
|
|---|
| 82 | static int opact(NODE *p);
|
|---|
| 83 | static int moditype(TWORD);
|
|---|
| 84 | static NODE *strargs(NODE *);
|
|---|
| 85 | static void rmcops(NODE *p);
|
|---|
| 86 | void putjops(NODE *, void *);
|
|---|
| 87 | static struct symtab *findmember(struct symtab *, char *);
|
|---|
| 88 | int inftn; /* currently between epilog/prolog */
|
|---|
| 89 |
|
|---|
| 90 | static char *tnames[] = {
|
|---|
| 91 | "undef",
|
|---|
| 92 | "farg",
|
|---|
| 93 | "char",
|
|---|
| 94 | "unsigned char",
|
|---|
| 95 | "short",
|
|---|
| 96 | "unsigned short",
|
|---|
| 97 | "int",
|
|---|
| 98 | "unsigned int",
|
|---|
| 99 | "long",
|
|---|
| 100 | "unsigned long",
|
|---|
| 101 | "long long",
|
|---|
| 102 | "unsigned long long",
|
|---|
| 103 | "float",
|
|---|
| 104 | "double",
|
|---|
| 105 | "long double",
|
|---|
| 106 | "strty",
|
|---|
| 107 | "unionty",
|
|---|
| 108 | "enumty",
|
|---|
| 109 | "moety",
|
|---|
| 110 | "void",
|
|---|
| 111 | "signed", /* pass1 */
|
|---|
| 112 | "bool", /* pass1 */
|
|---|
| 113 | "fimag", /* pass1 */
|
|---|
| 114 | "dimag", /* pass1 */
|
|---|
| 115 | "limag", /* pass1 */
|
|---|
| 116 | "fcomplex", /* pass1 */
|
|---|
| 117 | "dcomplex", /* pass1 */
|
|---|
| 118 | "lcomplex", /* pass1 */
|
|---|
| 119 | "enumty", /* pass1 */
|
|---|
| 120 | "?", "?"
|
|---|
| 121 | };
|
|---|
| 122 |
|
|---|
| 123 | /* some special actions, used in finding the type of nodes */
|
|---|
| 124 | # define NCVT 01
|
|---|
| 125 | # define PUN 02
|
|---|
| 126 | # define TYPL 04
|
|---|
| 127 | # define TYPR 010
|
|---|
| 128 | # define TYMATCH 040
|
|---|
| 129 | # define LVAL 0100
|
|---|
| 130 | # define CVTO 0200
|
|---|
| 131 | # define CVTL 0400
|
|---|
| 132 | # define CVTR 01000
|
|---|
| 133 | # define PTMATCH 02000
|
|---|
| 134 | # define OTHER 04000
|
|---|
| 135 | # define NCVTR 010000
|
|---|
| 136 |
|
|---|
| 137 | /* node conventions:
|
|---|
| 138 |
|
|---|
| 139 | NAME: rval>0 is stab index for external
|
|---|
| 140 | rval<0 is -inlabel number
|
|---|
| 141 | lval is offset in bits
|
|---|
| 142 | ICON: lval has the value
|
|---|
| 143 | rval has the STAB index, or - label number,
|
|---|
| 144 | if a name whose address is in the constant
|
|---|
| 145 | rval = NONAME means no name
|
|---|
| 146 | REG: rval is reg. identification cookie
|
|---|
| 147 |
|
|---|
| 148 | */
|
|---|
| 149 |
|
|---|
| 150 | int bdebug = 0;
|
|---|
| 151 | extern int negrel[];
|
|---|
| 152 |
|
|---|
| 153 | NODE *
|
|---|
| 154 | buildtree(int o, NODE *l, NODE *r)
|
|---|
| 155 | {
|
|---|
| 156 | NODE *p, *q;
|
|---|
| 157 | int actions;
|
|---|
| 158 | int opty;
|
|---|
| 159 | struct symtab *sp = NULL; /* XXX gcc */
|
|---|
| 160 | NODE *lr, *ll;
|
|---|
| 161 |
|
|---|
| 162 | #ifdef PCC_DEBUG
|
|---|
| 163 | if (bdebug) {
|
|---|
| 164 | printf("buildtree(%s, %p, %p)\n", copst(o), l, r);
|
|---|
| 165 | if (l) fwalk(l, eprint, 0);
|
|---|
| 166 | if (r) fwalk(r, eprint, 0);
|
|---|
| 167 | }
|
|---|
| 168 | #endif
|
|---|
| 169 | opty = coptype(o);
|
|---|
| 170 |
|
|---|
| 171 | /* check for constants */
|
|---|
| 172 |
|
|---|
| 173 | if (o == ANDAND || o == OROR || o == NOT) {
|
|---|
| 174 | if (l->n_op == FCON) {
|
|---|
| 175 | p = bcon(!FLOAT_ISZERO(l->n_dcon));
|
|---|
| 176 | nfree(l);
|
|---|
| 177 | l = p;
|
|---|
| 178 | }
|
|---|
| 179 | if (o != NOT && r->n_op == FCON) {
|
|---|
| 180 | p = bcon(!FLOAT_ISZERO(r->n_dcon));
|
|---|
| 181 | nfree(r);
|
|---|
| 182 | r = p;
|
|---|
| 183 | }
|
|---|
| 184 | }
|
|---|
| 185 |
|
|---|
| 186 | if( opty == UTYPE && l->n_op == ICON ){
|
|---|
| 187 |
|
|---|
| 188 | switch( o ){
|
|---|
| 189 |
|
|---|
| 190 | case NOT:
|
|---|
| 191 | case UMINUS:
|
|---|
| 192 | case COMPL:
|
|---|
| 193 | if( conval( l, o, l ) ) return(l);
|
|---|
| 194 | break;
|
|---|
| 195 | }
|
|---|
| 196 | } else if (o == NOT && l->n_op == FCON) {
|
|---|
| 197 | l = clocal(block(SCONV, l, NIL, INT, 0, MKAP(INT)));
|
|---|
| 198 | } else if( o == UMINUS && l->n_op == FCON ){
|
|---|
| 199 | l->n_dcon = FLOAT_NEG(l->n_dcon);
|
|---|
| 200 | return(l);
|
|---|
| 201 |
|
|---|
| 202 | } else if( o==QUEST && l->n_op==ICON ) {
|
|---|
| 203 | CONSZ c = l->n_lval;
|
|---|
| 204 | nfree(l);
|
|---|
| 205 | if (c) {
|
|---|
| 206 | walkf(r->n_right, putjops, 0);
|
|---|
| 207 | tfree(r->n_right);
|
|---|
| 208 | l = r->n_left;
|
|---|
| 209 | } else {
|
|---|
| 210 | walkf(r->n_left, putjops, 0);
|
|---|
| 211 | tfree(r->n_left);
|
|---|
| 212 | l = r->n_right;
|
|---|
| 213 | }
|
|---|
| 214 | nfree(r);
|
|---|
| 215 | return(l);
|
|---|
| 216 | } else if( opty == BITYPE && l->n_op == ICON && r->n_op == ICON ){
|
|---|
| 217 |
|
|---|
| 218 | switch( o ){
|
|---|
| 219 |
|
|---|
| 220 | case PLUS:
|
|---|
| 221 | case MINUS:
|
|---|
| 222 | case MUL:
|
|---|
| 223 | case DIV:
|
|---|
| 224 | case MOD:
|
|---|
| 225 | /*
|
|---|
| 226 | * Do type propagation for simple types here.
|
|---|
| 227 | * The constant value is correct anyway.
|
|---|
| 228 | * Maybe this op shortcut should be removed?
|
|---|
| 229 | */
|
|---|
| 230 | if (l->n_sp == NULL && r->n_sp == NULL &&
|
|---|
| 231 | l->n_type < BTMASK && r->n_type < BTMASK) {
|
|---|
| 232 | if (l->n_type > r->n_type)
|
|---|
| 233 | r->n_type = l->n_type;
|
|---|
| 234 | else
|
|---|
| 235 | l->n_type = r->n_type;
|
|---|
| 236 | }
|
|---|
| 237 | /* FALLTHROUGH */
|
|---|
| 238 | case ULT:
|
|---|
| 239 | case UGT:
|
|---|
| 240 | case ULE:
|
|---|
| 241 | case UGE:
|
|---|
| 242 | case LT:
|
|---|
| 243 | case GT:
|
|---|
| 244 | case LE:
|
|---|
| 245 | case GE:
|
|---|
| 246 | case EQ:
|
|---|
| 247 | case NE:
|
|---|
| 248 | case ANDAND:
|
|---|
| 249 | case OROR:
|
|---|
| 250 | case AND:
|
|---|
| 251 | case OR:
|
|---|
| 252 | case ER:
|
|---|
| 253 | case LS:
|
|---|
| 254 | case RS:
|
|---|
| 255 | if (!ISPTR(l->n_type) && !ISPTR(r->n_type)) {
|
|---|
| 256 | if( conval( l, o, r ) ) {
|
|---|
| 257 | nfree(r);
|
|---|
| 258 | return(l);
|
|---|
| 259 | }
|
|---|
| 260 | }
|
|---|
| 261 | break;
|
|---|
| 262 | }
|
|---|
| 263 | } else if (opty == BITYPE && (l->n_op == FCON || l->n_op == ICON) &&
|
|---|
| 264 | (r->n_op == FCON || r->n_op == ICON) && (o == PLUS || o == MINUS ||
|
|---|
| 265 | o == MUL || o == DIV || (o >= EQ && o <= GT) )) {
|
|---|
| 266 | TWORD t;
|
|---|
| 267 | #ifndef CC_DIV_0
|
|---|
| 268 | if (o == DIV &&
|
|---|
| 269 | ((r->n_op == ICON && r->n_lval == 0) ||
|
|---|
| 270 | (r->n_op == FCON && r->n_dcon == 0.0)))
|
|---|
| 271 | goto runtime; /* HW dependent */
|
|---|
| 272 | #endif
|
|---|
| 273 | if (l->n_op == ICON)
|
|---|
| 274 | l->n_dcon = FLOAT_CAST(l->n_lval, l->n_type);
|
|---|
| 275 | if (r->n_op == ICON)
|
|---|
| 276 | r->n_dcon = FLOAT_CAST(r->n_lval, r->n_type);
|
|---|
| 277 | switch(o){
|
|---|
| 278 | case PLUS:
|
|---|
| 279 | case MINUS:
|
|---|
| 280 | case MUL:
|
|---|
| 281 | case DIV:
|
|---|
| 282 | switch (o) {
|
|---|
| 283 | case PLUS:
|
|---|
| 284 | l->n_dcon = FLOAT_PLUS(l->n_dcon, r->n_dcon);
|
|---|
| 285 | break;
|
|---|
| 286 | case MINUS:
|
|---|
| 287 | l->n_dcon = FLOAT_MINUS(l->n_dcon, r->n_dcon);
|
|---|
| 288 | break;
|
|---|
| 289 | case MUL:
|
|---|
| 290 | l->n_dcon = FLOAT_MUL(l->n_dcon, r->n_dcon);
|
|---|
| 291 | break;
|
|---|
| 292 | case DIV:
|
|---|
| 293 | l->n_dcon = FLOAT_DIV(l->n_dcon, r->n_dcon);
|
|---|
| 294 | break;
|
|---|
| 295 | }
|
|---|
| 296 | t = (l->n_type > r->n_type ? l->n_type : r->n_type);
|
|---|
| 297 | l->n_op = FCON;
|
|---|
| 298 | l->n_type = t;
|
|---|
| 299 | l->n_ap = MKAP(t);
|
|---|
| 300 | nfree(r);
|
|---|
| 301 | return(l);
|
|---|
| 302 | case EQ:
|
|---|
| 303 | case NE:
|
|---|
| 304 | case LE:
|
|---|
| 305 | case LT:
|
|---|
| 306 | case GE:
|
|---|
| 307 | case GT:
|
|---|
| 308 | switch (o) {
|
|---|
| 309 | case EQ:
|
|---|
| 310 | l->n_lval = FLOAT_EQ(l->n_dcon, r->n_dcon);
|
|---|
| 311 | break;
|
|---|
| 312 | case NE:
|
|---|
| 313 | l->n_lval = FLOAT_NE(l->n_dcon, r->n_dcon);
|
|---|
| 314 | break;
|
|---|
| 315 | case LE:
|
|---|
| 316 | l->n_lval = FLOAT_LE(l->n_dcon, r->n_dcon);
|
|---|
| 317 | break;
|
|---|
| 318 | case LT:
|
|---|
| 319 | l->n_lval = FLOAT_LT(l->n_dcon, r->n_dcon);
|
|---|
| 320 | break;
|
|---|
| 321 | case GE:
|
|---|
| 322 | l->n_lval = FLOAT_GE(l->n_dcon, r->n_dcon);
|
|---|
| 323 | break;
|
|---|
| 324 | case GT:
|
|---|
| 325 | l->n_lval = FLOAT_GT(l->n_dcon, r->n_dcon);
|
|---|
| 326 | break;
|
|---|
| 327 | }
|
|---|
| 328 | nfree(r);
|
|---|
| 329 | r = bcon(l->n_lval);
|
|---|
| 330 | nfree(l);
|
|---|
| 331 | return r;
|
|---|
| 332 | }
|
|---|
| 333 | }
|
|---|
| 334 | #ifndef CC_DIV_0
|
|---|
| 335 | runtime:
|
|---|
| 336 | #endif
|
|---|
| 337 | /* its real; we must make a new node */
|
|---|
| 338 |
|
|---|
| 339 | p = block(o, l, r, INT, 0, MKAP(INT));
|
|---|
| 340 |
|
|---|
| 341 | actions = opact(p);
|
|---|
| 342 |
|
|---|
| 343 | if (actions & LVAL) { /* check left descendent */
|
|---|
| 344 | if (notlval(p->n_left)) {
|
|---|
| 345 | uerror("lvalue required");
|
|---|
| 346 | nfree(p);
|
|---|
| 347 | return l;
|
|---|
| 348 | #ifdef notyet
|
|---|
| 349 | } else {
|
|---|
| 350 | if ((l->n_type > BTMASK && ISCON(l->n_qual)) ||
|
|---|
| 351 | (l->n_type <= BTMASK && ISCON(l->n_qual << TSHIFT)))
|
|---|
| 352 | if (blevel > 0)
|
|---|
| 353 | uerror("lvalue is declared const");
|
|---|
| 354 | #endif
|
|---|
| 355 | }
|
|---|
| 356 | }
|
|---|
| 357 |
|
|---|
| 358 | if( actions & NCVTR ){
|
|---|
| 359 | p->n_left = pconvert( p->n_left );
|
|---|
| 360 | }
|
|---|
| 361 | else if( !(actions & NCVT ) ){
|
|---|
| 362 | switch( opty ){
|
|---|
| 363 |
|
|---|
| 364 | case BITYPE:
|
|---|
| 365 | p->n_right = pconvert( p->n_right );
|
|---|
| 366 | case UTYPE:
|
|---|
| 367 | p->n_left = pconvert( p->n_left );
|
|---|
| 368 |
|
|---|
| 369 | }
|
|---|
| 370 | }
|
|---|
| 371 |
|
|---|
| 372 | if ((actions&PUN) && (o!=CAST))
|
|---|
| 373 | chkpun(p);
|
|---|
| 374 |
|
|---|
| 375 | if( actions & (TYPL|TYPR) ){
|
|---|
| 376 |
|
|---|
| 377 | q = (actions&TYPL) ? p->n_left : p->n_right;
|
|---|
| 378 |
|
|---|
| 379 | p->n_type = q->n_type;
|
|---|
| 380 | p->n_qual = q->n_qual;
|
|---|
| 381 | p->n_df = q->n_df;
|
|---|
| 382 | p->n_ap = q->n_ap;
|
|---|
| 383 | }
|
|---|
| 384 |
|
|---|
| 385 | if( actions & CVTL ) p = convert( p, CVTL );
|
|---|
| 386 | if( actions & CVTR ) p = convert( p, CVTR );
|
|---|
| 387 | if( actions & TYMATCH ) p = tymatch(p);
|
|---|
| 388 | if( actions & PTMATCH ) p = ptmatch(p);
|
|---|
| 389 |
|
|---|
| 390 | if( actions & OTHER ){
|
|---|
| 391 | struct symtab *sp1;
|
|---|
| 392 |
|
|---|
| 393 | l = p->n_left;
|
|---|
| 394 | r = p->n_right;
|
|---|
| 395 |
|
|---|
| 396 | switch(o){
|
|---|
| 397 |
|
|---|
| 398 | case NAME:
|
|---|
| 399 | cerror("buildtree NAME");
|
|---|
| 400 |
|
|---|
| 401 | case STREF:
|
|---|
| 402 | /* p->x turned into *(p+offset) */
|
|---|
| 403 | /* rhs must be a name; check correctness */
|
|---|
| 404 |
|
|---|
| 405 | /* Find member symbol struct */
|
|---|
| 406 | if (l->n_type != PTR+STRTY && l->n_type != PTR+UNIONTY){
|
|---|
| 407 | uerror("struct or union required");
|
|---|
| 408 | break;
|
|---|
| 409 | }
|
|---|
| 410 |
|
|---|
| 411 | if ((sp1 = strmemb(l->n_ap)) == NULL) {
|
|---|
| 412 | uerror("undefined struct or union");
|
|---|
| 413 | break;
|
|---|
| 414 | }
|
|---|
| 415 |
|
|---|
| 416 | if ((sp = findmember(sp1, r->n_name)) == NULL) {
|
|---|
| 417 | uerror("member '%s' not declared", r->n_name);
|
|---|
| 418 | break;
|
|---|
| 419 | }
|
|---|
| 420 |
|
|---|
| 421 | r->n_sp = sp;
|
|---|
| 422 | p = stref(p);
|
|---|
| 423 | break;
|
|---|
| 424 |
|
|---|
| 425 | case UMUL:
|
|---|
| 426 | if (l->n_op == ADDROF) {
|
|---|
| 427 | nfree(p);
|
|---|
| 428 | p = l->n_left;
|
|---|
| 429 | nfree(l);
|
|---|
| 430 | }
|
|---|
| 431 | if( !ISPTR(l->n_type))uerror("illegal indirection");
|
|---|
| 432 | p->n_type = DECREF(l->n_type);
|
|---|
| 433 | p->n_qual = DECREF(l->n_qual);
|
|---|
| 434 | p->n_df = l->n_df;
|
|---|
| 435 | p->n_ap = l->n_ap;
|
|---|
| 436 | break;
|
|---|
| 437 |
|
|---|
| 438 | case ADDROF:
|
|---|
| 439 | switch( l->n_op ){
|
|---|
| 440 |
|
|---|
| 441 | case UMUL:
|
|---|
| 442 | nfree(p);
|
|---|
| 443 | p = l->n_left;
|
|---|
| 444 | nfree(l);
|
|---|
| 445 | case TEMP:
|
|---|
| 446 | case NAME:
|
|---|
| 447 | p->n_type = INCREF(l->n_type);
|
|---|
| 448 | p->n_qual = INCQAL(l->n_qual);
|
|---|
| 449 | p->n_df = l->n_df;
|
|---|
| 450 | p->n_ap = l->n_ap;
|
|---|
| 451 | break;
|
|---|
| 452 |
|
|---|
| 453 | case COMOP:
|
|---|
| 454 | nfree(p);
|
|---|
| 455 | lr = buildtree(ADDROF, l->n_right, NIL);
|
|---|
| 456 | p = buildtree( COMOP, l->n_left, lr );
|
|---|
| 457 | nfree(l);
|
|---|
| 458 | break;
|
|---|
| 459 |
|
|---|
| 460 | case QUEST:
|
|---|
| 461 | lr = buildtree( ADDROF, l->n_right->n_right, NIL );
|
|---|
| 462 | ll = buildtree( ADDROF, l->n_right->n_left, NIL );
|
|---|
| 463 | nfree(p); nfree(l->n_right);
|
|---|
| 464 | p = buildtree( QUEST, l->n_left, buildtree( COLON, ll, lr ) );
|
|---|
| 465 | nfree(l);
|
|---|
| 466 | break;
|
|---|
| 467 |
|
|---|
| 468 | default:
|
|---|
| 469 | uerror("unacceptable operand of &: %d", l->n_op );
|
|---|
| 470 | break;
|
|---|
| 471 | }
|
|---|
| 472 | break;
|
|---|
| 473 |
|
|---|
| 474 | case LS:
|
|---|
| 475 | case RS: /* must make type size at least int... */
|
|---|
| 476 | if (p->n_type == CHAR || p->n_type == SHORT) {
|
|---|
| 477 | p->n_left = makety(l, INT, 0, 0, MKAP(INT));
|
|---|
| 478 | } else if (p->n_type == UCHAR || p->n_type == USHORT) {
|
|---|
| 479 | p->n_left = makety(l, UNSIGNED, 0, 0,
|
|---|
| 480 | MKAP(UNSIGNED));
|
|---|
| 481 | }
|
|---|
| 482 | l = p->n_left;
|
|---|
| 483 | p->n_type = l->n_type;
|
|---|
| 484 | p->n_qual = l->n_qual;
|
|---|
| 485 | p->n_df = l->n_df;
|
|---|
| 486 | p->n_ap = l->n_ap;
|
|---|
| 487 |
|
|---|
| 488 | /* FALLTHROUGH */
|
|---|
| 489 | case LSEQ:
|
|---|
| 490 | case RSEQ: /* ...but not for assigned types */
|
|---|
| 491 | if(tsize(r->n_type, r->n_df, r->n_ap) > SZINT)
|
|---|
| 492 | p->n_right = makety(r, INT, 0, 0, MKAP(INT));
|
|---|
| 493 | break;
|
|---|
| 494 |
|
|---|
| 495 | case RETURN:
|
|---|
| 496 | case ASSIGN:
|
|---|
| 497 | case CAST:
|
|---|
| 498 | /* structure assignment */
|
|---|
| 499 | /* take the addresses of the two sides; then make an
|
|---|
| 500 | * operator using STASG and
|
|---|
| 501 | * the addresses of left and right */
|
|---|
| 502 |
|
|---|
| 503 | if (strmemb(l->n_ap) != strmemb(r->n_ap))
|
|---|
| 504 | uerror("assignment of different structures");
|
|---|
| 505 |
|
|---|
| 506 | r = buildtree(ADDROF, r, NIL);
|
|---|
| 507 |
|
|---|
| 508 | l = block(STASG, l, r, r->n_type, r->n_df, r->n_ap);
|
|---|
| 509 | l = clocal(l);
|
|---|
| 510 |
|
|---|
| 511 | if( o == RETURN ){
|
|---|
| 512 | nfree(p);
|
|---|
| 513 | p = l;
|
|---|
| 514 | break;
|
|---|
| 515 | }
|
|---|
| 516 |
|
|---|
| 517 | p->n_op = UMUL;
|
|---|
| 518 | p->n_left = l;
|
|---|
| 519 | p->n_right = NIL;
|
|---|
| 520 | break;
|
|---|
| 521 |
|
|---|
| 522 | case QUEST: /* fixup types of : */
|
|---|
| 523 | if (r->n_left->n_type != p->n_type)
|
|---|
| 524 | r->n_left = makety(r->n_left, p->n_type,
|
|---|
| 525 | p->n_qual, p->n_df, p->n_ap);
|
|---|
| 526 | if (r->n_right->n_type != p->n_type)
|
|---|
| 527 | r->n_right = makety(r->n_right, p->n_type,
|
|---|
| 528 | p->n_qual, p->n_df, p->n_ap);
|
|---|
| 529 | break;
|
|---|
| 530 |
|
|---|
| 531 | case COLON:
|
|---|
| 532 | /* structure colon */
|
|---|
| 533 |
|
|---|
| 534 | if (strmemb(l->n_ap) != strmemb(r->n_ap))
|
|---|
| 535 | uerror( "type clash in conditional" );
|
|---|
| 536 | break;
|
|---|
| 537 |
|
|---|
| 538 | case CALL:
|
|---|
| 539 | p->n_right = r = strargs(p->n_right);
|
|---|
| 540 | p = funcode(p);
|
|---|
| 541 | /* FALLTHROUGH */
|
|---|
| 542 | case UCALL:
|
|---|
| 543 | if (!ISPTR(l->n_type))
|
|---|
| 544 | uerror("illegal function");
|
|---|
| 545 | p->n_type = DECREF(l->n_type);
|
|---|
| 546 | if (!ISFTN(p->n_type))
|
|---|
| 547 | uerror("illegal function");
|
|---|
| 548 | p->n_type = DECREF(p->n_type);
|
|---|
| 549 | p->n_df = l->n_df+1; /* add one for prototypes */
|
|---|
| 550 | p->n_ap = l->n_ap;
|
|---|
| 551 | if (p->n_type == STRTY || p->n_type == UNIONTY) {
|
|---|
| 552 | /* function returning structure */
|
|---|
| 553 | /* make function really return ptr to str., with * */
|
|---|
| 554 |
|
|---|
| 555 | p->n_op += STCALL-CALL;
|
|---|
| 556 | p->n_type = INCREF(p->n_type);
|
|---|
| 557 | p = clocal(p); /* before recursing */
|
|---|
| 558 | p = buildtree(UMUL, p, NIL);
|
|---|
| 559 |
|
|---|
| 560 | }
|
|---|
| 561 | break;
|
|---|
| 562 |
|
|---|
| 563 | default:
|
|---|
| 564 | cerror( "other code %d", o );
|
|---|
| 565 | }
|
|---|
| 566 |
|
|---|
| 567 | }
|
|---|
| 568 |
|
|---|
| 569 | /*
|
|---|
| 570 | * Allow (void)0 casts.
|
|---|
| 571 | * XXX - anything on the right side must be possible to cast.
|
|---|
| 572 | * XXX - remove void types further on.
|
|---|
| 573 | */
|
|---|
| 574 | if (p->n_op == CAST && p->n_type == VOID &&
|
|---|
| 575 | p->n_right->n_op == ICON)
|
|---|
| 576 | p->n_right->n_type = VOID;
|
|---|
| 577 |
|
|---|
| 578 | if (actions & CVTO)
|
|---|
| 579 | p = oconvert(p);
|
|---|
| 580 | p = clocal(p);
|
|---|
| 581 |
|
|---|
| 582 | #ifdef PCC_DEBUG
|
|---|
| 583 | if (bdebug) {
|
|---|
| 584 | printf("End of buildtree:\n");
|
|---|
| 585 | fwalk(p, eprint, 0);
|
|---|
| 586 | }
|
|---|
| 587 | #endif
|
|---|
| 588 |
|
|---|
| 589 | return(p);
|
|---|
| 590 |
|
|---|
| 591 | }
|
|---|
| 592 |
|
|---|
| 593 | /* Find a member in a struct or union. May be an unnamed member */
|
|---|
| 594 | static struct symtab *
|
|---|
| 595 | findmember(struct symtab *sp, char *s)
|
|---|
| 596 | {
|
|---|
| 597 | struct symtab *sp2, *sp3;
|
|---|
| 598 |
|
|---|
| 599 | for (; sp != NULL; sp = sp->snext) {
|
|---|
| 600 | if (sp->sname[0] == '*') {
|
|---|
| 601 | /* unnamed member, recurse down */
|
|---|
| 602 | if ((sp2 = findmember(strmemb(sp->sap), s))) {
|
|---|
| 603 | sp3 = tmpalloc(sizeof (struct symtab));
|
|---|
| 604 | *sp3 = *sp2;
|
|---|
| 605 | sp3->soffset += sp->soffset;
|
|---|
| 606 | return sp3;
|
|---|
| 607 | }
|
|---|
| 608 | } else if (sp->sname == s)
|
|---|
| 609 | return sp;
|
|---|
| 610 | }
|
|---|
| 611 | return NULL;
|
|---|
| 612 | }
|
|---|
| 613 |
|
|---|
| 614 |
|
|---|
| 615 | /*
|
|---|
| 616 | * Check if there will be a lost label destination inside of a ?:
|
|---|
| 617 | * It cannot be reached so just print it out.
|
|---|
| 618 | */
|
|---|
| 619 | void
|
|---|
| 620 | putjops(NODE *p, void *arg)
|
|---|
| 621 | {
|
|---|
| 622 | if (p->n_op == COMOP && p->n_left->n_op == GOTO)
|
|---|
| 623 | plabel(p->n_left->n_left->n_lval+1);
|
|---|
| 624 | }
|
|---|
| 625 |
|
|---|
| 626 | /*
|
|---|
| 627 | * Build a name node based on a symtab entry.
|
|---|
| 628 | * broken out from buildtree().
|
|---|
| 629 | */
|
|---|
| 630 | NODE *
|
|---|
| 631 | nametree(struct symtab *sp)
|
|---|
| 632 | {
|
|---|
| 633 | NODE *p;
|
|---|
| 634 |
|
|---|
| 635 | p = block(NAME, NIL, NIL, sp->stype, sp->sdf, sp->sap);
|
|---|
| 636 | p->n_qual = sp->squal;
|
|---|
| 637 | p->n_sp = sp;
|
|---|
| 638 |
|
|---|
| 639 | #ifndef NO_C_BUILTINS
|
|---|
| 640 | if (sp->sname[0] == '_' && strncmp(sp->sname, "__builtin_", 10) == 0)
|
|---|
| 641 | return p; /* do not touch builtins here */
|
|---|
| 642 |
|
|---|
| 643 | #endif
|
|---|
| 644 |
|
|---|
| 645 | if (sp->sflags & STNODE) {
|
|---|
| 646 | /* Generated for optimizer */
|
|---|
| 647 | p->n_op = TEMP;
|
|---|
| 648 | p->n_rval = sp->soffset;
|
|---|
| 649 | }
|
|---|
| 650 |
|
|---|
| 651 | #ifdef GCC_COMPAT
|
|---|
| 652 | /* Get a label name */
|
|---|
| 653 | if (sp->sflags == SLBLNAME) {
|
|---|
| 654 | p->n_type = VOID;
|
|---|
| 655 | p->n_ap = MKAP(VOID);
|
|---|
| 656 | }
|
|---|
| 657 | #endif
|
|---|
| 658 | if (sp->stype == UNDEF) {
|
|---|
| 659 | uerror("%s undefined", sp->sname);
|
|---|
| 660 | /* make p look reasonable */
|
|---|
| 661 | p->n_type = INT;
|
|---|
| 662 | p->n_ap = MKAP(INT);
|
|---|
| 663 | p->n_df = NULL;
|
|---|
| 664 | defid(p, SNULL);
|
|---|
| 665 | }
|
|---|
| 666 | if (sp->sclass == MOE) {
|
|---|
| 667 | p->n_op = ICON;
|
|---|
| 668 | p->n_lval = sp->soffset;
|
|---|
| 669 | p->n_df = NULL;
|
|---|
| 670 | p->n_sp = NULL;
|
|---|
| 671 | }
|
|---|
| 672 | return clocal(p);
|
|---|
| 673 | }
|
|---|
| 674 |
|
|---|
| 675 | /*
|
|---|
| 676 | * Cast a node to another type by inserting a cast.
|
|---|
| 677 | * Just a nicer interface to buildtree.
|
|---|
| 678 | * Returns the new tree.
|
|---|
| 679 | */
|
|---|
| 680 | NODE *
|
|---|
| 681 | cast(NODE *p, TWORD t, TWORD u)
|
|---|
| 682 | {
|
|---|
| 683 | NODE *q;
|
|---|
| 684 |
|
|---|
| 685 | q = block(NAME, NIL, NIL, t, 0, MKAP(BTYPE(t)));
|
|---|
| 686 | q->n_qual = u;
|
|---|
| 687 | q = buildtree(CAST, q, p);
|
|---|
| 688 | p = q->n_right;
|
|---|
| 689 | nfree(q->n_left);
|
|---|
| 690 | nfree(q);
|
|---|
| 691 | return p;
|
|---|
| 692 | }
|
|---|
| 693 |
|
|---|
| 694 | /*
|
|---|
| 695 | * Cast and complain if necessary by not inserining a cast.
|
|---|
| 696 | */
|
|---|
| 697 | NODE *
|
|---|
| 698 | ccast(NODE *p, TWORD t, TWORD u, union dimfun *df, struct attr *ap)
|
|---|
| 699 | {
|
|---|
| 700 | NODE *q;
|
|---|
| 701 |
|
|---|
| 702 | /* let buildtree do typechecking (and casting) */
|
|---|
| 703 | q = block(NAME, NIL, NIL, t, df, ap);
|
|---|
| 704 | p = buildtree(ASSIGN, q, p);
|
|---|
| 705 | nfree(p->n_left);
|
|---|
| 706 | q = optim(p->n_right);
|
|---|
| 707 | nfree(p);
|
|---|
| 708 | return q;
|
|---|
| 709 | }
|
|---|
| 710 |
|
|---|
| 711 | /*
|
|---|
| 712 | * Do a conditional branch.
|
|---|
| 713 | */
|
|---|
| 714 | void
|
|---|
| 715 | cbranch(NODE *p, NODE *q)
|
|---|
| 716 | {
|
|---|
| 717 | p = buildtree(CBRANCH, p, q);
|
|---|
| 718 | if (p->n_left->n_op == ICON) {
|
|---|
| 719 | if (p->n_left->n_lval != 0) {
|
|---|
| 720 | branch(q->n_lval); /* branch always */
|
|---|
| 721 | reached = 0;
|
|---|
| 722 | }
|
|---|
| 723 | tfree(p);
|
|---|
| 724 | tfree(q);
|
|---|
| 725 | return;
|
|---|
| 726 | }
|
|---|
| 727 | ecomp(p);
|
|---|
| 728 | }
|
|---|
| 729 |
|
|---|
| 730 | NODE *
|
|---|
| 731 | strargs( p ) register NODE *p; { /* rewrite structure flavored arguments */
|
|---|
| 732 |
|
|---|
| 733 | if( p->n_op == CM ){
|
|---|
| 734 | p->n_left = strargs( p->n_left );
|
|---|
| 735 | p->n_right = strargs( p->n_right );
|
|---|
| 736 | return( p );
|
|---|
| 737 | }
|
|---|
| 738 |
|
|---|
| 739 | if( p->n_type == STRTY || p->n_type == UNIONTY ){
|
|---|
| 740 | p = block(STARG, p, NIL, p->n_type, p->n_df, p->n_ap);
|
|---|
| 741 | p->n_left = buildtree( ADDROF, p->n_left, NIL );
|
|---|
| 742 | p = clocal(p);
|
|---|
| 743 | }
|
|---|
| 744 | return( p );
|
|---|
| 745 | }
|
|---|
| 746 |
|
|---|
| 747 | /*
|
|---|
| 748 | * apply the op o to the lval part of p; if binary, rhs is val
|
|---|
| 749 | */
|
|---|
| 750 | int
|
|---|
| 751 | conval(NODE *p, int o, NODE *q)
|
|---|
| 752 | {
|
|---|
| 753 | TWORD tl = p->n_type, tr = q->n_type, td;
|
|---|
| 754 | int i, u;
|
|---|
| 755 | CONSZ val;
|
|---|
| 756 | U_CONSZ v1, v2;
|
|---|
| 757 |
|
|---|
| 758 | val = q->n_lval;
|
|---|
| 759 |
|
|---|
| 760 | /* make both sides same type */
|
|---|
| 761 | if (tl < BTMASK && tr < BTMASK) {
|
|---|
| 762 | td = tl > tr ? tl : tr;
|
|---|
| 763 | if (td < INT)
|
|---|
| 764 | td = INT;
|
|---|
| 765 | u = ISUNSIGNED(td);
|
|---|
| 766 | if (tl != td)
|
|---|
| 767 | p = makety(p, td, 0, 0, MKAP(td));
|
|---|
| 768 | if (tr != td)
|
|---|
| 769 | q = makety(q, td, 0, 0, MKAP(td));
|
|---|
| 770 | } else
|
|---|
| 771 | u = ISUNSIGNED(tl) || ISUNSIGNED(tr);
|
|---|
| 772 | if( u && (o==LE||o==LT||o==GE||o==GT)) o += (UGE-GE);
|
|---|
| 773 |
|
|---|
| 774 | if (p->n_sp != NULL && q->n_sp != NULL)
|
|---|
| 775 | return(0);
|
|---|
| 776 | if (q->n_sp != NULL && o != PLUS)
|
|---|
| 777 | return(0);
|
|---|
| 778 | if (p->n_sp != NULL && o != PLUS && o != MINUS)
|
|---|
| 779 | return(0);
|
|---|
| 780 |
|
|---|
| 781 | v1 = p->n_lval;
|
|---|
| 782 | v2 = q->n_lval;
|
|---|
| 783 | switch( o ){
|
|---|
| 784 |
|
|---|
| 785 | case PLUS:
|
|---|
| 786 | p->n_lval += val;
|
|---|
| 787 | if (p->n_sp == NULL) {
|
|---|
| 788 | p->n_right = q->n_right;
|
|---|
| 789 | p->n_type = q->n_type;
|
|---|
| 790 | }
|
|---|
| 791 | break;
|
|---|
| 792 | case MINUS:
|
|---|
| 793 | p->n_lval -= val;
|
|---|
| 794 | break;
|
|---|
| 795 | case MUL:
|
|---|
| 796 | p->n_lval *= val;
|
|---|
| 797 | break;
|
|---|
| 798 | case DIV:
|
|---|
| 799 | if (val == 0)
|
|---|
| 800 | uerror("division by 0");
|
|---|
| 801 | else {
|
|---|
| 802 | if (u) {
|
|---|
| 803 | v1 /= v2;
|
|---|
| 804 | p->n_lval = v1;
|
|---|
| 805 | } else
|
|---|
| 806 | p->n_lval /= val;
|
|---|
| 807 | }
|
|---|
| 808 | break;
|
|---|
| 809 | case MOD:
|
|---|
| 810 | if (val == 0)
|
|---|
| 811 | uerror("division by 0");
|
|---|
| 812 | else {
|
|---|
| 813 | if (u) {
|
|---|
| 814 | v1 %= v2;
|
|---|
| 815 | p->n_lval = v1;
|
|---|
| 816 | } else
|
|---|
| 817 | p->n_lval %= val;
|
|---|
| 818 | }
|
|---|
| 819 | break;
|
|---|
| 820 | case AND:
|
|---|
| 821 | p->n_lval &= val;
|
|---|
| 822 | break;
|
|---|
| 823 | case OR:
|
|---|
| 824 | p->n_lval |= val;
|
|---|
| 825 | break;
|
|---|
| 826 | case ER:
|
|---|
| 827 | p->n_lval ^= val;
|
|---|
| 828 | break;
|
|---|
| 829 | case LS:
|
|---|
| 830 | i = (int)val;
|
|---|
| 831 | p->n_lval = p->n_lval << i;
|
|---|
| 832 | break;
|
|---|
| 833 | case RS:
|
|---|
| 834 | i = (int)val;
|
|---|
| 835 | if (u) {
|
|---|
| 836 | v1 = v1 >> i;
|
|---|
| 837 | p->n_lval = v1;
|
|---|
| 838 | } else
|
|---|
| 839 | p->n_lval = p->n_lval >> i;
|
|---|
| 840 | break;
|
|---|
| 841 |
|
|---|
| 842 | case UMINUS:
|
|---|
| 843 | p->n_lval = - p->n_lval;
|
|---|
| 844 | break;
|
|---|
| 845 | case COMPL:
|
|---|
| 846 | p->n_lval = ~p->n_lval;
|
|---|
| 847 | break;
|
|---|
| 848 | case NOT:
|
|---|
| 849 | p->n_lval = !p->n_lval;
|
|---|
| 850 | break;
|
|---|
| 851 | case LT:
|
|---|
| 852 | p->n_lval = p->n_lval < val;
|
|---|
| 853 | break;
|
|---|
| 854 | case LE:
|
|---|
| 855 | p->n_lval = p->n_lval <= val;
|
|---|
| 856 | break;
|
|---|
| 857 | case GT:
|
|---|
| 858 | p->n_lval = p->n_lval > val;
|
|---|
| 859 | break;
|
|---|
| 860 | case GE:
|
|---|
| 861 | p->n_lval = p->n_lval >= val;
|
|---|
| 862 | break;
|
|---|
| 863 | case ULT:
|
|---|
| 864 | p->n_lval = v1 < v2;
|
|---|
| 865 | break;
|
|---|
| 866 | case ULE:
|
|---|
| 867 | p->n_lval = v1 <= v2;
|
|---|
| 868 | break;
|
|---|
| 869 | case UGT:
|
|---|
| 870 | p->n_lval = v1 > v2;
|
|---|
| 871 | break;
|
|---|
| 872 | case UGE:
|
|---|
| 873 | p->n_lval = v1 >= v2;
|
|---|
| 874 | break;
|
|---|
| 875 | case EQ:
|
|---|
| 876 | p->n_lval = p->n_lval == val;
|
|---|
| 877 | break;
|
|---|
| 878 | case NE:
|
|---|
| 879 | p->n_lval = p->n_lval != val;
|
|---|
| 880 | break;
|
|---|
| 881 | case ANDAND:
|
|---|
| 882 | p->n_lval = p->n_lval && val;
|
|---|
| 883 | break;
|
|---|
| 884 | case OROR:
|
|---|
| 885 | p->n_lval = p->n_lval || val;
|
|---|
| 886 | break;
|
|---|
| 887 | default:
|
|---|
| 888 | return(0);
|
|---|
| 889 | }
|
|---|
| 890 | /* Do the best in making everything type correct after calc */
|
|---|
| 891 | if (p->n_sp == NULL && q->n_sp == NULL)
|
|---|
| 892 | p->n_lval = valcast(p->n_lval, p->n_type);
|
|---|
| 893 | return(1);
|
|---|
| 894 | }
|
|---|
| 895 |
|
|---|
| 896 | /*
|
|---|
| 897 | * Ensure that v matches the type t; sign- or zero-extended
|
|---|
| 898 | * as suitable to CONSZ.
|
|---|
| 899 | * Only to be used for integer types.
|
|---|
| 900 | */
|
|---|
| 901 | CONSZ
|
|---|
| 902 | valcast(CONSZ v, TWORD t)
|
|---|
| 903 | {
|
|---|
| 904 | CONSZ r;
|
|---|
| 905 |
|
|---|
| 906 | if (t < CHAR || t > ULONGLONG)
|
|---|
| 907 | return v; /* cannot cast */
|
|---|
| 908 |
|
|---|
| 909 | if (t >= LONGLONG)
|
|---|
| 910 | return v; /* already largest */
|
|---|
| 911 |
|
|---|
| 912 | #define M(x) ((((1ULL << ((x)-1)) - 1) << 1) + 1)
|
|---|
| 913 | #define NOTM(x) (~M(x))
|
|---|
| 914 | #define SBIT(x) (1ULL << ((x)-1))
|
|---|
| 915 |
|
|---|
| 916 | r = v & M(btattr[t].atypsz);
|
|---|
| 917 | if (!ISUNSIGNED(t) && (SBIT(btattr[t].atypsz) & r))
|
|---|
| 918 | r = r | NOTM(btattr[t].atypsz);
|
|---|
| 919 | return r;
|
|---|
| 920 | }
|
|---|
| 921 |
|
|---|
| 922 | /*
|
|---|
| 923 | * Checks p for the existance of a pun. This is called when the op of p
|
|---|
| 924 | * is ASSIGN, RETURN, CAST, COLON, or relational.
|
|---|
| 925 | * One case is when enumerations are used: this applies only to lint.
|
|---|
| 926 | * In the other case, one operand is a pointer, the other integer type
|
|---|
| 927 | * we check that this integer is in fact a constant zero...
|
|---|
| 928 | * in the case of ASSIGN, any assignment of pointer to integer is illegal
|
|---|
| 929 | * this falls out, because the LHS is never 0.
|
|---|
| 930 | * XXX - check for COMOPs in assignment RHS?
|
|---|
| 931 | */
|
|---|
| 932 | void
|
|---|
| 933 | chkpun(NODE *p)
|
|---|
| 934 | {
|
|---|
| 935 | union dimfun *d1, *d2;
|
|---|
| 936 | NODE *q;
|
|---|
| 937 | int t1, t2;
|
|---|
| 938 |
|
|---|
| 939 | t1 = p->n_left->n_type;
|
|---|
| 940 | t2 = p->n_right->n_type;
|
|---|
| 941 |
|
|---|
| 942 | switch (p->n_op) {
|
|---|
| 943 | case RETURN:
|
|---|
| 944 | /* return of void allowed but nothing else */
|
|---|
| 945 | if (t1 == VOID && t2 == VOID)
|
|---|
| 946 | return;
|
|---|
| 947 | if (t1 == VOID) {
|
|---|
| 948 | werror("returning value from void function");
|
|---|
| 949 | return;
|
|---|
| 950 | }
|
|---|
| 951 | if (t2 == VOID) {
|
|---|
| 952 | uerror("using void value");
|
|---|
| 953 | return;
|
|---|
| 954 | }
|
|---|
| 955 | case COLON:
|
|---|
| 956 | if (t1 == VOID && t2 == VOID)
|
|---|
| 957 | return;
|
|---|
| 958 | break;
|
|---|
| 959 | default:
|
|---|
| 960 | if ((t1 == VOID && t2 != VOID) || (t1 != VOID && t2 == VOID)) {
|
|---|
| 961 | uerror("value of void expression used");
|
|---|
| 962 | return;
|
|---|
| 963 | }
|
|---|
| 964 | break;
|
|---|
| 965 | }
|
|---|
| 966 |
|
|---|
| 967 | /* allow void pointer assignments in any direction */
|
|---|
| 968 | if (BTYPE(t1) == VOID && (t2 & TMASK))
|
|---|
| 969 | return;
|
|---|
| 970 | if (BTYPE(t2) == VOID && (t1 & TMASK))
|
|---|
| 971 | return;
|
|---|
| 972 |
|
|---|
| 973 | /* boolean have special syntax */
|
|---|
| 974 | if (t1 == BOOL) {
|
|---|
| 975 | if (!ISARY(t2)) /* Anything scalar */
|
|---|
| 976 | return;
|
|---|
| 977 | }
|
|---|
| 978 |
|
|---|
| 979 | if (ISPTR(t1) || ISARY(t1))
|
|---|
| 980 | q = p->n_right;
|
|---|
| 981 | else
|
|---|
| 982 | q = p->n_left;
|
|---|
| 983 |
|
|---|
| 984 | if (!ISPTR(q->n_type) && !ISARY(q->n_type)) {
|
|---|
| 985 | if (q->n_op != ICON || q->n_lval != 0)
|
|---|
| 986 | werror("illegal combination of pointer and integer");
|
|---|
| 987 | } else {
|
|---|
| 988 | if (t1 == t2) {
|
|---|
| 989 | if (ISSOU(BTYPE(t1)) &&
|
|---|
| 990 | !suemeq(p->n_left->n_ap, p->n_right->n_ap))
|
|---|
| 991 | werror("illegal structure pointer combination");
|
|---|
| 992 | return;
|
|---|
| 993 | }
|
|---|
| 994 | d1 = p->n_left->n_df;
|
|---|
| 995 | d2 = p->n_right->n_df;
|
|---|
| 996 | for (;;) {
|
|---|
| 997 | if (ISARY(t1) || ISPTR(t1)) {
|
|---|
| 998 | if (!ISARY(t2) && !ISPTR(t2))
|
|---|
| 999 | break;
|
|---|
| 1000 | if (ISARY(t1) && ISARY(t2) && d1->ddim != d2->ddim) {
|
|---|
| 1001 | werror("illegal array size combination");
|
|---|
| 1002 | return;
|
|---|
| 1003 | }
|
|---|
| 1004 | if (ISARY(t1))
|
|---|
| 1005 | ++d1;
|
|---|
| 1006 | if (ISARY(t2))
|
|---|
| 1007 | ++d2;
|
|---|
| 1008 | } else if (ISFTN(t1)) {
|
|---|
| 1009 | if (chkftn(d1->dfun, d2->dfun)) {
|
|---|
| 1010 | werror("illegal function "
|
|---|
| 1011 | "pointer combination");
|
|---|
| 1012 | return;
|
|---|
| 1013 | }
|
|---|
| 1014 | ++d1;
|
|---|
| 1015 | ++d2;
|
|---|
| 1016 | } else
|
|---|
| 1017 | break;
|
|---|
| 1018 | t1 = DECREF(t1);
|
|---|
| 1019 | t2 = DECREF(t2);
|
|---|
| 1020 | }
|
|---|
| 1021 | if (DEUNSIGN(t1) != DEUNSIGN(t2))
|
|---|
| 1022 | warner(Wpointer_sign, NULL);
|
|---|
| 1023 | }
|
|---|
| 1024 | }
|
|---|
| 1025 |
|
|---|
| 1026 | NODE *
|
|---|
| 1027 | stref(NODE *p)
|
|---|
| 1028 | {
|
|---|
| 1029 | NODE *r;
|
|---|
| 1030 | struct attr *ap;
|
|---|
| 1031 | union dimfun *d;
|
|---|
| 1032 | TWORD t, q;
|
|---|
| 1033 | int dsc;
|
|---|
| 1034 | OFFSZ off;
|
|---|
| 1035 | struct symtab *s;
|
|---|
| 1036 |
|
|---|
| 1037 | /* make p->x */
|
|---|
| 1038 | /* this is also used to reference automatic variables */
|
|---|
| 1039 |
|
|---|
| 1040 | s = p->n_right->n_sp;
|
|---|
| 1041 | nfree(p->n_right);
|
|---|
| 1042 | r = p->n_left;
|
|---|
| 1043 | nfree(p);
|
|---|
| 1044 | p = pconvert(r);
|
|---|
| 1045 |
|
|---|
| 1046 | /* make p look like ptr to x */
|
|---|
| 1047 |
|
|---|
| 1048 | if (!ISPTR(p->n_type))
|
|---|
| 1049 | p->n_type = PTR+UNIONTY;
|
|---|
| 1050 |
|
|---|
| 1051 | t = INCREF(s->stype);
|
|---|
| 1052 | q = INCQAL(s->squal);
|
|---|
| 1053 | d = s->sdf;
|
|---|
| 1054 | ap = s->sap;
|
|---|
| 1055 |
|
|---|
| 1056 | p = makety(p, t, q, d, ap);
|
|---|
| 1057 |
|
|---|
| 1058 | /* compute the offset to be added */
|
|---|
| 1059 |
|
|---|
| 1060 | off = s->soffset;
|
|---|
| 1061 | dsc = s->sclass;
|
|---|
| 1062 |
|
|---|
| 1063 | #ifndef CAN_UNALIGN
|
|---|
| 1064 | /*
|
|---|
| 1065 | * If its a packed struct, and the target cannot do unaligned
|
|---|
| 1066 | * accesses, then split it up in two bitfield operations.
|
|---|
| 1067 | * LHS and RHS accesses are different, so must delay
|
|---|
| 1068 | * it until we know. Do the bitfield construct here though.
|
|---|
| 1069 | */
|
|---|
| 1070 | if ((dsc & FIELD) == 0 && (off % talign(s->stype, s->sap))) {
|
|---|
| 1071 | #if 0
|
|---|
| 1072 | int sz = tsize(s->stype, s->sdf, s->sap);
|
|---|
| 1073 | int al = talign(s->stype, s->sap);
|
|---|
| 1074 | int sz1 = al - (off % al);
|
|---|
| 1075 | #endif
|
|---|
| 1076 | }
|
|---|
| 1077 | #endif
|
|---|
| 1078 |
|
|---|
| 1079 | #if 0
|
|---|
| 1080 | if (dsc & FIELD) { /* make fields look like ints */
|
|---|
| 1081 | off = (off/ALINT)*ALINT;
|
|---|
| 1082 | ap = MKAP(INT);
|
|---|
| 1083 | }
|
|---|
| 1084 | #endif
|
|---|
| 1085 | if (off != 0) {
|
|---|
| 1086 | p = block(PLUS, p, offcon(off, t, d, ap), t, d, ap);
|
|---|
| 1087 | p->n_qual = q;
|
|---|
| 1088 | p = optim(p);
|
|---|
| 1089 | }
|
|---|
| 1090 |
|
|---|
| 1091 | p = buildtree(UMUL, p, NIL);
|
|---|
| 1092 |
|
|---|
| 1093 | /* if field, build field info */
|
|---|
| 1094 |
|
|---|
| 1095 | if (dsc & FIELD) {
|
|---|
| 1096 | p = block(FLD, p, NIL, s->stype, 0, s->sap);
|
|---|
| 1097 | p->n_qual = q;
|
|---|
| 1098 | p->n_rval = PKFIELD(dsc&FLDSIZ, s->soffset%talign(s->stype, ap));
|
|---|
| 1099 | }
|
|---|
| 1100 |
|
|---|
| 1101 | p = clocal(p);
|
|---|
| 1102 | return p;
|
|---|
| 1103 | }
|
|---|
| 1104 |
|
|---|
| 1105 | int
|
|---|
| 1106 | notlval(p) register NODE *p; {
|
|---|
| 1107 |
|
|---|
| 1108 | /* return 0 if p an lvalue, 1 otherwise */
|
|---|
| 1109 |
|
|---|
| 1110 | again:
|
|---|
| 1111 |
|
|---|
| 1112 | switch( p->n_op ){
|
|---|
| 1113 |
|
|---|
| 1114 | case FLD:
|
|---|
| 1115 | p = p->n_left;
|
|---|
| 1116 | goto again;
|
|---|
| 1117 |
|
|---|
| 1118 | case NAME:
|
|---|
| 1119 | case OREG:
|
|---|
| 1120 | case UMUL:
|
|---|
| 1121 | if( ISARY(p->n_type) || ISFTN(p->n_type) ) return(1);
|
|---|
| 1122 | case TEMP:
|
|---|
| 1123 | case REG:
|
|---|
| 1124 | return(0);
|
|---|
| 1125 |
|
|---|
| 1126 | default:
|
|---|
| 1127 | return(1);
|
|---|
| 1128 |
|
|---|
| 1129 | }
|
|---|
| 1130 |
|
|---|
| 1131 | }
|
|---|
| 1132 | /* make a constant node with value i */
|
|---|
| 1133 | NODE *
|
|---|
| 1134 | bcon(int i)
|
|---|
| 1135 | {
|
|---|
| 1136 | return xbcon(i, NULL, INT);
|
|---|
| 1137 | }
|
|---|
| 1138 |
|
|---|
| 1139 | NODE *
|
|---|
| 1140 | xbcon(CONSZ val, struct symtab *sp, TWORD type)
|
|---|
| 1141 | {
|
|---|
| 1142 | NODE *p;
|
|---|
| 1143 |
|
|---|
| 1144 | p = block(ICON, NIL, NIL, type, 0, MKAP(type));
|
|---|
| 1145 | p->n_lval = val;
|
|---|
| 1146 | p->n_sp = sp;
|
|---|
| 1147 | return clocal(p);
|
|---|
| 1148 | }
|
|---|
| 1149 |
|
|---|
| 1150 | NODE *
|
|---|
| 1151 | bpsize(NODE *p)
|
|---|
| 1152 | {
|
|---|
| 1153 | int isdyn(struct symtab *sp);
|
|---|
| 1154 | struct attr *ap;
|
|---|
| 1155 | struct symtab s;
|
|---|
| 1156 | NODE *q, *r;
|
|---|
| 1157 | TWORD t;
|
|---|
| 1158 |
|
|---|
| 1159 | s.stype = DECREF(p->n_type);
|
|---|
| 1160 | s.sdf = p->n_df;
|
|---|
| 1161 | if (isdyn(&s)) {
|
|---|
| 1162 | q = bcon(1);
|
|---|
| 1163 | for (t = s.stype; t > BTMASK; t = DECREF(t)) {
|
|---|
| 1164 | if (ISPTR(t))
|
|---|
| 1165 | return buildtree(MUL, q, bcon(SZPOINT(t)));
|
|---|
| 1166 | if (ISARY(t)) {
|
|---|
| 1167 | if (s.sdf->ddim < 0)
|
|---|
| 1168 | r = tempnode(-s.sdf->ddim,
|
|---|
| 1169 | INT, 0, MKAP(INT));
|
|---|
| 1170 | else
|
|---|
| 1171 | r = bcon(s.sdf->ddim/SZCHAR);
|
|---|
| 1172 | q = buildtree(MUL, q, r);
|
|---|
| 1173 | s.sdf++;
|
|---|
| 1174 | }
|
|---|
| 1175 | }
|
|---|
| 1176 | ap = attr_find(p->n_ap, ATTR_BASETYP);
|
|---|
| 1177 | p = buildtree(MUL, q, bcon(ap->atypsz/SZCHAR));
|
|---|
| 1178 | } else
|
|---|
| 1179 | p = (offcon(psize(p), p->n_type, p->n_df, p->n_ap));
|
|---|
| 1180 | return p;
|
|---|
| 1181 | }
|
|---|
| 1182 |
|
|---|
| 1183 | /*
|
|---|
| 1184 | * p is a node of type pointer; psize returns the
|
|---|
| 1185 | * size of the thing pointed to
|
|---|
| 1186 | */
|
|---|
| 1187 | OFFSZ
|
|---|
| 1188 | psize(NODE *p)
|
|---|
| 1189 | {
|
|---|
| 1190 |
|
|---|
| 1191 | if (!ISPTR(p->n_type)) {
|
|---|
| 1192 | uerror("pointer required");
|
|---|
| 1193 | return(SZINT);
|
|---|
| 1194 | }
|
|---|
| 1195 | /* note: no pointers to fields */
|
|---|
| 1196 | return(tsize(DECREF(p->n_type), p->n_df, p->n_ap));
|
|---|
| 1197 | }
|
|---|
| 1198 |
|
|---|
| 1199 | /*
|
|---|
| 1200 | * convert an operand of p
|
|---|
| 1201 | * f is either CVTL or CVTR
|
|---|
| 1202 | * operand has type int, and is converted by the size of the other side
|
|---|
| 1203 | * convert is called when an integer is to be added to a pointer, for
|
|---|
| 1204 | * example in arrays or structures.
|
|---|
| 1205 | */
|
|---|
| 1206 | NODE *
|
|---|
| 1207 | convert(NODE *p, int f)
|
|---|
| 1208 | {
|
|---|
| 1209 | union dimfun *df;
|
|---|
| 1210 | TWORD ty, ty2;
|
|---|
| 1211 | NODE *q, *r, *s, *rv;
|
|---|
| 1212 |
|
|---|
| 1213 | if (f == CVTL) {
|
|---|
| 1214 | q = p->n_left;
|
|---|
| 1215 | s = p->n_right;
|
|---|
| 1216 | } else {
|
|---|
| 1217 | q = p->n_right;
|
|---|
| 1218 | s = p->n_left;
|
|---|
| 1219 | }
|
|---|
| 1220 | ty2 = ty = DECREF(s->n_type);
|
|---|
| 1221 | while (ISARY(ty))
|
|---|
| 1222 | ty = DECREF(ty);
|
|---|
| 1223 |
|
|---|
| 1224 | r = offcon(tsize(ty, s->n_df, s->n_ap), s->n_type, s->n_df, s->n_ap);
|
|---|
| 1225 | ty = ty2;
|
|---|
| 1226 | rv = bcon(1);
|
|---|
| 1227 | df = s->n_df;
|
|---|
| 1228 | while (ISARY(ty)) {
|
|---|
| 1229 | rv = buildtree(MUL, rv, df->ddim >= 0 ? bcon(df->ddim) :
|
|---|
| 1230 | tempnode(-df->ddim, INT, 0, MKAP(INT)));
|
|---|
| 1231 | df++;
|
|---|
| 1232 | ty = DECREF(ty);
|
|---|
| 1233 | }
|
|---|
| 1234 | rv = clocal(block(PMCONV, rv, r, INT, 0, MKAP(INT)));
|
|---|
| 1235 | rv = optim(rv);
|
|---|
| 1236 |
|
|---|
| 1237 | r = block(PMCONV, q, rv, INT, 0, MKAP(INT));
|
|---|
| 1238 | r = clocal(r);
|
|---|
| 1239 | /*
|
|---|
| 1240 | * Indexing is only allowed with integer arguments, so insert
|
|---|
| 1241 | * SCONV here if arg is not an integer.
|
|---|
| 1242 | * XXX - complain?
|
|---|
| 1243 | */
|
|---|
| 1244 | if (r->n_type != INTPTR)
|
|---|
| 1245 | r = clocal(block(SCONV, r, NIL, INTPTR, 0, MKAP(INTPTR)));
|
|---|
| 1246 | if (f == CVTL)
|
|---|
| 1247 | p->n_left = r;
|
|---|
| 1248 | else
|
|---|
| 1249 | p->n_right = r;
|
|---|
| 1250 | return(p);
|
|---|
| 1251 | }
|
|---|
| 1252 |
|
|---|
| 1253 | NODE *
|
|---|
| 1254 | pconvert( p ) register NODE *p; {
|
|---|
| 1255 |
|
|---|
| 1256 | /* if p should be changed into a pointer, do so */
|
|---|
| 1257 |
|
|---|
| 1258 | if( ISARY( p->n_type) ){
|
|---|
| 1259 | p->n_type = DECREF( p->n_type );
|
|---|
| 1260 | ++p->n_df;
|
|---|
| 1261 | return( buildtree( ADDROF, p, NIL ) );
|
|---|
| 1262 | }
|
|---|
| 1263 | if( ISFTN( p->n_type) )
|
|---|
| 1264 | return( buildtree( ADDROF, p, NIL ) );
|
|---|
| 1265 |
|
|---|
| 1266 | return( p );
|
|---|
| 1267 | }
|
|---|
| 1268 |
|
|---|
| 1269 | NODE *
|
|---|
| 1270 | oconvert(p) register NODE *p; {
|
|---|
| 1271 | /* convert the result itself: used for pointer and unsigned */
|
|---|
| 1272 |
|
|---|
| 1273 | switch(p->n_op) {
|
|---|
| 1274 |
|
|---|
| 1275 | case LE:
|
|---|
| 1276 | case LT:
|
|---|
| 1277 | case GE:
|
|---|
| 1278 | case GT:
|
|---|
| 1279 | if(ISUNSIGNED(p->n_left->n_type) ||
|
|---|
| 1280 | ISUNSIGNED(p->n_right->n_type) ||
|
|---|
| 1281 | ISPTR(p->n_left->n_type) ||
|
|---|
| 1282 | ISPTR(p->n_right->n_type))
|
|---|
| 1283 | p->n_op += (ULE-LE);
|
|---|
| 1284 | /* FALLTHROUGH */
|
|---|
| 1285 | case EQ:
|
|---|
| 1286 | case NE:
|
|---|
| 1287 | return( p );
|
|---|
| 1288 |
|
|---|
| 1289 | case MINUS:
|
|---|
| 1290 | p->n_type = INTPTR;
|
|---|
| 1291 | p->n_ap = MKAP(INTPTR);
|
|---|
| 1292 | return( clocal( block( PVCONV,
|
|---|
| 1293 | p, bpsize(p->n_left), INT, 0, MKAP(INT))));
|
|---|
| 1294 | }
|
|---|
| 1295 |
|
|---|
| 1296 | cerror( "illegal oconvert: %d", p->n_op );
|
|---|
| 1297 |
|
|---|
| 1298 | return(p);
|
|---|
| 1299 | }
|
|---|
| 1300 |
|
|---|
| 1301 | /*
|
|---|
| 1302 | * makes the operands of p agree; they are
|
|---|
| 1303 | * either pointers or integers, by this time
|
|---|
| 1304 | * with MINUS, the sizes must be the same
|
|---|
| 1305 | * with COLON, the types must be the same
|
|---|
| 1306 | */
|
|---|
| 1307 | NODE *
|
|---|
| 1308 | ptmatch(NODE *p)
|
|---|
| 1309 | {
|
|---|
| 1310 | struct attr *ap, *ap2;
|
|---|
| 1311 | union dimfun *d, *d2;
|
|---|
| 1312 | TWORD t1, t2, t, q1, q2, q;
|
|---|
| 1313 | int o;
|
|---|
| 1314 |
|
|---|
| 1315 | o = p->n_op;
|
|---|
| 1316 | t = t1 = p->n_left->n_type;
|
|---|
| 1317 | q = q1 = p->n_left->n_qual;
|
|---|
| 1318 | t2 = p->n_right->n_type;
|
|---|
| 1319 | q2 = p->n_right->n_qual;
|
|---|
| 1320 | d = p->n_left->n_df;
|
|---|
| 1321 | d2 = p->n_right->n_df;
|
|---|
| 1322 | ap = p->n_left->n_ap;
|
|---|
| 1323 | ap2 = p->n_right->n_ap;
|
|---|
| 1324 |
|
|---|
| 1325 | switch( o ){
|
|---|
| 1326 |
|
|---|
| 1327 | case ASSIGN:
|
|---|
| 1328 | case RETURN:
|
|---|
| 1329 | case CAST:
|
|---|
| 1330 | { break; }
|
|---|
| 1331 |
|
|---|
| 1332 | case MINUS: {
|
|---|
| 1333 | int isdyn(struct symtab *sp);
|
|---|
| 1334 | struct symtab s1, s2;
|
|---|
| 1335 |
|
|---|
| 1336 | s1.stype = DECREF(t);
|
|---|
| 1337 | s1.sdf = d;
|
|---|
| 1338 | s2.stype = DECREF(t2);
|
|---|
| 1339 | s2.sdf = d2;
|
|---|
| 1340 | if (isdyn(&s1) || isdyn(&s2))
|
|---|
| 1341 | ; /* We don't know */
|
|---|
| 1342 | else if (psize(p->n_left) != psize(p->n_right))
|
|---|
| 1343 | uerror("illegal pointer subtraction");
|
|---|
| 1344 | break;
|
|---|
| 1345 | }
|
|---|
| 1346 |
|
|---|
| 1347 | case COLON:
|
|---|
| 1348 | if (t1 != t2) {
|
|---|
| 1349 | /*
|
|---|
| 1350 | * Check for void pointer types. They are allowed
|
|---|
| 1351 | * to cast to/from any pointers.
|
|---|
| 1352 | */
|
|---|
| 1353 | if (ISPTR(t1) && ISPTR(t2) &&
|
|---|
| 1354 | (BTYPE(t1) == VOID || BTYPE(t2) == VOID))
|
|---|
| 1355 | break;
|
|---|
| 1356 | uerror("illegal types in :");
|
|---|
| 1357 | }
|
|---|
| 1358 | break;
|
|---|
| 1359 |
|
|---|
| 1360 | default: /* must work harder: relationals or comparisons */
|
|---|
| 1361 |
|
|---|
| 1362 | if( !ISPTR(t1) ){
|
|---|
| 1363 | t = t2;
|
|---|
| 1364 | q = q2;
|
|---|
| 1365 | d = d2;
|
|---|
| 1366 | ap = ap2;
|
|---|
| 1367 | break;
|
|---|
| 1368 | }
|
|---|
| 1369 | if( !ISPTR(t2) ){
|
|---|
| 1370 | break;
|
|---|
| 1371 | }
|
|---|
| 1372 |
|
|---|
| 1373 | /* both are pointers */
|
|---|
| 1374 | if( talign(t2,ap2) < talign(t,ap) ){
|
|---|
| 1375 | t = t2;
|
|---|
| 1376 | q = q2;
|
|---|
| 1377 | ap = ap2;
|
|---|
| 1378 | }
|
|---|
| 1379 | break;
|
|---|
| 1380 | }
|
|---|
| 1381 |
|
|---|
| 1382 | p->n_left = makety( p->n_left, t, q, d, ap );
|
|---|
| 1383 | p->n_right = makety( p->n_right, t, q, d, ap );
|
|---|
| 1384 | if( o!=MINUS && !clogop(o) ){
|
|---|
| 1385 |
|
|---|
| 1386 | p->n_type = t;
|
|---|
| 1387 | p->n_qual = q;
|
|---|
| 1388 | p->n_df = d;
|
|---|
| 1389 | p->n_ap = ap;
|
|---|
| 1390 | }
|
|---|
| 1391 |
|
|---|
| 1392 | return(clocal(p));
|
|---|
| 1393 | }
|
|---|
| 1394 |
|
|---|
| 1395 | int tdebug = 0;
|
|---|
| 1396 |
|
|---|
| 1397 |
|
|---|
| 1398 | /*
|
|---|
| 1399 | * Satisfy the types of various arithmetic binary ops.
|
|---|
| 1400 | *
|
|---|
| 1401 | * rules are:
|
|---|
| 1402 | * if assignment, type of LHS
|
|---|
| 1403 | * if any doubles, make double
|
|---|
| 1404 | * else if any float make float
|
|---|
| 1405 | * else if any longlongs, make long long
|
|---|
| 1406 | * else if any longs, make long
|
|---|
| 1407 | * else etcetc.
|
|---|
| 1408 | *
|
|---|
| 1409 | * If the op with the highest rank is unsigned, this is the resulting type.
|
|---|
| 1410 | * See: 6.3.1.1 rank order equal of signed and unsigned types
|
|---|
| 1411 | * 6.3.1.8 Usual arithmetic conversions
|
|---|
| 1412 | */
|
|---|
| 1413 | NODE *
|
|---|
| 1414 | tymatch(NODE *p)
|
|---|
| 1415 | {
|
|---|
| 1416 | TWORD tl, tr, t, tu;
|
|---|
| 1417 | NODE *l, *r;
|
|---|
| 1418 | int o, lu, ru;
|
|---|
| 1419 |
|
|---|
| 1420 | o = p->n_op;
|
|---|
| 1421 | r = p->n_right;
|
|---|
| 1422 | l = p->n_left;
|
|---|
| 1423 |
|
|---|
| 1424 | tl = l->n_type;
|
|---|
| 1425 | tr = r->n_type;
|
|---|
| 1426 |
|
|---|
| 1427 | lu = ru = 0;
|
|---|
| 1428 | if (ISUNSIGNED(tl)) {
|
|---|
| 1429 | lu = 1;
|
|---|
| 1430 | tl = DEUNSIGN(tl);
|
|---|
| 1431 | }
|
|---|
| 1432 | if (ISUNSIGNED(tr)) {
|
|---|
| 1433 | ru = 1;
|
|---|
| 1434 | tr = DEUNSIGN(tr);
|
|---|
| 1435 | }
|
|---|
| 1436 |
|
|---|
| 1437 | if (clogop(o) && tl == tr && lu != ru &&
|
|---|
| 1438 | l->n_op != ICON && r->n_op != ICON)
|
|---|
| 1439 | warner(Wsign_compare, NULL);
|
|---|
| 1440 |
|
|---|
| 1441 | if (tl == LDOUBLE || tr == LDOUBLE)
|
|---|
| 1442 | t = LDOUBLE;
|
|---|
| 1443 | else if (tl == DOUBLE || tr == DOUBLE)
|
|---|
| 1444 | t = DOUBLE;
|
|---|
| 1445 | else if (tl == FLOAT || tr == FLOAT)
|
|---|
| 1446 | t = FLOAT;
|
|---|
| 1447 | else if (tl==LONGLONG || tr == LONGLONG)
|
|---|
| 1448 | t = LONGLONG;
|
|---|
| 1449 | else if (tl==LONG || tr==LONG)
|
|---|
| 1450 | t = LONG;
|
|---|
| 1451 | else /* everything else */
|
|---|
| 1452 | t = INT;
|
|---|
| 1453 |
|
|---|
| 1454 | if (casgop(o)) {
|
|---|
| 1455 | tu = l->n_type;
|
|---|
| 1456 | t = tl;
|
|---|
| 1457 | } else {
|
|---|
| 1458 | /* Should result be unsigned? */
|
|---|
| 1459 | /* This depends on ctype() being called correctly */
|
|---|
| 1460 | tu = t;
|
|---|
| 1461 | if (UNSIGNABLE(t) && (lu || ru)) {
|
|---|
| 1462 | if (tl >= tr && lu)
|
|---|
| 1463 | tu = ENUNSIGN(t);
|
|---|
| 1464 | if (tr >= tl && ru)
|
|---|
| 1465 | tu = ENUNSIGN(t);
|
|---|
| 1466 | }
|
|---|
| 1467 | }
|
|---|
| 1468 |
|
|---|
| 1469 | /* because expressions have values that are at least as wide
|
|---|
| 1470 | as INT or UNSIGNED, the only conversions needed
|
|---|
| 1471 | are those involving FLOAT/DOUBLE, and those
|
|---|
| 1472 | from LONG to INT and ULONG to UNSIGNED */
|
|---|
| 1473 |
|
|---|
| 1474 | if (t != tl || (ru && !lu)) {
|
|---|
| 1475 | if (o != CAST && r->n_op != ICON &&
|
|---|
| 1476 | tsize(tl, 0, MKAP(tl)) > tsize(tu, 0, MKAP(tu)))
|
|---|
| 1477 | warner(Wtruncate, tnames[tu], tnames[tl]);
|
|---|
| 1478 | p->n_left = makety( p->n_left, tu, 0, 0, MKAP(tu));
|
|---|
| 1479 | }
|
|---|
| 1480 |
|
|---|
| 1481 | if (t != tr || o==CAST || (lu && !ru)) {
|
|---|
| 1482 | if (o != CAST && r->n_op != ICON &&
|
|---|
| 1483 | tsize(tr, 0, MKAP(tr)) > tsize(tu, 0, MKAP(tu)))
|
|---|
| 1484 | warner(Wtruncate, tnames[tu], tnames[tr]);
|
|---|
| 1485 | p->n_right = makety(p->n_right, tu, 0, 0, MKAP(tu));
|
|---|
| 1486 | }
|
|---|
| 1487 |
|
|---|
| 1488 | if( casgop(o) ){
|
|---|
| 1489 | p->n_type = p->n_left->n_type;
|
|---|
| 1490 | p->n_df = p->n_left->n_df;
|
|---|
| 1491 | p->n_ap = p->n_left->n_ap;
|
|---|
| 1492 | }
|
|---|
| 1493 | else if( !clogop(o) ){
|
|---|
| 1494 | p->n_type = tu;
|
|---|
| 1495 | p->n_df = NULL;
|
|---|
| 1496 | p->n_ap = MKAP(t);
|
|---|
| 1497 | }
|
|---|
| 1498 |
|
|---|
| 1499 | #ifdef PCC_DEBUG
|
|---|
| 1500 | if (tdebug) {
|
|---|
| 1501 | printf("tymatch(%p): ", p);
|
|---|
| 1502 | tprint(stdout, tl, 0);
|
|---|
| 1503 | printf(" %s ", copst(o));
|
|---|
| 1504 | tprint(stdout, tr, 0);
|
|---|
| 1505 | printf(" => ");
|
|---|
| 1506 | tprint(stdout, tu, 0);
|
|---|
| 1507 | printf("\n");
|
|---|
| 1508 | fwalk(p, eprint, 0);
|
|---|
| 1509 | }
|
|---|
| 1510 | #endif
|
|---|
| 1511 |
|
|---|
| 1512 | return(p);
|
|---|
| 1513 | }
|
|---|
| 1514 |
|
|---|
| 1515 | /*
|
|---|
| 1516 | * Create a float const node of zero.
|
|---|
| 1517 | */
|
|---|
| 1518 | static NODE *
|
|---|
| 1519 | fzero(TWORD t)
|
|---|
| 1520 | {
|
|---|
| 1521 | NODE *p = block(FCON, NIL, NIL, t, 0, MKAP(t));
|
|---|
| 1522 |
|
|---|
| 1523 | p->n_dcon = FLOAT_CAST(0, INT);
|
|---|
| 1524 | return p;
|
|---|
| 1525 | }
|
|---|
| 1526 |
|
|---|
| 1527 | /*
|
|---|
| 1528 | * make p into type t by inserting a conversion
|
|---|
| 1529 | */
|
|---|
| 1530 | NODE *
|
|---|
| 1531 | makety(NODE *p, TWORD t, TWORD q, union dimfun *d, struct attr *ap)
|
|---|
| 1532 | {
|
|---|
| 1533 |
|
|---|
| 1534 | if (t == p->n_type) {
|
|---|
| 1535 | p->n_df = d;
|
|---|
| 1536 | p->n_ap = ap;
|
|---|
| 1537 | p->n_qual = q;
|
|---|
| 1538 | return(p);
|
|---|
| 1539 | }
|
|---|
| 1540 |
|
|---|
| 1541 | if (p->n_op == FCON && (t >= FLOAT && t <= LDOUBLE)) {
|
|---|
| 1542 | if (t == FLOAT)
|
|---|
| 1543 | p->n_dcon = (float)p->n_dcon;
|
|---|
| 1544 | else if (t == DOUBLE)
|
|---|
| 1545 | p->n_dcon = (double)p->n_dcon;
|
|---|
| 1546 | else
|
|---|
| 1547 | p->n_dcon = (long double)p->n_dcon;
|
|---|
| 1548 | p->n_type = t;
|
|---|
| 1549 | return p;
|
|---|
| 1550 | }
|
|---|
| 1551 |
|
|---|
| 1552 | if (p->n_op == FCON) {
|
|---|
| 1553 | int isf = ISFTY(t);
|
|---|
| 1554 | NODE *r;
|
|---|
| 1555 |
|
|---|
| 1556 | if (isf||ISITY(t)) {
|
|---|
| 1557 | if (isf == ISFTY(p->n_type)) {
|
|---|
| 1558 | p->n_type = t;
|
|---|
| 1559 | p->n_qual = q;
|
|---|
| 1560 | p->n_df = d;
|
|---|
| 1561 | p->n_ap = ap;
|
|---|
| 1562 | return(p);
|
|---|
| 1563 | } else if (isf == ISITY(p->n_type)) {
|
|---|
| 1564 | /* will be zero */
|
|---|
| 1565 | nfree(p);
|
|---|
| 1566 | return fzero(t);
|
|---|
| 1567 | } else if (ISCTY(p->n_type))
|
|---|
| 1568 | cerror("complex constant");
|
|---|
| 1569 | } else if (ISCTY(t)) {
|
|---|
| 1570 | if (ISITY(p->n_type)) {
|
|---|
| 1571 | /* convert to correct subtype */
|
|---|
| 1572 | r = fzero(t - (COMPLEX-DOUBLE));
|
|---|
| 1573 | p->n_type = t + (IMAG-COMPLEX);
|
|---|
| 1574 | p->n_qual = q;
|
|---|
| 1575 | p->n_df = d;
|
|---|
| 1576 | p->n_ap = MKAP(p->n_type);
|
|---|
| 1577 | return block(CM, r, p, t, 0, MKAP(t));
|
|---|
| 1578 | } else if (ISFTY(p->n_type)) {
|
|---|
| 1579 | /* convert to correct subtype */
|
|---|
| 1580 | r = fzero(t + (IMAG-COMPLEX));
|
|---|
| 1581 | p->n_type = t - (COMPLEX-DOUBLE);
|
|---|
| 1582 | p->n_qual = q;
|
|---|
| 1583 | p->n_df = d;
|
|---|
| 1584 | p->n_ap = MKAP(p->n_type);
|
|---|
| 1585 | return block(CM, p, r, t, 0, MKAP(t));
|
|---|
| 1586 | } else if (ISCTY(p->n_type))
|
|---|
| 1587 | cerror("complex constant2");
|
|---|
| 1588 | }
|
|---|
| 1589 | }
|
|---|
| 1590 |
|
|---|
| 1591 | if (t & TMASK) {
|
|---|
| 1592 | /* non-simple type */
|
|---|
| 1593 | p = block(PCONV, p, NIL, t, d, ap);
|
|---|
| 1594 | p->n_qual = q;
|
|---|
| 1595 | return clocal(p);
|
|---|
| 1596 | }
|
|---|
| 1597 |
|
|---|
| 1598 | if (p->n_op == ICON) {
|
|---|
| 1599 | if (ISFTY(t)) {
|
|---|
| 1600 | p->n_op = FCON;
|
|---|
| 1601 | p->n_dcon = FLOAT_CAST(p->n_lval, p->n_type);
|
|---|
| 1602 | p->n_type = t;
|
|---|
| 1603 | p->n_qual = q;
|
|---|
| 1604 | p->n_ap = MKAP(t);
|
|---|
| 1605 | return (clocal(p));
|
|---|
| 1606 | } else if (ISCTY(t) || ISITY(t))
|
|---|
| 1607 | cerror("complex constant3");
|
|---|
| 1608 | }
|
|---|
| 1609 |
|
|---|
| 1610 | p = block(SCONV, p, NIL, t, d, ap);
|
|---|
| 1611 | p->n_qual = q;
|
|---|
| 1612 | return clocal(p);
|
|---|
| 1613 |
|
|---|
| 1614 | }
|
|---|
| 1615 |
|
|---|
| 1616 | NODE *
|
|---|
| 1617 | block(int o, NODE *l, NODE *r, TWORD t, union dimfun *d, struct attr *ap)
|
|---|
| 1618 | {
|
|---|
| 1619 | register NODE *p;
|
|---|
| 1620 |
|
|---|
| 1621 | p = talloc();
|
|---|
| 1622 | p->n_rval = 0;
|
|---|
| 1623 | p->n_op = o;
|
|---|
| 1624 | p->n_lval = 0; /* Protect against large lval */
|
|---|
| 1625 | p->n_left = l;
|
|---|
| 1626 | p->n_right = r;
|
|---|
| 1627 | p->n_type = t;
|
|---|
| 1628 | p->n_qual = 0;
|
|---|
| 1629 | p->n_df = d;
|
|---|
| 1630 | p->n_ap = ap;
|
|---|
| 1631 | #if !defined(MULTIPASS)
|
|---|
| 1632 | /* p->n_reg = */p->n_su = 0;
|
|---|
| 1633 | p->n_regw = 0;
|
|---|
| 1634 | #endif
|
|---|
| 1635 | return(p);
|
|---|
| 1636 | }
|
|---|
| 1637 |
|
|---|
| 1638 | /*
|
|---|
| 1639 | * Return the constant value from an ICON.
|
|---|
| 1640 | */
|
|---|
| 1641 | CONSZ
|
|---|
| 1642 | icons(NODE *p)
|
|---|
| 1643 | {
|
|---|
| 1644 | /* if p is an integer constant, return its value */
|
|---|
| 1645 | CONSZ val;
|
|---|
| 1646 |
|
|---|
| 1647 | if (p->n_op != ICON || p->n_sp != NULL) {
|
|---|
| 1648 | uerror( "constant expected");
|
|---|
| 1649 | val = 1;
|
|---|
| 1650 | } else
|
|---|
| 1651 | val = p->n_lval;
|
|---|
| 1652 | tfree(p);
|
|---|
| 1653 | return(val);
|
|---|
| 1654 | }
|
|---|
| 1655 |
|
|---|
| 1656 | /*
|
|---|
| 1657 | * the intent of this table is to examine the
|
|---|
| 1658 | * operators, and to check them for
|
|---|
| 1659 | * correctness.
|
|---|
| 1660 | *
|
|---|
| 1661 | * The table is searched for the op and the
|
|---|
| 1662 | * modified type (where this is one of the
|
|---|
| 1663 | * types INT (includes char and short), LONG,
|
|---|
| 1664 | * DOUBLE (includes FLOAT), and POINTER
|
|---|
| 1665 | *
|
|---|
| 1666 | * The default action is to make the node type integer
|
|---|
| 1667 | *
|
|---|
| 1668 | * The actions taken include:
|
|---|
| 1669 | * PUN check for puns
|
|---|
| 1670 | * CVTL convert the left operand
|
|---|
| 1671 | * CVTR convert the right operand
|
|---|
| 1672 | * TYPL the type is determined by the left operand
|
|---|
| 1673 | * TYPR the type is determined by the right operand
|
|---|
| 1674 | * TYMATCH force type of left and right to match,by inserting conversions
|
|---|
| 1675 | * PTMATCH like TYMATCH, but for pointers
|
|---|
| 1676 | * LVAL left operand must be lval
|
|---|
| 1677 | * CVTO convert the op
|
|---|
| 1678 | * NCVT do not convert the operands
|
|---|
| 1679 | * OTHER handled by code
|
|---|
| 1680 | * NCVTR convert the left operand, not the right...
|
|---|
| 1681 | *
|
|---|
| 1682 | */
|
|---|
| 1683 |
|
|---|
| 1684 | # define MINT 01 /* integer */
|
|---|
| 1685 | # define MDBI 02 /* integer or double */
|
|---|
| 1686 | # define MSTR 04 /* structure */
|
|---|
| 1687 | # define MPTR 010 /* pointer */
|
|---|
| 1688 | # define MPTI 020 /* pointer or integer */
|
|---|
| 1689 |
|
|---|
| 1690 | int
|
|---|
| 1691 | opact(NODE *p)
|
|---|
| 1692 | {
|
|---|
| 1693 | int mt12, mt1, mt2, o;
|
|---|
| 1694 |
|
|---|
| 1695 | mt1 = mt2 = mt12 = 0;
|
|---|
| 1696 |
|
|---|
| 1697 | switch (coptype(o = p->n_op)) {
|
|---|
| 1698 | case BITYPE:
|
|---|
| 1699 | mt12=mt2 = moditype(p->n_right->n_type);
|
|---|
| 1700 | case UTYPE:
|
|---|
| 1701 | mt12 &= (mt1 = moditype(p->n_left->n_type));
|
|---|
| 1702 | break;
|
|---|
| 1703 | }
|
|---|
| 1704 |
|
|---|
| 1705 | switch( o ){
|
|---|
| 1706 |
|
|---|
| 1707 | case NAME :
|
|---|
| 1708 | case ICON :
|
|---|
| 1709 | case FCON :
|
|---|
| 1710 | case CALL :
|
|---|
| 1711 | case UCALL:
|
|---|
| 1712 | case UMUL:
|
|---|
| 1713 | { return( OTHER ); }
|
|---|
| 1714 | case UMINUS:
|
|---|
| 1715 | if( mt1 & MDBI ) return( TYPL );
|
|---|
| 1716 | break;
|
|---|
| 1717 |
|
|---|
| 1718 | case COMPL:
|
|---|
| 1719 | if( mt1 & MINT ) return( TYPL );
|
|---|
| 1720 | break;
|
|---|
| 1721 |
|
|---|
| 1722 | case ADDROF:
|
|---|
| 1723 | return( NCVT+OTHER );
|
|---|
| 1724 | case NOT:
|
|---|
| 1725 | /* case INIT: */
|
|---|
| 1726 | case CM:
|
|---|
| 1727 | case CBRANCH:
|
|---|
| 1728 | case ANDAND:
|
|---|
| 1729 | case OROR:
|
|---|
| 1730 | return( 0 );
|
|---|
| 1731 |
|
|---|
| 1732 | case MUL:
|
|---|
| 1733 | case DIV:
|
|---|
| 1734 | if( mt12 & MDBI ) return( TYMATCH );
|
|---|
| 1735 | break;
|
|---|
| 1736 |
|
|---|
| 1737 | case MOD:
|
|---|
| 1738 | case AND:
|
|---|
| 1739 | case OR:
|
|---|
| 1740 | case ER:
|
|---|
| 1741 | if( mt12 & MINT ) return( TYMATCH );
|
|---|
| 1742 | break;
|
|---|
| 1743 |
|
|---|
| 1744 | case LS:
|
|---|
| 1745 | case RS:
|
|---|
| 1746 | if( mt12 & MINT ) return( TYPL+OTHER );
|
|---|
| 1747 | break;
|
|---|
| 1748 |
|
|---|
| 1749 | case EQ:
|
|---|
| 1750 | case NE:
|
|---|
| 1751 | case LT:
|
|---|
| 1752 | case LE:
|
|---|
| 1753 | case GT:
|
|---|
| 1754 | case GE:
|
|---|
| 1755 | if( mt12 & MDBI ) return( TYMATCH+CVTO );
|
|---|
| 1756 | else if( mt12 & MPTR ) return( PTMATCH+PUN+CVTO );
|
|---|
| 1757 | else if( mt12 & MPTI ) return( PTMATCH+PUN );
|
|---|
| 1758 | else break;
|
|---|
| 1759 |
|
|---|
| 1760 | case QUEST:
|
|---|
| 1761 | return( TYPR+OTHER );
|
|---|
| 1762 | case COMOP:
|
|---|
| 1763 | return( TYPR );
|
|---|
| 1764 |
|
|---|
| 1765 | case STREF:
|
|---|
| 1766 | return( NCVTR+OTHER );
|
|---|
| 1767 |
|
|---|
| 1768 | case FORCE:
|
|---|
| 1769 | return( TYPL );
|
|---|
| 1770 |
|
|---|
| 1771 | case COLON:
|
|---|
| 1772 | if( mt12 & MDBI ) return( TYMATCH );
|
|---|
| 1773 | else if( mt12 & MPTR ) return( TYPL+PTMATCH+PUN );
|
|---|
| 1774 | else if( (mt1&MINT) && (mt2&MPTR) ) return( TYPR+PUN );
|
|---|
| 1775 | else if( (mt1&MPTR) && (mt2&MINT) ) return( TYPL+PUN );
|
|---|
| 1776 | else if( mt12 & MSTR ) return( NCVT+TYPL+OTHER );
|
|---|
| 1777 | break;
|
|---|
| 1778 |
|
|---|
| 1779 | case ASSIGN:
|
|---|
| 1780 | case RETURN:
|
|---|
| 1781 | if( mt12 & MSTR ) return( LVAL+NCVT+TYPL+OTHER );
|
|---|
| 1782 | case CAST:
|
|---|
| 1783 | if( mt12 & MDBI ) return( TYPL+LVAL+TYMATCH );
|
|---|
| 1784 | else if( mt1 & MPTR) return( LVAL+PTMATCH+PUN );
|
|---|
| 1785 | else if( mt12 & MPTI ) return( TYPL+LVAL+TYMATCH+PUN );
|
|---|
| 1786 | break;
|
|---|
| 1787 |
|
|---|
| 1788 | case LSEQ:
|
|---|
| 1789 | case RSEQ:
|
|---|
| 1790 | if( mt12 & MINT ) return( TYPL+LVAL+OTHER );
|
|---|
| 1791 | break;
|
|---|
| 1792 |
|
|---|
| 1793 | case MULEQ:
|
|---|
| 1794 | case DIVEQ:
|
|---|
| 1795 | if( mt12 & MDBI ) return( LVAL+TYMATCH );
|
|---|
| 1796 | break;
|
|---|
| 1797 |
|
|---|
| 1798 | case MODEQ:
|
|---|
| 1799 | case ANDEQ:
|
|---|
| 1800 | case OREQ:
|
|---|
| 1801 | case EREQ:
|
|---|
| 1802 | if (mt12 & MINT)
|
|---|
| 1803 | return(LVAL+TYMATCH);
|
|---|
| 1804 | break;
|
|---|
| 1805 |
|
|---|
| 1806 | case PLUSEQ:
|
|---|
| 1807 | case MINUSEQ:
|
|---|
| 1808 | case INCR:
|
|---|
| 1809 | case DECR:
|
|---|
| 1810 | if (mt12 & MDBI)
|
|---|
| 1811 | return(TYMATCH+LVAL);
|
|---|
| 1812 | else if ((mt1&MPTR) && (mt2&MINT))
|
|---|
| 1813 | return(TYPL+LVAL+CVTR);
|
|---|
| 1814 | break;
|
|---|
| 1815 |
|
|---|
| 1816 | case MINUS:
|
|---|
| 1817 | if (mt12 & MPTR)
|
|---|
| 1818 | return(CVTO+PTMATCH+PUN);
|
|---|
| 1819 | if (mt2 & MPTR)
|
|---|
| 1820 | break;
|
|---|
| 1821 | /* FALLTHROUGH */
|
|---|
| 1822 | case PLUS:
|
|---|
| 1823 | if (mt12 & MDBI)
|
|---|
| 1824 | return(TYMATCH);
|
|---|
| 1825 | else if ((mt1&MPTR) && (mt2&MINT))
|
|---|
| 1826 | return(TYPL+CVTR);
|
|---|
| 1827 | else if ((mt1&MINT) && (mt2&MPTR))
|
|---|
| 1828 | return(TYPR+CVTL);
|
|---|
| 1829 |
|
|---|
| 1830 | }
|
|---|
| 1831 | uerror("operands of %s have incompatible types", copst(o));
|
|---|
| 1832 | return(NCVT);
|
|---|
| 1833 | }
|
|---|
| 1834 |
|
|---|
| 1835 | int
|
|---|
| 1836 | moditype(TWORD ty)
|
|---|
| 1837 | {
|
|---|
| 1838 | switch (ty) {
|
|---|
| 1839 |
|
|---|
| 1840 | case STRTY:
|
|---|
| 1841 | case UNIONTY:
|
|---|
| 1842 | return( MSTR );
|
|---|
| 1843 |
|
|---|
| 1844 | case BOOL:
|
|---|
| 1845 | case CHAR:
|
|---|
| 1846 | case SHORT:
|
|---|
| 1847 | case UCHAR:
|
|---|
| 1848 | case USHORT:
|
|---|
| 1849 | case UNSIGNED:
|
|---|
| 1850 | case ULONG:
|
|---|
| 1851 | case ULONGLONG:
|
|---|
| 1852 | case INT:
|
|---|
| 1853 | case LONG:
|
|---|
| 1854 | case LONGLONG:
|
|---|
| 1855 | return( MINT|MDBI|MPTI );
|
|---|
| 1856 | case FLOAT:
|
|---|
| 1857 | case DOUBLE:
|
|---|
| 1858 | case LDOUBLE:
|
|---|
| 1859 | #ifndef NO_COMPLEX
|
|---|
| 1860 | case FCOMPLEX:
|
|---|
| 1861 | case COMPLEX:
|
|---|
| 1862 | case LCOMPLEX:
|
|---|
| 1863 | case FIMAG:
|
|---|
| 1864 | case IMAG:
|
|---|
| 1865 | case LIMAG:
|
|---|
| 1866 | #endif
|
|---|
| 1867 | return( MDBI );
|
|---|
| 1868 | default:
|
|---|
| 1869 | return( MPTR|MPTI );
|
|---|
| 1870 |
|
|---|
| 1871 | }
|
|---|
| 1872 | }
|
|---|
| 1873 |
|
|---|
| 1874 | int tvaloff = MAXREGS+NPERMREG > 100 ? MAXREGS+NPERMREG + 100 : 100;
|
|---|
| 1875 |
|
|---|
| 1876 | /*
|
|---|
| 1877 | * Returns a TEMP node with temp number nr.
|
|---|
| 1878 | * If nr == 0, return a node with a new number.
|
|---|
| 1879 | */
|
|---|
| 1880 | NODE *
|
|---|
| 1881 | tempnode(int nr, TWORD type, union dimfun *df, struct attr *ap)
|
|---|
| 1882 | {
|
|---|
| 1883 | NODE *r;
|
|---|
| 1884 |
|
|---|
| 1885 | if (tvaloff == -NOOFFSET)
|
|---|
| 1886 | tvaloff++; /* Skip this for array indexing */
|
|---|
| 1887 | r = block(TEMP, NIL, NIL, type, df, ap);
|
|---|
| 1888 | regno(r) = nr ? nr : tvaloff;
|
|---|
| 1889 | tvaloff += szty(type);
|
|---|
| 1890 | return r;
|
|---|
| 1891 | }
|
|---|
| 1892 |
|
|---|
| 1893 | /*
|
|---|
| 1894 | * Do sizeof on p.
|
|---|
| 1895 | */
|
|---|
| 1896 | NODE *
|
|---|
| 1897 | doszof(NODE *p)
|
|---|
| 1898 | {
|
|---|
| 1899 | extern NODE *arrstk[10];
|
|---|
| 1900 | extern int arrstkp;
|
|---|
| 1901 | union dimfun *df;
|
|---|
| 1902 | TWORD ty;
|
|---|
| 1903 | NODE *rv, *q;
|
|---|
| 1904 | int astkp;
|
|---|
| 1905 |
|
|---|
| 1906 | if (p->n_op == FLD)
|
|---|
| 1907 | uerror("can't apply sizeof to bit-field");
|
|---|
| 1908 |
|
|---|
| 1909 | /*
|
|---|
| 1910 | * Arrays may be dynamic, may need to make computations.
|
|---|
| 1911 | */
|
|---|
| 1912 |
|
|---|
| 1913 | rv = bcon(1);
|
|---|
| 1914 | df = p->n_df;
|
|---|
| 1915 | ty = p->n_type;
|
|---|
| 1916 | astkp = 0;
|
|---|
| 1917 | while (ISARY(ty)) {
|
|---|
| 1918 | if (df->ddim == NOOFFSET)
|
|---|
| 1919 | uerror("sizeof of incomplete type");
|
|---|
| 1920 | if (df->ddim < 0) {
|
|---|
| 1921 | if (arrstkp)
|
|---|
| 1922 | q = arrstk[astkp++];
|
|---|
| 1923 | else
|
|---|
| 1924 | q = tempnode(-df->ddim, INT, 0, MKAP(INT));
|
|---|
| 1925 | } else
|
|---|
| 1926 | q = bcon(df->ddim);
|
|---|
| 1927 | rv = buildtree(MUL, rv, q);
|
|---|
| 1928 | df++;
|
|---|
| 1929 | ty = DECREF(ty);
|
|---|
| 1930 | }
|
|---|
| 1931 | rv = buildtree(MUL, rv, bcon(tsize(ty, p->n_df, p->n_ap)/SZCHAR));
|
|---|
| 1932 | tfree(p);
|
|---|
| 1933 | arrstkp = 0; /* XXX - may this fail? */
|
|---|
| 1934 | return rv;
|
|---|
| 1935 | }
|
|---|
| 1936 |
|
|---|
| 1937 | #ifdef PCC_DEBUG
|
|---|
| 1938 | void
|
|---|
| 1939 | eprint(NODE *p, int down, int *a, int *b)
|
|---|
| 1940 | {
|
|---|
| 1941 | int ty;
|
|---|
| 1942 |
|
|---|
| 1943 | *a = *b = down+1;
|
|---|
| 1944 | while( down > 1 ){
|
|---|
| 1945 | printf( "\t" );
|
|---|
| 1946 | down -= 2;
|
|---|
| 1947 | }
|
|---|
| 1948 | if( down ) printf( " " );
|
|---|
| 1949 |
|
|---|
| 1950 | ty = coptype( p->n_op );
|
|---|
| 1951 |
|
|---|
| 1952 | printf("%p) %s, ", p, copst(p->n_op));
|
|---|
| 1953 | if (p->n_op == XARG || p->n_op == XASM)
|
|---|
| 1954 | printf("id '%s', ", p->n_name);
|
|---|
| 1955 | if (ty == LTYPE) {
|
|---|
| 1956 | printf(CONFMT, p->n_lval);
|
|---|
| 1957 | if (p->n_op == NAME || p->n_op == ICON)
|
|---|
| 1958 | printf(", %p, ", p->n_sp);
|
|---|
| 1959 | else
|
|---|
| 1960 | printf(", %d, ", p->n_rval);
|
|---|
| 1961 | }
|
|---|
| 1962 | tprint(stdout, p->n_type, p->n_qual);
|
|---|
| 1963 | printf( ", %p, ", p->n_df);
|
|---|
| 1964 | dump_attr(p->n_ap);
|
|---|
| 1965 | }
|
|---|
| 1966 | # endif
|
|---|
| 1967 |
|
|---|
| 1968 | /*
|
|---|
| 1969 | * Emit everything that should be emitted on the left side
|
|---|
| 1970 | * of a comma operator, and remove the operator.
|
|---|
| 1971 | * Do not traverse through QUEST, ANDAND and OROR.
|
|---|
| 1972 | * Enable this for all targets when stable enough.
|
|---|
| 1973 | */
|
|---|
| 1974 | static void
|
|---|
| 1975 | comops(NODE *p)
|
|---|
| 1976 | {
|
|---|
| 1977 | int o;
|
|---|
| 1978 | NODE *q;
|
|---|
| 1979 |
|
|---|
| 1980 | while (p->n_op == COMOP) {
|
|---|
| 1981 | /* XXX hack for GCC ({ }) ops */
|
|---|
| 1982 | if (p->n_left->n_op == GOTO) {
|
|---|
| 1983 | int v = (int)p->n_left->n_left->n_lval;
|
|---|
| 1984 | ecomp(p->n_left);
|
|---|
| 1985 | plabel(v+1);
|
|---|
| 1986 | } else
|
|---|
| 1987 | ecomp(p->n_left); /* will recurse if more COMOPs */
|
|---|
| 1988 | q = p->n_right;
|
|---|
| 1989 | *p = *q;
|
|---|
| 1990 | nfree(q);
|
|---|
| 1991 | }
|
|---|
| 1992 | o = coptype(p->n_op);
|
|---|
| 1993 | if (p->n_op == QUEST || p->n_op == ANDAND || p->n_op == OROR)
|
|---|
| 1994 | o = UTYPE;
|
|---|
| 1995 | if (o != LTYPE)
|
|---|
| 1996 | comops(p->n_left);
|
|---|
| 1997 | if (o == BITYPE)
|
|---|
| 1998 | comops(p->n_right);
|
|---|
| 1999 | }
|
|---|
| 2000 |
|
|---|
| 2001 | /*
|
|---|
| 2002 | * Walk up through the tree from the leaves,
|
|---|
| 2003 | * removing constant operators.
|
|---|
| 2004 | */
|
|---|
| 2005 | static void
|
|---|
| 2006 | logwalk(NODE *p)
|
|---|
| 2007 | {
|
|---|
| 2008 | int o = coptype(p->n_op);
|
|---|
| 2009 | NODE *l, *r;
|
|---|
| 2010 |
|
|---|
| 2011 | l = p->n_left;
|
|---|
| 2012 | r = p->n_right;
|
|---|
| 2013 | switch (o) {
|
|---|
| 2014 | case LTYPE:
|
|---|
| 2015 | return;
|
|---|
| 2016 | case BITYPE:
|
|---|
| 2017 | logwalk(r);
|
|---|
| 2018 | case UTYPE:
|
|---|
| 2019 | logwalk(l);
|
|---|
| 2020 | }
|
|---|
| 2021 | if (!clogop(p->n_op))
|
|---|
| 2022 | return;
|
|---|
| 2023 | if (p->n_op == NOT && l->n_op == ICON) {
|
|---|
| 2024 | p->n_lval = l->n_lval == 0;
|
|---|
| 2025 | nfree(l);
|
|---|
| 2026 | p->n_op = ICON;
|
|---|
| 2027 | }
|
|---|
| 2028 | if (l->n_op == ICON && r->n_op == ICON) {
|
|---|
| 2029 | if (conval(l, p->n_op, r) == 0) {
|
|---|
| 2030 | /*
|
|---|
| 2031 | * people sometimes tend to do really odd compares,
|
|---|
| 2032 | * like "if ("abc" == "def")" etc.
|
|---|
| 2033 | * do it runtime instead.
|
|---|
| 2034 | */
|
|---|
| 2035 | } else {
|
|---|
| 2036 | p->n_lval = l->n_lval;
|
|---|
| 2037 | p->n_op = ICON;
|
|---|
| 2038 | nfree(l);
|
|---|
| 2039 | nfree(r);
|
|---|
| 2040 | }
|
|---|
| 2041 | }
|
|---|
| 2042 | }
|
|---|
| 2043 |
|
|---|
| 2044 | /*
|
|---|
| 2045 | * Removes redundant logical operators for branch conditions.
|
|---|
| 2046 | */
|
|---|
| 2047 | static void
|
|---|
| 2048 | fixbranch(NODE *p, int label)
|
|---|
| 2049 | {
|
|---|
| 2050 |
|
|---|
| 2051 | logwalk(p);
|
|---|
| 2052 |
|
|---|
| 2053 | if (p->n_op == ICON) {
|
|---|
| 2054 | if (p->n_lval != 0)
|
|---|
| 2055 | branch(label);
|
|---|
| 2056 | nfree(p);
|
|---|
| 2057 | } else {
|
|---|
| 2058 | if (!clogop(p->n_op)) /* Always conditional */
|
|---|
| 2059 | p = buildtree(NE, p, bcon(0));
|
|---|
| 2060 | ecode(buildtree(CBRANCH, p, bcon(label)));
|
|---|
| 2061 | }
|
|---|
| 2062 | }
|
|---|
| 2063 |
|
|---|
| 2064 | /*
|
|---|
| 2065 | * Write out logical expressions as branches.
|
|---|
| 2066 | */
|
|---|
| 2067 | static void
|
|---|
| 2068 | andorbr(NODE *p, int true, int false)
|
|---|
| 2069 | {
|
|---|
| 2070 | NODE *q;
|
|---|
| 2071 | int o, lab;
|
|---|
| 2072 |
|
|---|
| 2073 | lab = -1;
|
|---|
| 2074 | switch (o = p->n_op) {
|
|---|
| 2075 | case EQ:
|
|---|
| 2076 | case NE:
|
|---|
| 2077 | /*
|
|---|
| 2078 | * Remove redundant EQ/NE nodes.
|
|---|
| 2079 | */
|
|---|
| 2080 | while (((o = p->n_left->n_op) == EQ || o == NE) &&
|
|---|
| 2081 | p->n_right->n_op == ICON) {
|
|---|
| 2082 | o = p->n_op;
|
|---|
| 2083 | q = p->n_left;
|
|---|
| 2084 | if (p->n_right->n_lval == 0) {
|
|---|
| 2085 | nfree(p->n_right);
|
|---|
| 2086 | *p = *q;
|
|---|
| 2087 | nfree(q);
|
|---|
| 2088 | if (o == EQ)
|
|---|
| 2089 | p->n_op = negrel[p->n_op - EQ];
|
|---|
| 2090 | #if 0
|
|---|
| 2091 | p->n_op = NE; /* toggla */
|
|---|
| 2092 | #endif
|
|---|
| 2093 | } else if (p->n_right->n_lval == 1) {
|
|---|
| 2094 | nfree(p->n_right);
|
|---|
| 2095 | *p = *q;
|
|---|
| 2096 | nfree(q);
|
|---|
| 2097 | if (o == NE)
|
|---|
| 2098 | p->n_op = negrel[p->n_op - EQ];
|
|---|
| 2099 | #if 0
|
|---|
| 2100 | p->n_op = EQ; /* toggla */
|
|---|
| 2101 | #endif
|
|---|
| 2102 | } else
|
|---|
| 2103 | break; /* XXX - should always be false */
|
|---|
| 2104 |
|
|---|
| 2105 | }
|
|---|
| 2106 | /* FALLTHROUGH */
|
|---|
| 2107 | case LE:
|
|---|
| 2108 | case LT:
|
|---|
| 2109 | case GE:
|
|---|
| 2110 | case GT:
|
|---|
| 2111 | calc: if (true < 0) {
|
|---|
| 2112 | p->n_op = negrel[p->n_op - EQ];
|
|---|
| 2113 | true = false;
|
|---|
| 2114 | false = -1;
|
|---|
| 2115 | }
|
|---|
| 2116 |
|
|---|
| 2117 | rmcops(p->n_left);
|
|---|
| 2118 | rmcops(p->n_right);
|
|---|
| 2119 | fixbranch(p, true);
|
|---|
| 2120 | if (false >= 0)
|
|---|
| 2121 | branch(false);
|
|---|
| 2122 | break;
|
|---|
| 2123 |
|
|---|
| 2124 | case ULE:
|
|---|
| 2125 | case UGT:
|
|---|
| 2126 | /* Convert to friendlier ops */
|
|---|
| 2127 | if (p->n_right->n_op == ICON && p->n_right->n_lval == 0)
|
|---|
| 2128 | p->n_op = o == ULE ? EQ : NE;
|
|---|
| 2129 | goto calc;
|
|---|
| 2130 |
|
|---|
| 2131 | case UGE:
|
|---|
| 2132 | case ULT:
|
|---|
| 2133 | /* Already true/false by definition */
|
|---|
| 2134 | if (p->n_right->n_op == ICON && p->n_right->n_lval == 0) {
|
|---|
| 2135 | if (true < 0) {
|
|---|
| 2136 | o = o == ULT ? UGE : ULT;
|
|---|
| 2137 | true = false;
|
|---|
| 2138 | }
|
|---|
| 2139 | rmcops(p->n_left);
|
|---|
| 2140 | ecode(p->n_left);
|
|---|
| 2141 | rmcops(p->n_right);
|
|---|
| 2142 | ecode(p->n_right);
|
|---|
| 2143 | nfree(p);
|
|---|
| 2144 | if (o == UGE) /* true */
|
|---|
| 2145 | branch(true);
|
|---|
| 2146 | break;
|
|---|
| 2147 | }
|
|---|
| 2148 | goto calc;
|
|---|
| 2149 |
|
|---|
| 2150 | case ANDAND:
|
|---|
| 2151 | lab = false<0 ? getlab() : false ;
|
|---|
| 2152 | andorbr(p->n_left, -1, lab);
|
|---|
| 2153 | comops(p->n_right);
|
|---|
| 2154 | andorbr(p->n_right, true, false);
|
|---|
| 2155 | if (false < 0)
|
|---|
| 2156 | plabel( lab);
|
|---|
| 2157 | nfree(p);
|
|---|
| 2158 | break;
|
|---|
| 2159 |
|
|---|
| 2160 | case OROR:
|
|---|
| 2161 | lab = true<0 ? getlab() : true;
|
|---|
| 2162 | andorbr(p->n_left, lab, -1);
|
|---|
| 2163 | comops(p->n_right);
|
|---|
| 2164 | andorbr(p->n_right, true, false);
|
|---|
| 2165 | if (true < 0)
|
|---|
| 2166 | plabel( lab);
|
|---|
| 2167 | nfree(p);
|
|---|
| 2168 | break;
|
|---|
| 2169 |
|
|---|
| 2170 | case NOT:
|
|---|
| 2171 | andorbr(p->n_left, false, true);
|
|---|
| 2172 | nfree(p);
|
|---|
| 2173 | break;
|
|---|
| 2174 |
|
|---|
| 2175 | default:
|
|---|
| 2176 | rmcops(p);
|
|---|
| 2177 | if (true >= 0)
|
|---|
| 2178 | fixbranch(p, true);
|
|---|
| 2179 | if (false >= 0) {
|
|---|
| 2180 | if (true >= 0)
|
|---|
| 2181 | branch(false);
|
|---|
| 2182 | else
|
|---|
| 2183 | fixbranch(buildtree(EQ, p, bcon(0)), false);
|
|---|
| 2184 | }
|
|---|
| 2185 | }
|
|---|
| 2186 | }
|
|---|
| 2187 |
|
|---|
| 2188 | /*
|
|---|
| 2189 | * Create a node for either TEMP or on-stack storage.
|
|---|
| 2190 | */
|
|---|
| 2191 | static NODE *
|
|---|
| 2192 | cstknode(TWORD t, union dimfun *df, struct attr *ap)
|
|---|
| 2193 | {
|
|---|
| 2194 | struct symtab *sp;
|
|---|
| 2195 |
|
|---|
| 2196 | /* create a symtab entry suitable for this type */
|
|---|
| 2197 | sp = getsymtab("0hej", STEMP);
|
|---|
| 2198 | sp->stype = t;
|
|---|
| 2199 | sp->sdf = df;
|
|---|
| 2200 | sp->sap = ap;
|
|---|
| 2201 | sp->sclass = AUTO;
|
|---|
| 2202 | sp->soffset = NOOFFSET;
|
|---|
| 2203 | oalloc(sp, &autooff);
|
|---|
| 2204 | return nametree(sp);
|
|---|
| 2205 |
|
|---|
| 2206 | }
|
|---|
| 2207 |
|
|---|
| 2208 | /*
|
|---|
| 2209 | * Massage the output trees to remove C-specific nodes:
|
|---|
| 2210 | * COMOPs are split into separate statements.
|
|---|
| 2211 | * QUEST/COLON are rewritten to branches.
|
|---|
| 2212 | * ANDAND/OROR/NOT are rewritten to branches for lazy-evaluation.
|
|---|
| 2213 | * CBRANCH conditions are rewritten for lazy-evaluation.
|
|---|
| 2214 | */
|
|---|
| 2215 | static void
|
|---|
| 2216 | rmcops(NODE *p)
|
|---|
| 2217 | {
|
|---|
| 2218 | TWORD type;
|
|---|
| 2219 | NODE *q, *r, *tval;
|
|---|
| 2220 | int o, ty, lbl, lbl2;
|
|---|
| 2221 |
|
|---|
| 2222 | tval = NIL;
|
|---|
| 2223 | o = p->n_op;
|
|---|
| 2224 | ty = coptype(o);
|
|---|
| 2225 | if (BTYPE(p->n_type) == ENUMTY) { /* fixup enum */
|
|---|
| 2226 | struct symtab *sp = strmemb(p->n_ap);
|
|---|
| 2227 | MODTYPE(p->n_type, sp->stype);
|
|---|
| 2228 | /*
|
|---|
| 2229 | * XXX may fail if these are true:
|
|---|
| 2230 | * - variable-sized enums
|
|---|
| 2231 | * - non-byte-addressed targets.
|
|---|
| 2232 | */
|
|---|
| 2233 | if (BTYPE(p->n_type) == ENUMTY && ISPTR(p->n_type))
|
|---|
| 2234 | MODTYPE(p->n_type, INT); /* INT ok? */
|
|---|
| 2235 | }
|
|---|
| 2236 | switch (o) {
|
|---|
| 2237 | case QUEST:
|
|---|
| 2238 |
|
|---|
| 2239 | /*
|
|---|
| 2240 | * Create a branch node from ?:
|
|---|
| 2241 | * || and && must be taken special care of.
|
|---|
| 2242 | */
|
|---|
| 2243 | type = p->n_type;
|
|---|
| 2244 | andorbr(p->n_left, -1, lbl = getlab());
|
|---|
| 2245 |
|
|---|
| 2246 | /* Make ASSIGN node */
|
|---|
| 2247 | /* Only if type is not void */
|
|---|
| 2248 | q = p->n_right->n_left;
|
|---|
| 2249 | comops(q);
|
|---|
| 2250 | if (type != VOID) {
|
|---|
| 2251 | tval = cstknode(q->n_type, q->n_df, q->n_ap);
|
|---|
| 2252 | q = buildtree(ASSIGN, ccopy(tval), q);
|
|---|
| 2253 | }
|
|---|
| 2254 | rmcops(q);
|
|---|
| 2255 | ecode(q); /* Done with assign */
|
|---|
| 2256 | branch(lbl2 = getlab());
|
|---|
| 2257 | plabel( lbl);
|
|---|
| 2258 |
|
|---|
| 2259 | q = p->n_right->n_right;
|
|---|
| 2260 | comops(q);
|
|---|
| 2261 | if (type != VOID) {
|
|---|
| 2262 | q = buildtree(ASSIGN, ccopy(tval), q);
|
|---|
| 2263 | }
|
|---|
| 2264 | rmcops(q);
|
|---|
| 2265 | ecode(q); /* Done with assign */
|
|---|
| 2266 |
|
|---|
| 2267 | plabel( lbl2);
|
|---|
| 2268 |
|
|---|
| 2269 | nfree(p->n_right);
|
|---|
| 2270 | if (p->n_type != VOID) {
|
|---|
| 2271 | *p = *tval;
|
|---|
| 2272 | nfree(tval);
|
|---|
| 2273 | } else {
|
|---|
| 2274 | p->n_op = ICON;
|
|---|
| 2275 | p->n_lval = 0;
|
|---|
| 2276 | p->n_sp = NULL;
|
|---|
| 2277 | }
|
|---|
| 2278 | break;
|
|---|
| 2279 |
|
|---|
| 2280 | case ULE:
|
|---|
| 2281 | case ULT:
|
|---|
| 2282 | case UGE:
|
|---|
| 2283 | case UGT:
|
|---|
| 2284 | case EQ:
|
|---|
| 2285 | case NE:
|
|---|
| 2286 | case LE:
|
|---|
| 2287 | case LT:
|
|---|
| 2288 | case GE:
|
|---|
| 2289 | case GT:
|
|---|
| 2290 | case ANDAND:
|
|---|
| 2291 | case OROR:
|
|---|
| 2292 | case NOT:
|
|---|
| 2293 | #ifdef SPECIAL_CCODES
|
|---|
| 2294 | #error fix for private CCODES handling
|
|---|
| 2295 | #else
|
|---|
| 2296 | r = talloc();
|
|---|
| 2297 | *r = *p;
|
|---|
| 2298 | andorbr(r, -1, lbl = getlab());
|
|---|
| 2299 |
|
|---|
| 2300 | tval = cstknode(p->n_type, p->n_df, p->n_ap);
|
|---|
| 2301 |
|
|---|
| 2302 | ecode(buildtree(ASSIGN, ccopy(tval), bcon(1)));
|
|---|
| 2303 | branch(lbl2 = getlab());
|
|---|
| 2304 | plabel( lbl);
|
|---|
| 2305 | ecode(buildtree(ASSIGN, ccopy(tval), bcon(0)));
|
|---|
| 2306 | plabel( lbl2);
|
|---|
| 2307 |
|
|---|
| 2308 | *p = *tval;
|
|---|
| 2309 | nfree(tval);
|
|---|
| 2310 |
|
|---|
| 2311 | #endif
|
|---|
| 2312 | break;
|
|---|
| 2313 | case CBRANCH:
|
|---|
| 2314 | andorbr(p->n_left, p->n_right->n_lval, -1);
|
|---|
| 2315 | nfree(p->n_right);
|
|---|
| 2316 | p->n_op = ICON; p->n_type = VOID;
|
|---|
| 2317 | break;
|
|---|
| 2318 | case COMOP:
|
|---|
| 2319 | cerror("COMOP error");
|
|---|
| 2320 |
|
|---|
| 2321 | default:
|
|---|
| 2322 | if (ty == LTYPE)
|
|---|
| 2323 | return;
|
|---|
| 2324 | rmcops(p->n_left);
|
|---|
| 2325 | if (ty == BITYPE)
|
|---|
| 2326 | rmcops(p->n_right);
|
|---|
| 2327 | }
|
|---|
| 2328 | }
|
|---|
| 2329 |
|
|---|
| 2330 | /*
|
|---|
| 2331 | * Return 1 if an assignment is found.
|
|---|
| 2332 | */
|
|---|
| 2333 | static int
|
|---|
| 2334 | has_se(NODE *p)
|
|---|
| 2335 | {
|
|---|
| 2336 | if (cdope(p->n_op) & ASGFLG)
|
|---|
| 2337 | return 1;
|
|---|
| 2338 | if (coptype(p->n_op) == LTYPE)
|
|---|
| 2339 | return 0;
|
|---|
| 2340 | if (has_se(p->n_left))
|
|---|
| 2341 | return 1;
|
|---|
| 2342 | if (coptype(p->n_op) == BITYPE)
|
|---|
| 2343 | return has_se(p->n_right);
|
|---|
| 2344 | return 0;
|
|---|
| 2345 | }
|
|---|
| 2346 |
|
|---|
| 2347 | /*
|
|---|
| 2348 | * Find and convert asgop's to separate statements.
|
|---|
| 2349 | * Be careful about side effects.
|
|---|
| 2350 | * assign tells whether ASSIGN should be considered giving
|
|---|
| 2351 | * side effects or not.
|
|---|
| 2352 | */
|
|---|
| 2353 | static NODE *
|
|---|
| 2354 | delasgop(NODE *p)
|
|---|
| 2355 | {
|
|---|
| 2356 | NODE *q, *r;
|
|---|
| 2357 | int tval;
|
|---|
| 2358 |
|
|---|
| 2359 | if (p->n_op == INCR || p->n_op == DECR) {
|
|---|
| 2360 | /*
|
|---|
| 2361 | * Rewrite x++ to (x += 1) -1; and deal with it further down.
|
|---|
| 2362 | * Pass2 will remove -1 if unnecessary.
|
|---|
| 2363 | */
|
|---|
| 2364 | q = ccopy(p);
|
|---|
| 2365 | tfree(p->n_left);
|
|---|
| 2366 | q->n_op = (p->n_op==INCR)?PLUSEQ:MINUSEQ;
|
|---|
| 2367 | p->n_op = (p->n_op==INCR)?MINUS:PLUS;
|
|---|
| 2368 | p->n_left = delasgop(q);
|
|---|
| 2369 |
|
|---|
| 2370 | } else if ((cdope(p->n_op)&ASGOPFLG) &&
|
|---|
| 2371 | p->n_op != RETURN && p->n_op != CAST) {
|
|---|
| 2372 | NODE *l = p->n_left;
|
|---|
| 2373 | NODE *ll = l->n_left;
|
|---|
| 2374 |
|
|---|
| 2375 | if (has_se(l)) {
|
|---|
| 2376 | q = tempnode(0, ll->n_type, ll->n_df, ll->n_ap);
|
|---|
| 2377 | tval = regno(q);
|
|---|
| 2378 | r = tempnode(tval, ll->n_type, ll->n_df,ll->n_ap);
|
|---|
| 2379 | l->n_left = q;
|
|---|
| 2380 | /* Now the left side of node p has no side effects. */
|
|---|
| 2381 | /* side effects on the right side must be obeyed */
|
|---|
| 2382 | p = delasgop(p);
|
|---|
| 2383 |
|
|---|
| 2384 | r = buildtree(ASSIGN, r, ll);
|
|---|
| 2385 | r = delasgop(r);
|
|---|
| 2386 | ecode(r);
|
|---|
| 2387 | } else {
|
|---|
| 2388 | #if 0 /* Cannot call buildtree() here, it would invoke double add shifts */
|
|---|
| 2389 | p->n_right = buildtree(UNASG p->n_op, ccopy(l),
|
|---|
| 2390 | p->n_right);
|
|---|
| 2391 | #else
|
|---|
| 2392 | p->n_right = block(UNASG p->n_op, ccopy(l),
|
|---|
| 2393 | p->n_right, p->n_type, p->n_df, p->n_ap);
|
|---|
| 2394 | #endif
|
|---|
| 2395 | p->n_op = ASSIGN;
|
|---|
| 2396 | p->n_right = delasgop(p->n_right);
|
|---|
| 2397 | p->n_right = clocal(p->n_right);
|
|---|
| 2398 | }
|
|---|
| 2399 |
|
|---|
| 2400 | } else {
|
|---|
| 2401 | if (coptype(p->n_op) == LTYPE)
|
|---|
| 2402 | return p;
|
|---|
| 2403 | p->n_left = delasgop(p->n_left);
|
|---|
| 2404 | if (coptype(p->n_op) == BITYPE)
|
|---|
| 2405 | p->n_right = delasgop(p->n_right);
|
|---|
| 2406 | }
|
|---|
| 2407 | return p;
|
|---|
| 2408 | }
|
|---|
| 2409 |
|
|---|
| 2410 | int edebug = 0;
|
|---|
| 2411 | void
|
|---|
| 2412 | ecomp(NODE *p)
|
|---|
| 2413 | {
|
|---|
| 2414 |
|
|---|
| 2415 | #ifdef PCC_DEBUG
|
|---|
| 2416 | if (edebug)
|
|---|
| 2417 | fwalk(p, eprint, 0);
|
|---|
| 2418 | #endif
|
|---|
| 2419 | if (!reached) {
|
|---|
| 2420 | warner(Wunreachable_code, NULL);
|
|---|
| 2421 | reached = 1;
|
|---|
| 2422 | }
|
|---|
| 2423 | p = optim(p);
|
|---|
| 2424 | comops(p);
|
|---|
| 2425 | rmcops(p);
|
|---|
| 2426 | p = delasgop(p);
|
|---|
| 2427 | if (p->n_op == ICON && p->n_type == VOID)
|
|---|
| 2428 | tfree(p);
|
|---|
| 2429 | else
|
|---|
| 2430 | ecode(p);
|
|---|
| 2431 | }
|
|---|
| 2432 |
|
|---|
| 2433 |
|
|---|
| 2434 | #if defined(MULTIPASS)
|
|---|
| 2435 | void
|
|---|
| 2436 | p2tree(NODE *p)
|
|---|
| 2437 | {
|
|---|
| 2438 | struct symtab *q;
|
|---|
| 2439 | int ty;
|
|---|
| 2440 |
|
|---|
| 2441 | myp2tree(p); /* local action can be taken here */
|
|---|
| 2442 |
|
|---|
| 2443 | ty = coptype(p->n_op);
|
|---|
| 2444 |
|
|---|
| 2445 | printf("%d\t", p->n_op);
|
|---|
| 2446 |
|
|---|
| 2447 | if (ty == LTYPE) {
|
|---|
| 2448 | printf(CONFMT, p->n_lval);
|
|---|
| 2449 | printf("\t");
|
|---|
| 2450 | }
|
|---|
| 2451 | if (ty != BITYPE) {
|
|---|
| 2452 | if (p->n_op == NAME || p->n_op == ICON)
|
|---|
| 2453 | printf("0\t");
|
|---|
| 2454 | else
|
|---|
| 2455 | printf("%d\t", p->n_rval);
|
|---|
| 2456 | }
|
|---|
| 2457 |
|
|---|
| 2458 | printf("%o\t", p->n_type);
|
|---|
| 2459 |
|
|---|
| 2460 | /* handle special cases */
|
|---|
| 2461 |
|
|---|
| 2462 | switch (p->n_op) {
|
|---|
| 2463 |
|
|---|
| 2464 | case NAME:
|
|---|
| 2465 | case ICON:
|
|---|
| 2466 | /* print external name */
|
|---|
| 2467 | if ((q = p->n_sp) != NULL) {
|
|---|
| 2468 | if ((q->sclass == STATIC && q->slevel > 0)) {
|
|---|
| 2469 | printf(LABFMT, q->soffset);
|
|---|
| 2470 | } else
|
|---|
| 2471 | printf("%s\n",
|
|---|
| 2472 | q->soname ? q->soname : exname(q->sname));
|
|---|
| 2473 | } else
|
|---|
| 2474 | printf("\n");
|
|---|
| 2475 | break;
|
|---|
| 2476 |
|
|---|
| 2477 | case STARG:
|
|---|
| 2478 | case STASG:
|
|---|
| 2479 | case STCALL:
|
|---|
| 2480 | case USTCALL:
|
|---|
| 2481 | /* print out size */
|
|---|
| 2482 | /* use lhs size, in order to avoid hassles
|
|---|
| 2483 | * with the structure `.' operator
|
|---|
| 2484 | */
|
|---|
| 2485 |
|
|---|
| 2486 | /* note: p->left not a field... */
|
|---|
| 2487 | printf(CONFMT, (CONSZ)tsize(STRTY, p->n_left->n_df,
|
|---|
| 2488 | p->n_left->n_ap));
|
|---|
| 2489 | printf("\t%d\t\n", talign(STRTY, p->n_left->n_ap));
|
|---|
| 2490 | break;
|
|---|
| 2491 |
|
|---|
| 2492 | case XARG:
|
|---|
| 2493 | case XASM:
|
|---|
| 2494 | break;
|
|---|
| 2495 |
|
|---|
| 2496 | default:
|
|---|
| 2497 | printf( "\n" );
|
|---|
| 2498 | }
|
|---|
| 2499 |
|
|---|
| 2500 | if (ty != LTYPE)
|
|---|
| 2501 | p2tree(p->n_left);
|
|---|
| 2502 | if (ty == BITYPE)
|
|---|
| 2503 | p2tree(p->n_right);
|
|---|
| 2504 | }
|
|---|
| 2505 | #else
|
|---|
| 2506 | static char *
|
|---|
| 2507 | sptostr(struct symtab *sp)
|
|---|
| 2508 | {
|
|---|
| 2509 | char *cp = inlalloc(32);
|
|---|
| 2510 | int n = sp->soffset;
|
|---|
| 2511 | if (n < 0)
|
|---|
| 2512 | n = -n;
|
|---|
| 2513 | snprintf(cp, 32, LABFMT, n);
|
|---|
| 2514 | return cp;
|
|---|
| 2515 | }
|
|---|
| 2516 |
|
|---|
| 2517 | void
|
|---|
| 2518 | p2tree(NODE *p)
|
|---|
| 2519 | {
|
|---|
| 2520 | struct symtab *q;
|
|---|
| 2521 | int ty;
|
|---|
| 2522 |
|
|---|
| 2523 | myp2tree(p); /* local action can be taken here */
|
|---|
| 2524 |
|
|---|
| 2525 | /* Fix left imaginary types */
|
|---|
| 2526 | if (ISITY(BTYPE(p->n_type)))
|
|---|
| 2527 | MODTYPE(p->n_type, p->n_type - (FIMAG-FLOAT));
|
|---|
| 2528 |
|
|---|
| 2529 | ty = coptype(p->n_op);
|
|---|
| 2530 |
|
|---|
| 2531 | switch( p->n_op ){
|
|---|
| 2532 |
|
|---|
| 2533 | case NAME:
|
|---|
| 2534 | case ICON:
|
|---|
| 2535 | if ((q = p->n_sp) != NULL) {
|
|---|
| 2536 | if ((q->sclass == STATIC && q->slevel > 0)
|
|---|
| 2537 | #ifdef GCC_COMPAT
|
|---|
| 2538 | || q->sflags == SLBLNAME
|
|---|
| 2539 | #endif
|
|---|
| 2540 | ) {
|
|---|
| 2541 | p->n_name = sptostr(q);
|
|---|
| 2542 | } else {
|
|---|
| 2543 | if ((p->n_name = q->soname) == NULL)
|
|---|
| 2544 | p->n_name = addname(exname(q->sname));
|
|---|
| 2545 | }
|
|---|
| 2546 | } else
|
|---|
| 2547 | p->n_name = "";
|
|---|
| 2548 | break;
|
|---|
| 2549 |
|
|---|
| 2550 | case STASG:
|
|---|
| 2551 | /* STASG used for stack array init */
|
|---|
| 2552 | if (ISARY(p->n_type)) {
|
|---|
| 2553 | int size1 = (int)tsize(p->n_type, p->n_left->n_df,
|
|---|
| 2554 | p->n_left->n_ap)/SZCHAR;
|
|---|
| 2555 | p->n_stsize = (int)tsize(p->n_type, p->n_right->n_df,
|
|---|
| 2556 | p->n_right->n_ap)/SZCHAR;
|
|---|
| 2557 | if (size1 < p->n_stsize)
|
|---|
| 2558 | p->n_stsize = size1;
|
|---|
| 2559 | p->n_stalign = talign(p->n_type,
|
|---|
| 2560 | p->n_left->n_ap)/SZCHAR;
|
|---|
| 2561 | break;
|
|---|
| 2562 | }
|
|---|
| 2563 | /* FALLTHROUGH */
|
|---|
| 2564 | case STARG:
|
|---|
| 2565 | case STCALL:
|
|---|
| 2566 | case USTCALL:
|
|---|
| 2567 | /* set up size parameters */
|
|---|
| 2568 | p->n_stsize = (int)((tsize(STRTY, p->n_left->n_df,
|
|---|
| 2569 | p->n_left->n_ap)+SZCHAR-1)/SZCHAR);
|
|---|
| 2570 | p->n_stalign = talign(STRTY,p->n_left->n_ap)/SZCHAR;
|
|---|
| 2571 | if (p->n_stalign == 0)
|
|---|
| 2572 | p->n_stalign = 1; /* At least char for packed structs */
|
|---|
| 2573 | break;
|
|---|
| 2574 |
|
|---|
| 2575 | case XARG:
|
|---|
| 2576 | case XASM:
|
|---|
| 2577 | break;
|
|---|
| 2578 |
|
|---|
| 2579 | default:
|
|---|
| 2580 | p->n_name = "";
|
|---|
| 2581 | }
|
|---|
| 2582 |
|
|---|
| 2583 | if( ty != LTYPE ) p2tree( p->n_left );
|
|---|
| 2584 | if( ty == BITYPE ) p2tree( p->n_right );
|
|---|
| 2585 | }
|
|---|
| 2586 |
|
|---|
| 2587 | #endif
|
|---|
| 2588 |
|
|---|
| 2589 | /*
|
|---|
| 2590 | * Change void data types into char.
|
|---|
| 2591 | */
|
|---|
| 2592 | static void
|
|---|
| 2593 | delvoid(NODE *p, void *arg)
|
|---|
| 2594 | {
|
|---|
| 2595 | /* Convert "PTR undef" (void *) to "PTR uchar" */
|
|---|
| 2596 | if (BTYPE(p->n_type) == VOID)
|
|---|
| 2597 | p->n_type = (p->n_type & ~BTMASK) | UCHAR;
|
|---|
| 2598 | if (BTYPE(p->n_type) == BOOL) {
|
|---|
| 2599 | if (p->n_op == SCONV && p->n_type == BOOL) {
|
|---|
| 2600 | /* create a jump and a set */
|
|---|
| 2601 | NODE *r;
|
|---|
| 2602 | int l, l2;
|
|---|
| 2603 |
|
|---|
| 2604 | r = tempnode(0, BOOL_TYPE, NULL, MKAP(BOOL_TYPE));
|
|---|
| 2605 | cbranch(buildtree(EQ, p->n_left, bcon(0)),
|
|---|
| 2606 | bcon(l = getlab()));
|
|---|
| 2607 | *p = *r;
|
|---|
| 2608 | ecode(buildtree(ASSIGN, tcopy(r), bcon(1)));
|
|---|
| 2609 | branch(l2 = getlab());
|
|---|
| 2610 | plabel(l);
|
|---|
| 2611 | ecode(buildtree(ASSIGN, r, bcon(0)));
|
|---|
| 2612 | plabel(l2);
|
|---|
| 2613 | } else
|
|---|
| 2614 | p->n_type = (p->n_type & ~BTMASK) | BOOL_TYPE;
|
|---|
| 2615 | }
|
|---|
| 2616 |
|
|---|
| 2617 | }
|
|---|
| 2618 |
|
|---|
| 2619 | void
|
|---|
| 2620 | ecode(NODE *p)
|
|---|
| 2621 | {
|
|---|
| 2622 | /* walk the tree and write out the nodes.. */
|
|---|
| 2623 |
|
|---|
| 2624 | if (nerrors)
|
|---|
| 2625 | return;
|
|---|
| 2626 |
|
|---|
| 2627 | #ifdef GCC_COMPAT
|
|---|
| 2628 | {
|
|---|
| 2629 | NODE *q = p;
|
|---|
| 2630 |
|
|---|
| 2631 | if (q->n_op == UMUL)
|
|---|
| 2632 | q = p->n_left;
|
|---|
| 2633 | if (cdope(q->n_op)&CALLFLG &&
|
|---|
| 2634 | attr_find(q->n_ap, GCC_ATYP_WARN_UNUSED_RESULT))
|
|---|
| 2635 | werror("return value ignored");
|
|---|
| 2636 | }
|
|---|
| 2637 | #endif
|
|---|
| 2638 | p = optim(p);
|
|---|
| 2639 | p = delasgop(p);
|
|---|
| 2640 | walkf(p, delvoid, 0);
|
|---|
| 2641 | #ifdef PCC_DEBUG
|
|---|
| 2642 | if (xdebug) {
|
|---|
| 2643 | printf("Fulltree:\n");
|
|---|
| 2644 | fwalk(p, eprint, 0);
|
|---|
| 2645 | }
|
|---|
| 2646 | #endif
|
|---|
| 2647 | p2tree(p);
|
|---|
| 2648 | #if !defined(MULTIPASS)
|
|---|
| 2649 | send_passt(IP_NODE, p);
|
|---|
| 2650 | #endif
|
|---|
| 2651 | }
|
|---|
| 2652 |
|
|---|
| 2653 | /*
|
|---|
| 2654 | * Send something further on to the next pass.
|
|---|
| 2655 | */
|
|---|
| 2656 | void
|
|---|
| 2657 | send_passt(int type, ...)
|
|---|
| 2658 | {
|
|---|
| 2659 | struct interpass *ip;
|
|---|
| 2660 | struct interpass_prolog *ipp;
|
|---|
| 2661 | extern int crslab;
|
|---|
| 2662 | va_list ap;
|
|---|
| 2663 | int sz;
|
|---|
| 2664 |
|
|---|
| 2665 | va_start(ap, type);
|
|---|
| 2666 | if (cftnsp == NULL && type != IP_ASM) {
|
|---|
| 2667 | #ifdef notyet
|
|---|
| 2668 | cerror("no function");
|
|---|
| 2669 | #endif
|
|---|
| 2670 | if (type == IP_NODE)
|
|---|
| 2671 | tfree(va_arg(ap, NODE *));
|
|---|
| 2672 | return;
|
|---|
| 2673 | }
|
|---|
| 2674 | if (type == IP_PROLOG || type == IP_EPILOG)
|
|---|
| 2675 | sz = sizeof(struct interpass_prolog);
|
|---|
| 2676 | else
|
|---|
| 2677 | sz = sizeof(struct interpass);
|
|---|
| 2678 |
|
|---|
| 2679 | ip = inlalloc(sz);
|
|---|
| 2680 | ip->type = type;
|
|---|
| 2681 | ip->lineno = lineno;
|
|---|
| 2682 | switch (type) {
|
|---|
| 2683 | case IP_NODE:
|
|---|
| 2684 | ip->ip_node = va_arg(ap, NODE *);
|
|---|
| 2685 | break;
|
|---|
| 2686 | case IP_EPILOG:
|
|---|
| 2687 | if (!isinlining)
|
|---|
| 2688 | defloc(cftnsp);
|
|---|
| 2689 | /* FALLTHROUGH */
|
|---|
| 2690 | case IP_PROLOG:
|
|---|
| 2691 | inftn = type == IP_PROLOG ? 1 : 0;
|
|---|
| 2692 | ipp = (struct interpass_prolog *)ip;
|
|---|
| 2693 | memset(ipp->ipp_regs, (type == IP_PROLOG)? -1 : 0,
|
|---|
| 2694 | sizeof(ipp->ipp_regs));
|
|---|
| 2695 | ipp->ipp_autos = va_arg(ap, int);
|
|---|
| 2696 | ipp->ipp_name = va_arg(ap, char *);
|
|---|
| 2697 | ipp->ipp_type = va_arg(ap, TWORD);
|
|---|
| 2698 | ipp->ipp_vis = va_arg(ap, int);
|
|---|
| 2699 | ip->ip_lbl = va_arg(ap, int);
|
|---|
| 2700 | ipp->ip_tmpnum = va_arg(ap, int);
|
|---|
| 2701 | ipp->ip_lblnum = crslab;
|
|---|
| 2702 | if (type == IP_PROLOG)
|
|---|
| 2703 | ipp->ip_lblnum--;
|
|---|
| 2704 | break;
|
|---|
| 2705 | case IP_DEFLAB:
|
|---|
| 2706 | ip->ip_lbl = va_arg(ap, int);
|
|---|
| 2707 | break;
|
|---|
| 2708 | case IP_ASM:
|
|---|
| 2709 | if (blevel == 0) { /* outside function */
|
|---|
| 2710 | printf("\t");
|
|---|
| 2711 | printf("%s", va_arg(ap, char *));
|
|---|
| 2712 | printf("\n");
|
|---|
| 2713 | va_end(ap);
|
|---|
| 2714 | defloc(NULL);
|
|---|
| 2715 | return;
|
|---|
| 2716 | }
|
|---|
| 2717 | ip->ip_asm = va_arg(ap, char *);
|
|---|
| 2718 | break;
|
|---|
| 2719 | default:
|
|---|
| 2720 | cerror("bad send_passt type %d", type);
|
|---|
| 2721 | }
|
|---|
| 2722 | va_end(ap);
|
|---|
| 2723 | pass1_lastchance(ip); /* target-specific info */
|
|---|
| 2724 | if (isinlining)
|
|---|
| 2725 | inline_addarg(ip);
|
|---|
| 2726 | else
|
|---|
| 2727 | pass2_compile(ip);
|
|---|
| 2728 | }
|
|---|
| 2729 |
|
|---|
| 2730 | char *
|
|---|
| 2731 | copst(int op)
|
|---|
| 2732 | {
|
|---|
| 2733 | if (op <= MAXOP)
|
|---|
| 2734 | return opst[op];
|
|---|
| 2735 | #define SNAM(x,y) case x: return #y;
|
|---|
| 2736 | switch (op) {
|
|---|
| 2737 | SNAM(QUALIFIER,QUALIFIER)
|
|---|
| 2738 | SNAM(CLASS,CLASS)
|
|---|
| 2739 | SNAM(RB,])
|
|---|
| 2740 | SNAM(DOT,.)
|
|---|
| 2741 | SNAM(ELLIPSIS,...)
|
|---|
| 2742 | SNAM(LB,[)
|
|---|
| 2743 | SNAM(TYPE,TYPE)
|
|---|
| 2744 | SNAM(COMOP,COMOP)
|
|---|
| 2745 | SNAM(QUEST,?)
|
|---|
| 2746 | SNAM(COLON,:)
|
|---|
| 2747 | SNAM(ANDAND,&&)
|
|---|
| 2748 | SNAM(OROR,||)
|
|---|
| 2749 | SNAM(NOT,!)
|
|---|
| 2750 | SNAM(CAST,CAST)
|
|---|
| 2751 | SNAM(PLUSEQ,+=)
|
|---|
| 2752 | SNAM(MINUSEQ,-=)
|
|---|
| 2753 | SNAM(MULEQ,*=)
|
|---|
| 2754 | SNAM(DIVEQ,/=)
|
|---|
| 2755 | SNAM(MODEQ,%=)
|
|---|
| 2756 | SNAM(ANDEQ,&=)
|
|---|
| 2757 | SNAM(OREQ,|=)
|
|---|
| 2758 | SNAM(EREQ,^=)
|
|---|
| 2759 | SNAM(LSEQ,<<=)
|
|---|
| 2760 | SNAM(RSEQ,>>=)
|
|---|
| 2761 | SNAM(INCR,++)
|
|---|
| 2762 | SNAM(DECR,--)
|
|---|
| 2763 | SNAM(STRING,STRING)
|
|---|
| 2764 | SNAM(SZOF,SIZEOF)
|
|---|
| 2765 | SNAM(ATTRIB,ATTRIBUTE)
|
|---|
| 2766 | SNAM(TYMERGE,TYMERGE)
|
|---|
| 2767 | #ifdef GCC_COMPAT
|
|---|
| 2768 | SNAM(XREAL,__real__)
|
|---|
| 2769 | SNAM(XIMAG,__imag__)
|
|---|
| 2770 | #endif
|
|---|
| 2771 | default:
|
|---|
| 2772 | cerror("bad copst %d", op);
|
|---|
| 2773 | }
|
|---|
| 2774 | return 0; /* XXX gcc */
|
|---|
| 2775 | }
|
|---|
| 2776 |
|
|---|
| 2777 | int
|
|---|
| 2778 | cdope(int op)
|
|---|
| 2779 | {
|
|---|
| 2780 | if (op <= MAXOP)
|
|---|
| 2781 | return dope[op];
|
|---|
| 2782 | switch (op) {
|
|---|
| 2783 | case CLOP:
|
|---|
| 2784 | case STRING:
|
|---|
| 2785 | case QUALIFIER:
|
|---|
| 2786 | case CLASS:
|
|---|
| 2787 | case RB:
|
|---|
| 2788 | case ELLIPSIS:
|
|---|
| 2789 | case TYPE:
|
|---|
| 2790 | return LTYPE;
|
|---|
| 2791 | case DOT:
|
|---|
| 2792 | case SZOF:
|
|---|
| 2793 | case COMOP:
|
|---|
| 2794 | case QUEST:
|
|---|
| 2795 | case COLON:
|
|---|
| 2796 | case LB:
|
|---|
| 2797 | case TYMERGE:
|
|---|
| 2798 | return BITYPE;
|
|---|
| 2799 | case XIMAG:
|
|---|
| 2800 | case XREAL:
|
|---|
| 2801 | case ATTRIB:
|
|---|
| 2802 | return UTYPE;
|
|---|
| 2803 | case ANDAND:
|
|---|
| 2804 | case OROR:
|
|---|
| 2805 | return BITYPE|LOGFLG;
|
|---|
| 2806 | case NOT:
|
|---|
| 2807 | return UTYPE|LOGFLG;
|
|---|
| 2808 | case CAST:
|
|---|
| 2809 | return BITYPE|ASGFLG|ASGOPFLG;
|
|---|
| 2810 | case PLUSEQ:
|
|---|
| 2811 | return BITYPE|ASGFLG|ASGOPFLG|FLOFLG|SIMPFLG|COMMFLG;
|
|---|
| 2812 | case MINUSEQ:
|
|---|
| 2813 | return BITYPE|FLOFLG|SIMPFLG|ASGFLG|ASGOPFLG;
|
|---|
| 2814 | case MULEQ:
|
|---|
| 2815 | return BITYPE|FLOFLG|MULFLG|ASGFLG|ASGOPFLG;
|
|---|
| 2816 | case OREQ:
|
|---|
| 2817 | case EREQ:
|
|---|
| 2818 | case ANDEQ:
|
|---|
| 2819 | return BITYPE|SIMPFLG|COMMFLG|ASGFLG|ASGOPFLG;
|
|---|
| 2820 | case DIVEQ:
|
|---|
| 2821 | return BITYPE|FLOFLG|MULFLG|DIVFLG|ASGFLG|ASGOPFLG;
|
|---|
| 2822 | case MODEQ:
|
|---|
| 2823 | return BITYPE|DIVFLG|ASGFLG|ASGOPFLG;
|
|---|
| 2824 | case LSEQ:
|
|---|
| 2825 | case RSEQ:
|
|---|
| 2826 | return BITYPE|SHFFLG|ASGFLG|ASGOPFLG;
|
|---|
| 2827 | case INCR:
|
|---|
| 2828 | case DECR:
|
|---|
| 2829 | return BITYPE|ASGFLG;
|
|---|
| 2830 | }
|
|---|
| 2831 | cerror("cdope missing op %d", op);
|
|---|
| 2832 | return 0; /* XXX gcc */
|
|---|
| 2833 | }
|
|---|
| 2834 |
|
|---|
| 2835 | /*
|
|---|
| 2836 | * make a fresh copy of p
|
|---|
| 2837 | */
|
|---|
| 2838 | NODE *
|
|---|
| 2839 | ccopy(NODE *p)
|
|---|
| 2840 | {
|
|---|
| 2841 | NODE *q;
|
|---|
| 2842 |
|
|---|
| 2843 | q = talloc();
|
|---|
| 2844 | *q = *p;
|
|---|
| 2845 |
|
|---|
| 2846 | switch (coptype(q->n_op)) {
|
|---|
| 2847 | case BITYPE:
|
|---|
| 2848 | q->n_right = ccopy(p->n_right);
|
|---|
| 2849 | case UTYPE:
|
|---|
| 2850 | q->n_left = ccopy(p->n_left);
|
|---|
| 2851 | }
|
|---|
| 2852 |
|
|---|
| 2853 | return(q);
|
|---|
| 2854 | }
|
|---|
| 2855 |
|
|---|
| 2856 | /*
|
|---|
| 2857 | * set PROG-seg label.
|
|---|
| 2858 | */
|
|---|
| 2859 | void
|
|---|
| 2860 | plabel(int label)
|
|---|
| 2861 | {
|
|---|
| 2862 | reached = 1; /* Will this always be correct? */
|
|---|
| 2863 | send_passt(IP_DEFLAB, label);
|
|---|
| 2864 | }
|
|---|
| 2865 |
|
|---|
| 2866 | /*
|
|---|
| 2867 | * Perform integer promotion on node n.
|
|---|
| 2868 | */
|
|---|
| 2869 | NODE *
|
|---|
| 2870 | intprom(NODE *n)
|
|---|
| 2871 | {
|
|---|
| 2872 | if ((n->n_type >= CHAR && n->n_type < INT) || n->n_type == BOOL) {
|
|---|
| 2873 | if ((n->n_type == UCHAR && MAX_UCHAR > MAX_INT) ||
|
|---|
| 2874 | (n->n_type == USHORT && MAX_USHORT > MAX_INT))
|
|---|
| 2875 | return makety(n, UNSIGNED, 0, 0, MKAP(UNSIGNED));
|
|---|
| 2876 | return makety(n, INT, 0, 0, MKAP(INT));
|
|---|
| 2877 | }
|
|---|
| 2878 | return n;
|
|---|
| 2879 | }
|
|---|
| 2880 |
|
|---|
| 2881 | /*
|
|---|
| 2882 | * Return CON/VOL/0, whichever are active for the current type.
|
|---|
| 2883 | */
|
|---|
| 2884 | int
|
|---|
| 2885 | cqual(TWORD t, TWORD q)
|
|---|
| 2886 | {
|
|---|
| 2887 | while (ISARY(t))
|
|---|
| 2888 | t = DECREF(t), q = DECQAL(q);
|
|---|
| 2889 | if (t <= BTMASK)
|
|---|
| 2890 | q <<= TSHIFT;
|
|---|
| 2891 | return q & (CON|VOL);
|
|---|
| 2892 | }
|
|---|
| 2893 |
|
|---|
| 2894 | int crslab = 10;
|
|---|
| 2895 | /*
|
|---|
| 2896 | * Return a number for internal labels.
|
|---|
| 2897 | */
|
|---|
| 2898 | int
|
|---|
| 2899 | getlab(void)
|
|---|
| 2900 | {
|
|---|
| 2901 | return crslab++;
|
|---|
| 2902 | }
|
|---|