mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01: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);
|
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
|
/* Special values used by the interpreter
|
||||||
*/
|
*/
|
||||||
#define EXP_CANT_INTERPRET ((Expression *)1)
|
#define EXP_CANT_INTERPRET ((Expression *)1)
|
||||||
|
|||||||
@@ -160,6 +160,11 @@ enum TOK
|
|||||||
TOKfile,
|
TOKfile,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// LLVMDC specific
|
||||||
|
#if IN_LLVM
|
||||||
|
TOKgep,
|
||||||
|
#endif
|
||||||
|
|
||||||
TOKMAX
|
TOKMAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
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; }
|
#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
0
lib/.empty
Normal file → Executable 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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,5 +5,5 @@ void main()
|
|||||||
auto dg = &foo;
|
auto dg = &foo;
|
||||||
|
|
||||||
if(dg.funcptr is null)
|
if(dg.funcptr is null)
|
||||||
{}
|
{ assert(0); }
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user