diff options
author | Bill Wendling <isanbard@gmail.com> | 2011-08-12 20:24:12 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2011-08-12 20:24:12 +0000 |
commit | e6e8826870bee3facb04f950f0bd725f8a88623d (patch) | |
tree | 5fe10abfdbebc25ea75271004fe7afae60a3943e /lib | |
parent | 79628e92e1f903d50340d4cd3d1ea8c5fff63a87 (diff) | |
download | llvm-e6e8826870bee3facb04f950f0bd725f8a88623d.tar.gz llvm-e6e8826870bee3facb04f950f0bd725f8a88623d.tar.bz2 llvm-e6e8826870bee3facb04f950f0bd725f8a88623d.tar.xz |
Initial commit of the 'landingpad' instruction.
This implements the 'landingpad' instruction. It's used to indicate that a basic
block is a landing pad. There are several restrictions on its use (see
LangRef.html for more detail). These restrictions allow the exception handling
code to gather the information it needs in a much more sane way.
This patch has the definition, implementation, C interface, parsing, and bitcode
support in it.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137501 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AsmParser/LLLexer.cpp | 6 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 42 | ||||
-rw-r--r-- | lib/AsmParser/LLParser.h | 1 | ||||
-rw-r--r-- | lib/AsmParser/LLToken.h | 2 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 38 | ||||
-rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 17 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h | 1 | ||||
-rw-r--r-- | lib/Transforms/Scalar/SCCP.cpp | 1 | ||||
-rw-r--r-- | lib/VMCore/AsmWriter.cpp | 18 | ||||
-rw-r--r-- | lib/VMCore/BasicBlock.cpp | 12 | ||||
-rw-r--r-- | lib/VMCore/Core.cpp | 17 | ||||
-rw-r--r-- | lib/VMCore/Instruction.cpp | 1 | ||||
-rw-r--r-- | lib/VMCore/Instructions.cpp | 89 | ||||
-rw-r--r-- | lib/VMCore/Verifier.cpp | 65 |
15 files changed, 303 insertions, 10 deletions
diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index c3a5a4d0db..fdadd1ba93 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -584,6 +584,11 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(x); KEYWORD(blockaddress); + + KEYWORD(personality); + KEYWORD(cleanup); + KEYWORD(catch); + KEYWORD(filter); #undef KEYWORD // Keywords for types. @@ -653,6 +658,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(shufflevector, ShuffleVector); INSTKEYWORD(extractvalue, ExtractValue); INSTKEYWORD(insertvalue, InsertValue); + INSTKEYWORD(landingpad, LandingPad); #undef INSTKEYWORD // Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 8b30eef3d5..6a4c2a8fb9 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2945,6 +2945,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_insertelement: return ParseInsertElement(Inst, PFS); case lltok::kw_shufflevector: return ParseShuffleVector(Inst, PFS); case lltok::kw_phi: return ParsePHI(Inst, PFS); + case lltok::kw_landingpad: return ParseLandingPad(Inst, PFS); case lltok::kw_call: return ParseCall(Inst, PFS, false); case lltok::kw_tail: return ParseCall(Inst, PFS, true); // Memory. @@ -3519,6 +3520,47 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { return AteExtraComma ? InstExtraComma : InstNormal; } +/// ParseLandingPad +/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? Clause+ +/// Clause +/// ::= 'catch' TypeAndValue +/// ::= 'filter' +/// ::= 'filter' TypeAndValue ( ',' TypeAndValue )* +bool LLParser::ParseLandingPad(Instruction *&Inst, PerFunctionState &PFS) { + Type *Ty = 0; LocTy TyLoc; + Value *PersFn; LocTy PersFnLoc; + LocTy LPLoc = Lex.getLoc(); + + if (ParseType(Ty, TyLoc) || + ParseToken(lltok::kw_personality, "expected 'personality'") || + ParseTypeAndValue(PersFn, PersFnLoc, PFS)) + return true; + + LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, 0); + LP->setCleanup(EatIfPresent(lltok::kw_cleanup)); + + while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ + LandingPadInst::ClauseType CT; + if (EatIfPresent(lltok::kw_catch)) + CT = LandingPadInst::Catch; + else if (EatIfPresent(lltok::kw_filter)) + CT = LandingPadInst::Filter; + else + return TokError("expected 'catch' or 'filter' clause type"); + + Value *V; LocTy VLoc; + if (ParseTypeAndValue(V, VLoc, PFS)) { + delete LP; + return true; + } + + LP->addClause(V); + } + + Inst = LP; + return false; +} + /// ParseCall /// ::= 'tail'? 'call' OptionalCallingConv OptionalAttrs Type Value /// ParameterList OptionalAttrs diff --git a/lib/AsmParser/LLParser.h b/lib/AsmParser/LLParser.h index 815f062026..ef4d3dba9e 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -360,6 +360,7 @@ namespace llvm { bool ParseInsertElement(Instruction *&I, PerFunctionState &PFS); bool ParseShuffleVector(Instruction *&I, PerFunctionState &PFS); int ParsePHI(Instruction *&I, PerFunctionState &PFS); + bool ParseLandingPad(Instruction *&I, PerFunctionState &PFS); bool ParseCall(Instruction *&I, PerFunctionState &PFS, bool isTail); int ParseAlloc(Instruction *&I, PerFunctionState &PFS); int ParseLoad(Instruction *&I, PerFunctionState &PFS, diff --git a/lib/AsmParser/LLToken.h b/lib/AsmParser/LLToken.h index 3da85ad5d7..d22ecf31bd 100644 --- a/lib/AsmParser/LLToken.h +++ b/lib/AsmParser/LLToken.h @@ -124,6 +124,8 @@ namespace lltok { kw_fptoui, kw_fptosi, kw_inttoptr, kw_ptrtoint, kw_bitcast, kw_select, kw_va_arg, + kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter, + kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_unwind, kw_resume, kw_unreachable, diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 8f4e8c3e46..a33705d2dd 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2543,6 +2543,44 @@ bool BitcodeReader::ParseFunctionBody(Function *F) { break; } + case bitc::FUNC_CODE_INST_LANDINGPAD: { + // LANDINGPAD: [ty, val, val, num, (id0,val0 ...)?] + unsigned Idx = 0; + if (Record.size() < 4) + return Error("Invalid LANDINGPAD record"); + Type *Ty = getTypeByID(Record[Idx++]); + if (!Ty) return Error("Invalid LANDINGPAD record"); + Value *PersFn = 0; + if (getValueTypePair(Record, Idx, NextValueNo, PersFn)) + return Error("Invalid LANDINGPAD record"); + + bool IsCleanup = !!Record[Idx++]; + unsigned NumClauses = Record[Idx++]; + LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, NumClauses); + LP->setCleanup(IsCleanup); + for (unsigned J = 0; J != NumClauses; ++J) { + LandingPadInst::ClauseType CT = + LandingPadInst::ClauseType(Record[Idx++]); (void)CT; + Value *Val; + + if (getValueTypePair(Record, Idx, NextValueNo, Val)) { + delete LP; + return Error("Invalid LANDINGPAD record"); + } + + assert((CT != LandingPadInst::Catch || + !isa<ArrayType>(Val->getType())) && + "Catch clause has a invalid type!"); + assert((CT != LandingPadInst::Filter || + isa<ArrayType>(Val->getType())) && + "Filter clause has invalid type!"); + LP->addClause(Val); + } + + I = LP; + break; + } + case bitc::FUNC_CODE_INST_ALLOCA: { // ALLOCA: [instty, opty, op, align] if (Record.size() != 4) return Error("Invalid ALLOCA record"); diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index 12f0715f1a..5b3d96953a 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1165,6 +1165,23 @@ static void WriteInstruction(const Instruction &I, unsigned InstID, break; } + case Instruction::LandingPad: { + const LandingPadInst &LP = cast<LandingPadInst>(I); + Code = bitc::FUNC_CODE_INST_LANDINGPAD; + Vals.push_back(VE.getTypeID(LP.getType())); + PushValueAndType(LP.getPersonalityFn(), InstID, Vals, VE); + Vals.push_back(LP.isCleanup()); + Vals.push_back(LP.getNumClauses()); + for (unsigned I = 0, E = LP.getNumClauses(); I != E; ++I) { + if (LP.isCatch(I)) + Vals.push_back(LandingPadInst::Catch); + else + Vals.push_back(LandingPadInst::Filter); + PushValueAndType(LP.getClause(I), InstID, Vals, VE); + } + break; + } + case Instruction::Alloca: Code = bitc::FUNC_CODE_INST_ALLOCA; Vals.push_back(VE.getTypeID(I.getType())); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp index 438667e005..c1d533582f 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -2985,6 +2985,9 @@ void SelectionDAGBuilder::visitExtractValue(const ExtractValueInst &I) { &Values[0], NumValValues)); } +void SelectionDAGBuilder::visitLandingPad(const LandingPadInst &I) { +} + void SelectionDAGBuilder::visitGetElementPtr(const User &I) { SDValue N = getValue(I.getOperand(0)); Type *Ty = I.getOperand(0)->getType(); diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h index 050b86fb60..776b07072b 100644 --- a/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h +++ b/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h @@ -512,6 +512,7 @@ private: void visitExtractValue(const ExtractValueInst &I); void visitInsertValue(const InsertValueInst &I); + void visitLandingPad(const LandingPadInst &I); void visitGetElementPtr(const User &I); void visitSelect(const User &I); diff --git a/lib/Transforms/Scalar/SCCP.cpp b/lib/Transforms/Scalar/SCCP.cpp index c84d67b49a..59d96bee1c 100644 --- a/lib/Transforms/Scalar/SCCP.cpp +++ b/lib/Transforms/Scalar/SCCP.cpp @@ -515,6 +515,7 @@ private: void visitShuffleVectorInst(ShuffleVectorInst &I); void visitExtractValueInst(ExtractValueInst &EVI); void visitInsertValueInst(InsertValueInst &IVI); + void visitLandingPadInst(LandingPadInst &I) { markAnythingOverdefined(&I); } // Instructions that cannot be folded away. void visitStoreInst (StoreInst &I); diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 62214a1a2e..d166604113 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -1748,6 +1748,24 @@ void AssemblyWriter::printInstruction(const Instruction &I) { writeOperand(I.getOperand(1), true); for (const unsigned *i = IVI->idx_begin(), *e = IVI->idx_end(); i != e; ++i) Out << ", " << *i; + } else if (const LandingPadInst *LPI = dyn_cast<LandingPadInst>(&I)) { + Out << ' '; + TypePrinter.print(I.getType(), Out); + Out << " personality "; + writeOperand(I.getOperand(0), true); Out << '\n'; + + if (LPI->isCleanup()) + Out << " cleanup"; + + for (unsigned i = 0, e = LPI->getNumClauses(); i != e; ++i) { + if (i != 0 || LPI->isCleanup()) Out << "\n"; + if (LPI->isCatch(i)) + Out << " catch "; + else + Out << " filter "; + + writeOperand(LPI->getClause(i), true); + } } else if (isa<ReturnInst>(I) && !Operand) { Out << " void"; } else if (const CallInst *CI = dyn_cast<CallInst>(&I)) { diff --git a/lib/VMCore/BasicBlock.cpp b/lib/VMCore/BasicBlock.cpp index 5fab1d39ae..3e29f05d51 100644 --- a/lib/VMCore/BasicBlock.cpp +++ b/lib/VMCore/BasicBlock.cpp @@ -348,3 +348,15 @@ void BasicBlock::replaceSuccessorsPhiUsesWith(BasicBlock *New) { } } } + +/// isLandingPad - Return true if this basic block is a landing pad. I.e., it's +/// the destination of the 'unwind' edge of an invoke instruction. +bool BasicBlock::isLandingPad() const { + return isa<LandingPadInst>(getFirstNonPHI()); +} + +/// getLandingPadInst() - Return the landingpad instruction associated with +/// the landing pad. +LandingPadInst *BasicBlock::getLandingPadInst() { + return dyn_cast<LandingPadInst>(getFirstNonPHI()); +} diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 883ad91343..7e87103a0d 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -1683,6 +1683,14 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef B, LLVMValueRef Fn, Name)); } +LLVMValueRef LLVMBuildLandingPad(LLVMBuilderRef B, LLVMTypeRef Ty, + LLVMValueRef PersFn, unsigned NumClauses, + const char *Name) { + return wrap(unwrap(B)->CreateLandingPad(unwrap(Ty), + cast<Function>(unwrap(PersFn)), + NumClauses, Name)); +} + LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn) { return wrap(unwrap(B)->CreateResume(unwrap(Exn))); } @@ -1700,6 +1708,15 @@ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest) { unwrap<IndirectBrInst>(IndirectBr)->addDestination(unwrap(Dest)); } +void LLVMAddClause(LLVMValueRef LandingPad, LLVMValueRef ClauseVal) { + unwrap<LandingPadInst>(LandingPad)-> + addClause(cast<Constant>(unwrap(ClauseVal))); +} + +void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val) { + unwrap<LandingPadInst>(LandingPad)->setCleanup(Val); +} + /*--.. Arithmetic ..........................................................--*/ LLVMValueRef LLVMBuildAdd(LLVMBuilderRef B, LLVMValueRef LHS, LLVMValueRef RHS, diff --git a/lib/VMCore/Instruction.cpp b/lib/VMCore/Instruction.cpp index 216bb35d4d..eadcd098b1 100644 --- a/lib/VMCore/Instruction.cpp +++ b/lib/VMCore/Instruction.cpp @@ -162,6 +162,7 @@ const char *Instruction::getOpcodeName(unsigned OpCode) { case ShuffleVector: return "shufflevector"; case ExtractValue: return "extractvalue"; case InsertValue: return "insertvalue"; + case LandingPad: return "landingpad"; default: return "<Invalid operator> "; } diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index 8966bbe1dd..2f6c069a2d 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -166,6 +166,88 @@ Value *PHINode::hasConstantValue() const { return ConstantValue; } +//===----------------------------------------------------------------------===// +// LandingPadInst Implementation +//===----------------------------------------------------------------------===// + +LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + Instruction *InsertBefore) + : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore) { + init(PersonalityFn, 1 + NumReservedValues, NameStr); +} + +LandingPadInst::LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd) { + init(PersonalityFn, 1 + NumReservedValues, NameStr); +} + +LandingPadInst::LandingPadInst(const LandingPadInst &LP) + : Instruction(LP.getType(), Instruction::LandingPad, + allocHungoffUses(LP.getNumOperands()), LP.getNumOperands()), + ReservedSpace(LP.getNumOperands()) { + Use *OL = OperandList, *InOL = LP.OperandList; + for (unsigned I = 0, E = ReservedSpace; I != E; ++I) + OL[I] = InOL[I]; + + setCleanup(LP.isCleanup()); +} + +LandingPadInst::~LandingPadInst() { + dropHungoffUses(); +} + +LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedClauses, + const Twine &NameStr, + Instruction *InsertBefore) { + return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr, + InsertBefore); +} + +LandingPadInst *LandingPadInst::Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedClauses, + const Twine &NameStr, + BasicBlock *InsertAtEnd) { + return new LandingPadInst(RetTy, PersonalityFn, NumReservedClauses, NameStr, + InsertAtEnd); +} + +void LandingPadInst::init(Value *PersFn, unsigned NumReservedValues, + const Twine &NameStr) { + ReservedSpace = NumReservedValues; + NumOperands = 1; + OperandList = allocHungoffUses(ReservedSpace); + OperandList[0] = PersFn; + setName(NameStr); + setCleanup(false); +} + +/// growOperands - grow operands - This grows the operand list in response to a +/// push_back style of operation. This grows the number of ops by 2 times. +void LandingPadInst::growOperands(unsigned Size) { + unsigned e = getNumOperands(); + if (ReservedSpace >= e + Size) return; + ReservedSpace = (e + Size / 2) * 2; + + Use *NewOps = allocHungoffUses(ReservedSpace); + Use *OldOps = OperandList; + for (unsigned i = 0; i != e; ++i) + NewOps[i] = OldOps[i]; + + OperandList = NewOps; + Use::zap(OldOps, OldOps + e, true); +} + +void LandingPadInst::addClause(Value *Val) { + unsigned OpNo = getNumOperands(); + growOperands(1); + assert(OpNo < ReservedSpace && "Growing didn't work!"); + ++NumOperands; + OperandList[OpNo] = Val; +} //===----------------------------------------------------------------------===// // CallInst Implementation @@ -494,6 +576,9 @@ void InvokeInst::removeAttribute(unsigned i, Attributes attr) { setAttributes(PAL); } +LandingPadInst *InvokeInst::getLandingPadInst() const { + return cast<LandingPadInst>(getUnwindDest()->getFirstNonPHI()); +} //===----------------------------------------------------------------------===// // ReturnInst Implementation @@ -3344,6 +3429,10 @@ PHINode *PHINode::clone_impl() const { return new PHINode(*this); } +LandingPadInst *LandingPadInst::clone_impl() const { + return new LandingPadInst(*this); +} + ReturnInst *ReturnInst::clone_impl() const { return new(getNumOperands()) ReturnInst(*this); } diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp index 415c85e142..7635998a59 100644 --- a/lib/VMCore/Verifier.cpp +++ b/lib/VMCore/Verifier.cpp @@ -35,6 +35,12 @@ // * It is illegal to have a ret instruction that returns a value that does not // agree with the function return value type. // * Function call argument types match the function prototype +// * A landing pad is defined by a landingpad instruction, and can be jumped to +// only by the unwind edge of an invoke instruction. +// * A landingpad instruction must be the first non-PHI instruction in the +// block. +// * All landingpad instructions must use the same personality function with +// the same function. // * All other things that are tested by asserts spread about the code... // //===----------------------------------------------------------------------===// @@ -131,18 +137,22 @@ namespace { /// already. SmallPtrSet<MDNode *, 32> MDNodes; + /// PersonalityFn - The personality function referenced by the + /// LandingPadInsts. All LandingPadInsts within the same function must use + /// the same personality function. + const Value *PersonalityFn; + Verifier() - : FunctionPass(ID), - Broken(false), RealPass(true), action(AbortProcessAction), - Mod(0), Context(0), DT(0), MessagesStr(Messages) { - initializeVerifierPass(*PassRegistry::getPassRegistry()); - } + : FunctionPass(ID), Broken(false), RealPass(true), + action(AbortProcessAction), Mod(0), Context(0), DT(0), + MessagesStr(Messages), PersonalityFn(0) { + initializeVerifierPass(*PassRegistry::getPassRegistry()); + } explicit Verifier(VerifierFailureAction ctn) - : FunctionPass(ID), - Broken(false), RealPass(true), action(ctn), Mod(0), Context(0), DT(0), - MessagesStr(Messages) { - initializeVerifierPass(*PassRegistry::getPassRegistry()); - } + : FunctionPass(ID), Broken(false), RealPass(true), action(ctn), Mod(0), + Context(0), DT(0), MessagesStr(Messages), PersonalityFn(0) { + initializeVerifierPass(*PassRegistry::getPassRegistry()); + } bool doInitialization(Module &M) { Mod = &M; @@ -165,6 +175,7 @@ namespace { visit(F); InstsInThisBlock.clear(); + PersonalityFn = 0; // If this is a real pass, in a pass manager, we must abort before // returning back to the pass manager, or else the pass manager may try to @@ -284,6 +295,7 @@ namespace { void visitAllocaInst(AllocaInst &AI); void visitExtractValueInst(ExtractValueInst &EVI); void visitInsertValueInst(InsertValueInst &IVI); + void visitLandingPadInst(LandingPadInst &LPI); void VerifyCallSite(CallSite CS); bool PerformTypeCheck(Intrinsic::ID ID, Function *F, Type *Ty, @@ -1401,6 +1413,39 @@ void Verifier::visitInsertValueInst(InsertValueInst &IVI) { visitInstruction(IVI); } +void Verifier::visitLandingPadInst(LandingPadInst &LPI) { + BasicBlock *BB = LPI.getParent(); + + // The landingpad instruction is ill-formed if it doesn't have any clauses and + // isn't a cleanup. + Assert1(LPI.getNumClauses() > 0 || LPI.isCleanup(), + "LandingPadInst needs at least one clause or to be a cleanup.", &LPI); + + // The landingpad instruction defines its parent as a landing pad block. The + // landing pad block may be branched to only by the unwind edge of an invoke. + for (pred_iterator I = pred_begin(BB), E = pred_end(BB); I != E; ++I) { + const InvokeInst *II = dyn_cast<InvokeInst>((*I)->getTerminator()); + Assert1(II && II->getUnwindDest() == BB, + "Block containing LandingPadInst must be jumped to " + "only by the unwind edge of an invoke.", &LPI); + } + + // The landingpad instruction must be the first non-PHI instruction in the + // block. + Assert1(LPI.getParent()->getLandingPadInst() == &LPI, + "LandingPadInst not the first non-PHI instruction in the block.", + &LPI); + + // The personality functions for all landingpad instructions within the same + // function should match. + if (PersonalityFn) + Assert1(LPI.getPersonalityFn() == PersonalityFn, + "Personality function doesn't match others in function", &LPI); + PersonalityFn = LPI.getPersonalityFn(); + + visitInstruction(LPI); +} + /// verifyInstruction - Verify that an instruction is well formed. /// void Verifier::visitInstruction(Instruction &I) { |