summaryrefslogtreecommitdiffstats
path: root/llvm/lib/AsmParser
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/AsmParser')
-rw-r--r--llvm/lib/AsmParser/LLLexer.cpp1
-rw-r--r--llvm/lib/AsmParser/LLParser.cpp45
-rw-r--r--llvm/lib/AsmParser/LLParser.h6
-rw-r--r--llvm/lib/AsmParser/LLToken.h1
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,
OpenPOWER on IntegriCloud