Fixed .funcptr property of delegates, no longer uses the infamous DMD rewrites to pointer arithmetic, instead a GEPExp has been introduced.

This commit is contained in:
Tomas Lindquist Olsen
2008-09-15 02:04:26 +02:00
parent 431bc19d2f
commit 4280a86bcf
8 changed files with 67 additions and 8 deletions

View File

@@ -9071,4 +9071,30 @@ void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
expToCBuffer(buf, hgs, e2, PREC_cond); 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

View File

@@ -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 /* Special values used by the interpreter
*/ */
#define EXP_CANT_INTERPRET ((Expression *)1) #define EXP_CANT_INTERPRET ((Expression *)1)

View File

@@ -160,6 +160,11 @@ enum TOK
TOKfile, TOKfile,
#endif #endif
// LLVMDC specific
#if IN_LLVM
TOKgep,
#endif
TOKMAX TOKMAX
}; };

View File

@@ -3174,17 +3174,14 @@ Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident)
#endif #endif
if (ident == Id::ptr) if (ident == Id::ptr)
{ {
e = new GEPExp(e->loc, e, ident, 0);
e->type = tvoidptr; e->type = tvoidptr;
return e; return e;
} }
else if (ident == Id::funcptr) else if (ident == Id::funcptr)
{ {
e = e->addressOf(sc); e = new GEPExp(e->loc, e, ident, 1);
e->type = tvoidptr; 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();
return e; return e;
} }
else else

View File

@@ -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; } #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
STUB(Expression); STUB(Expression);
STUB(DotTypeExp); STUB(DotTypeExp);

0
lib/.empty Normal file → Executable file
View File

View File

@@ -9,5 +9,5 @@ void main()
void foo(cfloat c) void foo(cfloat c)
{ {
assert(c.re > 2.9999 && c.re < 3.0001); 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);
} }

View File

@@ -5,5 +5,5 @@ void main()
auto dg = &foo; auto dg = &foo;
if(dg.funcptr is null) if(dg.funcptr is null)
{} { assert(0); }
} }