comparison gen/toobj.c @ 85:f869c636a113 trunk

[svn r89] Fixed a bunch of problems with template instance across multiple modules. Fixed initialization of function local static variables, with a non const initializer (now happens on first call using a global to make sure it only happens once.)
author lindquist
date Fri, 02 Nov 2007 06:32:32 +0100
parents 169711a7126e
children
comparison
equal deleted inserted replaced
84:169711a7126e 85:f869c636a113
567 { 567 {
568 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars()); 568 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
569 LOG_SCOPE; 569 LOG_SCOPE;
570 llvm::Module* M = gIR->module; 570 llvm::Module* M = gIR->module;
571 571
572 if (aliassym)
573 {
574 toAlias()->toObjFile();
575 return;
576 }
577
572 // global variable or magic 578 // global variable or magic
573 if (isDataseg() || parent->isModule()) 579 if (isDataseg())
574 { 580 {
575 if (llvmTouched) return; 581 if (llvmTouched) return;
576 else llvmTouched = true; 582 else llvmTouched = true;
577 583
578 bool _isconst = isConst(); 584 bool _isconst = false;
585 if (isConst() && (init && !init->isExpInitializer()))
586 _isconst = true;
579 587
580 llvm::GlobalValue::LinkageTypes _linkage; 588 llvm::GlobalValue::LinkageTypes _linkage;
581 if (parent && parent->isFuncDeclaration()) 589 bool istempl = false;
590 if ((storage_class & STCcomdat) || (parent && DtoIsTemplateInstance(parent))) {
591 _linkage = llvm::GlobalValue::WeakLinkage;
592 istempl = true;
593 }
594 else if (parent && parent->isFuncDeclaration())
582 _linkage = llvm::GlobalValue::InternalLinkage; 595 _linkage = llvm::GlobalValue::InternalLinkage;
583 else 596 else
584 _linkage = DtoLinkage(protection, storage_class); 597 _linkage = DtoLinkage(protection, storage_class);
585 598
586 Type* t = DtoDType(type); 599 Type* t = DtoDType(type);
595 std::string _name(mangle()); 608 std::string _name(mangle());
596 609
597 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); 610 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M);
598 llvmValue = gvar; 611 llvmValue = gvar;
599 612
600 // if extern don't emit initializer 613 if (!(storage_class & STCextern) && (getModule() == gIR->dmodule || istempl))
601 if (!(storage_class & STCextern) && getModule() == gIR->dmodule)
602 { 614 {
603 _init = DtoConstInitializer(t, init); 615 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) {
616 _init = DtoConstInitializer(t, NULL);
617 // create a flag to make sure initialization only happens once
618 llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage;
619 std::string gflagname(_name);
620 gflagname.append("__initflag");
621 llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,M);
622
623 // check flag and do init if not already done
624 llvm::BasicBlock* oldend = gIR->scopeend();
625 llvm::BasicBlock* initbb = new llvm::BasicBlock("ifnotinit",gIR->topfunc(),oldend);
626 llvm::BasicBlock* endinitbb = new llvm::BasicBlock("ifnotinitend",gIR->topfunc(),oldend);
627 llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false));
628 gIR->ir->CreateCondBr(cond, initbb, endinitbb);
629 gIR->scope() = IRScope(initbb,endinitbb);
630 elem* ie = DtoInitializer(init);
631 if (!ie->inplace)
632 DtoAssign(t, gvar, ie->getValue());
633 gIR->ir->CreateStore(DtoConstBool(true), gflag);
634 gIR->ir->CreateBr(endinitbb);
635 gIR->scope() = IRScope(endinitbb,oldend);
636 }
637 else {
638 _init = DtoConstInitializer(t, init);
639 }
604 640
605 //Logger::cout() << "initializer: " << *_init << '\n'; 641 //Logger::cout() << "initializer: " << *_init << '\n';
606 if (_type != _init->getType()) { 642 if (_type != _init->getType()) {
607 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; 643 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
608 // zero initalizer 644 // zero initalizer
763 } 799 }
764 800
765 assert(f->llvmType); 801 assert(f->llvmType);
766 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0)); 802 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0));
767 803
804 // template instances should have weak linkage
805 assert(parent);
806 if (DtoIsTemplateInstance(parent)) {
807 func->setLinkage(llvm::GlobalValue::WeakLinkage);
808 }
809
768 // only members of the current module maybe be defined 810 // only members of the current module maybe be defined
769 if (getModule() == gIR->dmodule || parent->isTemplateInstance()) 811 if (getModule() == gIR->dmodule || DtoIsTemplateInstance(parent))
770 { 812 {
771 llvmDModule = gIR->dmodule; 813 llvmDModule = gIR->dmodule;
772 814
773 // handle static constructor / destructor 815 // handle static constructor / destructor
774 if (isStaticCtorDeclaration() || isStaticDtorDeclaration()) { 816 if (isStaticCtorDeclaration() || isStaticDtorDeclaration()) {
836 s.append("_storage"); 878 s.append("_storage");
837 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,f->llvmAllocaPoint); 879 llvm::Value* v = new llvm::AllocaInst(a->getType(),s,f->llvmAllocaPoint);
838 gIR->ir->CreateStore(a,v); 880 gIR->ir->CreateStore(a,v);
839 vd->llvmValue = v; 881 vd->llvmValue = v;
840 } 882 }
841 else assert(0); 883 else {
884 Logger::println("*** ATTENTION: some unknown argument: %s", arg ? arg->toChars() : 0);
885 }
842 } 886 }
843 887
844 // debug info 888 // debug info
845 if (global.params.symdebug) DtoDwarfFuncStart(this); 889 if (global.params.symdebug) DtoDwarfFuncStart(this);
846 890
939 } 983 }
940 } 984 }
941 985
942 gIR->functions.pop_back(); 986 gIR->functions.pop_back();
943 } 987 }
944 988 }
945 // template instances should have weak linkage 989 }
946 if (parent->isTemplateInstance()) {
947 func->setLinkage(llvm::GlobalValue::WeakLinkage);
948 }
949 }
950 }