comparison gen/toobj.c @ 52:0c77619e803b trunk

[svn r56] Initial support for TypeInfo. Enums not work. Several other bugfixes.
author lindquist
date Tue, 23 Oct 2007 05:55:12 +0200
parents 6fcc08a4d406
children 28e99b04a132
comparison
equal deleted inserted replaced
51:61bc1b4ad3c4 52:0c77619e803b
96 } 96 }
97 97
98 // run passes 98 // run passes
99 // TODO 99 // TODO
100 100
101 /*if (global.params.llvmLL) {
102 //assert(0);
103 std::ofstream os(llfile->name->toChars());
104 //llvm::WriteAssemblyToFile(ir.module, os);
105 ir.module->print(os);
106 }*/
107
108 // write bytecode 101 // write bytecode
109 //if (global.params.llvmBC) { 102 {
110 Logger::println("Writing LLVM bitcode\n"); 103 Logger::println("Writing LLVM bitcode\n");
111 std::ofstream os(bcfile->name->toChars(), std::ios::binary); 104 std::ofstream bos(bcfile->name->toChars(), std::ios::binary);
112 llvm::WriteBitcodeToFile(ir.module, os); 105 llvm::WriteBitcodeToFile(ir.module, bos);
113 //} 106 }
107
108 // disassemble ?
109 if (global.params.disassemble) {
110 Logger::println("Writing LLVM asm to: %s\n", llfile->name->toChars());
111 std::ofstream aos(llfile->name->toChars());
112 ir.module->print(aos);
113 }
114 114
115 delete ir.module; 115 delete ir.module;
116 gIR = NULL; 116 gIR = NULL;
117 } 117 }
118 118
293 llvmDModule = gIR->dmodule; 293 llvmDModule = gIR->dmodule;
294 294
295 gIR->structs.pop_back(); 295 gIR->structs.pop_back();
296 296
297 // generate typeinfo 297 // generate typeinfo
298 type->getTypeInfo(NULL); // generate TypeInfo 298 //type->getTypeInfo(NULL);
299 } 299 }
300 300
301 /* ================================================================== */ 301 /* ================================================================== */
302 302
303 static void LLVM_AddBaseClassData(BaseClasses* bcs) 303 static void LLVM_AddBaseClassData(BaseClasses* bcs)
405 const llvm::StructType* svtbl_ty = 0; 405 const llvm::StructType* svtbl_ty = 0;
406 if (!sinits.empty()) 406 if (!sinits.empty())
407 { 407 {
408 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage; 408 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
409 409
410 std::string varname(mangle()); 410 std::string varname("_D");
411 varname.append("__vtblZ"); 411 varname.append(mangle());
412 varname.append("6__vtblZ");
413
412 std::string styname(mangle()); 414 std::string styname(mangle());
413 styname.append("__vtblTy"); 415 styname.append("__vtblTy");
414 416
415 svtbl_ty = llvm::StructType::get(sinits_ty); 417 svtbl_ty = llvm::StructType::get(sinits_ty);
416 gIR->module->addTypeName(styname, svtbl_ty); 418 gIR->module->addTypeName(styname, svtbl_ty);
439 assert(svtblVar != 0); 441 assert(svtblVar != 0);
440 gIR->topstruct().inits[0] = svtblVar; 442 gIR->topstruct().inits[0] = svtblVar;
441 443
442 _init = llvm::ConstantStruct::get(structtype,gIR->topstruct().inits); 444 _init = llvm::ConstantStruct::get(structtype,gIR->topstruct().inits);
443 assert(_init); 445 assert(_init);
444 std::string initname(mangle()); 446
445 initname.append("__initZ"); 447 std::string initname("_D");
448 initname.append(mangle());
449 initname.append("6__initZ");
446 //Logger::cout() << *_init << '\n'; 450 //Logger::cout() << *_init << '\n';
447 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, 0, initname, gIR->module); 451 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, 0, initname, gIR->module);
448 ts->llvmInit = initvar; 452 ts->llvmInit = initvar;
449 if (define_vtable) { 453 if (define_vtable) {
450 initvar->setInitializer(_init); 454 initvar->setInitializer(_init);
497 else llvmTouched = true; 501 else llvmTouched = true;
498 502
499 bool _isconst = isConst(); 503 bool _isconst = isConst();
500 504
501 llvm::GlobalValue::LinkageTypes _linkage; 505 llvm::GlobalValue::LinkageTypes _linkage;
502 if (parent->isFuncDeclaration()) 506 if (parent && parent->isFuncDeclaration())
503 _linkage = llvm::GlobalValue::InternalLinkage; 507 _linkage = llvm::GlobalValue::InternalLinkage;
504 else 508 else
505 _linkage = LLVM_DtoLinkage(protection, storage_class); 509 _linkage = LLVM_DtoLinkage(protection, storage_class);
506 510
507 Type* t = LLVM_DtoDType(type); 511 Type* t = LLVM_DtoDType(type);
512 llvm::Constant* _init = 0; 516 llvm::Constant* _init = 0;
513 bool _signed = !type->isunsigned(); 517 bool _signed = !type->isunsigned();
514 518
515 Logger::println("Creating global variable"); 519 Logger::println("Creating global variable");
516 std::string _name(mangle()); 520 std::string _name(mangle());
521
517 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); 522 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M);
518 llvmValue = gvar; 523 llvmValue = gvar;
519 524
520 gIR->lvals.push_back(gvar); 525 // if extern don't emit initializer
521 _init = LLVM_DtoConstInitializer(t, init); 526 if (!(storage_class & STCextern))
522 gIR->lvals.pop_back(); 527 {
523 528 gIR->lvals.push_back(gvar);
524 //Logger::cout() << "initializer: " << *_init << '\n'; 529 _init = LLVM_DtoConstInitializer(t, init);
525 if (_type != _init->getType()) { 530 gIR->lvals.pop_back();
526 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; 531
527 // zero initalizer 532 //Logger::cout() << "initializer: " << *_init << '\n';
528 if (_init->isNullValue()) 533 if (_type != _init->getType()) {
529 _init = llvm::Constant::getNullValue(_type); 534 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
530 // pointer to global constant (struct.init) 535 // zero initalizer
531 else if (llvm::isa<llvm::GlobalVariable>(_init)) 536 if (_init->isNullValue())
532 { 537 _init = llvm::Constant::getNullValue(_type);
533 assert(_init->getType()->getContainedType(0) == _type); 538 // pointer to global constant (struct.init)
534 llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); 539 else if (llvm::isa<llvm::GlobalVariable>(_init))
535 assert(t->ty == Tstruct); 540 {
536 TypeStruct* ts = (TypeStruct*)t; 541 assert(_init->getType()->getContainedType(0) == _type);
537 assert(ts->sym->llvmInitZ); 542 llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
538 _init = ts->sym->llvmInitZ; 543 assert(t->ty == Tstruct);
539 } 544 TypeStruct* ts = (TypeStruct*)t;
540 // array single value init 545 assert(ts->sym->llvmInitZ);
541 else if (llvm::isa<llvm::ArrayType>(_type)) 546 _init = ts->sym->llvmInitZ;
542 { 547 }
543 const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(_type); 548 // array single value init
544 assert(_type->getContainedType(0) == _init->getType()); 549 else if (llvm::isa<llvm::ArrayType>(_type))
545 std::vector<llvm::Constant*> initvals; 550 {
546 initvals.resize(at->getNumElements(), _init); 551 const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(_type);
547 _init = llvm::ConstantArray::get(at, initvals); 552 assert(_type->getContainedType(0) == _init->getType());
548 } 553 std::vector<llvm::Constant*> initvals;
549 else { 554 initvals.resize(at->getNumElements(), _init);
550 Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; 555 _init = llvm::ConstantArray::get(at, initvals);
551 //assert(0); 556 }
552 } 557 else {
553 } 558 Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
554 559 //assert(0);
555 gvar->setInitializer(_init); 560 }
556 561 }
562
563 gvar->setInitializer(_init);
564 }
565
557 llvmDModule = gIR->dmodule; 566 llvmDModule = gIR->dmodule;
558 567
559 //if (storage_class & STCprivate) 568 //if (storage_class & STCprivate)
560 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); 569 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility);
561 } 570 }
616 { 625 {
617 static int tdi = 0; 626 static int tdi = 0;
618 Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars()); 627 Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
619 LOG_SCOPE; 628 LOG_SCOPE;
620 629
621 // TODO 630 // generate typeinfo
631 type->getTypeInfo(NULL);
622 } 632 }
623 633
624 /* ================================================================== */ 634 /* ================================================================== */
625 635
626 void EnumDeclaration::toObjFile() 636 void EnumDeclaration::toObjFile()
693 gIR->func().func = func; 703 gIR->func().func = func;
694 704
695 // first make absolutely sure the type is up to date 705 // first make absolutely sure the type is up to date
696 f->llvmType = llvmValue->getType()->getContainedType(0); 706 f->llvmType = llvmValue->getType()->getContainedType(0);
697 707
698 Logger::cout() << "func type: " << *f->llvmType << '\n'; 708 //Logger::cout() << "func type: " << *f->llvmType << '\n';
699 709
700 // this handling 710 // this handling
701 if (f->llvmUsesThis) { 711 if (f->llvmUsesThis) {
702 Logger::println("uses this"); 712 Logger::println("uses this");
703 if (f->llvmRetInPtr) 713 if (f->llvmRetInPtr)
752 fbody->toIR(gIR); 762 fbody->toIR(gIR);
753 763
754 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 764 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
755 // in automatically, so we do it here. 765 // in automatically, so we do it here.
756 if (!isMain()) { 766 if (!isMain()) {
757 if (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back())) { 767 if (!gIR->scopereturned()) {
758 // pass the previous block into this block 768 // pass the previous block into this block
759 //new llvm::BranchInst(irs.end, irs.begin); 769 //new llvm::BranchInst(irs.end, irs.begin);
760 if (func->getReturnType() == llvm::Type::VoidTy) { 770 if (func->getReturnType() == llvm::Type::VoidTy) {
761 new llvm::ReturnInst(gIR->scopebb()); 771 new llvm::ReturnInst(gIR->scopebb());
762 } 772 }
773 else {
774 new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());
775 }
763 } 776 }
764 } 777 }
765 778
766 // erase alloca point 779 // erase alloca point
767 f->llvmAllocaPoint->eraseFromParent(); 780 f->llvmAllocaPoint->eraseFromParent();
776 789
777 // if the last block is empty now, it must be unreachable or it's a bug somewhere else 790 // if the last block is empty now, it must be unreachable or it's a bug somewhere else
778 // would be nice to figure out how to assert that this is correct 791 // would be nice to figure out how to assert that this is correct
779 llvm::BasicBlock* lastbb = &func->getBasicBlockList().back(); 792 llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
780 if (lastbb->empty()) { 793 if (lastbb->empty()) {
781 lastbb->eraseFromParent(); 794 if (lastbb->getNumUses() == 0)
795 lastbb->eraseFromParent();
796 else {
797 new llvm::UnreachableInst(lastbb);
798 /*if (func->getReturnType() == llvm::Type::VoidTy) {
799 new llvm::ReturnInst(lastbb);
800 }
801 else {
802 new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), lastbb);
803 }*/
804 }
782 } 805 }
783 806
784 gIR->functions.pop_back(); 807 gIR->functions.pop_back();
785 } 808 }
786 809