diff options
27 files changed, 742 insertions, 106 deletions
diff --git a/docs/LangRef.html b/docs/LangRef.html index ab98d3d835..40affb7e91 100644 --- a/docs/LangRef.html +++ b/docs/LangRef.html @@ -123,6 +123,7 @@ <li><a href="#i_indirectbr">'<tt>indirectbr</tt>' Instruction</a></li> <li><a href="#i_invoke">'<tt>invoke</tt>' Instruction</a></li> <li><a href="#i_unwind">'<tt>unwind</tt>' Instruction</a></li> + <li><a href="#i_resume">'<tt>resume</tt>' Instruction</a></li> <li><a href="#i_unreachable">'<tt>unreachable</tt>' Instruction</a></li> </ol> </li> @@ -2942,13 +2943,14 @@ should not be exposed to source languages.</p> control flow, not values (the one exception being the '<a href="#i_invoke"><tt>invoke</tt></a>' instruction).</p> -<p>There are seven different terminator instructions: the +<p>There are eight different terminator instructions: the '<a href="#i_ret"><tt>ret</tt></a>' instruction, the '<a href="#i_br"><tt>br</tt></a>' instruction, the '<a href="#i_switch"><tt>switch</tt></a>' instruction, the '<a href="#i_indirectbr">'<tt>indirectbr</tt></a>' Instruction, the '<a href="#i_invoke"><tt>invoke</tt></a>' instruction, the - '<a href="#i_unwind"><tt>unwind</tt></a>' instruction, and the + '<a href="#i_unwind"><tt>unwind</tt></a>' instruction, the + '<a href="#i_resume"><tt>resume</tt></a>' instruction, and the '<a href="#i_unreachable"><tt>unreachable</tt></a>' instruction.</p> <!-- _______________________________________________________________________ --> @@ -3272,6 +3274,35 @@ that the invoke/unwind semantics are likely to change in future versions.</p> <!-- _______________________________________________________________________ --> <h4> + <a name="i_resume">'<tt>resume</tt>' Instruction</a> +</h4> + +<div> + +<h5>Syntax:</h5> +<pre> + resume <type> <value> +</pre> + +<h5>Overview:</h5> +<p>The '<tt>resume</tt>' instruction is a terminator instruction that has no + successors. Its operand must have the same type as the result of any + '<tt>landingpad</tt>' instruction in the same function.</p> + +<h5>Semantics:</h5> +<p>The '<tt>resume</tt>' instruction resumes propagation of an existing + (in-flight) exception.</p> + +<h5>Example:</h5> +<pre> + resume { i8*, i32 } %exn +</pre> + +</div> + +<!-- _______________________________________________________________________ --> + +<h4> <a name="i_unreachable">'<tt>unreachable</tt>' Instruction</a> </h4> diff --git a/include/llvm-c/Core.h b/include/llvm-c/Core.h index c9522a6666..3019d9231d 100644 --- a/include/llvm-c/Core.h +++ b/include/llvm-c/Core.h @@ -126,67 +126,69 @@ typedef enum { LLVMIndirectBr = 4, LLVMInvoke = 5, LLVMUnwind = 6, - LLVMUnreachable = 7, + LLVMResume = 7, + LLVMUnreachable = 8, /* Standard Binary Operators */ - LLVMAdd = 8, - LLVMFAdd = 9, - LLVMSub = 10, - LLVMFSub = 11, - LLVMMul = 12, - LLVMFMul = 13, - LLVMUDiv = 14, - LLVMSDiv = 15, - LLVMFDiv = 16, - LLVMURem = 17, - LLVMSRem = 18, - LLVMFRem = 19, + LLVMAdd = 9, + LLVMFAdd = 10, + LLVMSub = 11, + LLVMFSub = 12, + LLVMMul = 13, + LLVMFMul = 14, + LLVMUDiv = 15, + LLVMSDiv = 16, + LLVMFDiv = 17, + LLVMURem = 18, + LLVMSRem = 19, + LLVMFRem = 20, /* Logical Operators */ - LLVMShl = 20, - LLVMLShr = 21, - LLVMAShr = 22, - LLVMAnd = 23, - LLVMOr = 24, - LLVMXor = 25, + LLVMShl = 21, + LLVMLShr = 22, + LLVMAShr = 23, + LLVMAnd = 24, + LLVMOr = 25, + LLVMXor = 26, /* Memory Operators */ - LLVMAlloca = 26, - LLVMLoad = 27, - LLVMStore = 28, - LLVMGetElementPtr = 29, + LLVMAlloca = 27, + LLVMLoad = 28, + LLVMStore = 29, + LLVMGetElementPtr = 30, /* Cast Operators */ - LLVMTrunc = 30, - LLVMZExt = 31, - LLVMSExt = 32, - LLVMFPToUI = 33, - LLVMFPToSI = 34, - LLVMUIToFP = 35, - LLVMSIToFP = 36, - LLVMFPTrunc = 37, - LLVMFPExt = 38, - LLVMPtrToInt = 39, - LLVMIntToPtr = 40, - LLVMBitCast = 41, + LLVMTrunc = 31, + LLVMZExt = 32, + LLVMSExt = 33, + LLVMFPToUI = 34, + LLVMFPToSI = 35, + LLVMUIToFP = 36, + LLVMSIToFP = 37, + LLVMFPTrunc = 38, + LLVMFPExt = 39, + LLVMPtrToInt = 40, + LLVMIntToPtr = 41, + LLVMBitCast = 42, /* Other Operators */ - LLVMICmp = 42, - LLVMFCmp = 43, - LLVMPHI = 44, - LLVMCall = 45, - LLVMSelect = 46, + LLVMICmp = 43, + LLVMFCmp = 44, + LLVMPHI = 45, + LLVMCall = 46, + LLVMSelect = 47, /* UserOp1 */ /* UserOp2 */ - LLVMVAArg = 49, - LLVMExtractElement = 50, - LLVMInsertElement = 51, - LLVMShuffleVector = 52, - LLVMExtractValue = 53, - LLVMInsertValue = 54, + LLVMVAArg = 50, + LLVMExtractElement = 51, + LLVMInsertElement = 52, + LLVMShuffleVector = 53, + LLVMExtractValue = 54, + LLVMInsertValue = 55, + LLVMLandingPad = 56, /* Atomic operators */ - LLVMFence = 55 + LLVMFence = 57 } LLVMOpcode; typedef enum { @@ -277,6 +279,11 @@ typedef enum { LLVMRealPredicateTrue /**< Always true (always folded) */ } LLVMRealPredicate; +typedef enum { + LLVMCatch, /**< A catch clause */ + LLVMFilter /**< A filter clause */ +} LLVMLandingPadClauseTy; + void LLVMInitializeCore(LLVMPassRegistryRef R); @@ -463,6 +470,7 @@ LLVMTypeRef LLVMX86MMXType(void); macro(GetElementPtrInst) \ macro(InsertElementInst) \ macro(InsertValueInst) \ + macro(LandingPadInst) \ macro(PHINode) \ macro(SelectInst) \ macro(ShuffleVectorInst) \ @@ -474,6 +482,7 @@ LLVMTypeRef LLVMX86MMXType(void); macro(SwitchInst) \ macro(UnreachableInst) \ macro(UnwindInst) \ + macro(ResumeInst) \ macro(UnaryInstruction) \ macro(AllocaInst) \ macro(CastInst) \ @@ -822,6 +831,7 @@ LLVMValueRef LLVMBuildInvoke(LLVMBuilderRef, LLVMValueRef Fn, LLVMBasicBlockRef Then, LLVMBasicBlockRef Catch, const char *Name); LLVMValueRef LLVMBuildUnwind(LLVMBuilderRef); +LLVMValueRef LLVMBuildResume(LLVMBuilderRef B, LLVMValueRef Exn); LLVMValueRef LLVMBuildUnreachable(LLVMBuilderRef); /* Add a case to the switch instruction */ @@ -831,6 +841,13 @@ void LLVMAddCase(LLVMValueRef Switch, LLVMValueRef OnVal, /* Add a destination to the indirectbr instruction */ void LLVMAddDestination(LLVMValueRef IndirectBr, LLVMBasicBlockRef Dest); +/* Add a clause to the landingpad instruction */ +void LLVMAddClause(LLVMValueRef LandingPad, LLVMLandingPadClauseTy ClauseTy, + LLVMValueRef ClauseVal); + +/* Set the 'cleanup' flag in the landingpad instruction */ +void LLVMSetCleanup(LLVMValueRef LandingPad, LLVMBool Val); + /* Arithmetic */ LLVMValueRef LLVMBuildAdd(LLVMBuilderRef, LLVMValueRef LHS, LLVMValueRef RHS, const char *Name); diff --git a/include/llvm/Bitcode/LLVMBitCodes.h b/include/llvm/Bitcode/LLVMBitCodes.h index 503a867ed2..0f74f633ea 100644 --- a/include/llvm/Bitcode/LLVMBitCodes.h +++ b/include/llvm/Bitcode/LLVMBitCodes.h @@ -257,7 +257,7 @@ namespace bitc { FUNC_CODE_INST_UNREACHABLE = 15, // UNREACHABLE FUNC_CODE_INST_PHI = 16, // PHI: [ty, val0,bb0, ...] - // 17 is unused. + FUNC_CODE_INST_RESUME = 17, // RESUME: [opval] // 18 is unused. FUNC_CODE_INST_ALLOCA = 19, // ALLOCA: [instty, op, align] FUNC_CODE_INST_LOAD = 20, // LOAD: [opty, op, align, vol] @@ -284,7 +284,8 @@ namespace bitc { FUNC_CODE_INST_CALL = 34, // CALL: [attr, fnty, fnid, args...] FUNC_CODE_DEBUG_LOC = 35, // DEBUG_LOC: [Line,Col,ScopeVal, IAVal] - FUNC_CODE_INST_FENCE = 36 // FENCE: [ordering, synchscope] + FUNC_CODE_INST_FENCE = 36, // FENCE: [ordering, synchscope] + FUNC_CODE_INST_LANDINGPAD = 37 // LANDINGPAD: [ty,val,val,num,id0,val0...] }; } // End bitc namespace } // End llvm namespace diff --git a/include/llvm/Instruction.def b/include/llvm/Instruction.def index 81e306779e..a68601fbcd 100644 --- a/include/llvm/Instruction.def +++ b/include/llvm/Instruction.def @@ -100,41 +100,42 @@ HANDLE_TERM_INST ( 3, Switch , SwitchInst) HANDLE_TERM_INST ( 4, IndirectBr , IndirectBrInst) HANDLE_TERM_INST ( 5, Invoke , InvokeInst) HANDLE_TERM_INST ( 6, Unwind , UnwindInst) -HANDLE_TERM_INST ( 7, Unreachable, UnreachableInst) - LAST_TERM_INST ( 7) +HANDLE_TERM_INST ( 7, Resume , ResumeInst) +HANDLE_TERM_INST ( 8, Unreachable, UnreachableInst) + LAST_TERM_INST ( 8) // Standard binary operators... - FIRST_BINARY_INST( 8) -HANDLE_BINARY_INST( 8, Add , BinaryOperator) -HANDLE_BINARY_INST( 9, FAdd , BinaryOperator) -HANDLE_BINARY_INST(10, Sub , BinaryOperator) -HANDLE_BINARY_INST(11, FSub , BinaryOperator) -HANDLE_BINARY_INST(12, Mul , BinaryOperator) -HANDLE_BINARY_INST(13, FMul , BinaryOperator) -HANDLE_BINARY_INST(14, UDiv , BinaryOperator) -HANDLE_BINARY_INST(15, SDiv , BinaryOperator) -HANDLE_BINARY_INST(16, FDiv , BinaryOperator) -HANDLE_BINARY_INST(17, URem , BinaryOperator) -HANDLE_BINARY_INST(18, SRem , BinaryOperator) -HANDLE_BINARY_INST(19, FRem , BinaryOperator) + FIRST_BINARY_INST( 9) +HANDLE_BINARY_INST( 9, Add , BinaryOperator) +HANDLE_BINARY_INST(10, FAdd , BinaryOperator) +HANDLE_BINARY_INST(11, Sub , BinaryOperator) +HANDLE_BINARY_INST(12, FSub , BinaryOperator) +HANDLE_BINARY_INST(13, Mul , BinaryOperator) +HANDLE_BINARY_INST(14, FMul , BinaryOperator) +HANDLE_BINARY_INST(15, UDiv , BinaryOperator) +HANDLE_BINARY_INST(16, SDiv , BinaryOperator) +HANDLE_BINARY_INST(17, FDiv , BinaryOperator) +HANDLE_BINARY_INST(18, URem , BinaryOperator) +HANDLE_BINARY_INST(19, SRem , BinaryOperator) +HANDLE_BINARY_INST(20, FRem , BinaryOperator) // Logical operators (integer operands) -HANDLE_BINARY_INST(20, Shl , BinaryOperator) // Shift left (logical) -HANDLE_BINARY_INST(21, LShr , BinaryOperator) // Shift right (logical) -HANDLE_BINARY_INST(22, AShr , BinaryOperator) // Shift right (arithmetic) -HANDLE_BINARY_INST(23, And , BinaryOperator) -HANDLE_BINARY_INST(24, Or , BinaryOperator) -HANDLE_BINARY_INST(25, Xor , BinaryOperator) - LAST_BINARY_INST(25) +HANDLE_BINARY_INST(21, Shl , BinaryOperator) // Shift left (logical) +HANDLE_BINARY_INST(22, LShr , BinaryOperator) // Shift right (logical) +HANDLE_BINARY_INST(23, AShr , BinaryOperator) // Shift right (arithmetic) +HANDLE_BINARY_INST(24, And , BinaryOperator) +HANDLE_BINARY_INST(25, Or , BinaryOperator) +HANDLE_BINARY_INST(26, Xor , BinaryOperator) + LAST_BINARY_INST(26) // Memory operators... - FIRST_MEMORY_INST(26) -HANDLE_MEMORY_INST(26, Alloca, AllocaInst) // Stack management -HANDLE_MEMORY_INST(27, Load , LoadInst ) // Memory manipulation instrs -HANDLE_MEMORY_INST(28, Store , StoreInst ) -HANDLE_MEMORY_INST(29, GetElementPtr, GetElementPtrInst) -HANDLE_MEMORY_INST(30, Fence , FenceInst ) - LAST_MEMORY_INST(30) + FIRST_MEMORY_INST(27) +HANDLE_MEMORY_INST(27, Alloca, AllocaInst) // Stack management +HANDLE_MEMORY_INST(28, Load , LoadInst ) // Memory manipulation instrs +HANDLE_MEMORY_INST(29, Store , StoreInst ) +HANDLE_MEMORY_INST(30, GetElementPtr, GetElementPtrInst) +HANDLE_MEMORY_INST(31, Fence , FenceInst ) + LAST_MEMORY_INST(31) // Cast operators ... // NOTE: The order matters here because CastInst::isEliminableCastPair @@ -169,8 +170,8 @@ HANDLE_OTHER_INST(54, InsertElement, InsertElementInst) // insert into vector HANDLE_OTHER_INST(55, ShuffleVector, ShuffleVectorInst) // shuffle two vectors. HANDLE_OTHER_INST(56, ExtractValue, ExtractValueInst)// extract from aggregate HANDLE_OTHER_INST(57, InsertValue, InsertValueInst) // insert into aggregate - - LAST_OTHER_INST(57) +HANDLE_OTHER_INST(58, LandingPad, LandingPadInst) // Landing pad instruction. + LAST_OTHER_INST(58) #undef FIRST_TERM_INST #undef HANDLE_TERM_INST diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 89eb901c1d..d337002e0b 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -1775,6 +1775,116 @@ struct OperandTraits<PHINode> : public HungoffOperandTraits<2> { DEFINE_TRANSPARENT_OPERAND_ACCESSORS(PHINode, Value) +//===----------------------------------------------------------------------===// +// LandingPadInst Class +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------------- +/// LandingPadInst - The landingpad instruction holds all of the information +/// necessary to generate correct exception handling. The landingpad instruction +/// cannot be moved from the top of a landing pad block, which itself is +/// accessible only from the 'unwind' edge of an invoke. +/// +class LandingPadInst : public Instruction { + /// ReservedSpace - The number of operands actually allocated. NumOperands is + /// the number actually in use. + unsigned ReservedSpace; + + /// IsCleanup - True if the landingpad instruction is also a cleanup. + bool IsCleanup; + LandingPadInst(const LandingPadInst &LP); +public: + enum ClauseType { Catch, Filter }; +private: + /// ClauseIdxs - This indexes into the OperandList, indicating what the + /// values are at a given index. + SmallVector<ClauseType, 8> ClauseIdxs; + + void *operator new(size_t, unsigned); // DO NOT IMPLEMENT + // Allocate space for exactly zero operands. + void *operator new(size_t s) { + return User::operator new(s, 0); + } + void growOperands(); + void init(Value *PersFn, unsigned NumReservedValues, const Twine &NameStr); + + explicit LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + Instruction *InsertBefore) + : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertBefore), + IsCleanup(false) { + init(PersonalityFn, 1 + NumReservedValues, NameStr); + } + explicit LandingPadInst(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, const Twine &NameStr, + BasicBlock *InsertAtEnd) + : Instruction(RetTy, Instruction::LandingPad, 0, 0, InsertAtEnd), + IsCleanup(false) { + init(PersonalityFn, 1 + NumReservedValues, NameStr); + } +protected: + virtual LandingPadInst *clone_impl() const; +public: + static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, + const Twine &NameStr = "", + Instruction *InsertBefore = 0) { + return new LandingPadInst(RetTy, PersonalityFn, NumReservedValues, NameStr, + InsertBefore); + } + static LandingPadInst *Create(Type *RetTy, Value *PersonalityFn, + unsigned NumReservedValues, + const Twine &NameStr, BasicBlock *InsertAtEnd) { + return new LandingPadInst(RetTy, PersonalityFn, NumReservedValues, NameStr, + InsertAtEnd); + } + ~LandingPadInst(); + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// getPersonalityFn - Get the personality function associated with this + /// landing pad. + const Value *getPersonalityFn() const { return getOperand(0); } + + // Simple accessors. + bool isCleanup() const { return IsCleanup; } + void setCleanup(bool Val) { IsCleanup = Val; } + + /// addClause - Add a clause to the landing pad. + void addClause(ClauseType CT, Value *ClauseVal); + + /// getClauseType - Return the type of the clause at this index. The two + /// supported clauses are Catch and Filter. + ClauseType getClauseType(unsigned I) const { + assert(I < ClauseIdxs.size() && "Index too large!"); + return ClauseIdxs[I]; + } + + /// getClauseValue - Return the value of the clause at this index. + Value *getClauseValue(unsigned I) const { + assert(I + 1 < getNumOperands() && "Index too large!"); + return OperandList[I + 1]; + } + + /// getNumClauses - Get the number of clauses for this landing pad. + unsigned getNumClauses() const { return getNumOperands() - 1; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const LandingPadInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::LandingPad; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +}; + +template <> +struct OperandTraits<LandingPadInst> : public HungoffOperandTraits<2> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(LandingPadInst, Value) //===----------------------------------------------------------------------===// // ReturnInst Class @@ -2463,6 +2573,59 @@ private: }; //===----------------------------------------------------------------------===// +// ResumeInst Class +//===----------------------------------------------------------------------===// + +//===--------------------------------------------------------------------------- +/// ResumeInst - Resume the propagation of an exception. +/// +class ResumeInst : public TerminatorInst { + ResumeInst(const ResumeInst &RI); + + explicit ResumeInst(LLVMContext &C, Value *Exn, Instruction *InsertBefore=0); + ResumeInst(LLVMContext &C, Value *Exn, BasicBlock *InsertAtEnd); +protected: + virtual ResumeInst *clone_impl() const; +public: + static ResumeInst *Create(LLVMContext &C, Value *Exn, + Instruction *InsertBefore = 0) { + return new(1) ResumeInst(C, Exn, InsertBefore); + } + static ResumeInst *Create(LLVMContext &C, Value *Exn, + BasicBlock *InsertAtEnd) { + return new(1) ResumeInst(C, Exn, InsertAtEnd); + } + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + + /// Convenience accessor. + Value *getResumeValue() const { return Op<0>(); } + + unsigned getNumSuccessors() const { return 0; } + + // Methods for support type inquiry through isa, cast, and dyn_cast: + static inline bool classof(const ResumeInst *) { return true; } + static inline bool classof(const Instruction *I) { + return I->getOpcode() == Instruction::Resume; + } + static inline bool classof(const Value *V) { + return isa<Instruction>(V) && classof(cast<Instruction>(V)); + } +private: + virtual BasicBlock *getSuccessorV(unsigned idx) const; + virtual unsigned getNumSuccessorsV() const; + virtual void setSuccessorV(unsigned idx, BasicBlock *B); +}; + +template <> +struct OperandTraits<ResumeInst> : + public FixedNumOperandTraits<ResumeInst, 1> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ResumeInst, Value) + +//===----------------------------------------------------------------------===// // UnreachableInst Class //===----------------------------------------------------------------------===// diff --git a/include/llvm/Support/IRBuilder.h b/include/llvm/Support/IRBuilder.h index 0a2800eacd..7f89b247c4 100644 --- a/include/llvm/Support/IRBuilder.h +++ b/include/llvm/Support/IRBuilder.h @@ -479,6 +479,10 @@ public: return Insert(new UnwindInst(Context)); } + ResumeInst *CreateResume(Value *Exn) { + return Insert(ResumeInst::Create(Context, Exn)); + } + UnreachableInst *CreateUnreachable() { return Insert(new UnreachableInst(Context)); } @@ -1194,6 +1198,11 @@ public: return Insert(InsertValueInst::Create(Agg, Val, Idxs), Name); } + Value *CreateLandingPad(Type *Ty, Value *PersFn, unsigned NumClauses, + const Twine &Name = "") { + return Insert(LandingPadInst::Create(Ty, PersFn, NumClauses, Name)); + } + //===--------------------------------------------------------------------===// // Utility creation methods //===--------------------------------------------------------------------===// diff --git a/include/llvm/Support/InstVisitor.h b/include/llvm/Support/InstVisitor.h index 83b26f5c22..85e6f62903 100644 --- a/include/llvm/Support/InstVisitor.h +++ b/include/llvm/Support/InstVisitor.h @@ -163,6 +163,7 @@ public: RetTy visitIndirectBrInst(IndirectBrInst &I) { DELEGATE(TerminatorInst);} RetTy visitInvokeInst(InvokeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnwindInst(UnwindInst &I) { DELEGATE(TerminatorInst);} + RetTy visitResumeInst(ResumeInst &I) { DELEGATE(TerminatorInst);} RetTy visitUnreachableInst(UnreachableInst &I) { DELEGATE(TerminatorInst);} RetTy visitICmpInst(ICmpInst &I) { DELEGATE(CmpInst);} RetTy visitFCmpInst(FCmpInst &I) { DELEGATE(CmpInst);} @@ -192,6 +193,7 @@ public: RetTy visitShuffleVectorInst(ShuffleVectorInst &I) { DELEGATE(Instruction); } RetTy visitExtractValueInst(ExtractValueInst &I) { DELEGATE(Instruction);} RetTy visitInsertValueInst(InsertValueInst &I) { DELEGATE(Instruction); } + RetTy visitLandingPadInst(LandingPadInst &I) { DELEGATE(Instruction); } // Next level propagators: If the user does not overload a specific // instruction type, they can overload one of these to get the whole class diff --git a/lib/AsmParser/LLLexer.cpp b/lib/AsmParser/LLLexer.cpp index cdee98bd0c..970d7aa7ed 100644 --- a/lib/AsmParser/LLLexer.cpp +++ b/lib/AsmParser/LLLexer.cpp @@ -581,6 +581,11 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(x); KEYWORD(blockaddress); + + KEYWORD(personality); + KEYWORD(cleanup); + KEYWORD(catch); + KEYWORD(filter); #undef KEYWORD // Keywords for types. @@ -633,6 +638,7 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(switch, Switch); INSTKEYWORD(indirectbr, IndirectBr); INSTKEYWORD(invoke, Invoke); + INSTKEYWORD(resume, Resume); INSTKEYWORD(unwind, Unwind); INSTKEYWORD(unreachable, Unreachable); @@ -647,6 +653,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 @@ -674,7 +681,6 @@ lltok::Kind LLLexer::LexIdentifier() { return lltok::Error; } - /// Lex0x: Handle productions that start with 0x, knowing that it matches and /// that this is not a label: /// HexFPConstant 0x[0-9A-Fa-f]+ diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index 76771c29ba..547abfe24e 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2885,6 +2885,7 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_switch: return ParseSwitch(Inst, PFS); case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); + case lltok::kw_resume: return ParseResume(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -2944,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. @@ -3247,7 +3249,18 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { return false; } +/// ParseResume +/// ::= 'resume' TypeAndValue +bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { + Value *Exn; LocTy ExnLoc; + LocTy Loc = Lex.getLoc(); + if (ParseTypeAndValue(Exn, ExnLoc, PFS)) + return true; + ResumeInst *RI = ResumeInst::Create(Context, Exn); + Inst = RI; + return false; +} //===----------------------------------------------------------------------===// // Binary Operators. @@ -3495,6 +3508,56 @@ int LLParser::ParsePHI(Instruction *&Inst, PerFunctionState &PFS) { return AteExtraComma ? InstExtraComma : InstNormal; } +/// ParseLandingPad +/// ::= 'landingpad' Type 'personality' TypeAndValue 'cleanup'? +/// (ClauseID ClauseList)+ +/// ClauseID +/// ::= 'catch' +/// ::= 'filter' +/// ClauseList +/// ::= 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; + + bool IsCleanup = EatIfPresent(lltok::kw_cleanup); + + SmallVector<std::pair<LandingPadInst::ClauseType, Value*>, 16> Clauses; + while (Lex.getKind() == lltok::kw_catch || Lex.getKind() == lltok::kw_filter){ + LandingPadInst::ClauseType CT; + if (Lex.getKind() == lltok::kw_catch) { + CT = LandingPadInst::Catch; + ParseToken(lltok::kw_catch, "expected 'catch'"); + } else { + CT = LandingPadInst::Filter; + ParseToken(lltok::kw_filter, "expected 'filter'"); + } + + do { + Value *V; LocTy VLoc; + if (ParseTypeAndValue(V, VLoc, PFS)) + return true; + Clauses.push_back(std::make_pair(CT, V)); + } while (EatIfPresent(lltok::comma)); + } + + LandingPadInst *LP = LandingPadInst::Create(Ty, PersFn, Clauses.size()); + LP->setCleanup(IsCleanup); + + for (SmallVectorImpl<std::pair<LandingPadInst::ClauseType, Value*> >::iterator + I = Clauses.begin(), E = Clauses.end(); I != E; ++I) + LP->addClause(I->first, I->second); + + 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 1eaf3252a8..6d2a929cc4 100644 --- a/lib/AsmParser/LLParser.h +++ b/lib/AsmParser/LLParser.h @@ -347,6 +347,7 @@ namespace llvm { bool ParseSwitch(Instruction *&Inst, PerFunctionState &PFS); bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); + bool ParseResume(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, unsigned OperandType); @@ -359,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, bool isVolati |