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