# HG changeset patch # User lindquist # Date 1195513355 -3600 # Node ID 3efbcc81ba45670b4f07948e70468f32ade7376b # Parent 5b5194b25f332e4b18463305869e21bc7284c8c0 [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. diff -r 5b5194b25f33 -r 3efbcc81ba45 gen/complex.cpp --- a/gen/complex.cpp Mon Nov 19 06:01:48 2007 +0100 +++ b/gen/complex.cpp Tue Nov 20 00:02:35 2007 +0100 @@ -127,8 +127,7 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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"); } diff -r 5b5194b25f33 -r 3efbcc81ba45 gen/complex.h --- a/gen/complex.h Mon Nov 19 06:01:48 2007 +0100 +++ b/gen/complex.h Tue Nov 20 00:02:35 2007 +0100 @@ -17,6 +17,8 @@ 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); diff -r 5b5194b25f33 -r 3efbcc81ba45 gen/dvalue.h --- a/gen/dvalue.h Mon Nov 19 06:01:48 2007 +0100 +++ b/gen/dvalue.h Tue Nov 20 00:02:35 2007 +0100 @@ -31,7 +31,7 @@ struct DFuncValue; struct DSliceValue; struct DArrayLenValue; -struct DLValueCast; +struct DLRValue; struct DComplexValue; // base class for d-values @@ -51,8 +51,8 @@ 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 @@ 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) diff -r 5b5194b25f33 -r 3efbcc81ba45 gen/toir.cpp --- a/gen/toir.cpp Mon Nov 19 06:01:48 2007 +0100 +++ b/gen/toir.cpp Tue Nov 20 00:02:35 2007 +0100 @@ -562,7 +562,7 @@ 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* 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 @@ llvm::Value* v = lv; if (DtoCanLoad(v)) v = DtoLoad(v); - return new DLValueCast(type, lv, v); + return new DLRValue(e1->type, lv, type, v); } ////////////////////////////////////////////////////////////////////////////////////////// diff -r 5b5194b25f33 -r 3efbcc81ba45 gen/tollvm.cpp --- a/gen/tollvm.cpp Mon Nov 19 06:01:48 2007 +0100 +++ b/gen/tollvm.cpp Tue Nov 20 00:02:35 2007 +0100 @@ -689,6 +689,10 @@ 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 @@ 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 @@ 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 @@ } 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 @@ 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* 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 diff -r 5b5194b25f33 -r 3efbcc81ba45 llvmdc.kdevelop.filelist --- a/llvmdc.kdevelop.filelist Mon Nov 19 06:01:48 2007 +0100 +++ b/llvmdc.kdevelop.filelist Tue Nov 20 00:02:35 2007 +0100 @@ -132,7 +132,6 @@ 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/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_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_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/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 diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/build.sh --- a/lphobos/build.sh Mon Nov 19 06:01:48 2007 +0100 +++ b/lphobos/build.sh Tue Nov 20 00:02:35 2007 +0100 @@ -20,7 +20,7 @@ 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" diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/typeinfo1/ti_cdouble.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/typeinfo1/ti_cdouble.d Tue Nov 20 00:02:35 2007 +0100 @@ -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]; + } +} + diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/typeinfo1/ti_cfloat.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/typeinfo1/ti_cfloat.d Tue Nov 20 00:02:35 2007 +0100 @@ -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]; + } +} + diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/typeinfo1/ti_creal.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/typeinfo1/ti_creal.d Tue Nov 20 00:02:35 2007 +0100 @@ -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]; + } +} + diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/typeinfo2/ti_AC.d --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/lphobos/typeinfo2/ti_AC.d Tue Nov 20 00:02:35 2007 +0100 @@ -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); + } +} + diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/typeinfos1.d --- a/lphobos/typeinfos1.d Mon Nov 19 06:01:48 2007 +0100 +++ b/lphobos/typeinfos1.d Tue Nov 20 00:02:35 2007 +0100 @@ -2,13 +2,16 @@ import typeinfo1.ti_byte, +typeinfo1.ti_cdouble, +typeinfo1.ti_cfloat, typeinfo1.ti_char, +typeinfo1.ti_creal, +typeinfo1.ti_dchar, typeinfo1.ti_delegate, -typeinfo1.ti_dchar, typeinfo1.ti_double, typeinfo1.ti_float, +typeinfo1.ti_idouble, typeinfo1.ti_ifloat, -typeinfo1.ti_idouble, typeinfo1.ti_int, typeinfo1.ti_ireal, typeinfo1.ti_long, diff -r 5b5194b25f33 -r 3efbcc81ba45 lphobos/typeinfos2.d --- a/lphobos/typeinfos2.d Mon Nov 19 06:01:48 2007 +0100 +++ b/lphobos/typeinfos2.d Tue Nov 20 00:02:35 2007 +0100 @@ -1,6 +1,7 @@ module typeinfos2; import +//typeinfo2.to_AC, typeinfo2.ti_Adouble, typeinfo2.ti_Afloat, typeinfo2.ti_Ag, diff -r 5b5194b25f33 -r 3efbcc81ba45 test/complex3.d --- a/test/complex3.d Mon Nov 19 06:01:48 2007 +0100 +++ b/test/complex3.d Tue Nov 20 00:02:35 2007 +0100 @@ -4,6 +4,6 @@ { cfloat c1 = 1f + 0i; cfloat c2 = 0f + 0i; - //c2 += 1f + 0i; + c2 += 1f + 0i; //assert(c1 == c2); }