diff options
Diffstat (limited to 'llvm/lib/AsmParser/LLParser.cpp')
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index 2b8d2f81011..d73818d2b86 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -3175,7 +3175,9 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { return true; } - if (ParseGlobalValueVector(Elts) || + Optional<unsigned> InRangeOp; + if (ParseGlobalValueVector( + Elts, Opc == Instruction::GetElementPtr ? &InRangeOp : nullptr) || ParseToken(lltok::rparen, "expected ')' in constantexpr")) return true; @@ -3214,8 +3216,16 @@ bool LLParser::ParseValID(ValID &ID, PerFunctionState *PFS) { if (!GetElementPtrInst::getIndexedType(Ty, Indices)) return Error(ID.Loc, "invalid getelementptr indices"); - ID.ConstantVal = - ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, InBounds); + + if (InRangeOp) { + if (*InRangeOp == 0) + return Error(ID.Loc, + "inrange keyword may not appear on pointer operand"); + --*InRangeOp; + } + + ID.ConstantVal = ConstantExpr::getGetElementPtr(Ty, Elts[0], Indices, + InBounds, InRangeOp); } else if (Opc == Instruction::Select) { if (Elts.size() != 3) return Error(ID.Loc, "expected three operands to select"); @@ -3298,8 +3308,9 @@ bool LLParser::parseOptionalComdat(StringRef GlobalName, Comdat *&C) { /// ParseGlobalValueVector /// ::= /*empty*/ -/// ::= TypeAndValue (',' TypeAndValue)* -bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { +/// ::= [inrange] TypeAndValue (',' [inrange] TypeAndValue)* +bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts, + Optional<unsigned> *InRangeOp) { // Empty list. if (Lex.getKind() == lltok::rbrace || Lex.getKind() == lltok::rsquare || @@ -3307,14 +3318,14 @@ bool LLParser::ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts) { Lex.getKind() == lltok::rparen) return false; - Constant *C; - if (ParseGlobalTypeAndValue(C)) return true; - Elts.push_back(C); + do { + if (InRangeOp && !*InRangeOp && EatIfPresent(lltok::kw_inrange)) + *InRangeOp = Elts.size(); - while (EatIfPresent(lltok::comma)) { + Constant *C; if (ParseGlobalTypeAndValue(C)) return true; Elts.push_back(C); - } + } while (EatIfPresent(lltok::comma)); return false; } |