-
-
Notifications
You must be signed in to change notification settings - Fork 260
/
irlandingpad.h
125 lines (103 loc) · 3.55 KB
/
irlandingpad.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
//===-- ir/irlandingpad.h - Codegen state for EH blocks ---------*- C++ -*-===//
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
//
// State kept while doing codegen for a single "EH block" consisting of
// of several catch/finally/cleanup clauses. Handles nesting of these blocks.
//
//===----------------------------------------------------------------------===//
#ifndef LDC_IR_IRLANDINGPADINFO_H
#define LDC_IR_IRLANDINGPADINFO_H
#include "statement.h"
#include <deque>
#include <stack>
namespace llvm {
class Type;
class Value;
class BasicBlock;
class Function;
class LandingPadInst;
}
// holds information about a single catch
struct IRLandingPadCatchInfo
{
// default constructor for being able to store in a vector
IRLandingPadCatchInfo() :
target(NULL), end(0), catchStmt(NULL), catchType(0)
{}
IRLandingPadCatchInfo(Catch* catchStmt, llvm::BasicBlock* end);
// codegen the catch block
void toIR();
llvm::BasicBlock *target;
llvm::BasicBlock *end;
Catch *catchStmt;
ClassDeclaration *catchType;
};
// holds information about a single finally
class IRLandingPadCatchFinallyInfo
{
public:
virtual ~IRLandingPadCatchFinallyInfo() {}
virtual void toIR(LLValue *eh_ptr) = 0;
};
class IRLandingPadFinallyStatementInfo : public IRLandingPadCatchFinallyInfo
{
public:
IRLandingPadFinallyStatementInfo(Statement *finallyBody);
// codegen the finally block
void toIR(LLValue *eh_ptr);
private:
// the body of finally
Statement *finallyBody;
};
// holds information about a single try-catch-inally block
struct IRLandingPadScope
{
explicit IRLandingPadScope(llvm::BasicBlock *target_ = NULL) :
target(target_), finally(0), isFinallyCreatedInternally(false) {}
// the target for invokes
llvm::BasicBlock *target;
// information about catch blocks
std::deque<IRLandingPadCatchInfo> catches;
// information about a finally block
IRLandingPadCatchFinallyInfo *finally;
bool isFinallyCreatedInternally;
};
// holds information about all possible catch and finally actions
// and can emit landing pads to be called from the unwind runtime
struct IRLandingPad
{
IRLandingPad() : catch_var(NULL) {}
// creates a new landing pad according to given infos
// and the ones on the stack. also stores it as invoke target
void push(llvm::BasicBlock* inBB);
// add catch information, will be used in next call to push
void addCatch(Catch* catchstmt, llvm::BasicBlock* end);
// add finally statement, will be used in next call to push
void addFinally(Statement* finallyStmt);
// add finally information, will be used in next call to push
void addFinally(IRLandingPadCatchFinallyInfo *finallyInfo);
// builds the most recently constructed landing pad
// and the catch blocks, then pops the landing pad bb
// and its infos
void pop();
// creates or gets storage for exception object
llvm::Value* getExceptionStorage();
private:
friend class IRLandingPadFinallyStatementInfo;
// gets the current landing pad
llvm::BasicBlock* get();
// constructs the landing pad
void constructLandingPad(IRLandingPadScope scope);
// information about try-catch-finally blocks
std::stack<IRLandingPadScope> scopeStack;
IRLandingPadScope unpushedScope;
// storage for the catch variable
llvm::Value* catch_var;
};
#endif