# HG changeset patch # User Tomas Lindquist Olsen # Date 1221437066 -7200 # Node ID 4435f57956e7b58eadc97fdcfe958fb175a0f1ab # Parent 13ff066052269964539a50d3ce7882b070227714 Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced. diff -r 13ff06605226 -r 4435f57956e7 dmd/expression.c --- a/dmd/expression.c Sun Sep 14 22:49:19 2008 +0200 +++ b/dmd/expression.c Mon Sep 15 02:04:26 2008 +0200 @@ -9071,4 +9071,30 @@ 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 -r 13ff06605226 -r 4435f57956e7 dmd/expression.h --- a/dmd/expression.h Sun Sep 14 22:49:19 2008 +0200 +++ b/dmd/expression.h Mon Sep 15 02:04:26 2008 +0200 @@ -1496,6 +1496,26 @@ /****************************************************************/ +#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 -r 13ff06605226 -r 4435f57956e7 dmd/lexer.h --- a/dmd/lexer.h Sun Sep 14 22:49:19 2008 +0200 +++ b/dmd/lexer.h Mon Sep 15 02:04:26 2008 +0200 @@ -160,6 +160,11 @@ TOKfile, #endif +// LLVMDC specific +#if IN_LLVM + TOKgep, +#endif + TOKMAX }; diff -r 13ff06605226 -r 4435f57956e7 dmd/mtype.c --- a/dmd/mtype.c Sun Sep 14 22:49:19 2008 +0200 +++ b/dmd/mtype.c Mon Sep 15 02:04:26 2008 +0200 @@ -3174,17 +3174,14 @@ #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 -r 13ff06605226 -r 4435f57956e7 gen/toir.cpp --- a/gen/toir.cpp Sun Sep 14 22:49:19 2008 +0200 +++ b/gen/toir.cpp Mon Sep 15 02:04:26 2008 +0200 @@ -2380,6 +2380,17 @@ ////////////////////////////////////////////////////////////////////////////////////////// +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 -r 13ff06605226 -r 4435f57956e7 lib/.empty diff -r 13ff06605226 -r 4435f57956e7 tests/mini/compile_dgfuncptr.d --- a/tests/mini/compile_dgfuncptr.d Sun Sep 14 22:49:19 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,9 +0,0 @@ -void main() -{ - void foo() {} - - auto dg = &foo; - - if(dg.funcptr is null) - {} -} diff -r 13ff06605226 -r 4435f57956e7 tests/mini/complex5.d --- a/tests/mini/complex5.d Sun Sep 14 22:49:19 2008 +0200 +++ b/tests/mini/complex5.d Mon Sep 15 02:04:26 2008 +0200 @@ -9,5 +9,5 @@ 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 -r 13ff06605226 -r 4435f57956e7 tests/mini/dgfuncptr.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/mini/dgfuncptr.d Mon Sep 15 02:04:26 2008 +0200 @@ -0,0 +1,9 @@ +void main() +{ + void foo() {} + + auto dg = &foo; + + if(dg.funcptr is null) + { assert(0); } +}