Mercurial > projects > ldc
annotate ir/irlandingpad.cpp @ 650:aa6a0b7968f7
Added test case for bug #100
Removed dubious check for not emitting static private global in other modules without access. This should be handled properly somewhere else, it's causing unresolved global errors for stuff that should work (in MiniD)
author | Tomas Lindquist Olsen <tomas.l.olsen@gmail.com> |
---|---|
date | Sun, 05 Oct 2008 17:28:15 +0200 |
parents | d97b017a8aef |
children | 5761d7e6f628 |
rev | line source |
---|---|
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
1 #include "gen/llvm.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
2 #include "gen/tollvm.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
3 #include "gen/irstate.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
4 #include "gen/runtime.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
5 #include "gen/logger.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
6 #include "gen/classes.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
7 #include "gen/llvmhelpers.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
8 #include "ir/irlandingpad.h" |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
9 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
10 IRLandingPadInfo::IRLandingPadInfo(Catch* catchstmt, llvm::BasicBlock* end) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
11 : finallyBody(NULL) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
12 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
13 target = llvm::BasicBlock::Create("catch", gIR->topfunc(), end); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
14 gIR->scope() = IRScope(target,end); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
15 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
16 // assign storage to catch var |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
17 if(catchstmt->var) { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
18 assert(!catchstmt->var->ir.irLocal); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
19 catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
20 LLValue* catch_var = gIR->func()->landingPad.getExceptionStorage(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
21 catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type))); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
22 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
23 |
320
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
24 // emit handler, if there is one |
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
25 // handler is zero for instance for 'catch { debug foo(); }' |
332
d7e6ace5cca4
[svn r353] Fix typo. (fixes empty catch handlers, like catch_02.d)
ChristianK
parents:
320
diff
changeset
|
26 if(catchstmt->handler) |
320
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
27 catchstmt->handler->toIR(gIR); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
28 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
29 if (!gIR->scopereturned()) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
30 gIR->ir->CreateBr(end); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
31 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
32 assert(catchstmt->type); |
320
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
33 catchType = catchstmt->type->toBasetype()->isClassHandle(); |
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
34 assert(catchType); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
35 DtoForceDeclareDsymbol(catchType); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
36 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
37 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
38 IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
39 : target(NULL), finallyBody(finallystmt), catchType(NULL) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
40 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
41 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
42 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
43 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
44 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
45 void IRLandingPad::addCatch(Catch* catchstmt, llvm::BasicBlock* end) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
46 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
47 unpushed_infos.push_front(IRLandingPadInfo(catchstmt, end)); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
48 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
49 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
50 void IRLandingPad::addFinally(Statement* finallystmt) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
51 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
52 unpushed_infos.push_front(IRLandingPadInfo(finallystmt)); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
53 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
54 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
55 void IRLandingPad::push(llvm::BasicBlock* inBB) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
56 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
57 // store infos such that matches are right to left |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
58 nInfos.push(infos.size()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
59 infos.insert(infos.end(), unpushed_infos.begin(), unpushed_infos.end()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
60 unpushed_infos.clear(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
61 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
62 constructLandingPad(inBB); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
63 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
64 // store as invoke target |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
65 padBBs.push(inBB); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
66 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
67 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
68 void IRLandingPad::pop() |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
69 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
70 padBBs.pop(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
71 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
72 size_t n = nInfos.top(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
73 infos.resize(n); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
74 nInfos.pop(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
75 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
76 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
77 llvm::BasicBlock* IRLandingPad::get() |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
78 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
79 if(padBBs.size() == 0) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
80 return NULL; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
81 else |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
82 return padBBs.top(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
83 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
84 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
85 void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
86 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
87 // save and rewrite scope |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
88 IRScope savedscope = gIR->scope(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
89 gIR->scope() = IRScope(inBB,savedscope.end); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
90 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
91 // eh_ptr = llvm.eh.exception(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
92 llvm::Function* eh_exception_fn = GET_INTRINSIC_DECL(eh_exception); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
93 LLValue* eh_ptr = gIR->ir->CreateCall(eh_exception_fn); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
94 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
95 // build selector arguments |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
96 LLSmallVector<LLValue*, 6> selectorargs; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
97 |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
98 // put in classinfos in the right order |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
99 bool hasFinally = false; |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
100 std::deque<IRLandingPadInfo>::iterator it = infos.begin(), end = infos.end(); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
101 for(; it != end; ++it) |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
102 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
103 if(it->finallyBody) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
104 hasFinally = true; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
105 else |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
106 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
107 if(catchToInt.find(it->catchType) == catchToInt.end()) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
108 { |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
109 int newval = 1 + catchToInt.size(); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
110 catchToInt[it->catchType] = newval; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
111 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
112 assert(it->catchType); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
113 assert(it->catchType->ir.irStruct); |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
114 selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->classInfo); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
115 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
116 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
117 // if there's a finally, the eh table has to have a 0 action |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
118 if(hasFinally) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
119 selectorargs.push_back(llvm::ConstantInt::get(LLType::Int32Ty, 0)); |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
120 |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
121 // personality fn |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
122 llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality"); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
123 LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::Int8Ty)); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
124 selectorargs.insert(selectorargs.begin(), personality_fn_arg); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
125 |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
126 // eh storage target |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
127 selectorargs.insert(selectorargs.begin(), eh_ptr); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
128 |
320
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
129 // if there is a catch and some catch allocated storage, store exception object |
d772927ca496
[svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents:
319
diff
changeset
|
130 if(catchToInt.size() && catch_var) |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
131 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
132 const LLType* objectTy = DtoType(ClassDeclaration::object->type); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
133 gIR->ir->CreateStore(gIR->ir->CreateBitCast(eh_ptr, objectTy), catch_var); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
134 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
135 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
136 // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
137 llvm::Function* eh_selector_fn; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
138 if (global.params.is64bit) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
139 eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i64); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
140 else |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
141 eh_selector_fn = GET_INTRINSIC_DECL(eh_selector_i32); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
142 LLValue* eh_sel = gIR->ir->CreateCall(eh_selector_fn, selectorargs.begin(), selectorargs.end()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
143 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
144 // emit finallys and switches that branch to catches until there are no more catches |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
145 // then simply branch to the finally chain |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
146 llvm::SwitchInst* switchinst = NULL; |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
147 std::deque<IRLandingPadInfo>::reverse_iterator rit, rend = infos.rend(); |
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
148 for(rit = infos.rbegin(); rit != rend; ++rit) |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
149 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
150 // if it's a finally, emit its code |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
151 if(rit->finallyBody) |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
152 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
153 if(switchinst) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
154 switchinst = NULL; |
355
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
155 |
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
156 // since this may be emitted multiple times |
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
157 // give the labels a new scope |
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
158 gIR->func()->pushUniqueLabelScope("finally"); |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
159 rit->finallyBody->toIR(gIR); |
355
d8357f7004ca
[svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents:
349
diff
changeset
|
160 gIR->func()->popLabelScope(); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
161 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
162 // otherwise it's a catch and we'll add a switch case |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
163 else |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
164 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
165 if(!switchinst) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
166 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
167 switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create("switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
168 gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend()); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
169 } |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
170 // dubious comment |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
171 // catches matched first get the largest switchval, so do size - unique int |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
172 llvm::ConstantInt* switchval = llvm::ConstantInt::get(DtoSize_t(), catchToInt[rit->catchType]); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
173 // and make sure we don't add the same switchval twice, may happen with nested trys |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
174 if(!switchinst->findCaseValue(switchval)) |
612
d97b017a8aef
Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents:
479
diff
changeset
|
175 switchinst->addCase(switchval, rit->target); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
176 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
177 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
178 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
179 // no catch matched and all finallys executed - resume unwind |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
180 llvm::Function* unwind_resume_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_resume_unwind"); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
181 gIR->ir->CreateCall(unwind_resume_fn, eh_ptr); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
182 gIR->ir->CreateUnreachable(); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
183 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
184 gIR->scope() = savedscope; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
185 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
186 |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
187 LLValue* IRLandingPad::getExceptionStorage() |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
188 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
189 if(!catch_var) |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
190 { |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
191 Logger::println("Making new catch var"); |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
192 const LLType* objectTy = DtoType(ClassDeclaration::object->type); |
479
672eb4893b55
Move AllocaInst creation into DtoAlloca helper. Will enable special zero-init of fp80 reals' padding.
Christian Kamm <kamm incasoftware de>
parents:
355
diff
changeset
|
193 catch_var = DtoAlloca(objectTy,"catchvar"); |
319
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
194 } |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
195 return catch_var; |
e9c93739bc4c
[svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff
changeset
|
196 } |