Mercurial > projects > ldc
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 } |