diff options
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r-- | llvm/lib/AsmParser/LLLexer.cpp | 1 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 3 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 |
4 files changed, 25 insertions, 11 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 2dc1c0a1487..2ead37198b1 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -551,6 +551,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(nsw); KEYWORD(exact); KEYWORD(inbounds); + KEYWORD(inrange); KEYWORD(align); KEYWORD(addrspace); KEYWORD(section); 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; } diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 479ff96bc8a..16d4e8b5baa 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -411,7 +411,8 @@ namespace llvm { bool ParseValID(ValID &ID, PerFunctionState *PFS = nullptr); bool ParseGlobalValue(Type *Ty, Constant *&V); bool ParseGlobalTypeAndValue(Constant *&V); - bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts); + bool ParseGlobalValueVector(SmallVectorImpl<Constant *> &Elts, + Optional<unsigned> *InRangeOp = nullptr); bool parseOptionalComdat(StringRef GlobalName, Comdat *&C); bool ParseMetadataAsValue(Value *&V, PerFunctionState &PFS); bool ParseValueAsMetadata(Metadata *&MD, const Twine &TypeMsg, diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 555aee3ef04..a1695258bbe 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -103,6 +103,7 @@ enum Kind { kw_nsw, kw_exact, kw_inbounds, + kw_inrange, kw_align, kw_addrspace, kw_section, |