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