# HG changeset patch # User Christian Kamm # Date 1217320192 -7200 # Node ID fa91b03d9cd7d34888d79e862ade4fa0c2324fa8 # Parent 1c65b5477eaa27135c5560563934157796fe700d Error message for calling a function with a missing 'this' arg. diff -r 1c65b5477eaa -r fa91b03d9cd7 gen/classes.cpp --- a/gen/classes.cpp Mon Jul 28 21:37:47 2008 +0200 +++ b/gen/classes.cpp Tue Jul 29 10:29:52 2008 +0200 @@ -798,7 +798,7 @@ { DtoForceDeclareDsymbol(newexp->allocator); DFuncValue dfn(newexp->allocator, newexp->allocator->ir.irFunc->func); - DValue* res = DtoCallFunction(NULL, &dfn, newexp->newargs); + DValue* res = DtoCallFunction(newexp->loc, NULL, &dfn, newexp->newargs); mem = DtoBitCast(res->getRVal(), DtoType(tc), ".newclass_custom"); } // default allocator @@ -852,7 +852,7 @@ assert(newexp->arguments != NULL); DtoForceDeclareDsymbol(newexp->member); DFuncValue dfn(newexp->member, newexp->member->ir.irFunc->func, mem); - return DtoCallFunction(tc, &dfn, newexp->arguments); + return DtoCallFunction(newexp->loc, tc, &dfn, newexp->arguments); } // return default constructed class diff -r 1c65b5477eaa -r fa91b03d9cd7 gen/llvmhelpers.h --- a/gen/llvmhelpers.h Mon Jul 28 21:37:47 2008 +0200 +++ b/gen/llvmhelpers.h Tue Jul 29 10:29:52 2008 +0200 @@ -118,6 +118,6 @@ void DtoBuildDVarArgList(std::vector& args, llvm::PAListPtr& palist, TypeFunction* tf, Expressions* arguments, size_t argidx); /// -DValue* DtoCallFunction(Type* resulttype, DValue* fnval, Expressions* arguments); +DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* arguments); #endif diff -r 1c65b5477eaa -r fa91b03d9cd7 gen/tocall.cpp --- a/gen/tocall.cpp Mon Jul 28 21:37:47 2008 +0200 +++ b/gen/tocall.cpp Tue Jul 29 10:29:52 2008 +0200 @@ -180,7 +180,7 @@ } -DValue* DtoCallFunction(Type* resulttype, DValue* fnval, Expressions* arguments) +DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* arguments) { // the callee D type Type* calleeType = fnval->getType(); @@ -224,31 +224,40 @@ args.push_back(retvar); } - // then comes the 'this' argument - if (dfnval && dfnval->vthis) - { - LLValue* thisarg = DtoBitCast(dfnval->vthis, argiter->get()); - ++argiter; - args.push_back(thisarg); - } - // or a delegate context arg - else if (delegatecall) + // then comes a context argument... + if(usesthis || delegatecall || nestedcall) { - LLValue* ctxarg = DtoLoad(DtoGEPi(fnval->getRVal(), 0,0)); - assert(ctxarg->getType() == argiter->get()); - ++argiter; - args.push_back(ctxarg); - } - // or a nested function context arg - else if (nestedcall) - { - LLValue* contextptr = DtoNestedContext(dfnval->func->toParent2()->isFuncDeclaration()); - if (!contextptr) - contextptr = getNullPtr(getVoidPtrType()); + // ... which can be a 'this' argument + if (dfnval && dfnval->vthis) + { + LLValue* thisarg = DtoBitCast(dfnval->vthis, argiter->get()); + ++argiter; + args.push_back(thisarg); + } + // ... or a delegate context arg + else if (delegatecall) + { + LLValue* ctxarg = DtoLoad(DtoGEPi(fnval->getRVal(), 0,0)); + assert(ctxarg->getType() == argiter->get()); + ++argiter; + args.push_back(ctxarg); + } + // ... or a nested function context arg + else if (nestedcall) + { + LLValue* contextptr = DtoNestedContext(dfnval->func->toParent2()->isFuncDeclaration()); + if (!contextptr) + contextptr = getNullPtr(getVoidPtrType()); + else + contextptr = DtoBitCast(contextptr, getVoidPtrType()); + ++argiter; + args.push_back(contextptr); + } else - contextptr = DtoBitCast(contextptr, getVoidPtrType()); - ++argiter; - args.push_back(contextptr); + { + error(loc, "Context argument required but none given"); + fatal(); + } } // handle the rest of the arguments based on param passing style diff -r 1c65b5477eaa -r fa91b03d9cd7 gen/toir.cpp --- a/gen/toir.cpp Mon Jul 28 21:37:47 2008 +0200 +++ b/gen/toir.cpp Tue Jul 29 10:29:52 2008 +0200 @@ -886,7 +886,7 @@ } } - return DtoCallFunction(type, fnval, arguments); + return DtoCallFunction(loc, type, fnval, arguments); } //////////////////////////////////////////////////////////////////////////////////////////