From 041e8e8b54ef5fa7e5b7f287fcd292e8c6d3935a Mon Sep 17 00:00:00 2001 From: David Nadlinger Date: Fri, 14 Jun 2013 21:49:44 +0200 Subject: [PATCH] Remove LDC-specific .classinfo AST rewrite. Apart from reducing the diff to upstream DMD, this also fixes a "cannot interpret" CTFE issue. --- dmd2/mtype.c | 43 +------------------------------------------ gen/toir.cpp | 24 ++++++++++++++++++++++++ 2 files changed, 25 insertions(+), 42 deletions(-) diff --git a/dmd2/mtype.c b/dmd2/mtype.c index fdfebafd..eefbaa30 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -8703,47 +8703,9 @@ L1: e->type = t; // do this so we don't get redundant dereference } else - { - /* For class objects, the classinfo reference is the first + { /* For class objects, the classinfo reference is the first * entry in the vtbl[] */ -#if IN_LLVM - - Type* ct; - if (sym->isInterfaceDeclaration()) { - ct = t->pointerTo()->pointerTo()->pointerTo(); - } - else { - ct = t->pointerTo()->pointerTo(); - } - - e = e->castTo(sc, ct); - e = new PtrExp(e->loc, e); - e->type = ct->nextOf(); - e = new PtrExp(e->loc, e); - e->type = ct->nextOf()->nextOf(); - - if (sym->isInterfaceDeclaration()) - { - if (sym->isCOMinterface()) - { /* COM interface vtbl[]s are different in that the - * first entry is always pointer to QueryInterface(). - * We can't get a .classinfo for it. - */ - error(e->loc, "no .classinfo for COM interface objects"); - } - /* For an interface, the first entry in the vtbl[] - * is actually a pointer to an instance of struct Interface. - * The first member of Interface is the .classinfo, - * so add an extra pointer indirection. - */ - e = new PtrExp(e->loc, e); - e->type = ct->nextOf()->nextOf()->nextOf(); - } - } - -#else - e = new PtrExp(e->loc, e); e->type = t->pointerTo(); if (sym->isInterfaceDeclaration()) @@ -8767,9 +8729,6 @@ L1: } e = new PtrExp(e->loc, e, t); } - -#endif // !LDC - return e; } diff --git a/gen/toir.cpp b/gen/toir.cpp index 2ac4cbff..57e3615e 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -1333,6 +1333,30 @@ DValue* PtrExp::toElem(IRState* p) { V = e1->toElem(p)->getRVal(); } + + // The frontend emits dereferences of class/interfaces types to access the + // first member, which is the .classinfo property. + Type* origType = e1->type->toBasetype(); + if (origType->ty == Tclass) + { + TypeClass* ct = static_cast(origType); + + Type* resultType; + if (ct->sym->isInterfaceDeclaration()) + { + // For interfaces, the first entry in the vtbl is actually a pointer + // to an Interface instance, which has the type info as its first + // member, so we have to add an extra layer of indirection. + resultType = Type::typeinfointerface->type->pointerTo(); + } + else + { + resultType = Type::typeinfointerface->type; + } + + V = DtoBitCast(V, DtoType(resultType->pointerTo()->pointerTo())); + } + return new DVarValue(type, V); }