[svn r111] Fixed most problems with complex number support and added typeinfo for them.

Added typeinfo ti_C.
Did some changes to the way expressions that have both lvalue and rvalue LLVM values are handled.
This commit is contained in:
Tomas Lindquist Olsen
2007-11-20 00:02:35 +01:00
parent 2af443b045
commit adab52fad9
14 changed files with 442 additions and 127 deletions

View File

@@ -127,8 +127,7 @@ DValue* DtoComplex(Type* to, DValue* val)
TY ty = t->ty;
if (val->isComplex() || t->iscomplex()) {
assert(DtoDType(to) == t);
return val;
return DtoCastComplex(val, to);
}
const llvm::Type* base = DtoComplexBaseType(to);
@@ -166,6 +165,21 @@ void DtoComplexSet(llvm::Value* c, llvm::Value* re, llvm::Value* im)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoGetComplexParts(DValue* c, llvm::Value*& re, llvm::Value*& im)
{
// lhs values
if (DComplexValue* cx = c->isComplex()) {
re = cx->re;
im = cx->im;
}
else {
re = DtoLoad(DtoGEPi(c->getRVal(),0,0,"tmp"));
im = DtoLoad(DtoGEPi(c->getRVal(),0,1,"tmp"));
}
}
//////////////////////////////////////////////////////////////////////////////////////////
DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
{
lhs = DtoComplex(type, lhs);
@@ -174,24 +188,9 @@ DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs)
llvm::Value *a, *b, *c, *d, *re, *im;
// lhs values
if (DComplexValue* cx = lhs->isComplex()) {
a = cx->re;
b = cx->im;
}
else {
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(lhs, a, b);
// rhs values
if (DComplexValue* cx = rhs->isComplex()) {
c = cx->re;
d = cx->im;
}
else {
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(rhs, c, d);
// add up
re = gIR->ir->CreateAdd(a, c, "tmp");
@@ -210,24 +209,9 @@ DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs)
llvm::Value *a, *b, *c, *d, *re, *im;
// lhs values
if (DComplexValue* cx = lhs->isComplex()) {
a = cx->re;
b = cx->im;
}
else {
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(lhs, a, b);
// rhs values
if (DComplexValue* cx = rhs->isComplex()) {
c = cx->re;
d = cx->im;
}
else {
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(rhs, c, d);
// add up
re = gIR->ir->CreateSub(a, c, "tmp");
@@ -243,29 +227,14 @@ DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs)
lhs = DtoComplex(type, lhs);
rhs = DtoComplex(type, rhs);
llvm::Value *a, *b, *c, *d, *re, *im;
llvm::Value *a, *b, *c, *d;
// lhs values
if (DComplexValue* cx = lhs->isComplex()) {
a = cx->re;
b = cx->im;
}
else {
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(lhs, a, b);
// rhs values
if (DComplexValue* cx = rhs->isComplex()) {
c = cx->re;
d = cx->im;
}
else {
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(rhs, c, d);
llvm::Value *tmp1, *tmp2;
llvm::Value *tmp1, *tmp2, *re, *im;
tmp1 = gIR->ir->CreateMul(a, c, "tmp");
tmp2 = gIR->ir->CreateMul(b, d, "tmp");
@@ -285,29 +254,14 @@ DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
lhs = DtoComplex(type, lhs);
rhs = DtoComplex(type, rhs);
llvm::Value *a, *b, *c, *d, *re, *im;
llvm::Value *a, *b, *c, *d;
// lhs values
if (DComplexValue* cx = lhs->isComplex()) {
a = cx->re;
b = cx->im;
}
else {
a = DtoLoad(DtoGEPi(lhs->getRVal(),0,0,"tmp"));
b = DtoLoad(DtoGEPi(lhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(lhs, a, b);
// rhs values
if (DComplexValue* cx = rhs->isComplex()) {
c = cx->re;
d = cx->im;
}
else {
c = DtoLoad(DtoGEPi(rhs->getRVal(),0,0,"tmp"));
d = DtoLoad(DtoGEPi(rhs->getRVal(),0,1,"tmp"));
}
DtoGetComplexParts(rhs, c, d);
llvm::Value *tmp1, *tmp2, *denom;
llvm::Value *tmp1, *tmp2, *denom, *re, *im;
tmp1 = gIR->ir->CreateMul(c, c, "tmp");
tmp2 = gIR->ir->CreateMul(d, d, "tmp");
@@ -330,29 +284,27 @@ DValue* DtoComplexDiv(Type* type, DValue* lhs, DValue* rhs)
llvm::Value* DtoComplexEquals(TOK op, DValue* lhs, DValue* rhs)
{
llvm::Value* lvec = lhs->getRVal();
llvm::Value* rvec = rhs->getRVal();
Type* type = lhs->getType();
lhs = DtoComplex(type, lhs);
rhs = DtoComplex(type, rhs);
llvm::Value *a, *b, *c, *d;
// lhs values
DtoGetComplexParts(lhs, a, b);
// rhs values
DtoGetComplexParts(rhs, c, d);
// select predicate
llvm::FCmpInst::Predicate cmpop;
switch(op)
{
case TOKequal:
if (op == TOKequal)
cmpop = llvm::FCmpInst::FCMP_OEQ;
break;
case TOKnotequal:
else
cmpop = llvm::FCmpInst::FCMP_UNE;
break;
default:
assert(0);
}
llvm::Value* l1 = gIR->ir->CreateExtractElement(lvec, DtoConstUint(0), "re");
llvm::Value* r1 = gIR->ir->CreateExtractElement(rvec, DtoConstUint(0), "re");
llvm::Value* b1 = new llvm::FCmpInst(cmpop, l1, r1, "tmp", gIR->scopebb());
llvm::Value* l2 = gIR->ir->CreateExtractElement(lvec, DtoConstUint(1), "im");
llvm::Value* r2 = gIR->ir->CreateExtractElement(rvec, DtoConstUint(1), "im");
llvm::Value* b2 = new llvm::FCmpInst(cmpop, l2, r2, "tmp", gIR->scopebb());
// (l.re==r.re && l.im==r.im)
llvm::Value* b1 = new llvm::FCmpInst(cmpop, a, c, "tmp", gIR->scopebb());
llvm::Value* b2 = new llvm::FCmpInst(cmpop, b, d, "tmp", gIR->scopebb());
return gIR->ir->CreateAnd(b1,b2,"tmp");
}

View File

@@ -17,6 +17,8 @@ DValue* DtoComplex(Type* to, DValue* val);
void DtoComplexAssign(llvm::Value* l, llvm::Value* r);
void DtoComplexSet(llvm::Value* c, llvm::Value* re, llvm::Value* im);
void DtoGetComplexParts(DValue* c, llvm::Value*& re, llvm::Value*& im);
DValue* DtoComplexAdd(Type* type, DValue* lhs, DValue* rhs);
DValue* DtoComplexSub(Type* type, DValue* lhs, DValue* rhs);
DValue* DtoComplexMul(Type* type, DValue* lhs, DValue* rhs);

View File

@@ -31,7 +31,7 @@ struct DThisValue;
struct DFuncValue;
struct DSliceValue;
struct DArrayLenValue;
struct DLValueCast;
struct DLRValue;
struct DComplexValue;
// base class for d-values
@@ -51,8 +51,8 @@ struct DValue : Object
virtual DSliceValue* isSlice() { return NULL; }
virtual DFuncValue* isFunc() { return NULL; }
virtual DArrayLenValue* isArrayLen() { return NULL; }
virtual DLValueCast* isLValueCast() { return NULL; }
virtual DComplexValue* isComplex() { return NULL; };
virtual DComplexValue* isComplex() { return NULL; }
virtual DLRValue* isLRValue() { return NULL; }
virtual bool inPlace() { return false; }
@@ -172,24 +172,28 @@ struct DFuncValue : DValue
virtual DFuncValue* isFunc() { return this; }
};
// l-value cast d-value
struct DLValueCast : DValue
// l-value and r-value pair d-value
struct DLRValue : DValue
{
Type* type;
Type* ltype;
llvm::Value* lval;
Type* rtype;
llvm::Value* rval;
DLValueCast(Type* t, llvm::Value* l, llvm::Value* r) {
type = t;
DLRValue(Type* lt, llvm::Value* l, Type* rt, llvm::Value* r) {
ltype = lt;
lval = l;
rtype = rt;
rval = r;
}
virtual llvm::Value* getLVal() { assert(lval); return lval; }
virtual llvm::Value* getRVal() { assert(rval); return rval; }
virtual Type* getType() { assert(type); return type; }
virtual DLValueCast* isLValueCast() { return this; }
Type* getLType() { return ltype; }
Type* getRType() { return rtype; }
virtual Type* getType() { return getRType(); }
virtual DLRValue* isLRValue() { return this; }
};
// complex number immediate d-value (much like slice)

View File

@@ -562,7 +562,7 @@ DValue* AddAssignExp::toElem(IRState* p)
res = new DImValue(type, gep);
}
else if (t->iscomplex()) {
res = DtoComplexAdd(type, l, r);
res = DtoComplexAdd(e1->type, l, r);
}
else {
res = DtoBinAdd(l,r);
@@ -1056,17 +1056,17 @@ DValue* CastExp::toElem(IRState* p)
DValue* u = e1->toElem(p);
DValue* v = DtoCast(u, to);
if (v->isSlice())
if (v->isSlice()) {
assert(!gIR->topexp() || gIR->topexp()->e1 != this);
return v;
else if (u->isLValueCast() || (u->isVar() && u->isVar()->lval))
return new DLValueCast(to, u->getLVal(), v->getRVal());
else if (gIR->topexp() && gIR->topexp()->e1 == this) {
llvm::Value* lval = u->getLVal();
llvm::Value* rval = v->getRVal();
Logger::cout() << "lval: " << *lval << "rval: " << *rval << '\n';
return new DLValueCast(to, lval, rval);
}
else if (u->isLRValue() || (u->isVar() && u->isVar()->lval))
return new DLRValue(e1->type, u->getLVal(), to, v->getRVal());
else if (gIR->topexp() && gIR->topexp()->e1 == this)
return new DLRValue(e1->type, u->getLVal(), to, v->getRVal());
return v;
}
@@ -1193,7 +1193,7 @@ DValue* PtrExp::toElem(IRState* p)
llvm::Value* v = lv;
if (DtoCanLoad(v))
v = DtoLoad(v);
return new DLValueCast(type, lv, v);
return new DLRValue(e1->type, lv, type, v);
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -689,6 +689,10 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
retval = new llvm::AllocaInst(DtoType(realtype), "tmpparam", gIR->topallocapoint());
DtoSetArray(retval, DtoArrayLen(sv), DtoArrayPtr(sv));
}
else if (DComplexValue* cv = arg->isComplex()) {
retval = new llvm::AllocaInst(DtoType(realtype), "tmpparam", gIR->topallocapoint());
DtoComplexSet(retval, cv->re, cv->im);
}
else {
retval = arg->getRVal();
}
@@ -719,6 +723,14 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint());
}
}
else if (realtype->iscomplex()) {
if (arg->isComplex()) {
allocaInst = new llvm::AllocaInst(realtypell, "tmpparam", gIR->topallocapoint());
}
else {
allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint());
}
}
else
assert(0);
@@ -736,6 +748,9 @@ llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expressio
if (sl->len) Logger::cout() << "len = " << *sl->len << '\n';
assert(0);
}
else if (DComplexValue* cl = arg->isComplex()) {
assert(0 && "complex in the wrong place");
}
else {
retval = arg->getRVal();
}
@@ -895,19 +910,27 @@ void DtoAssign(DValue* lhs, DValue* rhs)
}
else if (t->iscomplex()) {
assert(!lhs->isComplex());
if (DComplexValue* cx = rhs->isComplex()) {
DtoComplexSet(lhs->getRVal(), cx->re, cx->im);
llvm::Value* dst;
if (DLRValue* lr = lhs->isLRValue()) {
dst = lr->getLVal();
rhs = DtoCastComplex(rhs, lr->getLType());
}
else {
DtoComplexAssign(lhs->getRVal(), rhs->getRVal());
dst = lhs->getRVal();
}
if (DComplexValue* cx = rhs->isComplex())
DtoComplexSet(dst, cx->re, cx->im);
else
DtoComplexAssign(dst, rhs->getRVal());
}
else {
llvm::Value* r = rhs->getRVal();
llvm::Value* l = lhs->getLVal();
Logger::cout() << "assign\nlhs: " << *l << "rhs: " << *r << '\n';
const llvm::Type* lit = l->getType()->getContainedType(0);
if (r->getType() != lit) {
if (r->getType() != lit) { // :(
r = DtoBitCast(r, lit);
Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n';
}
@@ -982,6 +1005,7 @@ DValue* DtoCastPtr(DValue* val, Type* to)
rval = new llvm::PtrToIntInst(val->getRVal(), tolltype, "tmp", gIR->scopebb());
}
else {
Logger::println("invalid cast from '%s' to '%s'", val->getType()->toChars(), to->toChars());
assert(0);
}
@@ -1040,16 +1064,48 @@ DValue* DtoCastFloat(DValue* val, Type* to)
DValue* DtoCastComplex(DValue* val, Type* _to)
{
Type* to = DtoDType(_to);
llvm::Value* v = val->getRVal();
Type* vty = val->getType();
if (to->iscomplex()) {
assert(0);
if (vty->size() == to->size())
return val;
llvm::Value *re, *im;
DtoGetComplexParts(val, re, im);
const llvm::Type* toty = DtoComplexBaseType(to);
if (to->size() < vty->size()) {
re = gIR->ir->CreateFPTrunc(re, toty, "tmp");
im = gIR->ir->CreateFPTrunc(im, toty, "tmp");
}
else if (to->size() > vty->size()) {
re = gIR->ir->CreateFPExt(re, toty, "tmp");
im = gIR->ir->CreateFPExt(im, toty, "tmp");
}
else {
return val;
}
if (val->isComplex())
return new DComplexValue(_to, re, im);
// unfortunately at this point, the cast value can show up as the lvalue for += and similar expressions.
// so we need to give it storage, or fix the system that handles this stuff (DLRValue)
llvm::Value* mem = new llvm::AllocaInst(DtoType(_to), "castcomplextmp", gIR->topallocapoint());
DtoComplexSet(mem, re, im);
return new DLRValue(val->getType(), val->getRVal(), _to, mem);
}
else if (to->isimaginary()) {
DImValue* im = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(1), "im"));
if (val->isComplex())
return new DImValue(to, val->isComplex()->im);
llvm::Value* v = val->getRVal();
DImValue* im = new DImValue(to, DtoLoad(DtoGEPi(v,0,1,"tmp")));
return DtoCastFloat(im, to);
}
else if (to->isfloating()) {
DImValue* re = new DImValue(to, gIR->ir->CreateExtractElement(v, DtoConstUint(0), "re"));
if (val->isComplex())
return new DImValue(to, val->isComplex()->re);
llvm::Value* v = val->getRVal();
DImValue* re = new DImValue(to, DtoLoad(DtoGEPi(v,0,0,"tmp")));
return DtoCastFloat(re, to);
}
else

View File

@@ -132,7 +132,6 @@ gen/tollvm.cpp
gen/tollvm.h
gen/toobj.cpp
gen/typeinf.h
gen/typeinfo12.d
gen/typinf.cpp
lphobos
lphobos/crc32.d
@@ -193,7 +192,10 @@ lphobos/std/uni.d
lphobos/std/utf.d
lphobos/typeinfo1
lphobos/typeinfo1/ti_byte.d
lphobos/typeinfo1/ti_cdouble.d
lphobos/typeinfo1/ti_cfloat.d
lphobos/typeinfo1/ti_char.d
lphobos/typeinfo1/ti_creal.d
lphobos/typeinfo1/ti_dchar.d
lphobos/typeinfo1/ti_delegate.d
lphobos/typeinfo1/ti_double.d
@@ -213,6 +215,7 @@ lphobos/typeinfo1/ti_ushort.d
lphobos/typeinfo1/ti_void.d
lphobos/typeinfo1/ti_wchar.d
lphobos/typeinfo2
lphobos/typeinfo2/ti_AC.d
lphobos/typeinfo2/ti_Adouble.d
lphobos/typeinfo2/ti_Afloat.d
lphobos/typeinfo2/ti_Ag.d
@@ -220,6 +223,7 @@ lphobos/typeinfo2/ti_Aint.d
lphobos/typeinfo2/ti_Along.d
lphobos/typeinfo2/ti_Areal.d
lphobos/typeinfo2/ti_Ashort.d
lphobos/typeinfo2/ti_C.d
lphobos/typeinfos1.d
lphobos/typeinfos2.d
runalltests.d
@@ -304,8 +308,8 @@ test/bug62.d
test/bug63.d
test/bug64.d
test/bug66.d
test/bug69.d
test/bug7.d
test/bug70.d
test/bug8.d
test/bug9.d
test/c.d

View File

@@ -20,7 +20,7 @@ llvm-link -f -o=../lib/llvmdcore.bc `ls obj/internal.*.bc` ../lib/llvmdcore.bc o
echo "compiling typeinfo 1"
rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix || exit 1
rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix -v || exit 1
llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo1.*.bc` ../lib/llvmdcore.bc || exit 1
echo "compiling typeinfo 2"

View File

@@ -0,0 +1,67 @@
// cdouble
module std.typeinfo.ti_cdouble;
class TypeInfo_r : TypeInfo
{
char[] toString() { return "cdouble"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
(cast(uint *)p)[2] + (cast(uint *)p)[3];
}
static int _equals(cdouble f1, cdouble f2)
{
return f1 == f2;
}
static int _compare(cdouble f1, cdouble f2)
{ int result;
if (f1.re < f2.re)
result = -1;
else if (f1.re > f2.re)
result = 1;
else if (f1.im < f2.im)
result = -1;
else if (f1.im > f2.im)
result = 1;
else
result = 0;
return result;
}
int equals(void *p1, void *p2)
{
return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
}
size_t tsize()
{
return cdouble.sizeof;
}
void swap(void *p1, void *p2)
{
cdouble t;
t = *cast(cdouble *)p1;
*cast(cdouble *)p1 = *cast(cdouble *)p2;
*cast(cdouble *)p2 = t;
}
void[] init()
{ static cdouble r;
return (cast(cdouble *)&r)[0 .. 1];
}
}

View File

@@ -0,0 +1,66 @@
// cfloat
module std.typeinfo.ti_cfloat;
class TypeInfo_q : TypeInfo
{
char[] toString() { return "cfloat"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1];
}
static int _equals(cfloat f1, cfloat f2)
{
return f1 == f2;
}
static int _compare(cfloat f1, cfloat f2)
{ int result;
if (f1.re < f2.re)
result = -1;
else if (f1.re > f2.re)
result = 1;
else if (f1.im < f2.im)
result = -1;
else if (f1.im > f2.im)
result = 1;
else
result = 0;
return result;
}
int equals(void *p1, void *p2)
{
return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
}
size_t tsize()
{
return cfloat.sizeof;
}
void swap(void *p1, void *p2)
{
cfloat t;
t = *cast(cfloat *)p1;
*cast(cfloat *)p1 = *cast(cfloat *)p2;
*cast(cfloat *)p2 = t;
}
void[] init()
{ static cfloat r;
return (cast(cfloat *)&r)[0 .. 1];
}
}

View File

@@ -0,0 +1,68 @@
// creal
module std.typeinfo.ti_creal;
class TypeInfo_c : TypeInfo
{
char[] toString() { return "creal"; }
hash_t getHash(void *p)
{
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
(cast(uint *)p)[2] + (cast(uint *)p)[3] +
(cast(uint *)p)[4];
}
static int _equals(creal f1, creal f2)
{
return f1 == f2;
}
static int _compare(creal f1, creal f2)
{ int result;
if (f1.re < f2.re)
result = -1;
else if (f1.re > f2.re)
result = 1;
else if (f1.im < f2.im)
result = -1;
else if (f1.im > f2.im)
result = 1;
else
result = 0;
return result;
}
int equals(void *p1, void *p2)
{
return _equals(*cast(creal *)p1, *cast(creal *)p2);
}
int compare(void *p1, void *p2)
{
return _compare(*cast(creal *)p1, *cast(creal *)p2);
}
size_t tsize()
{
return creal.sizeof;
}
void swap(void *p1, void *p2)
{
creal t;
t = *cast(creal *)p1;
*cast(creal *)p1 = *cast(creal *)p2;
*cast(creal *)p2 = t;
}
void[] init()
{ static creal r;
return (cast(creal *)&r)[0 .. 1];
}
}

92
lphobos/typeinfo2/ti_AC.d Normal file
View File

@@ -0,0 +1,92 @@
module std.typeinfo.ti_AC;
// Object[]
class TypeInfo_AC : TypeInfo
{
hash_t getHash(void *p)
{ Object[] s = *cast(Object[]*)p;
hash_t hash = 0;
foreach (Object o; s)
{
if (o)
hash += o.toHash();
}
return hash;
}
int equals(void *p1, void *p2)
{
Object[] s1 = *cast(Object[]*)p1;
Object[] s2 = *cast(Object[]*)p2;
if (s1.length == s2.length)
{
for (size_t u = 0; u < s1.length; u++)
{ Object o1 = s1[u];
Object o2 = s2[u];
// Do not pass null's to Object.opEquals()
if (o1 is o2 ||
(!(o1 is null) && !(o2 is null) && o1.opEquals(o2)))
continue;
return 0;
}
return 1;
}
return 0;
}
int compare(void *p1, void *p2)
{
Object[] s1 = *cast(Object[]*)p1;
Object[] s2 = *cast(Object[]*)p2;
int c;
c = cast(int)s1.length - cast(int)s2.length;
if (c == 0)
{
for (size_t u = 0; u < s1.length; u++)
{ Object o1 = s1[u];
Object o2 = s2[u];
if (o1 is o2)
continue;
// Regard null references as always being "less than"
if (o1)
{
if (!o2)
{ c = 1;
break;
}
c = o1.opCmp(o2);
if (c)
break;
}
else
{ c = -1;
break;
}
}
}
return c;
}
size_t tsize()
{
return (Object[]).sizeof;
}
uint flags()
{
return 1;
}
TypeInfo next()
{
return typeid(Object);
}
}

View File

@@ -2,13 +2,16 @@ module typeinfos1;
import
typeinfo1.ti_byte,
typeinfo1.ti_cdouble,
typeinfo1.ti_cfloat,
typeinfo1.ti_char,
typeinfo1.ti_delegate,
typeinfo1.ti_creal,
typeinfo1.ti_dchar,
typeinfo1.ti_delegate,
typeinfo1.ti_double,
typeinfo1.ti_float,
typeinfo1.ti_ifloat,
typeinfo1.ti_idouble,
typeinfo1.ti_ifloat,
typeinfo1.ti_int,
typeinfo1.ti_ireal,
typeinfo1.ti_long,

View File

@@ -1,6 +1,7 @@
module typeinfos2;
import
//typeinfo2.to_AC,
typeinfo2.ti_Adouble,
typeinfo2.ti_Afloat,
typeinfo2.ti_Ag,

View File

@@ -4,6 +4,6 @@ void main()
{
cfloat c1 = 1f + 0i;
cfloat c2 = 0f + 0i;
//c2 += 1f + 0i;
c2 += 1f + 0i;
//assert(c1 == c2);
}