comparison 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
comparison
equal deleted inserted replaced
161:3a891cfcd249 162:1856c62af24b
26 if (gIR->irType[type].type != NULL) { 26 if (gIR->irType[type].type != NULL) {
27 return llvm::cast<llvm::FunctionType>(gIR->irType[type].type->get()); 27 return llvm::cast<llvm::FunctionType>(gIR->irType[type].type->get());
28 } 28 }
29 29
30 bool typesafeVararg = false; 30 bool typesafeVararg = false;
31 if (f->linkage == LINKd && f->varargs == 1) { 31 bool arrayVararg = false;
32 typesafeVararg = true; 32 if (f->linkage == LINKd)
33 {
34 if (f->varargs == 1)
35 typesafeVararg = true;
36 else if (f->varargs == 2)
37 arrayVararg = true;
33 } 38 }
34 39
35 // return value type 40 // return value type
36 const llvm::Type* rettype; 41 const llvm::Type* rettype;
37 const llvm::Type* actualRettype; 42 const llvm::Type* actualRettype;
80 types.push_back(getPtrToType(getPtrToType(gIR->irDsymbol[ti].irStruct->constInit->getType()))); 85 types.push_back(getPtrToType(getPtrToType(gIR->irDsymbol[ti].irStruct->constInit->getType())));
81 const llvm::Type* t1 = llvm::StructType::get(types); 86 const llvm::Type* t1 = llvm::StructType::get(types);
82 paramvec.push_back(getPtrToType(t1)); 87 paramvec.push_back(getPtrToType(t1));
83 paramvec.push_back(getPtrToType(llvm::Type::Int8Ty)); 88 paramvec.push_back(getPtrToType(llvm::Type::Int8Ty));
84 } 89 }
90 else if (arrayVararg)
91 {
92 // do nothing?
93 }
85 94
86 size_t n = Argument::dim(f->parameters); 95 size_t n = Argument::dim(f->parameters);
87 96
88 for (int i=0; i < n; ++i) { 97 for (int i=0; i < n; ++i) {
89 Argument* arg = Argument::getNth(f->parameters, i); 98 Argument* arg = Argument::getNth(f->parameters, i);
118 paramvec.push_back(at); 127 paramvec.push_back(at);
119 } 128 }
120 } 129 }
121 130
122 // construct function type 131 // construct function type
123 bool isvararg = !typesafeVararg && f->varargs; 132 bool isvararg = !(typesafeVararg || arrayVararg) && f->varargs;
124 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); 133 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
125 134
126 f->llvmRetInPtr = retinptr; 135 f->llvmRetInPtr = retinptr;
127 f->llvmUsesThis = usesthis; 136 f->llvmUsesThis = usesthis;
128 137
381 // static dtor 390 // static dtor
382 else if (fdecl->isStaticDtorDeclaration()) { 391 else if (fdecl->isStaticDtorDeclaration()) {
383 gIR->dtors.push_back(fdecl); 392 gIR->dtors.push_back(fdecl);
384 } 393 }
385 394
386 // name parameters 395 // we never reference parameters of function prototypes
387 llvm::Function::arg_iterator iarg = func->arg_begin(); 396 if (!declareOnly)
388 int k = 0; 397 {
389 if (f->llvmRetInPtr) { 398 // name parameters
390 iarg->setName("retval"); 399 llvm::Function::arg_iterator iarg = func->arg_begin();
391 gIR->irDsymbol[fdecl].irFunc->retArg = iarg; 400 int k = 0;
392 ++iarg; 401 if (f->llvmRetInPtr) {
393 } 402 iarg->setName("retval");
394 if (f->llvmUsesThis) { 403 gIR->irDsymbol[fdecl].irFunc->retArg = iarg;
395 iarg->setName("this"); 404 ++iarg;
396 gIR->irDsymbol[fdecl].irFunc->thisVar = iarg; 405 }
397 assert(gIR->irDsymbol[fdecl].irFunc->thisVar); 406 if (f->llvmUsesThis) {
398 ++iarg; 407 iarg->setName("this");
399 } 408 gIR->irDsymbol[fdecl].irFunc->thisVar = iarg;
400 409 assert(gIR->irDsymbol[fdecl].irFunc->thisVar);
401 if (f->linkage == LINKd && f->varargs == 1) { 410 ++iarg;
402 iarg->setName("_arguments"); 411 }
403 gIR->irDsymbol[fdecl].irFunc->_arguments = iarg; 412
404 ++iarg; 413 if (f->linkage == LINKd && f->varargs == 1) {
405 iarg->setName("_argptr"); 414 iarg->setName("_arguments");
406 gIR->irDsymbol[fdecl].irFunc->_argptr = iarg; 415 gIR->irDsymbol[fdecl].irFunc->_arguments = iarg;
407 ++iarg; 416 ++iarg;
408 } 417 iarg->setName("_argptr");
409 418 gIR->irDsymbol[fdecl].irFunc->_argptr = iarg;
410 for (; iarg != func->arg_end(); ++iarg) 419 ++iarg;
411 { 420 }
412 Argument* arg = Argument::getNth(f->parameters, k++); 421
413 //arg->llvmValue = iarg; 422 for (; iarg != func->arg_end(); ++iarg)
414 //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); 423 {
415 if (arg && arg->ident != 0) { 424 if (fdecl->parameters && fdecl->parameters->dim > k)
416 if (arg->vardecl) { 425 {
417 if (gIR->irDsymbol[arg->vardecl].irLocal) 426 Dsymbol* argsym = (Dsymbol*)fdecl->parameters->data[k++];
418 { 427 VarDeclaration* argvd = argsym->isVarDeclaration();
419 Logger::cout() << "WTF!?!: " << *gIR->irDsymbol[arg->vardecl].irLocal->value << '\n'; 428 assert(argvd);
420 } 429 assert(!gIR->irDsymbol[argvd].irLocal);
421 assert(!gIR->irDsymbol[arg->vardecl].irLocal); 430 gIR->irDsymbol[argvd].irLocal = new IrLocal(argvd);
422 assert(!gIR->irDsymbol[arg->vardecl].irGlobal); 431 gIR->irDsymbol[argvd].irLocal->value = iarg;
423 assert(!gIR->irDsymbol[arg->vardecl].irField); 432 iarg->setName(argvd->ident->toChars());
424 gIR->irDsymbol[arg->vardecl].irLocal = new IrLocal(arg->vardecl);
425 gIR->irDsymbol[arg->vardecl].irLocal->value = iarg;
426 } 433 }
427 iarg->setName(arg->ident->toChars()); 434 else
428 } 435 {
429 else { 436 iarg->setName("unnamed");
430 iarg->setName("unnamed"); 437 }
431 } 438 }
432 } 439 }
433 440
434 if (fdecl->isUnitTestDeclaration()) 441 if (fdecl->isUnitTestDeclaration())
435 gIR->unitTests.push_back(fdecl); 442 gIR->unitTests.push_back(fdecl);
498 gIR->irDsymbol[fd->vresult].irLocal = new IrLocal(fd->vresult); 505 gIR->irDsymbol[fd->vresult].irLocal = new IrLocal(fd->vresult);
499 gIR->irDsymbol[fd->vresult].irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint); 506 gIR->irDsymbol[fd->vresult].irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
500 } 507 }
501 508
502 // give arguments storage 509 // give arguments storage
503 size_t n = Argument::dim(f->parameters); 510 if (fd->parameters)
504 for (int i=0; i < n; ++i) { 511 {
505 Argument* arg = Argument::getNth(f->parameters, i); 512 size_t n = fd->parameters->dim;
506 if (arg && arg->vardecl) { 513 for (int i=0; i < n; ++i)
507 VarDeclaration* vd = arg->vardecl; 514 {
515 Dsymbol* argsym = (Dsymbol*)fd->parameters->data[i];
516 VarDeclaration* vd = argsym->isVarDeclaration();
517 assert(vd);
518
508 if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)) 519 if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
509 continue; 520 continue;
521
510 llvm::Value* a = gIR->irDsymbol[vd].irLocal->value; 522 llvm::Value* a = gIR->irDsymbol[vd].irLocal->value;
511 assert(a); 523 assert(a);
512 std::string s(a->getName()); 524 std::string s(a->getName());
513 Logger::println("giving argument '%s' storage", s.c_str()); 525 Logger::println("giving argument '%s' storage", s.c_str());
514 s.append("_storage"); 526 s.append("_storage");
527
515 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint); 528 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
516 gIR->ir->CreateStore(a,v); 529 gIR->ir->CreateStore(a,v);
517 gIR->irDsymbol[vd].irLocal->value = v; 530 gIR->irDsymbol[vd].irLocal->value = v;
518 }
519 else {
520 Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
521 } 531 }
522 } 532 }
523 533
524 // debug info 534 // debug info
525 if (global.params.symdebug) DtoDwarfFuncStart(fd); 535 if (global.params.symdebug) DtoDwarfFuncStart(fd);