Mercurial > projects > ldc
annotate gen/tollvm.c @ 81:3587401b6eeb trunk
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
Changed: Renamed all the LLVM_Dto... helper function to just Dto...
author | lindquist |
---|---|
date | Thu, 01 Nov 2007 17:27:18 +0100 |
parents | 2332006e1fa4 |
children | d8dd47ef3973 |
rev | line source |
---|---|
1 | 1 #include <iostream> |
2 | |
40 | 3 #include "gen/llvm.h" |
1 | 4 |
5 #include "mtype.h" | |
6 #include "dsymbol.h" | |
7 #include "aggregate.h" | |
8 #include "declaration.h" | |
9 #include "init.h" | |
10 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
11 #include "gen/tollvm.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
12 #include "gen/irstate.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
13 #include "gen/logger.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
14 #include "gen/runtime.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
15 #include "gen/elem.h" |
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
16 #include "gen/arrays.h" |
1 | 17 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
18 bool DtoIsPassedByRef(Type* type) |
40 | 19 { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
20 TY t = DtoDType(type)->ty; |
73 | 21 return (t == Tstruct || t == Tarray || t == Tdelegate); |
40 | 22 } |
23 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
24 Type* DtoDType(Type* t) |
40 | 25 { |
26 if (t->ty == Ttypedef) { | |
27 Type* bt = t->toBasetype(); | |
28 assert(bt); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
29 return DtoDType(bt); |
40 | 30 } |
31 return t; | |
32 } | |
33 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
34 const llvm::Type* DtoType(Type* t) |
1 | 35 { |
36 assert(t); | |
37 switch (t->ty) | |
38 { | |
39 // integers | |
40 case Tint8: | |
41 case Tuns8: | |
42 case Tchar: | |
43 return (const llvm::Type*)llvm::Type::Int8Ty; | |
44 case Tint16: | |
45 case Tuns16: | |
46 case Twchar: | |
47 return (const llvm::Type*)llvm::Type::Int16Ty; | |
48 case Tint32: | |
49 case Tuns32: | |
50 case Tdchar: | |
51 return (const llvm::Type*)llvm::Type::Int32Ty; | |
52 case Tint64: | |
53 case Tuns64: | |
54 return (const llvm::Type*)llvm::Type::Int64Ty; | |
55 | |
56 case Tbool: | |
57 return (const llvm::Type*)llvm::ConstantInt::getTrue()->getType(); | |
58 | |
59 // floats | |
60 case Tfloat32: | |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
61 case Timaginary32: |
1 | 62 return llvm::Type::FloatTy; |
63 case Tfloat64: | |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
64 case Timaginary64: |
1 | 65 case Tfloat80: |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
66 case Timaginary80: |
1 | 67 return llvm::Type::DoubleTy; |
68 | |
62
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
69 // complex |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
70 case Tcomplex32: |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
71 case Tcomplex64: |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
72 case Tcomplex80: |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
73 assert(0 && "complex number types not yet implemented"); |
b86e00b938a5
[svn r66] Added support for imaginary floating point types
lindquist
parents:
58
diff
changeset
|
74 |
1 | 75 // pointers |
76 case Tpointer: { | |
77 assert(t->next); | |
78 if (t->next->ty == Tvoid) | |
79 return (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty); | |
80 else | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
81 return (const llvm::Type*)llvm::PointerType::get(DtoType(t->next)); |
1 | 82 } |
83 | |
84 // arrays | |
85 case Tarray: | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
86 return DtoArrayType(t); |
1 | 87 case Tsarray: |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
88 return DtoStaticArrayType(t); |
1 | 89 |
90 // void | |
91 case Tvoid: | |
92 return llvm::Type::VoidTy; | |
93 | |
94 // aggregates | |
95 case Tstruct: { | |
96 if (t->llvmType == 0) | |
97 { | |
98 // recursive or cyclic declaration | |
99 if (!gIR->structs.empty()) | |
100 { | |
101 IRStruct* found = 0; | |
102 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) | |
103 { | |
104 if (t == i->type) | |
105 { | |
106 return i->recty.get(); | |
107 } | |
108 } | |
109 } | |
110 | |
111 // forward declaration | |
112 TypeStruct* ts = (TypeStruct*)t; | |
113 assert(ts->sym); | |
114 ts->sym->toObjFile(); | |
115 } | |
116 return t->llvmType; | |
117 } | |
118 | |
119 case Tclass: { | |
120 if (t->llvmType == 0) | |
121 { | |
6 | 122 // recursive or cyclic declaration |
123 if (!gIR->structs.empty()) | |
124 { | |
125 IRStruct* found = 0; | |
126 for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i) | |
127 { | |
128 if (t == i->type) | |
129 { | |
130 return llvm::PointerType::get(i->recty.get()); | |
131 } | |
132 } | |
133 } | |
134 | |
135 // forward declaration | |
1 | 136 TypeClass* tc = (TypeClass*)t; |
137 assert(tc->sym); | |
6 | 138 tc->sym->toObjFile(); |
1 | 139 } |
140 return llvm::PointerType::get(t->llvmType); | |
141 } | |
142 | |
143 // functions | |
144 case Tfunction: | |
145 { | |
146 if (t->llvmType == 0) { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
147 return DtoFunctionType(t,NULL); |
1 | 148 } |
149 else { | |
150 return t->llvmType; | |
151 } | |
152 } | |
6 | 153 |
1 | 154 // delegates |
155 case Tdelegate: | |
156 { | |
157 if (t->llvmType == 0) { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
158 return DtoDelegateType(t); |
1 | 159 } |
160 else { | |
161 return t->llvmType; | |
162 } | |
163 } | |
164 | |
165 // typedefs | |
52 | 166 // enum |
1 | 167 case Ttypedef: |
52 | 168 case Tenum: |
1 | 169 { |
170 Type* bt = t->toBasetype(); | |
171 assert(bt); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
172 return DtoType(bt); |
1 | 173 } |
174 | |
175 default: | |
176 printf("trying to convert unknown type with value %d\n", t->ty); | |
177 assert(0); | |
178 } | |
179 return 0; | |
180 } | |
181 | |
182 ////////////////////////////////////////////////////////////////////////////////////////// | |
183 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
184 const llvm::FunctionType* DtoFunctionType(Type* type, const llvm::Type* thistype, bool ismain) |
1 | 185 { |
72 | 186 TypeFunction* f = (TypeFunction*)type; |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
187 assert(f != 0); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
188 |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
189 bool typesafeVararg = false; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
190 if (f->linkage == LINKd && f->varargs == 1) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
191 typesafeVararg = true; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
192 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
193 |
1 | 194 // return value type |
195 const llvm::Type* rettype; | |
196 const llvm::Type* actualRettype; | |
197 Type* rt = f->next; | |
198 bool retinptr = false; | |
199 bool usesthis = false; | |
200 | |
72 | 201 if (ismain) { |
1 | 202 rettype = llvm::Type::Int32Ty; |
203 actualRettype = rettype; | |
204 } | |
72 | 205 else { |
206 assert(rt); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
207 if (DtoIsPassedByRef(rt)) { |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
208 rettype = llvm::PointerType::get(DtoType(rt)); |
1 | 209 actualRettype = llvm::Type::VoidTy; |
210 f->llvmRetInPtr = retinptr = true; | |
211 } | |
212 else { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
213 rettype = DtoType(rt); |
1 | 214 actualRettype = rettype; |
215 } | |
216 } | |
217 | |
218 // parameter types | |
219 std::vector<const llvm::Type*> paramvec; | |
220 | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
221 if (retinptr) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
222 Logger::cout() << "returning through pointer parameter: " << *rettype << '\n'; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
223 paramvec.push_back(rettype); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
224 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
225 |
72 | 226 if (thistype) { |
227 paramvec.push_back(thistype); | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
228 usesthis = true; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
229 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
230 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
231 if (typesafeVararg) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
232 ClassDeclaration* ti = Type::typeinfo; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
233 if (!ti->llvmInitZ) |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
234 ti->toObjFile(); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
235 assert(ti->llvmInitZ); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
236 std::vector<const llvm::Type*> types; |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
237 types.push_back(DtoSize_t()); |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
238 types.push_back(llvm::PointerType::get(llvm::PointerType::get(ti->llvmInitZ->getType()))); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
239 const llvm::Type* t1 = llvm::StructType::get(types); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
240 paramvec.push_back(llvm::PointerType::get(t1)); |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
241 paramvec.push_back(llvm::PointerType::get(llvm::Type::Int8Ty)); |
1 | 242 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
243 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
244 size_t n = Argument::dim(f->parameters); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
245 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
246 for (int i=0; i < n; ++i) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
247 Argument* arg = Argument::getNth(f->parameters, i); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
248 // ensure scalar |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
249 Type* argT = DtoDType(arg->type); |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
250 assert(argT); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
251 |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
252 if ((arg->storageClass & STCref) || (arg->storageClass & STCout)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
253 //assert(arg->vardecl); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
254 //arg->vardecl->refparam = true; |
9 | 255 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
256 else |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
257 arg->llvmCopy = true; |
1 | 258 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
259 const llvm::Type* at = DtoType(argT); |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
260 if (llvm::isa<llvm::StructType>(at)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
261 Logger::println("struct param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
262 paramvec.push_back(llvm::PointerType::get(at)); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
263 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
264 else if (llvm::isa<llvm::ArrayType>(at)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
265 Logger::println("sarray param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
266 assert(argT->ty == Tsarray); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
267 //paramvec.push_back(llvm::PointerType::get(at->getContainedType(0))); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
268 paramvec.push_back(llvm::PointerType::get(at)); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
269 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
270 else if (llvm::isa<llvm::OpaqueType>(at)) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
271 Logger::println("opaque param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
272 if (argT->ty == Tstruct || argT->ty == Tclass) |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
273 paramvec.push_back(llvm::PointerType::get(at)); |
40 | 274 else |
275 assert(0); | |
276 } | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
277 /*if (llvm::isa<llvm::StructType>(at) || argT->ty == Tstruct || argT->ty == Tsarray) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
278 paramvec.push_back(llvm::PointerType::get(at)); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
279 }*/ |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
280 else { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
281 if (!arg->llvmCopy) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
282 Logger::println("ref param"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
283 at = llvm::PointerType::get(at); |
1 | 284 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
285 else { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
286 Logger::println("in param"); |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
287 } |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
288 paramvec.push_back(at); |
1 | 289 } |
290 } | |
291 | |
292 // construct function type | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
293 bool isvararg = !typesafeVararg && f->varargs; |
1 | 294 llvm::FunctionType* functype = llvm::FunctionType::get(actualRettype, paramvec, isvararg); |
295 | |
9 | 296 f->llvmRetInPtr = retinptr; |
297 f->llvmUsesThis = usesthis; | |
1 | 298 return functype; |
299 } | |
300 | |
301 ////////////////////////////////////////////////////////////////////////////////////////// | |
302 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
303 static const llvm::FunctionType* DtoVaFunctionType(FuncDeclaration* fdecl) |
72 | 304 { |
305 TypeFunction* f = (TypeFunction*)fdecl->type; | |
306 assert(f != 0); | |
307 | |
308 const llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
309 std::vector<const llvm::Type*> args; | |
310 | |
311 if (fdecl->llvmInternal == LLVMva_start) { | |
312 args.push_back(i8pty); | |
313 } | |
314 else if (fdecl->llvmInternal == LLVMva_intrinsic) { | |
315 size_t n = Argument::dim(f->parameters); | |
316 for (size_t i=0; i<n; ++i) { | |
317 args.push_back(i8pty); | |
318 } | |
319 } | |
320 else | |
321 assert(0); | |
322 | |
323 const llvm::FunctionType* fty = llvm::FunctionType::get(llvm::Type::VoidTy, args, false); | |
324 f->llvmType = fty; | |
325 return fty; | |
326 } | |
327 | |
328 ////////////////////////////////////////////////////////////////////////////////////////// | |
329 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
330 const llvm::FunctionType* DtoFunctionType(FuncDeclaration* fdecl) |
72 | 331 { |
332 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
333 return DtoVaFunctionType(fdecl); |
72 | 334 } |
335 | |
336 // type has already been resolved | |
337 if (fdecl->type->llvmType != 0) { | |
338 return llvm::cast<llvm::FunctionType>(fdecl->type->llvmType); | |
339 } | |
340 | |
341 const llvm::Type* thisty = NULL; | |
342 if (fdecl->needThis()) { | |
343 if (AggregateDeclaration* ad = fdecl->isMember()) { | |
344 Logger::print("isMember = this is: %s\n", ad->type->toChars()); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
345 thisty = DtoType(ad->type); |
72 | 346 Logger::cout() << "this llvm type: " << *thisty << '\n'; |
347 if (llvm::isa<llvm::StructType>(thisty) || thisty == gIR->topstruct().recty.get()) | |
348 thisty = llvm::PointerType::get(thisty); | |
349 } | |
350 else | |
351 assert(0); | |
352 } | |
353 else if (fdecl->isNested()) { | |
354 thisty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
355 } | |
356 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
357 const llvm::FunctionType* functype = DtoFunctionType(fdecl->type, thisty, fdecl->isMain()); |
72 | 358 fdecl->type->llvmType = functype; |
359 return functype; | |
360 } | |
361 | |
362 ////////////////////////////////////////////////////////////////////////////////////////// | |
363 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
364 const llvm::StructType* DtoDelegateType(Type* t) |
1 | 365 { |
366 const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
367 const llvm::Type* func = DtoFunctionType(t->next, i8ptr); |
1 | 368 const llvm::Type* funcptr = llvm::PointerType::get(func); |
369 | |
370 std::vector<const llvm::Type*> types; | |
371 types.push_back(i8ptr); | |
372 types.push_back(funcptr); | |
373 return llvm::StructType::get(types); | |
374 } | |
375 | |
376 ////////////////////////////////////////////////////////////////////////////////////////// | |
377 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
378 const llvm::Type* DtoStructType(Type* t) |
1 | 379 { |
380 assert(0); | |
381 std::vector<const llvm::Type*> types; | |
382 return llvm::StructType::get(types); | |
383 } | |
384 | |
385 | |
386 ////////////////////////////////////////////////////////////////////////////////////////// | |
387 | |
388 static llvm::Function* LLVM_DeclareMemIntrinsic(const char* name, int bits, bool set=false) | |
389 { | |
390 assert(bits == 32 || bits == 64); | |
391 const llvm::Type* int8ty = (const llvm::Type*)llvm::Type::Int8Ty; | |
392 const llvm::Type* int32ty = (const llvm::Type*)llvm::Type::Int32Ty; | |
393 const llvm::Type* int64ty = (const llvm::Type*)llvm::Type::Int64Ty; | |
394 const llvm::Type* int8ptrty = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty); | |
395 const llvm::Type* voidty = (const llvm::Type*)llvm::Type::VoidTy; | |
396 | |
397 assert(gIR); | |
398 assert(gIR->module); | |
399 | |
400 // parameter types | |
401 std::vector<const llvm::Type*> pvec; | |
402 pvec.push_back(int8ptrty); | |
403 pvec.push_back(set?int8ty:int8ptrty); | |
404 pvec.push_back(bits==32?int32ty:int64ty); | |
405 pvec.push_back(int32ty); | |
406 llvm::FunctionType* functype = llvm::FunctionType::get(voidty, pvec, false); | |
407 return new llvm::Function(functype, llvm::GlobalValue::ExternalLinkage, name, gIR->module); | |
408 } | |
409 | |
410 ////////////////////////////////////////////////////////////////////////////////////////// | |
411 | |
412 // llvm.memset.i32 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
413 llvm::Function* LLVM_DeclareMemSet32() |
1 | 414 { |
415 static llvm::Function* _func = 0; | |
416 if (_func == 0) { | |
417 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i32", 32, true); | |
418 } | |
419 return _func; | |
420 } | |
421 | |
422 ////////////////////////////////////////////////////////////////////////////////////////// | |
423 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
424 llvm::Function* LLVM_DeclareMemSet64() |
1 | 425 { |
426 static llvm::Function* _func = 0; | |
427 if (_func == 0) { | |
428 _func = LLVM_DeclareMemIntrinsic("llvm.memset.i64", 64, true); | |
429 } | |
430 return _func; | |
431 } | |
432 | |
433 ////////////////////////////////////////////////////////////////////////////////////////// | |
434 | |
435 // llvm.memcpy.i32 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
436 llvm::Function* LLVM_DeclareMemCpy32() |
1 | 437 { |
438 static llvm::Function* _func = 0; | |
439 if (_func == 0) { | |
440 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i32", 32); | |
441 } | |
442 return _func; | |
443 } | |
444 | |
445 ////////////////////////////////////////////////////////////////////////////////////////// | |
446 | |
447 // llvm.memcpy.i64 | |
4
e116aa1488e6
[svn r8] changed backend includes to always use the gen/<foo>.h prefix
lindquist
parents:
1
diff
changeset
|
448 llvm::Function* LLVM_DeclareMemCpy64() |
1 | 449 { |
450 static llvm::Function* _func = 0; | |
451 if (_func == 0) { | |
452 _func = LLVM_DeclareMemIntrinsic("llvm.memcpy.i64", 64); | |
453 } | |
454 return _func; | |
455 } | |
456 | |
457 ////////////////////////////////////////////////////////////////////////////////////////// | |
458 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
459 llvm::Value* DtoStructZeroInit(llvm::Value* v) |
1 | 460 { |
461 assert(gIR); | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
462 uint64_t n = gTargetData->getTypeSize(v->getType()->getContainedType(0)); |
1 | 463 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); |
464 llvm::Type* sarrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
465 | |
466 llvm::Value* sarr = new llvm::BitCastInst(v,sarrty,"tmp",gIR->scopebb()); | |
467 | |
468 llvm::Function* fn = LLVM_DeclareMemSet32(); | |
469 std::vector<llvm::Value*> llargs; | |
470 llargs.resize(4); | |
471 llargs[0] = sarr; | |
472 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | |
473 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
474 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
475 | |
476 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
477 | |
478 return ret; | |
479 } | |
480 | |
481 ////////////////////////////////////////////////////////////////////////////////////////// | |
482 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
483 llvm::Value* DtoStructCopy(llvm::Value* dst, llvm::Value* src) |
1 | 484 { |
485 assert(dst->getType() == src->getType()); | |
486 assert(gIR); | |
487 | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
488 uint64_t n = gTargetData->getTypeSize(dst->getType()->getContainedType(0)); |
1 | 489 //llvm::Type* sarrty = llvm::PointerType::get(llvm::ArrayType::get(llvm::Type::Int8Ty, n)); |
490 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
491 | |
492 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
493 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | |
494 | |
495 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
496 std::vector<llvm::Value*> llargs; | |
497 llargs.resize(4); | |
498 llargs[0] = dstarr; | |
499 llargs[1] = srcarr; | |
500 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
501 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
502 | |
503 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
504 } | |
505 | |
506 ////////////////////////////////////////////////////////////////////////////////////////// | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
507 llvm::Constant* DtoConstStructInitializer(StructInitializer* si) |
1 | 508 { |
509 llvm::StructType* structtype = llvm::cast<llvm::StructType>(si->ad->llvmType); | |
510 size_t n = structtype->getNumElements(); | |
511 | |
512 assert(si->value.dim == si->vars.dim); | |
513 | |
514 std::vector<llvm::Constant*> inits; | |
515 inits.resize(n, NULL); | |
516 for (int i = 0; i < si->value.dim; ++i) | |
517 { | |
518 Initializer* ini = (Initializer*)si->value.data[i]; | |
519 assert(ini); | |
520 | |
521 VarDeclaration* vd = (VarDeclaration*)si->vars.data[i]; | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
522 Type* vdtype = DtoDType(vd->type); |
1 | 523 assert(vd); |
524 Logger::println("vars[%d] = %s", i, vd->toChars()); | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
525 |
73 | 526 llvm::Constant* v = 0; |
1 | 527 |
73 | 528 assert(vd->llvmFieldIndex >= 0); |
529 unsigned idx = vd->llvmFieldIndex; | |
1 | 530 |
531 if (ExpInitializer* ex = ini->isExpInitializer()) | |
532 { | |
40 | 533 v = ex->exp->toConstElem(gIR); |
1 | 534 } |
535 else if (StructInitializer* si = ini->isStructInitializer()) | |
536 { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
537 v = DtoConstStructInitializer(si); |
1 | 538 } |
539 else if (ArrayInitializer* ai = ini->isArrayInitializer()) | |
540 { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
541 v = DtoConstArrayInitializer(ai); |
1 | 542 } |
543 else if (ini->isVoidInitializer()) | |
544 { | |
545 v = llvm::UndefValue::get(structtype->getElementType(idx)); | |
546 } | |
547 else | |
548 assert(v); | |
549 | |
550 inits[idx] = v; | |
73 | 551 Logger::cout() << "init[" << idx << "] = " << *v << '\n'; |
1 | 552 } |
553 | |
554 // fill out nulls | |
555 assert(si->ad->llvmInitZ); | |
556 if (si->ad->llvmInitZ->isNullValue()) | |
557 { | |
558 for (int i = 0; i < n; ++i) | |
559 { | |
560 if (inits[i] == 0) | |
561 { | |
562 inits[i] = llvm::Constant::getNullValue(structtype->getElementType(i)); | |
563 } | |
564 } | |
565 } | |
566 else | |
567 { | |
568 for (int i = 0; i < n; ++i) | |
569 { | |
570 if (inits[i] == 0) | |
571 { | |
572 inits[i] = si->ad->llvmInitZ->getOperand(i); | |
573 } | |
574 } | |
575 } | |
576 | |
577 return llvm::ConstantStruct::get(structtype, inits); | |
578 } | |
579 | |
580 | |
581 | |
582 ////////////////////////////////////////////////////////////////////////////////////////// | |
583 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
584 llvm::Value* DtoNullDelegate(llvm::Value* v) |
1 | 585 { |
586 assert(gIR); | |
587 d_uns64 n = (global.params.is64bit) ? 16 : 8; | |
588 | |
589 llvm::Type* i8p_ty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
590 | |
591 llvm::Value* arr = new llvm::BitCastInst(v,i8p_ty,"tmp",gIR->scopebb()); | |
592 | |
593 llvm::Function* fn = LLVM_DeclareMemSet32(); | |
594 std::vector<llvm::Value*> llargs; | |
595 llargs.resize(4); | |
596 llargs[0] = arr; | |
597 llargs[1] = llvm::ConstantInt::get(llvm::Type::Int8Ty, 0, false); | |
598 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
599 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
600 | |
601 llvm::Value* ret = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
602 | |
603 return ret; | |
604 } | |
605 | |
606 ////////////////////////////////////////////////////////////////////////////////////////// | |
607 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
608 llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src) |
1 | 609 { |
610 assert(dst->getType() == src->getType()); | |
611 assert(gIR); | |
612 | |
613 d_uns64 n = (global.params.is64bit) ? 16 : 8; | |
614 | |
615 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
616 | |
617 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); | |
618 llvm::Value* srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); | |
619 | |
620 llvm::Function* fn = LLVM_DeclareMemCpy32(); | |
621 std::vector<llvm::Value*> llargs; | |
622 llargs.resize(4); | |
623 llargs[0] = dstarr; | |
624 llargs[1] = srcarr; | |
625 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); | |
626 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
627 | |
628 return new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
629 } | |
630 | |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
631 ////////////////////////////////////////////////////////////////////////////////////////// |
1 | 632 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
633 llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs) |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
634 { |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
635 llvm::ICmpInst::Predicate pred = (op == TOKequal) ? llvm::ICmpInst::ICMP_EQ : llvm::ICmpInst::ICMP_NE; |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
636 llvm::Value* l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,0,"tmp"),"tmp"); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
637 llvm::Value* r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,0,"tmp"),"tmp"); |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
638 llvm::Value* b1 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
639 l = gIR->ir->CreateLoad(DtoGEPi(lhs,0,1,"tmp"),"tmp"); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
640 r = gIR->ir->CreateLoad(DtoGEPi(rhs,0,1,"tmp"),"tmp"); |
53
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
641 llvm::Value* b2 = gIR->ir->CreateICmp(pred,l,r,"tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
642 llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
643 if (op == TOKnotequal) |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
644 return gIR->ir->CreateNot(b,"tmp"); |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
645 return b; |
06ccc817acd4
[svn r57] Added most basic TypeInfo (rebuild lphobos).
lindquist
parents:
52
diff
changeset
|
646 } |
1 | 647 |
648 ////////////////////////////////////////////////////////////////////////////////////////// | |
649 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
650 llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc) |
1 | 651 { |
652 switch(prot) | |
653 { | |
654 case PROTprivate: | |
655 return llvm::GlobalValue::InternalLinkage; | |
656 | |
657 case PROTpublic: | |
658 case PROTpackage: | |
659 case PROTprotected: | |
660 case PROTexport: | |
661 return llvm::GlobalValue::ExternalLinkage; | |
662 | |
663 case PROTundefined: | |
664 case PROTnone: | |
665 assert(0 && "Unsupported linkage type"); | |
666 } | |
667 return llvm::GlobalValue::ExternalLinkage; | |
668 | |
669 /* ExternalLinkage = 0, LinkOnceLinkage, WeakLinkage, AppendingLinkage, | |
670 InternalLinkage, DLLImportLinkage, DLLExportLinkage, ExternalWeakLinkage, | |
671 GhostLinkage */ | |
672 } | |
673 | |
674 ////////////////////////////////////////////////////////////////////////////////////////// | |
675 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
676 unsigned DtoCallingConv(LINK l) |
1 | 677 { |
678 if (l == LINKc) | |
679 return llvm::CallingConv::C; | |
680 else if (l == LINKd || l == LINKdefault) | |
681 return llvm::CallingConv::Fast; | |
682 else if (l == LINKwindows) | |
683 return llvm::CallingConv::X86_StdCall; | |
684 else | |
685 assert(0 && "Unsupported calling convention"); | |
686 } | |
687 | |
688 ////////////////////////////////////////////////////////////////////////////////////////// | |
689 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
690 llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val) |
1 | 691 { |
692 const llvm::Type* ptrTy = ptr->getType()->getContainedType(0); | |
693 const llvm::Type* valTy = val->getType(); | |
694 // ptr points to val's type | |
695 if (ptrTy == valTy) | |
696 { | |
697 return val; | |
698 } | |
699 // ptr is integer pointer | |
700 else if (ptrTy->isInteger()) | |
701 { | |
702 // val is integer | |
703 assert(valTy->isInteger()); | |
704 const llvm::IntegerType* pt = llvm::cast<const llvm::IntegerType>(ptrTy); | |
705 const llvm::IntegerType* vt = llvm::cast<const llvm::IntegerType>(valTy); | |
706 if (pt->getBitWidth() < vt->getBitWidth()) { | |
707 return new llvm::TruncInst(val, pt, "tmp", gIR->scopebb()); | |
708 } | |
709 else | |
710 assert(0); | |
711 } | |
712 // something else unsupported | |
713 else | |
714 { | |
715 Logger::cout() << *ptrTy << '|' << *valTy << '\n'; | |
716 assert(0); | |
717 } | |
718 return 0; | |
719 } | |
720 | |
721 ////////////////////////////////////////////////////////////////////////////////////////// | |
722 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
723 llvm::Value* DtoBoolean(llvm::Value* val) |
1 | 724 { |
725 const llvm::Type* t = val->getType(); | |
726 if (t->isInteger()) | |
727 { | |
728 if (t == llvm::Type::Int1Ty) | |
729 return val; | |
730 else { | |
731 llvm::Value* zero = llvm::ConstantInt::get(t, 0, false); | |
732 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, val, zero, "tmp", gIR->scopebb()); | |
733 } | |
734 } | |
735 else if (llvm::isa<llvm::PointerType>(t)) { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
736 const llvm::Type* st = DtoSize_t(); |
1 | 737 llvm::Value* ptrasint = new llvm::PtrToIntInst(val,st,"tmp",gIR->scopebb()); |
738 llvm::Value* zero = llvm::ConstantInt::get(st, 0, false); | |
739 return new llvm::ICmpInst(llvm::ICmpInst::ICMP_NE, ptrasint, zero, "tmp", gIR->scopebb()); | |
740 } | |
741 else | |
742 { | |
743 Logger::cout() << *t << '\n'; | |
744 } | |
745 assert(0); | |
746 return 0; | |
747 } | |
748 | |
749 ////////////////////////////////////////////////////////////////////////////////////////// | |
750 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
751 const llvm::Type* DtoSize_t() |
1 | 752 { |
753 if (global.params.is64bit) | |
754 return llvm::Type::Int64Ty; | |
755 else | |
756 return llvm::Type::Int32Ty; | |
757 } | |
758 | |
759 ////////////////////////////////////////////////////////////////////////////////////////// | |
760 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
761 void DtoMain() |
1 | 762 { |
763 // emit main function llvm style | |
764 // int main(int argc, char**argv, char**env); | |
765 | |
766 assert(gIR != 0); | |
767 IRState& ir = *gIR; | |
768 | |
769 assert(ir.emitMain && ir.mainFunc); | |
770 | |
771 // parameter types | |
772 std::vector<const llvm::Type*> pvec; | |
773 pvec.push_back((const llvm::Type*)llvm::Type::Int32Ty); | |
774 const llvm::Type* chPtrType = (const llvm::Type*)llvm::PointerType::get(llvm::Type::Int8Ty); | |
775 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType)); | |
776 pvec.push_back((const llvm::Type*)llvm::PointerType::get(chPtrType)); | |
777 const llvm::Type* rettype = (const llvm::Type*)llvm::Type::Int32Ty; | |
778 | |
779 llvm::FunctionType* functype = llvm::FunctionType::get(rettype, pvec, false); | |
780 llvm::Function* func = new llvm::Function(functype,llvm::GlobalValue::ExternalLinkage,"main",ir.module); | |
781 | |
782 llvm::BasicBlock* bb = new llvm::BasicBlock("entry",func); | |
783 | |
784 // call static ctors | |
785 llvm::Function* fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_ctors"); | |
786 new llvm::CallInst(fn,"",bb); | |
787 | |
788 // call user main function | |
789 llvm::CallInst* call = new llvm::CallInst(ir.mainFunc,"ret",bb); | |
790 call->setCallingConv(ir.mainFunc->getCallingConv()); | |
791 | |
792 // call static dtors | |
793 fn = LLVM_D_GetRuntimeFunction(ir.module,"_d_run_module_dtors"); | |
794 new llvm::CallInst(fn,"",bb); | |
795 | |
796 // return | |
797 new llvm::ReturnInst(call,bb); | |
798 } | |
799 | |
800 ////////////////////////////////////////////////////////////////////////////////////////// | |
801 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
802 void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance) |
1 | 803 { |
804 Array* arr = &tc->sym->dtors; | |
805 for (size_t i=0; i<arr->dim; i++) | |
806 { | |
807 FuncDeclaration* fd = (FuncDeclaration*)arr->data[i]; | |
808 assert(fd->llvmValue); | |
809 new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb()); | |
810 } | |
811 } | |
812 | |
813 ////////////////////////////////////////////////////////////////////////////////////////// | |
814 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
815 void DtoInitClass(TypeClass* tc, llvm::Value* dst) |
1 | 816 { |
817 assert(gIR); | |
818 | |
819 assert(tc->llvmType); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
820 uint64_t size_t_size = gTargetData->getTypeSize(DtoSize_t()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
821 uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size; |
1 | 822 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
823 // set vtable field |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
824 llvm::Value* vtblvar = DtoGEPi(dst,0,0,"tmp",gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
825 assert(tc->sym->llvmVtbl); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
826 new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb()); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
827 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
828 // copy the static initializer |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
829 if (n > 0) { |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
830 assert(tc->llvmInit); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
831 assert(dst->getType() == tc->llvmInit->getType()); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
832 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
833 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
1 | 834 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
835 llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
836 dstarr = DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
837 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
838 llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
839 srcarr = DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb()); |
1 | 840 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
841 llvm::Function* fn = LLVM_DeclareMemCpy32(); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
842 std::vector<llvm::Value*> llargs; |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
843 llargs.resize(4); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
844 llargs[0] = dstarr; |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
845 llargs[1] = srcarr; |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
846 llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
847 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
848 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
849 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
850 } |
1 | 851 } |
852 | |
853 ////////////////////////////////////////////////////////////////////////////////////////// | |
854 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
855 llvm::Constant* DtoConstInitializer(Type* type, Initializer* init) |
1 | 856 { |
21
8d45266bbabe
[svn r25] * Fixed a lot of problems with string literals
lindquist
parents:
18
diff
changeset
|
857 llvm::Constant* _init = 0; // may return zero |
1 | 858 if (!init) |
859 { | |
40 | 860 Logger::println("const default initializer for %s", type->toChars()); |
861 _init = type->defaultInit()->toConstElem(gIR); | |
1 | 862 } |
863 else if (ExpInitializer* ex = init->isExpInitializer()) | |
864 { | |
40 | 865 Logger::println("const expression initializer"); |
866 _init = ex->exp->toConstElem(gIR); | |
1 | 867 } |
868 else if (StructInitializer* si = init->isStructInitializer()) | |
869 { | |
40 | 870 Logger::println("const struct initializer"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
871 _init = DtoConstStructInitializer(si); |
1 | 872 } |
873 else if (ArrayInitializer* ai = init->isArrayInitializer()) | |
874 { | |
40 | 875 Logger::println("const array initializer"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
876 _init = DtoConstArrayInitializer(ai); |
1 | 877 } |
878 else if (init->isVoidInitializer()) | |
879 { | |
40 | 880 Logger::println("const void initializer"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
881 const llvm::Type* ty = DtoType(type); |
1 | 882 _init = llvm::Constant::getNullValue(ty); |
883 } | |
884 else { | |
40 | 885 Logger::println("unsupported const initializer: %s", init->toChars()); |
886 } | |
887 return _init; | |
888 } | |
889 | |
890 ////////////////////////////////////////////////////////////////////////////////////////// | |
891 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
892 void DtoInitializer(Initializer* init) |
40 | 893 { |
894 if (ExpInitializer* ex = init->isExpInitializer()) | |
895 { | |
896 Logger::println("expression initializer"); | |
897 elem* e = ex->exp->toElem(gIR); | |
898 delete e; | |
899 } | |
900 else { | |
1 | 901 Logger::println("unsupported initializer: %s", init->toChars()); |
902 } | |
903 } | |
6 | 904 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
905 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
906 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
907 llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb) |
6 | 908 { |
909 std::vector<llvm::Value*> v(2); | |
910 v[0] = i0; | |
911 v[1] = i1; | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
912 Logger::cout() << "DtoGEP: " << *ptr << '\n'; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
913 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
6 | 914 } |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
915 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
916 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
917 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
918 llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb) |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
919 { |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
920 size_t n = src.size(); |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
921 std::vector<llvm::Value*> dst(n); |
40 | 922 std::ostream& ostr = Logger::cout(); |
923 ostr << "indices for '" << *ptr << "':"; | |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
924 for (size_t i=0; i<n; ++i) |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
925 { |
40 | 926 ostr << ' ' << i; |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
927 dst[i] = llvm::ConstantInt::get(llvm::Type::Int32Ty, src[i], false); |
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
928 } |
40 | 929 ostr << '\n'; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
930 return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb?bb:gIR->scopebb()); |
8
5e69b77a5c51
[svn r12] fixed accessing aggregate fields of aggregates
lindquist
parents:
6
diff
changeset
|
931 } |
9 | 932 |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
933 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
934 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
935 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb) |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
936 { |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
937 return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb?bb:gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
938 } |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
939 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
940 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
941 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
942 llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb) |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
943 { |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
944 std::vector<llvm::Value*> v(2); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
945 v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
946 v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
947 return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb?bb:gIR->scopebb()); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
948 } |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
949 |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
950 ////////////////////////////////////////////////////////////////////////////////////////// |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
951 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
952 static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl) |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
953 { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
954 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
955 const llvm::FunctionType* fty = DtoVaFunctionType(fdecl); |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
956 llvm::Constant* fn = 0; |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
957 |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
958 if (fdecl->llvmInternal == LLVMva_start) { |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
959 fn = gIR->module->getOrInsertFunction("llvm.va_start", fty); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
960 assert(fn); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
961 } |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
962 else if (fdecl->llvmInternal == LLVMva_intrinsic) { |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
963 fn = gIR->module->getOrInsertFunction(fdecl->llvmInternal1, fty); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
964 assert(fn); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
965 } |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
966 else |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
967 assert(0); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
968 |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
969 llvm::Function* func = llvm::cast_or_null<llvm::Function>(fn); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
970 assert(func); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
971 assert(func->isIntrinsic()); |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
972 fdecl->llvmValue = func; |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
973 return func; |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
974 } |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
975 |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
976 ////////////////////////////////////////////////////////////////////////////////////////// |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
977 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
978 llvm::Function* DtoDeclareFunction(FuncDeclaration* fdecl) |
9 | 979 { |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
980 if ((fdecl->llvmInternal == LLVMva_start) || (fdecl->llvmInternal == LLVMva_intrinsic)) { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
981 return DtoDeclareVaFunction(fdecl); |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
982 } |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
983 |
27
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
984 // mangled name |
55
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
985 char* mangled_name; |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
986 if (fdecl->llvmInternal == LLVMintrinsic) |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
987 mangled_name = fdecl->llvmInternal1; |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
988 else |
0ccfae271c45
[svn r59] Added support for C-style variadic functions. Currently only works on x86, x86-64 va_arg is broken in LLVM 2.1. PPC and PPC64 unknown.
lindquist
parents:
54
diff
changeset
|
989 mangled_name = fdecl->mangle(); |
27
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
990 |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
991 // unit test special handling |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
992 if (fdecl->isUnitTestDeclaration()) |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
993 { |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
994 assert(0 && "no unittests yet"); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
995 /*const llvm::FunctionType* fnty = llvm::FunctionType::get(llvm::Type::VoidTy, std::vector<const llvm::Type*>(), false); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
996 // make the function |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
997 llvm::Function* func = gIR->module->getFunction(mangled_name); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
998 if (func == 0) |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
999 func = new llvm::Function(fnty,llvm::GlobalValue::InternalLinkage,mangled_name,gIR->module); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1000 func->setCallingConv(llvm::CallingConv::Fast); |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1001 fdecl->llvmValue = func; |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1002 return func; |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1003 */ |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1004 } |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1005 |
92408a3a2bac
[svn r31] * Fixed returning through hidden pointer was unable to report back the return value
lindquist
parents:
24
diff
changeset
|
1006 // regular function |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1007 TypeFunction* f = (TypeFunction*)DtoDType(fdecl->type); |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1008 assert(f != 0); |
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1009 |
9 | 1010 if (fdecl->llvmValue != 0) { |
18 | 1011 if (!llvm::isa<llvm::Function>(fdecl->llvmValue)) |
1012 { | |
1013 Logger::cout() << *fdecl->llvmValue << '\n'; | |
1014 assert(0); | |
1015 } | |
9 | 1016 return llvm::cast<llvm::Function>(fdecl->llvmValue); |
1017 } | |
1018 | |
18 | 1019 Logger::print("FuncDeclaration::toObjFile(%s): %s\n", fdecl->needThis()?"this":"static",fdecl->toChars()); |
9 | 1020 LOG_SCOPE; |
1021 | |
1022 if (fdecl->llvmInternal == LLVMintrinsic && fdecl->fbody) { | |
1023 error("intrinsics cannot have function bodies"); | |
1024 fatal(); | |
1025 } | |
1026 | |
1027 // construct function | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1028 const llvm::FunctionType* functype = (f->llvmType == 0) ? DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType); |
9 | 1029 |
1030 // make the function | |
1031 llvm::Function* func = gIR->module->getFunction(mangled_name); | |
1032 if (func == 0) { | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1033 func = new llvm::Function(functype,DtoLinkage(fdecl->protection, fdecl->storage_class),mangled_name,gIR->module); |
9 | 1034 } |
1035 | |
1036 if (fdecl->llvmInternal != LLVMintrinsic) | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1037 func->setCallingConv(DtoCallingConv(f->linkage)); |
9 | 1038 |
1039 fdecl->llvmValue = func; | |
1040 f->llvmType = functype; | |
11
d3ee9efe20e2
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
lindquist
parents:
9
diff
changeset
|
1041 assert(llvm::isa<llvm::FunctionType>(f->llvmType)); |
9 | 1042 |
1043 if (fdecl->isMain()) { | |
1044 gIR->mainFunc = func; | |
1045 } | |
1046 | |
1047 // name parameters | |
1048 llvm::Function::arg_iterator iarg = func->arg_begin(); | |
1049 int k = 0; | |
1050 if (f->llvmRetInPtr) { | |
1051 iarg->setName("retval"); | |
1052 f->llvmRetArg = iarg; | |
1053 ++iarg; | |
1054 } | |
1055 if (f->llvmUsesThis) { | |
1056 iarg->setName("this"); | |
1057 ++iarg; | |
1058 } | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1059 int varargs = -1; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1060 if (f->linkage == LINKd && f->varargs == 1) |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1061 varargs = 0; |
9 | 1062 for (; iarg != func->arg_end(); ++iarg) |
1063 { | |
1064 Argument* arg = Argument::getNth(f->parameters, k++); | |
1065 //arg->llvmValue = iarg; | |
1066 //printf("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident); | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1067 if (arg && arg->ident != 0) { |
9 | 1068 if (arg->vardecl) { |
1069 arg->vardecl->llvmValue = iarg; | |
1070 } | |
1071 iarg->setName(arg->ident->toChars()); | |
1072 } | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1073 else if (!arg && varargs >= 0) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1074 if (varargs == 0) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1075 iarg->setName("_arguments"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1076 fdecl->llvmArguments = iarg; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1077 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1078 else if (varargs == 1) { |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1079 iarg->setName("_argptr"); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1080 fdecl->llvmArgPtr = iarg; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1081 } |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1082 else |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1083 assert(0); |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1084 varargs++; |
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1085 } |
9 | 1086 else { |
1087 iarg->setName("unnamed"); | |
1088 } | |
1089 } | |
1090 | |
1091 return func; | |
1092 } | |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1093 |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1094 ////////////////////////////////////////////////////////////////////////////////////////// |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1095 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1096 void DtoGiveArgumentStorage(elem* l) |
29
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1097 { |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1098 assert(l->mem == 0); |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1099 assert(l->val); |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1100 assert(llvm::isa<llvm::Argument>(l->val)); |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1101 assert(l->vardecl != 0); |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1102 |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1103 llvm::AllocaInst* allocainst = new llvm::AllocaInst(l->val->getType(), l->val->getName()+"_storage", gIR->topallocapoint()); |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1104 l->mem = allocainst; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1105 l->vardecl->llvmValue = l->mem; |
253a5fc4033a
[svn r33] * Added support for assignment to function arguments
lindquist
parents:
27
diff
changeset
|
1106 } |
34 | 1107 |
1108 ////////////////////////////////////////////////////////////////////////////////////////// | |
1109 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1110 llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty) |
34 | 1111 { |
1112 /*size_t sz = gTargetData->getTypeSize(ty); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1113 llvm::ConstantInt* n = llvm::ConstantInt::get(DtoSize_t(), sz, false); |
34 | 1114 if (ptr == 0) { |
1115 llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
1116 ptr = llvm::ConstantPointerNull::get(i8pty); | |
1117 } | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1118 return DtoRealloc(ptr, n);*/ |
34 | 1119 return NULL; |
1120 } | |
1121 | |
1122 ////////////////////////////////////////////////////////////////////////////////////////// | |
1123 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1124 llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* n) |
34 | 1125 { |
1126 assert(ptr); | |
1127 assert(n); | |
1128 | |
1129 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_realloc"); | |
1130 assert(fn); | |
1131 | |
1132 llvm::Value* newptr = ptr; | |
1133 | |
1134 llvm::PointerType* i8pty = llvm::PointerType::get(llvm::Type::Int8Ty); | |
1135 if (ptr->getType() != i8pty) { | |
1136 newptr = new llvm::BitCastInst(ptr,i8pty,"tmp",gIR->scopebb()); | |
1137 } | |
1138 | |
1139 std::vector<llvm::Value*> args; | |
1140 args.push_back(newptr); | |
1141 args.push_back(n); | |
1142 llvm::Value* ret = new llvm::CallInst(fn, args.begin(), args.end(), "tmprealloc", gIR->scopebb()); | |
1143 | |
1144 return ret->getType() == ptr->getType() ? ret : new llvm::BitCastInst(ret,ptr->getType(),"tmp",gIR->scopebb()); | |
1145 } | |
1146 | |
1147 ////////////////////////////////////////////////////////////////////////////////////////// | |
1148 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1149 void DtoAssert(llvm::Value* cond, llvm::Value* loc, llvm::Value* msg) |
34 | 1150 { |
1151 assert(loc); | |
1152 std::vector<llvm::Value*> llargs; | |
1153 llargs.resize(3); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1154 llargs[0] = cond ? DtoBoolean(cond) : llvm::ConstantInt::getFalse(); |
34 | 1155 llargs[1] = loc; |
1156 llargs[2] = msg ? msg : llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)); | |
1157 | |
1158 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_assert"); | |
1159 assert(fn); | |
1160 llvm::CallInst* call = new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); | |
1161 call->setCallingConv(llvm::CallingConv::C); | |
1162 } | |
1163 | |
40 | 1164 ////////////////////////////////////////////////////////////////////////////////////////// |
34 | 1165 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1166 llvm::Value* DtoArgument(const llvm::Type* paramtype, Argument* fnarg, Expression* argexp) |
40 | 1167 { |
1168 llvm::Value* retval = 0; | |
1169 | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1170 bool haslvals = !gIR->exps.empty(); |
40 | 1171 if (haslvals) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1172 gIR->exps.push_back(IRExp(NULL,NULL,NULL)); |
40 | 1173 |
1174 elem* arg = argexp->toElem(gIR); | |
1175 | |
1176 if (haslvals) | |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1177 gIR->exps.pop_back(); |
40 | 1178 |
1179 if (arg->inplace) { | |
1180 assert(arg->mem != 0); | |
1181 retval = arg->mem; | |
1182 delete arg; | |
1183 return retval; | |
1184 } | |
1185 | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1186 Type* realtype = DtoDType(argexp->type); |
40 | 1187 TY argty = realtype->ty; |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1188 if (DtoIsPassedByRef(realtype)) { |
40 | 1189 if (!fnarg || !fnarg->llvmCopy) { |
1190 retval = arg->getValue(); | |
1191 assert(retval != 0); | |
1192 } | |
1193 else { | |
1194 llvm::Value* allocaInst = 0; | |
1195 llvm::BasicBlock* entryblock = &gIR->topfunc()->front(); | |
1196 //const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(arg->mem->getType()); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1197 const llvm::Type* realtypell = DtoType(realtype); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1198 const llvm::PointerType* pty = llvm::PointerType::get(realtypell); |
40 | 1199 if (argty == Tstruct) { |
1200 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1201 DtoStructCopy(allocaInst,arg->mem); |
40 | 1202 } |
1203 else if (argty == Tdelegate) { | |
1204 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1205 DtoDelegateCopy(allocaInst,arg->mem); |
40 | 1206 } |
1207 else if (argty == Tarray) { | |
1208 if (arg->type == elem::SLICE) { | |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1209 allocaInst = new llvm::AllocaInst(realtypell, "tmpparam", gIR->topallocapoint()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1210 DtoSetArray(allocaInst, arg->arg, arg->mem); |
40 | 1211 } |
1212 else { | |
1213 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", gIR->topallocapoint()); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1214 DtoArrayAssign(allocaInst,arg->mem); |
40 | 1215 } |
1216 } | |
1217 else | |
1218 assert(0); | |
1219 | |
1220 assert(allocaInst != 0); | |
1221 retval = allocaInst; | |
1222 } | |
1223 } | |
1224 else if (!fnarg || fnarg->llvmCopy) { | |
1225 Logger::println("regular arg"); | |
1226 assert(arg->type != elem::SLICE); | |
1227 if (arg->mem) Logger::cout() << "mem = " << *arg->mem << '\n'; | |
1228 if (arg->val) Logger::cout() << "val = " << *arg->val << '\n'; | |
1229 if (arg->arg) Logger::cout() << "arg = " << *arg->arg << '\n'; | |
1230 retval = arg->arg ? arg->arg : arg->field ? arg->mem : arg->getValue(); | |
1231 } | |
1232 else { | |
1233 Logger::println("as ptr arg"); | |
1234 retval = arg->mem ? arg->mem : arg->val; | |
57
a9d29e9f1fed
[svn r61] Added support for D-style variadic functions :)
lindquist
parents:
55
diff
changeset
|
1235 if (paramtype && retval->getType() != paramtype) |
40 | 1236 { |
1237 assert(retval->getType() == paramtype->getContainedType(0)); | |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1238 DtoGiveArgumentStorage(arg); |
40 | 1239 new llvm::StoreInst(retval, arg->mem, gIR->scopebb()); |
1240 retval = arg->mem; | |
1241 } | |
1242 } | |
1243 | |
78
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1244 if (fnarg && paramtype && retval->getType() != paramtype) { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1245 // this is unfortunately needed with the way SymOffExp is overused |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1246 // and static arrays can end up being a pointer to their element type |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1247 if (arg->field) { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1248 retval = gIR->ir->CreateBitCast(retval, paramtype, "tmp"); |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1249 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1250 else { |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1251 Logger::cout() << "got '" << *retval->getType() << "' expected '" << *paramtype << "'\n"; |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1252 assert(0 && "parameter type that was actually passed is invalid"); |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1253 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1254 } |
2332006e1fa4
[svn r82] Fixed: Fall-through switch cases were broken.
lindquist
parents:
77
diff
changeset
|
1255 |
40 | 1256 delete arg; |
1257 | |
1258 return retval; | |
1259 } | |
34 | 1260 |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1261 ////////////////////////////////////////////////////////////////////////////////////////// |
34 | 1262 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1263 llvm::Value* DtoNestedVariable(VarDeclaration* vd) |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1264 { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1265 FuncDeclaration* fd = vd->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1266 assert(fd != NULL); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1267 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1268 IRFunction* fcur = &gIR->func(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1269 FuncDeclaration* f = fcur->decl; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1270 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1271 // on this stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1272 if (fd == f) { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1273 llvm::Value* v = DtoGEPi(vd->llvmValue,0,unsigned(vd->llvmNestedIndex),"tmp"); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1274 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { |
73 | 1275 Logger::cout() << "1267 loading: " << *v << '\n'; |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1276 v = gIR->ir->CreateLoad(v,"tmp"); |
73 | 1277 } |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1278 return v; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1279 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1280 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1281 // on a caller stack |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1282 llvm::Value* ptr = f->llvmThisVar; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1283 assert(ptr); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1284 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1285 f = f->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1286 assert(f); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1287 assert(f->llvmNested); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1288 const llvm::Type* nesttype = f->llvmNested->getType(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1289 assert(nesttype); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1290 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1291 ptr = gIR->ir->CreateBitCast(ptr, nesttype, "tmp"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1292 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1293 Logger::cout() << "nested var reference:" << '\n' << *ptr << *nesttype << '\n'; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1294 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1295 while (f) { |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1296 if (fd == f) { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1297 llvm::Value* v = DtoGEPi(ptr,0,vd->llvmNestedIndex,"tmp"); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1298 if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))) { |
73 | 1299 Logger::cout() << "1291 loading: " << *v << '\n'; |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1300 v = gIR->ir->CreateLoad(v,"tmp"); |
73 | 1301 } |
67
f918f3e2e99e
[svn r71] Fixed accessing parent function arguments from inside nested delegates.
lindquist
parents:
62
diff
changeset
|
1302 return v; |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1303 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1304 else { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1305 ptr = DtoGEPi(ptr,0,0,"tmp"); |
50
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1306 ptr = gIR->ir->CreateLoad(ptr,"tmp"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1307 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1308 f = f->toParent()->isFuncDeclaration(); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1309 } |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1310 |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1311 assert(0 && "nested var not found"); |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1312 return NULL; |
6fcc08a4d406
[svn r54] Added support for nested delegates referencing parent's stack variables.
lindquist
parents:
49
diff
changeset
|
1313 } |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1314 |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1315 ////////////////////////////////////////////////////////////////////////////////////////// |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1316 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1317 void DtoAssign(Type* t, llvm::Value* lhs, llvm::Value* rhs) |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1318 { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1319 Logger::cout() << "assignment:" << '\n' << *lhs << *rhs << '\n'; |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1320 |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1321 if (t->ty == Tstruct) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1322 assert(lhs->getType() == rhs->getType()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1323 DtoStructCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1324 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1325 else if (t->ty == Tarray) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1326 assert(lhs->getType() == rhs->getType()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1327 DtoArrayAssign(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1328 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1329 else if (t->ty == Tsarray) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1330 assert(lhs->getType() == rhs->getType()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1331 DtoStaticArrayCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1332 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1333 else if (t->ty == Tdelegate) { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1334 assert(lhs->getType() == rhs->getType()); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1335 DtoDelegateCopy(lhs,rhs); |
51
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1336 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1337 else { |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1338 assert(lhs->getType()->getContainedType(0) == rhs->getType()); |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1339 gIR->ir->CreateStore(rhs, lhs); |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1340 } |
61bc1b4ad3c4
[svn r55] Foreach was always generating code as if the value variable was 'ref'
lindquist
parents:
50
diff
changeset
|
1341 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1342 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1343 ////////////////////////////////////////////////////////////////////////////////////////// |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1344 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1345 llvm::ConstantInt* DtoConstSize_t(size_t i) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1346 { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1347 return llvm::ConstantInt::get(DtoSize_t(), i, false); |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1348 } |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1349 llvm::ConstantInt* DtoConstUint(unsigned i) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1350 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1351 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1352 } |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1353 llvm::ConstantInt* DtoConstInt(int i) |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1354 { |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1355 return llvm::ConstantInt::get(llvm::Type::Int32Ty, i, true); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1356 } |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1357 llvm::Constant* DtoConstBool(bool b) |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1358 { |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1359 return llvm::ConstantInt::get(llvm::Type::Int1Ty, b, false); |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1360 } |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1361 |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1362 ////////////////////////////////////////////////////////////////////////////////////////// |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1363 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1364 llvm::Constant* DtoConstString(const char* str) |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1365 { |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1366 std::string s(str); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1367 llvm::Constant* init = llvm::ConstantArray::get(s, true); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1368 llvm::GlobalVariable* gvar = new llvm::GlobalVariable( |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1369 init->getType(), true,llvm::GlobalValue::InternalLinkage, init, "stringliteral", gIR->module); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1370 llvm::Constant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) }; |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1371 return DtoConstSlice( |
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1372 DtoConstSize_t(s.length()), |
54
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1373 llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2) |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1374 ); |
28e99b04a132
[svn r58] Fixed cond expression resulting in a non-basic type.
lindquist
parents:
53
diff
changeset
|
1375 } |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1376 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1377 ////////////////////////////////////////////////////////////////////////////////////////// |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1378 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1379 void DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes) |
58
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1380 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1381 assert(dst->getType() == src->getType()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1382 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1383 llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1384 llvm::Value *dstarr, *srcarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1385 if (dst->getType() == arrty) |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1386 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1387 dstarr = dst; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1388 srcarr = src; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1389 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1390 else |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1391 { |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1392 dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1393 srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1394 } |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1395 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1396 llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32(); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1397 std::vector<llvm::Value*> llargs; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1398 llargs.resize(4); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1399 llargs[0] = dstarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1400 llargs[1] = srcarr; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1401 llargs[2] = nbytes; |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1402 llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1403 |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1404 new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb()); |
2c3cd3596187
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
lindquist
parents:
57
diff
changeset
|
1405 } |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1406 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1407 ////////////////////////////////////////////////////////////////////////////////////////// |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1408 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1409 llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, unsigned os, std::vector<unsigned>& idxs) |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1410 { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1411 Logger::println("checking for offset %u type %s:", os, t->toChars()); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1412 LOG_SCOPE; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1413 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1414 if (idxs.empty()) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1415 idxs.push_back(0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1416 |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1417 const llvm::Type* llt = llvm::PointerType::get(DtoType(t)); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1418 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1419 for (unsigned i=0; i<sd->fields.dim; ++i) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1420 VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i]; |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1421 Type* vdtype = DtoDType(vd->type); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1422 Logger::println("found %u type %s", vd->offset, vdtype->toChars()); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1423 assert(vd->llvmFieldIndex >= 0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1424 if (os == vd->offset && vdtype == t) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1425 idxs.push_back(vd->llvmFieldIndex); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1426 ptr = DtoGEP(ptr, idxs, "tmp"); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1427 if (ptr->getType() != llt) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1428 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1429 if (vd->llvmFieldIndexOffset) |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1430 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1431 return ptr; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1432 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1433 else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1434 TypeStruct* ts = (TypeStruct*)vdtype; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1435 StructDeclaration* ssd = ts->sym; |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1436 idxs.push_back(vd->llvmFieldIndex); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1437 if (vd->llvmFieldIndexOffset) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1438 Logger::println("has union field offset"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1439 ptr = DtoGEP(ptr, idxs, "tmp"); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1440 if (ptr->getType() != llt) |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1441 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1442 ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb()); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1443 std::vector<unsigned> tmp; |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1444 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1445 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1446 else { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1447 const llvm::Type* sty = llvm::PointerType::get(DtoType(vd->type)); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1448 if (ptr->getType() != sty) { |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1449 ptr = gIR->ir->CreateBitCast(ptr, sty, "tmp"); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1450 std::vector<unsigned> tmp; |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1451 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1452 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1453 else { |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1454 return DtoIndexStruct(ptr, ssd, t, os-vd->offset, idxs); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1455 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1456 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1457 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1458 } |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1459 |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1460 size_t llt_sz = gTargetData->getTypeSize(llt->getContainedType(0)); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1461 assert(os % llt_sz == 0); |
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1462 ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp"); |
81
3587401b6eeb
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
lindquist
parents:
78
diff
changeset
|
1463 return new llvm::GetElementPtrInst(ptr, DtoConstUint(os / llt_sz), "tmp", gIR->scopebb()); |
77
714057ff2dbb
[svn r81] Fixed: Union support was very buggy. Should be fairly solid now.
lindquist
parents:
73
diff
changeset
|
1464 } |