summaryrefslogtreecommitdiffstats
path: root/llvm/lib/AsmParser
diff options
context:
space:
mode:
authorDavid Majnemer <david.majnemer@gmail.com>2015-07-10 07:00:44 +0000
committerDavid Majnemer <david.majnemer@gmail.com>2015-07-10 07:00:44 +0000
commitae2ffc8a8c825acf46f58f20dc7d0ae5fecbdd0b (patch)
treebba694cd7ab6a7a5eb4aca757ebfc3b38b1e949d /llvm/lib/AsmParser
parent83505347724a3eeb42f66a0b58fb8ff5c4c9ea4c (diff)
downloadbcm5719-llvm-ae2ffc8a8c825acf46f58f20dc7d0ae5fecbdd0b.tar.gz
bcm5719-llvm-ae2ffc8a8c825acf46f58f20dc7d0ae5fecbdd0b.zip
New EH representation for MSVC compatibility
Summary: 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. Reviewers: rnk, JosephTremoulet, reames, nlewycky, rjmccall Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D11041 llvm-svn: 241888
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp7
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp161
-rw-r--r--llvm/lib/AsmParser/LLParser.h9
-rw-r--r--llvm/lib/AsmParser/LLToken.h4
4 files changed, 180 insertions, 1 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 88f359d4fd5..69c2048aae2 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);
@@ -748,6 +749,12 @@ lltok::Kind LLLexer::LexIdentifier() {
INSTKEYWORD(extractvalue, ExtractValue);
INSTKEYWORD(insertvalue, InsertValue);
INSTKEYWORD(landingpad, LandingPad);
+ INSTKEYWORD(cleanupret, CleanupRet);
+ INSTKEYWORD(catchret, CatchRet);
+ INSTKEYWORD(catchblock, CatchBlock);
+ INSTKEYWORD(terminateblock, TerminateBlock);
+ INSTKEYWORD(cleanupblock, CleanupBlock);
+ INSTKEYWORD(catchendblock, CatchEndBlock);
#undef INSTKEYWORD
#define DWKEYWORD(TYPE, TOKEN) \
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 91a88bc91fd..4e28410abdc 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -4489,6 +4489,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_catchblock: return ParseCatchBlock(Inst, PFS);
+ case lltok::kw_terminateblock: return ParseTerminateBlock(Inst, PFS);
+ case lltok::kw_cleanupblock: return ParseCleanupBlock(Inst, PFS);
+ case lltok::kw_catchendblock: return ParseCatchEndBlock(Inst, PFS);
// Binary Operators.
case lltok::kw_add:
case lltok::kw_sub:
@@ -4882,6 +4888,161 @@ bool LLParser::ParseResume(Instruction *&Inst, PerFunctionState &PFS) {
return false;
}
+bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args,
+ PerFunctionState &PFS) {
+ if (ParseToken(lltok::lsquare, "expected '[' in cleanupblock"))
+ 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;
+}
+
+/// ParseCatchBlock
+/// ::= 'catchblock' Type ParamList 'to' TypeAndValue 'unwind' TypeAndValue
+bool LLParser::ParseCatchBlock(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 catchblock") ||
+ ParseTypeAndBasicBlock(NormalBB, PFS) ||
+ ParseToken(lltok::kw_unwind, "expected 'unwind' in catchblock") ||
+ ParseTypeAndBasicBlock(UnwindBB, PFS))
+ return true;
+
+ Inst = CatchBlockInst::Create(RetType, NormalBB, UnwindBB, Args);
+ return false;
+}
+
+/// ParseTerminateBlock
+/// ::= 'terminateblock' ParamList 'to' TypeAndValue
+bool LLParser::ParseTerminateBlock(Instruction *&Inst, PerFunctionState &PFS) {
+ SmallVector<Value *, 8> Args;
+ if (ParseExceptionArgs(Args, PFS))
+ return true;
+
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in terminateblock"))
+ 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 = TerminateBlockInst::Create(Context, UnwindBB, Args);
+ return false;
+}
+
+/// ParseCleanupBlock
+/// ::= 'cleanupblock' ParamList
+bool LLParser::ParseCleanupBlock(Instruction *&Inst, PerFunctionState &PFS) {
+ Type *RetType = nullptr;
+
+ SmallVector<Value *, 8> Args;
+ if (ParseType(RetType, /*AllowVoid=*/true) || ParseExceptionArgs(Args, PFS))
+ return true;
+
+ Inst = CleanupBlockInst::Create(RetType, Args);
+ return false;
+}
+
+/// ParseCatchEndBlock
+/// ::= 'catchendblock' unwind ('to' 'caller' | TypeAndValue)
+bool LLParser::ParseCatchEndBlock(Instruction *&Inst, PerFunctionState &PFS) {
+ if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret"))
+ 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 = CatchEndBlockInst::Create(Context, UnwindBB);
+ return false;
+}
+
//===----------------------------------------------------------------------===//
// Binary Operators.
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h
index 6e57b3e0667..2a39b6d364d 100644
--- a/llvm/lib/AsmParser/LLParser.h
+++ b/llvm/lib/AsmParser/LLParser.h
@@ -381,6 +381,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);
@@ -441,6 +444,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 ParseCatchBlock(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseTerminateBlock(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCleanupBlock(Instruction *&Inst, PerFunctionState &PFS);
+ bool ParseCatchEndBlock(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 2487d120813..6e24224978e 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,
@@ -176,7 +177,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_catchblock,
+ kw_terminateblock, kw_cleanupblock, kw_catchendblock,
kw_alloca, kw_load, kw_store, kw_fence, kw_cmpxchg, kw_atomicrmw,
kw_getelementptr,
OpenPOWER on IntegriCloud