Mercurial > projects > ldc
comparison gen/functions.cpp @ 715:30b42a283c8e
Removed TypeOpaque from DMD.
Changed runtime functions taking opaque[] to void[].
Implemented proper type painting, to avoid "resizing" array casts in runtime calls that previously took opaque[].
Implemented dynamic arrays as first class types, this implements proper ABI for these types on x86.
Added dwarf region end after call to assert function, fixes some problems with llvm not allowing this to be missing.
Reverted change to WithStatement from rev [704] it breaks MiniD, mini/with2.d needs to be fixed some other way...
Fixed tango bug 1339 in runtime, problem with _adReverseChar on invalid UTF-8.
Disabled .bc generation in the compiler runtime part, genobj.d triggers some llvm bug when using debug info. the .o seems to work fine.
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Wed, 22 Oct 2008 14:55:33 +0200 |
parents | df196c8dea26 |
children | 7261ff0f95ff |
comparison
equal
deleted
inserted
replaced
714:1e98c99a87cb | 715:30b42a283c8e |
---|---|
57 actualRettype = rettype; | 57 actualRettype = rettype; |
58 if (Argument::dim(f->parameters) == 0) | 58 if (Argument::dim(f->parameters) == 0) |
59 { | 59 { |
60 const LLType* arrTy = DtoArrayType(LLType::Int8Ty); | 60 const LLType* arrTy = DtoArrayType(LLType::Int8Ty); |
61 const LLType* arrArrTy = DtoArrayType(arrTy); | 61 const LLType* arrArrTy = DtoArrayType(arrTy); |
62 paramvec.push_back(getPtrToType(arrArrTy)); | 62 paramvec.push_back(arrArrTy); |
63 } | 63 } |
64 } | 64 } |
65 else{ | 65 else{ |
66 assert(rt); | 66 assert(rt); |
67 if (DtoIsReturnedInArg(rt)) { | 67 if (DtoIsReturnedInArg(rt)) { |
101 assert(ti->ir.irStruct->constInit); | 101 assert(ti->ir.irStruct->constInit); |
102 std::vector<const LLType*> types; | 102 std::vector<const LLType*> types; |
103 types.push_back(DtoSize_t()); | 103 types.push_back(DtoSize_t()); |
104 types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType()))); | 104 types.push_back(getPtrToType(getPtrToType(ti->ir.irStruct->constInit->getType()))); |
105 const LLType* t1 = llvm::StructType::get(types); | 105 const LLType* t1 = llvm::StructType::get(types); |
106 paramvec.push_back(getPtrToType(t1)); | 106 paramvec.push_back(t1); |
107 paramvec.push_back(getPtrToType(LLType::Int8Ty)); | 107 paramvec.push_back(getPtrToType(LLType::Int8Ty)); |
108 } | 108 } |
109 else if (arrayVararg) | 109 else if (arrayVararg) |
110 { | 110 { |
111 // do nothing? | 111 // do nothing? |
121 | 121 |
122 bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); | 122 bool refOrOut = ((arg->storageClass & STCref) || (arg->storageClass & STCout)); |
123 | 123 |
124 const LLType* at = DtoType(argT); | 124 const LLType* at = DtoType(argT); |
125 | 125 |
126 // FIXME: using the llvm type for these is a bad idea... aggregates are first class now and we're starting to use it ... | 126 // opaque types need special handling |
127 | 127 if (llvm::isa<llvm::OpaqueType>(at)) { |
128 if (argT->iscomplex()) { | |
129 goto Lbadstuff; | |
130 } | |
131 else if (isaStruct(at)) { | |
132 Logger::println("struct param"); | |
133 paramvec.push_back(getPtrToType(at)); | |
134 if (!refOrOut) | |
135 arg->llvmAttrs |= llvm::Attribute::ByVal; | |
136 } | |
137 else if (isaArray(at)) { | |
138 // static array are passed by reference | |
139 Logger::println("sarray param"); | |
140 assert(argT->ty == Tsarray); | |
141 paramvec.push_back(getPtrToType(at)); | |
142 } | |
143 else if (llvm::isa<llvm::OpaqueType>(at)) { | |
144 Logger::println("opaque param"); | 128 Logger::println("opaque param"); |
145 assert(argT->ty == Tstruct || argT->ty == Tclass); | 129 assert(argT->ty == Tstruct || argT->ty == Tclass); |
146 paramvec.push_back(getPtrToType(at)); | 130 paramvec.push_back(getPtrToType(at)); |
147 } | 131 } |
132 // structs and delegates are passed as a reference, but by value | |
133 else if (argT->ty == Tstruct || argT->ty == Tdelegate) { | |
134 Logger::println("struct/sarray param"); | |
135 if (!refOrOut) | |
136 arg->llvmAttrs |= llvm::Attribute::ByVal; | |
137 paramvec.push_back(getPtrToType(at)); | |
138 } | |
139 // static arrays are passed directly by reference | |
140 else if (argT->ty == Tsarray) | |
141 { | |
142 Logger::println("static array param"); | |
143 at = getPtrToType(at); | |
144 paramvec.push_back(at); | |
145 } | |
146 // firstclass ' ref/out ' parameter | |
147 else if (refOrOut) { | |
148 Logger::println("ref/out param"); | |
149 at = getPtrToType(at); | |
150 paramvec.push_back(at); | |
151 } | |
152 // firstclass ' in ' parameter | |
148 else { | 153 else { |
149 Lbadstuff: | 154 Logger::println("in param"); |
150 if (refOrOut) { | 155 if (unsigned ea = DtoShouldExtend(argT)) |
151 Logger::println("by ref param"); | 156 arg->llvmAttrs |= ea; |
152 at = getPtrToType(at); | |
153 } | |
154 else { | |
155 Logger::println("in param"); | |
156 if (unsigned ea = DtoShouldExtend(argT)) | |
157 { | |
158 arg->llvmAttrs |= ea; | |
159 } | |
160 } | |
161 paramvec.push_back(at); | 157 paramvec.push_back(at); |
162 } | 158 } |
163 | 159 |
164 // handle lazy args | 160 // handle lazy args |
165 if (arg->storageClass & STClazy) | 161 if (arg->storageClass & STClazy) |
358 if (f->retInPtr) | 354 if (f->retInPtr) |
359 { | 355 { |
360 PAWI.Index = 1; | 356 PAWI.Index = 1; |
361 PAWI.Attrs = llvm::Attribute::StructRet; | 357 PAWI.Attrs = llvm::Attribute::StructRet; |
362 attrs.push_back(PAWI); | 358 attrs.push_back(PAWI); |
363 } | |
364 | |
365 // set byval attrs on implicit main arg | |
366 if (fdecl->isMain() && Argument::dim(f->parameters) == 0) | |
367 { | |
368 PAWI.Index = llidx; | |
369 PAWI.Attrs = llvm::Attribute::ByVal; | |
370 attrs.push_back(PAWI); | |
371 llidx++; | |
372 } | 359 } |
373 | 360 |
374 // set attrs on the rest of the arguments | 361 // set attrs on the rest of the arguments |
375 for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) | 362 for (; llidx <= funcNumArgs && Argument::dim(f->parameters) > k; ++llidx,++k) |
376 { | 363 { |
773 LLValue* val = DtoBitCast(fd->vresult->ir.irLocal->value, getVoidPtrType()); | 760 LLValue* val = DtoBitCast(fd->vresult->ir.irLocal->value, getVoidPtrType()); |
774 DtoStore(val, gep); | 761 DtoStore(val, gep); |
775 } | 762 } |
776 } | 763 } |
777 | 764 |
778 // copy _argptr to a memory location | 765 // copy _argptr and _arguments to a memory location |
779 if (f->linkage == LINKd && f->varargs == 1) | 766 if (f->linkage == LINKd && f->varargs == 1) |
780 { | 767 { |
768 // _argptr | |
781 LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptr_mem"); | 769 LLValue* argptrmem = DtoAlloca(fd->ir.irFunc->_argptr->getType(), "_argptr_mem"); |
782 new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); | 770 new llvm::StoreInst(fd->ir.irFunc->_argptr, argptrmem, gIR->scopebb()); |
783 fd->ir.irFunc->_argptr = argptrmem; | 771 fd->ir.irFunc->_argptr = argptrmem; |
772 | |
773 // _arguments | |
774 LLValue* argumentsmem = DtoAlloca(fd->ir.irFunc->_arguments->getType(), "_arguments_mem"); | |
775 new llvm::StoreInst(fd->ir.irFunc->_arguments, argumentsmem, gIR->scopebb()); | |
776 fd->ir.irFunc->_arguments = argumentsmem; | |
784 } | 777 } |
785 | 778 |
786 // output function body | 779 // output function body |
787 fd->fbody->toIR(gIR); | 780 fd->fbody->toIR(gIR); |
788 | 781 |