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 //////////////////////////////////////////////////////////////////////////////////////////