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.
This commit is contained in:
Tomas Lindquist Olsen 2009-06-03 02:28:48 +02:00
parent 2cd4d15be1
commit f6997cb604
12 changed files with 82 additions and 18 deletions

View file

@ -3914,7 +3914,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
assert(0); assert(0);
} }
buf->writeByte(mc); buf->writeByte(mc);
// Possible conflict from merge
if (ispure || isnothrow || isref) if (ispure || isnothrow || isref)
{ {
if (ispure) if (ispure)
@ -3924,6 +3924,32 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle)
if (isref) if (isref)
buf->writestring("Nc"); 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 // Write argument types
Argument::argsToDecoBuffer(buf, parameters, mangle); Argument::argsToDecoBuffer(buf, parameters, mangle);
//if (buf->data[buf->offset - 1] == '@') halt(); //if (buf->data[buf->offset - 1] == '@') halt();

View file

@ -153,7 +153,7 @@ class TypeInfo_Struct : TypeInfo
string name; string name;
void[] m_init; void[] m_init;
uint function(in void*) xtoHash; hash_t function(in void*) xtoHash;
equals_t function(in void*, in void*) xopEquals; equals_t function(in void*, in void*) xopEquals;
int function(in void*, in void*) xopCmp; int function(in void*, in void*) xopCmp;
string function(in void*) xtoString; string function(in void*) xtoString;

View file

@ -151,7 +151,7 @@ class ClassInfo : Object
Interface[] interfaces; /// interfaces this class implements Interface[] interfaces; /// interfaces this class implements
ClassInfo base; /// base class ClassInfo base; /// base class
void* destructor; void* destructor;
void* classInvariant; void(*classInvariant)(Object);
uint flags; uint flags;
// 1: // is IUnknown or is derived from IUnknown // 1: // is IUnknown or is derived from IUnknown
// 2: // has no possible pointers into GC memory // 2: // has no possible pointers into GC memory
@ -162,7 +162,7 @@ class ClassInfo : Object
void* deallocator; void* deallocator;
OffsetTypeInfo[] offTi; OffsetTypeInfo[] offTi;
void* defaultConstructor; // default Constructor void* defaultConstructor; // default Constructor
const(MemberInfo[]) function(in char[]) xgetMembers; const(MemberInfo[]) function(string) xgetMembers;
TypeInfo typeinfo; TypeInfo typeinfo;
/** /**
@ -207,7 +207,7 @@ class ClassInfo : Object
* Search for all members with the name 'name'. * Search for all members with the name 'name'.
* If name[] is null, return all members. * If name[] is null, return all members.
*/ */
const(MemberInfo[]) getMembers(in char[] name) const(MemberInfo[]) getMembers(string name)
{ {
if (flags & 16 && xgetMembers) if (flags & 16 && xgetMembers)
return xgetMembers(name); return xgetMembers(name);
@ -230,7 +230,7 @@ struct OffsetTypeInfo
* Can be retrieved for any type using a * Can be retrieved for any type using a
* <a href="../expression.html#typeidexpression">TypeidExpression</a>. * <a href="../expression.html#typeidexpression">TypeidExpression</a>.
*/ */
class TypeInfo class TypeInfo : Object
{ {
override hash_t toHash() override hash_t toHash()
{ {
@ -881,7 +881,7 @@ class TypeInfo_Struct : TypeInfo
hash_t function(in void*) xtoHash; hash_t function(in void*) xtoHash;
equals_t function(in void*, in void*) xopEquals; equals_t function(in void*, in void*) xopEquals;
int function(in void*, in void*) xopCmp; int function(in void*, in void*) xopCmp;
char[] function(in void*) xtoString; string function(in void*) xtoString;
uint m_flags; uint m_flags;

View file

@ -735,9 +735,10 @@ void X86_64TargetABI::rewriteFunctionType(TypeFunction* tf) {
Type* ty = arg.type->toBasetype(); Type* ty = arg.type->toBasetype();
fixup(arg); fixup(arg);
#if 0
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "New arg type: " << *arg.ltype << '\n'; Logger::cout() << "New arg type: " << *arg.ltype << '\n';
#endif
} }
} }
} }

View file

@ -385,8 +385,10 @@ struct IntrinsicABI : TargetABI
if (ty->ty == Tstruct) if (ty->ty == Tstruct)
fixup(arg); fixup(arg);
#if 0
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "New arg type: " << *arg.ltype << '\n'; Logger::cout() << "New arg type: " << *arg.ltype << '\n';
#endif
} }
} }
}; };

View file

@ -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 :/ // DtoTypeInfoOf only does declare, not enough in this case :/
t->vtinfo->codegen(Type::sir); t->vtinfo->codegen(Type::sir);
#if 0
if (Logger::enabled()) if (Logger::enabled())
Logger::cout() << "typeinfo decl: " << *tival << '\n'; Logger::cout() << "typeinfo decl: " << *tival << '\n';
#endif
args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2))); args.push_back(DtoBitCast(tival, fn->getFunctionType()->getParamType(2)));
} }

View file

@ -486,12 +486,14 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
src = DtoBitCast(src, st); src = DtoBitCast(src, st);
// gep to the index // gep to the index
#if 0
if (Logger::enabled()) if (Logger::enabled())
{ {
Logger::cout() << "src2: " << *src << '\n'; Logger::cout() << "src2: " << *src << '\n';
Logger::cout() << "index: " << field->index << '\n'; Logger::cout() << "index: " << field->index << '\n';
Logger::cout() << "srctype: " << *src->getType() << '\n'; Logger::cout() << "srctype: " << *src->getType() << '\n';
} }
#endif
LLValue* val = DtoGEPi(src, 0, field->index); LLValue* val = DtoGEPi(src, 0, field->index);
// do we need to offset further? (union area) // do we need to offset further? (union area)
@ -678,12 +680,12 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
// ClassInfo *base; // base class // ClassInfo *base; // base class
// void *destructor; // void *destructor;
// void *invariant; // class invariant // void *invariant; // class invariant
// version(D_Version2)
// void *xgetMembers;
// uint flags; // uint flags;
// void *deallocator; // void *deallocator;
// OffsetTypeInfo[] offTi; // OffsetTypeInfo[] offTi;
// void *defaultConstructor; // void *defaultConstructor;
// version(D_Version2)
// const(MemberInfo[]) function(string) xgetMembers;
// TypeInfo typeinfo; // since dmd 1.045 // TypeInfo typeinfo; // since dmd 1.045
// } // }
@ -798,9 +800,6 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
// default constructor // default constructor
b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo()); b.push_funcptr(cd->defaultCtor, Type::tvoid->pointerTo());
// typeinfo - since 1.045
b.push_typeinfo(cd->type);
#if DMDV2 #if DMDV2
// xgetMembers // xgetMembers
@ -811,6 +810,9 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
#endif #endif
// typeinfo - since 1.045
b.push_typeinfo(cd->type);
/*size_t n = inits.size(); /*size_t n = inits.size();
for (size_t i=0; i<n; ++i) for (size_t i=0; i<n; ++i)
{ {

View file

@ -848,7 +848,9 @@ void DtoConstInitGlobal(VarDeclaration* vd)
{ {
Logger::println("setting initializer"); Logger::println("setting initializer");
Logger::cout() << "global: " << *gvar << '\n'; Logger::cout() << "global: " << *gvar << '\n';
#if 0
Logger::cout() << "init: " << *initVal << '\n'; Logger::cout() << "init: " << *initVal << '\n';
#endif
} }
gvar->setInitializer(initVal); gvar->setInitializer(initVal);

View file

@ -565,7 +565,7 @@ int main(int argc, char** argv)
// unsupported // unsupported
else else
{ {
error("target triple '%s' is not supported", global.params.targetTriple); error("target '%s' is not yet supported", global.params.targetTriple);
fatal(); fatal();
} }

View file

@ -432,18 +432,22 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
assert(fnarg); assert(fnarg);
DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]);
#if 0
if (Logger::enabled()) { if (Logger::enabled()) {
Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n'; Logger::cout() << "Argument before ABI: " << *argval->getRVal() << '\n';
Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n'; Logger::cout() << "Argument type before ABI: " << *DtoType(argval->getType()) << '\n';
} }
#endif
// give the ABI a say // give the ABI a say
LLValue* arg = tf->fty.putParam(argval->getType(), i, argval); LLValue* arg = tf->fty.putParam(argval->getType(), i, argval);
#if 0
if (Logger::enabled()) { if (Logger::enabled()) {
Logger::cout() << "Argument after ABI: " << *arg << '\n'; Logger::cout() << "Argument after ABI: " << *arg << '\n';
Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n'; Logger::cout() << "Argument type after ABI: " << *arg->getType() << '\n';
} }
#endif
int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i; int j = tf->fty.reverseParams ? beg + n - i - 1 : beg + i;

View file

@ -646,16 +646,23 @@ void TypeInfoStructDeclaration::llvmDefine()
b.push_uint(hasptrs); b.push_uint(hasptrs);
#if DMDV2 #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; // 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; //void function(void*) xdtor;
b.push_null_vp(); VarDeclaration* xdtor = (VarDeclaration*)tscd->fields.data[8];
b.push_null(xdtor->type);
//void function(void*) xpostblit; //void function(void*) xpostblit;
b.push_null_vp(); VarDeclaration* xpostblit = (VarDeclaration*)tscd->fields.data[9];
b.push_null(xpostblit->type);
#endif #endif
// finish // finish

View file

@ -178,6 +178,24 @@ LLConstant * IrStruct::getVtblInit()
IF_LOG Logger::cout() << "constVtbl type: " << *constVtbl->getType() << std::endl; IF_LOG Logger::cout() << "constVtbl type: " << *constVtbl->getType() << std::endl;
IF_LOG Logger::cout() << "vtbl type: " << *type->irtype->isClass()->getVtbl() << std::endl; IF_LOG Logger::cout() << "vtbl type: " << *type->irtype->isClass()->getVtbl() << std::endl;
#endif #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() && assert(constVtbl->getType() == type->irtype->isClass()->getVtbl() &&
"vtbl initializer type mismatch"); "vtbl initializer type mismatch");