mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-05-14 05:51:29 +02:00
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:
@@ -9071,4 +9071,30 @@ void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
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
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
#define EXP_CANT_INTERPRET ((Expression *)1)
|
||||
|
||||
@@ -160,6 +160,11 @@ enum TOK
|
||||
TOKfile,
|
||||
#endif
|
||||
|
||||
// LLVMDC specific
|
||||
#if IN_LLVM
|
||||
TOKgep,
|
||||
#endif
|
||||
|
||||
TOKMAX
|
||||
};
|
||||
|
||||
|
||||
@@ -3174,17 +3174,14 @@ Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
#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
|
||||
|
||||
11
gen/toir.cpp
11
gen/toir.cpp
@@ -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; }
|
||||
STUB(Expression);
|
||||
STUB(DotTypeExp);
|
||||
|
||||
0
lib/.empty
Normal file → Executable file
0
lib/.empty
Normal file → Executable file
@@ -9,5 +9,5 @@ void main()
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ void main()
|
||||
auto dg = &foo;
|
||||
|
||||
if(dg.funcptr is null)
|
||||
{}
|
||||
{ assert(0); }
|
||||
}
|
||||
Reference in New Issue
Block a user