comparison gen/toobj.c @ 40:8b0e809563df trunk

[svn r44] Lots of bug fixes. New array literal support New array ~= operator support (for single element) New with statement support More...
author lindquist
date Fri, 19 Oct 2007 07:43:21 +0200
parents 27b2f40bdb58
children 6fcc08a4d406
comparison
equal deleted inserted replaced
39:fd5e8bbfcb25 40:8b0e809563df
9 9
10 #include <cstddef> 10 #include <cstddef>
11 #include <iostream> 11 #include <iostream>
12 #include <fstream> 12 #include <fstream>
13 13
14 #include "llvm/Type.h" 14 #include "gen/llvm.h"
15 #include "llvm/Constants.h"
16 #include "llvm/DerivedTypes.h"
17 #include "llvm/Instructions.h"
18 #include "llvm/Analysis/Verifier.h" 15 #include "llvm/Analysis/Verifier.h"
19 #include "llvm/Bitcode/ReaderWriter.h" 16 #include "llvm/Bitcode/ReaderWriter.h"
20
21 #include "llvm/Target/TargetData.h"
22 #include "llvm/Target/TargetMachine.h" 17 #include "llvm/Target/TargetMachine.h"
23 #include "llvm/Target/TargetMachineRegistry.h" 18 #include "llvm/Target/TargetMachineRegistry.h"
24 19
25 #include "mars.h" 20 #include "mars.h"
26 #include "module.h" 21 #include "module.h"
150 { 145 {
151 Logger::println("checking for offset %u type %s:", os, t->toChars()); 146 Logger::println("checking for offset %u type %s:", os, t->toChars());
152 LOG_SCOPE; 147 LOG_SCOPE;
153 for (unsigned i=0; i<fields.dim; ++i) { 148 for (unsigned i=0; i<fields.dim; ++i) {
154 VarDeclaration* vd = (VarDeclaration*)fields.data[i]; 149 VarDeclaration* vd = (VarDeclaration*)fields.data[i];
155 Logger::println("found %u type %s", vd->offset, vd->type->toChars()); 150 Type* vdtype = LLVM_DtoDType(vd->type);
156 if (os == vd->offset && vd->type == t) { 151 Logger::println("found %u type %s", vd->offset, vdtype->toChars());
152 if (os == vd->offset && vdtype == t) {
157 result.push_back(i); 153 result.push_back(i);
158 return; 154 return;
159 } 155 }
160 else if (vd->type->ty == Tstruct && (vd->offset + vd->type->size()) > os) { 156 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
161 TypeStruct* ts = (TypeStruct*)vd->type; 157 TypeStruct* ts = (TypeStruct*)vdtype;
162 StructDeclaration* sd = ts->sym; 158 StructDeclaration* sd = ts->sym;
163 result.push_back(i); 159 result.push_back(i);
164 sd->offsetToIndex(t, os - vd->offset, result); 160 sd->offsetToIndex(t, os - vd->offset, result);
165 return; 161 return;
166 } 162 }
210 206
211 /* ================================================================== */ 207 /* ================================================================== */
212 208
213 void StructDeclaration::toObjFile() 209 void StructDeclaration::toObjFile()
214 { 210 {
215 TypeStruct* ts = (TypeStruct*)type; 211 TypeStruct* ts = (TypeStruct*)LLVM_DtoDType(type);
216 if (llvmType != 0) 212 if (llvmType != 0)
217 return; 213 return;
218 214
219 static int sdi = 0; 215 static int sdi = 0;
220 Logger::print("StructDeclaration::toObjFile(%d): %s\n", sdi++, toChars()); 216 Logger::print("StructDeclaration::toObjFile(%d): %s\n", sdi++, toChars());
286 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, _init, initname, gIR->module); 282 llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, _init, initname, gIR->module);
287 ts->llvmInit = initvar; 283 ts->llvmInit = initvar;
288 284
289 // generate member function definitions 285 // generate member function definitions
290 gIR->topstruct().queueFuncs = false; 286 gIR->topstruct().queueFuncs = false;
291 IRState::FuncDeclVec& mfs = gIR->topstruct().funcs; 287 IRStruct::FuncDeclVec& mfs = gIR->topstruct().funcs;
292 size_t n = mfs.size(); 288 size_t n = mfs.size();
293 for (size_t i=0; i<n; ++i) { 289 for (size_t i=0; i<n; ++i) {
294 mfs[i]->toObjFile(); 290 mfs[i]->toObjFile();
295 } 291 }
296 292
309 // add base class data members first 305 // add base class data members first
310 for (int j=0; j<bcs->dim; j++) 306 for (int j=0; j<bcs->dim; j++)
311 { 307 {
312 BaseClass* bc = (BaseClass*)(bcs->data[j]); 308 BaseClass* bc = (BaseClass*)(bcs->data[j]);
313 assert(bc); 309 assert(bc);
310 Logger::println("Adding base class members of %s", bc->base->toChars());
311 LOG_SCOPE;
312
314 LLVM_AddBaseClassData(&bc->base->baseclasses); 313 LLVM_AddBaseClassData(&bc->base->baseclasses);
315 for (int k=0; k < bc->base->members->dim; k++) { 314 for (int k=0; k < bc->base->members->dim; k++) {
316 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]); 315 Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
317 if (dsym->isVarDeclaration()) 316 if (dsym->isVarDeclaration())
318 { 317 {
322 } 321 }
323 } 322 }
324 323
325 void ClassDeclaration::toObjFile() 324 void ClassDeclaration::toObjFile()
326 { 325 {
327 TypeClass* ts = (TypeClass*)type; 326 TypeClass* ts = (TypeClass*)LLVM_DtoDType(type);
328 if (ts->llvmType != 0 || llvmInProgress) 327 if (ts->llvmType != 0 || llvmInProgress)
329 return; 328 return;
330 329
331 llvmInProgress = true; 330 llvmInProgress = true;
332 331
451 initvar->setInitializer(_init); 450 initvar->setInitializer(_init);
452 } 451 }
453 452
454 // generate member function definitions 453 // generate member function definitions
455 gIR->topstruct().queueFuncs = false; 454 gIR->topstruct().queueFuncs = false;
456 IRState::FuncDeclVec& mfs = gIR->topstruct().funcs; 455 IRStruct::FuncDeclVec& mfs = gIR->topstruct().funcs;
457 size_t n = mfs.size(); 456 size_t n = mfs.size();
458 for (size_t i=0; i<n; ++i) { 457 for (size_t i=0; i<n; ++i) {
459 mfs[i]->toObjFile(); 458 mfs[i]->toObjFile();
460 } 459 }
461 460
477 476
478 /* ================================================================== */ 477 /* ================================================================== */
479 478
480 void VarDeclaration::toObjFile() 479 void VarDeclaration::toObjFile()
481 { 480 {
482 static int vdi = 0; 481 Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
483 Logger::print("VarDeclaration::toObjFile(%d): %s | %s\n", vdi++, toChars(), type->toChars());
484 LOG_SCOPE; 482 LOG_SCOPE;
485 llvm::Module* M = gIR->module; 483 llvm::Module* M = gIR->module;
486 484
487 // handle bind pragma 485 // handle bind pragma
488 if (llvmInternal == LLVMbind) { 486 if (llvmInternal == LLVMbind) {
491 assert(llvmValue); 489 assert(llvmValue);
492 return; 490 return;
493 } 491 }
494 492
495 // global variable or magic 493 // global variable or magic
496 if (isDataseg()) 494 if (isDataseg() || parent->isModule())
497 { 495 {
496 if (llvmTouched) return;
497 else llvmTouched = true;
498
498 bool _isconst = isConst(); 499 bool _isconst = isConst();
499 500
500 llvm::GlobalValue::LinkageTypes _linkage; 501 llvm::GlobalValue::LinkageTypes _linkage;
501 if (parent->isFuncDeclaration()) 502 if (parent->isFuncDeclaration())
502 _linkage = llvm::GlobalValue::InternalLinkage; 503 _linkage = llvm::GlobalValue::InternalLinkage;
503 else 504 else
504 _linkage = LLVM_DtoLinkage(protection, storage_class); 505 _linkage = LLVM_DtoLinkage(protection, storage_class);
505 506
506 const llvm::Type* _type = LLVM_DtoType(type); 507 Type* t = LLVM_DtoDType(type);
508
509 const llvm::Type* _type = LLVM_DtoType(t);
507 assert(_type); 510 assert(_type);
508 511
509 llvm::Constant* _init = 0; 512 llvm::Constant* _init = 0;
510 bool _signed = !type->isunsigned(); 513 bool _signed = !type->isunsigned();
511 514
512 Logger::println("Creating global variable"); 515 Logger::println("Creating global variable");
513 std::string _name(mangle()); 516 std::string _name(mangle());
514 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M); 517 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M);
515 llvmValue = gvar; 518 llvmValue = gvar;
519
516 gIR->lvals.push_back(gvar); 520 gIR->lvals.push_back(gvar);
517 521 _init = LLVM_DtoConstInitializer(t, init);
518 _init = LLVM_DtoInitializer(type, init); 522 gIR->lvals.pop_back();
519 assert(_init);
520 523
521 //Logger::cout() << "initializer: " << *_init << '\n'; 524 //Logger::cout() << "initializer: " << *_init << '\n';
522 if (_type != _init->getType()) { 525 if (_type != _init->getType()) {
523 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n"; 526 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
524 // zero initalizer 527 // zero initalizer
527 // pointer to global constant (struct.init) 530 // pointer to global constant (struct.init)
528 else if (llvm::isa<llvm::GlobalVariable>(_init)) 531 else if (llvm::isa<llvm::GlobalVariable>(_init))
529 { 532 {
530 assert(_init->getType()->getContainedType(0) == _type); 533 assert(_init->getType()->getContainedType(0) == _type);
531 llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init); 534 llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
532 assert(type->ty == Tstruct); 535 assert(t->ty == Tstruct);
533 TypeStruct* ts = (TypeStruct*)type; 536 TypeStruct* ts = (TypeStruct*)t;
534 assert(ts->sym->llvmInitZ); 537 assert(ts->sym->llvmInitZ);
535 _init = ts->sym->llvmInitZ; 538 _init = ts->sym->llvmInitZ;
536 } 539 }
537 // array single value init 540 // array single value init
538 else if (llvm::isa<llvm::ArrayType>(_type)) 541 else if (llvm::isa<llvm::ArrayType>(_type))
547 Logger::cout() << "Unexpected initializer type: " << *_type << '\n'; 550 Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
548 //assert(0); 551 //assert(0);
549 } 552 }
550 } 553 }
551 554
552 gIR->lvals.pop_back();
553
554 gvar->setInitializer(_init); 555 gvar->setInitializer(_init);
556
557 llvmDModule = gIR->dmodule;
555 558
556 //if (storage_class & STCprivate) 559 //if (storage_class & STCprivate)
557 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility); 560 // gvar->setVisibility(llvm::GlobalValue::ProtectedVisibility);
558 } 561 }
559 562
560 // inside aggregate declaration. declare a field. 563 // inside aggregate declaration. declare a field.
561 else 564 else
562 { 565 {
563 Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset); 566 Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset);
564 567
565 const llvm::Type* _type = LLVM_DtoType(type); 568 Type* t = LLVM_DtoDType(type);
569 const llvm::Type* _type = LLVM_DtoType(t);
566 gIR->topstruct().fields.push_back(_type); 570 gIR->topstruct().fields.push_back(_type);
567 571
568 llvm::Constant*_init = LLVM_DtoInitializer(type, init); 572 llvm::Constant*_init = LLVM_DtoConstInitializer(t, init);
569 assert(_init); 573 assert(_init);
570 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n'; 574 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n';
571 if (!_init || _type != _init->getType()) 575 if (_type != _init->getType())
572 { 576 {
573 if (type->ty == Tsarray) 577 if (t->ty == Tsarray)
574 { 578 {
575 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(_type); 579 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(_type);
576 uint64_t n = arrty->getNumElements(); 580 uint64_t n = arrty->getNumElements();
577 std::vector<llvm::Constant*> vals(n,_init); 581 std::vector<llvm::Constant*> vals(n,_init);
578 _init = llvm::ConstantArray::get(arrty, vals); 582 _init = llvm::ConstantArray::get(arrty, vals);
579 } 583 }
580 else if (type->ty == Tarray) 584 else if (t->ty == Tarray)
581 { 585 {
582 assert(llvm::isa<llvm::StructType>(_type)); 586 assert(llvm::isa<llvm::StructType>(_type));
583 _init = llvm::ConstantAggregateZero::get(_type); 587 _init = llvm::ConstantAggregateZero::get(_type);
584 } 588 }
585 else if (type->ty == Tstruct) 589 else if (t->ty == Tstruct)
586 { 590 {
587 const llvm::StructType* structty = llvm::cast<llvm::StructType>(_type); 591 const llvm::StructType* structty = llvm::cast<llvm::StructType>(_type);
588 TypeStruct* ts = (TypeStruct*)type; 592 TypeStruct* ts = (TypeStruct*)t;
589 assert(ts); 593 assert(ts);
590 assert(ts->sym); 594 assert(ts->sym);
591 assert(ts->sym->llvmInitZ); 595 assert(ts->sym->llvmInitZ);
592 _init = ts->sym->llvmInitZ; 596 _init = ts->sym->llvmInitZ;
593 } 597 }
594 else if (type->ty == Tclass) 598 else if (t->ty == Tclass)
595 { 599 {
596 _init = llvm::Constant::getNullValue(_type); 600 _init = llvm::Constant::getNullValue(_type);
597 } 601 }
598 else { 602 else {
599 Logger::println("failed for type %s", type->toChars()); 603 Logger::println("failed for type %s", type->toChars());
642 llvmQueued = true; 646 llvmQueued = true;
643 } 647 }
644 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete 648 return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete
645 } 649 }
646 650
647 TypeFunction* f = (TypeFunction*)type; 651 Type* t = LLVM_DtoDType(type);
652 TypeFunction* f = (TypeFunction*)t;
648 assert(f->llvmType); 653 assert(f->llvmType);
649 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0)); 654 const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0));
650 655
651 // only members of the current module maybe be defined 656 // only members of the current module maybe be defined
652 if (getModule() == gIR->dmodule || parent->isTemplateInstance()) 657 if (getModule() == gIR->dmodule || parent->isTemplateInstance())
682 } 687 }
683 688
684 // function definition 689 // function definition
685 if (allow_fbody && fbody != 0) 690 if (allow_fbody && fbody != 0)
686 { 691 {
687 gIR->funcdecls.push_back(this); 692 gIR->functions.push_back(IRFunction(this));
693 gIR->func().func = func;
688 694
689 // first make absolutely sure the type is up to date 695 // first make absolutely sure the type is up to date
690 f->llvmType = llvmValue->getType()->getContainedType(0); 696 f->llvmType = llvmValue->getType()->getContainedType(0);
691 697
692 Logger::cout() << "func type: " << *f->llvmType << '\n'; 698 Logger::cout() << "func type: " << *f->llvmType << '\n';
701 } 707 }
702 708
703 if (isMain()) 709 if (isMain())
704 gIR->emitMain = true; 710 gIR->emitMain = true;
705 711
706 gIR->funcs.push(func); 712 llvm::BasicBlock* beginbb = new llvm::BasicBlock("entry",func);
707 gIR->functypes.push(f); 713 llvm::BasicBlock* endbb = new llvm::BasicBlock("endentry",func);
708
709 IRScope irs;
710 irs.begin = new llvm::BasicBlock("entry",func);
711 irs.end = new llvm::BasicBlock("endentry",func);
712 714
713 //assert(gIR->scopes.empty()); 715 //assert(gIR->scopes.empty());
714 gIR->scopes.push_back(irs); 716 gIR->scopes.push_back(IRScope(beginbb, endbb));
715 717
716 // create alloca point 718 // create alloca point
717 f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb()); 719 f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb());
720 gIR->func().allocapoint = f->llvmAllocaPoint;
718 721
719 // output function body 722 // output function body
720 fbody->toIR(gIR); 723 fbody->toIR(gIR);
721 724
722 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement 725 // llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
723 // in automatically, so we do it here. 726 // in automatically, so we do it here.
724 if (!isMain() && (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back()))) { 727 if (!isMain()) {
725 // pass the previous block into this block 728 if (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back())) {
726 //new llvm::BranchInst(irs.end, irs.begin); 729 // pass the previous block into this block
727 new llvm::ReturnInst(gIR->scopebb()); 730 //new llvm::BranchInst(irs.end, irs.begin);
731 if (func->getReturnType() == llvm::Type::VoidTy) {
732 new llvm::ReturnInst(gIR->scopebb());
733 }
734
735 }
728 } 736 }
729 737
730 // erase alloca point 738 // erase alloca point
731 f->llvmAllocaPoint->eraseFromParent(); 739 f->llvmAllocaPoint->eraseFromParent();
732 f->llvmAllocaPoint = 0; 740 f->llvmAllocaPoint = 0;
741 gIR->func().allocapoint = 0;
733 742
734 gIR->scopes.pop_back(); 743 gIR->scopes.pop_back();
735 //assert(gIR->scopes.empty());
736
737 gIR->functypes.pop();
738 gIR->funcs.pop();
739 744
740 // get rid of the endentry block, it's never used 745 // get rid of the endentry block, it's never used
741 assert(!func->getBasicBlockList().empty()); 746 assert(!func->getBasicBlockList().empty());
742 func->getBasicBlockList().pop_back(); 747 func->getBasicBlockList().pop_back();
743 748
744 // if the last block is empty now, it must be unreachable or it's a bug somewhere else 749 // if the last block is empty now, it must be unreachable or it's a bug somewhere else
745 // would be nice to figure out how to assert that this is correct 750 // would be nice to figure out how to assert that this is correct
746 llvm::BasicBlock* lastbb = &func->getBasicBlockList().back(); 751 llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
747 if (lastbb->empty()) { 752 if (lastbb->empty()) {
748 // possibly assert(lastbb->getNumPredecessors() == 0); ??? try it out sometime ... 753 lastbb->eraseFromParent();
749 new llvm::UnreachableInst(lastbb); 754 }
750 } 755
751 756 gIR->functions.pop_back();
752 gIR->funcdecls.pop_back();
753 } 757 }
754 758
755 // template instances should have weak linkage 759 // template instances should have weak linkage
756 if (parent->isTemplateInstance()) { 760 if (parent->isTemplateInstance()) {
757 func->setLinkage(llvm::GlobalValue::WeakLinkage); 761 func->setLinkage(llvm::GlobalValue::WeakLinkage);