diff gen/typinf.c @ 72:d7e764e62462 trunk

[svn r76] Fixed: TypeInfo for structs. Fixed: PostExp was unable to allocate storage for parameters. Fixed: Many types of functions and delegates were broken. Misc cleanups.
author lindquist
date Mon, 29 Oct 2007 03:28:12 +0100
parents 53d3086b5ad3
children b706170e24a9
line wrap: on
line diff
--- a/gen/typinf.c	Sun Oct 28 19:48:57 2007 +0100
+++ b/gen/typinf.c	Mon Oct 29 03:28:12 2007 +0100
@@ -263,12 +263,6 @@
 void TypeInfoDeclaration::toDt(dt_t **pdt)
 {
     assert(0 && "TypeInfoDeclaration");
-
-    /*
-    //printf("TypeInfoDeclaration::toDt() %s\n", toChars());
-    dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
-    dtdword(pdt, 0);                // monitor
-    */
 }
 
 /* ========================================================================= */
@@ -316,7 +310,6 @@
     if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type
     {
         sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
-        //sinits.push_back(initZ->getOperand(3));
     }
     else
     {
@@ -334,43 +327,6 @@
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module);
 
     llvmValue = gvar;
-
-    /*
-    dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
-    dtdword(pdt, 0);                // monitor
-
-    assert(tinfo->ty == Ttypedef);
-
-    TypeTypedef *tc = (TypeTypedef *)tinfo;
-    TypedefDeclaration *sd = tc->sym;
-    //printf("basetype = %s\n", sd->basetype->toChars());
-
-    // Put out:
-    //  TypeInfo base;
-    //  char[] name;
-    //  void[] m_init;
-
-    sd->basetype = sd->basetype->merge();
-    sd->basetype->getTypeInfo(NULL);        // generate vtinfo
-    assert(sd->basetype->vtinfo);
-    dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr);   // TypeInfo for basetype
-
-    char *name = sd->toPrettyChars();
-    size_t namelen = strlen(name);
-    dtdword(pdt, namelen);
-    dtabytes(pdt, TYnptr, 0, namelen + 1, name);
-
-    // void[] init;
-    if (tinfo->isZeroInit() || !sd->init)
-    {   // 0 initializer, or the same as the base type
-    dtdword(pdt, 0);    // init.length
-    dtdword(pdt, 0);    // init.ptr
-    }
-    else
-    {
-    dtdword(pdt, sd->type->size()); // init.length
-    dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
-    */
 }
 
 /* ========================================================================= */
@@ -418,7 +374,6 @@
     if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type
     {
         sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
-        //sinits.push_back(initZ->getOperand(3));
     }
     else
     {
@@ -437,44 +392,6 @@
     llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module);
 
     llvmValue = gvar;
-
-    /*
-
-    //printf("TypeInfoEnumDeclaration::toDt()\n");
-    dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
-    dtdword(pdt, 0);                // monitor
-
-    assert(tinfo->ty == Tenum);
-
-    TypeEnum *tc = (TypeEnum *)tinfo;
-    EnumDeclaration *sd = tc->sym;
-
-    // Put out:
-    //  TypeInfo base;
-    //  char[] name;
-    //  void[] m_init;
-
-    sd->memtype->getTypeInfo(NULL);
-    dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr);    // TypeInfo for enum members
-
-    char *name = sd->toPrettyChars();
-    size_t namelen = strlen(name);
-    dtdword(pdt, namelen);
-    dtabytes(pdt, TYnptr, 0, namelen + 1, name);
-
-    // void[] init;
-    if (tinfo->isZeroInit() || !sd->defaultval)
-    {   // 0 initializer, or the same as the base type
-    dtdword(pdt, 0);    // init.length
-    dtdword(pdt, 0);    // init.ptr
-    }
-    else
-    {
-    dtdword(pdt, sd->type->size()); // init.length
-    dtxoff(pdt, sd->toInitializer(), 0, TYnptr);    // init.ptr
-    }
-
-    */
 }
 
 /* ========================================================================= */
@@ -610,7 +527,166 @@
 
 void TypeInfoStructDeclaration::toDt(dt_t **pdt)
 {
-    assert(0 && "TypeInfoStructDeclaration");
+    Logger::println("TypeInfoStructDeclaration::toDt() %s", toChars());
+    LOG_SCOPE;
+
+    assert(tinfo->ty == Tstruct);
+    TypeStruct *tc = (TypeStruct *)tinfo;
+    StructDeclaration *sd = tc->sym;
+
+    ClassDeclaration* base = Type::typeinfostruct;
+    base->toObjFile();
+
+    const llvm::StructType* stype = llvm::cast<llvm::StructType>(base->llvmType);
+
+    std::vector<llvm::Constant*> sinits;
+    sinits.push_back(base->llvmVtbl);
+
+    // char[] name
+    char *name = sd->toPrettyChars();
+    sinits.push_back(LLVM_DtoConstString(name));
+    assert(sinits.back()->getType() == stype->getElementType(1));
+
+    // void[] init
+    const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty);
+    if (sd->zeroInit) // 0 initializer, or the same as the base type
+    {
+        sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
+    }
+    else
+    {
+        assert(sd->llvmInitZ);
+        size_t cisize = gTargetData->getTypeSize(tc->llvmType);
+        llvm::Constant* cicast = llvm::ConstantExpr::getBitCast(tc->llvmInit, initpt);
+        sinits.push_back(LLVM_DtoConstSlice(LLVM_DtoConstSize_t(cisize), cicast));
+    }
+
+    // toX functions ground work
+    FuncDeclaration *fd;
+    FuncDeclaration *fdx;
+    TypeFunction *tf;
+    Type *ta;
+    Dsymbol *s;
+
+    static TypeFunction *tftohash;
+    static TypeFunction *tftostring;
+
+    if (!tftohash)
+    {
+    Scope sc;
+
+    tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
+    tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
+
+    tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
+    tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
+    }
+
+    TypeFunction *tfeqptr;
+    {
+    Scope sc;
+    Arguments *arguments = new Arguments;
+    Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
+
+    arguments->push(arg);
+    tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
+    tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
+    }
+
+#if 0
+    TypeFunction *tfeq;
+    {
+    Scope sc;
+    Array *arguments = new Array;
+    Argument *arg = new Argument(In, tc, NULL, NULL);
+
+    arguments->push(arg);
+    tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
+    tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
+    }
+#endif
+
+    const llvm::PointerType* ptty = llvm::cast<llvm::PointerType>(stype->getElementType(3));
+
+    s = search_function(sd, Id::tohash);
+    fdx = s ? s->isFuncDeclaration() : NULL;
+    if (fdx)
+    {
+        fd = fdx->overloadExactMatch(tftohash);
+        if (fd) {
+            assert(fd->llvmValue != 0);
+            llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
+            assert(c);
+            c = llvm::ConstantExpr::getBitCast(c, ptty);
+            sinits.push_back(c);
+        }
+        else {
+            //fdx->error("must be declared as extern (D) uint toHash()");
+            sinits.push_back(llvm::ConstantPointerNull::get(ptty));
+        }
+    }
+    else {
+        sinits.push_back(llvm::ConstantPointerNull::get(ptty));
+    }
+
+    s = search_function(sd, Id::eq);
+    fdx = s ? s->isFuncDeclaration() : NULL;
+    for (int i = 0; i < 2; i++)
+    {
+        ptty = llvm::cast<llvm::PointerType>(stype->getElementType(4+i));
+        if (fdx)
+        {
+            fd = fdx->overloadExactMatch(tfeqptr);
+            if (fd) {
+                assert(fd->llvmValue != 0);
+                llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
+                assert(c);
+                c = llvm::ConstantExpr::getBitCast(c, ptty);
+                sinits.push_back(c);
+            }
+            else {
+                //fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
+                sinits.push_back(llvm::ConstantPointerNull::get(ptty));
+            }
+        }
+        else {
+            sinits.push_back(llvm::ConstantPointerNull::get(ptty));
+        }
+
+        s = search_function(sd, Id::cmp);
+        fdx = s ? s->isFuncDeclaration() : NULL;
+    }
+
+    ptty = llvm::cast<llvm::PointerType>(stype->getElementType(6));
+    s = search_function(sd, Id::tostring);
+    fdx = s ? s->isFuncDeclaration() : NULL;
+    if (fdx)
+    {
+        fd = fdx->overloadExactMatch(tftostring);
+        if (fd) {
+            assert(fd->llvmValue != 0);
+            llvm::Constant* c = llvm::cast_or_null<llvm::Constant>(fd->llvmValue);
+            assert(c);
+            c = llvm::ConstantExpr::getBitCast(c, ptty);
+            sinits.push_back(c);
+        }
+        else {
+            //fdx->error("must be declared as extern (D) char[] toString()");
+            sinits.push_back(llvm::ConstantPointerNull::get(ptty));
+        }
+    }
+    else {
+        sinits.push_back(llvm::ConstantPointerNull::get(ptty));
+    }
+
+    // uint m_flags;
+    sinits.push_back(LLVM_DtoConstUint(tc->hasPointers()));
+
+    // create the symbol
+    llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
+    llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module);
+
+    llvmValue = gvar;
 
     /*
     //printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());