comparison gen/tollvm.cpp @ 100:5071469303d4 trunk

[svn r104] TONS OF FIXES. Split up declaration, constant initializer gen and definition for globals, structs, classes and functions. Improved ClassInfo support (not complete), not in vtable yet. Fixed a bunch of forward reference problems. Much more. Major commit! :)
author lindquist
date Fri, 16 Nov 2007 08:21:47 +0100
parents a676a7743642
children 027b8d8b71ec
comparison
equal deleted inserted replaced
99:a676a7743642 100:5071469303d4
12 #include "gen/irstate.h" 12 #include "gen/irstate.h"
13 #include "gen/logger.h" 13 #include "gen/logger.h"
14 #include "gen/runtime.h" 14 #include "gen/runtime.h"
15 #include "gen/arrays.h" 15 #include "gen/arrays.h"
16 #include "gen/dvalue.h" 16 #include "gen/dvalue.h"
17 #include "gen/functions.h"
17 #include "gen/structs.h" 18 #include "gen/structs.h"
19 #include "gen/classes.h"
18 20
19 bool DtoIsPassedByRef(Type* type) 21 bool DtoIsPassedByRef(Type* type)
20 { 22 {
21 TY t = DtoDType(type)->ty; 23 TY t = DtoDType(type)->ty;
22 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray); 24 return (t == Tstruct || t == Tarray || t == Tdelegate || t == Tsarray);
93 case Tvoid: 95 case Tvoid:
94 return llvm::Type::VoidTy; 96 return llvm::Type::VoidTy;
95 97
96 // aggregates 98 // aggregates
97 case Tstruct: { 99 case Tstruct: {
98 if (t->llvmType == 0) 100 if (!t->llvmType || *t->llvmType == NULL) {
99 {
100 // recursive or cyclic declaration 101 // recursive or cyclic declaration
101 if (!gIR->structs.empty()) 102 if (!gIR->structs.empty())
102 { 103 {
103 IRStruct* found = 0; 104 IRStruct* found = 0;
104 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) 105 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
105 { 106 {
106 if (t == i->type) 107 if (t == (*i)->type)
107 { 108 {
108 return i->recty.get(); 109 return (*i)->recty.get();
109 } 110 }
110 } 111 }
111 } 112 }
112 113
113 // forward declaration 114 // forward declaration
114 TypeStruct* ts = (TypeStruct*)t; 115 TypeStruct* ts = (TypeStruct*)t;
115 assert(ts->sym); 116 assert(ts->sym);
116 ts->sym->toObjFile(); 117 ts->sym->toObjFile();
117 } 118 }
118 return t->llvmType; 119 return t->llvmType->get();
119 } 120 }
120 121
121 case Tclass: { 122 case Tclass: {
122 if (t->llvmType == 0) 123 if (!t->llvmType || *t->llvmType == NULL) {
123 {
124 // recursive or cyclic declaration 124 // recursive or cyclic declaration
125 if (!gIR->structs.empty()) 125 if (!gIR->structs.empty())
126 { 126 {
127 IRStruct* found = 0; 127 IRStruct* found = 0;
128 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)
129 { 129 {
130 if (t == i->type) 130 if (t == (*i)->type)
131 { 131 {
132 return llvm::PointerType::get(i->recty.get()); 132 return llvm::PointerType::get((*i)->recty.get());
133 } 133 }
134 } 134 }
135 } 135 }
136 136
137 // forward declaration 137 // forward declaration
138 TypeClass* tc = (TypeClass*)t; 138 TypeClass* tc = (TypeClass*)t;
139 assert(tc->sym); 139 assert(tc->sym);
140 tc->sym->toObjFile(); 140 tc->sym->toObjFile();
141 } 141 }
142 return llvm::PointerType::get(t->llvmType); 142 return llvm::PointerType::get(t->llvmType->get());
143 } 143 }
144 144
145 // functions 145 // functions
146 case Tfunction: 146 case Tfunction:
147 { 147 {
148 if (t->llvmType == 0) { 148 if (!t->llvmType || *t->llvmType == NULL) {
149 return DtoFunctionType(t,NULL); 149 return DtoFunctionType(t,NULL);
150 } 150 }
151 else { 151 else {
152 return t->llvmType; 152 return t->llvmType->get();
153 } 153 }
154 } 154 }
155 155
156 // delegates 156 // delegates
157 case Tdelegate: 157 case Tdelegate:
158 { 158 {
159 if (t->llvmType == 0) { 159 if (!t->llvmType || *t->llvmType == NULL) {
160 return DtoDelegateType(t); 160 return DtoDelegateType(t);
161 } 161 }
162 else { 162 else {
163 return t->llvmType; 163 return t->llvmType->get();
164 } 164 }
165 } 165 }
166 166
167 // typedefs 167 // typedefs
168 // enum 168 // enum
177 default: 177 default:
178 printf("trying to convert unknown type with value %d\n", t->ty); 178 printf("trying to convert unknown type with value %d\n", t->ty);
179 assert(0); 179 assert(0);
180 } 180 }
181 return 0; 181 return 0;
182 }
183
184 //////////////////////////////////////////////////////////////////////////////////////////
185
186 const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype, bool ismain)
187 {
188 TypeFunction* f = (TypeFunction*)type;
189 assert(f != 0);
190
191 bool typesafeVararg = false;
192 if (f->linkage == LINKd && f->varargs == 1) {
193 typesafeVararg = true;
194 }
195
196 // return value type
197 const llvm::Type* rettype;
198 const llvm::Type* actualRettype;
199 Type* rt = f->next;
200 bool retinptr = false;
201 bool usesthis = false;
202
203 if (ismain) {
204 rettype = llvm::Type::Int32Ty;
205 actualRettype = rettype;
206 }
207 else {
208 assert(rt);
209 if (DtoIsPassedByRef(rt)) {
210 rettype = llvm::PointerType::get(DtoType(rt));
211 actualRettype = llvm::Type::VoidTy;
212 f->llvmRetInPtr = retinptr = true;
213 }
214 else {
215 rettype = DtoType(rt);
216 actualRettype = rettype;
217 }
218 }
219
220 // parameter types
221 std::vector<const llvm::Type*> paramvec;
222
223 if (retinptr) {
224 Logger::cout() << "returning through pointer parameter: " << *rettype << '\n';
225 paramvec.push_back(rettype);
226 }
227
228 if (thistype) {
229 paramvec.push_back(thistype);
230 usesthis = true;
231 }
232
233 if (typesafeVararg) {
234 ClassDeclaration* ti = Type::typeinfo;
235 if (!ti->llvmInitZ)
236 ti->toObjFile();
237 assert(ti->llvmInitZ);
238 std::vector<const llvm::Type*> types;
239 types.push_back(DtoSize_t());
240 types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType())));
241 const llvm::Type* t1 = llvm::StructType::get(types);
242 paramvec.push_back(llvm::PointerType::get(t1));
243 paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty));
244 }
245
246 size_t n = Argument::dim(f->parameters);
247
248 for (int i=0; i < n; ++i) {
249 Argument* arg = Argument::getNth(f->parameters, i);
250 // ensure scalar
251 Type* argT = DtoDType(arg->type);
252 assert(argT);
253
254 if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) {
255 //assert(arg->vardecl);
256 //arg->vardecl->refparam = true;
257 }
258 else
259 arg->llvmCopy = true;
260
261 const llvm::Type* at = DtoType(argT);
262 if (isaStruct(at)) {
263 Logger::println("struct param");
264 paramvec.push_back(llvm::PointerType::get(at));
265 }
266 else if (isaArray(at)) {
267 Logger::println("sarray param");
268 assert(argT->ty == Tsarray);
269 //paramvec.push_back(llvm::PointerType::get(at->getContainedType(0)));
270 paramvec.push_back(llvm::PointerType::get(at));
271 }
272 else if (llvm::isa<llvm::OpaqueType>(at)) {
273 Logger::println("opaque param");
274 assert(argT->ty == Tstruct || argT->ty == Tclass);
275 paramvec.push_back(llvm::PointerType::get(at));
276 }
277 else {
278 if (!arg->llvmCopy) {
279 Logger::println("ref param");
280 at = llvm::PointerType::get(at);
281 }
282 else {
283 Logger::println("in param");
284 }
285 paramvec.push_back(at);
286 }
287 }
288
289 // construct function type
290 bool isvararg = !typesafeVararg && f->varargs;
291 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg);
292
293 f->llvmRetInPtr = retinptr;
294 f->llvmUsesThis = usesthis;
295 return functype;
296 }
297
298 //////////////////////////////////////////////////////////////////////////////////////////
299
300 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl)
301 {
302 TypeFunction* f = (TypeFunction*)fdecl->type;
303 assert(f != 0);
304
305 const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty);
306 std::vector<const llvm::Type*> args;
307
308 if (fdecl->llvmInternal == LLVMva_start) {
309 args.push_back(i8pty);
310 }
311 else if (fdecl->llvmInternal == LLVMva_intrinsic) {
312 size_t n = Argument::dim(f->parameters);
313 for (size_t i=0; i<n; ++i) {
314 args.push_back(i8pty);
315 }
316 }
317 else
318 assert(0);
319
320 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false);
321 f->llvmType = fty;
322 return fty;
323 }
324
325 //////////////////////////////////////////////////////////////////////////////////////////
326
327 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl)
328 {
329 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
330 return DtoVaFunctionType(fdecl);
331 }
332
333 // type has already been resolved
334 if (fdecl->type->llvmType != 0) {
335 return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType);
336 }
337
338 const llvm::Type* thisty = NULL;
339 if (fdecl->needThis()) {
340 if (AggregateDeclaration* ad = fdecl->isMember()) {
341 Logger::print("isMember = this is: %s\n", ad->type->toChars());
342 thisty = DtoType(ad->type);
343 Logger::cout() << "this llvm type: " << *thisty << '\n';
344 if (isaStruct(thisty) || thisty == gIR->topstruct().recty.get())
345 thisty = llvm::PointerType::get(thisty);
346 }
347 else
348 assert(0);
349 }
350 else if (fdecl->isNested()) {
351 thisty = llvm::PointerType::get(llvm::Type::Int8Ty);
352 }
353
354 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain());
355 fdecl->type->llvmType = functype;
356 return functype;
357 } 182 }
358 183
359 ////////////////////////////////////////////////////////////////////////////////////////// 184 //////////////////////////////////////////////////////////////////////////////////////////
360 185
361 const llvm::StructType* DtoDelegateType(Type* t) 186 const llvm::StructType* DtoDelegateType(Type* t)
628 return llvm::Type::Int32Ty; 453 return llvm::Type::Int32Ty;
629 } 454 }
630 455
631 ////////////////////////////////////////////////////////////////////////////////////////// 456 //////////////////////////////////////////////////////////////////////////////////////////
632 457
633 void DtoMain()
634 {
635 // emit main function llvm style
636 // int main(int argc, char**argv, char**env);
637
638 assert(gIR != 0);
639 IRState& ir = *gIR;
640
641 assert(ir.emitMain && ir.mainFunc);
642
643 // parameter types
644 std::vector<const llvm::Type*> pvec;
645 pvec.push_back((const llvm::Type*)llvm::Type::Int32Ty);
646 const llvm::Type* chPtrType = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty);
647 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
648 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType));
649 const llvm::Type* rettype = (const llvm::Type*)llvm::Type::Int32Ty;
650
651 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, pvec, false);
652 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module);
653
654 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func);
655
656 // call static ctors
657 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors");
658 llvm::Instruction* apt = new llvm::CallInst(fn,"",bb);
659
660 // call user main function
661 const llvm::FunctionType* mainty = ir.mainFunc->getFunctionType();
662 llvm::CallInst* call;
663 if (mainty->getNumParams() > 0)
664 {
665 // main with arguments
666 assert(mainty->getNumParams() == 1);
667 std::vector<llvm::Value*> args;
668 llvm::Function* mfn = LLVM_D_GetRuntimeFunction(ir.module,"_d_main_args");
669
670 llvm::Function::arg_iterator argi = func->arg_begin();
671 args.push_back(argi++);
672 args.push_back(argi++);
673
674 const llvm::Type* at = mainty->getParamType(0)->getContainedType(0);
675 llvm::Value* arr = new llvm::AllocaInst(at->getContainedType(1)->getContainedType(0), func->arg_begin(), "argstorage", apt);
676 llvm::Value* a = new llvm::AllocaInst(at, "argarray", apt);
677 llvm::Value* ptr = DtoGEPi(a,0,0,"tmp",bb);
678 llvm::Value* v = args[0];
679 if (v->getType() != DtoSize_t())
680 v = new llvm::ZExtInst(v, DtoSize_t(), "tmp", bb);
681 new llvm::StoreInst(v,ptr,bb);
682 ptr = DtoGEPi(a,0,1,"tmp",bb);
683 new llvm::StoreInst(arr,ptr,bb);
684 args.push_back(a);
685 new llvm::CallInst(mfn, args.begin(), args.end(), "", bb);
686 call = new llvm::CallInst(ir.mainFunc,a,"ret",bb);
687 }
688 else
689 {
690 // main with no arguments
691 call = new llvm::CallInst(ir.mainFunc,"ret",bb);
692 }
693 call->setCallingConv(ir.mainFunc->getCallingConv());
694
695 // call static dtors
696 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors");
697 new llvm::CallInst(fn,"",bb);
698
699 // return
700 new llvm::ReturnInst(call,bb);
701 }
702
703 //////////////////////////////////////////////////////////////////////////////////////////
704
705 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
706 {
707 Array* arr = &tc->sym->dtors;
708 for (size_t i=0; i<arr->dim; i++)
709 {
710 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
711 assert(fd->llvmValue);
712 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
713 }
714 }
715
716 //////////////////////////////////////////////////////////////////////////////////////////
717
718 void DtoInitClass(TypeClass* tc, llvm::Value* dst)
719 {
720 assert(gIR);
721
722 assert(tc->llvmType);
723 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t());
724 uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size;
725
726 // set vtable field
727 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
728 assert(tc->sym->llvmVtbl);
729 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb());
730
731 // copy the static initializer
732 if (n > 0) {
733 assert(tc->llvmInit);
734 assert(dst->getType() == tc->llvmInit->getType());
735
736 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
737
738 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
739 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
740
741 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
742 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
743
744 llvm::Function* fn = LLVM_DeclareMemCpy32();
745 std::vector<llvm::Value*> llargs;
746 llargs.resize(4);
747 llargs[0] = dstarr;
748 llargs[1] = srcarr;
749 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
750 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
751
752 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
753 }
754 }
755
756 //////////////////////////////////////////////////////////////////////////////////////////
757
758 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init) 458 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init)
759 { 459 {
760 llvm::Constant* _init = 0; // may return zero 460 llvm::Constant* _init = 0; // may return zero
761 if (!init) 461 if (!init)
762 { 462 {
785 _init = llvm::Constant::getNullValue(ty); 485 _init = llvm::Constant::getNullValue(ty);
786 } 486 }
787 else { 487 else {
788 Logger::println("unsupported const initializer: %s", init->toChars()); 488 Logger::println("unsupported const initializer: %s", init->toChars());
789 } 489 }
490 return _init;
491 }
492
493 //////////////////////////////////////////////////////////////////////////////////////////
494
495 llvm::Constant* DtoConstFieldInitializer(Type* t, Initializer* init)
496 {
497 Logger::println("DtoConstFieldInitializer");
498 LOG_SCOPE;
499
500 const llvm::Type* _type = DtoType(t);
501
502 llvm::Constant* _init = DtoConstInitializer(t, init);
503 assert(_init);
504 if (_type != _init->getType())
505 {
506 Logger::cout() << "field init is: " << *_init << " type should be " << *_type << '\n';
507 if (t->ty == Tsarray)
508 {
509 const llvm::ArrayType* arrty = isaArray(_type);
510 uint64_t n = arrty->getNumElements();
511 std::vector<llvm::Constant*> vals(n,_init);
512 _init = llvm::ConstantArray::get(arrty, vals);
513 }
514 else if (t->ty == Tarray)
515 {
516 assert(isaStruct(_type));
517 _init = llvm::ConstantAggregateZero::get(_type);
518 }
519 else if (t->ty == Tstruct)
520 {
521 const llvm::StructType* structty = isaStruct(_type);
522 TypeStruct* ts = (TypeStruct*)t;
523 assert(ts);
524 assert(ts->sym);
525 assert(ts->sym->llvmInitZ);
526 _init = ts->sym->llvmInitZ;
527 }
528 else if (t->ty == Tclass)
529 {
530 _init = llvm::Constant::getNullValue(_type);
531 }
532 else {
533 Logger::println("failed for type %s", t->toChars());
534 assert(0);
535 }
536 }
537
790 return _init; 538 return _init;
791 } 539 }
792 540
793 ////////////////////////////////////////////////////////////////////////////////////////// 541 //////////////////////////////////////////////////////////////////////////////////////////
794 542
852 { 600 {
853 std::vector<llvm::Value*> v(2); 601 std::vector<llvm::Value*> v(2);
854 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); 602 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false);
855 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); 603 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false);
856 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); 604 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb());
857 }
858
859 //////////////////////////////////////////////////////////////////////////////////////////
860
861 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
862 {
863 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type);
864 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl);
865 llvm::Constant* fn = 0;
866
867 if (fdecl->llvmInternal == LLVMva_start) {
868 fn = gIR->module->getOrInsertFunction("llvm.va_start", fty);
869 assert(fn);
870 }
871 else if (fdecl->llvmInternal == LLVMva_intrinsic) {
872 fn = gIR->module->getOrInsertFunction(fdecl->llvmInternal1, fty);
873 assert(fn);
874 }
875 else
876 assert(0);
877
878 llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn);
879 assert(func);
880 assert(func->isIntrinsic());
881 fdecl->llvmValue = func;
882 return func;
883 }
884
885 //////////////////////////////////////////////////////////////////////////////////////////
886
887 llvm::Function* DtoDeclareFunction(FuncDeclaration* fdecl)
888 {
889 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) {
890 return DtoDeclareVaFunction(fdecl);
891 }
892
893 // mangled name
894 char* mangled_name;
895 if (fdecl->llvmInternal == LLVMintrinsic)
896 mangled_name = fdecl->llvmInternal1;
897 else
898 mangled_name = fdecl->mangle();
899
900 // unit test special handling
901 if (fdecl->isUnitTestDeclaration())
902 {
903 assert(0 && "no unittests yet");
904 /*const llvm::FunctionType* fnty = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector<const llvm::Type*>(), false);
905 // make the function
906 llvm::Function* func = gIR->module->getFunction(mangled_name);
907 if (func == 0)
908 func = new llvm::Function(fnty,llvm::GlobalValue::InternalLinkage,mangled_name,gIR->module);
909 func->setCallingConv(llvm::CallingConv::Fast);
910 fdecl->llvmValue = func;
911 return func;
912 */
913 }
914
915 // regular function
916 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type);
917 assert(f != 0);
918
919 if (fdecl->llvmValue != 0) {
920 if (!llvm::isa<llvm::Function>(fdecl->llvmValue))
921 {
922 Logger::cout() << *fdecl->llvmValue << '\n';
923 assert(0);
924 }
925 return llvm::cast<llvm::Function>(fdecl->llvmValue);
926 }
927
928 Logger::print("FuncDeclaration::toObjFile(%s): %s\n", fdecl->needThis()?"this":"static",fdecl->toChars());
929 LOG_SCOPE;
930
931 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) {
932 error("intrinsics cannot have function bodies");
933 fatal();
934 }
935
936 // construct function
937 const llvm::FunctionType* functype = (f->llvmType == 0) ? DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType);
938
939 // make the function
940 llvm::Function* func = gIR->module->getFunction(mangled_name);
941 if (func == 0) {
942 func = new llvm::Function(functype,DtoLinkage(fdecl->protection, fdecl->storage_class),mangled_name,gIR->module);
943 }
944
945 if (fdecl->llvmInternal != LLVMintrinsic)
946 func->setCallingConv(DtoCallingConv(f->linkage));
947
948 fdecl->llvmValue = func;
949 f->llvmType = functype;
950 assert(llvm::isa<llvm::FunctionType>(f->llvmType));
951
952 if (fdecl->isMain()) {
953 gIR->mainFunc = func;
954 }
955
956 // name parameters
957 llvm::Function::arg_iterator iarg = func->arg_begin();
958 int k = 0;
959 if (f->llvmRetInPtr) {
960 iarg->setName("retval");
961 f->llvmRetArg = iarg;
962 ++iarg;
963 }
964 if (f->llvmUsesThis) {
965 iarg->setName("this");
966 ++iarg;
967 }
968 int varargs = -1;
969 if (f->linkage == LINKd && f->varargs == 1)
970 varargs = 0;
971 for (; iarg != func->arg_end(); ++iarg)
972 {
973 Argument* arg = Argument::getNth(f->parameters, k++);
974 //arg->llvmValue = iarg;
975 //Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
976 if (arg && arg->ident != 0) {
977 if (arg->vardecl) {
978 arg->vardecl->llvmValue = iarg;
979 }
980 iarg->setName(arg->ident->toChars());
981 }
982 else if (!arg && varargs >= 0) {
983 if (varargs == 0) {
984 iarg->setName("_arguments");
985 fdecl->llvmArguments = iarg;
986 }
987 else if (varargs == 1) {
988 iarg->setName("_argptr");
989 fdecl->llvmArgPtr = iarg;
990 }
991 else
992 assert(0);
993 varargs++;
994 }
995 else {
996 iarg->setName("unnamed");
997 }
998 }
999
1000 Logger::cout() << "func decl: " << *func << '\n';
1001
1002 return func;
1003 } 605 }
1004 606
1005 ////////////////////////////////////////////////////////////////////////////////////////// 607 //////////////////////////////////////////////////////////////////////////////////////////
1006 608
1007 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty) 609 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty)
1172 llvm::Value* DtoNestedVariable(VarDeclaration* vd) 774 llvm::Value* DtoNestedVariable(VarDeclaration* vd)
1173 { 775 {
1174 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); 776 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration();
1175 assert(fd != NULL); 777 assert(fd != NULL);
1176 778
1177 IRFunction* fcur = &gIR->func(); 779 IRFunction* fcur = gIR->func();
1178 FuncDeclaration* f = fcur->decl; 780 FuncDeclaration* f = fcur->decl;
1179 781
1180 // on this stack 782 // on this stack
1181 if (fd == f) { 783 if (fd == f) {
1182 llvm::Value* v = DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp"); 784 llvm::Value* v = DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp");
1278 else if (t->ty == Tclass) { 880 else if (t->ty == Tclass) {
1279 assert(t2->ty == Tclass); 881 assert(t2->ty == Tclass);
1280 // assignment to this in constructor special case 882 // assignment to this in constructor special case
1281 if (lhs->isThis()) { 883 if (lhs->isThis()) {
1282 llvm::Value* tmp = rhs->getRVal(); 884 llvm::Value* tmp = rhs->getRVal();
1283 FuncDeclaration* fdecl = gIR->func().decl; 885 FuncDeclaration* fdecl = gIR->func()->decl;
1284 // respecify the this param 886 // respecify the this param
1285 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar)) 887 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
1286 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint()); 888 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
1287 DtoStore(tmp, fdecl->llvmThisVar); 889 DtoStore(tmp, fdecl->llvmThisVar);
1288 } 890 }
1714 } 1316 }
1715 gIR->ir->CreateStore(DtoConstBool(true), gflag); 1317 gIR->ir->CreateStore(DtoConstBool(true), gflag);
1716 gIR->ir->CreateBr(endinitbb); 1318 gIR->ir->CreateBr(endinitbb);
1717 gIR->scope() = IRScope(endinitbb,oldend); 1319 gIR->scope() = IRScope(endinitbb,oldend);
1718 } 1320 }
1321
1322 //////////////////////////////////////////////////////////////////////////////////////////
1323
1324 void DtoDefineDsymbol(Dsymbol* dsym)
1325 {
1326 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1327 DtoDefineStruct(sd);
1328 }
1329 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1330 DtoDefineClass(cd);
1331 }
1332 else if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
1333 DtoDefineFunc(fd);
1334 }
1335 else {
1336 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1337 assert(0 && "unsupported dsymbol for DtoDefineDsymbol");
1338 }
1339 }
1340
1341 //////////////////////////////////////////////////////////////////////////////////////////
1342
1343 void DtoConstInitDsymbol(Dsymbol* dsym)
1344 {
1345 if (StructDeclaration* sd = dsym->isStructDeclaration()) {
1346 DtoConstInitStruct(sd);
1347 }
1348 else if (ClassDeclaration* cd = dsym->isClassDeclaration()) {
1349 DtoConstInitClass(cd);
1350 }
1351 else if (VarDeclaration* vd = dsym->isVarDeclaration()) {
1352 DtoConstInitGlobal(vd);
1353 }
1354 else {
1355 error(dsym->loc, "unsupported dsymbol: %s", dsym->toChars());
1356 assert(0 && "unsupported dsymbol for DtoInitDsymbol");
1357 }
1358 }
1359
1360 //////////////////////////////////////////////////////////////////////////////////////////
1361
1362 void DtoConstInitGlobal(VarDeclaration* vd)
1363 {
1364 Logger::println("DtoConstInitGlobal(%s)", vd->toChars());
1365 LOG_SCOPE;
1366
1367 if (vd->llvmDModule) return;
1368 vd->llvmDModule = gIR->dmodule;
1369
1370 bool emitRTstaticInit = false;
1371
1372 llvm::Constant* _init = 0;
1373 if (vd->parent && vd->parent->isFuncDeclaration() && vd->init && vd->init->isExpInitializer()) {
1374 _init = DtoConstInitializer(vd->type, NULL);
1375 emitRTstaticInit = true;
1376 }
1377 else {
1378 _init = DtoConstInitializer(vd->type, vd->init);
1379 }
1380
1381 const llvm::Type* _type = DtoType(vd->type);
1382 Type* t = DtoDType(vd->type);
1383
1384 //Logger::cout() << "initializer: " << *_init << '\n';
1385 if (_type != _init->getType()) {
1386 Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
1387 // zero initalizer
1388 if (_init->isNullValue())
1389 _init = llvm::Constant::getNullValue(_type);
1390 // pointer to global constant (struct.init)
1391 else if (llvm::isa<llvm::GlobalVariable>(_init))
1392 {
1393 assert(_init->getType()->getContainedType(0) == _type);
1394 llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
1395 assert(t->ty == Tstruct);
1396 TypeStruct* ts = (TypeStruct*)t;
1397 assert(ts->sym->llvmInitZ);
1398 _init = ts->sym->llvmInitZ;
1399 }
1400 // array single value init
1401 else if (isaArray(_type))
1402 {
1403 _init = DtoConstStaticArray(_type, _init);
1404 }
1405 else {
1406 Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
1407 //assert(0);
1408 }
1409 }
1410
1411 bool istempl = false;
1412 if ((vd->storage_class & STCcomdat) || (vd->parent && DtoIsTemplateInstance(vd->parent))) {
1413 istempl = true;
1414 }
1415
1416 if (_init && _init->getType() != _type)
1417 _type = _init->getType();
1418 llvm::cast<llvm::OpaqueType>(vd->llvmIRGlobal->type.get())->refineAbstractTypeTo(_type);
1419 _type = vd->llvmIRGlobal->type.get();
1420 assert(!_type->isAbstract());
1421
1422 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->llvmValue);
1423 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
1424 {
1425 gvar->setInitializer(_init);
1426 }
1427
1428 if (emitRTstaticInit)
1429 DtoLazyStaticInit(istempl, gvar, vd->init, t);
1430 }