comparison gen/statements.cpp @ 148:86d3bb8ca33e trunk

[svn r154] renaming enclosingtry to enclosingtryfinally to distinguish it from enclosingtrycatch, which will probably need to be added for exception handling
author ChristianK
date Sat, 22 Mar 2008 12:20:32 +0100
parents ddfdae91281a
children 7f92f477ff53
comparison
equal deleted inserted replaced
147:0636f6269dfd 148:86d3bb8ca33e
51 void emit_finallyblocks(IRState* p, TryFinallyStatement* start, TryFinallyStatement* end) 51 void emit_finallyblocks(IRState* p, TryFinallyStatement* start, TryFinallyStatement* end)
52 { 52 {
53 // verify that end encloses start 53 // verify that end encloses start
54 TryFinallyStatement* endfinally = start; 54 TryFinallyStatement* endfinally = start;
55 while(endfinally != NULL && endfinally != end) { 55 while(endfinally != NULL && endfinally != end) {
56 endfinally = endfinally->enclosingtry; 56 endfinally = endfinally->enclosingtryfinally;
57 } 57 }
58 assert(endfinally == end); 58 assert(endfinally == end);
59 59
60 // emit code for finallys between start and end 60 // emit code for finallys between start and end
61 TryFinallyStatement* tf = start; 61 TryFinallyStatement* tf = start;
62 while(tf != end) { 62 while(tf != end) {
63 tf->finalbody->toIR(p); 63 tf->finalbody->toIR(p);
64 tf = tf->enclosingtry; 64 tf = tf->enclosingtryfinally;
65 } 65 }
66 } 66 }
67 67
68 ////////////////////////////////////////////////////////////////////////////// 68 //////////////////////////////////////////////////////////////////////////////
69 69
88 p->exps.pop_back(); 88 p->exps.pop_back();
89 89
90 if (!e->inPlace()) 90 if (!e->inPlace())
91 DtoAssign(rvar, e); 91 DtoAssign(rvar, e);
92 92
93 emit_finallyblocks(p, enclosingtry, NULL); 93 emit_finallyblocks(p, enclosingtryfinally, NULL);
94 94
95 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl); 95 if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
96 new llvm::ReturnInst(p->scopebb()); 96 new llvm::ReturnInst(p->scopebb());
97 97
98 } 98 }
101 DValue* e = exp->toElem(p); 101 DValue* e = exp->toElem(p);
102 llvm::Value* v = e->getRVal(); 102 llvm::Value* v = e->getRVal();
103 delete e; 103 delete e;
104 Logger::cout() << "return value is '" <<*v << "'\n"; 104 Logger::cout() << "return value is '" <<*v << "'\n";
105 105
106 emit_finallyblocks(p, enclosingtry, NULL); 106 emit_finallyblocks(p, enclosingtryfinally, NULL);
107 107
108 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 108 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
109 new llvm::ReturnInst(v, p->scopebb()); 109 new llvm::ReturnInst(v, p->scopebb());
110 } 110 }
111 } 111 }
112 else 112 else
113 { 113 {
114 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) { 114 if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
115 emit_finallyblocks(p, enclosingtry, NULL); 115 emit_finallyblocks(p, enclosingtryfinally, NULL);
116 116
117 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl); 117 if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
118 new llvm::ReturnInst(p->scopebb()); 118 new llvm::ReturnInst(p->scopebb());
119 } 119 }
120 else { 120 else {
252 252
253 // rewrite scope 253 // rewrite scope
254 gIR->scope() = IRScope(whilebodybb,endbb); 254 gIR->scope() = IRScope(whilebodybb,endbb);
255 255
256 // while body code 256 // while body code
257 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,whilebb,endbb)); 257 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,whilebb,endbb));
258 body->toIR(p); 258 body->toIR(p);
259 p->loopbbs.pop_back(); 259 p->loopbbs.pop_back();
260 260
261 // loop 261 // loop
262 if (!gIR->scopereturned()) 262 if (!gIR->scopereturned())
284 284
285 // replace current scope 285 // replace current scope
286 gIR->scope() = IRScope(dowhilebb,endbb); 286 gIR->scope() = IRScope(dowhilebb,endbb);
287 287
288 // do-while body code 288 // do-while body code
289 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,dowhilebb,endbb)); 289 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,dowhilebb,endbb));
290 body->toIR(p); 290 body->toIR(p);
291 p->loopbbs.pop_back(); 291 p->loopbbs.pop_back();
292 292
293 // create the condition 293 // create the condition
294 DValue* cond_e = condition->toElem(p); 294 DValue* cond_e = condition->toElem(p);
322 322
323 // move into the for condition block, ie. start the loop 323 // move into the for condition block, ie. start the loop
324 assert(!gIR->scopereturned()); 324 assert(!gIR->scopereturned());
325 new llvm::BranchInst(forbb, gIR->scopebb()); 325 new llvm::BranchInst(forbb, gIR->scopebb());
326 326
327 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,forincbb,endbb)); 327 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,forincbb,endbb));
328 328
329 // replace current scope 329 // replace current scope
330 gIR->scope() = IRScope(forbb,forbodybb); 330 gIR->scope() = IRScope(forbb,forbodybb);
331 331
332 // create the condition 332 // create the condition
373 LOG_SCOPE; 373 LOG_SCOPE;
374 374
375 if (ident != 0) { 375 if (ident != 0) {
376 Logger::println("ident = %s", ident->toChars()); 376 Logger::println("ident = %s", ident->toChars());
377 377
378 emit_finallyblocks(p, enclosingtry, target->enclosingtry); 378 emit_finallyblocks(p, enclosingtryfinally, target->enclosingtryfinally);
379 379
380 // get the loop statement the label refers to 380 // get the loop statement the label refers to
381 Statement* targetLoopStatement = target->statement; 381 Statement* targetLoopStatement = target->statement;
382 ScopeStatement* tmp; 382 ScopeStatement* tmp;
383 while(tmp = targetLoopStatement->isScopeStatement()) 383 while(tmp = targetLoopStatement->isScopeStatement())
392 } 392 }
393 } 393 }
394 assert(0); 394 assert(0);
395 } 395 }
396 else { 396 else {
397 emit_finallyblocks(p, enclosingtry, gIR->loopbbs.back().enclosingtry); 397 emit_finallyblocks(p, enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
398 new llvm::BranchInst(gIR->loopbbs.back().end, gIR->scopebb()); 398 new llvm::BranchInst(gIR->loopbbs.back().end, gIR->scopebb());
399 } 399 }
400 } 400 }
401 401
402 ////////////////////////////////////////////////////////////////////////////// 402 //////////////////////////////////////////////////////////////////////////////
407 LOG_SCOPE; 407 LOG_SCOPE;
408 408
409 if (ident != 0) { 409 if (ident != 0) {
410 Logger::println("ident = %s", ident->toChars()); 410 Logger::println("ident = %s", ident->toChars());
411 411
412 emit_finallyblocks(p, enclosingtry, target->enclosingtry); 412 emit_finallyblocks(p, enclosingtryfinally, target->enclosingtryfinally);
413 413
414 // get the loop statement the label refers to 414 // get the loop statement the label refers to
415 Statement* targetLoopStatement = target->statement; 415 Statement* targetLoopStatement = target->statement;
416 ScopeStatement* tmp; 416 ScopeStatement* tmp;
417 while(tmp = targetLoopStatement->isScopeStatement()) 417 while(tmp = targetLoopStatement->isScopeStatement())
426 } 426 }
427 } 427 }
428 assert(0); 428 assert(0);
429 } 429 }
430 else { 430 else {
431 emit_finallyblocks(p, enclosingtry, gIR->loopbbs.back().enclosingtry); 431 emit_finallyblocks(p, enclosingtryfinally, gIR->loopbbs.back().enclosingtryfinally);
432 new llvm::BranchInst(gIR->loopbbs.back().begin, gIR->scopebb()); 432 new llvm::BranchInst(gIR->loopbbs.back().begin, gIR->scopebb());
433 } 433 }
434 } 434 }
435 435
436 ////////////////////////////////////////////////////////////////////////////// 436 //////////////////////////////////////////////////////////////////////////////
711 // insert case statements 711 // insert case statements
712 for (size_t i=0; i<n; ++i) 712 for (size_t i=0; i<n; ++i)
713 { 713 {
714 llvm::BasicBlock* nextbb = (i == n-1) ? (defbb ? defbb : endbb) : vcases[i+1].first; 714 llvm::BasicBlock* nextbb = (i == n-1) ? (defbb ? defbb : endbb) : vcases[i+1].first;
715 p->scope() = IRScope(vcases[i].first,nextbb); 715 p->scope() = IRScope(vcases[i].first,nextbb);
716 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,p->scopebb(),endbb)); 716 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb));
717 vbodies[i]->toIR(p); 717 vbodies[i]->toIR(p);
718 p->loopbbs.pop_back(); 718 p->loopbbs.pop_back();
719 719
720 llvm::BasicBlock* curbb = p->scopebb(); 720 llvm::BasicBlock* curbb = p->scopebb();
721 if (curbb->empty() || !curbb->back().isTerminator()) 721 if (curbb->empty() || !curbb->back().isTerminator())
726 726
727 // default statement 727 // default statement
728 if (defbb) 728 if (defbb)
729 { 729 {
730 p->scope() = IRScope(defbb,endbb); 730 p->scope() = IRScope(defbb,endbb);
731 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,p->scopebb(),endbb)); 731 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb));
732 Logger::println("doing default statement"); 732 Logger::println("doing default statement");
733 sdefault->statement->toIR(p); 733 sdefault->statement->toIR(p);
734 p->loopbbs.pop_back(); 734 p->loopbbs.pop_back();
735 735
736 llvm::BasicBlock* curbb = p->scopebb(); 736 llvm::BasicBlock* curbb = p->scopebb();
761 761
762 llvm::BasicBlock* oldend = gIR->scopeend(); 762 llvm::BasicBlock* oldend = gIR->scopeend();
763 llvm::BasicBlock* endbb = new llvm::BasicBlock("unrolledend", p->topfunc(), oldend); 763 llvm::BasicBlock* endbb = new llvm::BasicBlock("unrolledend", p->topfunc(), oldend);
764 764
765 p->scope() = IRScope(p->scopebb(),endbb); 765 p->scope() = IRScope(p->scopebb(),endbb);
766 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,p->scopebb(),endbb)); 766 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,p->scopebb(),endbb));
767 767
768 for (int i=0; i<statements->dim; ++i) 768 for (int i=0; i<statements->dim; ++i)
769 { 769 {
770 Statement* s = (Statement*)statements->data[i]; 770 Statement* s = (Statement*)statements->data[i];
771 s->toIR(p); 771 s->toIR(p);
919 DtoAssign(dst, src); 919 DtoAssign(dst, src);
920 value->irLocal->value = valvar; 920 value->irLocal->value = valvar;
921 } 921 }
922 922
923 // emit body 923 // emit body
924 p->loopbbs.push_back(IRLoopScope(this,enclosingtry,nextbb,endbb)); 924 p->loopbbs.push_back(IRLoopScope(this,enclosingtryfinally,nextbb,endbb));
925 body->toIR(p); 925 body->toIR(p);
926 p->loopbbs.pop_back(); 926 p->loopbbs.pop_back();
927 927
928 if (!p->scopereturned()) 928 if (!p->scopereturned())
929 new llvm::BranchInst(nextbb, p->scopebb()); 929 new llvm::BranchInst(nextbb, p->scopebb());
979 if (label->statement->llvmBB == NULL) 979 if (label->statement->llvmBB == NULL)
980 label->statement->llvmBB = new llvm::BasicBlock("label", p->topfunc()); 980 label->statement->llvmBB = new llvm::BasicBlock("label", p->topfunc());
981 assert(!p->scopereturned()); 981 assert(!p->scopereturned());
982 982
983 // find finallys between goto and label 983 // find finallys between goto and label
984 TryFinallyStatement* endfinally = enclosingtry; 984 TryFinallyStatement* endfinally = enclosingtryfinally;
985 while(endfinally != NULL && endfinally != label->statement->enclosingtry) { 985 while(endfinally != NULL && endfinally != label->statement->enclosingtryfinally) {
986 endfinally = endfinally->enclosingtry; 986 endfinally = endfinally->enclosingtryfinally;
987 } 987 }
988 988
989 // error if didn't find tf statement of label 989 // error if didn't find tf statement of label
990 if(endfinally != label->statement->enclosingtry) 990 if(endfinally != label->statement->enclosingtryfinally)
991 error("cannot goto into try block", loc.toChars()); 991 error("cannot goto into try block", loc.toChars());
992 992
993 // emit code for finallys between goto and label 993 // emit code for finallys between goto and label
994 emit_finallyblocks(p, enclosingtry, endfinally); 994 emit_finallyblocks(p, enclosingtryfinally, endfinally);
995 995
996 new llvm::BranchInst(label->statement->llvmBB, p->scopebb()); 996 new llvm::BranchInst(label->statement->llvmBB, p->scopebb());
997 p->scope() = IRScope(bb,oldend); 997 p->scope() = IRScope(bb,oldend);
998 } 998 }
999 999
1008 llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotodefault", p->topfunc(), oldend); 1008 llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotodefault", p->topfunc(), oldend);
1009 1009
1010 assert(!p->scopereturned()); 1010 assert(!p->scopereturned());
1011 assert(sw->sdefault->bodyBB); 1011 assert(sw->sdefault->bodyBB);
1012 1012
1013 emit_finallyblocks(p, enclosingtry, sw->enclosingtry); 1013 emit_finallyblocks(p, enclosingtryfinally, sw->enclosingtryfinally);
1014 1014
1015 new llvm::BranchInst(sw->sdefault->bodyBB, p->scopebb()); 1015 new llvm::BranchInst(sw->sdefault->bodyBB, p->scopebb());
1016 p->scope() = IRScope(bb,oldend); 1016 p->scope() = IRScope(bb,oldend);
1017 } 1017 }
1018 1018
1027 llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotocase", p->topfunc(), oldend); 1027 llvm::BasicBlock* bb = new llvm::BasicBlock("aftergotocase", p->topfunc(), oldend);
1028 1028
1029 assert(!p->scopereturned()); 1029 assert(!p->scopereturned());
1030 assert(cs->bodyBB); 1030 assert(cs->bodyBB);
1031 1031
1032 emit_finallyblocks(p, enclosingtry, sw->enclosingtry); 1032 emit_finallyblocks(p, enclosingtryfinally, sw->enclosingtryfinally);
1033 1033
1034 new llvm::BranchInst(cs->bodyBB, p->scopebb()); 1034 new llvm::BranchInst(cs->bodyBB, p->scopebb());
1035 p->scope() = IRScope(bb,oldend); 1035 p->scope() = IRScope(bb,oldend);
1036 } 1036 }
1037 1037