diff options
author | Michael Forney <mforney@mforney.org> | 2019-04-03 12:36:14 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2019-04-03 21:56:48 -0700 |
commit | 5b8a2d225ca3777c7b49421182bb5c1faf99ae64 (patch) | |
tree | 979f3ff190c9eb01c0a16dbce1f52e807f6daf2a /expr.c | |
parent | b3865e402e426387d4cdccdcd249a02d5ba1bc05 (diff) |
Revert "Make member access its own expression type"
This reverts commit b3865e402e426387d4cdccdcd249a02d5ba1bc05.
This breaks member address expressions in static initializers. We can
support bit-fields by instead adding a "bit-field" expression that
affects loads and stores to the underlying object.
Diffstat (limited to 'expr.c')
-rw-r--r-- | expr.c | 24 |
1 files changed, 12 insertions, 12 deletions
@@ -483,7 +483,9 @@ postfixexpr(struct scope *s, struct expr *r) struct type *t; enum typequal tq; struct param *p; + uint64_t offset; enum tokenkind op; + bool lvalue; if (!r) r = primaryexpr(s); @@ -564,19 +566,17 @@ postfixexpr(struct scope *s, struct expr *r) next(); if (tok.kind != TIDENT) error(&tok.loc, "expected identifier after '->' operator"); - e = mkexpr(EXPRMEMBER, NULL, 0); - e->member.base = r; - e->member.offset = 0; - e->type = typemember(t, tok.lit, &e->member.offset); - if (!e->type) + lvalue = op == TARROW || r->unary.base->flags & EXPRFLAG_LVAL; + r = exprconvert(r, mkpointertype(&typechar)); + offset = 0; + t = typemember(t, tok.lit, &offset); + if (!t) error(&tok.loc, "struct/union has no member named '%s'", tok.lit); - if (op == TARROW || r->unary.base->flags & EXPRFLAG_LVAL) { - e->type = mkqualifiedtype(e->type, tq); - e->flags |= EXPRFLAG_LVAL; - } else { - e->type = typeunqual(e->type, NULL); - } - e = decay(e); + r = mkbinaryexpr(&tok.loc, TADD, r, mkconstexpr(&typeulong, offset)); + r = exprconvert(r, mkpointertype(mkqualifiedtype(t, tq))); + e = mkunaryexpr(TMUL, r); + if (!lvalue) + e->flags &= ~EXPRFLAG_LVAL; next(); break; case TINC: |