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 | 45 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLParser.h | 6 | ||||
-rw-r--r-- | llvm/lib/AsmParser/LLToken.h | 1 |
4 files changed, 53 insertions, 0 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp index 1e5bcdd930c..962298fcd54 100644 --- a/llvm/lib/AsmParser/LLLexer.cpp +++ b/llvm/lib/AsmParser/LLLexer.cpp @@ -612,6 +612,7 @@ lltok::Kind LLLexer::LexIdentifier() { KEYWORD(byval); KEYWORD(inalloca); KEYWORD(cold); + KEYWORD(dereferenceable); KEYWORD(inlinehint); KEYWORD(inreg); KEYWORD(jumptable); diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp index be55ac6481f..ac6e0e512fe 100644 --- a/llvm/lib/AsmParser/LLParser.cpp +++ b/llvm/lib/AsmParser/LLParser.cpp @@ -1052,6 +1052,7 @@ bool LLParser::ParseFnAttributeValuePairs(AttrBuilder &B, "invalid use of attribute on a function"); break; case lltok::kw_byval: + case lltok::kw_dereferenceable: case lltok::kw_inalloca: case lltok::kw_nest: case lltok::kw_noalias: @@ -1212,6 +1213,16 @@ bool LLParser::ParseUInt32(unsigned &Val) { return false; } +/// ParseUInt64 +/// ::= uint64 +bool LLParser::ParseUInt64(uint64_t &Val) { + if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned()) + return TokError("expected integer"); + Val = Lex.getAPSIntVal().getLimitedValue(); + Lex.Lex(); + return false; +} + /// ParseTLSModel /// := 'localdynamic' /// := 'initialexec' @@ -1284,6 +1295,13 @@ bool LLParser::ParseOptionalParamAttrs(AttrBuilder &B) { continue; } case lltok::kw_byval: B.addAttribute(Attribute::ByVal); break; + case lltok::kw_dereferenceable: { + uint64_t Bytes; + if (ParseOptionalDereferenceableBytes(Bytes)) + return true; + B.addDereferenceableAttr(Bytes); + continue; + } case lltok::kw_inalloca: B.addAttribute(Attribute::InAlloca); break; case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_nest: B.addAttribute(Attribute::Nest); break; @@ -1341,6 +1359,13 @@ bool LLParser::ParseOptionalReturnAttrs(AttrBuilder &B) { switch (Token) { default: // End of attributes. return HaveError; + case lltok::kw_dereferenceable: { + uint64_t Bytes; + if (ParseOptionalDereferenceableBytes(Bytes)) + return true; + B.addDereferenceableAttr(Bytes); + continue; + } case lltok::kw_inreg: B.addAttribute(Attribute::InReg); break; case lltok::kw_noalias: B.addAttribute(Attribute::NoAlias); break; case lltok::kw_nonnull: B.addAttribute(Attribute::NonNull); break; @@ -1606,6 +1631,26 @@ bool LLParser::ParseOptionalAlignment(unsigned &Alignment) { return false; } +/// ParseOptionalDereferenceableBytes +/// ::= /* empty */ +/// ::= 'dereferenceable' '(' 4 ')' +bool LLParser::ParseOptionalDereferenceableBytes(uint64_t &Bytes) { + Bytes = 0; + if (!EatIfPresent(lltok::kw_dereferenceable)) + return false; + LocTy ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::lparen)) + return Error(ParenLoc, "expected '('"); + LocTy DerefLoc = Lex.getLoc(); + if (ParseUInt64(Bytes)) return true; + ParenLoc = Lex.getLoc(); + if (!EatIfPresent(lltok::rparen)) + return Error(ParenLoc, "expected ')'"); + if (!Bytes) + return Error(DerefLoc, "dereferenceable bytes must be non-zero"); + return false; +} + /// ParseOptionalCommaAlign /// ::= /// ::= ',' align 4 diff --git a/llvm/lib/AsmParser/LLParser.h b/llvm/lib/AsmParser/LLParser.h index 2efb260d66b..7203bb245d0 100644 --- a/llvm/lib/AsmParser/LLParser.h +++ b/llvm/lib/AsmParser/LLParser.h @@ -202,6 +202,11 @@ namespace llvm { Loc = Lex.getLoc(); return ParseUInt32(Val); } + bool ParseUInt64(uint64_t &Val); + bool ParseUInt64(uint64_t &Val, LocTy &Loc) { + Loc = Lex.getLoc(); + return ParseUInt64(Val); + } bool ParseTLSModel(GlobalVariable::ThreadLocalMode &TLM); bool ParseOptionalThreadLocal(GlobalVariable::ThreadLocalMode &TLM); @@ -219,6 +224,7 @@ namespace llvm { bool ParseOptionalDLLStorageClass(unsigned &DLLStorageClass); bool ParseOptionalCallingConv(CallingConv::ID &CC); bool ParseOptionalAlignment(unsigned &Alignment); + bool ParseOptionalDereferenceableBytes(uint64_t &Bytes); bool ParseScopeAndOrdering(bool isAtomic, SynchronizationScope &Scope, AtomicOrdering &Ordering); bool ParseOrdering(AtomicOrdering &Ordering); diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h index 534d82415fd..2f02606f93e 100644 --- a/llvm/lib/AsmParser/LLToken.h +++ b/llvm/lib/AsmParser/LLToken.h @@ -106,6 +106,7 @@ namespace lltok { kw_byval, kw_inalloca, kw_cold, + kw_dereferenceable, kw_inlinehint, kw_inreg, kw_jumptable, |