From b72a4fa645e30afa67a70cc6d2b14eb59fabbdbb Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Tue, 23 Oct 2007 07:16:02 +0200 Subject: [PATCH] [svn r57] Added most basic TypeInfo (rebuild lphobos). Fixed some SymOffExp bugs. Added another typeinfo test case. --- gen/toir.c | 18 +++++++-- gen/tollvm.c | 15 ++++++++ gen/tollvm.h | 1 + lphobos/typeinfo/ti_dchar.d | 45 ++++++++++++++++++++++ lphobos/typeinfo/ti_delegate.d | 40 +++++++++++++++++++ lphobos/typeinfo/ti_double.d | 70 ++++++++++++++++++++++++++++++++++ lphobos/typeinfo/ti_float.d | 70 ++++++++++++++++++++++++++++++++++ lphobos/typeinfo/ti_long.d | 43 +++++++++++++++++++++ lphobos/typeinfo/ti_real.d | 70 ++++++++++++++++++++++++++++++++++ lphobos/typeinfo/ti_ulong.d | 43 +++++++++++++++++++++ lphobos/typeinfo/ti_void.d | 44 +++++++++++++++++++++ lphobos/typeinfo/ti_wchar.d | 44 +++++++++++++++++++++ lphobos/typeinfos.d | 20 ++++++++++ test/typeinfo2.d | 14 +++++++ 14 files changed, 533 insertions(+), 4 deletions(-) create mode 100644 lphobos/typeinfo/ti_dchar.d create mode 100644 lphobos/typeinfo/ti_delegate.d create mode 100644 lphobos/typeinfo/ti_double.d create mode 100644 lphobos/typeinfo/ti_float.d create mode 100644 lphobos/typeinfo/ti_long.d create mode 100644 lphobos/typeinfo/ti_real.d create mode 100644 lphobos/typeinfo/ti_ulong.d create mode 100644 lphobos/typeinfo/ti_void.d create mode 100644 lphobos/typeinfo/ti_wchar.d create mode 100644 lphobos/typeinfos.d create mode 100644 test/typeinfo2.d diff --git a/gen/toir.c b/gen/toir.c index 51022f53..e5b01d64 100644 --- a/gen/toir.c +++ b/gen/toir.c @@ -1058,7 +1058,7 @@ elem* CallExp::toElem(IRState* p) Logger::cout() << "what are we calling? : " << *funcval << '\n'; } assert(llfnty); - Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; + //Logger::cout() << "Function LLVM type: " << *llfnty << '\n'; // argument handling llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); @@ -1132,7 +1132,7 @@ elem* CallExp::toElem(IRState* p) Logger::cout() << *llargs[i] << '\n'; } - Logger::cout() << "Calling: " << *funcval->getType() << '\n'; + //Logger::cout() << "Calling: " << *funcval->getType() << '\n'; // call the function llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); @@ -1155,7 +1155,7 @@ elem* CallExp::toElem(IRState* p) elem* CastExp::toElem(IRState* p) { - Logger::print("CastExp::toElem: %s\n", toChars()); + Logger::print("CastExp::toElem: %s | %s\n", toChars(), type->toChars()); LOG_SCOPE; elem* e = new elem; elem* u = e1->toElem(p); @@ -1363,6 +1363,12 @@ elem* SymOffExp::toElem(IRState* p) e = new elem; assert(llvalue); e->mem = llvalue; + const llvm::Type* llt = LLVM_DtoType(t); + if (llvalue->getType() != llt) { + Logger::cout() << "llt is:" << *llt << '\n'; + //const llvm::PointerType* vpty = llvm::PointerType::get(llvm::Type::Int8Ty); + e->mem = p->ir->CreateBitCast(e->mem, llt, "tmp"); + } e->type = elem::VAL; } else { @@ -1465,7 +1471,7 @@ elem* DotVarExp::toElem(IRState* p) llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); funcval = LLVM_DtoGEP(e->arg, zero, zero, "tmp", p->scopebb()); funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); - funcval = LLVM_DtoGEP(funcval, zero, vtblidx, "tmp", p->scopebb()); + funcval = LLVM_DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); assert(funcval->getType() == fdecl->llvmValue->getType()); e->callconv = LLVM_DtoCallingConv(fdecl->linkage); @@ -1925,6 +1931,10 @@ elem* EqualExp::toElem(IRState* p) { e->val = LLVM_DtoDynArrayCompare(op,l->mem,r->mem); } + else if (t->ty == Tdelegate) + { + e->val = LLVM_DtoCompareDelegate(op,l->mem,r->mem); + } else { assert(0 && "Unsupported EqualExp type"); diff --git a/gen/tollvm.c b/gen/tollvm.c index 02d84743..bf84b7a4 100644 --- a/gen/tollvm.c +++ b/gen/tollvm.c @@ -610,7 +610,22 @@ llvm::Value* LLVM_DtoDelegateCopy(llvm::Value* dst, llvm::Value* src) return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); } +////////////////////////////////////////////////////////////////////////////////////////// +llvm::Value* LLVM_DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs) +{ + llvm::ICmpInst::Predicate pred = (op == TOKequal) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; + llvm::Value* l = gIR->ir->CreateLoad(LLVM_DtoGEPi(lhs,0,0,"tmp"),"tmp"); + llvm::Value* r = gIR->ir->CreateLoad(LLVM_DtoGEPi(rhs,0,0,"tmp"),"tmp"); + llvm::Value* b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + l = gIR->ir->CreateLoad(LLVM_DtoGEPi(lhs,0,1,"tmp"),"tmp"); + r = gIR->ir->CreateLoad(LLVM_DtoGEPi(rhs,0,1,"tmp"),"tmp"); + llvm::Value* b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); + llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); + if (op == TOKnotequal) + return gIR->ir->CreateNot(b,"tmp"); + return b; +} ////////////////////////////////////////////////////////////////////////////////////////// diff --git a/gen/tollvm.h b/gen/tollvm.h index 7d6568a0..14dba07b 100644 --- a/gen/tollvm.h +++ b/gen/tollvm.h @@ -18,6 +18,7 @@ llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl); const llvm::StructType* LLVM_DtoDelegateType(Type* t); llvm::Value* LLVM_DtoNullDelegate(llvm::Value* v); llvm::Value* LLVM_DtoDelegateCopy(llvm::Value* dst, llvm::Value* src); +llvm::Value* LLVM_DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs); llvm::GlobalValue::LinkageTypes LLVM_DtoLinkage(PROT prot, uint stc); unsigned LLVM_DtoCallingConv(LINK l); diff --git a/lphobos/typeinfo/ti_dchar.d b/lphobos/typeinfo/ti_dchar.d new file mode 100644 index 00000000..01854e17 --- /dev/null +++ b/lphobos/typeinfo/ti_dchar.d @@ -0,0 +1,45 @@ + +// dchar + +module typeinfo.ti_dchar; + +class TypeInfo_w : TypeInfo +{ + char[] toString() { return "dchar"; } + + hash_t getHash(void *p) + { + return *cast(dchar *)p; + } + + int equals(void *p1, void *p2) + { + return *cast(dchar *)p1 == *cast(dchar *)p2; + } + + int compare(void *p1, void *p2) + { + return *cast(dchar *)p1 - *cast(dchar *)p2; + } + + size_t tsize() + { + return dchar.sizeof; + } + + void swap(void *p1, void *p2) + { + dchar t; + + t = *cast(dchar *)p1; + *cast(dchar *)p1 = *cast(dchar *)p2; + *cast(dchar *)p2 = t; + } + + void[] init() + { static dchar c; + + return (cast(dchar *)&c)[0 .. 1]; + } +} + diff --git a/lphobos/typeinfo/ti_delegate.d b/lphobos/typeinfo/ti_delegate.d new file mode 100644 index 00000000..5b6e6092 --- /dev/null +++ b/lphobos/typeinfo/ti_delegate.d @@ -0,0 +1,40 @@ + +// delegate + +module typeinfo.ti_delegate; + +alias void delegate(int) dg; + +class TypeInfo_D : TypeInfo +{ + hash_t getHash(void *p) + { long l = *cast(long *)p; + + return cast(uint)(l + (l >> 32)); + } + + int equals(void *p1, void *p2) + { + return *cast(dg *)p1 == *cast(dg *)p2; + } + + size_t tsize() + { + return dg.sizeof; + } + + void swap(void *p1, void *p2) + { + dg t; + + t = *cast(dg *)p1; + *cast(dg *)p1 = *cast(dg *)p2; + *cast(dg *)p2 = t; + } + + uint flags() + { + return 1; + } +} + diff --git a/lphobos/typeinfo/ti_double.d b/lphobos/typeinfo/ti_double.d new file mode 100644 index 00000000..d96e0f95 --- /dev/null +++ b/lphobos/typeinfo/ti_double.d @@ -0,0 +1,70 @@ + +// double + +module typeinfo.ti_double; + +class TypeInfo_d : TypeInfo +{ + char[] toString() { return "double"; } + + hash_t getHash(void *p) + { + return (cast(uint *)p)[0] + (cast(uint *)p)[1]; + } + + static bool _isnan(double d) + { + return d !<>= 0; + } + + static int _equals(double f1, double f2) + { + return f1 == f2 || + (_isnan(f1) && _isnan(f2)); + } + + static int _compare(double d1, double d2) + { + if (d1 !<>= d2) // if either are NaN + { + if (_isnan(d1)) + { if (_isnan(d2)) + return 0; + return -1; + } + return 1; + } + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1); + } + + int equals(void *p1, void *p2) + { + return _equals(*cast(double *)p1, *cast(double *)p2); + } + + int compare(void *p1, void *p2) + { + return _compare(*cast(double *)p1, *cast(double *)p2); + } + + size_t tsize() + { + return double.sizeof; + } + + void swap(void *p1, void *p2) + { + double t; + + t = *cast(double *)p1; + *cast(double *)p1 = *cast(double *)p2; + *cast(double *)p2 = t; + } + + void[] init() + { static double r; + + return (&r)[0 .. 1]; + } +} + diff --git a/lphobos/typeinfo/ti_float.d b/lphobos/typeinfo/ti_float.d new file mode 100644 index 00000000..a7f6060c --- /dev/null +++ b/lphobos/typeinfo/ti_float.d @@ -0,0 +1,70 @@ + +// float + +module typeinfo.ti_float; + +class TypeInfo_f : TypeInfo +{ + char[] toString() { return "float"; } + + hash_t getHash(void *p) + { + return *cast(uint *)p; + } + + static bool _isnan(float f) + { + return f !<>= 0; + } + + static int _equals(float f1, float f2) + { + return f1 == f2 || + (_isnan(f1) && _isnan(f2)); + } + + static int _compare(float d1, float d2) + { + if (d1 !<>= d2) // if either are NaN + { + if (_isnan(d1)) + { if (_isnan(d2)) + return 0; + return -1; + } + return 1; + } + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1); + } + + int equals(void *p1, void *p2) + { + return _equals(*cast(float *)p1, *cast(float *)p2); + } + + int compare(void *p1, void *p2) + { + return _compare(*cast(float *)p1, *cast(float *)p2); + } + + size_t tsize() + { + return float.sizeof; + } + + void swap(void *p1, void *p2) + { + float t; + + t = *cast(float *)p1; + *cast(float *)p1 = *cast(float *)p2; + *cast(float *)p2 = t; + } + + void[] init() + { static float r; + + return (&r)[0 .. 1]; + } +} + diff --git a/lphobos/typeinfo/ti_long.d b/lphobos/typeinfo/ti_long.d new file mode 100644 index 00000000..771fec6e --- /dev/null +++ b/lphobos/typeinfo/ti_long.d @@ -0,0 +1,43 @@ + +// long + +module typeinfo.ti_long; + +class TypeInfo_l : TypeInfo +{ + char[] toString() { return "long"; } + + hash_t getHash(void *p) + { + return *cast(uint *)p + (cast(uint *)p)[1]; + } + + int equals(void *p1, void *p2) + { + return *cast(long *)p1 == *cast(long *)p2; + } + + int compare(void *p1, void *p2) + { + if (*cast(long *)p1 < *cast(long *)p2) + return -1; + else if (*cast(long *)p1 > *cast(long *)p2) + return 1; + return 0; + } + + size_t tsize() + { + return long.sizeof; + } + + void swap(void *p1, void *p2) + { + long t; + + t = *cast(long *)p1; + *cast(long *)p1 = *cast(long *)p2; + *cast(long *)p2 = t; + } +} + diff --git a/lphobos/typeinfo/ti_real.d b/lphobos/typeinfo/ti_real.d new file mode 100644 index 00000000..8d429ee1 --- /dev/null +++ b/lphobos/typeinfo/ti_real.d @@ -0,0 +1,70 @@ + +// real + +module typeinfo.ti_real; + +class TypeInfo_e : TypeInfo +{ + char[] toString() { return "real"; } + + hash_t getHash(void *p) + { + return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4]; + } + + static bool _isnan(real r) + { + return r !<>= 0; + } + + static int _equals(real f1, real f2) + { + return f1 == f2 || + (_isnan(f1) && _isnan(f2)); + } + + static int _compare(real d1, real d2) + { + if (d1 !<>= d2) // if either are NaN + { + if (_isnan(d1)) + { if (_isnan(d2)) + return 0; + return -1; + } + return 1; + } + return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1); + } + + int equals(void *p1, void *p2) + { + return _equals(*cast(real *)p1, *cast(real *)p2); + } + + int compare(void *p1, void *p2) + { + return _compare(*cast(real *)p1, *cast(real *)p2); + } + + size_t tsize() + { + return real.sizeof; + } + + void swap(void *p1, void *p2) + { + real t; + + t = *cast(real *)p1; + *cast(real *)p1 = *cast(real *)p2; + *cast(real *)p2 = t; + } + + void[] init() + { static real r; + + return (&r)[0 .. 1]; + } +} + diff --git a/lphobos/typeinfo/ti_ulong.d b/lphobos/typeinfo/ti_ulong.d new file mode 100644 index 00000000..a0d1a36c --- /dev/null +++ b/lphobos/typeinfo/ti_ulong.d @@ -0,0 +1,43 @@ + +// ulong + +module typeinfo.ti_ulong; + +class TypeInfo_m : TypeInfo +{ + char[] toString() { return "ulong"; } + + hash_t getHash(void *p) + { + return *cast(uint *)p + (cast(uint *)p)[1]; + } + + int equals(void *p1, void *p2) + { + return *cast(ulong *)p1 == *cast(ulong *)p2; + } + + int compare(void *p1, void *p2) + { + if (*cast(ulong *)p1 < *cast(ulong *)p2) + return -1; + else if (*cast(ulong *)p1 > *cast(ulong *)p2) + return 1; + return 0; + } + + size_t tsize() + { + return ulong.sizeof; + } + + void swap(void *p1, void *p2) + { + ulong t; + + t = *cast(ulong *)p1; + *cast(ulong *)p1 = *cast(ulong *)p2; + *cast(ulong *)p2 = t; + } +} + diff --git a/lphobos/typeinfo/ti_void.d b/lphobos/typeinfo/ti_void.d new file mode 100644 index 00000000..b875f711 --- /dev/null +++ b/lphobos/typeinfo/ti_void.d @@ -0,0 +1,44 @@ + +// void + +module typeinfo.ti_void; + +class TypeInfo_v : TypeInfo +{ + char[] toString() { return "void"; } + + hash_t getHash(void *p) + { + assert(0); + } + + int equals(void *p1, void *p2) + { + return *cast(byte *)p1 == *cast(byte *)p2; + } + + int compare(void *p1, void *p2) + { + return *cast(byte *)p1 - *cast(byte *)p2; + } + + size_t tsize() + { + return void.sizeof; + } + + void swap(void *p1, void *p2) + { + byte t; + + t = *cast(byte *)p1; + *cast(byte *)p1 = *cast(byte *)p2; + *cast(byte *)p2 = t; + } + + uint flags() + { + return 1; + } +} + diff --git a/lphobos/typeinfo/ti_wchar.d b/lphobos/typeinfo/ti_wchar.d new file mode 100644 index 00000000..8d324ade --- /dev/null +++ b/lphobos/typeinfo/ti_wchar.d @@ -0,0 +1,44 @@ + +module typeinfo.ti_wchar; + + +class TypeInfo_u : TypeInfo +{ + char[] toString() { return "wchar"; } + + hash_t getHash(void *p) + { + return *cast(wchar *)p; + } + + int equals(void *p1, void *p2) + { + return *cast(wchar *)p1 == *cast(wchar *)p2; + } + + int compare(void *p1, void *p2) + { + return *cast(wchar *)p1 - *cast(wchar *)p2; + } + + size_t tsize() + { + return wchar.sizeof; + } + + void swap(void *p1, void *p2) + { + wchar t; + + t = *cast(wchar *)p1; + *cast(wchar *)p1 = *cast(wchar *)p2; + *cast(wchar *)p2 = t; + } + + void[] init() + { static wchar c; + + return (cast(wchar *)&c)[0 .. 1]; + } +} + diff --git a/lphobos/typeinfos.d b/lphobos/typeinfos.d new file mode 100644 index 00000000..1cb833df --- /dev/null +++ b/lphobos/typeinfos.d @@ -0,0 +1,20 @@ +module typeinfos; + +import +typeinfo.ti_byte, +typeinfo.ti_char, +typeinfo.ti_delegate, +typeinfo.ti_dchar, +typeinfo.ti_double, +typeinfo.ti_float, +typeinfo.ti_int, +typeinfo.ti_long, +typeinfo.ti_ptr, +typeinfo.ti_real, +typeinfo.ti_short, +typeinfo.ti_ubyte, +typeinfo.ti_uint, +typeinfo.ti_ulong, +typeinfo.ti_ushort, +typeinfo.ti_void, +typeinfo.ti_wchar; diff --git a/test/typeinfo2.d b/test/typeinfo2.d new file mode 100644 index 00000000..fb3d1f3f --- /dev/null +++ b/test/typeinfo2.d @@ -0,0 +1,14 @@ +module typeinfo2; + +void main() +{ + auto ti = typeid(float); + float f = 2.5; + hash_t fh = ti.getHash(&f); + assert(ti.next is null); + float g = 4.0; + ti.swap(&f,&g); + assert(f == 4.0 && g == 2.5); + assert(fh == *cast(uint*)(&g)); + assert(!ti.flags); +}