Mercurial > projects > ldc
diff gen/functions.cpp @ 162:1856c62af24b trunk
[svn r178] Fixed codegen values for function arguments, the old approach was completely broken, amazing it even worked...
author | lindquist |
---|---|
date | Mon, 05 May 2008 00:56:53 +0200 |
parents | 5c17f81fc1c1 |
children | a8cd9bc1021a |
line wrap: on
line diff
--- a/gen/functions.cpp Sun May 04 21:25:48 2008 +0200 +++ b/gen/functions.cpp Mon May 05 00:56:53 2008 +0200 @@ -28,8 +28,13 @@ } bool typesafeVararg = false; - if (f->linkage == LINKd && f->varargs == 1) { - typesafeVararg = true; + bool arrayVararg = false; + if (f->linkage == LINKd) + { + if (f->varargs == 1) + typesafeVararg = true; + else if (f->varargs == 2) + arrayVararg = true; } // return value type @@ -82,6 +87,10 @@ paramvec.push_back(getPtrToType(t1)); paramvec.push_back(getPtrToType(llvm::Type::Int8Ty)); } + else if (arrayVararg) + { + // do nothing? + } size_t n = Argument::dim(f->parameters); @@ -120,7 +129,7 @@ } // construct function type - bool isvararg = !typesafeVararg && f->varargs; + bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs; llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); f->llvmRetInPtr = retinptr; @@ -383,51 +392,49 @@ gIR->dtors.push_back(fdecl); } - // name parameters - llvm::Function::arg_iterator iarg = func->arg_begin(); - int k = 0; - if (f->llvmRetInPtr) { - iarg->setName("retval"); - gIR->irDsymbol[fdecl].irFunc->retArg = iarg; - ++iarg; - } - if (f->llvmUsesThis) { - iarg->setName("this"); - gIR->irDsymbol[fdecl].irFunc->thisVar = iarg; - assert(gIR->irDsymbol[fdecl].irFunc->thisVar); - ++iarg; - } + // we never reference parameters of function prototypes + if (!declareOnly) + { + // name parameters + llvm::Function::arg_iterator iarg = func->arg_begin(); + int k = 0; + if (f->llvmRetInPtr) { + iarg->setName("retval"); + gIR->irDsymbol[fdecl].irFunc->retArg = iarg; + ++iarg; + } + if (f->llvmUsesThis) { + iarg->setName("this"); + gIR->irDsymbol[fdecl].irFunc->thisVar = iarg; + assert(gIR->irDsymbol[fdecl].irFunc->thisVar); + ++iarg; + } - if (f->linkage == LINKd && f->varargs == 1) { - iarg->setName("_arguments"); - gIR->irDsymbol[fdecl].irFunc->_arguments = iarg; - ++iarg; - iarg->setName("_argptr"); - gIR->irDsymbol[fdecl].irFunc->_argptr = iarg; - ++iarg; - } + if (f->linkage == LINKd && f->varargs == 1) { + iarg->setName("_arguments"); + gIR->irDsymbol[fdecl].irFunc->_arguments = iarg; + ++iarg; + iarg->setName("_argptr"); + gIR->irDsymbol[fdecl].irFunc->_argptr = iarg; + ++iarg; + } - for (; iarg != func->arg_end(); ++iarg) - { - Argument* arg = Argument::getNth(f->parameters, k++); - //arg->llvmValue = iarg; - //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); - if (arg && arg->ident != 0) { - if (arg->vardecl) { - if (gIR->irDsymbol[arg->vardecl].irLocal) - { - Logger::cout() << "WTF!?!: " << *gIR->irDsymbol[arg->vardecl].irLocal->value << '\n'; - } - assert(!gIR->irDsymbol[arg->vardecl].irLocal); - assert(!gIR->irDsymbol[arg->vardecl].irGlobal); - assert(!gIR->irDsymbol[arg->vardecl].irField); - gIR->irDsymbol[arg->vardecl].irLocal = new IrLocal(arg->vardecl); - gIR->irDsymbol[arg->vardecl].irLocal->value = iarg; + for (; iarg != func->arg_end(); ++iarg) + { + if (fdecl->parameters && fdecl->parameters->dim > k) + { + Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[k++]; + VarDeclaration* argvd = argsym->isVarDeclaration(); + assert(argvd); + assert(!gIR->irDsymbol[argvd].irLocal); + gIR->irDsymbol[argvd].irLocal = new IrLocal(argvd); + gIR->irDsymbol[argvd].irLocal->value = iarg; + iarg->setName(argvd->ident->toChars()); } - iarg->setName(arg->ident->toChars()); - } - else { - iarg->setName("unnamed"); + else + { + iarg->setName("unnamed"); + } } } @@ -500,25 +507,28 @@ } // give arguments storage - size_t n = Argument::dim(f->parameters); - for (int i=0; i < n; ++i) { - Argument* arg = Argument::getNth(f->parameters, i); - if (arg && arg->vardecl) { - VarDeclaration* vd = arg->vardecl; + if (fd->parameters) + { + size_t n = fd->parameters->dim; + for (int i=0; i < n; ++i) + { + Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i]; + VarDeclaration* vd = argsym->isVarDeclaration(); + assert(vd); + if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) continue; + llvm::Value* a = gIR->irDsymbol[vd].irLocal->value; assert(a); std::string s(a->getName()); Logger::println("giving argument '%s' storage", s.c_str()); s.append("_storage"); + llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); gIR->ir->CreateStore(a,v); gIR->irDsymbol[vd].irLocal->value = v; } - else { - Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0); - } } // debug info