annotate ir/irlandingpad.cpp @ 632:df196c8dea26

Updated to latest LLVM trunk, function notes have been removed and merged with parameter attributes, which have been renamed to just attributes. Nothing seems to have broke!
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 01 Oct 2008 23:17:14 +0200
parents d97b017a8aef
children 5761d7e6f628
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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 }