These patches, to LLVM and llvm-gcc, add support for nested
try-catch statements. Previously, only the inner most
catch or filter was being taken into account. Thanks to
inlining it is possible for a function to contain any
number of filters and catches nested within each other
(without inlining filters only occur outermost). To support
this I've junked the eh.filter intrinsic and extended the
eh.selector intrinsic so it can simultaneously contain catches
and filters. To indicate a filter, the number of typeinfos
in the filter is given as an argument, followed by the typeinfos
themselves. For example,
%s = eh.selector(exception,personality,t1,2,t2,t3,t4);
has a catch (typeinfo t1) followed by a filter of length 2
(typeinfos t2 and t3) followed by another catch (typeinfo t4).
This is not very beautiful but it is simple, effective and
unambiguous.
An alternative would have been to keep eh.filter and output
multiple filter/selector intrinsics like this:
%s1 = eh.selector(exception,personality,t4);
%s2 = eh.filter(exception,personality,t2,t3);
%s3 = eh.selector(exception,personality,t1);
(yes, in reverse order). Then %s1 and %s2 would never be used,
and %s3 would be tested against the various typeinfos, even if
they were never mentioned in the %s3 selector itself (eg t4).
It also requires extra mucking around with the live-in markings
for the exception and selector registers produced during codegen.
I decided it was better to enhance eh.selector and get rid of
eh.filter. Note that this means that eh.selector now corresponds
directly to the action sequence in the dwarf eh table.
The testcase shows the difference before and after (I've simplified
the output a bit):
Before:
%eh_select = call @llvm.eh.filter(%eh_ptr, @__gxx_personality_v0,
null) ; "empty" filter [the "null" should not be here - also fixed in
this patch]
After:
%eh_select = call @llvm.eh.selector(%eh_ptr, @__gxx_personality_v0,
i32 0, ; empty filter
@_ZTI3One, ; catch
i32 1, @_ZTI3Two, ; filter of length 1
@_ZTI5Three, @_ZTI4Four, ; two catches
i32 2, @_ZTI4Five, @_ZTI3Six, ; filter of length 2
null) ; catch-all
Ciao,
Duncan.
Index: llvm.master/include/llvm/Intrinsics.td
===================================================================
--- llvm.master.orig/include/llvm/Intrinsics.td 2007-07-03 08:49:15.000000000 +0200
+++ llvm.master/include/llvm/Intrinsics.td 2007-07-03 17:13:45.000000000 +0200
@@ -231,8 +231,6 @@
def int_eh_exception : Intrinsic<[llvm_ptr_ty]>;
def int_eh_selector : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty,
llvm_vararg_ty]>;
-def int_eh_filter : Intrinsic<[llvm_i32_ty, llvm_ptr_ty, llvm_ptr_ty,
- llvm_vararg_ty]>;
def int_eh_typeid_for : Intrinsic<[llvm_i32_ty, llvm_ptr_ty]>;
//===---------------- Generic Variable Attribute Intrinsics----------------===//
Index: llvm.master/lib/CodeGen/IntrinsicLowering.cpp
===================================================================
--- llvm.master.orig/lib/CodeGen/IntrinsicLowering.cpp 2007-07-03 08:49:15.000000000 +0200
+++ llvm.master/lib/CodeGen/IntrinsicLowering.cpp 2007-07-03 14:43:18.000000000 +0200
@@ -708,7 +708,6 @@
case Intrinsic::dbg_declare:
case Intrinsic::eh_exception:
case Intrinsic::eh_selector:
- case Intrinsic::eh_filter:
break; // Simply strip out debugging and eh intrinsics
case Intrinsic::var_annotation:
Index: llvm.master/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
--- llvm.master.orig/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp 2007-07-03 08:49:36.000000000 +0200
+++ llvm.master/lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp 2007-07-03 19:35:36.000000000 +0200
@@ -205,12 +205,11 @@
};
}
-/// isFilterOrSelector - Return true if this instruction is a call to the
-/// eh.filter or the eh.selector intrinsic.
-static bool isFilterOrSelector(Instruction *I) {
+/// isSelector - Return true if this instruction is a call to the
+/// eh.selector intrinsic.
+static bool isSelector(Instruction *I) {
if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I))
- return II->getIntrinsicID() == Intrinsic::eh_selector
- || II->getIntrinsicID() == Intrinsic::eh_filter;
+ return II->getIntrinsicID() == Intrinsic::eh_selector;
return false;
}
@@ -2293,12 +2292,12 @@
}
}
-/// ExtractGlobalVariable - If C is a global variable, or a bitcast of one
+/// ExtractGlobalVariable - If V is a global variable, or a bitcast of one
/// (possibly constant folded), return it. Otherwise return NULL.
-static GlobalVariable *ExtractGlobalVariable (Constant *C) {
- if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C))
+static GlobalVariable *ExtractGlobalVariable (Value *V) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(V))
return GV;
- else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
+ else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
if (CE->getOpcode() == Instruction::BitCast)
return dyn_cast<GlobalVariable>(CE->getOperand(0));
else if (CE->getOpcode() == Instruction::GetElementPtr) {
@@ -2311,8 +2310,16 @@
return NULL;
}
+/// ExtractTypeInfo - Extracts the type info from a value.
+static GlobalVariable *ExtractTypeInfo (Value *V) {
+ GlobalVariable *GV = ExtractGlobalVariable(V);
+ assert (GV || isa<ConstantPointerNull>(V) &&
+ "TypeInfo must be a global variable or NULL");
+ return GV;
+}
+
/// addCatchInfo - Extract the personality and type infos from an eh.selector
-/// or eh.filter call, and add them to the specified machine basic block.
+/// call, and add them to the specified machine basic block.
static void addCatchInfo(CallInst &I, MachineModuleInfo *MMI,
MachineBasicBlock *MBB) {
// Inform the MachineModuleInfo of the personality for this landing pad.
@@ -2325,17 +2332,38 @@
// Gather all the type infos for this landing pad and pass them along to
// MachineModuleInfo.
std::vector<GlobalVariable *> TyInfo;
- for (unsigned i = 3, N = I.getNumOperands(); i < N; ++i) {
- Constant *C = cast<Constant>(I.getOperand(i));
- GlobalVariable *GV = ExtractGlobalVariable(C);
- assert (GV || isa<ConstantPointerNull>(C) &&
- "TypeInfo must be a global variable or NULL");
- TyInfo.push_back(GV);
+ unsigned N = I.getNumOperands();
+
+ for (unsigned i = N - 1; i > 2; --i) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(I.getOperand(i))) {
+ unsigned FilterLength = CI->getZExtValue();
+ unsigned FirstCatch = i + FilterLength + 1;
+ assert (FirstCatch <= N && "Invalid filter length");
+
+ if (FirstCatch < N) {
+ TyInfo.reserve(N - FirstCatch);
+ for (unsigned j = FirstCatch; j < N; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+ MMI->addCatchTypeInfo(MBB, TyInfo);
+ TyInfo.clear();
+ }
+
+ TyInfo.reserve(FilterLength);
+ for (unsigned j = i + 1; j < FirstCatch; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
+ MMI->addFilterTypeInfo(MBB, TyInfo);
+ TyInfo.clear();
+
+ N = i;
+ }
}
- if (I.getCalledFunction()->getIntrinsicID() == Intrinsic::eh_filter)
- MMI->addFilterTypeInfo(MBB, TyInfo);
- else
+
+ if (N > 3) {
+ TyInfo.reserve(N - 3);
+ for (unsigned j = 3; j < N; ++j)
+ TyInfo.push_back(ExtractTypeInfo(I.getOperand(j)));
MMI->addCatchTypeInfo(MBB, TyInfo);
+ }
}
/// propagateEHRegister - The specified EH register is required in a successor
@@ -2483,8 +2511,7 @@
return 0;
}
- case Intrinsic::eh_selector:
- case Intrinsic::eh_filter:{
+ case Intrinsic::eh_selector:{
MachineModuleInfo *MMI = DAG.getMachineModuleInfo();
if (ExceptionHandling && MMI) {
@@ -2518,10 +2545,7 @@
if (MMI) {
// Find the type id for the given typeinfo.
- Constant *C = cast<Constant>(I.getOperand(1));
- GlobalVariable *GV = ExtractGlobalVariable(C);
- assert (GV || isa<ConstantPointerNull>(C) &&
- "TypeInfo must be a global variable or NULL");
+ GlobalVariable *GV = ExtractTypeInfo(I.getOperand(1));
unsigned TypeID = MMI->getTypeIDFor(GV);
setValue(&I, DAG.getConstant(TypeID, MVT::i32));
@@ -4297,7 +4321,7 @@
assert(!FLI.MBBMap[SrcBB]->isLandingPad() &&
"Copying catch info out of a landing pad!");
for (BasicBlock::iterator I = SrcBB->begin(), E = --SrcBB->end(); I != E; ++I)
- if (isFilterOrSelector(I)) {
+ if (isSelector(I)) {
// Apply the catch info to DestBB.
addCatchInfo(cast<CallInst>(*I), MMI, FLI.MBBMap[DestBB]);
#ifndef NDEBUG
@@ -4341,19 +4365,19 @@
// function and list of typeids logically belong to the invoke (or, if you
// like, the basic block containing the invoke), and need to be associated
// with it in the dwarf exception handling tables. Currently however the
- // information is provided by intrinsics (eh.filter and eh.selector) that
- // can be moved to unexpected places by the optimizers: if the unwind edge
- // is critical, then breaking it can result in the intrinsics being in the
- // successor of the landing pad, not the landing pad itself. This results
- // in exceptions not being caught because no typeids are associated with
- // the invoke. This may not be the only way things can go wrong, but it
- // is the only way we try to work around for the moment.
+ // information is provided by an intrinsic (eh.selector) that can be moved
+ // to unexpected places by the optimizers: if the unwind edge is critical,
+ // then breaking it can result in the intrinsics being in the successor of
+ // the landing pad, not the landing pad itself. This results in exceptions
+ // not being caught because no typeids are associated with the invoke.
+ // This may not be the only way things can go wrong, but it is the only way
+ // we try to work around for the moment.
BranchInst *Br = dyn_cast<BranchInst>(LLVMBB->getTerminator());
if (Br && Br->isUnconditional()) { // Critical edge?
BasicBlock::iterator I, E;
for (I = LLVMBB->begin(), E = --LLVMBB->end(); I != E; ++I)
- if (isFilterOrSelector(I))
+ if (isSelector(I))
break;
if (I == E)
Index: llvm.master/docs/ExceptionHandling.html
===================================================================
--- llvm.master.orig/docs/ExceptionHandling.html 2007-07-03 08:49:15.000000000 +0200
+++ llvm.master/docs/ExceptionHandling.html 2007-07-03 08:50:10.000000000 +0200
@@ -29,7 +29,6 @@
<ol>
<li><a href="#llvm_eh_exception"><tt>llvm.eh.exception</tt></a></li>
<li><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a></li>
- <li><a href="#llvm_eh_filter"><tt>llvm.eh.filter</tt></a></li>
<li><a href="#llvm_eh_typeid_for"><tt>llvm.eh.typeid.for</tt></a></li>
</ol></li>
<li><a href="#asm">Asm Table Formats</a>
@@ -212,13 +211,18 @@
<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a minimum of
three arguments. The first argument is the reference to the exception
structure. The second argument is a reference to the personality function to be
-used for this try catch sequence. The remaining arguments are references to the
-type infos for each of the catch statements in the order they should be tested.
+used for this try catch sequence. Each of the remaining arguments is either a
+reference to the type info for a catch statement, or a non-negative integer
+followed by that many type info references, representing a
+<a href="#throw_filters">filter</a>.
+The exception is tested against the arguments sequentially from first to last.
The <i>catch all</i> (...) is represented with a <tt>null i8*</tt>. The result
-of the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is the index of
-the type info in the corresponding exception table. The LLVM C++ front end
-generates code to save this value in an alloca location for further use in the
-landing pad and catch code.</p>
+of the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a positive
+number if the exception matched a type info, a negative number if it matched a
+filter, and zero if it didn't match anything. If a type info matched then the
+returned value is the index of the type info in the exception table.
+The LLVM C++ front end generates code to save this value in an alloca location
+for further use in the landing pad and catch code.</p>
<p>Once the landing pad has the type info selector, the code branches to the
code for the first catch. The catch then checks the value of the type info
@@ -268,12 +272,12 @@
<p>C++ allows the specification of which exception types that can be thrown from
a function. To represent this a top level landing pad may exist to filter out
invalid types. To express this in LLVM code the landing pad will call <a
-href="#llvm_eh_filter"><tt>llvm.eh.filter</tt></a> instead of <a
href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a>. The arguments are the
-same, but what gets created in the exception table is different. <a
-href="#llvm_eh_filter"><tt>llvm.eh.filter</tt></a> will return a negative value
-if it doesn't find a match. If no match is found then a call to
-<tt>__cxa_call_unexpected</tt> should be made, otherwise
+number of different type infos the function may throw, followed by the type
+infos themselves.
+<a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> will return a negative
+value if the exception does not match any of the type infos. If no match is
+found then a call to <tt>__cxa_call_unexpected</tt> should be made, otherwise
<tt>_Unwind_Resume</tt>. Each of these functions require a reference to the
exception structure.</p>
@@ -326,32 +330,16 @@
<p><a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> takes a minimum of
three arguments. The first argument is the reference to the exception
structure. The second argument is a reference to the personality function to be
-used for this try catch sequence. The remaining arguments are references to the
-type infos for each of the catch statements in the order they should be tested.
-The <i>catch all</i> (...) is represented with a <tt>null i8*</tt>.</p>
-
-</div>
-
-<!-- ======================================================================= -->
-<div class="doc_subsubsection">
- <a name="llvm_eh_filter">llvm.eh.filter</a>
-</div>
-
-<div class="doc_text">
-<pre>
- i32 %<a href="#llvm_eh_filter">llvm.eh.filter</a>(i8*, i8*, i8*, ...)
-</pre>
-
-<p>This intrinsic indicates that the exception selector is available at this
-point in the code. The backend will replace this intrinsic with code to fetch
-the second argument of a call. The effect is that the intrinsic result is the
-exception selector.</p>
-
-<p><a href="#llvm_eh_filter"><tt>llvm.eh.filter</tt></a> takes a minimum of
-three arguments. The first argument is the reference to the exception
-structure. The second argument is a reference to the personality function to be
-used for this function. The remaining arguments are references to the type infos
-for each type that can be thrown by the current function.</p>
+used for this try catch sequence. Each of the remaining arguments is either a
+reference to the type info for a catch statement, or a non-negative integer
+followed by that many type info references, representing a
+<a href="#throw_filters">filter</a>.
+The exception is tested against the arguments sequentially from first to last.
+The <i>catch all</i> (...) is represented with a <tt>null i8*</tt>. The result
+of the <a href="#llvm_eh_selector"><tt>llvm.eh.selector</tt></a> is a positive
+number if the exception matched a type info, a negative number if it matched a
+filter, and zero if it didn't match anything. If a type info matched then the
+returned value is the index of the type info in the exception table.</p>
</div>
@@ -427,15 +415,6 @@
<ol>
-<li><p>Need to create landing pads for code in between explicit landing pads.
-The landing pads will have a zero action and a NULL landing pad address and are
-used to inform the runtime that the exception should be rethrown.</li></p>
-
-<li><p>Actions for a given function should be folded to save space.</p></li>
-
-<li><p>Filters for inlined functions need to be handled more extensively.
-Currently it's hardwired for one filter per function.</li></p>
-
<li><p>Testing/Testing/Testing.</li></p>
</ol>
Index: gcc/llvm-convert.cpp
===================================================================
--- gcc/llvm-convert.cpp (revision 362)
+++ gcc/llvm-convert.cpp (working copy)
@@ -350,7 +350,6 @@
ExceptionSelectorValue = 0;
FuncEHException = 0;
FuncEHSelector = 0;
- FuncEHFilter = 0;
FuncEHGetTypeID = 0;
FuncCPPPersonality = 0;
FuncUnwindResume = 0;
@@ -1965,16 +1964,18 @@
/// GatherTypeInfo - Walk through the expression gathering all the
/// typeinfos that are used.
void TreeToLLVM::GatherTypeInfo(tree exp,
- std::vector<Value *> &TypeInfos) {
+ std::vector<Constant *> &TypeInfos) {
if (TREE_CODE(exp) == CATCH_EXPR || TREE_CODE(exp) == EH_FILTER_EXPR) {
tree Types = TREE_CODE(exp) == CATCH_EXPR ? CATCH_TYPES(exp)
: EH_FILTER_TYPES(exp);
if (!Types) {
- // Catch all.
- TypeInfos.push_back(
- Constant::getNullValue(PointerType::get(Type::Int8Ty))
- );
+ // Catch all or empty filter.
+ if (TREE_CODE(exp) == CATCH_EXPR)
+ // Catch all.
+ TypeInfos.push_back(
+ Constant::getNullValue(PointerType::get(Type::Int8Ty))
+ );
} else if (TREE_CODE(Types) != TREE_LIST) {
// Construct typeinfo object. Each call will produce a new expression
// even if duplicate.
@@ -1982,7 +1983,7 @@
// Produce value. Duplicate typeinfo get folded here.
Value *TypeInfo = Emit(TypeInfoNopExpr, 0);
// Capture typeinfo.
- TypeInfos.push_back(TypeInfo);
+ TypeInfos.push_back(cast<Constant>(TypeInfo));
} else {
for (; Types; Types = TREE_CHAIN (Types)) {
// Construct typeinfo object. Each call will produce a new expression
@@ -1991,7 +1992,7 @@
// Produce value. Duplicate typeinfo get folded here.
Value *TypeInfo = Emit(TypeInfoNopExpr, 0);
// Capture typeinfo.
- TypeInfos.push_back(TypeInfo);
+ TypeInfos.push_back(cast<Constant>(TypeInfo));
}
}
} else if (TREE_CODE(exp) == STATEMENT_LIST) {
@@ -2007,47 +2008,53 @@
/// AddLandingPad - Insert code to fetch and save the exception and exception
/// selector.
void TreeToLLVM::AddLandingPad() {
- tree TryCatch = 0;
- for (std::vector<EHScope>::reverse_iterator I = CurrentEHScopes.rbegin(),
- E = CurrentEHScopes.rend();
- I != E; ++I) {
- if (TREE_CODE(I->TryExpr) == TRY_CATCH_EXPR) {
- TryCatch = I->TryExpr;
- break;
- }
- }
-
CreateExceptionValues();
// Fetch and store the exception.
Value *Ex = Builder.CreateCall(FuncEHException, "eh_ptr");
Builder.CreateStore(Ex, ExceptionValue);
- if (!TryCatch) return;
-
- // Gather the typeinfo.
- std::vector<Value *> TypeInfos;
- tree Catches = TREE_OPERAND(TryCatch, 1);
- GatherTypeInfo(Catches, TypeInfos);
-
- // Choose type of landing pad type.
- Function *F = FuncEHSelector;
-
- if (TREE_CODE(Catches) == STATEMENT_LIST &&
- !tsi_end_p(tsi_start(Catches)) &&
- TREE_CODE(tsi_stmt(tsi_start(Catches))) == EH_FILTER_EXPR) {
- F = FuncEHFilter;
- }
-
- // Fetch and store exception handler.
+ // Fetch and store the exception selector.
std::vector<Value*> Args;
- Args.push_back(Builder.CreateLoad(ExceptionValue, "eh_ptr"));
- Args.push_back(CastToType(Instruction::BitCast, FuncCPPPersonality,
- PointerType::get(Type::Int8Ty)));
- for (unsigned i = 0, N = TypeInfos.size(); i < N; ++i)
- Args.push_back(TypeInfos[i]);
- Value *Select = Builder.CreateCall(F, &Args[0], Args.size(), "eh_select");
- Builder.CreateStore(Select, ExceptionSelectorValue);
+
+ for (std::vector<EHScope>::reverse_iterator I = CurrentEHScopes.rbegin(),
+ E = CurrentEHScopes.rend(); I != E; ++I) {
+ if (TREE_CODE(I->TryExpr) == TRY_CATCH_EXPR) {
+ if (I->InfosType == Unknown) {
+ // Gather the type info and determine the catch type.
+ tree Catches = TREE_OPERAND(I->TryExpr, 1);
+ GatherTypeInfo(Catches, I->TypeInfos);
+ I->InfosType = (TREE_CODE(Catches) == STATEMENT_LIST &&
+ !tsi_end_p(tsi_start(Catches)) &&
+ TREE_CODE(tsi_stmt(tsi_start(Catches))) ==
+ EH_FILTER_EXPR) ? FilterExpr : CatchList;
+ }
+
+ if (I->InfosType == CatchList && !I->TypeInfos.size())
+ continue;
+
+ // Lazily add the exception and the personality function.
+ if (!Args.size()) {
+ Args.push_back(Builder.CreateLoad(ExceptionValue, "eh_ptr"));
+ Args.push_back(CastToType(Instruction::BitCast, FuncCPPPersonality,
+ PointerType::get(Type::Int8Ty)));
+ }
+
+ if (I->InfosType == FilterExpr)
+ // Filter - note the size.
+ Args.push_back(ConstantInt::get(Type::Int32Ty, I->TypeInfos.size()));
+
+ Args.reserve(Args.size() + I->TypeInfos.size());
+ for (unsigned j = 0, N = I->TypeInfos.size(); j < N; ++j)
+ Args.push_back(I->TypeInfos[j]);
+ }
+ }
+
+ if (Args.size()) {
+ Value *Select = Builder.CreateCall(FuncEHSelector, &Args[0], Args.size(),
+ "eh_select");
+ Builder.CreateStore(Select, ExceptionSelectorValue);
+ }
}
@@ -2067,8 +2074,6 @@
Intrinsic::eh_exception);
FuncEHSelector = Intrinsic::getDeclaration(TheModule,
Intrinsic::eh_selector);
- FuncEHFilter = Intrinsic::getDeclaration(TheModule,
- Intrinsic::eh_filter);
FuncEHGetTypeID = Intrinsic::getDeclaration(TheModule,
Intrinsic::eh_typeid_for);
Index: gcc/llvm-internal.h
===================================================================
--- gcc/llvm-internal.h (revision 362)
+++ gcc/llvm-internal.h (working copy)
@@ -258,25 +258,38 @@
BranchFixup(BranchInst *srcBranch, bool IsExceptionEdge)
: SrcBranch(srcBranch), isExceptionEdge(IsExceptionEdge) {}
};
-
+
+ enum CatchTypes { Unknown = 0, CatchList, FilterExpr };
+
/// EHScope - One of these scopes is maintained for each TRY_CATCH_EXPR and
/// TRY_FINALLY_EXPR blocks that we are currently in.
struct EHScope {
/// TryExpr - This is the actual TRY_CATCH_EXPR or TRY_FINALLY_EXPR.
tree_node *TryExpr;
-
+
/// UnwindBlock - A basic block in this scope that branches to the unwind
/// destination. This is lazily created by the first invoke in this scope.
BasicBlock *UnwindBlock;
-
+
// The basic blocks that are directly in this region.
std::vector<BasicBlock*> Blocks;
-
+
/// BranchFixups - This is a list of fixups we need to process in this scope
/// or in a parent scope.
std::vector<BranchFixup> BranchFixups;
-
- EHScope(tree_node *expr) : TryExpr(expr), UnwindBlock(0) {}
+
+ /// InfosType - The nature of the type infos TryExpr contains: a list of
+ /// CATCH_EXPR (-> CatchList) or an EH_FILTER_EXPR (-> FilterExpr). Equal
+ /// to Unknown if type info information has not yet been gathered.
+ CatchTypes InfosType;
+
+ /// TypeInfos - The type infos corresponding to the catches or filter in
+ /// TryExpr. If InfosType is Unknown then this information has not yet
+ /// been gathered.
+ std::vector<Constant *> TypeInfos;
+
+ EHScope(tree_node *expr) :
+ TryExpr(expr), UnwindBlock(0), InfosType(Unknown) {}
};
/// CurrentEHScopes - The current stack of exception scopes we are
@@ -305,10 +318,6 @@
///
Function *FuncEHSelector;
- /// FuncEHFilter - Function used to handle the exception filtering.
- ///
- Function *FuncEHFilter;
-
/// FuncEHGetTypeID - Function used to return type id for give typeinfo.
///
Function *FuncEHGetTypeID;
@@ -457,7 +466,7 @@
private:
/// GatherTypeInfo - Walk through the expression gathering all the
/// typeinfos that are used.
- void GatherTypeInfo(tree_node *exp, std::vector<Value *> &TypeInfos);
+ void GatherTypeInfo(tree_node *exp, std::vector<Constant *> &TypeInfos);
/// AddLandingPad - Insert code to fetch and save the exception and exception
/// selector.
// RUN: %llvmgxx %s -S -emit-llvm -O2 -o - | \
// RUN: ignore grep {eh\.selector.*One.*Two.*Three.*Four.*Five.*Six.*null} | \
// RUN: wc -l | grep {\[02\]}
extern void X(void);
struct One {};
struct Two {};
struct Three {};
struct Four {};
struct Five {};
struct Six {};
static void A(void) throw ()
{
X();
}
static void B(void) throw (Two)
{
try { A(); } catch (One) {}
}
static void C(void) throw (Six, Five)
{
try { B(); } catch (Three) {} catch (Four) {}
}
int main ()
{
try { C(); } catch (...) {}
}
_______________________________________________
llvm-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits