Mercurial > projects > ldc
comparison gen/functions.cpp @ 117:56a21f3e5d3e trunk
[svn r121] Finished ModuleInfo implementation.
Static ctors/dtors now work according to spec.
Changed class vtable types slightly in some cases. Overridden functions now always take the the type of the first class declaring the method as this parameter. This helps when using headers (w. implementation somewhere else)
author | lindquist |
---|---|
date | Mon, 26 Nov 2007 04:49:23 +0100 |
parents | fd7ad91fd713 |
children | 79c9ac745fbc |
comparison
equal
deleted
inserted
replaced
116:fd7ad91fd713 | 117:56a21f3e5d3e |
---|---|
466 // only members of the current module or template instances maybe be defined | 466 // only members of the current module or template instances maybe be defined |
467 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) | 467 if (fd->getModule() == gIR->dmodule || DtoIsTemplateInstance(fd->parent)) |
468 { | 468 { |
469 fd->llvmDModule = gIR->dmodule; | 469 fd->llvmDModule = gIR->dmodule; |
470 | 470 |
471 // handle static constructor / destructor | |
472 if (fd->isStaticCtorDeclaration() || fd->isStaticDtorDeclaration()) { | |
473 const llvm::ArrayType* sctor_type = llvm::ArrayType::get(llvm::PointerType::get(functype),1); | |
474 //Logger::cout() << "static ctor type: " << *sctor_type << '\n'; | |
475 | |
476 llvm::Constant* sctor_func = llvm::cast<llvm::Constant>(fd->llvmValue); | |
477 //Logger::cout() << "static ctor func: " << *sctor_func << '\n'; | |
478 | |
479 llvm::Constant* sctor_init = llvm::ConstantArray::get(sctor_type,&sctor_func,1); | |
480 | |
481 //Logger::cout() << "static ctor init: " << *sctor_init << '\n'; | |
482 | |
483 // output the llvm.global_ctors array | |
484 const char* varname = fd->isStaticCtorDeclaration() ? "_d_module_ctor_array" : "_d_module_dtor_array"; | |
485 llvm::GlobalVariable* sctor_arr = new llvm::GlobalVariable(sctor_type, false, llvm::GlobalValue::AppendingLinkage, sctor_init, varname, gIR->module); | |
486 } | |
487 | |
488 // function definition | 471 // function definition |
489 if (fd->fbody != 0) | 472 if (fd->fbody != 0) |
490 { | 473 { |
491 Logger::println("Doing function body for: %s", fd->toChars()); | 474 Logger::println("Doing function body for: %s", fd->toChars()); |
492 assert(fd->llvmIRFunc); | 475 assert(fd->llvmIRFunc); |
493 gIR->functions.push_back(fd->llvmIRFunc); | 476 gIR->functions.push_back(fd->llvmIRFunc); |
494 | |
495 /* // moved to declaration | |
496 // this handling | |
497 if (f->llvmUsesThis) { | |
498 Logger::println("uses this"); | |
499 if (f->llvmRetInPtr) | |
500 fd->llvmThisVar = ++func->arg_begin(); | |
501 else | |
502 fd->llvmThisVar = func->arg_begin(); | |
503 assert(fd->llvmThisVar != 0); | |
504 } | |
505 */ | |
506 | 477 |
507 if (fd->isMain()) | 478 if (fd->isMain()) |
508 gIR->emitMain = true; | 479 gIR->emitMain = true; |
509 | 480 |
510 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func); | 481 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func); |
679 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module); | 650 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module); |
680 | 651 |
681 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func); | 652 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func); |
682 | 653 |
683 // call static ctors | 654 // call static ctors |
684 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors"); | 655 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_moduleCtor"); |
685 llvm::Instruction* apt = new llvm::CallInst(fn,"",bb); | 656 llvm::Instruction* apt = new llvm::CallInst(fn,"",bb); |
686 | 657 |
687 // call user main function | 658 // call user main function |
688 const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType(); | 659 const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType(); |
689 llvm::CallInst* call; | 660 llvm::CallInst* call; |
718 call = new llvm::CallInst(ir.mainFunc,"ret",bb); | 689 call = new llvm::CallInst(ir.mainFunc,"ret",bb); |
719 } | 690 } |
720 call->setCallingConv(ir.mainFunc->getCallingConv()); | 691 call->setCallingConv(ir.mainFunc->getCallingConv()); |
721 | 692 |
722 // call static dtors | 693 // call static dtors |
723 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors"); | 694 fn = LLVM_D_GetRuntimeFunction(ir.module,"_moduleDtor"); |
724 new llvm::CallInst(fn,"",bb); | 695 new llvm::CallInst(fn,"",bb); |
725 | 696 |
726 // return | 697 // return |
727 new llvm::ReturnInst(call,bb); | 698 new llvm::ReturnInst(call,bb); |
728 } | 699 } |
729 | 700 |
730 ////////////////////////////////////////////////////////////////////////////////////////// | 701 ////////////////////////////////////////////////////////////////////////////////////////// |
702 | |
703 const llvm::FunctionType* DtoBaseFunctionType(FuncDeclaration* fdecl) | |
704 { | |
705 Dsymbol* parent = fdecl->toParent(); | |
706 ClassDeclaration* cd = parent->isClassDeclaration(); | |
707 assert(cd); | |
708 | |
709 FuncDeclaration* f = fdecl; | |
710 | |
711 while (cd) | |
712 { | |
713 ClassDeclaration* base = cd->baseClass; | |
714 if (!base) | |
715 break; | |
716 FuncDeclaration* f2 = base->findFunc(fdecl->ident, (TypeFunction*)fdecl->type); | |
717 if (f2) { | |
718 f = f2; | |
719 cd = base; | |
720 } | |
721 else | |
722 break; | |
723 } | |
724 | |
725 DtoResolveDsymbol(f); | |
726 return llvm::cast<llvm::FunctionType>(DtoType(f->type)); | |
727 } | |
728 | |
729 ////////////////////////////////////////////////////////////////////////////////////////// |