# HG changeset patch # User Tomas Lindquist Olsen # Date 1242570421 -7200 # Node ID f15a2d131ceb06c75518a2d8574fb21844a6ca04 # Parent a0a4d4dac1a41c93289cd9c99ea97e45ff84f160 Update !ClassInfo generation to use !RTTIBuilder, slight update of !RTTIBuilder . diff -r a0a4d4dac1a4 -r f15a2d131ceb gen/classes.cpp --- 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 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; diff -r a0a4d4dac1a4 -r f15a2d131ceb gen/rttibuilder.cpp --- 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); +} diff -r a0a4d4dac1a4 -r f15a2d131ceb gen/rttibuilder.h --- 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