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.cpp37
-rw-r--r--llvm/lib/AsmParser/LLToken.h9
3 files changed, 42 insertions, 5 deletions
diff --git a/llvm/lib/AsmParser/LLLexer.cpp b/llvm/lib/AsmParser/LLLexer.cpp
index 63eb96324fa..2fd9861c517 100644
--- a/llvm/lib/AsmParser/LLLexer.cpp
+++ b/llvm/lib/AsmParser/LLLexer.cpp
@@ -748,6 +748,7 @@ lltok::Kind LLLexer::LexIdentifier() {
DWKEYWORD(ATE, DwarfAttEncoding);
DWKEYWORD(VIRTUALITY, DwarfVirtuality);
DWKEYWORD(LANG, DwarfLang);
+ DWKEYWORD(OP, DwarfOp);
#undef DWKEYWORD
// Check for [us]0x[0-9A-Fa-f]+ which are Hexadecimal constant generated by
diff --git a/llvm/lib/AsmParser/LLParser.cpp b/llvm/lib/AsmParser/LLParser.cpp
index 48dbaeeb76a..dc8367c5626 100644
--- a/llvm/lib/AsmParser/LLParser.cpp
+++ b/llvm/lib/AsmParser/LLParser.cpp
@@ -3599,9 +3599,44 @@ bool LLParser::ParseMDLocalVariable(MDNode *&Result, bool IsDistinct) {
return false;
}
+/// ParseMDExpression:
+/// ::= !MDExpression(0, 7, -1)
bool LLParser::ParseMDExpression(MDNode *&Result, bool IsDistinct) {
- return TokError("unimplemented parser");
+ assert(Lex.getKind() == lltok::MetadataVar && "Expected metadata type name");
+ Lex.Lex();
+
+ if (ParseToken(lltok::lparen, "expected '(' here"))
+ return true;
+
+ SmallVector<uint64_t, 8> Elements;
+ if (Lex.getKind() != lltok::rparen)
+ do {
+ if (Lex.getKind() == lltok::DwarfOp) {
+ if (unsigned Op = dwarf::getOperationEncoding(Lex.getStrVal())) {
+ Lex.Lex();
+ Elements.push_back(Op);
+ continue;
+ }
+ return TokError(Twine("invalid DWARF op '") + Lex.getStrVal() + "'");
+ }
+
+ if (Lex.getKind() != lltok::APSInt || Lex.getAPSIntVal().isSigned())
+ return TokError("expected unsigned integer");
+
+ auto &U = Lex.getAPSIntVal();
+ if (U.ugt(UINT64_MAX))
+ return TokError("element too large, limit is " + Twine(UINT64_MAX));
+ Elements.push_back(U.getZExtValue());
+ Lex.Lex();
+ } while (EatIfPresent(lltok::comma));
+
+ if (ParseToken(lltok::rparen, "expected ')' here"))
+ return true;
+
+ Result = GET_OR_DISTINCT(MDExpression, (Context, Elements));
+ return false;
}
+
bool LLParser::ParseMDObjCProperty(MDNode *&Result, bool IsDistinct) {
return TokError("unimplemented parser");
}
diff --git a/llvm/lib/AsmParser/LLToken.h b/llvm/lib/AsmParser/LLToken.h
index ff894df5db4..57218dafbb9 100644
--- a/llvm/lib/AsmParser/LLToken.h
+++ b/llvm/lib/AsmParser/LLToken.h
@@ -198,10 +198,11 @@ namespace lltok {
LocalVar, // %foo %"foo"
MetadataVar, // !foo
StringConstant, // "foo"
- DwarfTag, // DW_TAG_foo (includes "DW_TAG_")
- DwarfAttEncoding, // DW_ATE_foo (includes "DW_ATE_")
- DwarfVirtuality, // DW_VIRTUALITY_foo (includes "DW_VIRTUALITY_")
- DwarfLang, // DW_LANG_foo (includes "DW_LANG_")
+ DwarfTag, // DW_TAG_foo
+ DwarfAttEncoding, // DW_ATE_foo
+ DwarfVirtuality, // DW_VIRTUALITY_foo
+ DwarfLang, // DW_LANG_foo
+ DwarfOp, // DW_OP_foo
// Type valued tokens (TyVal).
Type,
OpenPOWER on IntegriCloud