int expr_is_addressable(expr *e) { if(type_is(e->tree_type, type_func)) return 1; return expr_is_lval(e) == LVALUE_USER_ASSIGNABLE; }
int expr_must_lvalue(expr *e, const char *desc) { int lval = (expr_is_lval(e) == LVALUE_USER_ASSIGNABLE); if(!lval || type_is_array(e->tree_type)){ fold_had_error = 1; warn_at_print_error(&e->where, "%s to %s - %s", desc, type_to_str(e->tree_type), lval ? "arrays not assignable" : "not an lvalue"); return 0; } return 1; }
void fold_expr_stmt(expr *e, symtable *stab) { stmt *last_stmt; int last; (void)stab; last = dynarray_count(e->code->bits.code.stmts); if(last){ last_stmt = e->code->bits.code.stmts[last - 1]; last_stmt->freestanding = 1; /* allow the final to be freestanding */ last_stmt->expr_no_pop = 1; } fold_stmt(e->code); /* symtab should've been set by parse */ if(last && stmt_kind(last_stmt, expr)){ expr *last_expr = last_stmt->expr; e->tree_type = last_expr->tree_type; if(fold_check_expr(e, FOLD_CHK_ALLOW_VOID, "({ ... }) statement")) { return; } switch(expr_is_lval(last_expr)){ case LVALUE_NO: break; case LVALUE_STRUCT: case LVALUE_USER_ASSIGNABLE: e->f_islval = expr_is_lval_struct; } }else{ e->tree_type = type_nav_btype(cc1_type_nav, type_void); } e->freestanding = 1; /* ({ ... }) on its own is freestanding */ }