comparison gen/toobj.c @ 81:3587401b6eeb trunk

[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed. Changed: Renamed all the LLVM_Dto... helper function to just Dto...
author lindquist
date Thu, 01 Nov 2007 17:27:18 +0100
parents 714057ff2dbb
children d8dd47ef3973
comparison
equal deleted inserted replaced
80:7299ff502248 81:3587401b6eeb
84 84
85 gTargetData = 0; 85 gTargetData = 0;
86 86
87 // emit the llvm main function if necessary 87 // emit the llvm main function if necessary
88 if (ir.emitMain) { 88 if (ir.emitMain) {
89 LLVM_DtoMain(); 89 DtoMain();
90 } 90 }
91 91
92 // verify the llvm 92 // verify the llvm
93 if (!global.params.novalidate) { 93 if (!global.params.novalidate) {
94 std::string verifyErr; 94 std::string verifyErr;
155 155
156 /* ================================================================== */ 156 /* ================================================================== */
157 157
158 void StructDeclaration::toObjFile() 158 void StructDeclaration::toObjFile()
159 { 159 {
160 TypeStruct* ts = (TypeStruct*)LLVM_DtoDType(type); 160 TypeStruct* ts = (TypeStruct*)DtoDType(type);
161 if (llvmType != 0) 161 if (llvmType != 0)
162 return; 162 return;
163 163
164 static int sdi = 0; 164 static int sdi = 0;
165 Logger::print("StructDeclaration::toObjFile(%d): %s\n", sdi++, toChars()); 165 Logger::print("StructDeclaration::toObjFile(%d): %s\n", sdi++, toChars());
198 for (IRStruct::OffsetMap::iterator i=gIR->topstruct().offsets.begin(); i!=gIR->topstruct().offsets.end(); ++i) { 198 for (IRStruct::OffsetMap::iterator i=gIR->topstruct().offsets.begin(); i!=gIR->topstruct().offsets.end(); ++i) {
199 // first iteration 199 // first iteration
200 if (lastoffset == (unsigned)-1) { 200 if (lastoffset == (unsigned)-1) {
201 lastoffset = i->first; 201 lastoffset = i->first;
202 assert(lastoffset == 0); 202 assert(lastoffset == 0);
203 fieldtype = LLVM_DtoType(i->second.var->type); 203 fieldtype = DtoType(i->second.var->type);
204 fieldinit = i->second.init; 204 fieldinit = i->second.init;
205 prevsize = gTargetData->getTypeSize(fieldtype); 205 prevsize = gTargetData->getTypeSize(fieldtype);
206 i->second.var->llvmFieldIndex = idx; 206 i->second.var->llvmFieldIndex = idx;
207 } 207 }
208 // colliding offset? 208 // colliding offset?
209 else if (lastoffset == i->first) { 209 else if (lastoffset == i->first) {
210 const llvm::Type* t = LLVM_DtoType(i->second.var->type); 210 const llvm::Type* t = DtoType(i->second.var->type);
211 size_t s = gTargetData->getTypeSize(t); 211 size_t s = gTargetData->getTypeSize(t);
212 if (s > prevsize) { 212 if (s > prevsize) {
213 fieldpad += s - prevsize; 213 fieldpad += s - prevsize;
214 prevsize = s; 214 prevsize = s;
215 } 215 }
216 llvmHasUnions = true; 216 llvmHasUnions = true;
217 i->second.var->llvmFieldIndex = idx; 217 i->second.var->llvmFieldIndex = idx;
218 } 218 }
219 // intersecting offset? 219 // intersecting offset?
220 else if (i->first < (lastoffset + prevsize)) { 220 else if (i->first < (lastoffset + prevsize)) {
221 const llvm::Type* t = LLVM_DtoType(i->second.var->type); 221 const llvm::Type* t = DtoType(i->second.var->type);
222 size_t s = gTargetData->getTypeSize(t); 222 size_t s = gTargetData->getTypeSize(t);
223 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size 223 assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
224 llvmHasUnions = true; 224 llvmHasUnions = true;
225 i->second.var->llvmFieldIndex = idx; 225 i->second.var->llvmFieldIndex = idx;
226 i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s; 226 i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
241 241
242 idx++; 242 idx++;
243 243
244 // start new 244 // start new
245 lastoffset = i->first; 245 lastoffset = i->first;
246 fieldtype = LLVM_DtoType(i->second.var->type); 246 fieldtype = DtoType(i->second.var->type);
247 fieldinit = i->second.init; 247 fieldinit = i->second.init;
248 prevsize = gTargetData->getTypeSize(fieldtype); 248 prevsize = gTargetData->getTypeSize(fieldtype);
249 i->second.var->llvmFieldIndex = idx; 249 i->second.var->llvmFieldIndex = idx;
250 fieldpad = 0; 250 fieldpad = 0;
251 } 251 }
387 } 387 }
388 } 388 }
389 389
390 void ClassDeclaration::toObjFile() 390 void ClassDeclaration::toObjFile()
391 { 391 {
392 TypeClass* ts = (TypeClass*)LLVM_DtoDType(type); 392 TypeClass* ts = (TypeClass*)DtoDType(type);
393 if (ts->llvmType != 0 || llvmInProgress) 393 if (ts->llvmType != 0 || llvmInProgress)
394 return; 394 return;
395 395
396 llvmInProgress = true; 396 llvmInProgress = true;
397 397
421 dsym->toObjFile(); 421 dsym->toObjFile();
422 } 422 }
423 423
424 // fill out fieldtypes/inits 424 // fill out fieldtypes/inits
425 for (IRStruct::OffsetMap::iterator i=gIR->topstruct().offsets.begin(); i!=gIR->topstruct().offsets.end(); ++i) { 425 for (IRStruct::OffsetMap::iterator i=gIR->topstruct().offsets.begin(); i!=gIR->topstruct().offsets.end(); ++i) {
426 fieldtypes.push_back(LLVM_DtoType(i->second.var->type)); 426 fieldtypes.push_back(DtoType(i->second.var->type));
427 fieldinits.push_back(i->second.init); 427 fieldinits.push_back(i->second.init);
428 } 428 }
429 429
430 llvm::StructType* structtype = llvm::StructType::get(fieldtypes); 430 llvm::StructType* structtype = llvm::StructType::get(fieldtypes);
431 // refine abstract types for stuff like: class C {C next;} 431 // refine abstract types for stuff like: class C {C next;}
572 572
573 llvm::GlobalValue::LinkageTypes _linkage; 573 llvm::GlobalValue::LinkageTypes _linkage;
574 if (parent && parent->isFuncDeclaration()) 574 if (parent && parent->isFuncDeclaration())
575 _linkage = llvm::GlobalValue::InternalLinkage; 575 _linkage = llvm::GlobalValue::InternalLinkage;
576 else 576 else
577 _linkage = LLVM_DtoLinkage(protection, storage_class); 577 _linkage = DtoLinkage(protection, storage_class);
578 578
579 Type* t = LLVM_DtoDType(type); 579 Type* t = DtoDType(type);
580 580
581 const llvm::Type* _type = LLVM_DtoType(t); 581 const llvm::Type* _type = DtoType(t);
582 assert(_type); 582 assert(_type);
583 583
584 llvm::Constant* _init = 0; 584 llvm::Constant* _init = 0;
585 bool _signed = !type->isunsigned(); 585 bool _signed = !type->isunsigned();
586 586
591 llvmValue = gvar; 591 llvmValue = gvar;
592 592
593 // if extern don't emit initializer 593 // if extern don't emit initializer
594 if (!(storage_class & STCextern)) 594 if (!(storage_class & STCextern))
595 { 595 {
596 _init = LLVM_DtoConstInitializer(t, init); 596 _init = DtoConstInitializer(t, init);
597 597
598 //Logger::cout() << "initializer: " << *_init << '\n'; 598 //Logger::cout() << "initializer: " << *_init << '\n';
599 if (_type != _init->getType()) { 599 if (_type != _init->getType()) {
600 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; 600 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
601 // zero initalizer 601 // zero initalizer
612 _init = ts->sym->llvmInitZ; 612 _init = ts->sym->llvmInitZ;
613 } 613 }
614 // array single value init 614 // array single value init
615 else if (llvm::isa<llvm::ArrayType>(_type)) 615 else if (llvm::isa<llvm::ArrayType>(_type))
616 { 616 {
617 _init = LLVM_DtoConstStaticArray(_type, _init); 617 _init = DtoConstStaticArray(_type, _init);
618 } 618 }
619 else { 619 else {
620 Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; 620 Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
621 //assert(0); 621 //assert(0);
622 } 622 }
635 // inside aggregate declaration. declare a field. 635 // inside aggregate declaration. declare a field.
636 else 636 else
637 { 637 {
638 Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); 638 Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset);
639 639
640 Type* t = LLVM_DtoDType(type); 640 Type* t = DtoDType(type);
641 const llvm::Type* _type = LLVM_DtoType(t); 641 const llvm::Type* _type = DtoType(t);
642 642
643 llvm::Constant*_init = LLVM_DtoConstInitializer(t, init); 643 llvm::Constant*_init = DtoConstInitializer(t, init);
644 assert(_init); 644 assert(_init);
645 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; 645 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n';
646 if (_type != _init->getType()) 646 if (_type != _init->getType())
647 { 647 {
648 if (t->ty == Tsarray) 648 if (t->ty == Tsarray)
714 if (isUnitTestDeclaration()) { 714 if (isUnitTestDeclaration()) {
715 Logger::println("*** ATTENTION: ignoring unittest declaration: %s", toChars()); 715 Logger::println("*** ATTENTION: ignoring unittest declaration: %s", toChars());
716 return; 716 return;
717 } 717 }
718 718
719 Type* t = LLVM_DtoDType(type); 719 Type* t = DtoDType(type);
720 TypeFunction* f = (TypeFunction*)t; 720 TypeFunction* f = (TypeFunction*)t;
721 721
722 bool declareOnly = false; 722 bool declareOnly = false;
723 if (TemplateInstance* tinst = parent->isTemplateInstance()) { 723 if (TemplateInstance* tinst = parent->isTemplateInstance()) {
724 TemplateDeclaration* tempdecl = tinst->tempdecl; 724 TemplateDeclaration* tempdecl = tinst->tempdecl;
734 llvmInternal = LLVMva_arg; 734 llvmInternal = LLVMva_arg;
735 return; 735 return;
736 } 736 }
737 } 737 }
738 738
739 llvm::Function* func = LLVM_DtoDeclareFunction(this); 739 llvm::Function* func = DtoDeclareFunction(this);
740 740
741 if (declareOnly) 741 if (declareOnly)
742 return; 742 return;
743 743
744 if (!gIR->structs.empty() && gIR->topstruct().queueFuncs) { 744 if (!gIR->structs.empty() && gIR->topstruct().queueFuncs) {
828 if (vd->isParameter()) { 828 if (vd->isParameter()) {
829 assert(vd->llvmValue); 829 assert(vd->llvmValue);
830 nestTypes.push_back(vd->llvmValue->getType()); 830 nestTypes.push_back(vd->llvmValue->getType());
831 } 831 }
832 else { 832 else {
833 nestTypes.push_back(LLVM_DtoType(vd->type)); 833 nestTypes.push_back(DtoType(vd->type));
834 } 834 }
835 } 835 }
836 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes); 836 const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
837 Logger::cout() << "nested var struct has type:" << '\n' << *nestSType; 837 Logger::cout() << "nested var struct has type:" << '\n' << *nestSType;
838 llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",f->llvmAllocaPoint); 838 llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",f->llvmAllocaPoint);
839 if (parentNested) { 839 if (parentNested) {
840 assert(llvmThisVar); 840 assert(llvmThisVar);
841 llvm::Value* ptr = gIR->ir->CreateBitCast(llvmThisVar, parentNested->getType(), "tmp"); 841 llvm::Value* ptr = gIR->ir->CreateBitCast(llvmThisVar, parentNested->getType(), "tmp");
842 gIR->ir->CreateStore(ptr, LLVM_DtoGEPi(llvmNested, 0,0, "tmp")); 842 gIR->ir->CreateStore(ptr, DtoGEPi(llvmNested, 0,0, "tmp"));
843 } 843 }
844 for (std::set<VarDeclaration*>::iterator i=llvmNestedVars.begin(); i!=llvmNestedVars.end(); ++i) { 844 for (std::set<VarDeclaration*>::iterator i=llvmNestedVars.begin(); i!=llvmNestedVars.end(); ++i) {
845 VarDeclaration* vd = *i; 845 VarDeclaration* vd = *i;
846 if (vd->isParameter()) { 846 if (vd->isParameter()) {
847 gIR->ir->CreateStore(vd->llvmValue, LLVM_DtoGEPi(llvmNested, 0, vd->llvmNestedIndex, "tmp")); 847 gIR->ir->CreateStore(vd->llvmValue, DtoGEPi(llvmNested, 0, vd->llvmNestedIndex, "tmp"));
848 vd->llvmValue = llvmNested; 848 vd->llvmValue = llvmNested;
849 } 849 }
850 } 850 }
851 } 851 }
852 852