diff --git a/gen/functions.cpp b/gen/functions.cpp index 58dabe36..9a4dc539 100644 --- a/gen/functions.cpp +++ b/gen/functions.cpp @@ -158,11 +158,10 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo at = getPtrToType(DtoType(ltd)); Logger::cout() << "lazy updated to: " << *at << '\n'; paramvec.back() = at; + // lazy doesn't need byval as the delegate is not visible to the user } } - //warning("set %d byval args for type: %s", nbyval, f->toChars()); - // construct function type bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); @@ -306,8 +305,6 @@ void DtoResolveFunction(FuncDeclaration* fdecl) static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclaration* fdecl) { - assert(f->parameters); - int llidx = 1; if (f->llvmRetInPtr) ++llidx; if (f->llvmUsesThis) ++llidx; @@ -328,6 +325,14 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati attrs.push_back(PAWI); } + // set sret param + if (f->llvmRetInPtr) + { + PAWI.Index = 1; + PAWI.Attrs = llvm::ParamAttr::StructRet; + attrs.push_back(PAWI); + } + // set byval attrs on implicit main arg if (fdecl->isMain() && Argument::dim(f->parameters) == 0) { @@ -338,9 +343,9 @@ static void set_param_attrs(TypeFunction* f, llvm::Function* func, FuncDeclarati } // set attrs on the rest of the arguments - for (; llidx <= funcNumArgs && f->parameters->dim > k; ++llidx,++k) + for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) { - Argument* fnarg = (Argument*)f->parameters->data[k]; + Argument* fnarg = Argument::getNth(f->parameters, k); assert(fnarg); PAWI.Index = llidx; @@ -428,7 +433,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) assert(llvm::isa(f->ir.type->get())); // parameter attributes - if (f->parameters && !fdecl->isIntrinsic()) { + if (!fdecl->isIntrinsic()) { set_param_attrs(f, func, fdecl); } @@ -458,7 +463,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl) ++iarg; } if (f->llvmUsesThis) { - iarg->setName("this"); + iarg->setName(fdecl->isNested()?".context":"this"); fdecl->ir.irFunc->thisVar = iarg; assert(fdecl->ir.irFunc->thisVar); ++iarg; diff --git a/gen/tocall.cpp b/gen/tocall.cpp index f47e8f64..82db954c 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -213,6 +213,13 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* LLFunctionType::param_iterator argbegin = callableTy->param_begin(); LLFunctionType::param_iterator argiter = argbegin; + // parameter attributes + llvm::PAListPtr palist; + + // return attrs + if (tf->llvmRetAttrs) + palist = palist.addAttr(0, tf->llvmRetAttrs); + // handle implicit arguments std::vector args; @@ -222,6 +229,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* LLValue* retvar = new llvm::AllocaInst(argiter->get()->getContainedType(0), ".rettmp", gIR->topallocapoint()); ++argiter; args.push_back(retvar); + palist = palist.addAttr(1, llvm::ParamAttr::StructRet); } // then comes a context argument... @@ -261,10 +269,6 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* } // handle the rest of the arguments based on param passing style - llvm::PAListPtr palist; - - if (tf->llvmRetAttrs) - palist = palist.addAttr(0, tf->llvmRetAttrs); // variadic instrinsics need some custom casts if (va_intrinsic) @@ -296,7 +300,7 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* Argument* fnarg = Argument::getNth(tf->parameters, i); DValue* argval = DtoArgument(fnarg, (Expression*)arguments->data[i]); LLValue* arg = argval->getRVal(); - if (fnarg) + if (fnarg) // can fnarg ever be null in this block? { if (arg->getType() != callableTy->getParamType(j)) arg = DtoBitCast(arg, callableTy->getParamType(j)); diff --git a/runtime/llvmdc.diff b/runtime/llvmdc.diff index c5670a1f..ef1e51b5 100644 --- a/runtime/llvmdc.diff +++ b/runtime/llvmdc.diff @@ -94,6 +94,54 @@ Index: lib/common/tango/core/Thread.d version( X86_64 ) { +Index: lib/unittest.sh +=================================================================== +--- lib/unittest.sh (revision 3831) ++++ lib/unittest.sh (working copy) +@@ -18,8 +18,9 @@ + --help: This message + --run-all: Reports result instead of breaking. Do not use this if you want to + run unittest runner through a debugger. +- dmd: Builds unittests for dmd +- gdc: Builds unittests for gdc ++ dmd: Builds unittests for dmd ++ gdc: Builds unittests for gdc ++ llvmdc: Builds unittests for llvmdc + + : Builds unittests for all known compilers.' + exit 0 +@@ -125,6 +126,9 @@ + gdc) + GDC=1 + ;; ++ llvmdc) ++ LLVMDC=1 ++ ;; + *) + usage + ;; +@@ -132,10 +136,11 @@ + shift + done + +-if [ ! "$DMD" -a ! "$GDC" ] ++if [ ! "$DMD" -a ! "$GDC" -a ! "$LLVMDC" ] + then + DMD=1 + GDC=1 ++ LLVMDC=1 + fi + + if [ "$DMD" = "1" ] +@@ -146,4 +151,7 @@ + then + compile gdc runUnitTest_gdc + fi +- ++if [ "$LLVMDC" = "1" ] ++then ++ compile llvmdc runUnitTest_llvmdc ++fi Index: lib/gc/basic/gcx.d =================================================================== --- lib/gc/basic/gcx.d (revision 3831)