mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-08 20:06:03 +03:00
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.
This commit is contained in:
parent
2cd4d15be1
commit
f6997cb604
12 changed files with 82 additions and 18 deletions
28
dmd2/mtype.c
28
dmd2/mtype.c
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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");
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue