diff options
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser/MIParser.cpp')
-rw-r--r-- | llvm/lib/CodeGen/MIRParser/MIParser.cpp | 64 |
1 files changed, 59 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp index c68d87b15a3..5d68d4463a6 100644 --- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp @@ -39,6 +39,7 @@ #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DataLayout.h" +#include "llvm/IR/DebugInfoMetadata.h" #include "llvm/IR/DebugLoc.h" #include "llvm/IR/Function.h" #include "llvm/IR/InstrTypes.h" @@ -209,6 +210,7 @@ public: bool parseJumpTableIndexOperand(MachineOperand &Dest); bool parseExternalSymbolOperand(MachineOperand &Dest); bool parseMDNode(MDNode *&Node); + bool parseDIExpression(MDNode *&Node); bool parseMetadataOperand(MachineOperand &Dest); bool parseCFIOffset(int &Offset); bool parseCFIRegister(unsigned &Reg); @@ -854,10 +856,14 @@ bool MIParser::parseStandaloneStackObject(int &FI) { bool MIParser::parseStandaloneMDNode(MDNode *&Node) { lex(); - if (Token.isNot(MIToken::exclaim)) + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(Node)) + return true; + } else if (Token.is(MIToken::md_diexpr)) { + if (parseDIExpression(Node)) + return true; + } else return error("expected a metadata node"); - if (parseMDNode(Node)) - return true; if (Token.isNot(MIToken::Eof)) return error("expected end of string after the metadata node"); return false; @@ -1492,6 +1498,7 @@ bool MIParser::parseSubRegisterIndexOperand(MachineOperand &Dest) { bool MIParser::parseMDNode(MDNode *&Node) { assert(Token.is(MIToken::exclaim)); + auto Loc = Token.location(); lex(); if (Token.isNot(MIToken::IntegerLiteral) || Token.integerValue().isSigned()) @@ -1507,10 +1514,56 @@ bool MIParser::parseMDNode(MDNode *&Node) { return false; } +bool MIParser::parseDIExpression(MDNode *&Expr) { + assert(Token.is(MIToken::md_diexpr)); + lex(); + + // FIXME: Share this parsing with the IL parser. + SmallVector<uint64_t, 8> Elements; + + if (expectAndConsume(MIToken::lparen)) + return true; + + if (Token.isNot(MIToken::rparen)) { + do { + if (Token.is(MIToken::Identifier)) { + if (unsigned Op = dwarf::getOperationEncoding(Token.stringValue())) { + lex(); + Elements.push_back(Op); + continue; + } + return error(Twine("invalid DWARF op '") + Token.stringValue() + "'"); + } + + if (Token.isNot(MIToken::IntegerLiteral) || + Token.integerValue().isSigned()) + return error("expected unsigned integer"); + + auto &U = Token.integerValue(); + if (U.ugt(UINT64_MAX)) + return error("element too large, limit is " + Twine(UINT64_MAX)); + Elements.push_back(U.getZExtValue()); + lex(); + + } while (consumeIfPresent(MIToken::comma)); + } + + if (expectAndConsume(MIToken::rparen)) + return true; + + Expr = DIExpression::get(MF.getFunction()->getContext(), Elements); + return false; +} + bool MIParser::parseMetadataOperand(MachineOperand &Dest) { MDNode *Node = nullptr; - if (parseMDNode(Node)) - return true; + if (Token.is(MIToken::exclaim)) { + if (parseMDNode(Node)) + return true; + } else if (Token.is(MIToken::md_diexpr)) { + if (parseDIExpression(Node)) + return true; + } Dest = MachineOperand::CreateMetadata(Node); return false; } @@ -1851,6 +1904,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest, return parseExternalSymbolOperand(Dest); case MIToken::SubRegisterIndex: return parseSubRegisterIndexOperand(Dest); + case MIToken::md_diexpr: case MIToken::exclaim: return parseMetadataOperand(Dest); case MIToken::kw_cfi_same_value: |