summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MIRParser
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2015-07-20 20:31:01 +0000
committerAlex Lorenz <arphaman@gmail.com>2015-07-20 20:31:01 +0000
commitb29554dab927a92dda672cb597d3675f457a4ca2 (patch)
tree056fc98353fdcc8ee436ba3f3fb491df7099beae /llvm/lib/CodeGen/MIRParser
parentd285d3fbb7bed80d324d0ed4eae7f956a1fe11a3 (diff)
downloadbcm5719-llvm-b29554dab927a92dda672cb597d3675f457a4ca2.tar.gz
bcm5719-llvm-b29554dab927a92dda672cb597d3675f457a4ca2.zip
MIR Parser: Add support for quoted named global value operands.
This commit extends the machine instruction lexer and implements support for the quoted global value tokens. With this change the syntax for the global value identifier tokens becomes identical to the syntax for the global identifier tokens from the LLVM's assembly language. Reviewers: Duncan P. N. Exon Smith llvm-svn: 242702
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser')
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp62
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.h22
-rw-r--r--llvm/lib/CodeGen/MIRParser/MIParser.cpp25
3 files changed, 102 insertions, 7 deletions
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.cpp b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
index 771e3e1aa0f..9ec12ee2427 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.cpp
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "MILexer.h"
+#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Twine.h"
#include <cctype>
@@ -68,6 +69,51 @@ static bool isIdentifierChar(char C) {
C == '$';
}
+void MIToken::unescapeQuotedStringValue(std::string &Str) const {
+ assert(isStringValueQuoted() && "String value isn't quoted");
+ StringRef Value = Range.drop_front(StringOffset);
+ assert(Value.front() == '"' && Value.back() == '"');
+ Cursor C = Cursor(Value.substr(1, Value.size() - 2));
+
+ Str.clear();
+ Str.reserve(C.remaining().size());
+ while (!C.isEOF()) {
+ char Char = C.peek();
+ if (Char == '\\') {
+ if (C.peek(1) == '\\') {
+ // Two '\' become one
+ Str += '\\';
+ C.advance(2);
+ continue;
+ }
+ if (isxdigit(C.peek(1)) && isxdigit(C.peek(2))) {
+ Str += hexDigitValue(C.peek(1)) * 16 + hexDigitValue(C.peek(2));
+ C.advance(3);
+ continue;
+ }
+ }
+ Str += Char;
+ C.advance();
+ }
+}
+
+/// Lex a string constant using the following regular expression: \"[^\"]*\"
+static Cursor lexStringConstant(
+ Cursor C,
+ function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
+ assert(C.peek() == '"');
+ for (C.advance(); C.peek() != '"'; C.advance()) {
+ if (C.isEOF()) {
+ ErrorCallback(
+ C.location(),
+ "end of machine instruction reached before the closing '\"'");
+ return None;
+ }
+ }
+ C.advance();
+ return C;
+}
+
static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
return StringSwitch<MIToken::TokenKind>(Identifier)
.Case("_", MIToken::underscore)
@@ -190,12 +236,22 @@ static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
return C;
}
-static Cursor maybeLexGlobalValue(Cursor C, MIToken &Token) {
+static Cursor maybeLexGlobalValue(
+ Cursor C, MIToken &Token,
+ function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
if (C.peek() != '@')
return None;
auto Range = C;
C.advance(); // Skip the '@'
- // TODO: add support for quoted names.
+ if (C.peek() == '"') {
+ if (Cursor R = lexStringConstant(C, ErrorCallback)) {
+ Token = MIToken(MIToken::QuotedNamedGlobalValue, Range.upto(R),
+ /*StringOffset=*/1); // Drop the '@'
+ return R;
+ }
+ Token = MIToken(MIToken::Error, Range.remaining());
+ return Range;
+ }
if (!isdigit(C.peek())) {
while (isIdentifierChar(C.peek()))
C.advance();
@@ -267,7 +323,7 @@ StringRef llvm::lexMIToken(
return R.remaining();
if (Cursor R = maybeLexRegister(C, Token))
return R.remaining();
- if (Cursor R = maybeLexGlobalValue(C, Token))
+ if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
return R.remaining();
if (Cursor R = maybeLexIntegerLiteral(C, Token))
return R.remaining();
diff --git a/llvm/lib/CodeGen/MIRParser/MILexer.h b/llvm/lib/CodeGen/MIRParser/MILexer.h
index 2085eb38f0c..778640a2c81 100644
--- a/llvm/lib/CodeGen/MIRParser/MILexer.h
+++ b/llvm/lib/CodeGen/MIRParser/MILexer.h
@@ -52,6 +52,7 @@ struct MIToken {
StackObject,
FixedStackObject,
NamedGlobalValue,
+ QuotedNamedGlobalValue,
GlobalValue,
// Other tokens
@@ -94,7 +95,26 @@ public:
StringRef::iterator location() const { return Range.begin(); }
- StringRef stringValue() const { return Range.drop_front(StringOffset); }
+ bool isStringValueQuoted() const { return Kind == QuotedNamedGlobalValue; }
+
+ /// Return the token's raw string value.
+ ///
+ /// If the string value is quoted, this method returns that quoted string as
+ /// it is, without unescaping the string value.
+ StringRef rawStringValue() const { return Range.drop_front(StringOffset); }
+
+ /// Return token's string value.
+ ///
+ /// Expects the string value to be unquoted.
+ StringRef stringValue() const {
+ assert(!isStringValueQuoted() && "String value is quoted");
+ return Range.drop_front(StringOffset);
+ }
+
+ /// Unescapes the token's string value.
+ ///
+ /// Expects the string value to be quoted.
+ void unescapeQuotedStringValue(std::string &Str) const;
const APSInt &integerValue() const { return IntVal; }
diff --git a/llvm/lib/CodeGen/MIRParser/MIParser.cpp b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
index 3b820c3cdee..b458a8b8882 100644
--- a/llvm/lib/CodeGen/MIRParser/MIParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIParser.cpp
@@ -31,6 +31,22 @@ using namespace llvm;
namespace {
+struct StringValueUtility {
+ StringRef String;
+ std::string UnescapedString;
+
+ StringValueUtility(const MIToken &Token) {
+ if (Token.isStringValueQuoted()) {
+ Token.unescapeQuotedStringValue(UnescapedString);
+ String = UnescapedString;
+ return;
+ }
+ String = Token.stringValue();
+ }
+
+ operator StringRef() const { return String; }
+};
+
/// A wrapper struct around the 'MachineOperand' struct that includes a source
/// range.
struct MachineOperandWithLocation {
@@ -485,14 +501,16 @@ bool MIParser::parseFixedStackObjectOperand(MachineOperand &Dest) {
bool MIParser::parseGlobalAddressOperand(MachineOperand &Dest) {
switch (Token.kind()) {
- case MIToken::NamedGlobalValue: {
- auto Name = Token.stringValue();
+ case MIToken::NamedGlobalValue:
+ case MIToken::QuotedNamedGlobalValue: {
+ StringValueUtility Name(Token);
const Module *M = MF.getFunction()->getParent();
if (const auto *GV = M->getNamedValue(Name)) {
Dest = MachineOperand::CreateGA(GV, /*Offset=*/0);
break;
}
- return error(Twine("use of undefined global value '@") + Name + "'");
+ return error(Twine("use of undefined global value '@") +
+ Token.rawStringValue() + "'");
}
case MIToken::GlobalValue: {
unsigned GVIdx;
@@ -548,6 +566,7 @@ bool MIParser::parseMachineOperand(MachineOperand &Dest) {
return parseFixedStackObjectOperand(Dest);
case MIToken::GlobalValue:
case MIToken::NamedGlobalValue:
+ case MIToken::QuotedNamedGlobalValue:
return parseGlobalAddressOperand(Dest);
case MIToken::JumpTableIndex:
return parseJumpTableIndexOperand(Dest);
OpenPOWER on IntegriCloud