Mercurial > projects > ldc
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 |