comparison gen/tollvm.cpp @ 136:0e28624814e8 trunk

[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
author lindquist
date Thu, 17 Jan 2008 03:15:12 +0100
parents 176bd52b3cf5
children ce7b81fb957f
comparison
equal deleted inserted replaced
135:176bd52b3cf5 136:0e28624814e8
1 #include <iostream> 1 #include <iostream>
2 2
3 #include "gen/llvm.h" 3 #include "gen/llvm.h"
4 4
5 #include "mtype.h"
6 #include "dsymbol.h" 5 #include "dsymbol.h"
7 #include "aggregate.h" 6 #include "aggregate.h"
8 #include "declaration.h" 7 #include "declaration.h"
9 #include "init.h" 8 #include "init.h"
10 9
101 case Tstruct: { 100 case Tstruct: {
102 if (!t->llvmType || *t->llvmType == NULL) { 101 if (!t->llvmType || *t->llvmType == NULL) {
103 // recursive or cyclic declaration 102 // recursive or cyclic declaration
104 if (!gIR->structs.empty()) 103 if (!gIR->structs.empty())
105 { 104 {
106 IRStruct* found = 0; 105 IrStruct* found = 0;
107 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) 106 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
108 { 107 {
109 if (t == (*i)->type) 108 if (t == (*i)->type)
110 { 109 {
111 return (*i)->recty.get(); 110 return (*i)->recty.get();
115 } 114 }
116 115
117 TypeStruct* ts = (TypeStruct*)t; 116 TypeStruct* ts = (TypeStruct*)t;
118 assert(ts->sym); 117 assert(ts->sym);
119 DtoResolveDsymbol(ts->sym); 118 DtoResolveDsymbol(ts->sym);
120 return ts->sym->llvmIRStruct->recty.get();//t->llvmType->get(); 119 return ts->sym->llvmIrStruct->recty.get();//t->llvmType->get();
121 } 120 }
122 121
123 case Tclass: { 122 case Tclass: {
124 /*if (!t->llvmType || *t->llvmType == NULL) { 123 /*if (!t->llvmType || *t->llvmType == NULL) {
125 // recursive or cyclic declaration 124 // recursive or cyclic declaration
126 if (!gIR->structs.empty()) 125 if (!gIR->structs.empty())
127 { 126 {
128 IRStruct* found = 0; 127 IrStruct* found = 0;
129 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) 128 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
130 { 129 {
131 if (t == (*i)->type) 130 if (t == (*i)->type)
132 { 131 {
133 return getPtrToType((*i)->recty.get()); 132 return getPtrToType((*i)->recty.get());
138 }*/ 137 }*/
139 138
140 TypeClass* tc = (TypeClass*)t; 139 TypeClass* tc = (TypeClass*)t;
141 assert(tc->sym); 140 assert(tc->sym);
142 DtoResolveDsymbol(tc->sym); 141 DtoResolveDsymbol(tc->sym);
143 return getPtrToType(tc->sym->llvmIRStruct->recty.get());//t->llvmType->get()); 142 return getPtrToType(tc->sym->llvmIrStruct->recty.get());//t->llvmType->get());
144 } 143 }
145 144
146 // functions 145 // functions
147 case Tfunction: 146 case Tfunction:
148 { 147 {
685 if (!p->isFuncDeclaration() && !p->isClassDeclaration()) 684 if (!p->isFuncDeclaration() && !p->isClassDeclaration())
686 Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind()); 685 Logger::println("unexpected parent symbol found while resolving frame pointer - '%s' kind: '%s'", p->toChars(), p->kind());
687 assert(p->isFuncDeclaration() || p->isClassDeclaration()); 686 assert(p->isFuncDeclaration() || p->isClassDeclaration());
688 if (FuncDeclaration* fd = p->isFuncDeclaration()) 687 if (FuncDeclaration* fd = p->isFuncDeclaration())
689 { 688 {
690 llvm::Value* v = fd->llvmNested; 689 llvm::Value* v = fd->irFunc->nestedVar;
691 assert(v); 690 assert(v);
692 return v->getType(); 691 return v->getType();
693 } 692 }
694 else if (ClassDeclaration* cd = p->isClassDeclaration()) 693 else if (ClassDeclaration* cd = p->isClassDeclaration())
695 { 694 {
715 { 714 {
716 Logger::println("scope is function: %s", fd->toChars()); 715 Logger::println("scope is function: %s", fd->toChars());
717 716
718 if (fd->toParent2() == func) 717 if (fd->toParent2() == func)
719 { 718 {
720 if (!func->llvmNested) 719 if (!func->irFunc->nestedVar)
721 return NULL; 720 return NULL;
722 return DtoBitCast(v, func->llvmNested->getType()); 721 return DtoBitCast(v, func->irFunc->nestedVar->getType());
723 } 722 }
724 723
725 v = DtoBitCast(v, get_next_frame_ptr_type(fd)); 724 v = DtoBitCast(v, get_next_frame_ptr_type(fd));
726 Logger::cout() << "v = " << *v << '\n'; 725 Logger::cout() << "v = " << *v << '\n';
727 726
731 v = DtoLoad(v); 730 v = DtoLoad(v);
732 } 731 }
733 else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration()) 732 else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
734 { 733 {
735 size_t idx = 2; 734 size_t idx = 2;
736 idx += cd->llvmIRStruct->interfaces.size(); 735 idx += cd->llvmIrStruct->interfaces.size();
737 v = DtoGEPi(v,0,idx,"tmp"); 736 v = DtoGEPi(v,0,idx,"tmp");
738 v = DtoLoad(v); 737 v = DtoLoad(v);
739 } 738 }
740 else 739 else
741 { 740 {
745 } 744 }
746 else if (ClassDeclaration* cd = sc->isClassDeclaration()) 745 else if (ClassDeclaration* cd = sc->isClassDeclaration())
747 { 746 {
748 Logger::println("scope is class: %s", cd->toChars()); 747 Logger::println("scope is class: %s", cd->toChars());
749 /*size_t idx = 2; 748 /*size_t idx = 2;
750 idx += cd->llvmIRStruct->interfaces.size(); 749 idx += cd->llvmIrStruct->interfaces.size();
751 v = DtoGEPi(v,0,idx,"tmp"); 750 v = DtoGEPi(v,0,idx,"tmp");
752 Logger::cout() << "gep = " << *v << '\n'; 751 Logger::cout() << "gep = " << *v << '\n';
753 v = DtoLoad(v);*/ 752 v = DtoLoad(v);*/
754 return get_frame_ptr_impl(func, cd->toParent2(), v); 753 return get_frame_ptr_impl(func, cd->toParent2(), v);
755 } 754 }
764 763
765 static llvm::Value* get_frame_ptr(FuncDeclaration* func) 764 static llvm::Value* get_frame_ptr(FuncDeclaration* func)
766 { 765 {
767 Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars()); 766 Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars());
768 LOG_SCOPE; 767 LOG_SCOPE;
769 IRFunction* irfunc = gIR->func(); 768 IrFunction* irfunc = gIR->func();
770 769
771 // in the right scope already 770 // in the right scope already
772 if (func == irfunc->decl) 771 if (func == irfunc->decl)
773 return irfunc->decl->llvmNested; 772 return irfunc->decl->irFunc->nestedVar;
774 773
775 // use the 'this' pointer 774 // use the 'this' pointer
776 llvm::Value* ptr = irfunc->decl->llvmThisVar; 775 llvm::Value* ptr = irfunc->decl->irFunc->thisVar;
777 assert(ptr); 776 assert(ptr);
778 777
779 // return the fully resolved frame pointer 778 // return the fully resolved frame pointer
780 ptr = get_frame_ptr_impl(func, irfunc->decl, ptr); 779 ptr = get_frame_ptr_impl(func, irfunc->decl, ptr);
781 if (ptr) Logger::cout() << "Found context!" << *ptr; 780 if (ptr) Logger::cout() << "Found context!" << *ptr;
828 ////////////////////////////////////////////////////////////////////////////////////////// 827 //////////////////////////////////////////////////////////////////////////////////////////
829 828
830 llvm::Value* DtoNestedVariable(VarDeclaration* vd) 829 llvm::Value* DtoNestedVariable(VarDeclaration* vd)
831 { 830 {
832 // log the frame list 831 // log the frame list
833 IRFunction* irfunc = gIR->func(); 832 IrFunction* irfunc = gIR->func();
834 if (Logger::enabled()) 833 if (Logger::enabled())
835 print_nested_frame_list(vd, irfunc->decl); 834 print_nested_frame_list(vd, irfunc->decl);
836 835
837 // resolve frame ptr 836 // resolve frame ptr
838 FuncDeclaration* func = vd->toParent2()->isFuncDeclaration(); 837 FuncDeclaration* func = vd->toParent2()->isFuncDeclaration();
839 assert(func); 838 assert(func);
840 llvm::Value* ptr = DtoNestedContext(func); 839 llvm::Value* ptr = DtoNestedContext(func);
841 assert(ptr && "nested var, but no context"); 840 assert(ptr && "nested var, but no context");
842 841
843 // we must cast here to be sure. nested classes just have a void* 842 // we must cast here to be sure. nested classes just have a void*
844 ptr = DtoBitCast(ptr, func->llvmNested->getType()); 843 ptr = DtoBitCast(ptr, func->irFunc->nestedVar->getType());
845 844
846 // index nested var and load (if necessary) 845 // index nested var and load (if necessary)
847 llvm::Value* v = DtoGEPi(ptr, 0, vd->llvmNestedIndex, "tmp"); 846 llvm::Value* v = DtoGEPi(ptr, 0, vd->irLocal->nestedIndex, "tmp");
848 // references must be loaded, for normal variables this IS already the variable storage!!! 847 // references must be loaded, for normal variables this IS already the variable storage!!!
849 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) 848 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
850 v = DtoLoad(v); 849 v = DtoLoad(v);
851 850
852 // log and return 851 // log and return
920 // assignment to this in constructor special case 919 // assignment to this in constructor special case
921 if (lhs->isThis()) { 920 if (lhs->isThis()) {
922 llvm::Value* tmp = rhs->getRVal(); 921 llvm::Value* tmp = rhs->getRVal();
923 FuncDeclaration* fdecl = gIR->func()->decl; 922 FuncDeclaration* fdecl = gIR->func()->decl;
924 // respecify the this param 923 // respecify the this param
925 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar)) 924 if (!llvm::isa<llvm::AllocaInst>(fdecl->irFunc->thisVar))
926 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); 925 fdecl->irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
927 DtoStore(tmp, fdecl->llvmThisVar); 926 DtoStore(tmp, fdecl->irFunc->thisVar);
928 } 927 }
929 // regular class ref -> class ref assignment 928 // regular class ref -> class ref assignment
930 else { 929 else {
931 DtoStore(rhs->getRVal(), lhs->getLVal()); 930 DtoStore(rhs->getRVal(), lhs->getLVal());
932 } 931 }
1582 istempl = true; 1581 istempl = true;
1583 } 1582 }
1584 1583
1585 if (_init && _init->getType() != _type) 1584 if (_init && _init->getType() != _type)
1586 _type = _init->getType(); 1585 _type = _init->getType();
1587 llvm::cast<llvm::OpaqueType>(vd->llvmIRGlobal->type.get())->refineAbstractTypeTo(_type); 1586 llvm::cast<llvm::OpaqueType>(vd->irGlobal->type.get())->refineAbstractTypeTo(_type);
1588 _type = vd->llvmIRGlobal->type.get(); 1587 _type = vd->irGlobal->type.get();
1589 assert(!_type->isAbstract()); 1588 assert(!_type->isAbstract());
1590 1589
1591 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->llvmValue); 1590 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->irGlobal->value);
1592 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) 1591 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
1593 { 1592 {
1594 gvar->setInitializer(_init); 1593 gvar->setInitializer(_init);
1595 } 1594 }
1596 1595
1741 ++p; 1740 ++p;
1742 } 1741 }
1743 // create a noop with the code as the result name! 1742 // create a noop with the code as the result name!
1744 gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str()); 1743 gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
1745 } 1744 }
1745
1746 const llvm::StructType* DtoInterfaceInfoType()
1747 {
1748 static const llvm::StructType* t = NULL;
1749 if (t)
1750 return t;
1751
1752 // build interface info type
1753 std::vector<const llvm::Type*> types;
1754 // ClassInfo classinfo
1755 ClassDeclaration* cd2 = ClassDeclaration::classinfo;
1756 DtoResolveClass(cd2);
1757 types.push_back(getPtrToType(cd2->type->llvmType->get()));
1758 // void*[] vtbl
1759 std::vector<const llvm::Type*> vtbltypes;
1760 vtbltypes.push_back(DtoSize_t());
1761 const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
1762 vtbltypes.push_back(byteptrptrty);
1763 types.push_back(llvm::StructType::get(vtbltypes));
1764 // int offset
1765 types.push_back(llvm::Type::Int32Ty);
1766 // create type
1767 t = llvm::StructType::get(types);
1768
1769 return t;
1770 }