Mercurial > projects > ldc
comparison gen/toir.c @ 40:8b0e809563df trunk
[svn r44] Lots of bug fixes.
New array literal support
New array ~= operator support (for single element)
New with statement support
More...
author | lindquist |
---|---|
date | Fri, 19 Oct 2007 07:43:21 +0200 |
parents | 77cdca8c210f |
children | 0b9b286b67b6 |
comparison
equal
deleted
inserted
replaced
39:fd5e8bbfcb25 | 40:8b0e809563df |
---|---|
10 #include <math.h> | 10 #include <math.h> |
11 #include <sstream> | 11 #include <sstream> |
12 #include <fstream> | 12 #include <fstream> |
13 #include <iostream> | 13 #include <iostream> |
14 | 14 |
15 #include "llvm/Type.h" | 15 #include "gen/llvm.h" |
16 #include "llvm/DerivedTypes.h" | |
17 #include "llvm/Constants.h" | |
18 #include "llvm/Instructions.h" | |
19 #include "llvm/IntrinsicInst.h" | |
20 #include "llvm/CallingConv.h" | |
21 | 16 |
22 #include "total.h" | 17 #include "total.h" |
23 #include "init.h" | 18 #include "init.h" |
24 #include "symbol.h" | 19 #include "symbol.h" |
25 #include "mtype.h" | 20 #include "mtype.h" |
58 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); | 53 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); |
59 //allocainst->setAlignment(vd->type->alignsize()); // TODO | 54 //allocainst->setAlignment(vd->type->alignsize()); // TODO |
60 vd->llvmValue = allocainst; | 55 vd->llvmValue = allocainst; |
61 // e->val = really needed?? | 56 // e->val = really needed?? |
62 | 57 |
63 LLVM_DtoInitializer(vd->type, vd->init); | 58 LLVM_DtoInitializer(vd->init); |
64 } | 59 } |
65 } | 60 } |
66 // struct declaration | 61 // struct declaration |
67 else if (StructDeclaration* s = declaration->isStructDeclaration()) | 62 else if (StructDeclaration* s = declaration->isStructDeclaration()) |
68 { | 63 { |
69 Logger::println("StructDeclaration"); | 64 Logger::println("StructDeclaration"); |
70 s->toObjFile(); | 65 s->toObjFile(); |
71 } | 66 } |
67 // function declaration | |
68 else if (FuncDeclaration* f = declaration->isFuncDeclaration()) | |
69 { | |
70 Logger::println("FuncDeclaration"); | |
71 f->toObjFile(); | |
72 } | |
73 // alias declaration | |
74 else if (AliasDeclaration* a = declaration->isAliasDeclaration()) | |
75 { | |
76 Logger::println("AliasDeclaration"); | |
77 } | |
72 // unsupported declaration | 78 // unsupported declaration |
73 else | 79 else |
74 { | 80 { |
75 error("Only Var/Struct-Declaration is supported for DeclarationExp"); | 81 error("Only Var/Struct-Declaration is supported for DeclarationExp"); |
76 fatal(); | 82 fatal(); |
89 | 95 |
90 assert(var); | 96 assert(var); |
91 if (VarDeclaration* vd = var->isVarDeclaration()) | 97 if (VarDeclaration* vd = var->isVarDeclaration()) |
92 { | 98 { |
93 Logger::println("VarDeclaration"); | 99 Logger::println("VarDeclaration"); |
100 | |
101 // needed to take care of forward references of global variables | |
102 if (!vd->llvmTouched && vd->isDataseg()) | |
103 vd->toObjFile(); | |
94 | 104 |
95 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 105 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) |
96 { | 106 { |
97 Logger::println("TypeInfoDeclaration"); | 107 Logger::println("TypeInfoDeclaration"); |
98 } | 108 } |
99 | 109 |
100 // this must be a dollar expression or some other magic value | 110 // this must be a dollar expression or some other magic value |
111 // or it could be a forward declaration of a global variable | |
101 if (!vd->llvmValue) | 112 if (!vd->llvmValue) |
102 { | 113 { |
103 // dollar | 114 // dollar |
104 if (!p->arrays.empty()) | 115 if (!p->arrays.empty()) |
105 { | 116 { |
107 //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); | 118 //llvm::Value* tmp = new llvm::GetElementPtrInst(p->arrays.back(),zero,zero,"tmp",p->scopebb()); |
108 llvm::Value* tmp = LLVM_DtoGEP(p->arrays.back(),zero,zero,"tmp",p->scopebb()); | 119 llvm::Value* tmp = LLVM_DtoGEP(p->arrays.back(),zero,zero,"tmp",p->scopebb()); |
109 e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 120 e->val = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
110 e->type = elem::VAL; | 121 e->type = elem::VAL; |
111 } | 122 } |
112 // magic | 123 // typeinfo |
113 else | 124 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) |
114 { | 125 { |
115 if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 126 tid->toObjFile(); |
116 { | 127 e->mem = tid->llvmValue; |
117 tid->toObjFile(); | 128 e->type = elem::VAR; |
118 e->mem = tid->llvmValue; | 129 } |
119 e->type = elem::VAR; | 130 // global forward ref |
120 } | 131 else { |
121 else { | 132 Logger::println("unsupported: %s\n", vd->toChars()); |
122 Logger::println("unsupported: %s\n", vd->toChars()); | 133 assert(0 && "only magic supported is typeinfo"); |
123 assert(0 && "only magic supported is typeinfo"); | |
124 } | |
125 } | 134 } |
126 return e; | 135 return e; |
127 } | 136 } |
128 | 137 |
129 // function parameter | 138 // function parameter |
132 if (vd->storage_class & (STCref | STCout)) { | 141 if (vd->storage_class & (STCref | STCout)) { |
133 e->mem = vd->llvmValue; | 142 e->mem = vd->llvmValue; |
134 e->type = elem::VAR; | 143 e->type = elem::VAR; |
135 } | 144 } |
136 else { | 145 else { |
137 if (vd->type->ty == Tstruct || vd->type->ty == Tdelegate || vd->type->ty == Tarray) { | 146 if (LLVM_DtoIsPassedByRef(vd->type)) { |
138 e->mem = vd->llvmValue; | 147 e->mem = vd->llvmValue; |
139 e->type = elem::VAR; | 148 e->type = elem::VAR; |
140 } | 149 } |
141 else { | 150 else { |
142 if (llvm::isa<llvm::Argument>(vd->llvmValue)) { | 151 if (llvm::isa<llvm::Argument>(vd->llvmValue)) { |
171 e->funcdecl = fdecl; | 180 e->funcdecl = fdecl; |
172 } | 181 } |
173 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | 182 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) |
174 { | 183 { |
175 // this seems to be the static initialiser for structs | 184 // this seems to be the static initialiser for structs |
176 Logger::print("Sym: type=%s\n", sdecl->type->toChars()); | 185 Type* sdecltype = LLVM_DtoDType(sdecl->type); |
177 assert(sdecl->type->ty == Tstruct); | 186 Logger::print("Sym: type=%s\n", sdecltype->toChars()); |
178 //assert(sdecl->llvmInitZ); | 187 assert(sdecltype->ty == Tstruct); |
179 //e->val = sdecl->llvmInitZ; | 188 TypeStruct* ts = (TypeStruct*)sdecltype; |
180 TypeStruct* ts = (TypeStruct*)sdecl->type; | |
181 e->mem = ts->llvmInit; | 189 e->mem = ts->llvmInit; |
182 assert(e->mem); | 190 assert(e->mem); |
183 e->type = elem::VAR; | 191 e->type = elem::VAR; |
184 } | 192 } |
185 else | 193 else |
191 return e; | 199 return e; |
192 } | 200 } |
193 | 201 |
194 ////////////////////////////////////////////////////////////////////////////////////////// | 202 ////////////////////////////////////////////////////////////////////////////////////////// |
195 | 203 |
204 llvm::Constant* VarExp::toConstElem(IRState* p) | |
205 { | |
206 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
207 LOG_SCOPE; | |
208 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | |
209 { | |
210 // this seems to be the static initialiser for structs | |
211 Type* sdecltype = LLVM_DtoDType(sdecl->type); | |
212 Logger::print("Sym: type=%s\n", sdecltype->toChars()); | |
213 assert(sdecltype->ty == Tstruct); | |
214 TypeStruct* ts = (TypeStruct*)sdecltype; | |
215 assert(ts->sym->llvmInitZ); | |
216 return ts->sym->llvmInitZ; | |
217 } | |
218 assert(0 && "Only support const var exp is SymbolDeclaration"); | |
219 return NULL; | |
220 } | |
221 | |
222 ////////////////////////////////////////////////////////////////////////////////////////// | |
223 | |
196 elem* IntegerExp::toElem(IRState* p) | 224 elem* IntegerExp::toElem(IRState* p) |
197 { | 225 { |
198 Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars()); | 226 Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars()); |
199 LOG_SCOPE; | 227 LOG_SCOPE; |
200 elem* e = new elem; | 228 elem* e = new elem; |
229 e->val = toConstElem(p); | |
230 e->type = elem::CONST; | |
231 return e; | |
232 } | |
233 | |
234 ////////////////////////////////////////////////////////////////////////////////////////// | |
235 | |
236 llvm::Constant* IntegerExp::toConstElem(IRState* p) | |
237 { | |
238 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
239 LOG_SCOPE; | |
201 const llvm::Type* t = LLVM_DtoType(type); | 240 const llvm::Type* t = LLVM_DtoType(type); |
202 if (llvm::isa<llvm::PointerType>(t)) { | 241 if (llvm::isa<llvm::PointerType>(t)) { |
203 llvm::Constant* i = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)value,false); | 242 llvm::Constant* i = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)value,false); |
204 e->val = llvm::ConstantExpr::getIntToPtr(i, t); | 243 return llvm::ConstantExpr::getIntToPtr(i, t); |
205 } | 244 } |
206 else if (llvm::isa<llvm::IntegerType>(t)) { | 245 else if (llvm::isa<llvm::IntegerType>(t)) { |
207 e->val = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); | 246 return llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); |
208 } | 247 } |
209 else { | 248 assert(0); |
210 assert(0); | 249 return NULL; |
211 } | 250 } |
251 | |
252 ////////////////////////////////////////////////////////////////////////////////////////// | |
253 | |
254 elem* RealExp::toElem(IRState* p) | |
255 { | |
256 Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
257 LOG_SCOPE; | |
258 elem* e = new elem; | |
259 e->val = toConstElem(p); | |
212 e->type = elem::CONST; | 260 e->type = elem::CONST; |
213 return e; | 261 return e; |
214 } | 262 } |
215 | 263 |
216 ////////////////////////////////////////////////////////////////////////////////////////// | 264 ////////////////////////////////////////////////////////////////////////////////////////// |
217 | 265 |
218 elem* RealExp::toElem(IRState* p) | 266 llvm::Constant* RealExp::toConstElem(IRState* p) |
219 { | 267 { |
220 Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars()); | 268 Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
221 LOG_SCOPE; | 269 LOG_SCOPE; |
222 elem* e = new elem; | |
223 const llvm::Type* fty = LLVM_DtoType(type); | 270 const llvm::Type* fty = LLVM_DtoType(type); |
224 if (type->ty == Tfloat32) | 271 if (type->ty == Tfloat32) |
225 e->val = llvm::ConstantFP::get(fty,float(value)); | 272 return llvm::ConstantFP::get(fty,float(value)); |
226 else if (type->ty == Tfloat64 || type->ty == Tfloat80) | 273 else if (type->ty == Tfloat64 || type->ty == Tfloat80) |
227 e->val = llvm::ConstantFP::get(fty,double(value)); | 274 return llvm::ConstantFP::get(fty,double(value)); |
228 else | 275 assert(0); |
229 assert(0); | 276 return NULL; |
230 e->type = elem::CONST; | |
231 return e; | |
232 } | 277 } |
233 | 278 |
234 ////////////////////////////////////////////////////////////////////////////////////////// | 279 ////////////////////////////////////////////////////////////////////////////////////////// |
235 | 280 |
236 elem* NullExp::toElem(IRState* p) | 281 elem* NullExp::toElem(IRState* p) |
237 { | 282 { |
238 Logger::print("NullExp::toElem(type=%s): %s\n", type->toChars(),toChars()); | 283 Logger::print("NullExp::toElem(type=%s): %s\n", type->toChars(),toChars()); |
239 LOG_SCOPE; | 284 LOG_SCOPE; |
240 elem* e = new elem; | 285 elem* e = new elem; |
286 e->val = toConstElem(p); | |
287 e->type = elem::NUL; | |
288 //Logger::cout() << "null value is now " << *e->val << '\n'; | |
289 return e; | |
290 } | |
291 | |
292 ////////////////////////////////////////////////////////////////////////////////////////// | |
293 | |
294 llvm::Constant* NullExp::toConstElem(IRState* p) | |
295 { | |
296 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars()); | |
297 LOG_SCOPE; | |
241 const llvm::Type* t = LLVM_DtoType(type); | 298 const llvm::Type* t = LLVM_DtoType(type); |
242 | |
243 if (type->ty == Tarray) { | 299 if (type->ty == Tarray) { |
244 assert(llvm::isa<llvm::StructType>(t)); | 300 assert(llvm::isa<llvm::StructType>(t)); |
245 e->val = llvm::ConstantAggregateZero::get(t); | 301 return llvm::ConstantAggregateZero::get(t); |
246 } | 302 } |
247 else | 303 else { |
248 e->val = llvm::Constant::getNullValue(t); | 304 return llvm::Constant::getNullValue(t); |
249 assert(e->val); | 305 } |
250 | 306 assert(0); |
251 Logger::cout() << "null value is now " << *e->val << '\n'; | 307 return NULL; |
252 e->type = elem::NUL; | |
253 return e; | |
254 } | 308 } |
255 | 309 |
256 ////////////////////////////////////////////////////////////////////////////////////////// | 310 ////////////////////////////////////////////////////////////////////////////////////////// |
257 | 311 |
258 elem* StringExp::toElem(IRState* p) | 312 elem* StringExp::toElem(IRState* p) |
259 { | 313 { |
260 Logger::print("StringExp::toElem: %s | \n", toChars(), type->toChars()); | 314 Logger::print("StringExp::toElem: %s | \n", toChars(), type->toChars()); |
261 LOG_SCOPE; | 315 LOG_SCOPE; |
262 | 316 |
263 assert(type->next->ty == Tchar && "Only char is supported"); | 317 Type* dtype = LLVM_DtoDType(type); |
318 | |
319 assert(dtype->next->ty == Tchar && "Only char is supported"); | |
264 assert(sz == 1); | 320 assert(sz == 1); |
265 | 321 |
266 const llvm::Type* ct = LLVM_DtoType(type->next); | 322 const llvm::Type* ct = LLVM_DtoType(dtype->next); |
267 //printf("ct = %s\n", type->next->toChars()); | 323 //printf("ct = %s\n", type->next->toChars()); |
268 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); | 324 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); |
269 | 325 |
270 uint8_t* str = (uint8_t*)string; | 326 uint8_t* str = (uint8_t*)string; |
271 std::string cont((char*)str, len); | 327 std::string cont((char*)str, len); |
274 | 330 |
275 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | 331 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; |
276 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module); | 332 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,"stringliteral",gIR->module); |
277 | 333 |
278 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 334 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
279 //llvm::Value* arrptr = LLVM_DtoGEP(gvar,zero,zero,"tmp",p->scopebb()); | |
280 llvm::Constant* idxs[2] = { zero, zero }; | 335 llvm::Constant* idxs[2] = { zero, zero }; |
281 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 336 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
282 | 337 |
283 elem* e = new elem; | 338 elem* e = new elem; |
284 | 339 |
285 if (type->ty == Tarray) { | 340 if (dtype->ty == Tarray) { |
286 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); | 341 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); |
287 if (p->lvals.empty()) { | 342 if (p->lvals.empty() || !p->toplval()) { |
288 e->type = elem::SLICE; | 343 e->type = elem::SLICE; |
289 e->arg = clen; | 344 e->arg = clen; |
290 e->mem = arrptr; | 345 e->mem = arrptr; |
291 return e; | 346 return e; |
292 } | 347 } |
293 else { | 348 else if (llvm::Value* arr = p->toplval()) { |
294 llvm::Value* arr = p->toplval(); | |
295 if (llvm::isa<llvm::GlobalVariable>(arr)) { | 349 if (llvm::isa<llvm::GlobalVariable>(arr)) { |
296 e->val = LLVM_DtoConstantSlice(clen, arrptr); | 350 e->val = LLVM_DtoConstantSlice(clen, arrptr); |
297 } | 351 } |
298 else { | 352 else { |
299 LLVM_DtoSetArray(arr, clen, arrptr); | 353 LLVM_DtoSetArray(arr, clen, arrptr); |
300 e->inplace = true; | 354 e->inplace = true; |
301 } | 355 } |
302 } | 356 } |
303 } | 357 else |
304 else if (type->ty == Tsarray) { | 358 assert(0); |
359 } | |
360 else if (dtype->ty == Tsarray) { | |
305 const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); | 361 const llvm::Type* dstType = llvm::PointerType::get(llvm::ArrayType::get(ct, len)); |
306 e->mem = new llvm::BitCastInst(gvar, dstType, "tmp", gIR->scopebb()); | 362 e->mem = new llvm::BitCastInst(gvar, dstType, "tmp", gIR->scopebb()); |
307 } | 363 } |
308 else if (type->ty == Tpointer) { | 364 else if (dtype->ty == Tpointer) { |
309 e->mem = arrptr; | 365 e->mem = arrptr; |
310 } | 366 } |
311 else { | 367 else { |
312 assert(0); | 368 assert(0); |
313 } | 369 } |
314 | 370 |
315 e->type = elem::VAL; | 371 e->type = elem::VAL; |
316 | 372 |
317 return e; | 373 return e; |
374 } | |
375 | |
376 ////////////////////////////////////////////////////////////////////////////////////////// | |
377 | |
378 llvm::Constant* StringExp::toConstElem(IRState* p) | |
379 { | |
380 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
381 LOG_SCOPE; | |
382 | |
383 uint8_t* str = (uint8_t*)string; | |
384 std::string cont((char*)str, len); | |
385 | |
386 Type* t = LLVM_DtoDType(type); | |
387 | |
388 llvm::Constant* _init = llvm::ConstantArray::get(cont,true); | |
389 if (t->ty == Tsarray) { | |
390 return _init; | |
391 } | |
392 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | |
393 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module); | |
394 | |
395 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | |
396 llvm::Constant* idxs[2] = { zero, zero }; | |
397 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | |
398 | |
399 if (t->ty == Tpointer) { | |
400 return arrptr; | |
401 } | |
402 | |
403 if (t->ty == Tarray) { | |
404 llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false); | |
405 return LLVM_DtoConstantSlice(clen, arrptr); | |
406 } | |
407 | |
408 assert(0); | |
409 return NULL; | |
318 } | 410 } |
319 | 411 |
320 ////////////////////////////////////////////////////////////////////////////////////////// | 412 ////////////////////////////////////////////////////////////////////////////////////////// |
321 | 413 |
322 elem* AssignExp::toElem(IRState* p) | 414 elem* AssignExp::toElem(IRState* p) |
351 assert(0); | 443 assert(0); |
352 } | 444 } |
353 } | 445 } |
354 //e->val = l->store(r->getValue()); | 446 //e->val = l->store(r->getValue()); |
355 | 447 |
356 TY e1ty = e1->type->ty; | 448 Type* e1type = LLVM_DtoDType(e1->type); |
357 TY e2ty = e2->type->ty; | 449 Type* e2type = LLVM_DtoDType(e2->type); |
358 | 450 TY e1ty = e1type->ty; |
359 elem* e = new elem; | 451 TY e2ty = e2type->ty; |
452 | |
453 elem* e = new elem; | |
454 e->type = elem::VAR; | |
360 | 455 |
361 // struct | 456 // struct |
362 if (e1ty == Tstruct) { | 457 if (e1ty == Tstruct) { |
458 e->mem = l->mem; | |
363 // struct + struct | 459 // struct + struct |
364 if (e2ty == Tstruct) { | 460 if (e2ty == Tstruct) { |
365 // struct literals do the assignment themselvs (in place) | 461 // struct literals do the assignment themselvs (in place) |
366 if (!r->inplace) { | 462 if (!r->inplace) { |
367 TypeStruct* ts = (TypeStruct*)e2->type; | 463 TypeStruct* ts = (TypeStruct*)e2type; |
368 assert(r->mem); | 464 LLVM_DtoStructCopy(ts,l->mem,r->getValue()); |
369 LLVM_DtoStructCopy(ts,l->mem,r->mem); | |
370 } | 465 } |
371 else { | 466 else { |
372 e->inplace = true; | 467 e->inplace = true; |
373 } | 468 } |
374 } | 469 } |
375 // struct + const int | 470 // struct + const int |
376 else if (e2->type->isintegral()){ | 471 else if (e2type->isintegral()){ |
377 IntegerExp* iexp = (IntegerExp*)e2; | 472 IntegerExp* iexp = (IntegerExp*)e2; |
378 assert(iexp->value == 0 && "Only integral struct initializer allowed is zero"); | 473 assert(iexp->value == 0 && "Only integral struct initializer allowed is zero"); |
379 TypeStruct* st = (TypeStruct*)e1->type; | 474 TypeStruct* st = (TypeStruct*)e1type; |
380 LLVM_DtoStructZeroInit(st, l->mem); | 475 LLVM_DtoStructZeroInit(st, l->mem); |
381 } | 476 } |
382 // :x | 477 // :x |
383 else | 478 else |
384 assert(0 && "struct = unknown"); | 479 assert(0 && "struct = unknown"); |
385 } | 480 } |
386 else if (e1ty == Tsarray) { | 481 else if (e1ty == Tsarray) { |
387 assert(0 && "static array = not supported"); | 482 assert(0 && "static array not supported"); |
388 } | 483 } |
389 else if (e1ty == Tarray) { | 484 else if (e1ty == Tarray) { |
390 if (e2->type->isscalar() || e2->type->ty == Tclass){ | 485 if (e2type->isscalar() || e2type->ty == Tclass){ |
391 LLVM_DtoArrayInit(l->mem, r->getValue()); | 486 LLVM_DtoArrayInit(l->mem, r->getValue()); |
392 } | 487 } |
393 else if (e2ty == Tarray) { | 488 else if (e2ty == Tarray) { |
394 //new llvm::StoreInst(r->val,l->val,p->scopebb()); | 489 //new llvm::StoreInst(r->val,l->val,p->scopebb()); |
395 if (r->type == elem::NUL) { | 490 if (r->type == elem::NUL) { |
396 llvm::Constant* c = llvm::cast<llvm::Constant>(r->val); | 491 llvm::Constant* c = llvm::cast<llvm::Constant>(r->val); |
397 assert(c->isNullValue()); | 492 assert(c->isNullValue()); |
398 LLVM_DtoNullArray(l->mem); | 493 LLVM_DtoNullArray(l->mem); |
494 e->mem = l->mem; | |
399 } | 495 } |
400 else if (r->type == elem::SLICE) { | 496 else if (r->type == elem::SLICE) { |
401 if (l->type == elem::SLICE) | 497 if (l->type == elem::SLICE) { |
402 LLVM_DtoArrayCopy(l,r); | 498 LLVM_DtoArrayCopy(l,r); |
403 else | 499 e->type = elem::SLICE; |
404 LLVM_DtoSetArray(l->mem,r->arg,r->mem); | 500 e->mem = l->mem; |
501 e->arg = l->arg; | |
502 } | |
503 else { | |
504 LLVM_DtoSetArray(l->mem,r->arg,r->mem); | |
505 e->mem = l->mem; | |
506 } | |
405 } | 507 } |
406 else { | 508 else { |
407 // new expressions write directly to the array reference | 509 // new expressions write directly to the array reference |
408 // so do string literals | 510 // so do string literals |
511 e->mem = l->mem; | |
409 if (!r->inplace) { | 512 if (!r->inplace) { |
410 assert(r->mem); | 513 assert(r->mem); |
411 LLVM_DtoArrayAssign(l->mem, r->mem); | 514 LLVM_DtoArrayAssign(l->mem, r->mem); |
412 } | 515 } |
413 else { | 516 else { |
417 } | 520 } |
418 else | 521 else |
419 assert(0); | 522 assert(0); |
420 } | 523 } |
421 else if (e1ty == Tpointer) { | 524 else if (e1ty == Tpointer) { |
525 e->mem = l->mem; | |
422 if (e2ty == Tpointer) { | 526 if (e2ty == Tpointer) { |
423 llvm::Value* v = r->field ? r->mem : r->getValue(); | 527 llvm::Value* v = r->field ? r->mem : r->getValue(); |
424 Logger::cout() << "*=*: " << *v << ", " << *l->mem << '\n'; | 528 Logger::cout() << "*=*: " << *v << ", " << *l->mem << '\n'; |
425 new llvm::StoreInst(v, l->mem, p->scopebb()); | 529 new llvm::StoreInst(v, l->mem, p->scopebb()); |
426 } | 530 } |
431 if (e2ty == Tclass) { | 535 if (e2ty == Tclass) { |
432 llvm::Value* tmp = r->getValue(); | 536 llvm::Value* tmp = r->getValue(); |
433 Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n'; | 537 Logger::cout() << "tmp: " << *tmp << " ||| " << *l->mem << '\n'; |
434 // assignment to this in constructor special case | 538 // assignment to this in constructor special case |
435 if (l->isthis) { | 539 if (l->isthis) { |
436 FuncDeclaration* fdecl = p->funcdecls.back(); | 540 FuncDeclaration* fdecl = p->func().decl; |
437 // respecify the this param | 541 // respecify the this param |
438 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar)) | 542 if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar)) |
439 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint()); | 543 fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", p->topallocapoint()); |
440 new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb()); | 544 new llvm::StoreInst(tmp, fdecl->llvmThisVar, p->scopebb()); |
545 e->mem = fdecl->llvmThisVar; | |
441 } | 546 } |
442 // regular class ref -> class ref assignment | 547 // regular class ref -> class ref assignment |
443 else { | 548 else { |
444 new llvm::StoreInst(tmp, l->mem, p->scopebb()); | 549 new llvm::StoreInst(tmp, l->mem, p->scopebb()); |
550 e->mem = l->mem; | |
445 } | 551 } |
446 } | 552 } |
447 else | 553 else |
448 assert(0); | 554 assert(0); |
449 } | 555 } |
452 if (e2ty == Tdelegate) { | 558 if (e2ty == Tdelegate) { |
453 if (r->type == elem::NUL) { | 559 if (r->type == elem::NUL) { |
454 llvm::Constant* c = llvm::cast<llvm::Constant>(r->val); | 560 llvm::Constant* c = llvm::cast<llvm::Constant>(r->val); |
455 if (c->isNullValue()) { | 561 if (c->isNullValue()) { |
456 LLVM_DtoNullDelegate(l->mem); | 562 LLVM_DtoNullDelegate(l->mem); |
563 e->mem = l->mem; | |
457 } | 564 } |
458 else | 565 else |
459 assert(0); | 566 assert(0); |
460 } | 567 } |
461 else if (r->inplace) { | 568 else if (r->inplace) { |
462 // do nothing | 569 // do nothing |
463 e->inplace = true; | 570 e->inplace = true; |
571 e->mem = l->mem; | |
464 } | 572 } |
465 else | 573 else |
466 assert(0); | 574 assert(0); |
467 } | 575 } |
468 else | 576 else |
470 } | 578 } |
471 // !struct && !array && !pointer && !class | 579 // !struct && !array && !pointer && !class |
472 else { | 580 else { |
473 Logger::cout() << *l->mem << '\n'; | 581 Logger::cout() << *l->mem << '\n'; |
474 new llvm::StoreInst(r->getValue(),l->mem,p->scopebb()); | 582 new llvm::StoreInst(r->getValue(),l->mem,p->scopebb()); |
583 e->mem = l->mem; | |
475 } | 584 } |
476 | 585 |
477 delete r; | 586 delete r; |
478 delete l; | 587 delete l; |
588 | |
479 return e; | 589 return e; |
480 } | 590 } |
481 | 591 |
482 ////////////////////////////////////////////////////////////////////////////////////////// | 592 ////////////////////////////////////////////////////////////////////////////////////////// |
483 | 593 |
487 LOG_SCOPE; | 597 LOG_SCOPE; |
488 elem* e = new elem; | 598 elem* e = new elem; |
489 elem* l = e1->toElem(p); | 599 elem* l = e1->toElem(p); |
490 elem* r = e2->toElem(p); | 600 elem* r = e2->toElem(p); |
491 | 601 |
492 if (e1->type != e2->type) { | 602 Type* t = LLVM_DtoDType(type); |
493 if (e1->type->ty == Tpointer && e1->type->next->ty == Tstruct) { | 603 Type* e1type = LLVM_DtoDType(e1->type); |
604 Type* e2type = LLVM_DtoDType(e2->type); | |
605 | |
606 if (e1type != e2type) { | |
607 if (e1type->ty == Tpointer && e1type->next->ty == Tstruct) { | |
494 //assert(l->field); | 608 //assert(l->field); |
495 assert(r->type == elem::CONST); | 609 assert(r->type == elem::CONST); |
496 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->val); | 610 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->val); |
497 | 611 |
498 TypeStruct* ts = (TypeStruct*)e1->type->next; | 612 TypeStruct* ts = (TypeStruct*)e1type->next; |
499 std::vector<unsigned> offsets(1,0); | 613 std::vector<unsigned> offsets(1,0); |
500 ts->sym->offsetToIndex(type->next, cofs->getZExtValue(), offsets); | 614 ts->sym->offsetToIndex(t->next, cofs->getZExtValue(), offsets); |
501 e->mem = LLVM_DtoGEP(l->getValue(), offsets, "tmp", p->scopebb()); | 615 e->mem = LLVM_DtoGEP(l->getValue(), offsets, "tmp", p->scopebb()); |
502 e->type = elem::VAR; | 616 e->type = elem::VAR; |
503 e->field = true; | 617 e->field = true; |
504 } | 618 } |
505 else if (e1->type->ty == Tpointer) { | 619 else if (e1->type->ty == Tpointer) { |
527 LOG_SCOPE; | 641 LOG_SCOPE; |
528 | 642 |
529 elem* l = e1->toElem(p); | 643 elem* l = e1->toElem(p); |
530 elem* r = e2->toElem(p); | 644 elem* r = e2->toElem(p); |
531 | 645 |
646 Type* e1type = LLVM_DtoDType(e1->type); | |
647 | |
532 elem* e = new elem; | 648 elem* e = new elem; |
533 llvm::Value* val = 0; | 649 llvm::Value* val = 0; |
534 if (e1->type->ty == Tpointer) { | 650 if (e1type->ty == Tpointer) { |
535 val = e->mem = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 651 val = e->mem = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
536 } | 652 } |
537 else { | 653 else { |
538 val = e->val = llvm::BinaryOperator::createAdd(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 654 val = e->val = llvm::BinaryOperator::createAdd(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
539 } | 655 } |
596 LOG_SCOPE; | 712 LOG_SCOPE; |
597 | 713 |
598 elem* l = e1->toElem(p); | 714 elem* l = e1->toElem(p); |
599 elem* r = e2->toElem(p); | 715 elem* r = e2->toElem(p); |
600 | 716 |
717 Type* e1type = LLVM_DtoDType(e1->type); | |
718 | |
601 llvm::Value* tmp = 0; | 719 llvm::Value* tmp = 0; |
602 if (e1->type->ty == Tpointer) { | 720 if (e1type->ty == Tpointer) { |
603 tmp = r->getValue(); | 721 tmp = r->getValue(); |
604 llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false); | 722 llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false); |
605 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); | 723 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); |
606 tmp = new llvm::GetElementPtrInst(l->getValue(),tmp,"tmp",p->scopebb()); | 724 tmp = new llvm::GetElementPtrInst(l->getValue(),tmp,"tmp",p->scopebb()); |
607 } | 725 } |
688 LOG_SCOPE; | 806 LOG_SCOPE; |
689 elem* e = new elem; | 807 elem* e = new elem; |
690 elem* l = e1->toElem(p); | 808 elem* l = e1->toElem(p); |
691 elem* r = e2->toElem(p); | 809 elem* r = e2->toElem(p); |
692 | 810 |
693 if (type->isunsigned()) | 811 Type* t = LLVM_DtoDType(type); |
812 | |
813 if (t->isunsigned()) | |
694 e->val = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 814 e->val = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
695 else if (type->isintegral()) | 815 else if (t->isintegral()) |
696 e->val = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 816 e->val = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
697 else if (type->isfloating()) | 817 else if (t->isfloating()) |
698 e->val = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 818 e->val = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
699 else | 819 else |
700 assert(0); | 820 assert(0); |
701 e->type = elem::VAL; | 821 e->type = elem::VAL; |
702 delete l; | 822 delete l; |
712 LOG_SCOPE; | 832 LOG_SCOPE; |
713 | 833 |
714 elem* l = e1->toElem(p); | 834 elem* l = e1->toElem(p); |
715 elem* r = e2->toElem(p); | 835 elem* r = e2->toElem(p); |
716 | 836 |
837 Type* t = LLVM_DtoDType(type); | |
838 | |
717 llvm::Value* tmp; | 839 llvm::Value* tmp; |
718 if (type->isunsigned()) | 840 if (t->isunsigned()) |
719 tmp = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 841 tmp = llvm::BinaryOperator::createUDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
720 else if (type->isintegral()) | 842 else if (t->isintegral()) |
721 tmp = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 843 tmp = llvm::BinaryOperator::createSDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
722 else if (type->isfloating()) | 844 else if (t->isfloating()) |
723 tmp = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 845 tmp = llvm::BinaryOperator::createFDiv(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
724 else | 846 else |
725 assert(0); | 847 assert(0); |
726 | 848 |
727 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | 849 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; |
751 LOG_SCOPE; | 873 LOG_SCOPE; |
752 elem* e = new elem; | 874 elem* e = new elem; |
753 elem* l = e1->toElem(p); | 875 elem* l = e1->toElem(p); |
754 elem* r = e2->toElem(p); | 876 elem* r = e2->toElem(p); |
755 | 877 |
756 if (type->isunsigned()) | 878 Type* t = LLVM_DtoDType(type); |
879 | |
880 if (t->isunsigned()) | |
757 e->val = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 881 e->val = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
758 else if (type->isintegral()) | 882 else if (t->isintegral()) |
759 e->val = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 883 e->val = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
760 else if (type->isfloating()) | 884 else if (t->isfloating()) |
761 e->val = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 885 e->val = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
762 else | 886 else |
763 assert(0); | 887 assert(0); |
764 e->type = elem::VAL; | 888 e->type = elem::VAL; |
765 delete l; | 889 delete l; |
775 LOG_SCOPE; | 899 LOG_SCOPE; |
776 | 900 |
777 elem* l = e1->toElem(p); | 901 elem* l = e1->toElem(p); |
778 elem* r = e2->toElem(p); | 902 elem* r = e2->toElem(p); |
779 | 903 |
904 Type* t = LLVM_DtoDType(type); | |
905 | |
780 llvm::Value* tmp; | 906 llvm::Value* tmp; |
781 if (type->isunsigned()) | 907 if (t->isunsigned()) |
782 tmp = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 908 tmp = llvm::BinaryOperator::createURem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
783 else if (type->isintegral()) | 909 else if (t->isintegral()) |
784 tmp = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 910 tmp = llvm::BinaryOperator::createSRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
785 else if (type->isfloating()) | 911 else if (t->isfloating()) |
786 tmp = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 912 tmp = llvm::BinaryOperator::createFRem(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
787 else | 913 else |
788 assert(0); | 914 assert(0); |
789 | 915 |
790 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; | 916 /*llvm::Value* storeVal = l->storeVal ? l->storeVal : l->val; |
823 // hidden struct return parameter handling | 949 // hidden struct return parameter handling |
824 bool retinptr = false; | 950 bool retinptr = false; |
825 | 951 |
826 TypeFunction* tf = 0; | 952 TypeFunction* tf = 0; |
827 | 953 |
954 Type* e1type = LLVM_DtoDType(e1->type); | |
955 | |
828 // regular functions | 956 // regular functions |
829 if (e1->type->ty == Tfunction) { | 957 if (e1type->ty == Tfunction) { |
830 tf = (TypeFunction*)e1->type; | 958 tf = (TypeFunction*)e1type; |
831 if (tf->llvmRetInPtr) { | 959 if (tf->llvmRetInPtr) { |
832 retinptr = true; | 960 retinptr = true; |
833 } | 961 } |
834 dlink = tf->linkage; | 962 dlink = tf->linkage; |
835 } | 963 } |
836 | 964 |
837 // delegates | 965 // delegates |
838 else if (e1->type->ty == Tdelegate) { | 966 else if (e1type->ty == Tdelegate) { |
839 Logger::println("delegateTy = %s\n", e1->type->toChars()); | 967 Logger::println("delegateTy = %s\n", e1type->toChars()); |
840 assert(e1->type->next->ty == Tfunction); | 968 assert(e1type->next->ty == Tfunction); |
841 tf = (TypeFunction*)e1->type->next; | 969 tf = (TypeFunction*)e1type->next; |
842 if (tf->llvmRetInPtr) { | 970 if (tf->llvmRetInPtr) { |
843 retinptr = true; | 971 retinptr = true; |
844 } | 972 } |
845 dlink = tf->linkage; | 973 dlink = tf->linkage; |
846 delegateCall = true; | 974 delegateCall = true; |
897 | 1025 |
898 // argument handling | 1026 // argument handling |
899 llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); | 1027 llvm::FunctionType::param_iterator argiter = llfnty->param_begin(); |
900 int j = 0; | 1028 int j = 0; |
901 | 1029 |
902 // hidden struct return parameter | 1030 // hidden struct return arguments |
903 if (retinptr) { | 1031 if (retinptr) { |
904 if (!p->lvals.empty()) { | 1032 if (!p->lvals.empty()) { |
905 assert(llvm::isa<llvm::StructType>(p->toplval()->getType()->getContainedType(0))); | 1033 assert(llvm::isa<llvm::StructType>(p->toplval()->getType()->getContainedType(0))); |
906 llargs[j] = p->toplval(); | 1034 llargs[j] = p->toplval(); |
907 TY Dty = tf->next->ty; | 1035 if (LLVM_DtoIsPassedByRef(tf->next)) { |
908 if (Dty == Tstruct || Dty == Tdelegate || Dty == Tarray) { | |
909 e->inplace = true; | 1036 e->inplace = true; |
910 } | 1037 } |
911 else | 1038 else |
912 assert(0); | 1039 assert(0); |
913 } | 1040 } |
920 } | 1047 } |
921 else { | 1048 else { |
922 e->type = elem::VAL; | 1049 e->type = elem::VAL; |
923 } | 1050 } |
924 | 1051 |
925 // this parameter | 1052 // this arguments |
926 if (fn->arg) { | 1053 if (fn->arg) { |
927 Logger::println("This Call"); | 1054 Logger::println("This Call"); |
928 if (fn->arg->getType() != argiter->get()) { | 1055 if (fn->arg->getType() != argiter->get()) { |
929 //Logger::cout() << *fn->thisparam << '|' << *argiter->get() << '\n'; | 1056 //Logger::cout() << *fn->thisparam << '|' << *argiter->get() << '\n'; |
930 llargs[j] = new llvm::BitCastInst(fn->arg, argiter->get(), "tmp", p->scopebb()); | 1057 llargs[j] = new llvm::BitCastInst(fn->arg, argiter->get(), "tmp", p->scopebb()); |
933 llargs[j] = fn->arg; | 1060 llargs[j] = fn->arg; |
934 } | 1061 } |
935 ++j; | 1062 ++j; |
936 ++argiter; | 1063 ++argiter; |
937 } | 1064 } |
938 // delegate context parameter | 1065 // delegate context arguments |
939 else if (delegateCall) { | 1066 else if (delegateCall) { |
940 Logger::println("Delegate Call"); | 1067 Logger::println("Delegate Call"); |
941 llvm::Value* contextptr = LLVM_DtoGEP(fn->mem,zero,zero,"tmp",p->scopebb()); | 1068 llvm::Value* contextptr = LLVM_DtoGEP(fn->mem,zero,zero,"tmp",p->scopebb()); |
942 llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); | 1069 llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); |
943 ++j; | 1070 ++j; |
944 ++argiter; | 1071 ++argiter; |
945 } | 1072 } |
946 | 1073 |
947 // regular parameters | 1074 // regular arguments |
948 for (int i=0; i<arguments->dim; i++,j++) | 1075 for (int i=0; i<arguments->dim; i++,j++) |
949 { | 1076 { |
950 Expression* argexp = (Expression*)arguments->data[i]; | |
951 elem* arg = argexp->toElem(p); | |
952 if (arg->inplace) { | |
953 assert(arg->mem); | |
954 llargs[j] = arg->mem; | |
955 continue; | |
956 } | |
957 | |
958 Argument* fnarg = Argument::getNth(tf->parameters, i); | 1077 Argument* fnarg = Argument::getNth(tf->parameters, i); |
959 | 1078 llargs[j] = LLVM_DtoArgument(llfnty->getParamType(j), fnarg, (Expression*)arguments->data[i]); |
960 TY argty = argexp->type->ty; | |
961 if (argty == Tstruct || argty == Tdelegate || argty == Tarray) { | |
962 if (!fnarg || !fnarg->llvmCopy) { | |
963 llargs[j] = arg->getValue(); | |
964 assert(llargs[j] != 0); | |
965 } | |
966 else { | |
967 llvm::Value* allocaInst = 0; | |
968 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | |
969 const llvm::PointerType* pty = llvm::cast<llvm::PointerType>(arg->mem->getType()); | |
970 if (argty == Tstruct) { | |
971 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", p->topallocapoint()); | |
972 TypeStruct* ts = (TypeStruct*)argexp->type; | |
973 LLVM_DtoStructCopy(ts,allocaInst,arg->mem); | |
974 } | |
975 else if (argty == Tdelegate) { | |
976 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", p->topallocapoint()); | |
977 LLVM_DtoDelegateCopy(allocaInst,arg->mem); | |
978 } | |
979 else if (argty == Tarray) { | |
980 if (arg->type == elem::SLICE) { | |
981 allocaInst = new llvm::AllocaInst(LLVM_DtoType(argexp->type), "tmpparam", p->topallocapoint()); | |
982 LLVM_DtoSetArray(allocaInst, arg->arg, arg->mem); | |
983 } | |
984 else { | |
985 allocaInst = new llvm::AllocaInst(pty->getElementType(), "tmpparam", p->topallocapoint()); | |
986 LLVM_DtoArrayAssign(allocaInst,arg->mem); | |
987 } | |
988 } | |
989 else | |
990 assert(0); | |
991 | |
992 llargs[j] = allocaInst; | |
993 assert(llargs[j] != 0); | |
994 } | |
995 } | |
996 else if (!fnarg || fnarg->llvmCopy) { | |
997 Logger::println("regular arg"); | |
998 assert(arg->type != elem::SLICE); | |
999 llargs[j] = arg->arg ? arg->arg : arg->getValue(); | |
1000 assert(llargs[j] != 0); | |
1001 } | |
1002 else { | |
1003 Logger::println("as ptr arg"); | |
1004 llargs[j] = arg->mem ? arg->mem : arg->val; | |
1005 if (llargs[j]->getType() != llfnty->getParamType(j)) | |
1006 { | |
1007 assert(llargs[j]->getType() == llfnty->getParamType(j)->getContainedType(0)); | |
1008 LLVM_DtoGiveArgumentStorage(arg); | |
1009 new llvm::StoreInst(llargs[j], arg->mem, p->scopebb()); | |
1010 llargs[j] = arg->mem; | |
1011 } | |
1012 assert(llargs[j] != 0); | |
1013 } | |
1014 | |
1015 delete arg; | |
1016 } | 1079 } |
1017 | 1080 |
1018 // void returns cannot not be named | 1081 // void returns cannot not be named |
1019 const char* varname = ""; | 1082 const char* varname = ""; |
1020 if (llfnty->getReturnType() != llvm::Type::VoidTy) | 1083 if (llfnty->getReturnType() != llvm::Type::VoidTy) |
1051 { | 1114 { |
1052 Logger::print("CastExp::toElem: %s\n", toChars()); | 1115 Logger::print("CastExp::toElem: %s\n", toChars()); |
1053 LOG_SCOPE; | 1116 LOG_SCOPE; |
1054 elem* e = new elem; | 1117 elem* e = new elem; |
1055 elem* u = e1->toElem(p); | 1118 elem* u = e1->toElem(p); |
1056 const llvm::Type* totype = LLVM_DtoType(to); | 1119 const llvm::Type* tolltype = LLVM_DtoType(to); |
1057 Type* from = e1->type; | 1120 Type* fromtype = LLVM_DtoDType(e1->type); |
1058 int lsz = from->size(); | 1121 Type* totype = LLVM_DtoDType(to); |
1059 int rsz = to->size(); | 1122 int lsz = fromtype->size(); |
1123 int rsz = totype->size(); | |
1060 | 1124 |
1061 // this makes sure the strange lvalue casts don't screw things up | 1125 // this makes sure the strange lvalue casts don't screw things up |
1062 e->mem = u->mem; | 1126 e->mem = u->mem; |
1063 | 1127 |
1064 if (from->isintegral()) { | 1128 if (fromtype->isintegral()) { |
1065 if (to->isintegral()) { | 1129 if (totype->isintegral()) { |
1066 if (lsz < rsz) { | 1130 if (lsz < rsz) { |
1067 Logger::cout() << *totype << '\n'; | 1131 Logger::cout() << *tolltype << '\n'; |
1068 if (from->isunsigned() || from->ty == Tbool) { | 1132 if (fromtype->isunsigned() || fromtype->ty == Tbool) { |
1069 e->val = new llvm::ZExtInst(u->getValue(), totype, "tmp", p->scopebb()); | 1133 e->val = new llvm::ZExtInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1070 } else { | 1134 } else { |
1071 e->val = new llvm::SExtInst(u->getValue(), totype, "tmp", p->scopebb()); | 1135 e->val = new llvm::SExtInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1072 } | 1136 } |
1073 } | 1137 } |
1074 else if (lsz > rsz) { | 1138 else if (lsz > rsz) { |
1075 e->val = new llvm::TruncInst(u->getValue(), totype, "tmp", p->scopebb()); | 1139 e->val = new llvm::TruncInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1076 } | 1140 } |
1077 else { | 1141 else { |
1078 e->val = new llvm::BitCastInst(u->getValue(), totype, "tmp", p->scopebb()); | 1142 e->val = new llvm::BitCastInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1079 } | 1143 } |
1080 } | 1144 } |
1081 else if (to->isfloating()) { | 1145 else if (totype->isfloating()) { |
1082 if (from->isunsigned()) { | 1146 if (fromtype->isunsigned()) { |
1083 e->val = new llvm::UIToFPInst(u->getValue(), totype, "tmp", p->scopebb()); | 1147 e->val = new llvm::UIToFPInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1084 } | 1148 } |
1085 else { | 1149 else { |
1086 e->val = new llvm::SIToFPInst(u->getValue(), totype, "tmp", p->scopebb()); | 1150 e->val = new llvm::SIToFPInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1087 } | 1151 } |
1088 } | 1152 } |
1089 else { | 1153 else { |
1090 assert(0); | 1154 assert(0); |
1091 } | 1155 } |
1092 //e->storeVal = u->storeVal ? u->storeVal : u->val; | 1156 //e->storeVal = u->storeVal ? u->storeVal : u->val; |
1093 e->type = elem::VAL; | 1157 e->type = elem::VAL; |
1094 } | 1158 } |
1095 else if (from->isfloating()) { | 1159 else if (fromtype->isfloating()) { |
1096 if (to->isfloating()) { | 1160 if (totype->isfloating()) { |
1097 if ((from->ty == Tfloat80 || from->ty == Tfloat64) && (to->ty == Tfloat80 || to->ty == Tfloat64)) { | 1161 if ((fromtype->ty == Tfloat80 || fromtype->ty == Tfloat64) && (totype->ty == Tfloat80 || totype->ty == Tfloat64)) { |
1098 e->val = u->getValue(); | 1162 e->val = u->getValue(); |
1099 } | 1163 } |
1100 else if (lsz < rsz) { | 1164 else if (lsz < rsz) { |
1101 e->val = new llvm::FPExtInst(u->getValue(), totype, "tmp", p->scopebb()); | 1165 e->val = new llvm::FPExtInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1102 } | 1166 } |
1103 else if (lsz > rsz) { | 1167 else if (lsz > rsz) { |
1104 e->val = new llvm::FPTruncInst(u->getValue(), totype, "tmp", p->scopebb()); | 1168 e->val = new llvm::FPTruncInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1105 } | 1169 } |
1106 else { | 1170 else { |
1107 assert(0); | 1171 assert(0); |
1108 } | 1172 } |
1109 } | 1173 } |
1110 else if (to->isintegral()) { | 1174 else if (totype->isintegral()) { |
1111 if (to->isunsigned()) { | 1175 if (totype->isunsigned()) { |
1112 e->val = new llvm::FPToUIInst(u->getValue(), totype, "tmp", p->scopebb()); | 1176 e->val = new llvm::FPToUIInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1113 } | 1177 } |
1114 else { | 1178 else { |
1115 e->val = new llvm::FPToSIInst(u->getValue(), totype, "tmp", p->scopebb()); | 1179 e->val = new llvm::FPToSIInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1116 } | 1180 } |
1117 } | 1181 } |
1118 else { | 1182 else { |
1119 assert(0); | 1183 assert(0); |
1120 } | 1184 } |
1121 e->type = elem::VAL; | 1185 e->type = elem::VAL; |
1122 } | 1186 } |
1123 else if (from->ty == Tclass) { | 1187 else if (fromtype->ty == Tclass) { |
1124 //assert(to->ty == Tclass); | 1188 //assert(to->ty == Tclass); |
1125 e->val = new llvm::BitCastInst(u->getValue(), totype, "tmp", p->scopebb()); | 1189 e->val = new llvm::BitCastInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1126 e->type = elem::VAL; | 1190 e->type = elem::VAL; |
1127 } | 1191 } |
1128 else if (from->ty == Tarray || from->ty == Tsarray) { | 1192 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { |
1129 Logger::cout() << "from array or sarray" << '\n'; | 1193 Logger::cout() << "from array or sarray" << '\n'; |
1130 if (to->ty == Tpointer) { | 1194 if (totype->ty == Tpointer) { |
1131 Logger::cout() << "to pointer" << '\n'; | 1195 Logger::cout() << "to pointer" << '\n'; |
1132 assert(from->next == to->next); | 1196 assert(fromtype->next == totype->next); |
1133 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1197 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1134 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1198 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1135 llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb()); | 1199 llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb()); |
1136 e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); | 1200 e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); |
1137 e->type = elem::VAL; | 1201 e->type = elem::VAL; |
1138 } | 1202 } |
1139 else if (to->ty == Tarray) { | 1203 else if (totype->ty == Tarray) { |
1140 Logger::cout() << "to array" << '\n'; | 1204 Logger::cout() << "to array" << '\n'; |
1141 assert(from->next->size() == to->next->size()); | 1205 assert(fromtype->next->size() == totype->next->size()); |
1142 const llvm::Type* ptrty = LLVM_DtoType(to->next); | 1206 const llvm::Type* ptrty = LLVM_DtoType(totype->next); |
1143 if (ptrty == llvm::Type::VoidTy) | 1207 if (ptrty == llvm::Type::VoidTy) |
1144 ptrty = llvm::Type::Int8Ty; | 1208 ptrty = llvm::Type::Int8Ty; |
1145 ptrty = llvm::PointerType::get(ptrty); | 1209 ptrty = llvm::PointerType::get(ptrty); |
1146 | 1210 |
1147 if (u->type == elem::SLICE) { | 1211 if (u->type == elem::SLICE) { |
1148 e->mem = new llvm::BitCastInst(u->mem, ptrty, "tmp", p->scopebb()); | 1212 e->mem = new llvm::BitCastInst(u->mem, ptrty, "tmp", p->scopebb()); |
1149 e->arg = u->arg; | 1213 e->arg = u->arg; |
1150 } | 1214 } |
1151 else { | 1215 else { |
1152 llvm::Value* uval = u->getValue(); | 1216 llvm::Value* uval = u->getValue(); |
1153 if (from->ty == Tsarray) { | 1217 if (fromtype->ty == Tsarray) { |
1154 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; | 1218 Logger::cout() << "uvalTy = " << *uval->getType() << '\n'; |
1155 assert(llvm::isa<llvm::PointerType>(uval->getType())); | 1219 assert(llvm::isa<llvm::PointerType>(uval->getType())); |
1156 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(uval->getType()->getContainedType(0)); | 1220 const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(uval->getType()->getContainedType(0)); |
1157 e->arg = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false); | 1221 e->arg = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false); |
1158 e->mem = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb()); | 1222 e->mem = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb()); |
1169 e->mem = new llvm::BitCastInst(e->mem, ptrty, "tmp", p->scopebb()); | 1233 e->mem = new llvm::BitCastInst(e->mem, ptrty, "tmp", p->scopebb()); |
1170 } | 1234 } |
1171 } | 1235 } |
1172 e->type = elem::SLICE; | 1236 e->type = elem::SLICE; |
1173 } | 1237 } |
1174 else if (to->ty == Tsarray) { | 1238 else if (totype->ty == Tsarray) { |
1175 Logger::cout() << "to sarray" << '\n'; | 1239 Logger::cout() << "to sarray" << '\n'; |
1176 assert(0); | 1240 assert(0); |
1177 } | 1241 } |
1178 else { | 1242 else { |
1179 assert(0); | 1243 assert(0); |
1180 } | 1244 } |
1181 } | 1245 } |
1182 else if (from->ty == Tpointer) { | 1246 else if (fromtype->ty == Tpointer) { |
1183 if (to->ty == Tpointer || to->ty == Tclass) { | 1247 if (totype->ty == Tpointer || totype->ty == Tclass) { |
1184 llvm::Value* src = u->getValue(); | 1248 llvm::Value* src = u->getValue(); |
1185 //Logger::cout() << *src << '|' << *totype << '\n'; | 1249 //Logger::cout() << *src << '|' << *totype << '\n'; |
1186 e->val = new llvm::BitCastInst(src, totype, "tmp", p->scopebb()); | 1250 e->val = new llvm::BitCastInst(src, tolltype, "tmp", p->scopebb()); |
1187 } | 1251 } |
1188 else if (to->isintegral()) { | 1252 else if (totype->isintegral()) { |
1189 e->val = new llvm::PtrToIntInst(u->getValue(), totype, "tmp", p->scopebb()); | 1253 e->val = new llvm::PtrToIntInst(u->getValue(), tolltype, "tmp", p->scopebb()); |
1190 } | 1254 } |
1191 else | 1255 else |
1192 assert(0); | 1256 assert(0); |
1193 e->type = elem::VAL; | 1257 e->type = elem::VAL; |
1194 } | 1258 } |
1208 elem* e = 0; | 1272 elem* e = 0; |
1209 if (VarDeclaration* vd = var->isVarDeclaration()) | 1273 if (VarDeclaration* vd = var->isVarDeclaration()) |
1210 { | 1274 { |
1211 Logger::println("VarDeclaration"); | 1275 Logger::println("VarDeclaration"); |
1212 assert(vd->llvmValue); | 1276 assert(vd->llvmValue); |
1213 if (vd->type->ty == Tstruct && !(type->ty == Tpointer && type->next == vd->type)) { | 1277 Type* t = LLVM_DtoDType(type); |
1214 TypeStruct* vdt = (TypeStruct*)vd->type; | 1278 Type* vdtype = LLVM_DtoDType(vd->type); |
1279 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { | |
1280 TypeStruct* vdt = (TypeStruct*)vdtype; | |
1215 e = new elem; | 1281 e = new elem; |
1216 std::vector<unsigned> dst(1,0); | 1282 std::vector<unsigned> dst(1,0); |
1217 vdt->sym->offsetToIndex(type->next, offset, dst); | 1283 vdt->sym->offsetToIndex(t->next, offset, dst); |
1218 llvm::Value* ptr = vd->llvmValue; | 1284 llvm::Value* ptr = vd->llvmValue; |
1219 assert(ptr); | 1285 assert(ptr); |
1220 e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); | 1286 e->mem = LLVM_DtoGEP(ptr,dst,"tmp",p->scopebb()); |
1221 e->type = elem::VAL; | 1287 e->type = elem::VAL; |
1222 e->field = true; | 1288 e->field = true; |
1223 } | 1289 } |
1224 else if (vd->type->ty == Tsarray) { | 1290 else if (vdtype->ty == Tsarray) { |
1225 /*e = new elem; | 1291 /*e = new elem; |
1226 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1292 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1227 e->val = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());*/ | 1293 e->val = new llvm::GetElementPtrInst(vd->llvmValue,idx0,idx0,"tmp",p->scopebb());*/ |
1228 e = new elem; | 1294 e = new elem; |
1229 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1295 llvm::Value* idx0 = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1292 LOG_SCOPE; | 1358 LOG_SCOPE; |
1293 elem* e = new elem; | 1359 elem* e = new elem; |
1294 | 1360 |
1295 elem* l = e1->toElem(p); | 1361 elem* l = e1->toElem(p); |
1296 | 1362 |
1297 Logger::print("e1->type=%s\n", e1->type->toChars()); | 1363 Type* t = LLVM_DtoDType(type); |
1364 Type* e1type = LLVM_DtoDType(e1->type); | |
1365 | |
1366 Logger::print("e1->type=%s\n", e1type->toChars()); | |
1298 | 1367 |
1299 if (VarDeclaration* vd = var->isVarDeclaration()) { | 1368 if (VarDeclaration* vd = var->isVarDeclaration()) { |
1300 std::vector<unsigned> vdoffsets(1,0); | 1369 std::vector<unsigned> vdoffsets(1,0); |
1301 llvm::Value* src = 0; | 1370 llvm::Value* src = 0; |
1302 if (e1->type->ty == Tpointer) { | 1371 if (e1type->ty == Tpointer) { |
1303 assert(e1->type->next->ty == Tstruct); | 1372 assert(e1type->next->ty == Tstruct); |
1304 TypeStruct* ts = (TypeStruct*)e1->type->next; | 1373 TypeStruct* ts = (TypeStruct*)e1type->next; |
1305 ts->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); | 1374 ts->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); |
1306 Logger::println("Struct member offset:%d", vd->offset); | 1375 Logger::println("Struct member offset:%d", vd->offset); |
1307 src = l->val ? l->val : l->mem; | 1376 src = l->val ? l->val : l->mem; |
1308 } | 1377 } |
1309 else if (e1->type->ty == Tclass) { | 1378 else if (e1->type->ty == Tclass) { |
1310 TypeClass* tc = (TypeClass*)e1->type; | 1379 TypeClass* tc = (TypeClass*)e1type; |
1311 Logger::println("Class member offset: %d", vd->offset); | 1380 Logger::println("Class member offset: %d", vd->offset); |
1312 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); | 1381 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); |
1313 src = l->getValue(); | 1382 src = l->getValue(); |
1314 } | 1383 } |
1315 assert(vdoffsets.size() != 1); | 1384 assert(vdoffsets.size() != 1); |
1316 assert(src != 0); | 1385 assert(src != 0); |
1386 Logger::cout() << "src: " << *src << '\n'; | |
1317 llvm::Value* arrptr = LLVM_DtoGEP(src,vdoffsets,"tmp",p->scopebb()); | 1387 llvm::Value* arrptr = LLVM_DtoGEP(src,vdoffsets,"tmp",p->scopebb()); |
1318 e->mem = arrptr; | 1388 e->mem = arrptr; |
1319 Logger::cout() << "mem: " << *e->mem << '\n'; | 1389 Logger::cout() << "mem: " << *e->mem << '\n'; |
1320 e->type = elem::VAR; | 1390 e->type = elem::VAR; |
1321 } | 1391 } |
1330 e->arg = l->getValue(); | 1400 e->arg = l->getValue(); |
1331 | 1401 |
1332 // virtual call | 1402 // virtual call |
1333 if (fdecl->isVirtual()) { | 1403 if (fdecl->isVirtual()) { |
1334 assert(fdecl->vtblIndex > 0); | 1404 assert(fdecl->vtblIndex > 0); |
1335 assert(e1->type->ty == Tclass); | 1405 assert(e1type->ty == Tclass); |
1336 | 1406 |
1337 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1407 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1338 llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); | 1408 llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); |
1339 funcval = LLVM_DtoGEP(e->arg, zero, zero, "tmp", p->scopebb()); | 1409 funcval = LLVM_DtoGEP(e->arg, zero, zero, "tmp", p->scopebb()); |
1340 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1410 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
1363 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1433 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1364 LOG_SCOPE; | 1434 LOG_SCOPE; |
1365 elem* e = new elem; | 1435 elem* e = new elem; |
1366 | 1436 |
1367 if (VarDeclaration* vd = var->isVarDeclaration()) { | 1437 if (VarDeclaration* vd = var->isVarDeclaration()) { |
1368 /*assert(vd->llvmValue == 0); | 1438 llvm::Value* v = p->func().decl->llvmThisVar; |
1369 | |
1370 llvm::Function* fn = p->topfunc(); | |
1371 assert(fn); | |
1372 | |
1373 TypeFunction* tf = p->topfunctype(); | |
1374 assert(tf); | |
1375 | |
1376 llvm::Value* v = 0; | |
1377 if (tf->llvmRetInPtr) | |
1378 v = ++fn->arg_begin(); | |
1379 else | |
1380 v = fn->arg_begin(); | |
1381 assert(v);*/ | |
1382 | |
1383 llvm::Value* v = p->funcdecls.back()->llvmThisVar; | |
1384 if (llvm::isa<llvm::AllocaInst>(v)) | 1439 if (llvm::isa<llvm::AllocaInst>(v)) |
1385 v = new llvm::LoadInst(v, "tmp", p->scopebb()); | 1440 v = new llvm::LoadInst(v, "tmp", p->scopebb()); |
1386 e->mem = v; | 1441 e->mem = v; |
1387 e->type = elem::VAL; | 1442 e->type = elem::VAL; |
1388 e->isthis = true; | 1443 e->isthis = true; |
1438 llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); | 1493 llvm::Value* offset = llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false); |
1439 llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb()); | 1494 llvm::Value* arrptr = LLVM_DtoGEP(sptr,zero,offset,"tmp",p->scopebb()); |
1440 | 1495 |
1441 Expression* vx = (Expression*)elements->data[i]; | 1496 Expression* vx = (Expression*)elements->data[i]; |
1442 if (vx != 0) { | 1497 if (vx != 0) { |
1498 p->lvals.push_back(arrptr); | |
1443 elem* ve = vx->toElem(p); | 1499 elem* ve = vx->toElem(p); |
1444 llvm::Value* val = ve->getValue(); | 1500 p->lvals.pop_back(); |
1445 Logger::cout() << *val << " | " << *arrptr << '\n'; | 1501 |
1446 if (vx->type->ty == Tstruct) { | 1502 if (!ve->inplace) { |
1447 TypeStruct* ts = (TypeStruct*)vx->type; | 1503 llvm::Value* val = ve->getValue(); |
1448 LLVM_DtoStructCopy(ts,arrptr,val); | 1504 Logger::cout() << *val << " | " << *arrptr << '\n'; |
1449 } | 1505 |
1450 else | 1506 Type* vxtype = LLVM_DtoDType(vx->type); |
1451 new llvm::StoreInst(val, arrptr, p->scopebb()); | 1507 if (vxtype->ty == Tstruct) { |
1508 TypeStruct* ts = (TypeStruct*)vxtype; | |
1509 LLVM_DtoStructCopy(ts,arrptr,val); | |
1510 } | |
1511 else | |
1512 new llvm::StoreInst(val, arrptr, p->scopebb()); | |
1513 } | |
1452 delete ve; | 1514 delete ve; |
1453 } | 1515 } |
1454 else { | 1516 else { |
1455 assert(0); | 1517 assert(0); |
1456 } | 1518 } |
1461 return e; | 1523 return e; |
1462 } | 1524 } |
1463 | 1525 |
1464 ////////////////////////////////////////////////////////////////////////////////////////// | 1526 ////////////////////////////////////////////////////////////////////////////////////////// |
1465 | 1527 |
1528 llvm::Constant* StructLiteralExp::toConstElem(IRState* p) | |
1529 { | |
1530 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
1531 LOG_SCOPE; | |
1532 | |
1533 unsigned n = elements->dim; | |
1534 std::vector<llvm::Constant*> vals(n, NULL); | |
1535 | |
1536 for (unsigned i=0; i<n; ++i) | |
1537 { | |
1538 Expression* vx = (Expression*)elements->data[i]; | |
1539 vals[i] = vx->toConstElem(p); | |
1540 } | |
1541 | |
1542 assert(LLVM_DtoDType(type)->ty == Tstruct); | |
1543 const llvm::Type* t = LLVM_DtoType(type); | |
1544 const llvm::StructType* st = llvm::cast<llvm::StructType>(t); | |
1545 return llvm::ConstantStruct::get(st,vals); | |
1546 } | |
1547 | |
1548 ////////////////////////////////////////////////////////////////////////////////////////// | |
1549 | |
1466 elem* IndexExp::toElem(IRState* p) | 1550 elem* IndexExp::toElem(IRState* p) |
1467 { | 1551 { |
1468 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1552 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1469 LOG_SCOPE; | 1553 LOG_SCOPE; |
1470 | 1554 |
1471 elem* e = new elem; | 1555 elem* e = new elem; |
1472 | 1556 |
1473 elem* l = e1->toElem(p); | 1557 elem* l = e1->toElem(p); |
1558 | |
1559 Type* e1type = LLVM_DtoDType(e1->type); | |
1474 | 1560 |
1475 p->arrays.push_back(l->mem); // if $ is used it must be an array so this is fine. | 1561 p->arrays.push_back(l->mem); // if $ is used it must be an array so this is fine. |
1476 elem* r = e2->toElem(p); | 1562 elem* r = e2->toElem(p); |
1477 p->arrays.pop_back(); | 1563 p->arrays.pop_back(); |
1478 | 1564 |
1479 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1565 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1480 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1566 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1481 | 1567 |
1482 llvm::Value* arrptr = 0; | 1568 llvm::Value* arrptr = 0; |
1483 if (e1->type->ty == Tpointer) { | 1569 if (e1type->ty == Tpointer) { |
1484 arrptr = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb()); | 1570 arrptr = new llvm::GetElementPtrInst(l->getValue(),r->getValue(),"tmp",p->scopebb()); |
1485 } | 1571 } |
1486 else if (e1->type->ty == Tsarray) { | 1572 else if (e1type->ty == Tsarray) { |
1487 arrptr = LLVM_DtoGEP(l->mem, zero, r->getValue(),"tmp",p->scopebb()); | 1573 arrptr = LLVM_DtoGEP(l->getValue(), zero, r->getValue(),"tmp",p->scopebb()); |
1488 } | 1574 } |
1489 else if (e1->type->ty == Tarray) { | 1575 else if (e1type->ty == Tarray) { |
1490 arrptr = LLVM_DtoGEP(l->mem,zero,one,"tmp",p->scopebb()); | 1576 arrptr = LLVM_DtoGEP(l->mem,zero,one,"tmp",p->scopebb()); |
1491 arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb()); | 1577 arrptr = new llvm::LoadInst(arrptr,"tmp",p->scopebb()); |
1492 arrptr = new llvm::GetElementPtrInst(arrptr,r->getValue(),"tmp",p->scopebb()); | 1578 arrptr = new llvm::GetElementPtrInst(arrptr,r->getValue(),"tmp",p->scopebb()); |
1493 } | 1579 } |
1494 assert(arrptr); | 1580 assert(arrptr); |
1508 { | 1594 { |
1509 Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1595 Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1510 LOG_SCOPE; | 1596 LOG_SCOPE; |
1511 | 1597 |
1512 elem* v = e1->toElem(p); | 1598 elem* v = e1->toElem(p); |
1599 Type* e1type = LLVM_DtoDType(e1->type); | |
1513 | 1600 |
1514 elem* e = new elem; | 1601 elem* e = new elem; |
1515 assert(v->mem); | 1602 assert(v->mem); |
1516 e->type = elem::SLICE; | 1603 e->type = elem::SLICE; |
1517 | 1604 |
1529 if (lo->type == elem::CONST) | 1616 if (lo->type == elem::CONST) |
1530 { | 1617 { |
1531 assert(lo->val); | 1618 assert(lo->val); |
1532 assert(llvm::isa<llvm::ConstantInt>(lo->val)); | 1619 assert(llvm::isa<llvm::ConstantInt>(lo->val)); |
1533 | 1620 |
1534 if (e1->type->ty == Tpointer) { | 1621 if (e1type->ty == Tpointer) { |
1535 e->mem = v->getValue(); | 1622 e->mem = v->getValue(); |
1536 } | 1623 } |
1537 else if (e1->type->ty == Tarray) { | 1624 else if (e1type->ty == Tarray) { |
1538 llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb()); | 1625 llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb()); |
1539 e->mem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 1626 e->mem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
1627 } | |
1628 else if (e1type->ty == Tsarray) { | |
1629 e->mem = LLVM_DtoGEP(v->mem,zero,zero,"tmp",p->scopebb()); | |
1540 } | 1630 } |
1541 else | 1631 else |
1542 assert(e->mem); | 1632 assert(e->mem); |
1543 | 1633 |
1544 llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(lo->val); | 1634 llvm::ConstantInt* c = llvm::cast<llvm::ConstantInt>(lo->val); |
1546 e->mem = new llvm::GetElementPtrInst(e->mem,lo->val,"tmp",p->scopebb()); | 1636 e->mem = new llvm::GetElementPtrInst(e->mem,lo->val,"tmp",p->scopebb()); |
1547 } | 1637 } |
1548 } | 1638 } |
1549 else | 1639 else |
1550 { | 1640 { |
1551 llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb()); | 1641 if (e1type->ty == Tarray) { |
1552 tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 1642 llvm::Value* tmp = LLVM_DtoGEP(v->mem,zero,one,"tmp",p->scopebb()); |
1553 e->mem = new llvm::GetElementPtrInst(tmp,lo->getValue(),"tmp",p->scopebb()); | 1643 tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
1644 e->mem = new llvm::GetElementPtrInst(tmp,lo->getValue(),"tmp",p->scopebb()); | |
1645 } | |
1646 else if (e1type->ty == Tsarray) { | |
1647 e->mem = LLVM_DtoGEP(v->mem,zero,lo->getValue(),"tmp",p->scopebb()); | |
1648 } | |
1649 else | |
1650 assert(0); | |
1554 } | 1651 } |
1555 | 1652 |
1556 elem* up = upr->toElem(p); | 1653 elem* up = upr->toElem(p); |
1557 p->arrays.pop_back(); | 1654 p->arrays.pop_back(); |
1558 | 1655 |
1608 elem* e = new elem; | 1705 elem* e = new elem; |
1609 | 1706 |
1610 elem* l = e1->toElem(p); | 1707 elem* l = e1->toElem(p); |
1611 elem* r = e2->toElem(p); | 1708 elem* r = e2->toElem(p); |
1612 | 1709 |
1613 assert(e1->type == e2->type); | 1710 Type* t = LLVM_DtoDType(e1->type); |
1614 | 1711 Type* e2t = LLVM_DtoDType(e2->type); |
1615 Type* t = e1->type; | 1712 assert(t == e2t); |
1616 | 1713 |
1617 if (t->isintegral()) | 1714 if (t->isintegral()) |
1618 { | 1715 { |
1619 llvm::ICmpInst::Predicate cmpop; | 1716 llvm::ICmpInst::Predicate cmpop; |
1717 bool skip = false; | |
1620 switch(op) | 1718 switch(op) |
1621 { | 1719 { |
1622 case TOKlt: | 1720 case TOKlt: |
1721 case TOKul: | |
1623 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT; | 1722 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT; |
1624 break; | 1723 break; |
1625 case TOKle: | 1724 case TOKle: |
1725 case TOKule: | |
1626 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE; | 1726 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE; |
1627 break; | 1727 break; |
1628 case TOKgt: | 1728 case TOKgt: |
1729 case TOKug: | |
1629 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT; | 1730 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT; |
1630 break; | 1731 break; |
1631 case TOKge: | 1732 case TOKge: |
1733 case TOKuge: | |
1632 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE; | 1734 cmpop = t->isunsigned() ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE; |
1633 break; | 1735 break; |
1736 case TOKue: | |
1737 cmpop = llvm::ICmpInst::ICMP_EQ; | |
1738 break; | |
1739 case TOKlg: | |
1740 cmpop = llvm::ICmpInst::ICMP_NE; | |
1741 break; | |
1742 case TOKleg: | |
1743 skip = true; | |
1744 e->val = llvm::ConstantInt::getTrue(); | |
1745 break; | |
1746 case TOKunord: | |
1747 skip = true; | |
1748 e->val = llvm::ConstantInt::getFalse(); | |
1749 break; | |
1750 | |
1634 default: | 1751 default: |
1635 assert(0); | 1752 assert(0); |
1636 } | 1753 } |
1637 e->val = new llvm::ICmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | 1754 if (!skip) |
1755 { | |
1756 e->val = new llvm::ICmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | |
1757 } | |
1638 } | 1758 } |
1639 else if (t->isfloating()) | 1759 else if (t->isfloating()) |
1640 { | 1760 { |
1641 llvm::FCmpInst::Predicate cmpop; | 1761 llvm::FCmpInst::Predicate cmpop; |
1642 switch(op) | 1762 switch(op) |
1694 elem* e = new elem; | 1814 elem* e = new elem; |
1695 | 1815 |
1696 elem* l = e1->toElem(p); | 1816 elem* l = e1->toElem(p); |
1697 elem* r = e2->toElem(p); | 1817 elem* r = e2->toElem(p); |
1698 | 1818 |
1699 assert(e1->type == e2->type); | 1819 Type* t = LLVM_DtoDType(e1->type); |
1700 | 1820 Type* e2t = LLVM_DtoDType(e2->type); |
1701 Type* t = e1->type; | 1821 assert(t == e2t); |
1702 | 1822 |
1703 if (t->isintegral() || t->ty == Tpointer) | 1823 if (t->isintegral() || t->ty == Tpointer) |
1704 { | 1824 { |
1705 llvm::ICmpInst::Predicate cmpop; | 1825 llvm::ICmpInst::Predicate cmpop; |
1706 switch(op) | 1826 switch(op) |
1730 default: | 1850 default: |
1731 assert(0); | 1851 assert(0); |
1732 } | 1852 } |
1733 e->val = new llvm::FCmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); | 1853 e->val = new llvm::FCmpInst(cmpop, l->getValue(), r->getValue(), "tmp", p->scopebb()); |
1734 } | 1854 } |
1855 else if (t->ty == Tsarray) | |
1856 { | |
1857 e->val = LLVM_DtoStaticArrayCompare(op,l->mem,r->mem); | |
1858 } | |
1735 else if (t->ty == Tarray) | 1859 else if (t->ty == Tarray) |
1736 { | 1860 { |
1737 // array comparison invokes the typeinfo runtime | 1861 assert(0 && "array comparison invokes the typeinfo runtime"); |
1738 assert(0); | |
1739 } | 1862 } |
1740 else | 1863 else |
1741 { | 1864 { |
1742 assert(0 && "Unsupported EqualExp type"); | 1865 assert(0 && "Unsupported EqualExp type"); |
1743 } | 1866 } |
1766 e->type = elem::VAL; | 1889 e->type = elem::VAL; |
1767 | 1890 |
1768 llvm::Value* val = e->val; | 1891 llvm::Value* val = e->val; |
1769 llvm::Value* post = 0; | 1892 llvm::Value* post = 0; |
1770 | 1893 |
1771 if (e1->type->isintegral()) | 1894 Type* e1type = LLVM_DtoDType(e1->type); |
1772 { | 1895 Type* e2type = LLVM_DtoDType(e2->type); |
1773 assert(e2->type->isintegral()); | 1896 |
1774 llvm::Value* one = llvm::ConstantInt::get(val->getType(), 1, !e2->type->isunsigned()); | 1897 if (e1type->isintegral()) |
1898 { | |
1899 assert(e2type->isintegral()); | |
1900 llvm::Value* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned()); | |
1775 if (op == TOKplusplus) { | 1901 if (op == TOKplusplus) { |
1776 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); | 1902 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); |
1777 } | 1903 } |
1778 else if (op == TOKminusminus) { | 1904 else if (op == TOKminusminus) { |
1779 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); | 1905 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); |
1780 } | 1906 } |
1781 } | 1907 } |
1782 else if (e1->type->ty == Tpointer) | 1908 else if (e1type->ty == Tpointer) |
1783 { | 1909 { |
1784 assert(e2->type->isintegral()); | 1910 assert(e2type->isintegral()); |
1785 llvm::Constant* minusone = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)-1,true); | 1911 llvm::Constant* minusone = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)-1,true); |
1786 llvm::Constant* plusone = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)1,false); | 1912 llvm::Constant* plusone = llvm::ConstantInt::get(LLVM_DtoSize_t(),(uint64_t)1,false); |
1787 llvm::Constant* whichone = (op == TOKplusplus) ? plusone : minusone; | 1913 llvm::Constant* whichone = (op == TOKplusplus) ? plusone : minusone; |
1788 post = new llvm::GetElementPtrInst(val, whichone, "tmp", p->scopebb()); | 1914 post = new llvm::GetElementPtrInst(val, whichone, "tmp", p->scopebb()); |
1789 } | 1915 } |
1790 else if (e1->type->isfloating()) | 1916 else if (e1type->isfloating()) |
1791 { | 1917 { |
1792 assert(e2->type->isfloating()); | 1918 assert(e2type->isfloating()); |
1793 llvm::Value* one = llvm::ConstantFP::get(val->getType(), 1.0f); | 1919 llvm::Value* one = llvm::ConstantFP::get(val->getType(), 1.0f); |
1794 if (op == TOKplusplus) { | 1920 if (op == TOKplusplus) { |
1795 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); | 1921 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); |
1796 } | 1922 } |
1797 else if (op == TOKminusminus) { | 1923 else if (op == TOKminusminus) { |
1818 LOG_SCOPE; | 1944 LOG_SCOPE; |
1819 | 1945 |
1820 assert(!thisexp); | 1946 assert(!thisexp); |
1821 assert(!newargs); | 1947 assert(!newargs); |
1822 assert(newtype); | 1948 assert(newtype); |
1823 //assert(!arguments); | |
1824 //assert(!member); | |
1825 assert(!allocator); | 1949 assert(!allocator); |
1826 | 1950 |
1827 elem* e = new elem; | 1951 elem* e = new elem; |
1828 | 1952 |
1829 const llvm::Type* t = LLVM_DtoType(newtype); | 1953 Type* ntype = LLVM_DtoDType(newtype); |
1954 | |
1955 const llvm::Type* t = LLVM_DtoType(ntype); | |
1830 | 1956 |
1831 if (onstack) { | 1957 if (onstack) { |
1832 assert(newtype->ty == Tclass); | 1958 assert(ntype->ty == Tclass); |
1833 e->mem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); | 1959 e->mem = new llvm::AllocaInst(t->getContainedType(0),"tmp",p->topallocapoint()); |
1834 } | 1960 } |
1835 else { | 1961 else { |
1836 if (newtype->ty == Tclass) { | 1962 if (ntype->ty == Tclass) { |
1837 e->mem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); | 1963 e->mem = new llvm::MallocInst(t->getContainedType(0),"tmp",p->scopebb()); |
1838 } | 1964 } |
1839 else if (newtype->ty == Tarray) { | 1965 else if (ntype->ty == Tarray) { |
1840 assert(arguments); | 1966 assert(arguments); |
1841 if (arguments->dim == 1) { | 1967 if (arguments->dim == 1) { |
1842 elem* sz = ((Expression*)arguments->data[0])->toElem(p); | 1968 elem* sz = ((Expression*)arguments->data[0])->toElem(p); |
1843 llvm::Value* dimval = sz->getValue(); | 1969 llvm::Value* dimval = sz->getValue(); |
1844 LLVM_DtoNewDynArray(p->toplval(), dimval, newtype->next); | 1970 LLVM_DtoNewDynArray(p->toplval(), dimval, ntype->next); |
1845 delete sz; | 1971 delete sz; |
1846 } | 1972 } |
1847 else { | 1973 else { |
1848 assert(0); | 1974 assert(0); |
1849 } | 1975 } |
1851 else { | 1977 else { |
1852 e->mem = new llvm::MallocInst(t,"tmp",p->scopebb()); | 1978 e->mem = new llvm::MallocInst(t,"tmp",p->scopebb()); |
1853 } | 1979 } |
1854 } | 1980 } |
1855 | 1981 |
1856 if (newtype->ty == Tclass) { | 1982 if (ntype->ty == Tclass) { |
1857 // first apply the static initializer | 1983 // first apply the static initializer |
1858 assert(e->mem); | 1984 assert(e->mem); |
1859 LLVM_DtoInitClass((TypeClass*)newtype, e->mem); | 1985 LLVM_DtoInitClass((TypeClass*)ntype, e->mem); |
1860 | 1986 |
1861 // then call constructor | 1987 // then call constructor |
1862 if (arguments) { | 1988 if (arguments) { |
1989 assert(member); | |
1990 assert(member->llvmValue); | |
1991 llvm::Function* fn = llvm::cast<llvm::Function>(member->llvmValue); | |
1992 TypeFunction* tf = (TypeFunction*)LLVM_DtoDType(member->type); | |
1993 | |
1863 std::vector<llvm::Value*> ctorargs; | 1994 std::vector<llvm::Value*> ctorargs; |
1864 ctorargs.push_back(e->mem); | 1995 ctorargs.push_back(e->mem); |
1865 for (size_t i=0; i<arguments->dim; ++i) | 1996 for (size_t i=0; i<arguments->dim; ++i) |
1866 { | 1997 { |
1867 Expression* ex = (Expression*)arguments->data[i]; | 1998 Expression* ex = (Expression*)arguments->data[i]; |
1868 Logger::println("arg=%s", ex->toChars()); | 1999 Argument* fnarg = Argument::getNth(tf->parameters, i); |
1869 elem* exe = ex->toElem(p); | 2000 llvm::Value* a = LLVM_DtoArgument(fn->getFunctionType()->getParamType(i+1), fnarg, ex); |
1870 llvm::Value* v = exe->getValue(); | 2001 ctorargs.push_back(a); |
1871 assert(v); | 2002 } |
1872 ctorargs.push_back(v); | 2003 e->mem = new llvm::CallInst(fn, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); |
1873 delete exe; | 2004 } |
1874 } | 2005 } |
1875 assert(member); | 2006 else if (ntype->ty == Tstruct) { |
1876 assert(member->llvmValue); | 2007 TypeStruct* ts = (TypeStruct*)ntype; |
1877 e->mem = new llvm::CallInst(member->llvmValue, ctorargs.begin(), ctorargs.end(), "tmp", p->scopebb()); | |
1878 } | |
1879 } | |
1880 else if (newtype->ty == Tstruct) { | |
1881 TypeStruct* ts = (TypeStruct*)newtype; | |
1882 if (ts->isZeroInit()) { | 2008 if (ts->isZeroInit()) { |
1883 LLVM_DtoStructZeroInit(ts,e->mem); | 2009 LLVM_DtoStructZeroInit(ts,e->mem); |
1884 } | 2010 } |
1885 else { | 2011 else { |
1886 LLVM_DtoStructCopy(ts,e->mem,ts->llvmInit); | 2012 LLVM_DtoStructCopy(ts,e->mem,ts->llvmInit); |
1907 llvm::Value* ldval = 0; | 2033 llvm::Value* ldval = 0; |
1908 | 2034 |
1909 const llvm::Type* t = val->getType(); | 2035 const llvm::Type* t = val->getType(); |
1910 llvm::Constant* z = llvm::Constant::getNullValue(t); | 2036 llvm::Constant* z = llvm::Constant::getNullValue(t); |
1911 | 2037 |
1912 if (e1->type->ty == Tpointer) { | 2038 Type* e1type = LLVM_DtoDType(e1->type); |
2039 | |
2040 if (e1type->ty == Tpointer) { | |
1913 ldval = v->getValue(); | 2041 ldval = v->getValue(); |
1914 new llvm::FreeInst(ldval, p->scopebb()); | 2042 new llvm::FreeInst(ldval, p->scopebb()); |
1915 | 2043 |
1916 Logger::cout() << *z << '\n'; | 2044 Logger::cout() << *z << '\n'; |
1917 Logger::cout() << *val << '\n'; | 2045 Logger::cout() << *val << '\n'; |
1918 new llvm::StoreInst(z, v->mem, p->scopebb()); | 2046 new llvm::StoreInst(z, v->mem, p->scopebb()); |
1919 } | 2047 } |
1920 else if (e1->type->ty == Tclass) { | 2048 else if (e1type->ty == Tclass) { |
1921 TypeClass* tc = (TypeClass*)e1->type; | 2049 TypeClass* tc = (TypeClass*)e1type; |
1922 LLVM_DtoCallClassDtors(tc, val); | 2050 LLVM_DtoCallClassDtors(tc, val); |
1923 | 2051 |
1924 if (v->vardecl && !v->vardecl->onstack) { | 2052 if (v->vardecl && !v->vardecl->onstack) { |
1925 new llvm::FreeInst(val, p->scopebb()); | 2053 new llvm::FreeInst(val, p->scopebb()); |
1926 } | 2054 } |
1927 new llvm::StoreInst(z, v->mem, p->scopebb()); | 2055 new llvm::StoreInst(z, v->mem, p->scopebb()); |
1928 } | 2056 } |
1929 else if (e1->type->ty == Tarray) { | 2057 else if (e1type->ty == Tarray) { |
1930 // must be on the heap (correct?) | 2058 // must be on the heap (correct?) |
1931 ldval = v->getValue(); | 2059 ldval = v->getValue(); |
1932 | 2060 |
1933 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 2061 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1934 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 2062 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
2005 elem* u = e1->toElem(p); | 2133 elem* u = e1->toElem(p); |
2006 | 2134 |
2007 llvm::Value* b = LLVM_DtoBoolean(u->getValue()); | 2135 llvm::Value* b = LLVM_DtoBoolean(u->getValue()); |
2008 | 2136 |
2009 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true); | 2137 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true); |
2010 e->val = new llvm::ICmpInst(llvm::ICmpInst::ICMP_EQ,b,zero,"tmp",p->scopebb()); | 2138 e->val = p->ir->CreateICmpEQ(b,zero); |
2139 //e->val = new llvm::ICmpInst(llvm::ICmpInst::ICMP_EQ,b,zero,"tmp",p->scopebb()); | |
2011 e->type = elem::VAL; | 2140 e->type = elem::VAL; |
2012 | 2141 |
2013 delete u; | 2142 delete u; |
2014 | 2143 |
2015 return e; | 2144 return e; |
2149 LOG_SCOPE; | 2278 LOG_SCOPE; |
2150 | 2279 |
2151 llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); | 2280 llvm::Value* loca = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); |
2152 LLVM_DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL); | 2281 LLVM_DtoAssert(llvm::ConstantInt::getFalse(), loca, NULL); |
2153 | 2282 |
2154 //new llvm::UnreachableInst(p->scopebb()); | 2283 new llvm::UnreachableInst(p->scopebb()); |
2155 return 0; | 2284 return 0; |
2156 } | 2285 } |
2157 | 2286 |
2158 ////////////////////////////////////////////////////////////////////////////////////////// | 2287 ////////////////////////////////////////////////////////////////////////////////////////// |
2159 | 2288 |
2303 elem* e = new elem; | 2432 elem* e = new elem; |
2304 elem* l = e1->toElem(p); | 2433 elem* l = e1->toElem(p); |
2305 llvm::Value* val = l->getValue(); | 2434 llvm::Value* val = l->getValue(); |
2306 delete l; | 2435 delete l; |
2307 | 2436 |
2437 Type* t = LLVM_DtoDType(type); | |
2438 | |
2308 llvm::Value* zero = 0; | 2439 llvm::Value* zero = 0; |
2309 if (type->isintegral()) | 2440 if (t->isintegral()) |
2310 zero = llvm::ConstantInt::get(val->getType(), 0, true); | 2441 zero = llvm::ConstantInt::get(val->getType(), 0, true); |
2311 else if (type->isfloating()) { | 2442 else if (t->isfloating()) { |
2312 if (type->ty == Tfloat32) | 2443 if (t->ty == Tfloat32) |
2313 zero = llvm::ConstantFP::get(val->getType(), float(0)); | 2444 zero = llvm::ConstantFP::get(val->getType(), float(0)); |
2314 else if (type->ty == Tfloat64 || type->ty == Tfloat80) | 2445 else if (t->ty == Tfloat64 || t->ty == Tfloat80) |
2315 zero = llvm::ConstantFP::get(val->getType(), double(0)); | 2446 zero = llvm::ConstantFP::get(val->getType(), double(0)); |
2316 else | 2447 else |
2317 assert(0); | 2448 assert(0); |
2318 } | 2449 } |
2319 else | 2450 else |
2330 elem* CatExp::toElem(IRState* p) | 2461 elem* CatExp::toElem(IRState* p) |
2331 { | 2462 { |
2332 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2463 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2333 LOG_SCOPE; | 2464 LOG_SCOPE; |
2334 | 2465 |
2335 assert(0 && "array concatenation is not yet implemented"); | 2466 assert(0 && "array cat is not yet implemented"); |
2336 | 2467 |
2337 elem* lhs = e1->toElem(p); | 2468 elem* lhs = e1->toElem(p); |
2338 elem* rhs = e2->toElem(p); | 2469 elem* rhs = e2->toElem(p); |
2339 | 2470 |
2340 // determine new size | 2471 // determine new size |
2341 | 2472 |
2342 delete lhs; | 2473 delete lhs; |
2343 delete rhs; | 2474 delete rhs; |
2344 | 2475 |
2345 return 0; | 2476 return 0; |
2477 } | |
2478 | |
2479 ////////////////////////////////////////////////////////////////////////////////////////// | |
2480 | |
2481 elem* CatAssignExp::toElem(IRState* p) | |
2482 { | |
2483 Logger::print("CatAssignExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2484 LOG_SCOPE; | |
2485 | |
2486 elem* l = e1->toElem(p); | |
2487 assert(l->mem); | |
2488 | |
2489 Type* e1type = LLVM_DtoDType(e1->type); | |
2490 Type* elemtype = LLVM_DtoDType(e1type->next); | |
2491 Type* e2type = LLVM_DtoDType(e2->type); | |
2492 | |
2493 if (e2type == elemtype) { | |
2494 LLVM_DtoCatArrayElement(l->mem,e2); | |
2495 } | |
2496 else | |
2497 assert(0 && "only one element at a time right now"); | |
2498 | |
2499 return 0; | |
2500 } | |
2501 | |
2502 ////////////////////////////////////////////////////////////////////////////////////////// | |
2503 | |
2504 elem* ArrayLiteralExp::toElem(IRState* p) | |
2505 { | |
2506 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | |
2507 LOG_SCOPE; | |
2508 | |
2509 const llvm::Type* t = LLVM_DtoType(type); | |
2510 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | |
2511 | |
2512 llvm::Value* mem = 0; | |
2513 if (p->lvals.empty()) { | |
2514 assert(LLVM_DtoDType(type)->ty == Tsarray); | |
2515 mem = new llvm::AllocaInst(t,"tmparrayliteral",p->topallocapoint()); | |
2516 } | |
2517 else { | |
2518 mem = p->toplval(); | |
2519 if (!llvm::isa<llvm::PointerType>(mem->getType()) || | |
2520 !llvm::isa<llvm::ArrayType>(mem->getType()->getContainedType(0))) | |
2521 { | |
2522 error("TODO array literals can currently only be used to initialise static arrays"); | |
2523 fatal(); | |
2524 } | |
2525 } | |
2526 | |
2527 for (unsigned i=0; i<elements->dim; ++i) | |
2528 { | |
2529 Expression* expr = (Expression*)elements->data[i]; | |
2530 llvm::Value* elemAddr = LLVM_DtoGEPi(mem,0,i,"tmp",p->scopebb()); | |
2531 elem* e = expr->toElem(p); | |
2532 new llvm::StoreInst(e->getValue(), elemAddr, p->scopebb()); | |
2533 } | |
2534 | |
2535 elem* e = new elem; | |
2536 e->mem = mem; | |
2537 e->type = elem::VAL; | |
2538 e->inplace = true; | |
2539 | |
2540 return e; | |
2541 } | |
2542 | |
2543 ////////////////////////////////////////////////////////////////////////////////////////// | |
2544 | |
2545 llvm::Constant* ArrayLiteralExp::toConstElem(IRState* p) | |
2546 { | |
2547 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | |
2548 LOG_SCOPE; | |
2549 | |
2550 const llvm::Type* t = LLVM_DtoType(type); | |
2551 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | |
2552 assert(llvm::isa<llvm::ArrayType>(t)); | |
2553 const llvm::ArrayType* arrtype = llvm::cast<llvm::ArrayType>(t); | |
2554 | |
2555 assert(arrtype->getNumElements() == elements->dim); | |
2556 std::vector<llvm::Constant*> vals(elements->dim, NULL); | |
2557 for (unsigned i=0; i<elements->dim; ++i) | |
2558 { | |
2559 Expression* expr = (Expression*)elements->data[i]; | |
2560 vals[i] = expr->toConstElem(p); | |
2561 } | |
2562 | |
2563 return llvm::ConstantArray::get(arrtype, vals); | |
2346 } | 2564 } |
2347 | 2565 |
2348 ////////////////////////////////////////////////////////////////////////////////////////// | 2566 ////////////////////////////////////////////////////////////////////////////////////////// |
2349 | 2567 |
2350 #define STUB(x) elem *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } | 2568 #define STUB(x) elem *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } |
2372 //STUB(MulExp); | 2590 //STUB(MulExp); |
2373 //STUB(MulAssignExp); | 2591 //STUB(MulAssignExp); |
2374 //STUB(ModExp); | 2592 //STUB(ModExp); |
2375 //STUB(ModAssignExp); | 2593 //STUB(ModAssignExp); |
2376 //STUB(CatExp); | 2594 //STUB(CatExp); |
2377 STUB(CatAssignExp); | 2595 //STUB(CatAssignExp); |
2378 //STUB(AddExp); | 2596 //STUB(AddExp); |
2379 //STUB(AddAssignExp); | 2597 //STUB(AddAssignExp); |
2380 STUB(Expression); | 2598 STUB(Expression); |
2381 //STUB(MinExp); | 2599 //STUB(MinExp); |
2382 //STUB(MinAssignExp); | 2600 //STUB(MinAssignExp); |
2415 //STUB(IndexExp); | 2633 //STUB(IndexExp); |
2416 //STUB(CommaExp); | 2634 //STUB(CommaExp); |
2417 //STUB(ArrayLengthExp); | 2635 //STUB(ArrayLengthExp); |
2418 //STUB(HaltExp); | 2636 //STUB(HaltExp); |
2419 STUB(RemoveExp); | 2637 STUB(RemoveExp); |
2420 STUB(ArrayLiteralExp); | 2638 //STUB(ArrayLiteralExp); |
2421 STUB(AssocArrayLiteralExp); | 2639 STUB(AssocArrayLiteralExp); |
2422 //STUB(StructLiteralExp); | 2640 //STUB(StructLiteralExp); |
2423 | 2641 |
2642 #define CONSTSTUB(x) llvm::Constant* x::toConstElem(IRState * p) {error("const Exp type "#x" not implemented: '%s' type: '%s'", toChars(), type->toChars()); assert(0); fatal(); return NULL; } | |
2643 CONSTSTUB(Expression); | |
2644 //CONSTSTUB(IntegerExp); | |
2645 //CONSTSTUB(RealExp); | |
2646 //CONSTSTUB(NullExp); | |
2647 //CONSTSTUB(StringExp); | |
2648 //CONSTSTUB(VarExp); | |
2649 //CONSTSTUB(ArrayLiteralExp); | |
2650 CONSTSTUB(AssocArrayLiteralExp); | |
2651 //CONSTSTUB(StructLiteralExp); | |
2652 | |
2424 unsigned Type::totym() { return 0; } | 2653 unsigned Type::totym() { return 0; } |
2425 | 2654 |
2426 type * Type::toCtype() | 2655 type * Type::toCtype() |
2427 { | 2656 { |
2428 assert(0); | 2657 assert(0); |