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