annotate ir/irlandingpad.cpp @ 1650:40bd4a0d4870

Update to work with LLVM 2.7. Removed use of dyn_cast, llvm no compiles without exceptions and rtti by default. We do need exceptions for the libconfig stuff, but rtti isn't necessary (anymore). Debug info needs to be rewritten, as in LLVM 2.7 the format has completely changed. To have something to look at while rewriting, the old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means that you have to define this to compile at the moment. Updated tango 0.99.9 patch to include updated EH runtime code, which is needed for LLVM 2.7 as well.
author Tomas Lindquist Olsen
date Wed, 19 May 2010 12:42:32 +0200
parents f4c56ed32238
children
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 {
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
13 target = llvm::BasicBlock::Create(gIR->context(), "catch", gIR->topfunc(), end);
319
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) {
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
18 // use the same storage for all exceptions that are not accessed in
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
19 // nested functions
758
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
20 #if DMDV2
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
21 if(!catchstmt->var->nestedrefs.dim) {
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
22 #else
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
23 if(!catchstmt->var->nestedref) {
758
f04dde6e882c Added initial D2 support, D2 frontend and changes to codegen to make things compile.
Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
parents: 745
diff changeset
24 #endif
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
25 assert(!catchstmt->var->ir.irLocal);
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
26 catchstmt->var->ir.irLocal = new IrLocal(catchstmt->var);
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
27 LLValue* catch_var = gIR->func()->gen->landingPadInfo.getExceptionStorage();
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
28 catchstmt->var->ir.irLocal->value = gIR->ir->CreateBitCast(catch_var, getPtrToType(DtoType(catchstmt->var->type)));
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
29 }
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
30
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
31 // this will alloca if we haven't already and take care of nested refs
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
32 DtoDeclarationExp(catchstmt->var);
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
33
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
34 // the exception will only be stored in catch_var. copy it over if necessary
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
35 if(catchstmt->var->ir.irLocal->value != gIR->func()->gen->landingPadInfo.getExceptionStorage()) {
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
36 LLValue* exc = gIR->ir->CreateBitCast(DtoLoad(gIR->func()->gen->landingPadInfo.getExceptionStorage()), DtoType(catchstmt->var->type));
745
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
37 DtoStore(exc, catchstmt->var->ir.irLocal->value);
5761d7e6f628 Tried using DtoDeclarationExp for VarDecls in Statements to fix nesting issues
Christian Kamm <kamm incasoftware de>
parents: 612
diff changeset
38 }
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
39 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
40
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
41 // emit handler, if there is one
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
42 // 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
43 if(catchstmt->handler)
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
44 catchstmt->handler->toIR(gIR);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
45
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
46 if (!gIR->scopereturned())
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
47 gIR->ir->CreateBr(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 assert(catchstmt->type);
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
50 catchType = catchstmt->type->toBasetype()->isClassHandle();
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
51 assert(catchType);
1148
3d1b16dabd25 Eliminated the need for resolve, declare, const-init and define lists to drive code generation.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents: 758
diff changeset
52 catchType->codegen(Type::sir);
319
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 IRLandingPadInfo::IRLandingPadInfo(Statement* finallystmt)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
56 : target(NULL), finallyBody(finallystmt), catchType(NULL)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
57 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
58
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
59 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
60
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 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
63 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
64 unpushed_infos.push_front(IRLandingPadInfo(catchstmt, end));
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
65 }
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 void IRLandingPad::addFinally(Statement* finallystmt)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
68 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
69 unpushed_infos.push_front(IRLandingPadInfo(finallystmt));
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
70 }
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 void IRLandingPad::push(llvm::BasicBlock* inBB)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
73 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
74 // 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
75 nInfos.push(infos.size());
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
76 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
77 unpushed_infos.clear();
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 constructLandingPad(inBB);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
80
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
81 // store as invoke target
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
82 padBBs.push(inBB);
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::pop()
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 padBBs.pop();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
88
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
89 size_t n = nInfos.top();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
90 infos.resize(n);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
91 nInfos.pop();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
92 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
93
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
94 llvm::BasicBlock* IRLandingPad::get()
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
95 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
96 if(padBBs.size() == 0)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
97 return NULL;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
98 else
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
99 return padBBs.top();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
100 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
101
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
102 void IRLandingPad::constructLandingPad(llvm::BasicBlock* inBB)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
103 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
104 // save and rewrite scope
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
105 IRScope savedscope = gIR->scope();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
106 gIR->scope() = IRScope(inBB,savedscope.end);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
107
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
108 // eh_ptr = llvm.eh.exception();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
109 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
110 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
111
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
112 // build selector arguments
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
113 LLSmallVector<LLValue*, 6> selectorargs;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
114
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
115 // 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
116 bool hasFinally = false;
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
117 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
118 for(; it != end; ++it)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
119 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
120 if(it->finallyBody)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
121 hasFinally = true;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
122 else
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
123 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
124 if(catchToInt.find(it->catchType) == catchToInt.end())
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
125 {
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
126 int newval = 1 + catchToInt.size();
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
127 catchToInt[it->catchType] = newval;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
128 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
129 assert(it->catchType);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
130 assert(it->catchType->ir.irStruct);
1228
79758fd2f48a Added Doxygen file.
Tomas Lindquist Olsen <tomas.l.olsen gmail.com>
parents: 1148
diff changeset
131 selectorargs.insert(selectorargs.begin(), it->catchType->ir.irStruct->getClassInfoSymbol());
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
132 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
133 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
134 // 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
135 if(hasFinally)
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
136 selectorargs.push_back(DtoConstUint(0));
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
137
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
138 // personality fn
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
139 llvm::Function* personality_fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_eh_personality");
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
140 LLValue* personality_fn_arg = gIR->ir->CreateBitCast(personality_fn, getPtrToType(LLType::getInt8Ty(gIR->context())));
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
141 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
142
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
143 // eh storage target
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
144 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
145
320
d772927ca496 [svn r341] Fix all regressions between [332] and [340]:
ChristianK
parents: 319
diff changeset
146 // if there is a catch and some catch allocated storage, store exception object
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
147 if(catchToInt.size() && catch_var)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
148 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
149 const LLType* objectTy = DtoType(ClassDeclaration::object->type);
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
150 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
151 }
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 // eh_sel = llvm.eh.selector(eh_ptr, cast(byte*)&_d_eh_personality, <selectorargs>);
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
154 llvm::Function* eh_selector_fn = GET_INTRINSIC_DECL(eh_selector);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
155 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
156
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
157 // 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
158 // then simply branch to the finally chain
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
159 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
160 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
161 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
162 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
163 // 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
164 if(rit->finallyBody)
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
165 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
166 if(switchinst)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
167 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
168
d8357f7004ca [svn r376] Fix bug with finally blocks and labels. The labels would get emitted multiple times and conflict.
ChristianK
parents: 349
diff changeset
169 // 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
170 // give the labels a new scope
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
171 gIR->func()->gen->pushUniqueLabelScope("finally");
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
172 rit->finallyBody->toIR(gIR);
1508
e1e93343fc11 Move function codegen data from IrFunction to new FuncGen.
Christian Kamm <kamm incasoftware de>
parents: 1412
diff changeset
173 gIR->func()->gen->popLabelScope();
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
174 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
175 // 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
176 else
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 if(!switchinst)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
179 {
1571
8d086d552909 IntegerType is now contextifed.
Benjamin Kramer <benny.kra@gmail.com>
parents: 1554
diff changeset
180 switchinst = gIR->ir->CreateSwitch(eh_sel, llvm::BasicBlock::Create(gIR->context(), "switchdefault", gIR->topfunc(), gIR->scopeend()), infos.size());
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
181 gIR->scope() = IRScope(switchinst->getDefaultDest(), gIR->scopeend());
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
182 }
612
d97b017a8aef Fix issue with EH table indices and nested try-catch.
Christian Kamm <kamm incasoftware de>
parents: 479
diff changeset
183 // dubious comment
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
184 // catches matched first get the largest switchval, so do size - unique int
1650
40bd4a0d4870 Update to work with LLVM 2.7.
Tomas Lindquist Olsen
parents: 1584
diff changeset
185 llvm::ConstantInt* switchval = DtoConstUint(catchToInt[rit->catchType]);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
186 // 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
187 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
188 switchinst->addCase(switchval, rit->target);
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
189 }
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
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
192 // 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
193 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
194 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
195 gIR->ir->CreateUnreachable();
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
196
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
197 gIR->scope() = savedscope;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
198 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
199
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
200 LLValue* IRLandingPad::getExceptionStorage()
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
201 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
202 if(!catch_var)
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
203 {
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
204 Logger::println("Making new catch var");
1350
15e9762bb620 Adds explicit alignment information for alloca instructions in general, there's a few cases that still needs to be looked at but this should catch the majority. Fixes ticket #293 .
Tomas Lindquist Olsen <tomas.l.olsen gmail com>
parents: 1228
diff changeset
205 catch_var = DtoAlloca(ClassDeclaration::object->type, "catchvar");
319
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
206 }
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
207 return catch_var;
e9c93739bc4c [svn r340] Rework exception handling to work with nested tryfinally and trycatch.
ChristianK
parents:
diff changeset
208 }