changeset 53:06ccc817acd4 trunk

[svn r57] Added most basic TypeInfo (rebuild lphobos). Fixed some SymOffExp bugs. Added another typeinfo test case.
author lindquist
date Tue, 23 Oct 2007 07:16:02 +0200
parents 0c77619e803b
children 28e99b04a132
files gen/toir.c gen/tollvm.c gen/tollvm.h lphobos/typeinfo/ti_dchar.d lphobos/typeinfo/ti_delegate.d lphobos/typeinfo/ti_double.d lphobos/typeinfo/ti_float.d lphobos/typeinfo/ti_long.d lphobos/typeinfo/ti_real.d lphobos/typeinfo/ti_ulong.d lphobos/typeinfo/ti_void.d lphobos/typeinfo/ti_wchar.d lphobos/typeinfos.d test/typeinfo2.d
diffstat 14 files changed, 533 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/gen/toir.c	Tue Oct 23 05:55:12 2007 +0200
+++ b/gen/toir.c	Tue Oct 23 07:16:02 2007 +0200
@@ -1058,7 +1058,7 @@
         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 @@
         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* 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 @@
             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 @@
             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 @@
     {
         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");
--- a/gen/tollvm.c	Tue Oct 23 05:55:12 2007 +0200
+++ b/gen/tollvm.c	Tue Oct 23 07:16:02 2007 +0200
@@ -610,7 +610,22 @@
     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;
+}
 
 //////////////////////////////////////////////////////////////////////////////////////////
 
--- a/gen/tollvm.h	Tue Oct 23 05:55:12 2007 +0200
+++ b/gen/tollvm.h	Tue Oct 23 07:16:02 2007 +0200
@@ -18,6 +18,7 @@
 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);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_dchar.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_delegate.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_double.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_float.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_long.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_real.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_ulong.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_void.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfo/ti_wchar.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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];
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lphobos/typeinfos.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/typeinfo2.d	Tue Oct 23 07:16:02 2007 +0200
@@ -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);
+}