From 4280a86bcfffdd676963e637fc7f3c3e5018156b Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Mon, 15 Sep 2008 02:04:26 +0200 Subject: [PATCH] Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced. --- dmd/expression.c | 26 +++++++++++++++++++ dmd/expression.h | 20 ++++++++++++++ dmd/lexer.h | 5 ++++ dmd/mtype.c | 9 +++---- gen/toir.cpp | 11 ++++++++ lib/.empty | 0 tests/mini/complex5.d | 2 +- .../mini/{compile_dgfuncptr.d => dgfuncptr.d} | 2 +- 8 files changed, 67 insertions(+), 8 deletions(-) mode change 100644 => 100755 lib/.empty rename tests/mini/{compile_dgfuncptr.d => dgfuncptr.d} (81%) diff --git a/dmd/expression.c b/dmd/expression.c index 84b0fc28..da6a0af0 100644 --- a/dmd/expression.c +++ b/dmd/expression.c @@ -9071,4 +9071,30 @@ void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) expToCBuffer(buf, hgs, e2, PREC_cond); } +/************************************************************/ +#if IN_LLVM + +// Strictly LLVMDC specific stuff + +GEPExp::GEPExp(Loc loc, Expression* e, Identifier* id, unsigned idx) + : UnaExp(loc, TOKgep, sizeof(GEPExp), e) +{ + index = idx; + ident = id; +} + +void GEPExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs) +{ + expToCBuffer(buf, hgs, e1, PREC_primary); + buf->writeByte('.'); + buf->writestring(ident->toChars()); +} + +Expression* GEPExp::toLvalue(Scope* sc, Expression* e) +{ + // GEP's are always lvalues, at least in the "LLVM sense" ... + return this; +} + +#endif diff --git a/dmd/expression.h b/dmd/expression.h index 8c1e8077..a7d74b3e 100644 --- a/dmd/expression.h +++ b/dmd/expression.h @@ -1496,6 +1496,26 @@ struct LineInitExp : DefaultInitExp /****************************************************************/ +#if IN_LLVM + +// this stuff is strictly LLVMDC + +struct GEPExp : UnaExp +{ + unsigned index; + Identifier* ident; + + GEPExp(Loc loc, Expression* e, Identifier* id, unsigned idx); + void toCBuffer(OutBuffer *buf, HdrGenState *hgs); + Expression *toLvalue(Scope *sc, Expression *e); + + elem *toElem(IRState *irs); +}; + +#endif + +/****************************************************************/ + /* Special values used by the interpreter */ #define EXP_CANT_INTERPRET ((Expression *)1) diff --git a/dmd/lexer.h b/dmd/lexer.h index d4ec7e55..9bb27b87 100644 --- a/dmd/lexer.h +++ b/dmd/lexer.h @@ -160,6 +160,11 @@ enum TOK TOKfile, #endif +// LLVMDC specific +#if IN_LLVM + TOKgep, +#endif + TOKMAX }; diff --git a/dmd/mtype.c b/dmd/mtype.c index c2554ff0..b0fa52b4 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -3174,17 +3174,14 @@ Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident) #endif if (ident == Id::ptr) { + e = new GEPExp(e->loc, e, ident, 0); e->type = tvoidptr; return e; } else if (ident == Id::funcptr) { - e = e->addressOf(sc); - e->type = tvoidptr; - e = new AddExp(e->loc, e, new IntegerExp(PTRSIZE)); - e->type = tvoidptr; - e = new PtrExp(e->loc, e); - e->type = next->pointerTo(); + e = new GEPExp(e->loc, e, ident, 1); + e->type = tvoidptr; return e; } else diff --git a/gen/toir.cpp b/gen/toir.cpp index aaa1ad62..8081c2af 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2380,6 +2380,17 @@ DValue* AssocArrayLiteralExp::toElem(IRState* p) ////////////////////////////////////////////////////////////////////////////////////////// +DValue* GEPExp::toElem(IRState* p) +{ + // this should be good enough for now! + DValue* val = e1->toElem(p); + assert(val->isLVal()); + LLValue* v = DtoGEPi(val->getLVal(), 0, index); + return new DVarValue(type, DtoBitCast(v, getPtrToType(DtoType(type)))); +} + +////////////////////////////////////////////////////////////////////////////////////////// + #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } STUB(Expression); STUB(DotTypeExp); diff --git a/lib/.empty b/lib/.empty old mode 100644 new mode 100755 diff --git a/tests/mini/complex5.d b/tests/mini/complex5.d index f5e4de40..996b4bec 100644 --- a/tests/mini/complex5.d +++ b/tests/mini/complex5.d @@ -9,5 +9,5 @@ void main() void foo(cfloat c) { assert(c.re > 2.9999 && c.re < 3.0001); - assert(c.im > 1.9999i && c.im < 2.0001); + assert(c.im > 1.9999i && c.im < 2.0001i); } diff --git a/tests/mini/compile_dgfuncptr.d b/tests/mini/dgfuncptr.d similarity index 81% rename from tests/mini/compile_dgfuncptr.d rename to tests/mini/dgfuncptr.d index 3a909577..7132c5d3 100644 --- a/tests/mini/compile_dgfuncptr.d +++ b/tests/mini/dgfuncptr.d @@ -5,5 +5,5 @@ void main() auto dg = &foo; if(dg.funcptr is null) - {} + { assert(0); } }