# HG changeset patch # User Tomas Lindquist Olsen # Date 1242528070 -7200 # Node ID 63f4afd010360c9afa68ac0d37011234ac0a4df0 # Parent e630ff79e10d08f1f6958d2f88ec05636c7ce284 Cleaned up TypeInfo_Struct. Fixed problem with DtoConstSize_t taking a size_t argument, this is not enough for cross compiling from 32bit host to a 64bit target. It now takes uint64_t. There's probably a lot of similar case around to code ... diff -r e630ff79e10d -r 63f4afd01036 gen/rttibuilder.cpp --- a/gen/rttibuilder.cpp Sun May 17 03:10:55 2009 +0200 +++ b/gen/rttibuilder.cpp Sun May 17 04:41:10 2009 +0200 @@ -80,6 +80,30 @@ push_void_array(dim, G); } +void TypeInfoBuilder::push_uint(unsigned u) +{ + inits.push_back(DtoConstUint(u)); +} + +void TypeInfoBuilder::push_size(uint64_t s) +{ + inits.push_back(DtoConstSize_t(s)); +} + +void TypeInfoBuilder::push_funcptr(FuncDeclaration* fd) +{ + if (fd) + { + fd->codegen(Type::sir); + LLConstant* F = fd->ir.irFunc->func; + inits.push_back(F); + } + else + { + push_null_vp(); + } +} + void TypeInfoBuilder::finalize(IrGlobal* tid) { // create the inititalizer diff -r e630ff79e10d -r 63f4afd01036 gen/rttibuilder.h --- a/gen/rttibuilder.h Sun May 17 03:10:55 2009 +0200 +++ b/gen/rttibuilder.h Sun May 17 04:41:10 2009 +0200 @@ -22,12 +22,17 @@ void push(llvm::Constant* C); void push_null_vp(); + void push_null_void_array(); + void push_uint(unsigned u); + void push_size(uint64_t s); + void push_string(const char* str); void push_typeinfo(Type* t); void push_classinfo(ClassDeclaration* cd); - void push_string(const char* str); - void push_null_void_array(); + void push_funcptr(FuncDeclaration* fd); void push_void_array(size_t dim, llvm::Constant* ptr); void push_void_array(llvm::Constant* CI, Type* valtype, Dsymbol* sym); + + /// Creates the initializer constant and assigns it to the global. void finalize(IrGlobal* tid); }; diff -r e630ff79e10d -r 63f4afd01036 gen/tollvm.cpp --- a/gen/tollvm.cpp Sun May 17 03:10:55 2009 +0200 +++ b/gen/tollvm.cpp Sun May 17 04:41:10 2009 +0200 @@ -489,7 +489,7 @@ ////////////////////////////////////////////////////////////////////////////////////////// -llvm::ConstantInt* DtoConstSize_t(size_t i) +llvm::ConstantInt* DtoConstSize_t(uint64_t i) { return llvm::ConstantInt::get(DtoSize_t(), i, false); } diff -r e630ff79e10d -r 63f4afd01036 gen/tollvm.h --- a/gen/tollvm.h Sun May 17 03:10:55 2009 +0200 +++ b/gen/tollvm.h Sun May 17 04:41:10 2009 +0200 @@ -50,7 +50,7 @@ LLValue* DtoGEPi(LLValue* ptr, unsigned i0, unsigned i1, const char* var=NULL, llvm::BasicBlock* bb=NULL); // to constant helpers -LLConstantInt* DtoConstSize_t(size_t); +LLConstantInt* DtoConstSize_t(uint64_t); LLConstantInt* DtoConstUint(unsigned i); LLConstantInt* DtoConstInt(int i); LLConstantInt* DtoConstUbyte(unsigned char i); diff -r e630ff79e10d -r 63f4afd01036 gen/typinf.cpp --- a/gen/typinf.cpp Sun May 17 03:10:55 2009 +0200 +++ b/gen/typinf.cpp Sun May 17 04:41:10 2009 +0200 @@ -547,6 +547,21 @@ /* ========================================================================= */ +static FuncDeclaration* find_method_overload(AggregateDeclaration* ad, Identifier* id, TypeFunction* tf, Module* mod) +{ + Dsymbol *s = search_function(ad, id); + FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL; + if (fdx) + { + FuncDeclaration *fd = fdx->overloadExactMatch(tf, mod); + if (fd) + { + return fd; + } + } + return NULL; +} + void TypeInfoStructDeclaration::llvmDefine() { Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars()); @@ -565,190 +580,82 @@ } sd->codegen(Type::sir); - - ClassDeclaration* base = Type::typeinfostruct; - base->codegen(Type::sir); - - const LLStructType* stype = isaStruct(base->type->irtype->getPA()); + IrStruct* irstruct = sd->ir.irStruct; - // vtbl - std::vector sinits; - sinits.push_back(base->ir.irStruct->getVtblSymbol()); - - // monitor - sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); + TypeInfoBuilder b(Type::typeinfostruct); // char[] name - char *name = sd->toPrettyChars(); - sinits.push_back(DtoConstString(name)); - //Logger::println("************** A"); - assert(sinits.back()->getType() == stype->getElementType(2)); + b.push_string(sd->toPrettyChars()); // void[] init - const LLPointerType* initpt = getPtrToType(LLType::Int8Ty); -#if 0 - // the implementation of TypeInfo_Struct uses this to determine size. :/ - if (sd->zeroInit) // 0 initializer, or the same as the base type - { - sinits.push_back(DtoConstSlice(DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt))); - } - else -#endif - { - size_t cisize = getTypeStoreSize(tc->irtype->getPA().get()); - LLConstant* cicast = llvm::ConstantExpr::getBitCast(sd->ir.irStruct->getInitSymbol(), initpt); - sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast)); - } + // never emit a null array, even for zero initialized typeinfo + // the size() method uses this array! + size_t init_size = getTypeStoreSize(tc->irtype->getPA()); + b.push_void_array(init_size, irstruct->getInitSymbol()); // 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); + 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); } -#if 0 - TypeFunction *tfeq; + // this one takes a parameter, so we need to build a new one each time + // to get the right type. can we avoid this? + TypeFunction *tfeqptr; { - 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 - - //Logger::println("************** B"); - const LLPointerType* ptty = isaPointer(stype->getElementType(4)); - assert(ptty); - - s = search_function(sd, Id::tohash); - fdx = s ? s->isFuncDeclaration() : NULL; - if (fdx) - { - fd = fdx->overloadExactMatch(tftohash, getModule()); - if (fd) { - fd->codegen(Type::sir); - assert(fd->ir.irFunc->func != 0); - LLConstant* c = isaConstant(fd->ir.irFunc->func); - 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)); + 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); } - s = search_function(sd, Id::eq); - fdx = s ? s->isFuncDeclaration() : NULL; - for (int i = 0; i < 2; i++) - { - //Logger::println("************** C %d", i); - ptty = isaPointer(stype->getElementType(5+i)); - if (fdx) - { - fd = fdx->overloadExactMatch(tfeqptr, getModule()); - if (fd) { - fd->codegen(Type::sir); - assert(fd->ir.irFunc->func != 0); - LLConstant* c = isaConstant(fd->ir.irFunc->func); - 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)); - } + // well use this module for all overload lookups + Module *gm = getModule(); + + // toHash + FuncDeclaration* fd = find_method_overload(sd, Id::tohash, tftohash, gm); + b.push_funcptr(fd); - s = search_function(sd, Id::cmp); - fdx = s ? s->isFuncDeclaration() : NULL; - } + // opEquals + fd = find_method_overload(sd, Id::eq, tfeqptr, gm); + b.push_funcptr(fd); - //Logger::println("************** D"); - ptty = isaPointer(stype->getElementType(7)); - s = search_function(sd, Id::tostring); - fdx = s ? s->isFuncDeclaration() : NULL; - if (fdx) - { - fd = fdx->overloadExactMatch(tftostring, getModule()); - if (fd) { - fd->codegen(Type::sir); - assert(fd->ir.irFunc->func != 0); - LLConstant* c = isaConstant(fd->ir.irFunc->func); - 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)); - } + // opCmp + fd = find_method_overload(sd, Id::cmp, tfeqptr, gm); + b.push_funcptr(fd); + + // toString + fd = find_method_overload(sd, Id::tostring, tftostring, gm); + b.push_funcptr(fd); // uint m_flags; - sinits.push_back(DtoConstUint(tc->hasPointers())); + unsigned hasptrs = tc->hasPointers() ? 1 : 0; + b.push_uint(hasptrs); #if DMDV2 + // just (void*)null for now // const(MemberInfo[]) function(in char[]) xgetMembers; - sinits.push_back(LLConstant::getNullValue(stype->getElementType(sinits.size()))); + b.push_null_vp(); //void function(void*) xdtor; - sinits.push_back(LLConstant::getNullValue(stype->getElementType(sinits.size()))); + b.push_null_vp(); //void function(void*) xpostblit; - sinits.push_back(LLConstant::getNullValue(stype->getElementType(sinits.size()))); - + b.push_null_vp(); #endif - // 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); } /* ========================================================================= */