diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2015-07-31 17:58:14 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2015-07-31 17:58:14 +0000 |
| commit | 654e130b6ec76c1a2910b2594cb403ecd2773af8 (patch) | |
| tree | 79a53c08a138345e3cdd13b36940d3d1cf6f5917 /llvm/lib/AsmParser | |
| parent | e430654fd85a04f04c93eab40ba7fe87d8657130 (diff) | |
| download | bcm5719-llvm-654e130b6ec76c1a2910b2594cb403ecd2773af8.tar.gz bcm5719-llvm-654e130b6ec76c1a2910b2594cb403ecd2773af8.zip | |
New EH representation for MSVC compatibility
This introduces new instructions neccessary to implement MSVC-compatible
exception handling support. Most of the middle-end and none of the
back-end haven't been audited or updated to take them into account.
Differential Revision: http://reviews.llvm.org/D11097
llvm-svn: 243766
Diffstat (limited to 'llvm/lib/AsmParser')
| -rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 7 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 161 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 9 | ||||
| -rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 4 |
4 files changed, 180 insertions, 1 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 5c4bab734b2..be951f5c7d8 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -524,6 +524,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(undef); KEYWORD(null); KEYWORD(to); + KEYWORD(caller); KEYWORD(tail); KEYWORD(musttail); KEYWORD(target); @@ -749,6 +750,12 @@ lltok::Kind LLLexer::LexIdentifier() { INSTKEYWORD(extractvalue, ExtractValue); INSTKEYWORD(insertvalue, InsertValue); INSTKEYWORD(landingpad, LandingPad); + INSTKEYWORD(cleanupret, CleanupRet); + INSTKEYWORD(catchret, CatchRet); + INSTKEYWORD(catchpad, CatchPad); + INSTKEYWORD(terminatepad, TerminatePad); + INSTKEYWORD(cleanuppad, CleanupPad); + INSTKEYWORD(catchendpad, CatchEndPad); #undef INSTKEYWORD #define DWKEYWORD(TYPE, TOKEN) \ diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index f16921dea66..6c2cd08e580 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -4532,6 +4532,12 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, case lltok::kw_indirectbr: return ParseIndirectBr(Inst, PFS); case lltok::kw_invoke: return ParseInvoke(Inst, PFS); case lltok::kw_resume: return ParseResume(Inst, PFS); + case lltok::kw_cleanupret: return ParseCleanupRet(Inst, PFS); + case lltok::kw_catchret: return ParseCatchRet(Inst, PFS); + case lltok::kw_catchpad: return ParseCatchPad(Inst, PFS); + case lltok::kw_terminatepad: return ParseTerminatePad(Inst, PFS); + case lltok::kw_cleanuppad: return ParseCleanupPad(Inst, PFS); + case lltok::kw_catchendpad: return ParseCatchEndPad(Inst, PFS); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -4936,6 +4942,161 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) { return false; } +bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args, + PerFunctionState &PFS) { + if (ParseToken(lltok::lsquare, "expected '[' in cleanuppad")) + return true; + + while (Lex.getKind() != lltok::rsquare) { + // If this isn't the first argument, we need a comma. + if (!Args.empty() && + ParseToken(lltok::comma, "expected ',' in argument list")) + return true; + + // Parse the argument. + LocTy ArgLoc; + Type *ArgTy = nullptr; + if (ParseType(ArgTy, ArgLoc)) + return true; + + Value *V; + if (ArgTy->isMetadataTy()) { + if (ParseMetadataAsValue(V, PFS)) + return true; + } else { + if (ParseValue(ArgTy, V, PFS)) + return true; + } + Args.push_back(V); + } + + Lex.Lex(); // Lex the ']'. + return false; +} + +/// ParseCleanupRet +/// ::= 'cleanupret' ('void' | TypeAndValue) unwind ('to' 'caller' | TypeAndValue) +bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { + Type *RetTy = nullptr; + Value *RetVal = nullptr; + if (ParseType(RetTy, /*AllowVoid=*/true)) + return true; + + if (!RetTy->isVoidTy()) + if (ParseValue(RetTy, RetVal, PFS)) + return true; + + if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret")) + return true; + + BasicBlock *UnwindBB = nullptr; + if (Lex.getKind() == lltok::kw_to) { + Lex.Lex(); + if (ParseToken(lltok::kw_caller, "expected 'caller' in cleanupret")) + return true; + } else { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + return true; + } + } + + Inst = CleanupReturnInst::Create(Context, RetVal, UnwindBB); + return false; +} + +/// ParseCatchRet +/// ::= 'catchret' TypeAndValue +bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { + BasicBlock *BB; + if (ParseTypeAndBasicBlock(BB, PFS)) + return true; + + Inst = CatchReturnInst::Create(BB); + return false; +} + +/// ParseCatchPad +/// ::= 'catchpad' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue +bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { + Type *RetType = nullptr; + + SmallVector<Value *, 8> Args; + if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS)) + return true; + + BasicBlock *NormalBB, *UnwindBB; + if (ParseToken(lltok::kw_to, "expected 'to' in catchpad") || + ParseTypeAndBasicBlock(NormalBB, PFS) || + ParseToken(lltok::kw_unwind, "expected 'unwind' in catchpad") || + ParseTypeAndBasicBlock(UnwindBB, PFS)) + return true; + + Inst = CatchPadInst::Create(RetType, NormalBB, UnwindBB, Args); + return false; +} + +/// ParseTerminatePad +/// ::= 'terminatepad' ParamList 'to' TypeAndValue +bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) { + SmallVector<Value *, 8> Args; + if (ParseExceptionArgs(Args, PFS)) + return true; + + if (ParseToken(lltok::kw_unwind, "expected 'unwind' in terminatepad")) + return true; + + BasicBlock *UnwindBB = nullptr; + if (Lex.getKind() == lltok::kw_to) { + Lex.Lex(); + if (ParseToken(lltok::kw_caller, "expected 'caller' in terminatepad")) + return true; + } else { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + return true; + } + } + + Inst = TerminatePadInst::Create(Context, UnwindBB, Args); + return false; +} + +/// ParseCleanupPad +/// ::= 'cleanuppad' ParamList +bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { + Type *RetType = nullptr; + + SmallVector<Value *, 8> Args; + if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS)) + return true; + + Inst = CleanupPadInst::Create(RetType, Args); + return false; +} + +/// ParseCatchEndPad +/// ::= 'catchendpad' unwind ('to' 'caller' | TypeAndValue) +bool LLParser::ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS) { + if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad")) + return true; + + BasicBlock *UnwindBB = nullptr; + if (Lex.getKind() == lltok::kw_to) { + Lex.Lex(); + if (Lex.getKind() == lltok::kw_caller) { + Lex.Lex(); + } else { + return true; + } + } else { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + return true; + } + } + + Inst = CatchEndPadInst::Create(Context, UnwindBB); + return false; +} + //===----------------------------------------------------------------------===// // Binary Operators. //===----------------------------------------------------------------------===// diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 6ef92c12b52..0c066f4b603 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -385,6 +385,9 @@ namespace llvm { bool IsMustTailCall = false, bool InVarArgsFunc = false); + bool ParseExceptionArgs(SmallVectorImpl<Value *> &Args, + PerFunctionState &PFS); + // Constant Parsing. bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr); bool ParseGlobalValue(Type *Ty, Constant *&V); @@ -445,6 +448,12 @@ namespace llvm { bool ParseIndirectBr(Instruction *&Inst, PerFunctionState &PFS); bool ParseInvoke(Instruction *&Inst, PerFunctionState &PFS); bool ParseResume(Instruction *&Inst, PerFunctionState &PFS); + bool ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS); + bool ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS); + bool ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS); + bool ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS); + bool ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS); + bool ParseCatchEndPad(Instruction *&Inst, PerFunctionState &PFS); bool ParseArithmetic(Instruction *&I, PerFunctionState &PFS, unsigned Opc, unsigned OperandType); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 691f085f0c9..19bf7e4e4c1 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -51,6 +51,7 @@ namespace lltok { kw_zeroinitializer, kw_undef, kw_null, kw_to, + kw_caller, kw_tail, kw_musttail, kw_target, @@ -177,7 +178,8 @@ namespace lltok { kw_landingpad, kw_personality, kw_cleanup, kw_catch, kw_filter, kw_ret, kw_br, kw_switch, kw_indirectbr, kw_invoke, kw_resume, - kw_unreachable, + kw_unreachable, kw_cleanupret, kw_catchret, kw_catchpad, + kw_terminatepad, kw_cleanuppad, kw_catchendpad, kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw, kw_getelementptr, |

