Mercurial > projects > ldc
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); |