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