Mercurial > projects > ldc
comparison gen/statements.c @ 81:3587401b6eeb trunk
[svn r85] Fixed: if a return statement appeared in the try block of a nested try-finally, only the inner-most finally block would be executed.
Changed: Renamed all the LLVM_Dto... helper function to just Dto...
author | lindquist |
---|---|
date | Thu, 01 Nov 2007 17:27:18 +0100 |
parents | 7299ff502248 |
children | d8dd47ef3973 |
comparison
equal
deleted
inserted
replaced
80:7299ff502248 | 81:3587401b6eeb |
---|---|
5 #include <sstream> | 5 #include <sstream> |
6 #include <fstream> | 6 #include <fstream> |
7 #include <iostream> | 7 #include <iostream> |
8 | 8 |
9 #include "gen/llvm.h" | 9 #include "gen/llvm.h" |
10 #include "llvm/Transforms/Utils/Cloning.h" | |
10 | 11 |
11 #include "total.h" | 12 #include "total.h" |
12 #include "init.h" | 13 #include "init.h" |
13 #include "symbol.h" | 14 #include "symbol.h" |
14 #include "mtype.h" | 15 #include "mtype.h" |
38 else { | 39 else { |
39 Logger::println("*** ATTENTION: null statement found in CompoundStatement"); | 40 Logger::println("*** ATTENTION: null statement found in CompoundStatement"); |
40 //assert(0); | 41 //assert(0); |
41 } | 42 } |
42 } | 43 } |
43 | |
44 } | 44 } |
45 | 45 |
46 ////////////////////////////////////////////////////////////////////////////// | 46 ////////////////////////////////////////////////////////////////////////////// |
47 | 47 |
48 void ReturnStatement::toIR(IRState* p) | 48 void ReturnStatement::toIR(IRState* p) |
53 | 53 |
54 if (exp) | 54 if (exp) |
55 { | 55 { |
56 Logger::println("return type is: %s", exp->type->toChars()); | 56 Logger::println("return type is: %s", exp->type->toChars()); |
57 | 57 |
58 Type* exptype = LLVM_DtoDType(exp->type); | 58 Type* exptype = DtoDType(exp->type); |
59 TY expty = exptype->ty; | 59 TY expty = exptype->ty; |
60 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { | 60 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { |
61 assert(LLVM_DtoIsPassedByRef(exptype)); | 61 assert(DtoIsPassedByRef(exptype)); |
62 | 62 |
63 TypeFunction* f = p->topfunctype(); | 63 TypeFunction* f = p->topfunctype(); |
64 assert(f->llvmRetInPtr && f->llvmRetArg); | 64 assert(f->llvmRetInPtr && f->llvmRetArg); |
65 | 65 |
66 p->exps.push_back(IRExp(NULL,exp,f->llvmRetArg)); | 66 p->exps.push_back(IRExp(NULL,exp,f->llvmRetArg)); |
67 elem* e = exp->toElem(p); | 67 elem* e = exp->toElem(p); |
68 p->exps.pop_back(); | 68 p->exps.pop_back(); |
69 | 69 |
70 if (expty == Tstruct) { | 70 if (expty == Tstruct) { |
71 if (!e->inplace) | 71 if (!e->inplace) |
72 LLVM_DtoStructCopy(f->llvmRetArg,e->getValue()); | 72 DtoStructCopy(f->llvmRetArg,e->getValue()); |
73 } | 73 } |
74 else if (expty == Tdelegate) { | 74 else if (expty == Tdelegate) { |
75 if (!e->inplace) | 75 if (!e->inplace) |
76 LLVM_DtoDelegateCopy(f->llvmRetArg,e->getValue()); | 76 DtoDelegateCopy(f->llvmRetArg,e->getValue()); |
77 } | 77 } |
78 else if (expty == Tarray) { | 78 else if (expty == Tarray) { |
79 if (e->type == elem::SLICE) { | 79 if (e->type == elem::SLICE) { |
80 assert(e->mem); | 80 assert(e->mem); |
81 LLVM_DtoSetArray(f->llvmRetArg,e->arg,e->mem); | 81 DtoSetArray(f->llvmRetArg,e->arg,e->mem); |
82 } | 82 } |
83 else if (!e->inplace) { | 83 else if (!e->inplace) { |
84 if (e->type == elem::NUL) { | 84 if (e->type == elem::NUL) { |
85 LLVM_DtoNullArray(f->llvmRetArg); | 85 DtoNullArray(f->llvmRetArg); |
86 } | 86 } |
87 else { | 87 else { |
88 LLVM_DtoArrayAssign(f->llvmRetArg, e->getValue()); | 88 DtoArrayAssign(f->llvmRetArg, e->getValue()); |
89 } | 89 } |
90 } | 90 } |
91 } | 91 } |
92 else | 92 else |
93 assert(0); | 93 assert(0); |
94 | 94 |
95 IRFunction::FinallyVec& fin = p->func().finallys; | 95 IRFunction::FinallyVec& fin = p->func().finallys; |
96 if (fin.empty()) | 96 if (fin.empty()) |
97 new llvm::ReturnInst(p->scopebb()); | 97 new llvm::ReturnInst(p->scopebb()); |
98 else { | 98 else { |
99 new llvm::BranchInst(fin.back().bb, p->scopebb()); | 99 new llvm::BranchInst(fin.back().retbb, p->scopebb()); |
100 fin.back().ret = true; | |
101 } | 100 } |
102 delete e; | 101 delete e; |
103 } | 102 } |
104 else { | 103 else { |
105 elem* e = exp->toElem(p); | 104 elem* e = exp->toElem(p); |
110 IRFunction::FinallyVec& fin = p->func().finallys; | 109 IRFunction::FinallyVec& fin = p->func().finallys; |
111 if (fin.empty()) { | 110 if (fin.empty()) { |
112 new llvm::ReturnInst(v, p->scopebb()); | 111 new llvm::ReturnInst(v, p->scopebb()); |
113 } | 112 } |
114 else { | 113 else { |
115 llvm::Value* rettmp = new llvm::AllocaInst(v->getType(),"tmpreturn",p->topallocapoint()); | 114 if (!p->func().finallyretval) |
115 p->func().finallyretval = new llvm::AllocaInst(v->getType(),"tmpreturn",p->topallocapoint()); | |
116 llvm::Value* rettmp = p->func().finallyretval; | |
116 new llvm::StoreInst(v,rettmp,p->scopebb()); | 117 new llvm::StoreInst(v,rettmp,p->scopebb()); |
117 new llvm::BranchInst(fin.back().bb, p->scopebb()); | 118 new llvm::BranchInst(fin.back().retbb, p->scopebb()); |
118 fin.back().ret = true; | |
119 fin.back().retval = rettmp; | |
120 } | 119 } |
121 } | 120 } |
122 } | 121 } |
123 else | 122 else |
124 { | 123 { |
126 IRFunction::FinallyVec& fin = p->func().finallys; | 125 IRFunction::FinallyVec& fin = p->func().finallys; |
127 if (fin.empty()) { | 126 if (fin.empty()) { |
128 new llvm::ReturnInst(p->scopebb()); | 127 new llvm::ReturnInst(p->scopebb()); |
129 } | 128 } |
130 else { | 129 else { |
131 new llvm::BranchInst(fin.back().bb, p->scopebb()); | 130 new llvm::BranchInst(fin.back().retbb, p->scopebb()); |
132 fin.back().ret = true; | |
133 } | 131 } |
134 } | 132 } |
135 else { | 133 else { |
136 assert(0); // why should this ever happen? | 134 assert(0); // why should this ever happen? |
137 new llvm::UnreachableInst(p->scopebb()); | 135 new llvm::UnreachableInst(p->scopebb()); |
171 | 169 |
172 llvm::BasicBlock* oldend = gIR->scopeend(); | 170 llvm::BasicBlock* oldend = gIR->scopeend(); |
173 | 171 |
174 llvm::BasicBlock* ifbb = new llvm::BasicBlock("if", gIR->topfunc(), oldend); | 172 llvm::BasicBlock* ifbb = new llvm::BasicBlock("if", gIR->topfunc(), oldend); |
175 llvm::BasicBlock* endbb = new llvm::BasicBlock("endif", gIR->topfunc(), oldend); | 173 llvm::BasicBlock* endbb = new llvm::BasicBlock("endif", gIR->topfunc(), oldend); |
176 llvm::BasicBlock* elsebb = 0; | 174 llvm::BasicBlock* elsebb = elsebody ? new llvm::BasicBlock("else", gIR->topfunc(), endbb) : endbb; |
177 if (elsebody) { | |
178 elsebb = new llvm::BasicBlock("else", gIR->topfunc(), endbb); | |
179 } | |
180 else { | |
181 elsebb = endbb; | |
182 } | |
183 | 175 |
184 if (cond_val->getType() != llvm::Type::Int1Ty) { | 176 if (cond_val->getType() != llvm::Type::Int1Ty) { |
185 Logger::cout() << "if conditional: " << *cond_val << '\n'; | 177 Logger::cout() << "if conditional: " << *cond_val << '\n'; |
186 cond_val = LLVM_DtoBoolean(cond_val); | 178 cond_val = DtoBoolean(cond_val); |
187 } | 179 } |
188 llvm::Value* ifgoback = new llvm::BranchInst(ifbb, elsebb, cond_val, gIR->scopebegin()); | 180 llvm::Value* ifgoback = new llvm::BranchInst(ifbb, elsebb, cond_val, gIR->scopebegin()); |
189 | 181 |
190 // replace current scope | 182 // replace current scope |
191 gIR->scope() = IRScope(ifbb,elsebb); | 183 gIR->scope() = IRScope(ifbb,elsebb); |
192 | |
193 bool endifUsed = false; | |
194 | 184 |
195 // do scoped statements | 185 // do scoped statements |
196 ifbody->toIR(p); | 186 ifbody->toIR(p); |
197 if (!gIR->scopereturned()) { | 187 if (!gIR->scopereturned()) { |
198 new llvm::BranchInst(endbb,gIR->scopebegin()); | 188 new llvm::BranchInst(endbb,gIR->scopebegin()); |
199 endifUsed = true; | |
200 } | 189 } |
201 | 190 |
202 if (elsebody) { | 191 if (elsebody) { |
203 //assert(0); | 192 //assert(0); |
204 gIR->scope() = IRScope(elsebb,endbb); | 193 gIR->scope() = IRScope(elsebb,endbb); |
205 elsebody->toIR(p); | 194 elsebody->toIR(p); |
206 if (!gIR->scopereturned()) { | 195 if (!gIR->scopereturned()) { |
207 new llvm::BranchInst(endbb,gIR->scopebegin()); | 196 new llvm::BranchInst(endbb,gIR->scopebegin()); |
208 endifUsed = true; | |
209 } | 197 } |
210 } | 198 } |
211 | 199 |
212 // rewrite the scope | 200 // rewrite the scope |
213 gIR->scope() = IRScope(endbb,oldend); | 201 gIR->scope() = IRScope(endbb,oldend); |
221 LOG_SCOPE; | 209 LOG_SCOPE; |
222 | 210 |
223 llvm::BasicBlock* oldend = p->scopeend(); | 211 llvm::BasicBlock* oldend = p->scopeend(); |
224 | 212 |
225 llvm::BasicBlock* beginbb = 0; | 213 llvm::BasicBlock* beginbb = 0; |
226 | 214 |
227 // remove useless branches by clearing and reusing the current basicblock | 215 // remove useless branches by clearing and reusing the current basicblock |
228 llvm::BasicBlock* bb = p->scopebegin(); | 216 llvm::BasicBlock* bb = p->scopebegin(); |
229 if (bb->empty()) { | 217 if (bb->empty()) { |
230 beginbb = bb; | 218 beginbb = bb; |
231 } | 219 } |
265 // replace current scope | 253 // replace current scope |
266 gIR->scope() = IRScope(whilebb,endbb); | 254 gIR->scope() = IRScope(whilebb,endbb); |
267 | 255 |
268 // create the condition | 256 // create the condition |
269 elem* cond_e = condition->toElem(p); | 257 elem* cond_e = condition->toElem(p); |
270 llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue()); | 258 llvm::Value* cond_val = DtoBoolean(cond_e->getValue()); |
271 delete cond_e; | 259 delete cond_e; |
272 | 260 |
273 // conditional branch | 261 // conditional branch |
274 llvm::Value* ifbreak = new llvm::BranchInst(whilebodybb, endbb, cond_val, p->scopebb()); | 262 llvm::Value* ifbreak = new llvm::BranchInst(whilebodybb, endbb, cond_val, p->scopebb()); |
275 | 263 |
308 // do do-while body code | 296 // do do-while body code |
309 body->toIR(p); | 297 body->toIR(p); |
310 | 298 |
311 // create the condition | 299 // create the condition |
312 elem* cond_e = condition->toElem(p); | 300 elem* cond_e = condition->toElem(p); |
313 llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue()); | 301 llvm::Value* cond_val = DtoBoolean(cond_e->getValue()); |
314 delete cond_e; | 302 delete cond_e; |
315 | 303 |
316 // conditional branch | 304 // conditional branch |
317 llvm::Value* ifbreak = new llvm::BranchInst(dowhilebb, endbb, cond_val, gIR->scopebegin()); | 305 llvm::Value* ifbreak = new llvm::BranchInst(dowhilebb, endbb, cond_val, gIR->scopebegin()); |
318 | 306 |
347 // replace current scope | 335 // replace current scope |
348 gIR->scope() = IRScope(forbb,forbodybb); | 336 gIR->scope() = IRScope(forbb,forbodybb); |
349 | 337 |
350 // create the condition | 338 // create the condition |
351 elem* cond_e = condition->toElem(p); | 339 elem* cond_e = condition->toElem(p); |
352 llvm::Value* cond_val = LLVM_DtoBoolean(cond_e->getValue()); | 340 llvm::Value* cond_val = DtoBoolean(cond_e->getValue()); |
353 delete cond_e; | 341 delete cond_e; |
354 | 342 |
355 // conditional branch | 343 // conditional branch |
356 llvm::Value* ifbreak = new llvm::BranchInst(forbodybb, endbb, cond_val, forbb); | 344 llvm::Value* ifbreak = new llvm::BranchInst(forbodybb, endbb, cond_val, forbb); |
357 | 345 |
426 //statement->toIR(p); // this seems to be redundant | 414 //statement->toIR(p); // this seems to be redundant |
427 } | 415 } |
428 | 416 |
429 ////////////////////////////////////////////////////////////////////////////// | 417 ////////////////////////////////////////////////////////////////////////////// |
430 | 418 |
419 static void replaceFinallyBBs(std::vector<llvm::BasicBlock*>& a, std::vector<llvm::BasicBlock*>& b) | |
420 { | |
421 } | |
422 | |
431 void TryFinallyStatement::toIR(IRState* p) | 423 void TryFinallyStatement::toIR(IRState* p) |
432 { | 424 { |
433 static int wsi = 0; | 425 Logger::println("TryFinallyStatement::toIR(): %s", toChars()); |
434 Logger::println("TryFinallyStatement::toIR(%d): %s", wsi++, toChars()); | 426 LOG_SCOPE; |
435 LOG_SCOPE; | 427 |
436 | 428 // create basic blocks |
437 llvm::BasicBlock* oldend = p->scopeend(); | 429 llvm::BasicBlock* oldend = p->scopeend(); |
438 | 430 |
439 llvm::BasicBlock* trybb = new llvm::BasicBlock("try", p->topfunc(), oldend); | 431 llvm::BasicBlock* trybb = new llvm::BasicBlock("try", p->topfunc(), oldend); |
440 llvm::BasicBlock* finallybb = new llvm::BasicBlock("finally", p->topfunc(), oldend); | 432 llvm::BasicBlock* finallybb = new llvm::BasicBlock("finally", p->topfunc(), oldend); |
433 llvm::BasicBlock* finallyretbb = new llvm::BasicBlock("finallyreturn", p->topfunc(), oldend); | |
441 llvm::BasicBlock* endbb = new llvm::BasicBlock("endtryfinally", p->topfunc(), oldend); | 434 llvm::BasicBlock* endbb = new llvm::BasicBlock("endtryfinally", p->topfunc(), oldend); |
442 | 435 |
443 // pass the previous BB into this | 436 // pass the previous BB into this |
437 assert(!gIR->scopereturned()); | |
444 new llvm::BranchInst(trybb, p->scopebb()); | 438 new llvm::BranchInst(trybb, p->scopebb()); |
445 | 439 |
440 // do the try block | |
446 p->scope() = IRScope(trybb,finallybb); | 441 p->scope() = IRScope(trybb,finallybb); |
442 gIR->func().finallys.push_back(IRFinally(finallybb,finallyretbb)); | |
443 IRFinally& fin = p->func().finallys.back(); | |
447 | 444 |
448 assert(body); | 445 assert(body); |
449 gIR->func().finallys.push_back(IRFinally(finallybb)); | |
450 body->toIR(p); | 446 body->toIR(p); |
451 if (!gIR->scopereturned()) | 447 |
448 // terminate try BB | |
449 if (!p->scopereturned()) | |
452 new llvm::BranchInst(finallybb, p->scopebb()); | 450 new llvm::BranchInst(finallybb, p->scopebb()); |
453 | 451 |
454 // rewrite the scope | 452 // do finally block |
455 p->scope() = IRScope(finallybb,endbb); | 453 p->scope() = IRScope(finallybb,finallyretbb); |
456 | |
457 assert(finalbody); | 454 assert(finalbody); |
458 finalbody->toIR(p); | 455 finalbody->toIR(p); |
459 if (gIR->func().finallys.back().ret) { | 456 |
460 llvm::Value* retval = p->func().finallys.back().retval; | 457 // terminate finally |
458 if (!gIR->scopereturned()) { | |
459 new llvm::BranchInst(endbb, p->scopebb()); | |
460 } | |
461 | |
462 // do finally block (return path) | |
463 p->scope() = IRScope(finallyretbb,endbb); | |
464 assert(finalbody); | |
465 finalbody->toIR(p); // hope this will work, otherwise it's time it gets fixed | |
466 | |
467 // terminate finally (return path) | |
468 size_t nfin = p->func().finallys.size(); | |
469 if (nfin > 1) { | |
470 IRFinally& ofin = p->func().finallys[nfin-2]; | |
471 p->ir->CreateBr(ofin.retbb); | |
472 } | |
473 // no outer | |
474 else | |
475 { | |
476 llvm::Value* retval = p->func().finallyretval; | |
461 if (retval) { | 477 if (retval) { |
462 retval = new llvm::LoadInst(retval,"tmp",p->scopebb()); | 478 retval = p->ir->CreateLoad(retval,"tmp"); |
463 new llvm::ReturnInst(retval, p->scopebb()); | 479 p->ir->CreateRet(retval); |
464 } | 480 } |
465 else { | 481 else { |
466 new llvm::ReturnInst(p->scopebb()); | 482 FuncDeclaration* fd = p->func().decl; |
467 } | 483 if (fd->isMain()) { |
468 } | 484 assert(fd->type->next->ty == Tvoid); |
469 else if (!gIR->scopereturned()) { | 485 p->ir->CreateRet(DtoConstInt(0)); |
470 new llvm::BranchInst(endbb, p->scopebb()); | 486 } |
471 } | 487 else { |
472 | 488 p->ir->CreateRetVoid(); |
489 } | |
490 } | |
491 } | |
492 | |
493 // rewrite the scope | |
473 p->func().finallys.pop_back(); | 494 p->func().finallys.pop_back(); |
474 | |
475 // rewrite the scope | |
476 p->scope() = IRScope(endbb,oldend); | 495 p->scope() = IRScope(endbb,oldend); |
477 } | 496 } |
478 | 497 |
479 ////////////////////////////////////////////////////////////////////////////// | 498 ////////////////////////////////////////////////////////////////////////////// |
480 | 499 |
506 LOG_SCOPE; | 525 LOG_SCOPE; |
507 | 526 |
508 Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);"); | 527 Logger::println("*** ATTENTION: throw is not yet implemented, replacing expression with assert(0);"); |
509 | 528 |
510 llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); | 529 llvm::Value* line = llvm::ConstantInt::get(llvm::Type::Int32Ty, loc.linnum, false); |
511 LLVM_DtoAssert(NULL, line, NULL); | 530 DtoAssert(NULL, line, NULL); |
512 | 531 |
513 /* | 532 /* |
514 assert(exp); | 533 assert(exp); |
515 elem* e = exp->toElem(p); | 534 elem* e = exp->toElem(p); |
516 delete e; | 535 delete e; |
651 llvm::Value* val = arr->getValue(); | 670 llvm::Value* val = arr->getValue(); |
652 Logger::cout() << "aggr2llvm = " << *val << '\n'; | 671 Logger::cout() << "aggr2llvm = " << *val << '\n'; |
653 | 672 |
654 llvm::Value* numiters = 0; | 673 llvm::Value* numiters = 0; |
655 | 674 |
656 const llvm::Type* keytype = key ? LLVM_DtoType(key->type) : LLVM_DtoSize_t(); | 675 const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t(); |
657 llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint()); | 676 llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint()); |
658 if (key) key->llvmValue = keyvar; | 677 if (key) key->llvmValue = keyvar; |
659 | 678 |
660 const llvm::Type* valtype = LLVM_DtoType(value->type); | 679 const llvm::Type* valtype = DtoType(value->type); |
661 llvm::Value* valvar = !value->isRef() ? new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()) : NULL; | 680 llvm::Value* valvar = !value->isRef() ? new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint()) : NULL; |
662 | 681 |
663 Type* aggrtype = LLVM_DtoDType(aggr->type); | 682 Type* aggrtype = DtoDType(aggr->type); |
664 if (aggrtype->ty == Tsarray) | 683 if (aggrtype->ty == Tsarray) |
665 { | 684 { |
666 assert(llvm::isa<llvm::PointerType>(val->getType())); | 685 assert(llvm::isa<llvm::PointerType>(val->getType())); |
667 assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0))); | 686 assert(llvm::isa<llvm::ArrayType>(val->getType()->getContainedType(0))); |
668 size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements(); | 687 size_t n = llvm::cast<llvm::ArrayType>(val->getType()->getContainedType(0))->getNumElements(); |
674 if (arr->type == elem::SLICE) { | 693 if (arr->type == elem::SLICE) { |
675 numiters = arr->arg; | 694 numiters = arr->arg; |
676 val = arr->mem; | 695 val = arr->mem; |
677 } | 696 } |
678 else { | 697 else { |
679 numiters = p->ir->CreateLoad(LLVM_DtoGEPi(val,0,0,"tmp",p->scopebb())); | 698 numiters = p->ir->CreateLoad(DtoGEPi(val,0,0,"tmp",p->scopebb())); |
680 val = p->ir->CreateLoad(LLVM_DtoGEPi(val,0,1,"tmp",p->scopebb())); | 699 val = p->ir->CreateLoad(DtoGEPi(val,0,1,"tmp",p->scopebb())); |
681 } | 700 } |
682 } | 701 } |
683 else | 702 else |
684 { | 703 { |
685 assert(0 && "aggregate type is not Tarray or Tsarray"); | 704 assert(0 && "aggregate type is not Tarray or Tsarray"); |
723 | 742 |
724 // get value for this iteration | 743 // get value for this iteration |
725 llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false); | 744 llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false); |
726 llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp"); | 745 llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp"); |
727 if (aggrtype->ty == Tsarray) | 746 if (aggrtype->ty == Tsarray) |
728 value->llvmValue = LLVM_DtoGEP(val,zero,loadedKey,"tmp"); | 747 value->llvmValue = DtoGEP(val,zero,loadedKey,"tmp"); |
729 else if (aggrtype->ty == Tarray) | 748 else if (aggrtype->ty == Tarray) |
730 value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb()); | 749 value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb()); |
731 | 750 |
732 if (!value->isRef()) { | 751 if (!value->isRef()) { |
733 elem* e = new elem; | 752 elem* e = new elem; |
734 e->mem = value->llvmValue; | 753 e->mem = value->llvmValue; |
735 e->type = elem::VAR; | 754 e->type = elem::VAR; |
736 LLVM_DtoAssign(LLVM_DtoDType(value->type), valvar, e->getValue()); | 755 DtoAssign(DtoDType(value->type), valvar, e->getValue()); |
737 delete e; | 756 delete e; |
738 value->llvmValue = valvar; | 757 value->llvmValue = valvar; |
739 } | 758 } |
740 | 759 |
741 // body | 760 // body |