From f6997cb60474a3cfd666b69d4ade3b1b77c85b8b Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Wed, 3 Jun 2009 02:28:48 +0200 Subject: [PATCH] D2: Applied function type from D1 frontend that got removed in D2, it's critical for member function type to be correct. Fixed a bunch of type discrepancies in druntime object.di vs. genobj.d . Disabled (#if 0) some potentally very large type dumps for -vv . Updated classinfo and typeinfo generation for D2, almost complete now. Added finer grained checks for vtbl type mismatching, aids debugging. --- dmd2/mtype.c | 28 +++++++++++++++++++++++++++- druntime/import/object.di | 2 +- druntime/src/compiler/ldc/genobj.d | 10 +++++----- gen/abi-x86-64.cpp | 3 ++- gen/abi.cpp | 2 ++ gen/arrays.cpp | 2 ++ gen/classes.cpp | 12 +++++++----- gen/llvmhelpers.cpp | 2 ++ gen/main.cpp | 2 +- gen/tocall.cpp | 4 ++++ gen/typinf.cpp | 15 +++++++++++---- ir/irclass.cpp | 18 ++++++++++++++++++ 12 files changed, 82 insertions(+), 18 deletions(-) diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 1175c527..cf035d46 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -3914,7 +3914,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) assert(0); } buf->writeByte(mc); -// Possible conflict from merge + if (ispure || isnothrow || isref) { if (ispure) @@ -3924,6 +3924,32 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) if (isref) buf->writestring("Nc"); } + + // LDC: if we're not producing a mangle string, add the this + // type to prevent merging different member function + if (!mangle && funcdecl) + { + if (funcdecl->needThis()) + { + AggregateDeclaration* ad = funcdecl->isMember2(); + buf->writeByte('M'); + ad->type->toDecoBuffer(buf, false); + } + /* BUG This causes problems with delegate types + On the other hand, the llvm type for nested functions *is* different + so not doing anything here may be lead to bugs! + A sane solution would be DtoType(Dsymbol)... + if (funcdecl->isNested()) + { + buf->writeByte('M'); + if (funcdecl->toParent2() && funcdecl->toParent2()->isFuncDeclaration()) + { + FuncDeclaration* fd = funcdecl->toParent2()->isFuncDeclaration(); + fd->type->toDecoBuffer(buf, false); + } + }*/ + } + // Write argument types Argument::argsToDecoBuffer(buf, parameters, mangle); //if (buf->data[buf->offset - 1] == '@') halt(); diff --git a/druntime/import/object.di b/druntime/import/object.di index 4e95aa8c..274496ac 100644 --- a/druntime/import/object.di +++ b/druntime/import/object.di @@ -153,7 +153,7 @@ class TypeInfo_Struct : TypeInfo string name; void[] m_init; - uint function(in void*) xtoHash; + hash_t function(in void*) xtoHash; equals_t function(in void*, in void*) xopEquals; int function(in void*, in void*) xopCmp; string function(in void*) xtoString; diff --git a/druntime/src/compiler/ldc/genobj.d b/druntime/src/compiler/ldc/genobj.d index 7881404d..52db245d 100644 --- a/druntime/src/compiler/ldc/genobj.d +++ b/druntime/src/compiler/ldc/genobj.d @@ -151,7 +151,7 @@ class ClassInfo : Object Interface[] interfaces; /// interfaces this class implements ClassInfo base; /// base class void* destructor; - void* classInvariant; + void(*classInvariant)(Object); uint flags; // 1: // is IUnknown or is derived from IUnknown // 2: // has no possible pointers into GC memory @@ -162,7 +162,7 @@ class ClassInfo : Object void* deallocator; OffsetTypeInfo[] offTi; void* defaultConstructor; // default Constructor - const(MemberInfo[]) function(in char[]) xgetMembers; + const(MemberInfo[]) function(string) xgetMembers; TypeInfo typeinfo; /** @@ -207,7 +207,7 @@ class ClassInfo : Object * Search for all members with the name 'name'. * If name[] is null, return all members. */ - const(MemberInfo[]) getMembers(in char[] name) + const(MemberInfo[]) getMembers(string name) { if (flags & 16 && xgetMembers) return xgetMembers(name); @@ -230,7 +230,7 @@ struct OffsetTypeInfo * Can be retrieved for any type using a * TypeidExpression. */ -class TypeInfo +class TypeInfo : Object { override hash_t toHash() { @@ -881,7 +881,7 @@ class TypeInfo_Struct : TypeInfo hash_t function(in void*) xtoHash; equals_t function(in void*, in void*) xopEquals; int function(in void*, in void*) xopCmp; - char[] function(in void*) xtoString; + string function(in void*) xtoString; uint m_flags; diff --git a/gen/abi-x86-64.cpp b/gen/abi-x86-64.cpp index fa8b983a..6b520bed 100644 --- a/gen/abi-x86-64.cpp +++ b/gen/abi-x86-64.cpp @@ -735,9 +735,10 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) { Type* ty = arg.type->toBasetype(); fixup(arg); - +#if 0 if (Logger::enabled()) Logger::cout() << "New arg type: " << *arg.ltype << '\n'; +#endif } } } diff --git a/gen/abi.cpp b/gen/abi.cpp index 130e49f1..8e7c76f4 100644 --- a/gen/abi.cpp +++ b/gen/abi.cpp @@ -385,8 +385,10 @@ struct IntrinsicABI : TargetABI if (ty->ty == Tstruct) fixup(arg); +#if 0 if (Logger::enabled()) Logger::cout() << "New arg type: " << *arg.ltype << '\n'; +#endif } } }; diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 7818952e..6d98462a 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -701,8 +701,10 @@ static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue // DtoTypeInfoOf only does declare, not enough in this case :/ t->vtinfo->codegen(Type::sir); +#if 0 if (Logger::enabled()) Logger::cout() << "typeinfo decl: " << *tival << '\n'; +#endif args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2))); } diff --git a/gen/classes.cpp b/gen/classes.cpp index ca537419..96789509 100644 --- a/gen/classes.cpp +++ b/gen/classes.cpp @@ -486,12 +486,14 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd) src = DtoBitCast(src, st); // gep to the index +#if 0 if (Logger::enabled()) { Logger::cout() << "src2: " << *src << '\n'; Logger::cout() << "index: " << field->index << '\n'; Logger::cout() << "srctype: " << *src->getType() << '\n'; } +#endif LLValue* val = DtoGEPi(src, 0, field->index); // do we need to offset further? (union area) @@ -678,12 +680,12 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) // ClassInfo *base; // base class // void *destructor; // void *invariant; // class invariant -// version(D_Version2) -// void *xgetMembers; // uint flags; // void *deallocator; // OffsetTypeInfo[] offTi; // void *defaultConstructor; +// version(D_Version2) +// const(MemberInfo[]) function(string) xgetMembers; // TypeInfo typeinfo; // since dmd 1.045 // } @@ -798,9 +800,6 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) // default constructor b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo()); - // typeinfo - since 1.045 - b.push_typeinfo(cd->type); - #if DMDV2 // xgetMembers @@ -811,6 +810,9 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd) #endif + // typeinfo - since 1.045 + b.push_typeinfo(cd->type); + /*size_t n = inits.size(); for (size_t i=0; isetInitializer(initVal); diff --git a/gen/main.cpp b/gen/main.cpp index 02e404d6..3fe866a4 100644 --- a/gen/main.cpp +++ b/gen/main.cpp @@ -565,7 +565,7 @@ int main(int argc, char** argv) // unsupported else { - error("target triple '%s' is not supported", global.params.targetTriple); + error("target '%s' is not yet supported", global.params.targetTriple); fatal(); } diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 62b373d8..73e11a2e 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -432,18 +432,22 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* assert(fnarg); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); +#if 0 if (Logger::enabled()) { Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n'; Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n'; } +#endif // give the ABI a say LLValue* arg = tf->fty.putParam(argval->getType(), i, argval); +#if 0 if (Logger::enabled()) { Logger::cout() << "Argument after ABI: " << *arg << '\n'; Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n'; } +#endif int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i; diff --git a/gen/typinf.cpp b/gen/typinf.cpp index 829ed993..18c8b526 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -646,16 +646,23 @@ void TypeInfoStructDeclaration::llvmDefine() b.push_uint(hasptrs); #if DMDV2 - // just (void*)null for now + // FIXME: just emit nulls for now + + ClassDeclaration* tscd = Type::typeinfostruct; + + assert(tscd->fields.dim == 10); // const(MemberInfo[]) function(in char[]) xgetMembers; - b.push_null_vp(); + VarDeclaration* xgetMembers = (VarDeclaration*)tscd->fields.data[7]; + b.push_null(xgetMembers->type); //void function(void*) xdtor; - b.push_null_vp(); + VarDeclaration* xdtor = (VarDeclaration*)tscd->fields.data[8]; + b.push_null(xdtor->type); //void function(void*) xpostblit; - b.push_null_vp(); + VarDeclaration* xpostblit = (VarDeclaration*)tscd->fields.data[9]; + b.push_null(xpostblit->type); #endif // finish diff --git a/ir/irclass.cpp b/ir/irclass.cpp index bfe8f003..6ea0a062 100644 --- a/ir/irclass.cpp +++ b/ir/irclass.cpp @@ -178,6 +178,24 @@ LLConstant * IrStruct::getVtblInit() IF_LOG Logger::cout() << "constVtbl type: " << *constVtbl->getType() << std::endl; IF_LOG Logger::cout() << "vtbl type: " << *type->irtype->isClass()->getVtbl() << std::endl; #endif + +#if 1 + + size_t nc = constants.size(); + const LLType* vtblTy = type->irtype->isClass()->getVtbl(); + for (size_t i = 0; i < nc; ++i) + { + if (constVtbl->getOperand(i)->getType() != vtblTy->getContainedType(i)) + { + Logger::cout() << "type mismatch for entry # " << i << " in vtbl initializer" << std::endl; + + constVtbl->getOperand(i)->dump(); + vtblTy->getContainedType(i)->dump(gIR->module); + } + } + +#endif + assert(constVtbl->getType() == type->irtype->isClass()->getVtbl() && "vtbl initializer type mismatch");