changeset 599:4435f57956e7

Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Mon, 15 Sep 2008 02:04:26 +0200
parents 13ff06605226
children 311f16f26297
files dmd/expression.c dmd/expression.h dmd/lexer.h dmd/mtype.c gen/toir.cpp lib/.empty tests/mini/compile_dgfuncptr.d tests/mini/complex5.d tests/mini/dgfuncptr.d
diffstat 8 files changed, 76 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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)
--- 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
 };
 
--- 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
--- 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);
--- 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)
-  {}
-}
--- 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);
 }
--- /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); }
+}