Mercurial > projects > ldc
diff gen/functions.cpp @ 719:7261ff0f95ff
Implemented first class delegates. closes #101
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Wed, 22 Oct 2008 21:50:08 +0200 |
parents | 30b42a283c8e |
children | e177ae483f8e |
line wrap: on
line diff
--- a/gen/functions.cpp Wed Oct 22 20:00:57 2008 +0200 +++ b/gen/functions.cpp Wed Oct 22 21:50:08 2008 +0200 @@ -123,15 +123,24 @@ const LLType* at = DtoType(argT); + // handle lazy args + if (arg->storageClass & STClazy) + { + Logger::println("lazy param"); + TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd); + TypeDelegate *ltd = new TypeDelegate(ltf); + at = DtoType(ltd); + paramvec.push_back(at); + } // opaque types need special handling - if (llvm::isa<llvm::OpaqueType>(at)) { + else if (llvm::isa<llvm::OpaqueType>(at)) { Logger::println("opaque param"); assert(argT->ty == Tstruct || argT->ty == Tclass); paramvec.push_back(getPtrToType(at)); } - // structs and delegates are passed as a reference, but by value - else if (argT->ty == Tstruct || argT->ty == Tdelegate) { - Logger::println("struct/sarray param"); + // structs are passed as a reference, but by value + else if (argT->ty == Tstruct) { + Logger::println("struct param"); if (!refOrOut) arg->llvmAttrs |= llvm::Attribute::ByVal; paramvec.push_back(getPtrToType(at)); @@ -156,23 +165,6 @@ arg->llvmAttrs |= ea; paramvec.push_back(at); } - - // handle lazy args - if (arg->storageClass & STClazy) - { - if (Logger::enabled()) - Logger::cout() << "for lazy got: " << *paramvec.back() << '\n'; - - TypeFunction *ltf = new TypeFunction(NULL, arg->type, 0, LINKd); - TypeDelegate *ltd = new TypeDelegate(ltf); - at = getPtrToType(DtoType(ltd)); - - if (Logger::enabled()) - Logger::cout() << "lazy updated to: " << *at << '\n'; - - paramvec.back() = at; - // lazy doesn't need byval as the delegate is not visible to the user - } } // construct function type @@ -652,13 +644,14 @@ IrLocal* irloc = vd->ir.irLocal; assert(irloc); - bool refoutlazy = vd->storage_class & (STCref | STCout | STClazy); + bool refout = vd->storage_class & (STCref | STCout); + bool lazy = vd->storage_class & STClazy; - if (refoutlazy) + if (refout) { continue; } - else if (DtoIsPassedByRef(vd->type)) + else if (!lazy && DtoIsPassedByRef(vd->type)) { LLValue* vdirval = irloc->value; if (global.params.symdebug && !(isaArgument(vdirval) && !isaArgument(vdirval)->hasByValAttr())) @@ -875,6 +868,13 @@ else arg = new DImValue(argexp->type, arg->getRVal()); } + // lazy arg + else if (fnarg && (fnarg->storageClass & STClazy)) + { + assert(argexp->type->toBasetype()->ty == Tdelegate); + assert(!arg->isLVal()); + return arg; + } // byval arg, but expr has no storage yet else if (DtoIsPassedByRef(argexp->type) && (arg->isSlice() || arg->isNull())) {