summaryrefslogtreecommitdiffstats
path: root/llvm/lib/CodeGen/MIRParser/MILexer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/CodeGen/MIRParser/MILexer.cpp')
-rw-r--r--llvm/lib/CodeGen/MIRParser/MILexer.cpp62
1 files changed, 59 insertions, 3 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();
OpenPOWER on IntegriCloud