diff options
Diffstat (limited to 'lib/AsmParser/LLParser.cpp')
-rw-r--r-- | lib/AsmParser/LLParser.cpp | 284 |
1 files changed, 109 insertions, 175 deletions
diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index b5cbee5085b..2e411733e27 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2315,7 +2315,7 @@ bool LLParser::PerFunctionState::FinishFunction() { /// forward reference record if needed. This can return null if the value /// exists but does not have the right type. Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, - LocTy Loc, OperatorConstraint OC) { + LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = F.getValueSymbolTable().lookup(Name); @@ -2329,24 +2329,6 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, // If we have the value in the symbol table or fwd-ref table, return it. if (Val) { - // Check operator constraints. - switch (OC) { - case OC_None: - // no constraint - break; - case OC_CatchPad: - if (!isa<CatchPadInst>(Val)) { - P.Error(Loc, "'%" + Name + "' is not a catchpad"); - return nullptr; - } - break; - case OC_CleanupPad: - if (!isa<CleanupPadInst>(Val)) { - P.Error(Loc, "'%" + Name + "' is not a cleanuppad"); - return nullptr; - } - break; - } if (Val->getType() == Ty) return Val; if (Ty->isLabelTy()) P.Error(Loc, "'%" + Name + "' is not a basic block"); @@ -2365,30 +2347,16 @@ Value *LLParser::PerFunctionState::GetVal(const std::string &Name, Type *Ty, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; if (Ty->isLabelTy()) { - assert(!OC); FwdVal = BasicBlock::Create(F.getContext(), Name, &F); - } else if (!OC) { - FwdVal = new Argument(Ty, Name); } else { - switch (OC) { - case OC_CatchPad: - FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {}, - Name); - break; - case OC_CleanupPad: - FwdVal = CleanupPadInst::Create(F.getContext(), {}, Name); - break; - default: - llvm_unreachable("unexpected constraint"); - } + FwdVal = new Argument(Ty, Name); } ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; } -Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, - OperatorConstraint OC) { +Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc) { // Look this name up in the normal function symbol table. Value *Val = ID < NumberedVals.size() ? NumberedVals[ID] : nullptr; @@ -2402,24 +2370,6 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, // If we have the value in the symbol table or fwd-ref table, return it. if (Val) { - // Check operator constraint. - switch (OC) { - case OC_None: - // no constraint - break; - case OC_CatchPad: - if (!isa<CatchPadInst>(Val)) { - P.Error(Loc, "'%" + Twine(ID) + "' is not a catchpad"); - return nullptr; - } - break; - case OC_CleanupPad: - if (!isa<CleanupPadInst>(Val)) { - P.Error(Loc, "'%" + Twine(ID) + "' is not a cleanuppad"); - return nullptr; - } - break; - } if (Val->getType() == Ty) return Val; if (Ty->isLabelTy()) P.Error(Loc, "'%" + Twine(ID) + "' is not a basic block"); @@ -2437,21 +2387,9 @@ Value *LLParser::PerFunctionState::GetVal(unsigned ID, Type *Ty, LocTy Loc, // Otherwise, create a new forward reference for this value and remember it. Value *FwdVal; if (Ty->isLabelTy()) { - assert(!OC); FwdVal = BasicBlock::Create(F.getContext(), "", &F); - } else if (!OC) { - FwdVal = new Argument(Ty); } else { - switch (OC) { - case OC_CatchPad: - FwdVal = CatchPadInst::Create(&F.getEntryBlock(), &F.getEntryBlock(), {}); - break; - case OC_CleanupPad: - FwdVal = CleanupPadInst::Create(F.getContext(), {}); - break; - default: - llvm_unreachable("unexpected constraint"); - } + FwdVal = new Argument(Ty); } ForwardRefValIDs[ID] = std::make_pair(FwdVal, Loc); @@ -2487,17 +2425,6 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - // Check operator constraints. We only put cleanuppads or catchpads in - // the forward value map if the value is constrained to match. - if (isa<CatchPadInst>(Sentinel)) { - if (!isa<CatchPadInst>(Inst)) - return P.Error(FI->second.second, - "'%" + Twine(NameID) + "' is not a catchpad"); - } else if (isa<CleanupPadInst>(Sentinel)) { - if (!isa<CleanupPadInst>(Inst)) - return P.Error(FI->second.second, - "'%" + Twine(NameID) + "' is not a cleanuppad"); - } Sentinel->replaceAllUsesWith(Inst); delete Sentinel; @@ -2515,17 +2442,6 @@ bool LLParser::PerFunctionState::SetInstName(int NameID, if (Sentinel->getType() != Inst->getType()) return P.Error(NameLoc, "instruction forward referenced with type '" + getTypeString(FI->second.first->getType()) + "'"); - // Check operator constraints. We only put cleanuppads or catchpads in - // the forward value map if the value is constrained to match. - if (isa<CatchPadInst>(Sentinel)) { - if (!isa<CatchPadInst>(Inst)) - return P.Error(FI->second.second, - "'%" + NameStr + "' is not a catchpad"); - } else if (isa<CleanupPadInst>(Sentinel)) { - if (!isa<CleanupPadInst>(Inst)) - return P.Error(FI->second.second, - "'%" + NameStr + "' is not a cleanuppad"); - } Sentinel->replaceAllUsesWith(Inst); delete Sentinel; @@ -4235,30 +4151,18 @@ bool LLParser::ParseMetadata(Metadata *&MD, PerFunctionState *PFS) { //===----------------------------------------------------------------------===// bool LLParser::ConvertValIDToValue(Type *Ty, ValID &ID, Value *&V, - PerFunctionState *PFS, - OperatorConstraint OC) { + PerFunctionState *PFS) { if (Ty->isFunctionTy()) return Error(ID.Loc, "functions are not values, refer to them as pointers"); - if (OC && ID.Kind != ValID::t_LocalID && ID.Kind != ValID::t_LocalName) { - switch (OC) { - case OC_CatchPad: - return Error(ID.Loc, "Catchpad value required in this position"); - case OC_CleanupPad: - return Error(ID.Loc, "Cleanuppad value required in this position"); - default: - llvm_unreachable("Unexpected constraint kind"); - } - } - switch (ID.Kind) { case ValID::t_LocalID: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); - V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc, OC); + V = PFS->GetVal(ID.UIntVal, Ty, ID.Loc); return V == nullptr; case ValID::t_LocalName: if (!PFS) return Error(ID.Loc, "invalid use of function-local name"); - V = PFS->GetVal(ID.StrVal, Ty, ID.Loc, OC); + V = PFS->GetVal(ID.StrVal, Ty, ID.Loc); return V == nullptr; case ValID::t_InlineAsm: { if (!ID.FTy || !InlineAsm::Verify(ID.FTy, ID.StrVal2)) @@ -4385,11 +4289,10 @@ bool LLParser::parseConstantValue(Type *Ty, Constant *&C) { } } -bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS, - OperatorConstraint OC) { +bool LLParser::ParseValue(Type *Ty, Value *&V, PerFunctionState *PFS) { V = nullptr; ValID ID; - return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS, OC); + return ParseValID(ID, PFS) || ConvertValIDToValue(Ty, ID, V, PFS); } bool LLParser::ParseTypeAndValue(Value *&V, PerFunctionState *PFS) { @@ -4818,11 +4721,10 @@ int LLParser::ParseInstruction(Instruction *&Inst, BasicBlock *BB, 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); - case lltok::kw_cleanupendpad: return ParseCleanupEndPad(Inst, PFS); + case lltok::kw_catchswitch: return ParseCatchSwitch(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); // Binary Operators. case lltok::kw_add: case lltok::kw_sub: @@ -5262,11 +5164,14 @@ bool LLParser::ParseExceptionArgs(SmallVectorImpl<Value *> &Args, } /// ParseCleanupRet -/// ::= 'cleanupret' Value unwind ('to' 'caller' | TypeAndValue) +/// ::= 'cleanupret' from Value unwind ('to' 'caller' | TypeAndValue) bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { Value *CleanupPad = nullptr; - if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad)) + if (ParseToken(lltok::kw_from, "expected 'from' after cleanupret")) + return true; + + if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS)) return true; if (ParseToken(lltok::kw_unwind, "expected 'unwind' in cleanupret")) @@ -5283,16 +5188,19 @@ bool LLParser::ParseCleanupRet(Instruction *&Inst, PerFunctionState &PFS) { } } - Inst = CleanupReturnInst::Create(cast<CleanupPadInst>(CleanupPad), UnwindBB); + Inst = CleanupReturnInst::Create(CleanupPad, UnwindBB); return false; } /// ParseCatchRet -/// ::= 'catchret' Value 'to' TypeAndValue +/// ::= 'catchret' from Parent Value 'to' TypeAndValue bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { Value *CatchPad = nullptr; - if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS, OC_CatchPad)) + if (ParseToken(lltok::kw_from, "expected 'from' after catchret")) + return true; + + if (ParseValue(Type::getTokenTy(Context), CatchPad, PFS)) return true; BasicBlock *BB; @@ -5300,114 +5208,140 @@ bool LLParser::ParseCatchRet(Instruction *&Inst, PerFunctionState &PFS) { ParseTypeAndBasicBlock(BB, PFS)) return true; - Inst = CatchReturnInst::Create(cast<CatchPadInst>(CatchPad), BB); + Inst = CatchReturnInst::Create(CatchPad, BB); return false; } -/// ParseCatchPad -/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue -bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { - SmallVector<Value *, 8> Args; - if (ParseExceptionArgs(Args, PFS)) +/// ParseCatchSwitch +/// ::= 'catchswitch' within Parent +bool LLParser::ParseCatchSwitch(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad; + LocTy BBLoc; + + if (ParseToken(lltok::kw_within, "expected 'within' after catchswitch")) 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)) + if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && + Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for catchswitch"); + + if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS)) return true; - Inst = CatchPadInst::Create(NormalBB, UnwindBB, Args); - return false; -} + if (ParseToken(lltok::lsquare, "expected '[' with catchswitch labels")) + return true; -/// ParseTerminatePad -/// ::= 'terminatepad' ParamList 'to' TypeAndValue -bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) { - SmallVector<Value *, 8> Args; - if (ParseExceptionArgs(Args, PFS)) + SmallVector<BasicBlock *, 32> Table; + do { + BasicBlock *DestBB; + if (ParseTypeAndBasicBlock(DestBB, PFS)) + return true; + Table.push_back(DestBB); + } while (EatIfPresent(lltok::comma)); + + if (ParseToken(lltok::rsquare, "expected ']' after catchswitch labels")) return true; - if (ParseToken(lltok::kw_unwind, "expected 'unwind' in terminatepad")) + if (ParseToken(lltok::kw_unwind, + "expected 'unwind' after catchswitch scope")) return true; BasicBlock *UnwindBB = nullptr; - if (Lex.getKind() == lltok::kw_to) { - Lex.Lex(); - if (ParseToken(lltok::kw_caller, "expected 'caller' in terminatepad")) + if (EatIfPresent(lltok::kw_to)) { + if (ParseToken(lltok::kw_caller, "expected 'caller' in catchswitch")) return true; } else { - if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { + if (ParseTypeAndBasicBlock(UnwindBB, PFS)) return true; - } } - Inst = TerminatePadInst::Create(Context, UnwindBB, Args); + auto *CatchSwitch = + CatchSwitchInst::Create(ParentPad, UnwindBB, Table.size()); + for (BasicBlock *DestBB : Table) + CatchSwitch->addHandler(DestBB); + Inst = CatchSwitch; return false; } -/// ParseCleanupPad -/// ::= 'cleanuppad' ParamList -bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { +/// ParseCatchPad +/// ::= 'catchpad' ParamList 'to' TypeAndValue 'unwind' TypeAndValue +bool LLParser::ParseCatchPad(Instruction *&Inst, PerFunctionState &PFS) { + Value *CatchSwitch = nullptr; + + if (ParseToken(lltok::kw_within, "expected 'within' after catchpad")) + return true; + + if (Lex.getKind() != lltok::LocalVar && Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for catchpad"); + + if (ParseValue(Type::getTokenTy(Context), CatchSwitch, PFS)) + return true; + SmallVector<Value *, 8> Args; if (ParseExceptionArgs(Args, PFS)) return true; - Inst = CleanupPadInst::Create(Context, Args); + Inst = CatchPadInst::Create(CatchSwitch, 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")) +/// ParseTerminatePad +/// ::= 'terminatepad' within Parent ParamList 'to' TypeAndValue +bool LLParser::ParseTerminatePad(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad = nullptr; + + if (ParseToken(lltok::kw_within, "expected 'within' after terminatepad")) + return true; + + if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && + Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for terminatepad"); + + if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS)) + return true; + + 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 (Lex.getKind() == lltok::kw_caller) { - Lex.Lex(); - } else { + if (ParseToken(lltok::kw_caller, "expected 'caller' in terminatepad")) return true; - } } else { if (ParseTypeAndBasicBlock(UnwindBB, PFS)) { return true; } } - Inst = CatchEndPadInst::Create(Context, UnwindBB); + Inst = TerminatePadInst::Create(ParentPad, UnwindBB, Args); return false; } -/// ParseCatchEndPad -/// ::= 'cleanupendpad' Value unwind ('to' 'caller' | TypeAndValue) -bool LLParser::ParseCleanupEndPad(Instruction *&Inst, PerFunctionState &PFS) { - Value *CleanupPad = nullptr; +/// ParseCleanupPad +/// ::= 'cleanuppad' within Parent ParamList +bool LLParser::ParseCleanupPad(Instruction *&Inst, PerFunctionState &PFS) { + Value *ParentPad = nullptr; - if (ParseValue(Type::getTokenTy(Context), CleanupPad, PFS, OC_CleanupPad)) + if (ParseToken(lltok::kw_within, "expected 'within' after cleanuppad")) return true; - if (ParseToken(lltok::kw_unwind, "expected 'unwind' in catchendpad")) + if (Lex.getKind() != lltok::kw_none && Lex.getKind() != lltok::LocalVar && + Lex.getKind() != lltok::LocalVarID) + return TokError("expected scope value for cleanuppad"); + + if (ParseValue(Type::getTokenTy(Context), ParentPad, PFS)) 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; - } - } + SmallVector<Value *, 8> Args; + if (ParseExceptionArgs(Args, PFS)) + return true; - Inst = CleanupEndPadInst::Create(cast<CleanupPadInst>(CleanupPad), UnwindBB); + Inst = CleanupPadInst::Create(ParentPad, Args); return false; } |