# HG changeset patch # User Tomas Lindquist Olsen # Date 1242522655 -7200 # Node ID e630ff79e10d08f1f6958d2f88ec05636c7ce284 # Parent 551b01341728d5a1f8bd7b73382d3abf23ea939f Cleaned up TypeInfo generation, still need to do TypeInfo_Struct/Tuple. Eventually do ClassInfo and ModuleInfo as well using same interface. diff -r 551b01341728 -r e630ff79e10d gen/rttibuilder.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/rttibuilder.cpp Sun May 17 03:10:55 2009 +0200 @@ -0,0 +1,93 @@ +#include "gen/llvm.h" + +#include "aggregate.h" +#include "mtype.h" + +#include "gen/arrays.h" +#include "gen/irstate.h" +#include "gen/linkage.h" +#include "gen/llvmhelpers.h" +#include "gen/rttibuilder.h" +#include "gen/tollvm.h" + +#include "ir/irstruct.h" + +TypeInfoBuilder::TypeInfoBuilder(ClassDeclaration* base_class) +{ + // make sure the base typeinfo class has been processed + base_class->codegen(Type::sir); + + base = base_class; + basetype = (TypeClass*)base->type; + + baseir = base->ir.irStruct; + assert(baseir && "no IrStruct for TypeInfo base class"); + + // just start with adding the vtbl + inits.push_back(baseir->getVtblSymbol()); + // and monitor + push_null_vp(); +} + +void TypeInfoBuilder::push(llvm::Constant* C) +{ + inits.push_back(C); +} + +void TypeInfoBuilder::push_null_vp() +{ + inits.push_back(getNullValue(getVoidPtrType())); +} + +void TypeInfoBuilder::push_typeinfo(Type* t) +{ + inits.push_back(DtoTypeInfoOf(t, true)); +} + +void TypeInfoBuilder::push_classinfo(ClassDeclaration* cd) +{ + inits.push_back(cd->ir.irStruct->getClassInfoSymbol()); +} + +void TypeInfoBuilder::push_string(const char* str) +{ + inits.push_back(DtoConstString(str)); +} + +void TypeInfoBuilder::push_null_void_array() +{ + const llvm::Type* T = DtoType(Type::tvoid->arrayOf()); + inits.push_back(getNullValue(T)); +} + +void TypeInfoBuilder::push_void_array(size_t dim, llvm::Constant* ptr) +{ + inits.push_back(DtoConstSlice( + DtoConstSize_t(dim), + DtoBitCast(ptr, getVoidPtrType()))); +} + +void TypeInfoBuilder::push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym) +{ + std::string initname(sym->mangle()); + initname.append("13__defaultInitZ"); + + LLGlobalVariable* G = new llvm::GlobalVariable( + CI->getType(), true, TYPEINFO_LINKAGE_TYPE, CI, initname, gIR->module); + G->setAlignment(valtype->alignsize()); + + size_t dim = getTypePaddedSize(CI->getType()); + push_void_array(dim, G); +} + +void TypeInfoBuilder::finalize(IrGlobal* tid) +{ + // create the inititalizer + LLConstant* tiInit = llvm::ConstantStruct::get(&inits[0], inits.size(), false); + + // refine global type + llvm::cast(tid->type.get())->refineAbstractTypeTo(tiInit->getType()); + + // set the initializer + isaGlobalVar(tid->value)->setInitializer(tiInit); +} diff -r 551b01341728 -r e630ff79e10d gen/rttibuilder.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gen/rttibuilder.h Sun May 17 03:10:55 2009 +0200 @@ -0,0 +1,34 @@ +#ifndef __LDC_GEN_RTTIBUILDER_H__ +#define __LDC_GEN_RTTIBUILDER_H__ + +#include "llvm/Constant.h" +#include "llvm/ADT/SmallVector.h" + +struct ClassDeclaration; +struct TypeClass; + +struct IrStruct; + +struct TypeInfoBuilder +{ + ClassDeclaration* base; + TypeClass* basetype; + IrStruct* baseir; + + // 10 is enough for any D1 typeinfo + llvm::SmallVector inits; + + TypeInfoBuilder(ClassDeclaration* base_class); + + void push(llvm::Constant* C); + void push_null_vp(); + void push_typeinfo(Type* t); + void push_classinfo(ClassDeclaration* cd); + void push_string(const char* str); + void push_null_void_array(); + void push_void_array(size_t dim, llvm::Constant* ptr); + void push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym); + void finalize(IrGlobal* tid); +}; + +#endif diff -r 551b01341728 -r e630ff79e10d gen/typinf.cpp --- a/gen/typinf.cpp Sun May 17 02:22:21 2009 +0200 +++ b/gen/typinf.cpp Sun May 17 03:10:55 2009 +0200 @@ -41,6 +41,7 @@ #include "gen/classes.h" #include "gen/linkage.h" #include "gen/metadata.h" +#include "gen/rttibuilder.h" #include "ir/irvar.h" #include "ir/irtype.h" @@ -271,11 +272,11 @@ ////////////////////////////////////////////////////////////////////////////// // MAGIC PLACE +// (wut?) ////////////////////////////////////////////////////////////////////////////// void DtoResolveTypeInfo(TypeInfoDeclaration* tid); void DtoDeclareTypeInfo(TypeInfoDeclaration* tid); -void DtoConstInitTypeInfo(TypeInfoDeclaration* tid); void TypeInfoDeclaration::codegen(Ir*) { @@ -334,37 +335,27 @@ Logger::println("DtoDeclareTypeInfo(%s)", tid->toChars()); LOG_SCOPE; - IrGlobal* irg = tid->ir.irGlobal; - - std::string mangled(tid->mangle()); + if (Logger::enabled()) + { + std::string mangled(tid->mangle()); + Logger::println("type = '%s'", tid->tinfo->toChars()); + Logger::println("typeinfo mangle: %s", mangled.c_str()); + } - Logger::println("type = '%s'", tid->tinfo->toChars()); - Logger::println("typeinfo mangle: %s", mangled.c_str()); - + IrGlobal* irg = tid->ir.irGlobal; assert(irg->value != NULL); // this is a declaration of a builtin __initZ var if (tid->tinfo->builtinTypeInfo()) { // fixup the global - const llvm::Type* rty = Type::typeinfo->type->irtype->getPA().get(); + const llvm::Type* rty = Type::typeinfo->type->irtype->getPA(); llvm::cast(irg->type.get())->refineAbstractTypeTo(rty); LLGlobalVariable* g = isaGlobalVar(irg->value); g->setLinkage(llvm::GlobalValue::ExternalLinkage); return; } - // custom typedef - DtoConstInitTypeInfo(tid); -} - -void DtoConstInitTypeInfo(TypeInfoDeclaration* tid) -{ - if (tid->ir.initialized) return; - tid->ir.initialized = true; - - Logger::println("DtoConstInitTypeInfo(%s)", tid->toChars()); - LOG_SCOPE; - + // define custom typedef tid->llvmDefine(); } @@ -372,7 +363,7 @@ void TypeInfoDeclaration::llvmDefine() { - assert(0 && "TypeInfoDeclaration::llvmDeclare"); + assert(0 && "cannot generate generic typeinfo"); } /* ========================================================================= */ @@ -382,54 +373,35 @@ Logger::println("TypeInfoTypedefDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - ClassDeclaration* base = Type::typeinfotypedef; - base->codegen(Type::sir); - - // vtbl - std::vector sinits; - sinits.push_back(base->ir.irStruct->getVtblSymbol()); - - // monitor - sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty))); + TypeInfoBuilder b(Type::typeinfotypedef); assert(tinfo->ty == Ttypedef); TypeTypedef *tc = (TypeTypedef *)tinfo; TypedefDeclaration *sd = tc->sym; // TypeInfo base - sd->basetype = sd->basetype->merge(); // DMD does this! - LLConstant* castbase = DtoTypeInfoOf(sd->basetype, true); - sinits.push_back(castbase); + sd->basetype = sd->basetype->merge(); // dmd does it ... why? + b.push_typeinfo(sd->basetype); // char[] name - char *name = sd->toPrettyChars(); - sinits.push_back(DtoConstString(name)); + b.push_string(sd->toPrettyChars()); // void[] init - const LLPointerType* initpt = getPtrToType(LLType::Int8Ty); - if (tinfo->isZeroInit() || !sd->init) // 0 initializer, or the same as the base type + // emit null array if we should use the basetype, or if the basetype + // uses default initialization. + if (!sd->init || tinfo->isZeroInit(0)) { - sinits.push_back(DtoConstSlice(DtoConstSize_t(0), getNullPtr(initpt))); + b.push_null_void_array(); } + // otherwise emit a void[] with the default initializer else { - LLConstant* ci = DtoConstInitializer(sd->loc, sd->basetype, sd->init); - std::string ciname(sd->mangle()); - ciname.append("__init"); - llvm::GlobalVariable* civar = new llvm::GlobalVariable(DtoType(sd->basetype),true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module); - LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt); - size_t cisize = getTypeStoreSize(DtoType(sd->basetype)); - sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast)); + LLConstant* C = DtoConstInitializer(sd->loc, sd->basetype, sd->init); + b.push_void_array(C, sd->basetype, sd); } - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); - - // refine global type - llvm::cast(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -439,86 +411,35 @@ Logger::println("TypeInfoEnumDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - ClassDeclaration* base = Type::typeinfoenum; - base->codegen(Type::sir); - - // vtbl - std::vector sinits; - sinits.push_back(base->ir.irStruct->getVtblSymbol()); - - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); + TypeInfoBuilder b(Type::typeinfoenum); assert(tinfo->ty == Tenum); TypeEnum *tc = (TypeEnum *)tinfo; EnumDeclaration *sd = tc->sym; // TypeInfo base - LLConstant* castbase = DtoTypeInfoOf(sd->memtype, true); - sinits.push_back(castbase); + b.push_typeinfo(sd->memtype); // char[] name - char *name = sd->toPrettyChars(); - sinits.push_back(DtoConstString(name)); + b.push_string(sd->toPrettyChars()); // void[] init - const LLPointerType* initpt = getPtrToType(LLType::Int8Ty); - if (tinfo->isZeroInit() || !sd->defaultval) // 0 initializer, or the same as the base type + // emit void[] with the default initialier, the array is null if the default + // initializer is zero + if (!sd->defaultval || tinfo->isZeroInit(0)) { - sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); + b.push_null_void_array(); } + // otherwise emit a void[] with the default initializer else { - #if DMDV2 - assert(0 && "initializer not implemented"); - #else const LLType* memty = DtoType(sd->memtype); - LLConstant* ci = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned()); - std::string ciname(sd->mangle()); - ciname.append("__init"); - llvm::GlobalVariable* civar = new llvm::GlobalVariable(memty,true,llvm::GlobalValue::InternalLinkage,ci,ciname,gIR->module); - LLConstant* cicast = llvm::ConstantExpr::getBitCast(civar, initpt); - size_t cisize = getTypeStoreSize(memty); - sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast)); - #endif + LLConstant* C = llvm::ConstantInt::get(memty, sd->defaultval, !sd->memtype->isunsigned()); + b.push_void_array(C, sd->memtype, sd); } - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); - - // refine global type - llvm::cast(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); -} - -/* ========================================================================= */ - -static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd) -{ - ClassDeclaration* base = cd; - base->codegen(Type::sir); - - // vtbl - std::vector sinits; - sinits.push_back(base->ir.irStruct->getVtblSymbol()); - - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); - - // TypeInfo base - LLConstant* castbase = DtoTypeInfoOf(basetype, true); - sinits.push_back(castbase); - - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); - - // refine global type - llvm::cast(tid->ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(tid->ir.irGlobal->value)->setInitializer(tiInit); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -528,10 +449,11 @@ Logger::println("TypeInfoPointerDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - assert(tinfo->ty == Tpointer); - TypePointer *tc = (TypePointer *)tinfo; - - LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfopointer); + TypeInfoBuilder b(Type::typeinfopointer); + // TypeInfo base + b.push_typeinfo(tinfo->nextOf()); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -541,10 +463,11 @@ Logger::println("TypeInfoArrayDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - assert(tinfo->ty == Tarray); - TypeDArray *tc = (TypeDArray *)tinfo; - - LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfoarray); + TypeInfoBuilder b(Type::typeinfoarray); + // TypeInfo base + b.push_typeinfo(tinfo->nextOf()); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -554,39 +477,19 @@ Logger::println("TypeInfoStaticArrayDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - // init typeinfo class - ClassDeclaration* base = Type::typeinfostaticarray; - base->codegen(Type::sir); - - // get type of typeinfo class - const LLStructType* stype = isaStruct(base->type->irtype->getPA().get()); + assert(tinfo->ty == Tsarray); + TypeSArray *tc = (TypeSArray *)tinfo; - // initializer vector - std::vector sinits; - // first is always the vtable - sinits.push_back(base->ir.irStruct->getVtblSymbol()); - - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); + TypeInfoBuilder b(Type::typeinfostaticarray); // value typeinfo - assert(tinfo->ty == Tsarray); - TypeSArray *tc = (TypeSArray *)tinfo; - LLConstant* castbase = DtoTypeInfoOf(tc->next, true); - assert(castbase->getType() == stype->getElementType(2)); - sinits.push_back(castbase); + b.push_typeinfo(tc->nextOf()); // length - sinits.push_back(DtoConstSize_t(tc->dim->toInteger())); - - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); + b.push(DtoConstSize_t((size_t)tc->dim->toUInteger())); - // refine global type - llvm::cast(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -596,38 +499,19 @@ Logger::println("TypeInfoAssociativeArrayDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - // init typeinfo class - ClassDeclaration* base = Type::typeinfoassociativearray; - base->codegen(Type::sir); - - // initializer vector - std::vector sinits; - // first is always the vtable - sinits.push_back(base->ir.irStruct->getVtblSymbol()); - - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); - - // get type assert(tinfo->ty == Taarray); TypeAArray *tc = (TypeAArray *)tinfo; + TypeInfoBuilder b(Type::typeinfoassociativearray); + // value typeinfo - LLConstant* castbase = DtoTypeInfoOf(tc->next, true); - sinits.push_back(castbase); + b.push_typeinfo(tc->nextOf()); // key typeinfo - castbase = DtoTypeInfoOf(tc->index, true); - sinits.push_back(castbase); - - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); + b.push_typeinfo(tc->index); - // refine global type - llvm::cast(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -637,10 +521,11 @@ Logger::println("TypeInfoFunctionDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - assert(tinfo->ty == Tfunction); - TypeFunction *tc = (TypeFunction *)tinfo; - - LLVM_D_Define_TypeInfoBase(tc->next, this, Type::typeinfofunction); + TypeInfoBuilder b(Type::typeinfofunction); + // TypeInfo base + b.push_typeinfo(tinfo->nextOf()); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -651,9 +536,13 @@ LOG_SCOPE; assert(tinfo->ty == Tdelegate); - TypeDelegate *tc = (TypeDelegate *)tinfo; + Type* ret_type = tinfo->nextOf()->nextOf(); - LLVM_D_Define_TypeInfoBase(tc->nextOf()->nextOf(), this, Type::typeinfodelegate); + TypeInfoBuilder b(Type::typeinfodelegate); + // TypeInfo base + b.push_typeinfo(ret_type); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -874,30 +763,13 @@ TypeClass *tc = (TypeClass *)tinfo; tc->sym->codegen(Type::sir); - // init typeinfo class - ClassDeclaration* base = Type::typeinfoclass; - assert(base); - base->codegen(Type::sir); - - // initializer vector - std::vector sinits; - // first is always the vtable - sinits.push_back(base->ir.irStruct->getVtblSymbol()); + TypeInfoBuilder b(Type::typeinfoclass); - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); - - // get classinfo - sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol()); + // TypeInfo base + b.push_classinfo(tc->sym); - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); - - // refine global type - llvm::cast(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -912,33 +784,13 @@ TypeClass *tc = (TypeClass *)tinfo; tc->sym->codegen(Type::sir); - // init typeinfo class - ClassDeclaration* base = Type::typeinfointerface; - assert(base); - base->codegen(Type::sir); - - // get type of typeinfo class - const LLStructType* stype = isaStruct(base->type->irtype->getPA()); - - // initializer vector - std::vector sinits; - // first is always the vtable - sinits.push_back(base->ir.irStruct->getVtblSymbol()); + TypeInfoBuilder b(Type::typeinfointerface); - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); - - // get classinfo - sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol()); + // TypeInfo base + b.push_classinfo(tc->sym); - // create the inititalizer - LLConstant* tiInit = llvm::ConstantStruct::get(sinits); - - // refine global type - llvm::cast(ir.irGlobal->type.get())->refineAbstractTypeTo(tiInit->getType()); - - // set the initializer - isaGlobalVar(ir.irGlobal->value)->setInitializer(tiInit); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -1018,10 +870,11 @@ Logger::println("TypeInfoConstDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - Type *tm = tinfo->mutableOf(); - tm = tm->merge(); - - LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoconst); + TypeInfoBuilder b(Type::typeinfoconst); + // TypeInfo base + b.push_typeinfo(tinfo->mutableOf()->merge()); + // finish + b.finalize(ir.irGlobal); } /* ========================================================================= */ @@ -1031,10 +884,11 @@ Logger::println("TypeInfoInvariantDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; - Type *tm = tinfo->mutableOf(); - tm = tm->merge(); - - LLVM_D_Define_TypeInfoBase(tm, this, Type::typeinfoinvariant); + TypeInfoBuilder b(Type::typeinfoinvariant); + // TypeInfo base + b.push_typeinfo(tinfo->mutableOf()->merge()); + // finish + b.finalize(ir.irGlobal); } #endif