mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-10-25 10:27:04 +00:00
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 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@243766 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -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.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
Reference in New Issue
Block a user