Mercurial > projects > ldc
comparison gen/toir.cpp @ 213:7816aafeea3c trunk
[svn r229] Updated the object.d implementation to the latest Tango.
Fixed a bunch of the built-in typeinfos for arrays, they did not inherit TypeInfo_Array.
Applied patch to tango/text/convert/Layout.d by fvbommel, closes #47 .
Cleaned up some type code.
Replaced uses of llvm::Type with LLType (a typedef), same for Value and Constant.
Fixed a few cases where typeinfo for user structs could be emitted multiple times, seems to still be some cases of this :/
author | lindquist |
---|---|
date | Fri, 30 May 2008 19:32:04 +0200 |
parents | 4c2689d57ba4 |
children | a58d8f4b84df |
comparison
equal
deleted
inserted
replaced
212:4c2689d57ba4 | 213:7816aafeea3c |
---|---|
67 assert(vd->ir.irLocal->nestedIndex >= 0); | 67 assert(vd->ir.irLocal->nestedIndex >= 0); |
68 } | 68 } |
69 // normal stack variable | 69 // normal stack variable |
70 else { | 70 else { |
71 // allocate storage on the stack | 71 // allocate storage on the stack |
72 const llvm::Type* lltype = DtoType(vd->type); | 72 const LLType* lltype = DtoType(vd->type); |
73 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); | 73 llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint()); |
74 //allocainst->setAlignment(vd->type->alignsize()); // TODO | 74 //allocainst->setAlignment(vd->type->alignsize()); // TODO |
75 assert(!vd->ir.irLocal); | 75 assert(!vd->ir.irLocal); |
76 vd->ir.irLocal = new IrLocal(vd); | 76 vd->ir.irLocal = new IrLocal(vd); |
77 vd->ir.irLocal->value = allocainst; | 77 vd->ir.irLocal->value = allocainst; |
155 Logger::println("Id::_arguments"); | 155 Logger::println("Id::_arguments"); |
156 /*if (!vd->ir.getIrValue()) | 156 /*if (!vd->ir.getIrValue()) |
157 vd->ir.getIrValue() = p->func()->decl->irFunc->_arguments; | 157 vd->ir.getIrValue() = p->func()->decl->irFunc->_arguments; |
158 assert(vd->ir.getIrValue()); | 158 assert(vd->ir.getIrValue()); |
159 return new DVarValue(vd, vd->ir.getIrValue(), true);*/ | 159 return new DVarValue(vd, vd->ir.getIrValue(), true);*/ |
160 llvm::Value* v = p->func()->decl->ir.irFunc->_arguments; | 160 LLValue* v = p->func()->decl->ir.irFunc->_arguments; |
161 assert(v); | 161 assert(v); |
162 return new DVarValue(vd, v, true); | 162 return new DVarValue(vd, v, true); |
163 } | 163 } |
164 // _argptr | 164 // _argptr |
165 else if (vd->ident == Id::_argptr) | 165 else if (vd->ident == Id::_argptr) |
167 Logger::println("Id::_argptr"); | 167 Logger::println("Id::_argptr"); |
168 /*if (!vd->ir.getIrValue()) | 168 /*if (!vd->ir.getIrValue()) |
169 vd->ir.getIrValue() = p->func()->decl->irFunc->_argptr; | 169 vd->ir.getIrValue() = p->func()->decl->irFunc->_argptr; |
170 assert(vd->ir.getIrValue()); | 170 assert(vd->ir.getIrValue()); |
171 return new DVarValue(vd, vd->ir.getIrValue(), true);*/ | 171 return new DVarValue(vd, vd->ir.getIrValue(), true);*/ |
172 llvm::Value* v = p->func()->decl->ir.irFunc->_argptr; | 172 LLValue* v = p->func()->decl->ir.irFunc->_argptr; |
173 assert(v); | 173 assert(v); |
174 return new DVarValue(vd, v, true); | 174 return new DVarValue(vd, v, true); |
175 } | 175 } |
176 // _dollar | 176 // _dollar |
177 else if (vd->ident == Id::dollar) | 177 else if (vd->ident == Id::dollar) |
178 { | 178 { |
179 Logger::println("Id::dollar"); | 179 Logger::println("Id::dollar"); |
180 assert(!p->arrays.empty()); | 180 assert(!p->arrays.empty()); |
181 llvm::Value* tmp = DtoArrayLen(p->arrays.back()); | 181 LLValue* tmp = DtoArrayLen(p->arrays.back()); |
182 return new DVarValue(vd, tmp, false); | 182 return new DVarValue(vd, tmp, false); |
183 } | 183 } |
184 // typeinfo | 184 // typeinfo |
185 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 185 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) |
186 { | 186 { |
187 Logger::println("TypeInfoDeclaration"); | 187 Logger::println("TypeInfoDeclaration"); |
188 DtoForceDeclareDsymbol(tid); | 188 DtoForceDeclareDsymbol(tid); |
189 assert(tid->ir.getIrValue()); | 189 assert(tid->ir.getIrValue()); |
190 const llvm::Type* vartype = DtoType(type); | 190 const LLType* vartype = DtoType(type); |
191 llvm::Value* m; | 191 LLValue* m; |
192 if (tid->ir.getIrValue()->getType() != getPtrToType(vartype)) | 192 if (tid->ir.getIrValue()->getType() != getPtrToType(vartype)) |
193 m = p->ir->CreateBitCast(tid->ir.getIrValue(), vartype, "tmp"); | 193 m = p->ir->CreateBitCast(tid->ir.getIrValue(), vartype, "tmp"); |
194 else | 194 else |
195 m = tid->ir.getIrValue(); | 195 m = tid->ir.getIrValue(); |
196 return new DVarValue(vd, m, true); | 196 return new DVarValue(vd, m, true); |
261 return 0; | 261 return 0; |
262 } | 262 } |
263 | 263 |
264 ////////////////////////////////////////////////////////////////////////////////////////// | 264 ////////////////////////////////////////////////////////////////////////////////////////// |
265 | 265 |
266 llvm::Constant* VarExp::toConstElem(IRState* p) | 266 LLConstant* VarExp::toConstElem(IRState* p) |
267 { | 267 { |
268 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 268 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
269 LOG_SCOPE; | 269 LOG_SCOPE; |
270 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) | 270 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration()) |
271 { | 271 { |
280 } | 280 } |
281 else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration()) | 281 else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration()) |
282 { | 282 { |
283 DtoForceDeclareDsymbol(ti); | 283 DtoForceDeclareDsymbol(ti); |
284 assert(ti->ir.getIrValue()); | 284 assert(ti->ir.getIrValue()); |
285 const llvm::Type* vartype = DtoType(type); | 285 const LLType* vartype = DtoType(type); |
286 llvm::Constant* m = isaConstant(ti->ir.getIrValue()); | 286 LLConstant* m = isaConstant(ti->ir.getIrValue()); |
287 assert(m); | 287 assert(m); |
288 if (ti->ir.getIrValue()->getType() != getPtrToType(vartype)) | 288 if (ti->ir.getIrValue()->getType() != getPtrToType(vartype)) |
289 m = llvm::ConstantExpr::getBitCast(m, vartype); | 289 m = llvm::ConstantExpr::getBitCast(m, vartype); |
290 return m; | 290 return m; |
291 } | 291 } |
297 | 297 |
298 DValue* IntegerExp::toElem(IRState* p) | 298 DValue* IntegerExp::toElem(IRState* p) |
299 { | 299 { |
300 Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars()); | 300 Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars()); |
301 LOG_SCOPE; | 301 LOG_SCOPE; |
302 llvm::Constant* c = toConstElem(p); | 302 LLConstant* c = toConstElem(p); |
303 return new DConstValue(type, c); | 303 return new DConstValue(type, c); |
304 } | 304 } |
305 | 305 |
306 ////////////////////////////////////////////////////////////////////////////////////////// | 306 ////////////////////////////////////////////////////////////////////////////////////////// |
307 | 307 |
308 llvm::Constant* IntegerExp::toConstElem(IRState* p) | 308 LLConstant* IntegerExp::toConstElem(IRState* p) |
309 { | 309 { |
310 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 310 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
311 LOG_SCOPE; | 311 LOG_SCOPE; |
312 const llvm::Type* t = DtoType(type); | 312 const LLType* t = DtoType(type); |
313 if (isaPointer(t)) { | 313 if (isaPointer(t)) { |
314 Logger::println("pointer"); | 314 Logger::println("pointer"); |
315 llvm::Constant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false); | 315 LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false); |
316 return llvm::ConstantExpr::getIntToPtr(i, t); | 316 return llvm::ConstantExpr::getIntToPtr(i, t); |
317 } | 317 } |
318 assert(llvm::isa<llvm::IntegerType>(t)); | 318 assert(llvm::isa<llvm::IntegerType>(t)); |
319 llvm::Constant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); | 319 LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned()); |
320 assert(c); | 320 assert(c); |
321 Logger::cout() << "value = " << *c << '\n'; | 321 Logger::cout() << "value = " << *c << '\n'; |
322 return c; | 322 return c; |
323 } | 323 } |
324 | 324 |
326 | 326 |
327 DValue* RealExp::toElem(IRState* p) | 327 DValue* RealExp::toElem(IRState* p) |
328 { | 328 { |
329 Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars()); | 329 Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars()); |
330 LOG_SCOPE; | 330 LOG_SCOPE; |
331 llvm::Constant* c = toConstElem(p); | 331 LLConstant* c = toConstElem(p); |
332 return new DConstValue(type, c); | 332 return new DConstValue(type, c); |
333 } | 333 } |
334 | 334 |
335 ////////////////////////////////////////////////////////////////////////////////////////// | 335 ////////////////////////////////////////////////////////////////////////////////////////// |
336 | 336 |
337 llvm::Constant* RealExp::toConstElem(IRState* p) | 337 LLConstant* RealExp::toConstElem(IRState* p) |
338 { | 338 { |
339 Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 339 Logger::print("RealExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
340 LOG_SCOPE; | 340 LOG_SCOPE; |
341 Type* t = DtoDType(type); | 341 Type* t = DtoDType(type); |
342 return DtoConstFP(t, value); | 342 return DtoConstFP(t, value); |
346 | 346 |
347 DValue* NullExp::toElem(IRState* p) | 347 DValue* NullExp::toElem(IRState* p) |
348 { | 348 { |
349 Logger::print("NullExp::toElem(type=%s): %s\n", type->toChars(),toChars()); | 349 Logger::print("NullExp::toElem(type=%s): %s\n", type->toChars(),toChars()); |
350 LOG_SCOPE; | 350 LOG_SCOPE; |
351 llvm::Constant* c = toConstElem(p); | 351 LLConstant* c = toConstElem(p); |
352 return new DNullValue(type, c); | 352 return new DNullValue(type, c); |
353 } | 353 } |
354 | 354 |
355 ////////////////////////////////////////////////////////////////////////////////////////// | 355 ////////////////////////////////////////////////////////////////////////////////////////// |
356 | 356 |
357 llvm::Constant* NullExp::toConstElem(IRState* p) | 357 LLConstant* NullExp::toConstElem(IRState* p) |
358 { | 358 { |
359 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars()); | 359 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars()); |
360 LOG_SCOPE; | 360 LOG_SCOPE; |
361 const llvm::Type* t = DtoType(type); | 361 const LLType* t = DtoType(type); |
362 if (type->ty == Tarray) { | 362 if (type->ty == Tarray) { |
363 assert(isaStruct(t)); | 363 assert(isaStruct(t)); |
364 return llvm::ConstantAggregateZero::get(t); | 364 return llvm::ConstantAggregateZero::get(t); |
365 } | 365 } |
366 else { | 366 else { |
374 | 374 |
375 DValue* ComplexExp::toElem(IRState* p) | 375 DValue* ComplexExp::toElem(IRState* p) |
376 { | 376 { |
377 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); | 377 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars()); |
378 LOG_SCOPE; | 378 LOG_SCOPE; |
379 llvm::Constant* c = toConstElem(p); | 379 LLConstant* c = toConstElem(p); |
380 | 380 |
381 if (c->isNullValue()) { | 381 if (c->isNullValue()) { |
382 Type* t = DtoDType(type); | 382 Type* t = DtoDType(type); |
383 if (t->ty == Tcomplex32) | 383 if (t->ty == Tcomplex32) |
384 c = DtoConstFP(Type::tfloat32, 0); | 384 c = DtoConstFP(Type::tfloat32, 0); |
390 return new DComplexValue(type, c->getOperand(0), c->getOperand(1)); | 390 return new DComplexValue(type, c->getOperand(0), c->getOperand(1)); |
391 } | 391 } |
392 | 392 |
393 ////////////////////////////////////////////////////////////////////////////////////////// | 393 ////////////////////////////////////////////////////////////////////////////////////////// |
394 | 394 |
395 llvm::Constant* ComplexExp::toConstElem(IRState* p) | 395 LLConstant* ComplexExp::toConstElem(IRState* p) |
396 { | 396 { |
397 Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars()); | 397 Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars()); |
398 LOG_SCOPE; | 398 LOG_SCOPE; |
399 return DtoConstComplex(type, value.re, value.im); | 399 return DtoConstComplex(type, value.re, value.im); |
400 } | 400 } |
407 LOG_SCOPE; | 407 LOG_SCOPE; |
408 | 408 |
409 Type* dtype = DtoDType(type); | 409 Type* dtype = DtoDType(type); |
410 Type* cty = DtoDType(dtype->next); | 410 Type* cty = DtoDType(dtype->next); |
411 | 411 |
412 const llvm::Type* ct = DtoType(cty); | 412 const LLType* ct = DtoType(cty); |
413 if (ct == llvm::Type::VoidTy) | 413 if (ct == llvm::Type::VoidTy) |
414 ct = llvm::Type::Int8Ty; | 414 ct = llvm::Type::Int8Ty; |
415 //printf("ct = %s\n", type->next->toChars()); | 415 //printf("ct = %s\n", type->next->toChars()); |
416 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); | 416 const llvm::ArrayType* at = llvm::ArrayType::get(ct,len+1); |
417 | 417 |
418 llvm::Constant* _init; | 418 LLConstant* _init; |
419 if (cty->size() == 1) { | 419 if (cty->size() == 1) { |
420 uint8_t* str = (uint8_t*)string; | 420 uint8_t* str = (uint8_t*)string; |
421 std::string cont((char*)str, len); | 421 std::string cont((char*)str, len); |
422 _init = llvm::ConstantArray::get(cont,true); | 422 _init = llvm::ConstantArray::get(cont,true); |
423 } | 423 } |
424 else if (cty->size() == 2) { | 424 else if (cty->size() == 2) { |
425 uint16_t* str = (uint16_t*)string; | 425 uint16_t* str = (uint16_t*)string; |
426 std::vector<llvm::Constant*> vals; | 426 std::vector<LLConstant*> vals; |
427 for(size_t i=0; i<len; ++i) { | 427 for(size_t i=0; i<len; ++i) { |
428 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; | 428 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; |
429 } | 429 } |
430 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); | 430 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); |
431 _init = llvm::ConstantArray::get(at,vals); | 431 _init = llvm::ConstantArray::get(at,vals); |
432 } | 432 } |
433 else if (cty->size() == 4) { | 433 else if (cty->size() == 4) { |
434 uint32_t* str = (uint32_t*)string; | 434 uint32_t* str = (uint32_t*)string; |
435 std::vector<llvm::Constant*> vals; | 435 std::vector<LLConstant*> vals; |
436 for(size_t i=0; i<len; ++i) { | 436 for(size_t i=0; i<len; ++i) { |
437 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; | 437 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; |
438 } | 438 } |
439 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); | 439 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); |
440 _init = llvm::ConstantArray::get(at,vals); | 440 _init = llvm::ConstantArray::get(at,vals); |
445 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | 445 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; |
446 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; | 446 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; |
447 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module); | 447 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module); |
448 | 448 |
449 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 449 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
450 llvm::Constant* idxs[2] = { zero, zero }; | 450 LLConstant* idxs[2] = { zero, zero }; |
451 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 451 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
452 | 452 |
453 if (dtype->ty == Tarray) { | 453 if (dtype->ty == Tarray) { |
454 llvm::Constant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); | 454 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); |
455 if (!p->topexp() || p->topexp()->e2 != this) { | 455 if (!p->topexp() || p->topexp()->e2 != this) { |
456 llvm::Value* tmpmem = new llvm::AllocaInst(DtoType(dtype),"tempstring",p->topallocapoint()); | 456 LLValue* tmpmem = new llvm::AllocaInst(DtoType(dtype),"tempstring",p->topallocapoint()); |
457 DtoSetArray(tmpmem, clen, arrptr); | 457 DtoSetArray(tmpmem, clen, arrptr); |
458 return new DVarValue(type, tmpmem, true); | 458 return new DVarValue(type, tmpmem, true); |
459 } | 459 } |
460 else if (p->topexp()->e2 == this) { | 460 else if (p->topexp()->e2 == this) { |
461 DValue* arr = p->topexp()->v; | 461 DValue* arr = p->topexp()->v; |
469 } | 469 } |
470 } | 470 } |
471 assert(0); | 471 assert(0); |
472 } | 472 } |
473 else if (dtype->ty == Tsarray) { | 473 else if (dtype->ty == Tsarray) { |
474 const llvm::Type* dstType = getPtrToType(llvm::ArrayType::get(ct, len)); | 474 const LLType* dstType = getPtrToType(llvm::ArrayType::get(ct, len)); |
475 llvm::Value* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); | 475 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType); |
476 return new DVarValue(type, emem, true); | 476 return new DVarValue(type, emem, true); |
477 } | 477 } |
478 else if (dtype->ty == Tpointer) { | 478 else if (dtype->ty == Tpointer) { |
479 return new DImValue(type, arrptr); | 479 return new DImValue(type, arrptr); |
480 } | 480 } |
483 return 0; | 483 return 0; |
484 } | 484 } |
485 | 485 |
486 ////////////////////////////////////////////////////////////////////////////////////////// | 486 ////////////////////////////////////////////////////////////////////////////////////////// |
487 | 487 |
488 llvm::Constant* StringExp::toConstElem(IRState* p) | 488 LLConstant* StringExp::toConstElem(IRState* p) |
489 { | 489 { |
490 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 490 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
491 LOG_SCOPE; | 491 LOG_SCOPE; |
492 | 492 |
493 Type* t = DtoDType(type); | 493 Type* t = DtoDType(type); |
494 Type* cty = DtoDType(t->next); | 494 Type* cty = DtoDType(t->next); |
495 | 495 |
496 bool nullterm = (t->ty != Tsarray); | 496 bool nullterm = (t->ty != Tsarray); |
497 size_t endlen = nullterm ? len+1 : len; | 497 size_t endlen = nullterm ? len+1 : len; |
498 | 498 |
499 const llvm::Type* ct = DtoType(cty); | 499 const LLType* ct = DtoType(cty); |
500 const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen); | 500 const llvm::ArrayType* at = llvm::ArrayType::get(ct,endlen); |
501 | 501 |
502 llvm::Constant* _init; | 502 LLConstant* _init; |
503 if (cty->size() == 1) { | 503 if (cty->size() == 1) { |
504 uint8_t* str = (uint8_t*)string; | 504 uint8_t* str = (uint8_t*)string; |
505 std::string cont((char*)str, len); | 505 std::string cont((char*)str, len); |
506 _init = llvm::ConstantArray::get(cont, nullterm); | 506 _init = llvm::ConstantArray::get(cont, nullterm); |
507 } | 507 } |
508 else if (cty->size() == 2) { | 508 else if (cty->size() == 2) { |
509 uint16_t* str = (uint16_t*)string; | 509 uint16_t* str = (uint16_t*)string; |
510 std::vector<llvm::Constant*> vals; | 510 std::vector<LLConstant*> vals; |
511 for(size_t i=0; i<len; ++i) { | 511 for(size_t i=0; i<len; ++i) { |
512 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; | 512 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; |
513 } | 513 } |
514 if (nullterm) | 514 if (nullterm) |
515 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); | 515 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); |
516 _init = llvm::ConstantArray::get(at,vals); | 516 _init = llvm::ConstantArray::get(at,vals); |
517 } | 517 } |
518 else if (cty->size() == 4) { | 518 else if (cty->size() == 4) { |
519 uint32_t* str = (uint32_t*)string; | 519 uint32_t* str = (uint32_t*)string; |
520 std::vector<llvm::Constant*> vals; | 520 std::vector<LLConstant*> vals; |
521 for(size_t i=0; i<len; ++i) { | 521 for(size_t i=0; i<len; ++i) { |
522 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; | 522 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));; |
523 } | 523 } |
524 if (nullterm) | 524 if (nullterm) |
525 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); | 525 vals.push_back(llvm::ConstantInt::get(ct, 0, false)); |
535 | 535 |
536 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | 536 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; |
537 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module); | 537 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module); |
538 | 538 |
539 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 539 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
540 llvm::Constant* idxs[2] = { zero, zero }; | 540 LLConstant* idxs[2] = { zero, zero }; |
541 llvm::Constant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); | 541 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); |
542 | 542 |
543 if (t->ty == Tpointer) { | 543 if (t->ty == Tpointer) { |
544 return arrptr; | 544 return arrptr; |
545 } | 545 } |
546 else if (t->ty == Tarray) { | 546 else if (t->ty == Tarray) { |
547 llvm::Constant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); | 547 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false); |
548 return DtoConstSlice(clen, arrptr); | 548 return DtoConstSlice(clen, arrptr); |
549 } | 549 } |
550 | 550 |
551 assert(0); | 551 assert(0); |
552 return NULL; | 552 return NULL; |
584 } | 584 } |
585 | 585 |
586 if (l->isSlice() || l->isComplex()) | 586 if (l->isSlice() || l->isComplex()) |
587 return l; | 587 return l; |
588 | 588 |
589 llvm::Value* v; | 589 LLValue* v; |
590 if (l->isVar() && l->isVar()->lval) | 590 if (l->isVar() && l->isVar()->lval) |
591 v = l->getLVal(); | 591 v = l->getLVal(); |
592 else | 592 else |
593 v = l->getRVal(); | 593 v = l->getRVal(); |
594 | 594 |
617 assert(r->isConst()); | 617 assert(r->isConst()); |
618 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c); | 618 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c); |
619 | 619 |
620 TypeStruct* ts = (TypeStruct*)e1next; | 620 TypeStruct* ts = (TypeStruct*)e1next; |
621 std::vector<unsigned> offsets; | 621 std::vector<unsigned> offsets; |
622 llvm::Value* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); | 622 LLValue* v = DtoIndexStruct(l->getRVal(), ts->sym, t->next, cofs->getZExtValue(), offsets); |
623 return new DFieldValue(type, v, true); | 623 return new DFieldValue(type, v, true); |
624 } | 624 } |
625 else if (e1type->ty == Tpointer) { | 625 else if (e1type->ty == Tpointer) { |
626 Logger::println("add to pointer"); | 626 Logger::println("add to pointer"); |
627 if (r->isConst()) { | 627 if (r->isConst()) { |
629 if (cofs->isZero()) { | 629 if (cofs->isZero()) { |
630 Logger::println("is zero"); | 630 Logger::println("is zero"); |
631 return new DImValue(type, l->getRVal()); | 631 return new DImValue(type, l->getRVal()); |
632 } | 632 } |
633 } | 633 } |
634 llvm::Value* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb()); | 634 LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb()); |
635 return new DImValue(type, v); | 635 return new DImValue(type, v); |
636 } | 636 } |
637 else if (t->iscomplex()) { | 637 else if (t->iscomplex()) { |
638 return DtoComplexAdd(type, l, r); | 638 return DtoComplexAdd(type, l, r); |
639 } | 639 } |
661 | 661 |
662 Type* t = DtoDType(type); | 662 Type* t = DtoDType(type); |
663 | 663 |
664 DValue* res; | 664 DValue* res; |
665 if (DtoDType(e1->type)->ty == Tpointer) { | 665 if (DtoDType(e1->type)->ty == Tpointer) { |
666 llvm::Value* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); | 666 LLValue* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); |
667 res = new DImValue(type, gep); | 667 res = new DImValue(type, gep); |
668 } | 668 } |
669 else if (t->iscomplex()) { | 669 else if (t->iscomplex()) { |
670 res = DtoComplexAdd(e1->type, l, r); | 670 res = DtoComplexAdd(e1->type, l, r); |
671 } | 671 } |
699 Type* t = DtoDType(type); | 699 Type* t = DtoDType(type); |
700 Type* t1 = DtoDType(e1->type); | 700 Type* t1 = DtoDType(e1->type); |
701 Type* t2 = DtoDType(e2->type); | 701 Type* t2 = DtoDType(e2->type); |
702 | 702 |
703 if (t1->ty == Tpointer && t2->ty == Tpointer) { | 703 if (t1->ty == Tpointer && t2->ty == Tpointer) { |
704 llvm::Value* lv = l->getRVal(); | 704 LLValue* lv = l->getRVal(); |
705 llvm::Value* rv = r->getRVal(); | 705 LLValue* rv = r->getRVal(); |
706 Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n'; | 706 Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n'; |
707 lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp"); | 707 lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp"); |
708 rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp"); | 708 rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp"); |
709 llvm::Value* diff = p->ir->CreateSub(lv,rv,"tmp"); | 709 LLValue* diff = p->ir->CreateSub(lv,rv,"tmp"); |
710 if (diff->getType() != DtoType(type)) | 710 if (diff->getType() != DtoType(type)) |
711 diff = p->ir->CreateIntToPtr(diff, DtoType(type), "tmp"); | 711 diff = p->ir->CreateIntToPtr(diff, DtoType(type), "tmp"); |
712 return new DImValue(type, diff); | 712 return new DImValue(type, diff); |
713 } | 713 } |
714 else if (t1->ty == Tpointer) { | 714 else if (t1->ty == Tpointer) { |
715 llvm::Value* idx = p->ir->CreateNeg(r->getRVal(), "tmp"); | 715 LLValue* idx = p->ir->CreateNeg(r->getRVal(), "tmp"); |
716 llvm::Value* v = llvm::GetElementPtrInst::Create(l->getRVal(), idx, "tmp", p->scopebb()); | 716 LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), idx, "tmp", p->scopebb()); |
717 return new DImValue(type, v); | 717 return new DImValue(type, v); |
718 } | 718 } |
719 else if (t->iscomplex()) { | 719 else if (t->iscomplex()) { |
720 return DtoComplexSub(type, l, r); | 720 return DtoComplexSub(type, l, r); |
721 } | 721 } |
737 Type* t = DtoDType(type); | 737 Type* t = DtoDType(type); |
738 | 738 |
739 DValue* res; | 739 DValue* res; |
740 if (DtoDType(e1->type)->ty == Tpointer) { | 740 if (DtoDType(e1->type)->ty == Tpointer) { |
741 Logger::println("ptr"); | 741 Logger::println("ptr"); |
742 llvm::Value* tmp = r->getRVal(); | 742 LLValue* tmp = r->getRVal(); |
743 llvm::Value* zero = llvm::ConstantInt::get(tmp->getType(),0,false); | 743 LLValue* zero = llvm::ConstantInt::get(tmp->getType(),0,false); |
744 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); | 744 tmp = llvm::BinaryOperator::createSub(zero,tmp,"tmp",p->scopebb()); |
745 tmp = llvm::GetElementPtrInst::Create(l->getRVal(),tmp,"tmp",p->scopebb()); | 745 tmp = llvm::GetElementPtrInst::Create(l->getRVal(),tmp,"tmp",p->scopebb()); |
746 res = new DImValue(type, tmp); | 746 res = new DImValue(type, tmp); |
747 } | 747 } |
748 else if (t->iscomplex()) { | 748 else if (t->iscomplex()) { |
876 | 876 |
877 TypeFunction* tf = 0; | 877 TypeFunction* tf = 0; |
878 Type* e1type = DtoDType(e1->type); | 878 Type* e1type = DtoDType(e1->type); |
879 | 879 |
880 bool delegateCall = false; | 880 bool delegateCall = false; |
881 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false); | 881 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false); |
882 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false); | 882 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty,1,false); |
883 LINK dlink = LINKd; | 883 LINK dlink = LINKd; |
884 | 884 |
885 // hidden struct return parameter handling | 885 // hidden struct return parameter handling |
886 bool retinptr = false; | 886 bool retinptr = false; |
887 | 887 |
927 else if (fndecl->llvmInternal == LLVMva_arg) { | 927 else if (fndecl->llvmInternal == LLVMva_arg) { |
928 //Argument* fnarg = Argument::getNth(tf->parameters, 0); | 928 //Argument* fnarg = Argument::getNth(tf->parameters, 0); |
929 Expression* exp = (Expression*)arguments->data[0]; | 929 Expression* exp = (Expression*)arguments->data[0]; |
930 DValue* expelem = exp->toElem(p); | 930 DValue* expelem = exp->toElem(p); |
931 Type* t = DtoDType(type); | 931 Type* t = DtoDType(type); |
932 const llvm::Type* llt = DtoType(type); | 932 const LLType* llt = DtoType(type); |
933 if (DtoIsPassedByRef(t)) | 933 if (DtoIsPassedByRef(t)) |
934 llt = getPtrToType(llt); | 934 llt = getPtrToType(llt); |
935 // TODO | 935 // TODO |
936 if (strcmp(global.params.llvmArch, "x86") != 0) { | 936 if (strcmp(global.params.llvmArch, "x86") != 0) { |
937 warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars()); | 937 warning("%s: va_arg for C variadic functions is broken for anything but x86", loc.toChars()); |
942 //Argument* fnarg = Argument::getNth(tf->parameters, 0); | 942 //Argument* fnarg = Argument::getNth(tf->parameters, 0); |
943 Expression* exp = (Expression*)arguments->data[0]; | 943 Expression* exp = (Expression*)arguments->data[0]; |
944 DValue* expv = exp->toElem(p); | 944 DValue* expv = exp->toElem(p); |
945 if (expv->getType()->toBasetype()->ty != Tint32) | 945 if (expv->getType()->toBasetype()->ty != Tint32) |
946 expv = DtoCast(expv, Type::tint32); | 946 expv = DtoCast(expv, Type::tint32); |
947 llvm::Value* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb()); | 947 LLValue* alloc = new llvm::AllocaInst(llvm::Type::Int8Ty, expv->getRVal(), "alloca", p->scopebb()); |
948 return new DImValue(type, alloc); | 948 return new DImValue(type, alloc); |
949 } | 949 } |
950 } | 950 } |
951 | 951 |
952 // args | 952 // args |
957 if (delegateCall || (dfn && dfn->vthis)) n++; | 957 if (delegateCall || (dfn && dfn->vthis)) n++; |
958 if (retinptr) n++; | 958 if (retinptr) n++; |
959 if (tf->linkage == LINKd && tf->varargs == 1) n+=2; | 959 if (tf->linkage == LINKd && tf->varargs == 1) n+=2; |
960 if (dfn && dfn->func && dfn->func->isNested()) n++; | 960 if (dfn && dfn->func && dfn->func->isNested()) n++; |
961 | 961 |
962 llvm::Value* funcval = fn->getRVal(); | 962 LLValue* funcval = fn->getRVal(); |
963 assert(funcval != 0); | 963 assert(funcval != 0); |
964 std::vector<llvm::Value*> llargs(n, 0); | 964 std::vector<LLValue*> llargs(n, 0); |
965 | 965 |
966 const llvm::FunctionType* llfnty = 0; | 966 const llvm::FunctionType* llfnty = 0; |
967 | 967 |
968 // normal function call | 968 // normal function call |
969 if (llvm::isa<llvm::FunctionType>(funcval->getType())) { | 969 if (llvm::isa<llvm::FunctionType>(funcval->getType())) { |
983 } | 983 } |
984 // struct pointer - delegate | 984 // struct pointer - delegate |
985 else if (isaStruct(funcval->getType()->getContainedType(0))) { | 985 else if (isaStruct(funcval->getType()->getContainedType(0))) { |
986 funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb()); | 986 funcval = DtoGEP(funcval,zero,one,"tmp",p->scopebb()); |
987 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 987 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
988 const llvm::Type* ty = funcval->getType()->getContainedType(0); | 988 const LLType* ty = funcval->getType()->getContainedType(0); |
989 llfnty = llvm::cast<llvm::FunctionType>(ty); | 989 llfnty = llvm::cast<llvm::FunctionType>(ty); |
990 } | 990 } |
991 // unknown | 991 // unknown |
992 else { | 992 else { |
993 Logger::cout() << "what kind of pointer are we calling? : " << *funcval->getType() << '\n'; | 993 Logger::cout() << "what kind of pointer are we calling? : " << *funcval->getType() << '\n'; |
1009 | 1009 |
1010 // hidden struct return arguments | 1010 // hidden struct return arguments |
1011 if (retinptr) { | 1011 if (retinptr) { |
1012 if (topexp && topexp->e2 == this) { | 1012 if (topexp && topexp->e2 == this) { |
1013 assert(topexp->v); | 1013 assert(topexp->v); |
1014 llvm::Value* tlv = topexp->v->getLVal(); | 1014 LLValue* tlv = topexp->v->getLVal(); |
1015 assert(isaStruct(tlv->getType()->getContainedType(0))); | 1015 assert(isaStruct(tlv->getType()->getContainedType(0))); |
1016 llargs[j] = tlv; | 1016 llargs[j] = tlv; |
1017 isInPlace = true; | 1017 isInPlace = true; |
1018 /*if (DtoIsPassedByRef(tf->next)) { | 1018 /*if (DtoIsPassedByRef(tf->next)) { |
1019 isInPlace = true; | 1019 isInPlace = true; |
1024 else { | 1024 else { |
1025 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); | 1025 llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint()); |
1026 } | 1026 } |
1027 | 1027 |
1028 if (dfn && dfn->func && dfn->func->runTimeHack) { | 1028 if (dfn && dfn->func && dfn->func->runTimeHack) { |
1029 const llvm::Type* rettype = getPtrToType(DtoType(type)); | 1029 const LLType* rettype = getPtrToType(DtoType(type)); |
1030 if (llargs[j]->getType() != llfnty->getParamType(j)) { | 1030 if (llargs[j]->getType() != llfnty->getParamType(j)) { |
1031 Logger::println("llvmRunTimeHack==true - force casting return value param"); | 1031 Logger::println("llvmRunTimeHack==true - force casting return value param"); |
1032 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n'; | 1032 Logger::cout() << "casting: " << *llargs[j] << " to type: " << *llfnty->getParamType(j) << '\n'; |
1033 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); | 1033 llargs[j] = DtoBitCast(llargs[j], llfnty->getParamType(j)); |
1034 } | 1034 } |
1052 ++argiter; | 1052 ++argiter; |
1053 } | 1053 } |
1054 // delegate context arguments | 1054 // delegate context arguments |
1055 else if (delegateCall) { | 1055 else if (delegateCall) { |
1056 Logger::println("Delegate Call"); | 1056 Logger::println("Delegate Call"); |
1057 llvm::Value* contextptr = DtoGEP(fn->getRVal(),zero,zero,"tmp",p->scopebb()); | 1057 LLValue* contextptr = DtoGEP(fn->getRVal(),zero,zero,"tmp",p->scopebb()); |
1058 llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); | 1058 llargs[j] = new llvm::LoadInst(contextptr,"tmp",p->scopebb()); |
1059 ++j; | 1059 ++j; |
1060 ++argiter; | 1060 ++argiter; |
1061 } | 1061 } |
1062 // nested call | 1062 // nested call |
1063 else if (dfn && dfn->func && dfn->func->isNested()) { | 1063 else if (dfn && dfn->func && dfn->func->isNested()) { |
1064 Logger::println("Nested Call"); | 1064 Logger::println("Nested Call"); |
1065 llvm::Value* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); | 1065 LLValue* contextptr = DtoNestedContext(dfn->func->toParent2()->isFuncDeclaration()); |
1066 if (!contextptr) | 1066 if (!contextptr) |
1067 contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); | 1067 contextptr = llvm::ConstantPointerNull::get(getPtrToType(llvm::Type::Int8Ty)); |
1068 llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty)); | 1068 llargs[j] = DtoBitCast(contextptr, getPtrToType(llvm::Type::Int8Ty)); |
1069 ++j; | 1069 ++j; |
1070 ++argiter; | 1070 ++argiter; |
1090 { | 1090 { |
1091 Logger::println("doing d-style variadic arguments"); | 1091 Logger::println("doing d-style variadic arguments"); |
1092 | 1092 |
1093 size_t nimplicit = j; | 1093 size_t nimplicit = j; |
1094 | 1094 |
1095 std::vector<const llvm::Type*> vtypes; | 1095 std::vector<const LLType*> vtypes; |
1096 std::vector<llvm::Value*> vtypeinfos; | |
1097 | 1096 |
1098 // number of non variadic args | 1097 // number of non variadic args |
1099 int begin = tf->parameters->dim; | 1098 int begin = tf->parameters->dim; |
1100 Logger::println("num non vararg params = %d", begin); | 1099 Logger::println("num non vararg params = %d", begin); |
1101 | 1100 |
1106 Expression* argexp = (Expression*)arguments->data[i]; | 1105 Expression* argexp = (Expression*)arguments->data[i]; |
1107 vtypes.push_back(DtoType(argexp->type)); | 1106 vtypes.push_back(DtoType(argexp->type)); |
1108 } | 1107 } |
1109 const llvm::StructType* vtype = llvm::StructType::get(vtypes); | 1108 const llvm::StructType* vtype = llvm::StructType::get(vtypes); |
1110 Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; | 1109 Logger::cout() << "d-variadic argument struct type:\n" << *vtype << '\n'; |
1111 llvm::Value* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); | 1110 LLValue* mem = new llvm::AllocaInst(vtype,"_argptr_storage",p->topallocapoint()); |
1112 | 1111 |
1113 // store arguments in the struct | 1112 // store arguments in the struct |
1114 for (int i=begin,k=0; i<arguments->dim; i++,k++) | 1113 for (int i=begin,k=0; i<arguments->dim; i++,k++) |
1115 { | 1114 { |
1116 Expression* argexp = (Expression*)arguments->data[i]; | 1115 Expression* argexp = (Expression*)arguments->data[i]; |
1119 DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp")); | 1118 DtoVariadicArgument(argexp, DtoGEPi(mem,0,k,"tmp")); |
1120 } | 1119 } |
1121 | 1120 |
1122 // build type info array | 1121 // build type info array |
1123 assert(Type::typeinfo->ir.irStruct->constInit); | 1122 assert(Type::typeinfo->ir.irStruct->constInit); |
1124 const llvm::Type* typeinfotype = DtoType(Type::typeinfo->type); | 1123 const LLType* typeinfotype = DtoType(Type::typeinfo->type); |
1125 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); | 1124 const llvm::ArrayType* typeinfoarraytype = llvm::ArrayType::get(typeinfotype,vtype->getNumElements()); |
1126 | 1125 |
1127 llvm::Value* typeinfomem = new llvm::AllocaInst(typeinfoarraytype,"_arguments_storage",p->topallocapoint()); | 1126 llvm::GlobalVariable* typeinfomem = |
1127 new llvm::GlobalVariable(typeinfoarraytype, true, llvm::GlobalValue::InternalLinkage, NULL, "._arguments.storage", gIR->module); | |
1128 Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; | 1128 Logger::cout() << "_arguments storage: " << *typeinfomem << '\n'; |
1129 | |
1130 std::vector<LLConstant*> vtypeinfos; | |
1129 for (int i=begin,k=0; i<arguments->dim; i++,k++) | 1131 for (int i=begin,k=0; i<arguments->dim; i++,k++) |
1130 { | 1132 { |
1131 Expression* argexp = (Expression*)arguments->data[i]; | 1133 Expression* argexp = (Expression*)arguments->data[i]; |
1132 TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration(); | 1134 vtypeinfos.push_back(DtoTypeInfoOf(argexp->type)); |
1133 DtoForceDeclareDsymbol(tidecl); | 1135 } |
1134 assert(tidecl->ir.getIrValue()); | 1136 |
1135 vtypeinfos.push_back(tidecl->ir.getIrValue()); | 1137 // apply initializer |
1136 llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[k], typeinfotype, "tmp"); | 1138 LLConstant* tiinits = llvm::ConstantArray::get(typeinfoarraytype, vtypeinfos); |
1137 p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,k,"tmp")); | 1139 typeinfomem->setInitializer(tiinits); |
1138 } | |
1139 | 1140 |
1140 // put data in d-array | 1141 // put data in d-array |
1141 llvm::Value* typeinfoarrayparam = new llvm::AllocaInst(llfnty->getParamType(j)->getContainedType(0),"_arguments_array",p->topallocapoint()); | 1142 std::vector<LLConstant*> pinits; |
1142 p->ir->CreateStore(DtoConstSize_t(vtype->getNumElements()), DtoGEPi(typeinfoarrayparam,0,0,"tmp")); | 1143 pinits.push_back(DtoConstSize_t(vtype->getNumElements())); |
1143 llvm::Value* casttypeinfomem = p->ir->CreateBitCast(typeinfomem, getPtrToType(typeinfotype), "tmp"); | 1144 pinits.push_back(llvm::ConstantExpr::getBitCast(typeinfomem, getPtrToType(typeinfotype))); |
1144 p->ir->CreateStore(casttypeinfomem, DtoGEPi(typeinfoarrayparam,0,1,"tmp")); | 1145 const LLType* tiarrty = llfnty->getParamType(j)->getContainedType(0); |
1146 tiinits = llvm::ConstantStruct::get(pinits); | |
1147 LLValue* typeinfoarrayparam = new llvm::GlobalVariable(tiarrty, | |
1148 true, llvm::GlobalValue::InternalLinkage, tiinits, "._arguments.array", gIR->module); | |
1145 | 1149 |
1146 // specify arguments | 1150 // specify arguments |
1147 llargs[j] = typeinfoarrayparam;; | 1151 llargs[j] = typeinfoarrayparam;; |
1148 j++; | 1152 j++; |
1149 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); | 1153 llargs[j] = p->ir->CreateBitCast(mem, getPtrToType(llvm::Type::Int8Ty), "tmp"); |
1203 | 1207 |
1204 //Logger::cout() << "Calling: " << *funcval << '\n'; | 1208 //Logger::cout() << "Calling: " << *funcval << '\n'; |
1205 | 1209 |
1206 // call the function | 1210 // call the function |
1207 llvm::CallInst* call = llvm::CallInst::Create(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); | 1211 llvm::CallInst* call = llvm::CallInst::Create(funcval, llargs.begin(), llargs.end(), varname, p->scopebb()); |
1208 llvm::Value* retllval = (retinptr) ? llargs[0] : call; | 1212 LLValue* retllval = (retinptr) ? llargs[0] : call; |
1209 | 1213 |
1210 if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) { | 1214 if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) { |
1211 const llvm::Type* rettype = getPtrToType(DtoType(type)); | 1215 const LLType* rettype = getPtrToType(DtoType(type)); |
1212 if (retllval->getType() != rettype) { | 1216 if (retllval->getType() != rettype) { |
1213 Logger::println("llvmRunTimeHack==true - force casting return value"); | 1217 Logger::println("llvmRunTimeHack==true - force casting return value"); |
1214 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n'; | 1218 Logger::cout() << "from: " << *retllval->getType() << " to: " << *rettype << '\n'; |
1215 retllval = DtoBitCast(retllval, rettype); | 1219 retllval = DtoBitCast(retllval, rettype); |
1216 } | 1220 } |
1284 assert(vd->ir.getIrValue()); | 1288 assert(vd->ir.getIrValue()); |
1285 Type* t = DtoDType(type); | 1289 Type* t = DtoDType(type); |
1286 Type* tnext = DtoDType(t->next); | 1290 Type* tnext = DtoDType(t->next); |
1287 Type* vdtype = DtoDType(vd->type); | 1291 Type* vdtype = DtoDType(vd->type); |
1288 | 1292 |
1289 llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->ir.getIrValue(); | 1293 LLValue* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->ir.getIrValue(); |
1290 llvm::Value* varmem = 0; | 1294 LLValue* varmem = 0; |
1291 | 1295 |
1292 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { | 1296 if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) { |
1293 Logger::println("struct"); | 1297 Logger::println("struct"); |
1294 TypeStruct* vdt = (TypeStruct*)vdtype; | 1298 TypeStruct* vdt = (TypeStruct*)vdtype; |
1295 assert(vdt->sym); | 1299 assert(vdt->sym); |
1296 | 1300 |
1297 const llvm::Type* llt = DtoType(t); | 1301 const LLType* llt = DtoType(t); |
1298 if (offset == 0) { | 1302 if (offset == 0) { |
1299 varmem = p->ir->CreateBitCast(llvalue, llt, "tmp"); | 1303 varmem = p->ir->CreateBitCast(llvalue, llt, "tmp"); |
1300 } | 1304 } |
1301 else { | 1305 else { |
1302 std::vector<unsigned> dst; | 1306 std::vector<unsigned> dst; |
1307 Logger::println("sarray"); | 1311 Logger::println("sarray"); |
1308 | 1312 |
1309 assert(llvalue); | 1313 assert(llvalue); |
1310 //e->arg = llvalue; // TODO | 1314 //e->arg = llvalue; // TODO |
1311 | 1315 |
1312 const llvm::Type* llt = DtoType(t); | 1316 const LLType* llt = DtoType(t); |
1313 llvm::Value* off = 0; | 1317 LLValue* off = 0; |
1314 if (offset != 0) { | 1318 if (offset != 0) { |
1315 Logger::println("offset = %d\n", offset); | 1319 Logger::println("offset = %d\n", offset); |
1316 } | 1320 } |
1317 if (offset == 0) { | 1321 if (offset == 0) { |
1318 varmem = llvalue; | 1322 varmem = llvalue; |
1319 } | 1323 } |
1320 else { | 1324 else { |
1321 const llvm::Type* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0); | 1325 const LLType* elemtype = llvalue->getType()->getContainedType(0)->getContainedType(0); |
1322 size_t elemsz = getABITypeSize(elemtype); | 1326 size_t elemsz = getABITypeSize(elemtype); |
1323 varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp"); | 1327 varmem = DtoGEPi(llvalue, 0, offset / elemsz, "tmp"); |
1324 } | 1328 } |
1325 } | 1329 } |
1326 else if (offset == 0) { | 1330 else if (offset == 0) { |
1327 Logger::println("normal symoff"); | 1331 Logger::println("normal symoff"); |
1328 | 1332 |
1329 assert(llvalue); | 1333 assert(llvalue); |
1330 varmem = llvalue; | 1334 varmem = llvalue; |
1331 | 1335 |
1332 const llvm::Type* llt = DtoType(t); | 1336 const LLType* llt = DtoType(t); |
1333 if (llvalue->getType() != llt) { | 1337 if (llvalue->getType() != llt) { |
1334 varmem = p->ir->CreateBitCast(varmem, llt, "tmp"); | 1338 varmem = p->ir->CreateBitCast(varmem, llt, "tmp"); |
1335 } | 1339 } |
1336 } | 1340 } |
1337 else { | 1341 else { |
1384 Logger::println("lval PtrExp"); | 1388 Logger::println("lval PtrExp"); |
1385 return new DVarValue(type, a->getRVal(), true); | 1389 return new DVarValue(type, a->getRVal(), true); |
1386 } | 1390 } |
1387 | 1391 |
1388 // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! | 1392 // this should be deterministic but right now lvalue casts don't propagate lvalueness !?! |
1389 llvm::Value* lv = a->getRVal(); | 1393 LLValue* lv = a->getRVal(); |
1390 llvm::Value* v = lv; | 1394 LLValue* v = lv; |
1391 if (DtoCanLoad(v)) | 1395 if (DtoCanLoad(v)) |
1392 v = DtoLoad(v); | 1396 v = DtoLoad(v); |
1393 return new DLRValue(e1->type, lv, type, v); | 1397 return new DLRValue(e1->type, lv, type, v); |
1394 } | 1398 } |
1395 | 1399 |
1407 | 1411 |
1408 //Logger::println("e1type=%s", e1type->toChars()); | 1412 //Logger::println("e1type=%s", e1type->toChars()); |
1409 //Logger::cout() << *DtoType(e1type) << '\n'; | 1413 //Logger::cout() << *DtoType(e1type) << '\n'; |
1410 | 1414 |
1411 if (VarDeclaration* vd = var->isVarDeclaration()) { | 1415 if (VarDeclaration* vd = var->isVarDeclaration()) { |
1412 llvm::Value* arrptr; | 1416 LLValue* arrptr; |
1413 if (e1type->ty == Tpointer) { | 1417 if (e1type->ty == Tpointer) { |
1414 assert(e1type->next->ty == Tstruct); | 1418 assert(e1type->next->ty == Tstruct); |
1415 TypeStruct* ts = (TypeStruct*)e1type->next; | 1419 TypeStruct* ts = (TypeStruct*)e1type->next; |
1416 Logger::println("Struct member offset:%d", vd->offset); | 1420 Logger::println("Struct member offset:%d", vd->offset); |
1417 | 1421 |
1418 llvm::Value* src = l->getRVal(); | 1422 LLValue* src = l->getRVal(); |
1419 | 1423 |
1420 std::vector<unsigned> vdoffsets; | 1424 std::vector<unsigned> vdoffsets; |
1421 arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); | 1425 arrptr = DtoIndexStruct(src, ts->sym, vd->type, vd->offset, vdoffsets); |
1422 } | 1426 } |
1423 else if (e1type->ty == Tclass) { | 1427 else if (e1type->ty == Tclass) { |
1424 TypeClass* tc = (TypeClass*)e1type; | 1428 TypeClass* tc = (TypeClass*)e1type; |
1425 Logger::println("Class member offset: %d", vd->offset); | 1429 Logger::println("Class member offset: %d", vd->offset); |
1426 | 1430 |
1427 llvm::Value* src = l->getRVal(); | 1431 LLValue* src = l->getRVal(); |
1428 | 1432 |
1429 std::vector<unsigned> vdoffsets; | 1433 std::vector<unsigned> vdoffsets; |
1430 arrptr = DtoIndexClass(src, tc->sym, vd->type, vd->offset, vdoffsets); | 1434 arrptr = DtoIndexClass(src, tc->sym, vd->type, vd->offset, vdoffsets); |
1431 | 1435 |
1432 /*std::vector<unsigned> vdoffsets(1,0); | 1436 /*std::vector<unsigned> vdoffsets(1,0); |
1433 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); | 1437 tc->sym->offsetToIndex(vd->type, vd->offset, vdoffsets); |
1434 | 1438 |
1435 llvm::Value* src = l->getRVal(); | 1439 LLValue* src = l->getRVal(); |
1436 | 1440 |
1437 Logger::println("indices:"); | 1441 Logger::println("indices:"); |
1438 for (size_t i=0; i<vdoffsets.size(); ++i) | 1442 for (size_t i=0; i<vdoffsets.size(); ++i) |
1439 Logger::println("%d", vdoffsets[i]); | 1443 Logger::println("%d", vdoffsets[i]); |
1440 | 1444 |
1450 } | 1454 } |
1451 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) | 1455 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) |
1452 { | 1456 { |
1453 DtoResolveDsymbol(fdecl); | 1457 DtoResolveDsymbol(fdecl); |
1454 | 1458 |
1455 llvm::Value* funcval; | 1459 LLValue* funcval; |
1456 llvm::Value* vthis2 = 0; | 1460 LLValue* vthis2 = 0; |
1457 if (e1type->ty == Tclass) { | 1461 if (e1type->ty == Tclass) { |
1458 TypeClass* tc = (TypeClass*)e1type; | 1462 TypeClass* tc = (TypeClass*)e1type; |
1459 if (tc->sym->isInterfaceDeclaration()) { | 1463 if (tc->sym->isInterfaceDeclaration()) { |
1460 vthis2 = DtoCastInterfaceToObject(l, NULL)->getRVal(); | 1464 vthis2 = DtoCastInterfaceToObject(l, NULL)->getRVal(); |
1461 } | 1465 } |
1462 } | 1466 } |
1463 llvm::Value* vthis = l->getRVal(); | 1467 LLValue* vthis = l->getRVal(); |
1464 if (!vthis2) vthis2 = vthis; | 1468 if (!vthis2) vthis2 = vthis; |
1465 //unsigned cc = (unsigned)-1; | 1469 //unsigned cc = (unsigned)-1; |
1466 | 1470 |
1467 // super call | 1471 // super call |
1468 if (e1->op == TOKsuper) { | 1472 if (e1->op == TOKsuper) { |
1473 // normal virtual call | 1477 // normal virtual call |
1474 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { | 1478 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { |
1475 assert(fdecl->vtblIndex > 0); | 1479 assert(fdecl->vtblIndex > 0); |
1476 assert(e1type->ty == Tclass); | 1480 assert(e1type->ty == Tclass); |
1477 | 1481 |
1478 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1482 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1479 llvm::Value* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); | 1483 LLValue* vtblidx = llvm::ConstantInt::get(llvm::Type::Int32Ty, (size_t)fdecl->vtblIndex, false); |
1480 //Logger::cout() << "vthis: " << *vthis << '\n'; | 1484 //Logger::cout() << "vthis: " << *vthis << '\n'; |
1481 funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb()); | 1485 funcval = DtoGEP(vthis, zero, zero, "tmp", p->scopebb()); |
1482 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1486 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
1483 funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); | 1487 funcval = DtoGEP(funcval, zero, vtblidx, toChars(), p->scopebb()); |
1484 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); | 1488 funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb()); |
1512 { | 1516 { |
1513 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); | 1517 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars()); |
1514 LOG_SCOPE; | 1518 LOG_SCOPE; |
1515 | 1519 |
1516 if (VarDeclaration* vd = var->isVarDeclaration()) { | 1520 if (VarDeclaration* vd = var->isVarDeclaration()) { |
1517 llvm::Value* v; | 1521 LLValue* v; |
1518 v = p->func()->decl->ir.irFunc->thisVar; | 1522 v = p->func()->decl->ir.irFunc->thisVar; |
1519 if (llvm::isa<llvm::AllocaInst>(v)) | 1523 if (llvm::isa<llvm::AllocaInst>(v)) |
1520 v = new llvm::LoadInst(v, "tmp", p->scopebb()); | 1524 v = new llvm::LoadInst(v, "tmp", p->scopebb()); |
1521 const llvm::Type* t = DtoType(type); | 1525 const LLType* t = DtoType(type); |
1522 if (v->getType() != t) | 1526 if (v->getType() != t) |
1523 v = DtoBitCast(v, t, "tmp"); | 1527 v = DtoBitCast(v, t, "tmp"); |
1524 return new DThisValue(vd, v); | 1528 return new DThisValue(vd, v); |
1525 } | 1529 } |
1526 | 1530 |
1541 | 1545 |
1542 p->arrays.push_back(l); // if $ is used it must be an array so this is fine. | 1546 p->arrays.push_back(l); // if $ is used it must be an array so this is fine. |
1543 DValue* r = e2->toElem(p); | 1547 DValue* r = e2->toElem(p); |
1544 p->arrays.pop_back(); | 1548 p->arrays.pop_back(); |
1545 | 1549 |
1546 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1550 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1547 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1551 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1548 | 1552 |
1549 llvm::Value* arrptr = 0; | 1553 LLValue* arrptr = 0; |
1550 if (e1type->ty == Tpointer) { | 1554 if (e1type->ty == Tpointer) { |
1551 arrptr = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); | 1555 arrptr = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb()); |
1552 } | 1556 } |
1553 else if (e1type->ty == Tsarray) { | 1557 else if (e1type->ty == Tsarray) { |
1554 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb()); | 1558 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal(),"tmp",p->scopebb()); |
1577 | 1581 |
1578 Type* t = DtoDType(type); | 1582 Type* t = DtoDType(type); |
1579 Type* e1type = DtoDType(e1->type); | 1583 Type* e1type = DtoDType(e1->type); |
1580 | 1584 |
1581 DValue* v = e1->toElem(p); | 1585 DValue* v = e1->toElem(p); |
1582 llvm::Value* vmem = v->getRVal(); | 1586 LLValue* vmem = v->getRVal(); |
1583 assert(vmem); | 1587 assert(vmem); |
1584 | 1588 |
1585 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1589 LLValue* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1586 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1590 LLValue* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1587 | 1591 |
1588 llvm::Value* emem = 0; | 1592 LLValue* emem = 0; |
1589 llvm::Value* earg = 0; | 1593 LLValue* earg = 0; |
1590 | 1594 |
1591 // partial slice | 1595 // partial slice |
1592 if (lwr) | 1596 if (lwr) |
1593 { | 1597 { |
1594 assert(upr); | 1598 assert(upr); |
1602 | 1606 |
1603 if (e1type->ty == Tpointer) { | 1607 if (e1type->ty == Tpointer) { |
1604 emem = v->getRVal(); | 1608 emem = v->getRVal(); |
1605 } | 1609 } |
1606 else if (e1type->ty == Tarray) { | 1610 else if (e1type->ty == Tarray) { |
1607 llvm::Value* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); | 1611 LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); |
1608 emem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 1612 emem = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
1609 } | 1613 } |
1610 else if (e1type->ty == Tsarray) { | 1614 else if (e1type->ty == Tsarray) { |
1611 emem = DtoGEP(vmem,zero,zero,"tmp",p->scopebb()); | 1615 emem = DtoGEP(vmem,zero,zero,"tmp",p->scopebb()); |
1612 } | 1616 } |
1619 } | 1623 } |
1620 } | 1624 } |
1621 else | 1625 else |
1622 { | 1626 { |
1623 if (e1type->ty == Tarray) { | 1627 if (e1type->ty == Tarray) { |
1624 llvm::Value* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); | 1628 LLValue* tmp = DtoGEP(vmem,zero,one,"tmp",p->scopebb()); |
1625 tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); | 1629 tmp = new llvm::LoadInst(tmp,"tmp",p->scopebb()); |
1626 emem = llvm::GetElementPtrInst::Create(tmp,lo->getRVal(),"tmp",p->scopebb()); | 1630 emem = llvm::GetElementPtrInst::Create(tmp,lo->getRVal(),"tmp",p->scopebb()); |
1627 } | 1631 } |
1628 else if (e1type->ty == Tsarray) { | 1632 else if (e1type->ty == Tsarray) { |
1629 emem = DtoGEP(vmem,zero,lo->getRVal(),"tmp",p->scopebb()); | 1633 emem = DtoGEP(vmem,zero,lo->getRVal(),"tmp",p->scopebb()); |
1646 if (lwr_is_zero) { | 1650 if (lwr_is_zero) { |
1647 earg = cv->c; | 1651 earg = cv->c; |
1648 } | 1652 } |
1649 else { | 1653 else { |
1650 if (lo->isConst()) { | 1654 if (lo->isConst()) { |
1651 llvm::Constant* clo = llvm::cast<llvm::Constant>(lo->getRVal()); | 1655 LLConstant* clo = llvm::cast<llvm::Constant>(lo->getRVal()); |
1652 llvm::Constant* cup = llvm::cast<llvm::Constant>(cv->c); | 1656 LLConstant* cup = llvm::cast<llvm::Constant>(cv->c); |
1653 earg = llvm::ConstantExpr::getSub(cup, clo); | 1657 earg = llvm::ConstantExpr::getSub(cup, clo); |
1654 } | 1658 } |
1655 else { | 1659 else { |
1656 earg = llvm::BinaryOperator::createSub(cv->c, lo->getRVal(), "tmp", p->scopebb()); | 1660 earg = llvm::BinaryOperator::createSub(cv->c, lo->getRVal(), "tmp", p->scopebb()); |
1657 } | 1661 } |
1691 | 1695 |
1692 Type* t = DtoDType(e1->type); | 1696 Type* t = DtoDType(e1->type); |
1693 Type* e2t = DtoDType(e2->type); | 1697 Type* e2t = DtoDType(e2->type); |
1694 assert(DtoType(t) == DtoType(e2t)); | 1698 assert(DtoType(t) == DtoType(e2t)); |
1695 | 1699 |
1696 llvm::Value* eval = 0; | 1700 LLValue* eval = 0; |
1697 | 1701 |
1698 if (t->isintegral() || t->ty == Tpointer) | 1702 if (t->isintegral() || t->ty == Tpointer) |
1699 { | 1703 { |
1700 llvm::ICmpInst::Predicate cmpop; | 1704 llvm::ICmpInst::Predicate cmpop; |
1701 bool skip = false; | 1705 bool skip = false; |
1735 default: | 1739 default: |
1736 assert(0); | 1740 assert(0); |
1737 } | 1741 } |
1738 if (!skip) | 1742 if (!skip) |
1739 { | 1743 { |
1740 llvm::Value* a = l->getRVal(); | 1744 LLValue* a = l->getRVal(); |
1741 llvm::Value* b = r->getRVal(); | 1745 LLValue* b = r->getRVal(); |
1742 Logger::cout() << "type 1: " << *a << '\n'; | 1746 Logger::cout() << "type 1: " << *a << '\n'; |
1743 Logger::cout() << "type 2: " << *b << '\n'; | 1747 Logger::cout() << "type 2: " << *b << '\n'; |
1744 eval = new llvm::ICmpInst(cmpop, a, b, "tmp", p->scopebb()); | 1748 eval = new llvm::ICmpInst(cmpop, a, b, "tmp", p->scopebb()); |
1745 } | 1749 } |
1746 } | 1750 } |
1804 | 1808 |
1805 Type* t = DtoDType(e1->type); | 1809 Type* t = DtoDType(e1->type); |
1806 Type* e2t = DtoDType(e2->type); | 1810 Type* e2t = DtoDType(e2->type); |
1807 //assert(t == e2t); | 1811 //assert(t == e2t); |
1808 | 1812 |
1809 llvm::Value* eval = 0; | 1813 LLValue* eval = 0; |
1810 | 1814 |
1811 if (t->isintegral() || t->ty == Tpointer) | 1815 if (t->isintegral() || t->ty == Tpointer) |
1812 { | 1816 { |
1813 Logger::println("integral or pointer"); | 1817 Logger::println("integral or pointer"); |
1814 llvm::ICmpInst::Predicate cmpop; | 1818 llvm::ICmpInst::Predicate cmpop; |
1821 cmpop = llvm::ICmpInst::ICMP_NE; | 1825 cmpop = llvm::ICmpInst::ICMP_NE; |
1822 break; | 1826 break; |
1823 default: | 1827 default: |
1824 assert(0); | 1828 assert(0); |
1825 } | 1829 } |
1826 llvm::Value* lv = l->getRVal(); | 1830 LLValue* lv = l->getRVal(); |
1827 llvm::Value* rv = r->getRVal(); | 1831 LLValue* rv = r->getRVal(); |
1828 if (rv->getType() != lv->getType()) { | 1832 if (rv->getType() != lv->getType()) { |
1829 rv = DtoBitCast(rv, lv->getType()); | 1833 rv = DtoBitCast(rv, lv->getType()); |
1830 } | 1834 } |
1831 eval = new llvm::ICmpInst(cmpop, lv, rv, "tmp", p->scopebb()); | 1835 eval = new llvm::ICmpInst(cmpop, lv, rv, "tmp", p->scopebb()); |
1832 } | 1836 } |
1878 LOG_SCOPE; | 1882 LOG_SCOPE; |
1879 | 1883 |
1880 DValue* l = e1->toElem(p); | 1884 DValue* l = e1->toElem(p); |
1881 DValue* r = e2->toElem(p); | 1885 DValue* r = e2->toElem(p); |
1882 | 1886 |
1883 llvm::Value* val = l->getRVal(); | 1887 LLValue* val = l->getRVal(); |
1884 llvm::Value* post = 0; | 1888 LLValue* post = 0; |
1885 | 1889 |
1886 Type* e1type = DtoDType(e1->type); | 1890 Type* e1type = DtoDType(e1->type); |
1887 Type* e2type = DtoDType(e2->type); | 1891 Type* e2type = DtoDType(e2->type); |
1888 | 1892 |
1889 if (e1type->isintegral()) | 1893 if (e1type->isintegral()) |
1890 { | 1894 { |
1891 assert(e2type->isintegral()); | 1895 assert(e2type->isintegral()); |
1892 llvm::Value* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned()); | 1896 LLValue* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned()); |
1893 if (op == TOKplusplus) { | 1897 if (op == TOKplusplus) { |
1894 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); | 1898 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); |
1895 } | 1899 } |
1896 else if (op == TOKminusminus) { | 1900 else if (op == TOKminusminus) { |
1897 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); | 1901 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); |
1898 } | 1902 } |
1899 } | 1903 } |
1900 else if (e1type->ty == Tpointer) | 1904 else if (e1type->ty == Tpointer) |
1901 { | 1905 { |
1902 assert(e2type->isintegral()); | 1906 assert(e2type->isintegral()); |
1903 llvm::Constant* minusone = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)-1,true); | 1907 LLConstant* minusone = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)-1,true); |
1904 llvm::Constant* plusone = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)1,false); | 1908 LLConstant* plusone = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)1,false); |
1905 llvm::Constant* whichone = (op == TOKplusplus) ? plusone : minusone; | 1909 LLConstant* whichone = (op == TOKplusplus) ? plusone : minusone; |
1906 post = llvm::GetElementPtrInst::Create(val, whichone, "tmp", p->scopebb()); | 1910 post = llvm::GetElementPtrInst::Create(val, whichone, "tmp", p->scopebb()); |
1907 } | 1911 } |
1908 else if (e1type->isfloating()) | 1912 else if (e1type->isfloating()) |
1909 { | 1913 { |
1910 assert(e2type->isfloating()); | 1914 assert(e2type->isfloating()); |
1911 llvm::Value* one = DtoConstFP(e1type, 1.0); | 1915 LLValue* one = DtoConstFP(e1type, 1.0); |
1912 if (op == TOKplusplus) { | 1916 if (op == TOKplusplus) { |
1913 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); | 1917 post = llvm::BinaryOperator::createAdd(val,one,"tmp",p->scopebb()); |
1914 } | 1918 } |
1915 else if (op == TOKminusminus) { | 1919 else if (op == TOKminusminus) { |
1916 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); | 1920 post = llvm::BinaryOperator::createSub(val,one,"tmp",p->scopebb()); |
1959 assert(0); | 1963 assert(0); |
1960 } | 1964 } |
1961 // new struct | 1965 // new struct |
1962 else if (ntype->ty == Tstruct) | 1966 else if (ntype->ty == Tstruct) |
1963 { | 1967 { |
1968 Logger::println("new struct on heap: %s\n", newtype->toChars()); | |
1964 // allocate | 1969 // allocate |
1965 llvm::Value* mem = DtoNew(newtype); | 1970 LLValue* mem = DtoNew(newtype); |
1966 // init | 1971 // init |
1967 TypeStruct* ts = (TypeStruct*)ntype; | 1972 TypeStruct* ts = (TypeStruct*)ntype; |
1968 if (ts->isZeroInit()) { | 1973 if (ts->isZeroInit()) { |
1969 DtoStructZeroInit(mem); | 1974 DtoStructZeroInit(mem); |
1970 } | 1975 } |
1976 } | 1981 } |
1977 // new basic type | 1982 // new basic type |
1978 else | 1983 else |
1979 { | 1984 { |
1980 // allocate | 1985 // allocate |
1981 llvm::Value* mem = DtoNew(newtype); | 1986 LLValue* mem = DtoNew(newtype); |
1982 DVarValue tmpvar(newtype, mem, true); | 1987 DVarValue tmpvar(newtype, mem, true); |
1983 | 1988 |
1984 // default initialize | 1989 // default initialize |
1985 Expression* exp = newtype->defaultInit(loc); | 1990 Expression* exp = newtype->defaultInit(loc); |
1986 DValue* iv = exp->toElem(gIR); | 1991 DValue* iv = exp->toElem(gIR); |
2004 Type* et = DtoDType(e1->type); | 2009 Type* et = DtoDType(e1->type); |
2005 | 2010 |
2006 // simple pointer | 2011 // simple pointer |
2007 if (et->ty == Tpointer) | 2012 if (et->ty == Tpointer) |
2008 { | 2013 { |
2009 llvm::Value* rval = dval->getRVal(); | 2014 LLValue* rval = dval->getRVal(); |
2010 DtoDeleteMemory(rval); | 2015 DtoDeleteMemory(rval); |
2011 if (dval->isVar() && dval->isVar()->lval) | 2016 if (dval->isVar() && dval->isVar()->lval) |
2012 DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal()); | 2017 DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal()); |
2013 } | 2018 } |
2014 // class | 2019 // class |
2028 onstack = true; | 2033 onstack = true; |
2029 } | 2034 } |
2030 } | 2035 } |
2031 } | 2036 } |
2032 if (!onstack) { | 2037 if (!onstack) { |
2033 llvm::Value* rval = dval->getRVal(); | 2038 LLValue* rval = dval->getRVal(); |
2034 DtoDeleteClass(rval); | 2039 DtoDeleteClass(rval); |
2035 } | 2040 } |
2036 if (!dval->isThis() && dval->isVar() && dval->isVar()->lval) { | 2041 if (!dval->isThis() && dval->isVar() && dval->isVar()->lval) { |
2037 llvm::Value* lval = dval->getLVal(); | 2042 LLValue* lval = dval->getLVal(); |
2038 DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval); | 2043 DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval); |
2039 } | 2044 } |
2040 } | 2045 } |
2041 // dyn array | 2046 // dyn array |
2042 else if (et->ty == Tarray) | 2047 else if (et->ty == Tarray) |
2089 llvm::BasicBlock* oldend = p->scopeend(); | 2094 llvm::BasicBlock* oldend = p->scopeend(); |
2090 llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend); | 2095 llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend); |
2091 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend); | 2096 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend); |
2092 | 2097 |
2093 // test condition | 2098 // test condition |
2094 llvm::Value* condval = cond->getRVal(); | 2099 LLValue* condval = cond->getRVal(); |
2095 condval = DtoBoolean(condval); | 2100 condval = DtoBoolean(condval); |
2096 | 2101 |
2097 // branch | 2102 // branch |
2098 llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb()); | 2103 llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb()); |
2099 | 2104 |
2118 Logger::print("NotExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2123 Logger::print("NotExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2119 LOG_SCOPE; | 2124 LOG_SCOPE; |
2120 | 2125 |
2121 DValue* u = e1->toElem(p); | 2126 DValue* u = e1->toElem(p); |
2122 | 2127 |
2123 llvm::Value* b = DtoBoolean(u->getRVal()); | 2128 LLValue* b = DtoBoolean(u->getRVal()); |
2124 | 2129 |
2125 llvm::Constant* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true); | 2130 LLConstant* zero = llvm::ConstantInt::get(llvm::Type::Int1Ty, 0, true); |
2126 b = p->ir->CreateICmpEQ(b,zero); | 2131 b = p->ir->CreateICmpEQ(b,zero); |
2127 | 2132 |
2128 return new DImValue(type, b); | 2133 return new DImValue(type, b); |
2129 } | 2134 } |
2130 | 2135 |
2134 { | 2139 { |
2135 Logger::print("AndAndExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2140 Logger::print("AndAndExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2136 LOG_SCOPE; | 2141 LOG_SCOPE; |
2137 | 2142 |
2138 // allocate a temporary for the final result. failed to come up with a better way :/ | 2143 // allocate a temporary for the final result. failed to come up with a better way :/ |
2139 llvm::Value* resval = 0; | 2144 LLValue* resval = 0; |
2140 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | 2145 llvm::BasicBlock* entryblock = &p->topfunc()->front(); |
2141 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"andandtmp",p->topallocapoint()); | 2146 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"andandtmp",p->topallocapoint()); |
2142 | 2147 |
2143 DValue* u = e1->toElem(p); | 2148 DValue* u = e1->toElem(p); |
2144 | 2149 |
2145 llvm::BasicBlock* oldend = p->scopeend(); | 2150 llvm::BasicBlock* oldend = p->scopeend(); |
2146 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); | 2151 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend); |
2147 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); | 2152 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend); |
2148 | 2153 |
2149 llvm::Value* ubool = DtoBoolean(u->getRVal()); | 2154 LLValue* ubool = DtoBoolean(u->getRVal()); |
2150 new llvm::StoreInst(ubool,resval,p->scopebb()); | 2155 new llvm::StoreInst(ubool,resval,p->scopebb()); |
2151 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); | 2156 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb()); |
2152 | 2157 |
2153 p->scope() = IRScope(andand, andandend); | 2158 p->scope() = IRScope(andand, andandend); |
2154 DValue* v = e2->toElem(p); | 2159 DValue* v = e2->toElem(p); |
2155 | 2160 |
2156 llvm::Value* vbool = DtoBoolean(v->getRVal()); | 2161 LLValue* vbool = DtoBoolean(v->getRVal()); |
2157 llvm::Value* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); | 2162 LLValue* uandvbool = llvm::BinaryOperator::create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb()); |
2158 new llvm::StoreInst(uandvbool,resval,p->scopebb()); | 2163 new llvm::StoreInst(uandvbool,resval,p->scopebb()); |
2159 llvm::BranchInst::Create(andandend,p->scopebb()); | 2164 llvm::BranchInst::Create(andandend,p->scopebb()); |
2160 | 2165 |
2161 p->scope() = IRScope(andandend, oldend); | 2166 p->scope() = IRScope(andandend, oldend); |
2162 | 2167 |
2170 { | 2175 { |
2171 Logger::print("OrOrExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2176 Logger::print("OrOrExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2172 LOG_SCOPE; | 2177 LOG_SCOPE; |
2173 | 2178 |
2174 // allocate a temporary for the final result. failed to come up with a better way :/ | 2179 // allocate a temporary for the final result. failed to come up with a better way :/ |
2175 llvm::Value* resval = 0; | 2180 LLValue* resval = 0; |
2176 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | 2181 llvm::BasicBlock* entryblock = &p->topfunc()->front(); |
2177 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"orortmp",p->topallocapoint()); | 2182 resval = new llvm::AllocaInst(llvm::Type::Int1Ty,"orortmp",p->topallocapoint()); |
2178 | 2183 |
2179 DValue* u = e1->toElem(p); | 2184 DValue* u = e1->toElem(p); |
2180 | 2185 |
2181 llvm::BasicBlock* oldend = p->scopeend(); | 2186 llvm::BasicBlock* oldend = p->scopeend(); |
2182 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); | 2187 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend); |
2183 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); | 2188 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend); |
2184 | 2189 |
2185 llvm::Value* ubool = DtoBoolean(u->getRVal()); | 2190 LLValue* ubool = DtoBoolean(u->getRVal()); |
2186 new llvm::StoreInst(ubool,resval,p->scopebb()); | 2191 new llvm::StoreInst(ubool,resval,p->scopebb()); |
2187 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); | 2192 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb()); |
2188 | 2193 |
2189 p->scope() = IRScope(oror, ororend); | 2194 p->scope() = IRScope(oror, ororend); |
2190 DValue* v = e2->toElem(p); | 2195 DValue* v = e2->toElem(p); |
2191 | 2196 |
2192 llvm::Value* vbool = DtoBoolean(v->getRVal()); | 2197 LLValue* vbool = DtoBoolean(v->getRVal()); |
2193 new llvm::StoreInst(vbool,resval,p->scopebb()); | 2198 new llvm::StoreInst(vbool,resval,p->scopebb()); |
2194 llvm::BranchInst::Create(ororend,p->scopebb()); | 2199 llvm::BranchInst::Create(ororend,p->scopebb()); |
2195 | 2200 |
2196 p->scope() = IRScope(ororend, oldend); | 2201 p->scope() = IRScope(ororend, oldend); |
2197 | 2202 |
2206 { \ | 2211 { \ |
2207 Logger::print("%sExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ | 2212 Logger::print("%sExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \ |
2208 LOG_SCOPE; \ | 2213 LOG_SCOPE; \ |
2209 DValue* u = e1->toElem(p); \ | 2214 DValue* u = e1->toElem(p); \ |
2210 DValue* v = e2->toElem(p); \ | 2215 DValue* v = e2->toElem(p); \ |
2211 llvm::Value* x = llvm::BinaryOperator::create(llvm::Instruction::Y, u->getRVal(), v->getRVal(), "tmp", p->scopebb()); \ | 2216 LLValue* x = llvm::BinaryOperator::create(llvm::Instruction::Y, u->getRVal(), v->getRVal(), "tmp", p->scopebb()); \ |
2212 return new DImValue(type, x); \ | 2217 return new DImValue(type, x); \ |
2213 } \ | 2218 } \ |
2214 \ | 2219 \ |
2215 DValue* X##AssignExp::toElem(IRState* p) \ | 2220 DValue* X##AssignExp::toElem(IRState* p) \ |
2216 { \ | 2221 { \ |
2219 p->exps.push_back(IRExp(e1,e2,NULL)); \ | 2224 p->exps.push_back(IRExp(e1,e2,NULL)); \ |
2220 DValue* u = e1->toElem(p); \ | 2225 DValue* u = e1->toElem(p); \ |
2221 p->topexp()->v = u; \ | 2226 p->topexp()->v = u; \ |
2222 DValue* v = e2->toElem(p); \ | 2227 DValue* v = e2->toElem(p); \ |
2223 p->exps.pop_back(); \ | 2228 p->exps.pop_back(); \ |
2224 llvm::Value* uval = u->getRVal(); \ | 2229 LLValue* uval = u->getRVal(); \ |
2225 llvm::Value* vval = v->getRVal(); \ | 2230 LLValue* vval = v->getRVal(); \ |
2226 llvm::Value* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ | 2231 LLValue* tmp = llvm::BinaryOperator::create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \ |
2227 new llvm::StoreInst(DtoPointedType(u->getLVal(), tmp), u->getLVal(), p->scopebb()); \ | 2232 new llvm::StoreInst(DtoPointedType(u->getLVal(), tmp), u->getLVal(), p->scopebb()); \ |
2228 return u; \ | 2233 return u; \ |
2229 } | 2234 } |
2230 | 2235 |
2231 BinBitExp(And,And); | 2236 BinBitExp(And,And); |
2255 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2260 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2256 LOG_SCOPE; | 2261 LOG_SCOPE; |
2257 | 2262 |
2258 const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty); | 2263 const llvm::PointerType* int8ptrty = getPtrToType(llvm::Type::Int8Ty); |
2259 | 2264 |
2260 llvm::Value* lval; | 2265 LLValue* lval; |
2261 bool inplace = false; | 2266 bool inplace = false; |
2262 if (p->topexp() && p->topexp()->e2 == this) { | 2267 if (p->topexp() && p->topexp()->e2 == this) { |
2263 assert(p->topexp()->v); | 2268 assert(p->topexp()->v); |
2264 lval = p->topexp()->v->getLVal(); | 2269 lval = p->topexp()->v->getLVal(); |
2265 inplace = true; | 2270 inplace = true; |
2267 else { | 2272 else { |
2268 lval = new llvm::AllocaInst(DtoType(type), "tmpdelegate", p->topallocapoint()); | 2273 lval = new llvm::AllocaInst(DtoType(type), "tmpdelegate", p->topallocapoint()); |
2269 } | 2274 } |
2270 | 2275 |
2271 DValue* u = e1->toElem(p); | 2276 DValue* u = e1->toElem(p); |
2272 llvm::Value* uval; | 2277 LLValue* uval; |
2273 if (DFuncValue* f = u->isFunc()) { | 2278 if (DFuncValue* f = u->isFunc()) { |
2274 //assert(f->vthis); | 2279 //assert(f->vthis); |
2275 //uval = f->vthis; | 2280 //uval = f->vthis; |
2276 llvm::Value* nestvar = p->func()->decl->ir.irFunc->nestedVar; | 2281 LLValue* nestvar = p->func()->decl->ir.irFunc->nestedVar; |
2277 if (nestvar) | 2282 if (nestvar) |
2278 uval = nestvar; | 2283 uval = nestvar; |
2279 else | 2284 else |
2280 uval = llvm::ConstantPointerNull::get(int8ptrty); | 2285 uval = llvm::ConstantPointerNull::get(int8ptrty); |
2281 } | 2286 } |
2293 uval = src->getRVal(); | 2298 uval = src->getRVal(); |
2294 } | 2299 } |
2295 | 2300 |
2296 Logger::cout() << "context = " << *uval << '\n'; | 2301 Logger::cout() << "context = " << *uval << '\n'; |
2297 | 2302 |
2298 llvm::Value* context = DtoGEPi(lval,0,0,"tmp"); | 2303 LLValue* context = DtoGEPi(lval,0,0,"tmp"); |
2299 llvm::Value* castcontext = DtoBitCast(uval, int8ptrty); | 2304 LLValue* castcontext = DtoBitCast(uval, int8ptrty); |
2300 DtoStore(castcontext, context); | 2305 DtoStore(castcontext, context); |
2301 | 2306 |
2302 llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp"); | 2307 LLValue* fptr = DtoGEPi(lval,0,1,"tmp"); |
2303 | 2308 |
2304 Logger::println("func: '%s'", func->toPrettyChars()); | 2309 Logger::println("func: '%s'", func->toPrettyChars()); |
2305 | 2310 |
2306 llvm::Value* castfptr; | 2311 LLValue* castfptr; |
2307 if (func->isVirtual()) | 2312 if (func->isVirtual()) |
2308 castfptr = DtoVirtualFunctionPointer(u, func); | 2313 castfptr = DtoVirtualFunctionPointer(u, func); |
2309 else if (func->isAbstract()) | 2314 else if (func->isAbstract()) |
2310 assert(0 && "TODO delegate to abstract method"); | 2315 assert(0 && "TODO delegate to abstract method"); |
2311 else if (func->toParent()->isInterfaceDeclaration()) | 2316 else if (func->toParent()->isInterfaceDeclaration()) |
2330 LOG_SCOPE; | 2335 LOG_SCOPE; |
2331 | 2336 |
2332 DValue* u = e1->toElem(p); | 2337 DValue* u = e1->toElem(p); |
2333 DValue* v = e2->toElem(p); | 2338 DValue* v = e2->toElem(p); |
2334 | 2339 |
2335 llvm::Value* l = u->getRVal(); | 2340 LLValue* l = u->getRVal(); |
2336 llvm::Value* r = v->getRVal(); | 2341 LLValue* r = v->getRVal(); |
2337 | 2342 |
2338 Type* t1 = DtoDType(e1->type); | 2343 Type* t1 = DtoDType(e1->type); |
2339 | 2344 |
2340 llvm::Value* eval = 0; | 2345 LLValue* eval = 0; |
2341 | 2346 |
2342 if (t1->ty == Tarray) { | 2347 if (t1->ty == Tarray) { |
2343 if (v->isNull()) { | 2348 if (v->isNull()) { |
2344 r = NULL; | 2349 r = NULL; |
2345 } | 2350 } |
2400 { | 2405 { |
2401 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2406 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2402 LOG_SCOPE; | 2407 LOG_SCOPE; |
2403 | 2408 |
2404 Type* dtype = DtoDType(type); | 2409 Type* dtype = DtoDType(type); |
2405 const llvm::Type* resty = DtoType(dtype); | 2410 const LLType* resty = DtoType(dtype); |
2406 | 2411 |
2407 // allocate a temporary for the final result. failed to come up with a better way :/ | 2412 // allocate a temporary for the final result. failed to come up with a better way :/ |
2408 llvm::BasicBlock* entryblock = &p->topfunc()->front(); | 2413 llvm::BasicBlock* entryblock = &p->topfunc()->front(); |
2409 llvm::Value* resval = new llvm::AllocaInst(resty,"condtmp",p->topallocapoint()); | 2414 LLValue* resval = new llvm::AllocaInst(resty,"condtmp",p->topallocapoint()); |
2410 DVarValue* dvv = new DVarValue(type, resval, true); | 2415 DVarValue* dvv = new DVarValue(type, resval, true); |
2411 | 2416 |
2412 llvm::BasicBlock* oldend = p->scopeend(); | 2417 llvm::BasicBlock* oldend = p->scopeend(); |
2413 llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend); | 2418 llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend); |
2414 llvm::BasicBlock* condfalse = llvm::BasicBlock::Create("condfalse", gIR->topfunc(), oldend); | 2419 llvm::BasicBlock* condfalse = llvm::BasicBlock::Create("condfalse", gIR->topfunc(), oldend); |
2415 llvm::BasicBlock* condend = llvm::BasicBlock::Create("condend", gIR->topfunc(), oldend); | 2420 llvm::BasicBlock* condend = llvm::BasicBlock::Create("condend", gIR->topfunc(), oldend); |
2416 | 2421 |
2417 DValue* c = econd->toElem(p); | 2422 DValue* c = econd->toElem(p); |
2418 llvm::Value* cond_val = DtoBoolean(c->getRVal()); | 2423 LLValue* cond_val = DtoBoolean(c->getRVal()); |
2419 llvm::BranchInst::Create(condtrue,condfalse,cond_val,p->scopebb()); | 2424 llvm::BranchInst::Create(condtrue,condfalse,cond_val,p->scopebb()); |
2420 | 2425 |
2421 p->scope() = IRScope(condtrue, condfalse); | 2426 p->scope() = IRScope(condtrue, condfalse); |
2422 DValue* u = e1->toElem(p); | 2427 DValue* u = e1->toElem(p); |
2423 DtoAssign(dvv, u); | 2428 DtoAssign(dvv, u); |
2439 Logger::print("ComExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2444 Logger::print("ComExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2440 LOG_SCOPE; | 2445 LOG_SCOPE; |
2441 | 2446 |
2442 DValue* u = e1->toElem(p); | 2447 DValue* u = e1->toElem(p); |
2443 | 2448 |
2444 llvm::Value* value = u->getRVal(); | 2449 LLValue* value = u->getRVal(); |
2445 llvm::Value* minusone = llvm::ConstantInt::get(value->getType(), -1, true); | 2450 LLValue* minusone = llvm::ConstantInt::get(value->getType(), -1, true); |
2446 value = llvm::BinaryOperator::create(llvm::Instruction::Xor, value, minusone, "tmp", p->scopebb()); | 2451 value = llvm::BinaryOperator::create(llvm::Instruction::Xor, value, minusone, "tmp", p->scopebb()); |
2447 | 2452 |
2448 return new DImValue(type, value); | 2453 return new DImValue(type, value); |
2449 } | 2454 } |
2450 | 2455 |
2459 | 2464 |
2460 if (type->iscomplex()) { | 2465 if (type->iscomplex()) { |
2461 return DtoComplexNeg(type, l); | 2466 return DtoComplexNeg(type, l); |
2462 } | 2467 } |
2463 | 2468 |
2464 llvm::Value* val = l->getRVal(); | 2469 LLValue* val = l->getRVal(); |
2465 Type* t = DtoDType(type); | 2470 Type* t = DtoDType(type); |
2466 | 2471 |
2467 llvm::Value* zero = 0; | 2472 LLValue* zero = 0; |
2468 if (t->isintegral()) | 2473 if (t->isintegral()) |
2469 zero = llvm::ConstantInt::get(val->getType(), 0, true); | 2474 zero = llvm::ConstantInt::get(val->getType(), 0, true); |
2470 else if (t->isfloating()) { | 2475 else if (t->isfloating()) { |
2471 zero = DtoConstFP(type, 0.0); | 2476 zero = DtoConstFP(type, 0.0); |
2472 } | 2477 } |
2510 DtoCatArrayElement(ex->v->getLVal(),e1,e2); | 2515 DtoCatArrayElement(ex->v->getLVal(),e1,e2); |
2511 return new DImValue(type, ex->v->getLVal(), true); | 2516 return new DImValue(type, ex->v->getLVal(), true); |
2512 } | 2517 } |
2513 else { | 2518 else { |
2514 assert(t->ty == Tarray); | 2519 assert(t->ty == Tarray); |
2515 const llvm::Type* arrty = DtoType(t); | 2520 const LLType* arrty = DtoType(t); |
2516 llvm::Value* dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint()); | 2521 LLValue* dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint()); |
2517 if (arrNarr) | 2522 if (arrNarr) |
2518 DtoCatAr | 2523 DtoCatAr |
2519 DtoCatArrays(dst,e1,e2); | 2524 DtoCatArrays(dst,e1,e2); |
2520 else | 2525 else |
2521 DtoCatArrayElement(dst,e1,e2); | 2526 DtoCatArrayElement(dst,e1,e2); |
2564 Logger::println("kind = %s\n", fd->kind()); | 2569 Logger::println("kind = %s\n", fd->kind()); |
2565 | 2570 |
2566 DtoForceDefineDsymbol(fd); | 2571 DtoForceDefineDsymbol(fd); |
2567 | 2572 |
2568 bool temp = false; | 2573 bool temp = false; |
2569 llvm::Value* lval = NULL; | 2574 LLValue* lval = NULL; |
2570 if (p->topexp() && p->topexp()->e2 == this) { | 2575 if (p->topexp() && p->topexp()->e2 == this) { |
2571 assert(p->topexp()->v); | 2576 assert(p->topexp()->v); |
2572 lval = p->topexp()->v->getLVal(); | 2577 lval = p->topexp()->v->getLVal(); |
2573 } | 2578 } |
2574 else { | 2579 else { |
2575 const llvm::Type* dgty = DtoType(type); | 2580 const LLType* dgty = DtoType(type); |
2576 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; | 2581 Logger::cout() << "delegate without explicit storage:" << '\n' << *dgty << '\n'; |
2577 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); | 2582 lval = new llvm::AllocaInst(dgty,"dgstorage",p->topallocapoint()); |
2578 temp = true; | 2583 temp = true; |
2579 } | 2584 } |
2580 | 2585 |
2581 llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); | 2586 LLValue* context = DtoGEPi(lval,0,0,"tmp",p->scopebb()); |
2582 const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); | 2587 const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0)); |
2583 llvm::Value* llvmNested = p->func()->decl->ir.irFunc->nestedVar; | 2588 LLValue* llvmNested = p->func()->decl->ir.irFunc->nestedVar; |
2584 if (llvmNested == NULL) { | 2589 if (llvmNested == NULL) { |
2585 llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty); | 2590 LLValue* nullcontext = llvm::ConstantPointerNull::get(pty); |
2586 p->ir->CreateStore(nullcontext, context); | 2591 p->ir->CreateStore(nullcontext, context); |
2587 } | 2592 } |
2588 else { | 2593 else { |
2589 llvm::Value* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); | 2594 LLValue* nestedcontext = p->ir->CreateBitCast(llvmNested, pty, "tmp"); |
2590 p->ir->CreateStore(nestedcontext, context); | 2595 p->ir->CreateStore(nestedcontext, context); |
2591 } | 2596 } |
2592 | 2597 |
2593 llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); | 2598 LLValue* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb()); |
2594 | 2599 |
2595 assert(fd->ir.irFunc->func); | 2600 assert(fd->ir.irFunc->func); |
2596 llvm::Value* castfptr = new llvm::BitCastInst(fd->ir.irFunc->func,fptr->getType()->getContainedType(0),"tmp",p->scopebb()); | 2601 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func,fptr->getType()->getContainedType(0)); |
2597 new llvm::StoreInst(castfptr, fptr, p->scopebb()); | 2602 new llvm::StoreInst(castfptr, fptr, p->scopebb()); |
2598 | 2603 |
2599 if (temp) | 2604 if (temp) |
2600 return new DVarValue(type, lval, true); | 2605 return new DVarValue(type, lval, true); |
2601 else | 2606 else |
2619 size_t len = elements->dim; | 2624 size_t len = elements->dim; |
2620 // store into slice? | 2625 // store into slice? |
2621 bool sliceInPlace = false; | 2626 bool sliceInPlace = false; |
2622 | 2627 |
2623 // llvm target type | 2628 // llvm target type |
2624 const llvm::Type* llType = DtoType(arrayType); | 2629 const LLType* llType = DtoType(arrayType); |
2625 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; | 2630 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n"; |
2626 | 2631 |
2627 // llvm storage type | 2632 // llvm storage type |
2628 const llvm::Type* llStoType = llvm::ArrayType::get(DtoType(elemType), len); | 2633 const LLType* llStoType = llvm::ArrayType::get(DtoType(elemType), len); |
2629 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; | 2634 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n"; |
2630 | 2635 |
2631 // dst pointer | 2636 // dst pointer |
2632 llvm::Value* dstMem = 0; | 2637 LLValue* dstMem = 0; |
2633 | 2638 |
2634 // rvalue of assignment | 2639 // rvalue of assignment |
2635 if (p->topexp() && p->topexp()->e2 == this) | 2640 if (p->topexp() && p->topexp()->e2 == this) |
2636 { | 2641 { |
2637 DValue* topval = p->topexp()->v; | 2642 DValue* topval = p->topexp()->v; |
2659 | 2664 |
2660 // store elements | 2665 // store elements |
2661 for (size_t i=0; i<len; ++i) | 2666 for (size_t i=0; i<len; ++i) |
2662 { | 2667 { |
2663 Expression* expr = (Expression*)elements->data[i]; | 2668 Expression* expr = (Expression*)elements->data[i]; |
2664 llvm::Value* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); | 2669 LLValue* elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb()); |
2665 | 2670 |
2666 // emulate assignment | 2671 // emulate assignment |
2667 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); | 2672 DVarValue* vv = new DVarValue(expr->type, elemAddr, true); |
2668 p->exps.push_back(IRExp(NULL, expr, vv)); | 2673 p->exps.push_back(IRExp(NULL, expr, vv)); |
2669 DValue* e = expr->toElem(p); | 2674 DValue* e = expr->toElem(p); |
2681 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); | 2686 return new DSliceValue(type, DtoConstSize_t(len), DtoGEPi(dstMem,0,0,"tmp")); |
2682 } | 2687 } |
2683 | 2688 |
2684 ////////////////////////////////////////////////////////////////////////////////////////// | 2689 ////////////////////////////////////////////////////////////////////////////////////////// |
2685 | 2690 |
2686 llvm::Constant* ArrayLiteralExp::toConstElem(IRState* p) | 2691 LLConstant* ArrayLiteralExp::toConstElem(IRState* p) |
2687 { | 2692 { |
2688 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 2693 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
2689 LOG_SCOPE; | 2694 LOG_SCOPE; |
2690 | 2695 |
2691 const llvm::Type* t = DtoType(type); | 2696 const LLType* t = DtoType(type); |
2692 Logger::cout() << "array literal has llvm type: " << *t << '\n'; | 2697 Logger::cout() << "array literal has llvm type: " << *t << '\n'; |
2693 assert(isaArray(t)); | 2698 assert(isaArray(t)); |
2694 const llvm::ArrayType* arrtype = isaArray(t); | 2699 const llvm::ArrayType* arrtype = isaArray(t); |
2695 | 2700 |
2696 assert(arrtype->getNumElements() == elements->dim); | 2701 assert(arrtype->getNumElements() == elements->dim); |
2697 std::vector<llvm::Constant*> vals(elements->dim, NULL); | 2702 std::vector<LLConstant*> vals(elements->dim, NULL); |
2698 for (unsigned i=0; i<elements->dim; ++i) | 2703 for (unsigned i=0; i<elements->dim; ++i) |
2699 { | 2704 { |
2700 Expression* expr = (Expression*)elements->data[i]; | 2705 Expression* expr = (Expression*)elements->data[i]; |
2701 vals[i] = expr->toConstElem(p); | 2706 vals[i] = expr->toConstElem(p); |
2702 } | 2707 } |
2709 DValue* StructLiteralExp::toElem(IRState* p) | 2714 DValue* StructLiteralExp::toElem(IRState* p) |
2710 { | 2715 { |
2711 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2716 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2712 LOG_SCOPE; | 2717 LOG_SCOPE; |
2713 | 2718 |
2714 llvm::Value* sptr; | 2719 LLValue* sptr; |
2715 const llvm::Type* llt = DtoType(type); | 2720 const LLType* llt = DtoType(type); |
2716 | 2721 |
2717 llvm::Value* mem = 0; | 2722 LLValue* mem = 0; |
2718 | 2723 |
2719 // temporary struct literal | 2724 // temporary struct literal |
2720 if (!p->topexp() || p->topexp()->e2 != this) | 2725 if (!p->topexp() || p->topexp()->e2 != this) |
2721 { | 2726 { |
2722 sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint()); | 2727 sptr = new llvm::AllocaInst(llt,"tmpstructliteral",p->topallocapoint()); |
2732 unsigned n = elements->dim; | 2737 unsigned n = elements->dim; |
2733 | 2738 |
2734 // unions might have different types for each literal | 2739 // unions might have different types for each literal |
2735 if (sd->ir.irStruct->hasUnions) { | 2740 if (sd->ir.irStruct->hasUnions) { |
2736 // build the type of the literal | 2741 // build the type of the literal |
2737 std::vector<const llvm::Type*> tys; | 2742 std::vector<const LLType*> tys; |
2738 for (unsigned i=0; i<n; ++i) { | 2743 for (unsigned i=0; i<n; ++i) { |
2739 Expression* vx = (Expression*)elements->data[i]; | 2744 Expression* vx = (Expression*)elements->data[i]; |
2740 if (!vx) continue; | 2745 if (!vx) continue; |
2741 tys.push_back(DtoType(vx->type)); | 2746 tys.push_back(DtoType(vx->type)); |
2742 } | 2747 } |
2757 { | 2762 { |
2758 Expression* vx = (Expression*)elements->data[i]; | 2763 Expression* vx = (Expression*)elements->data[i]; |
2759 if (!vx) continue; | 2764 if (!vx) continue; |
2760 | 2765 |
2761 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; | 2766 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; |
2762 llvm::Value* arrptr = DtoGEPi(sptr,0,j,"tmp",p->scopebb()); | 2767 LLValue* arrptr = DtoGEPi(sptr,0,j,"tmp",p->scopebb()); |
2763 DValue* darrptr = new DVarValue(vx->type, arrptr, true); | 2768 DValue* darrptr = new DVarValue(vx->type, arrptr, true); |
2764 | 2769 |
2765 p->exps.push_back(IRExp(NULL,vx,darrptr)); | 2770 p->exps.push_back(IRExp(NULL,vx,darrptr)); |
2766 DValue* ve = vx->toElem(p); | 2771 DValue* ve = vx->toElem(p); |
2767 p->exps.pop_back(); | 2772 p->exps.pop_back(); |
2775 return new DImValue(type, sptr, true); | 2780 return new DImValue(type, sptr, true); |
2776 } | 2781 } |
2777 | 2782 |
2778 ////////////////////////////////////////////////////////////////////////////////////////// | 2783 ////////////////////////////////////////////////////////////////////////////////////////// |
2779 | 2784 |
2780 llvm::Constant* StructLiteralExp::toConstElem(IRState* p) | 2785 LLConstant* StructLiteralExp::toConstElem(IRState* p) |
2781 { | 2786 { |
2782 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); | 2787 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); |
2783 LOG_SCOPE; | 2788 LOG_SCOPE; |
2784 | 2789 |
2785 unsigned n = elements->dim; | 2790 unsigned n = elements->dim; |
2786 std::vector<llvm::Constant*> vals(n, NULL); | 2791 std::vector<LLConstant*> vals(n, NULL); |
2787 | 2792 |
2788 for (unsigned i=0; i<n; ++i) | 2793 for (unsigned i=0; i<n; ++i) |
2789 { | 2794 { |
2790 Expression* vx = (Expression*)elements->data[i]; | 2795 Expression* vx = (Expression*)elements->data[i]; |
2791 vals[i] = vx->toConstElem(p); | 2796 vals[i] = vx->toConstElem(p); |
2792 } | 2797 } |
2793 | 2798 |
2794 assert(DtoDType(type)->ty == Tstruct); | 2799 assert(DtoDType(type)->ty == Tstruct); |
2795 const llvm::Type* t = DtoType(type); | 2800 const LLType* t = DtoType(type); |
2796 const llvm::StructType* st = isaStruct(t); | 2801 const llvm::StructType* st = isaStruct(t); |
2797 return llvm::ConstantStruct::get(st,vals); | 2802 return llvm::ConstantStruct::get(st,vals); |
2798 } | 2803 } |
2799 | 2804 |
2800 ////////////////////////////////////////////////////////////////////////////////////////// | 2805 ////////////////////////////////////////////////////////////////////////////////////////// |
2842 { | 2847 { |
2843 aa = p->topexp()->v; | 2848 aa = p->topexp()->v; |
2844 } | 2849 } |
2845 else | 2850 else |
2846 { | 2851 { |
2847 llvm::Value* tmp = new llvm::AllocaInst(DtoType(type),"aaliteral",p->topallocapoint()); | 2852 LLValue* tmp = new llvm::AllocaInst(DtoType(type),"aaliteral",p->topallocapoint()); |
2848 aa = new DVarValue(type, tmp, true); | 2853 aa = new DVarValue(type, tmp, true); |
2849 } | 2854 } |
2850 | 2855 |
2851 const size_t n = keys->dim; | 2856 const size_t n = keys->dim; |
2852 for (size_t i=0; i<n; ++i) | 2857 for (size_t i=0; i<n; ++i) |
2943 //STUB(ArrayLiteralExp); | 2948 //STUB(ArrayLiteralExp); |
2944 //STUB(AssocArrayLiteralExp); | 2949 //STUB(AssocArrayLiteralExp); |
2945 //STUB(StructLiteralExp); | 2950 //STUB(StructLiteralExp); |
2946 STUB(TupleExp); | 2951 STUB(TupleExp); |
2947 | 2952 |
2948 #define CONSTSTUB(x) llvm::Constant* x::toConstElem(IRState * p) {error("const Exp type "#x" not implemented: '%s' type: '%s'", toChars(), type->toChars()); fatal(); return NULL; } | 2953 #define CONSTSTUB(x) LLConstant* x::toConstElem(IRState * p) {error("const Exp type "#x" not implemented: '%s' type: '%s'", toChars(), type->toChars()); fatal(); return NULL; } |
2949 CONSTSTUB(Expression); | 2954 CONSTSTUB(Expression); |
2950 //CONSTSTUB(IntegerExp); | 2955 //CONSTSTUB(IntegerExp); |
2951 //CONSTSTUB(RealExp); | 2956 //CONSTSTUB(RealExp); |
2952 //CONSTSTUB(NullExp); | 2957 //CONSTSTUB(NullExp); |
2953 //CONSTSTUB(ComplexExp); | 2958 //CONSTSTUB(ComplexExp); |