Remove LDC-specific .classinfo AST rewrite.

Apart from reducing the diff to upstream DMD, this also fixes a
"cannot interpret" CTFE issue.
This commit is contained in:
David Nadlinger
2013-06-14 21:49:44 +02:00
parent 3035735bc9
commit 041e8e8b54
2 changed files with 25 additions and 42 deletions

View File

@@ -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;
}

View File

@@ -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<TypeClass*>(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);
}