changeset 1463:a5526b7a5ae6

D2: Applied function type from D1 frontend that got removed in D2, it's critical for member function type to be correct. Fixed a bunch of type discrepancies in druntime object.di vs. genobj.d . Disabled (#if 0) some potentally very large type dumps for -vv . Updated classinfo and typeinfo generation for D2, almost complete now. Added finer grained checks for vtbl type mismatching, aids debugging.
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Wed, 03 Jun 2009 02:28:48 +0200
parents f0423003caa6
children 93644700a0b3
files dmd2/mtype.c druntime/import/object.di druntime/src/compiler/ldc/genobj.d gen/abi-x86-64.cpp gen/abi.cpp gen/arrays.cpp gen/classes.cpp gen/llvmhelpers.cpp gen/main.cpp gen/tocall.cpp gen/typinf.cpp ir/irclass.cpp
diffstat 12 files changed, 82 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/dmd2/mtype.c	Tue Jun 02 20:28:53 2009 +0200
+++ b/dmd2/mtype.c	Wed Jun 03 02:28:48 2009 +0200
@@ -3914,7 +3914,7 @@
 	    assert(0);
     }
     buf->writeByte(mc);
-// Possible conflict from merge
+
     if (ispure || isnothrow || isref)
     {
 	if (ispure)
@@ -3924,6 +3924,32 @@
 	if (isref)
 	    buf->writestring("Nc");
     }
+
+    // LDC: if we're not producing a mangle string, add the this
+    // type to prevent merging different member function
+    if (!mangle && funcdecl)
+    {
+        if (funcdecl->needThis())
+        {
+            AggregateDeclaration* ad = funcdecl->isMember2();
+            buf->writeByte('M');
+            ad->type->toDecoBuffer(buf, false);
+        }
+        /* BUG This causes problems with delegate types
+           On the other hand, the llvm type for nested functions *is* different
+           so not doing anything here may be lead to bugs!
+           A sane solution would be DtoType(Dsymbol)...
+        if (funcdecl->isNested())
+        {
+            buf->writeByte('M');
+            if (funcdecl->toParent2() && funcdecl->toParent2()->isFuncDeclaration())
+            {
+                FuncDeclaration* fd = funcdecl->toParent2()->isFuncDeclaration();
+                fd->type->toDecoBuffer(buf, false);
+            }
+        }*/
+    }
+
     // Write argument types
     Argument::argsToDecoBuffer(buf, parameters, mangle);
     //if (buf->data[buf->offset - 1] == '@') halt();
--- a/druntime/import/object.di	Tue Jun 02 20:28:53 2009 +0200
+++ b/druntime/import/object.di	Wed Jun 03 02:28:48 2009 +0200
@@ -153,7 +153,7 @@
     string name;
     void[] m_init;
 
-    uint function(in void*)               xtoHash;
+    hash_t function(in void*)               xtoHash;
     equals_t function(in void*, in void*) xopEquals;
     int function(in void*, in void*)      xopCmp;
     string function(in void*)             xtoString;
--- a/druntime/src/compiler/ldc/genobj.d	Tue Jun 02 20:28:53 2009 +0200
+++ b/druntime/src/compiler/ldc/genobj.d	Wed Jun 03 02:28:48 2009 +0200
@@ -151,7 +151,7 @@
     Interface[] interfaces;     /// interfaces this class implements
     ClassInfo   base;           /// base class
     void*       destructor;
-    void*	 classInvariant;
+    void(*classInvariant)(Object);
     uint        flags;
     //  1:                      // is IUnknown or is derived from IUnknown
     //  2:                      // has no possible pointers into GC memory
@@ -162,7 +162,7 @@
     void*       deallocator;
     OffsetTypeInfo[] offTi;
     void*	 defaultConstructor;   // default Constructor
-    const(MemberInfo[]) function(in char[]) xgetMembers;
+    const(MemberInfo[]) function(string) xgetMembers;
     TypeInfo typeinfo;
 
     /**
@@ -207,7 +207,7 @@
      * Search for all members with the name 'name'.
      * If name[] is null, return all members.
      */
-    const(MemberInfo[]) getMembers(in char[] name)
+    const(MemberInfo[]) getMembers(string name)
     {
         if (flags & 16 && xgetMembers)
             return xgetMembers(name);
@@ -230,7 +230,7 @@
  * Can be retrieved for any type using a
  * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
  */
-class TypeInfo
+class TypeInfo : Object
 {
     override hash_t toHash()
     {
@@ -881,7 +881,7 @@
     hash_t   function(in void*)           xtoHash;
     equals_t function(in void*, in void*) xopEquals;
     int      function(in void*, in void*) xopCmp;
-    char[]   function(in void*)           xtoString;
+    string   function(in void*)           xtoString;
 
     uint m_flags;
 
--- a/gen/abi-x86-64.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/abi-x86-64.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -735,9 +735,10 @@
             Type* ty = arg.type->toBasetype();
             
             fixup(arg);
-            
+#if 0
             if (Logger::enabled())
                 Logger::cout() << "New arg type: " << *arg.ltype << '\n';
+#endif
         }
     }
 }
--- a/gen/abi.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/abi.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -385,8 +385,10 @@
             if (ty->ty == Tstruct)
                 fixup(arg);
 
+#if 0
             if (Logger::enabled())
                 Logger::cout() << "New arg type: " << *arg.ltype << '\n';
+#endif
         }
     }
 };
--- a/gen/arrays.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/arrays.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -701,8 +701,10 @@
         // DtoTypeInfoOf only does declare, not enough in this case :/
         t->vtinfo->codegen(Type::sir);
 
+#if 0
         if (Logger::enabled())
             Logger::cout() << "typeinfo decl: " << *tival << '\n';
+#endif
 
         args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2)));
     }
--- a/gen/classes.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/classes.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -486,12 +486,14 @@
     src = DtoBitCast(src, st);
 
     // gep to the index
+#if 0
     if (Logger::enabled())
     {
         Logger::cout() << "src2: " << *src << '\n';
         Logger::cout() << "index: " << field->index << '\n';
         Logger::cout() << "srctype: " << *src->getType() << '\n';
     }
+#endif
     LLValue* val = DtoGEPi(src, 0, field->index);
 
     // do we need to offset further? (union area)
@@ -678,12 +680,12 @@
 //         ClassInfo *base;        // base class
 //         void *destructor;
 //         void *invariant;        // class invariant
-//         version(D_Version2)
-//         	void *xgetMembers; 
 //         uint flags;
 //         void *deallocator;
 //         OffsetTypeInfo[] offTi;
 //         void *defaultConstructor;
+//         version(D_Version2)
+//              const(MemberInfo[]) function(string) xgetMembers;
 //         TypeInfo typeinfo; // since dmd 1.045
 //        }
 
@@ -798,9 +800,6 @@
     // default constructor
     b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo());
 
-    // typeinfo - since 1.045
-    b.push_typeinfo(cd->type);
-
 #if DMDV2
 
     // xgetMembers
@@ -811,6 +810,9 @@
 
 #endif
 
+    // typeinfo - since 1.045
+    b.push_typeinfo(cd->type);
+
     /*size_t n = inits.size();
     for (size_t i=0; i<n; ++i)
     {
--- a/gen/llvmhelpers.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/llvmhelpers.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -848,7 +848,9 @@
         {
             Logger::println("setting initializer");
             Logger::cout() << "global: " << *gvar << '\n';
+#if 0
             Logger::cout() << "init:   " << *initVal << '\n';
+#endif
         }
 
         gvar->setInitializer(initVal);
--- a/gen/main.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/main.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -565,7 +565,7 @@
     // unsupported
     else
     {
-        error("target triple '%s' is not supported", global.params.targetTriple);
+        error("target '%s' is not yet supported", global.params.targetTriple);
         fatal();
     }
 
--- a/gen/tocall.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/tocall.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -432,18 +432,22 @@
             assert(fnarg);
             DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
 
+#if 0
             if (Logger::enabled()) {
                 Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n';
                 Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n';
             }
+#endif
 
             // give the ABI a say
             LLValue* arg = tf->fty.putParam(argval->getType(), i, argval);
 
+#if 0
             if (Logger::enabled()) {
                 Logger::cout() << "Argument after ABI: " << *arg << '\n';
                 Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n';
             }
+#endif
 
             int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i;
 
--- a/gen/typinf.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/gen/typinf.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -646,16 +646,23 @@
     b.push_uint(hasptrs);
 
 #if DMDV2
-    // just (void*)null for now
+    // FIXME: just emit nulls for now
+
+    ClassDeclaration* tscd = Type::typeinfostruct;
+
+    assert(tscd->fields.dim == 10);
 
     // const(MemberInfo[]) function(in char[]) xgetMembers;
-    b.push_null_vp();
+    VarDeclaration* xgetMembers = (VarDeclaration*)tscd->fields.data[7];
+    b.push_null(xgetMembers->type);
 
     //void function(void*)                    xdtor;
-    b.push_null_vp();
+    VarDeclaration* xdtor = (VarDeclaration*)tscd->fields.data[8];
+    b.push_null(xdtor->type);
 
     //void function(void*)                    xpostblit;
-    b.push_null_vp();
+    VarDeclaration* xpostblit = (VarDeclaration*)tscd->fields.data[9];
+    b.push_null(xpostblit->type);
 #endif
 
     // finish
--- a/ir/irclass.cpp	Tue Jun 02 20:28:53 2009 +0200
+++ b/ir/irclass.cpp	Wed Jun 03 02:28:48 2009 +0200
@@ -178,6 +178,24 @@
    IF_LOG Logger::cout() << "constVtbl type: " << *constVtbl->getType() << std::endl;
    IF_LOG Logger::cout() << "vtbl type: " << *type->irtype->isClass()->getVtbl() << std::endl;
 #endif
+
+#if 1
+
+    size_t nc = constants.size();
+    const LLType* vtblTy = type->irtype->isClass()->getVtbl();
+    for (size_t i = 0; i < nc; ++i)
+    {
+        if (constVtbl->getOperand(i)->getType() != vtblTy->getContainedType(i))
+        {
+            Logger::cout() << "type mismatch for entry # " << i << " in vtbl initializer" << std::endl;
+
+            constVtbl->getOperand(i)->dump();
+            vtblTy->getContainedType(i)->dump(gIR->module);
+        }
+    }
+
+#endif
+
     assert(constVtbl->getType() == type->irtype->isClass()->getVtbl() &&
         "vtbl initializer type mismatch");