Mercurial > projects > ldc
comparison gen/toobj.cpp @ 88:058d3925950e trunk
[svn r92] Fixed support for statically initialized unions. lots of bugfixes as cleanups too.
author | lindquist |
---|---|
date | Tue, 06 Nov 2007 10:03:14 +0100 |
parents | fd32135dca3e |
children | ccca1c13e13a |
comparison
equal
deleted
inserted
replaced
87:25d4fcce53f4 | 88:058d3925950e |
---|---|
34 #include "gen/irstate.h" | 34 #include "gen/irstate.h" |
35 #include "gen/elem.h" | 35 #include "gen/elem.h" |
36 #include "gen/logger.h" | 36 #include "gen/logger.h" |
37 #include "gen/tollvm.h" | 37 #include "gen/tollvm.h" |
38 #include "gen/arrays.h" | 38 #include "gen/arrays.h" |
39 #include "gen/structs.h" | |
39 #include "gen/todebug.h" | 40 #include "gen/todebug.h" |
40 #include "gen/runtime.h" | 41 #include "gen/runtime.h" |
41 | 42 |
42 ////////////////////////////////////////////////////////////////////////////////////////// | 43 ////////////////////////////////////////////////////////////////////////////////////////// |
43 | 44 |
285 | 286 |
286 if (parent->isModule()) { | 287 if (parent->isModule()) { |
287 gIR->module->addTypeName(mangle(),ts->llvmType); | 288 gIR->module->addTypeName(mangle(),ts->llvmType); |
288 } | 289 } |
289 | 290 |
291 llvmUnion = new DUnion; // uses gIR->topstruct() | |
292 | |
290 // generate static data | 293 // generate static data |
291 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; | 294 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; |
292 llvm::Constant* _init = 0; | 295 llvm::Constant* _init = 0; |
293 | 296 |
294 // always generate the constant initalizer | 297 // always generate the constant initalizer |
570 LOG_SCOPE; | 573 LOG_SCOPE; |
571 llvm::Module* M = gIR->module; | 574 llvm::Module* M = gIR->module; |
572 | 575 |
573 if (aliassym) | 576 if (aliassym) |
574 { | 577 { |
578 Logger::println("alias sym"); | |
575 toAlias()->toObjFile(); | 579 toAlias()->toObjFile(); |
576 return; | 580 return; |
577 } | 581 } |
578 | 582 |
579 // global variable or magic | 583 // global variable or magic |
606 bool _signed = !type->isunsigned(); | 610 bool _signed = !type->isunsigned(); |
607 | 611 |
608 Logger::println("Creating global variable"); | 612 Logger::println("Creating global variable"); |
609 std::string _name(mangle()); | 613 std::string _name(mangle()); |
610 | 614 |
611 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); | 615 bool emitRTstaticInit = false; |
612 llvmValue = gvar; | |
613 | 616 |
614 if (!(storage_class & STCextern) && (getModule() == gIR->dmodule || istempl)) | 617 if (!(storage_class & STCextern) && (getModule() == gIR->dmodule || istempl)) |
615 { | 618 { |
616 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) { | 619 if (parent && parent->isFuncDeclaration() && init && init->isExpInitializer()) { |
617 _init = DtoConstInitializer(t, NULL); | 620 _init = DtoConstInitializer(t, NULL); |
618 // create a flag to make sure initialization only happens once | 621 emitRTstaticInit = true; |
619 llvm::GlobalValue::LinkageTypes gflaglink = istempl ? llvm::GlobalValue::WeakLinkage : llvm::GlobalValue::InternalLinkage; | |
620 std::string gflagname(_name); | |
621 gflagname.append("__initflag"); | |
622 llvm::GlobalVariable* gflag = new llvm::GlobalVariable(llvm::Type::Int1Ty,false,gflaglink,DtoConstBool(false),gflagname,M); | |
623 | |
624 // check flag and do init if not already done | |
625 llvm::BasicBlock* oldend = gIR->scopeend(); | |
626 llvm::BasicBlock* initbb = new llvm::BasicBlock("ifnotinit",gIR->topfunc(),oldend); | |
627 llvm::BasicBlock* endinitbb = new llvm::BasicBlock("ifnotinitend",gIR->topfunc(),oldend); | |
628 llvm::Value* cond = gIR->ir->CreateICmpEQ(gIR->ir->CreateLoad(gflag,"tmp"),DtoConstBool(false)); | |
629 gIR->ir->CreateCondBr(cond, initbb, endinitbb); | |
630 gIR->scope() = IRScope(initbb,endinitbb); | |
631 elem* ie = DtoInitializer(init); | |
632 if (!ie->inPlace()) { | |
633 DValue* dst = new DVarValue(t, gvar, true); | |
634 DtoAssign(dst, ie); | |
635 delete dst; | |
636 } | |
637 gIR->ir->CreateStore(DtoConstBool(true), gflag); | |
638 gIR->ir->CreateBr(endinitbb); | |
639 gIR->scope() = IRScope(endinitbb,oldend); | |
640 } | 622 } |
641 else { | 623 else { |
642 _init = DtoConstInitializer(t, init); | 624 _init = DtoConstInitializer(t, init); |
643 } | 625 } |
644 | 626 |
666 else { | 648 else { |
667 Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; | 649 Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; |
668 //assert(0); | 650 //assert(0); |
669 } | 651 } |
670 } | 652 } |
671 | 653 } |
672 Logger::cout() << "final init = " << *_init << '\n'; | 654 |
673 gvar->setInitializer(_init); | 655 if (_init && _init->getType() != _type) |
674 } | 656 _type = _init->getType(); |
657 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,_init,_name,M); | |
658 llvmValue = gvar; | |
659 | |
660 if (emitRTstaticInit) | |
661 DtoLazyStaticInit(istempl, gvar, init, t); | |
675 | 662 |
676 llvmDModule = gIR->dmodule; | 663 llvmDModule = gIR->dmodule; |
677 | 664 |
678 //if (storage_class & STCprivate) | 665 //if (storage_class & STCprivate) |
679 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); | 666 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); |