changeset 1383:f15a2d131ceb

Update !ClassInfo generation to use !RTTIBuilder, slight update of !RTTIBuilder .
author Tomas Lindquist Olsen <tomas.l.olsen gmail com>
date Sun, 17 May 2009 16:27:01 +0200
parents a0a4d4dac1a4
children 68a0e361fdce
files gen/classes.cpp gen/rttibuilder.cpp gen/rttibuilder.h
diffstat 3 files changed, 95 insertions(+), 103 deletions(-) [+]
line wrap: on
line diff
--- a/gen/classes.cpp	Sun May 17 15:20:58 2009 +0200
+++ b/gen/classes.cpp	Sun May 17 16:27:01 2009 +0200
@@ -5,17 +5,19 @@
 #include "init.h"
 #include "declaration.h"
 
+#include "gen/dvalue.h"
 #include "gen/irstate.h"
-#include "gen/tollvm.h"
-#include "gen/llvmhelpers.h"
+
 #include "gen/arrays.h"
-#include "gen/logger.h"
 #include "gen/classes.h"
-#include "gen/structs.h"
 #include "gen/functions.h"
+#include "gen/llvmhelpers.h"
+#include "gen/logger.h"
+#include "gen/nested.h"
+#include "gen/rttibuilder.h"
 #include "gen/runtime.h"
-#include "gen/dvalue.h"
-#include "gen/nested.h"
+#include "gen/structs.h"
+#include "gen/tollvm.h"
 #include "gen/utils.h"
 
 #include "ir/irstruct.h"
@@ -666,45 +668,36 @@
     Logger::println("DtoDefineClassInfo(%s)", cd->toChars());
     LOG_SCOPE;
 
-    IrStruct* ir = cd->ir.irStruct;
-
     assert(cd->type->ty == Tclass);
-
     TypeClass* cdty = (TypeClass*)cd->type;
 
-    // holds the list of initializers for llvm
-    std::vector<LLConstant*> inits;
+    IrStruct* ir = cd->ir.irStruct;
+    assert(ir);
 
     ClassDeclaration* cinfo = ClassDeclaration::classinfo;
-    cinfo->codegen(Type::sir);
+
+    // use the rtti builder
+    RTTIBuilder b(ClassDeclaration::classinfo);
 
     LLConstant* c;
 
     const LLType* voidPtr = getVoidPtrType();
     const LLType* voidPtrPtr = getPtrToType(voidPtr);
 
-    // own vtable
-    c = cinfo->ir.irStruct->getVtblSymbol();
-    inits.push_back(c);
-
-    // monitor
-    c = LLConstant::getNullValue(voidPtr);
-    inits.push_back(c);
-
     // byte[] init
     if (cd->isInterfaceDeclaration())
-        c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(voidPtr));
+    {
+        b.push_null_void_array();
+    }
     else
     {
-        c = DtoBitCast(ir->getInitSymbol(), voidPtr);
-        //Logger::cout() << *ir->constInit->getType() << std::endl;
-        size_t initsz = getTypePaddedSize(ir->getInitSymbol()->getType()->getContainedType(0));
-        c = DtoConstSlice(DtoConstSize_t(initsz), c);
+        const LLType* cd_type = cdty->irtype->getPA();
+        size_t initsz = getTypePaddedSize(cd_type);
+        b.push_void_array(initsz, ir->getInitSymbol());
     }
-    inits.push_back(c);
 
     // class name
-    // from dmd
+    // code from dmd
     char *name = cd->ident->toChars();
     size_t namelen = strlen(name);
     if (!(namelen > 9 && memcmp(name, "TypeInfo_", 9) == 0))
@@ -712,116 +705,78 @@
         name = cd->toPrettyChars();
         namelen = strlen(name);
     }
-    c = DtoConstString(name);
-    inits.push_back(c);
+    b.push_string(name);
 
     // vtbl array
     if (cd->isInterfaceDeclaration())
-        c = DtoConstSlice(DtoConstSize_t(0), LLConstant::getNullValue(getPtrToType(voidPtr)));
-    else {
+    {
+        b.push_array(0, getNullValue(voidPtrPtr));
+    }
+    else
+    {
         c = DtoBitCast(ir->getVtblSymbol(), voidPtrPtr);
-        c = DtoConstSlice(DtoConstSize_t(cd->vtbl.dim), c);
+        b.push_array(cd->vtbl.dim, c);
     }
-    inits.push_back(c);
 
     // interfaces array
-    c = ir->getClassInfoInterfaces();
-    inits.push_back(c);
+    b.push(ir->getClassInfoInterfaces());
 
     // base classinfo
     // interfaces never get a base , just the interfaces[]
-    if (cd->baseClass && !cd->isInterfaceDeclaration()) {
-        c = cd->baseClass->ir.irStruct->getClassInfoSymbol();
-        assert(c);
-        inits.push_back(c);
-    }
-    else {
-        // null
-        c = LLConstant::getNullValue(DtoType(cinfo->type));
-        inits.push_back(c);
-    }
+    if (cd->baseClass && !cd->isInterfaceDeclaration())
+        b.push_classinfo(cd->baseClass);
+    else
+        b.push_null(cinfo->type);
 
     // destructor
     if (cd->isInterfaceDeclaration())
-        c = LLConstant::getNullValue(voidPtr);
+        b.push_null_vp();
     else
-        c = build_class_dtor(cd);
-    inits.push_back(c);
+        b.push(build_class_dtor(cd));
 
     // invariant
     VarDeclaration* invVar = (VarDeclaration*)cinfo->fields.data[6];
-    const LLType* invTy = DtoType(invVar->type);
-    if (cd->inv)
-    {
-        cd->inv->codegen(Type::sir);
-        c = cd->inv->ir.irFunc->func;
-        c = DtoBitCast(c, invTy);
-    }
-    else
-        c = LLConstant::getNullValue(invTy);
-    inits.push_back(c);
+    b.push_funcptr(cd->inv, invVar->type);
 
     // uint flags
     if (cd->isInterfaceDeclaration())
-        c = DtoConstUint(0);
-    else {
-        unsigned flags = build_classinfo_flags(cd);
-        c = DtoConstUint(flags);
-    }
-    inits.push_back(c);
+        b.push_uint(0);
+    else
+        b.push_uint(build_classinfo_flags(cd));
 
     // deallocator
-    if (cd->aggDelete)
-    {
-        cd->aggDelete->codegen(Type::sir);
-        c = cd->aggDelete->ir.irFunc->func;
-        c = DtoBitCast(c, voidPtr);
-    }
-    else
-        c = LLConstant::getNullValue(voidPtr);
-    inits.push_back(c);
+    b.push_funcptr(cd->aggDelete, Type::tvoid->pointerTo());
 
     // offset typeinfo
     VarDeclaration* offTiVar = (VarDeclaration*)cinfo->fields.data[9];
-    const LLType* offTiTy = DtoType(offTiVar->type);
 
 #if GENERATE_OFFTI
 
     if (cd->isInterfaceDeclaration())
-        c = LLConstant::getNullValue(offTiTy);
+        b.push_null(offTiVar->type);
     else
-        c = build_offti_array(cd, offTiTy);
+        b.push(build_offti_array(cd, DtoType(offTiVar->type)));
 
 #else // GENERATE_OFFTI
 
-    c = LLConstant::getNullValue(offTiTy);
+    b.push_null(offTiVar->type);
 
 #endif // GENERATE_OFFTI
 
-    inits.push_back(c);
-
     // default constructor
-    if (cd->defaultCtor)
-    {
-        cd->defaultCtor->codegen(Type::sir);
-        c = isaConstant(cd->defaultCtor->ir.irFunc->func);
-        c = DtoBitCast(c, voidPtr);
-    }
-    else
-        c = LLConstant::getNullValue(voidPtr);
-    inits.push_back(c);
+    b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo());
 
     // typeinfo - since 1.045
-    inits.push_back(DtoTypeInfoOf(cd->type, true));
+    b.push_typeinfo(cd->type);
 
 #if DMDV2
 
     // xgetMembers
     VarDeclaration* xgetVar = (VarDeclaration*)cinfo->fields.data[11];
-    const LLType* xgetTy = DtoType(xgetVar->type);
 
     // FIXME: fill it out!
-    inits.push_back( LLConstant::getNullValue(xgetTy) );
+    b.push_null(xgetVar->type);
+
 #endif
 
     /*size_t n = inits.size();
@@ -831,14 +786,14 @@
     }*/
 
     // build the initializer
-    LLConstant* finalinit = llvm::ConstantStruct::get(inits);
+    LLConstant* finalinit = b.get_constant();
+
     //Logger::cout() << "built the classinfo initializer:\n" << *finalinit <<'\n';
     ir->constClassInfo = finalinit;
 
     // sanity check
     assert(finalinit->getType() == ir->classInfo->getType()->getContainedType(0) &&
         "__ClassZ initializer does not match the ClassInfo type");
-    
 
     // return initializer
     return finalinit;
--- a/gen/rttibuilder.cpp	Sun May 17 15:20:58 2009 +0200
+++ b/gen/rttibuilder.cpp	Sun May 17 16:27:01 2009 +0200
@@ -34,6 +34,11 @@
     inits.push_back(C);
 }
 
+void RTTIBuilder::push_null(Type* T)
+{
+    inits.push_back(getNullValue(DtoType(T)));
+}
+
 void RTTIBuilder::push_null_vp()
 {
     inits.push_back(getNullValue(getVoidPtrType()));
@@ -77,10 +82,7 @@
         CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname, gIR->module);
     G->setAlignment(valtype->alignsize());
 
-    size_t dim = getTypePaddedSize(CI->getType());
-    LLConstant* ptr = DtoBitCast(CI, DtoType(valtype->pointerTo()));
-
-    push_void_array(dim, G);
+    push_void_array(getTypePaddedSize(CI->getType()), G);
 }
 
 void RTTIBuilder::push_array(llvm::Constant * CI, uint64_t dim, Type* valtype, Dsymbol * mangle_sym)
@@ -94,10 +96,12 @@
         CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname, gIR->module);
     G->setAlignment(valtype->alignsize());
 
-    inits.push_back(DtoConstSlice(
-        DtoConstSize_t(dim),
-        DtoBitCast(CI, DtoType(valtype->pointerTo()))
-        ));
+    push_array(dim, DtoBitCast(G, DtoType(valtype->pointerTo())));
+}
+
+void RTTIBuilder::push_array(uint64_t dim, llvm::Constant * ptr)
+{
+    inits.push_back(DtoConstSlice(DtoConstSize_t(dim), ptr));
 }
 
 void RTTIBuilder::push_uint(unsigned u)
@@ -110,14 +114,20 @@
     inits.push_back(DtoConstSize_t(s));
 }
 
-void RTTIBuilder::push_funcptr(FuncDeclaration* fd)
+void RTTIBuilder::push_funcptr(FuncDeclaration* fd, Type* castto)
 {
     if (fd)
     {
         fd->codegen(Type::sir);
         LLConstant* F = fd->ir.irFunc->func;
+        if (castto)
+            F = DtoBitCast(F, DtoType(castto));
         inits.push_back(F);
     }
+    else if (castto)
+    {
+        push_null(castto);
+    }
     else
     {
         push_null_vp();
@@ -135,3 +145,9 @@
     // set the initializer
     isaGlobalVar(tid->value)->setInitializer(tiInit);
 }
+
+LLConstant* RTTIBuilder::get_constant()
+{
+    // just return the inititalizer
+    return llvm::ConstantStruct::get(&inits[0], inits.size(), false);
+}
--- a/gen/rttibuilder.h	Sun May 17 15:20:58 2009 +0200
+++ b/gen/rttibuilder.h	Sun May 17 16:27:01 2009 +0200
@@ -22,6 +22,7 @@
     RTTIBuilder(ClassDeclaration* base_class);
 
     void push(llvm::Constant* C);
+    void push_null(Type* T);
     void push_null_vp();
     void push_null_void_array();
     void push_uint(unsigned u);
@@ -29,13 +30,33 @@
     void push_string(const char* str);
     void push_typeinfo(Type* t);
     void push_classinfo(ClassDeclaration* cd);
-    void push_funcptr(FuncDeclaration* fd);
+
+    /// pushes the function pointer or a null void* if it cannot.
+    void push_funcptr(FuncDeclaration* fd, Type* castto = NULL);
+
+    /// pushes the array slice given.
+    void push_array(uint64_t dim, llvm::Constant * ptr);
+
+    /// pushes void[] slice, dim is used directly, ptr is cast to void* .
     void push_void_array(uint64_t dim, llvm::Constant* ptr);
+
+    /// pushes void[] slice with data.
+    /// CI is the constant initializer the array should point to, the length
+    /// and ptr are resolved automatically
     void push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* mangle_sym);
+
+    /// pushes valtype[] slice with data.
+    /// CI is the constant initializer that .ptr should point to
+    /// dim is .length member directly
+    /// valtype provides the D element type, .ptr is cast to valtype->pointerTo()
+    /// mangle_sym provides the mangle prefix for the symbol generated.
     void push_array(llvm::Constant* CI, uint64_t dim, Type* valtype, Dsymbol* mangle_sym);
 
     /// Creates the initializer constant and assigns it to the global.
     void finalize(IrGlobal* tid);
+
+    /// Creates the initializer constant and assigns it to the global.
+    llvm::Constant* get_constant();
 };
 
 #endif