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