191370c5dSAlex Lorenz //===- MILexer.cpp - Machine instructions lexer implementation ----------===// 291370c5dSAlex Lorenz // 391370c5dSAlex Lorenz // The LLVM Compiler Infrastructure 491370c5dSAlex Lorenz // 591370c5dSAlex Lorenz // This file is distributed under the University of Illinois Open Source 691370c5dSAlex Lorenz // License. See LICENSE.TXT for details. 791370c5dSAlex Lorenz // 891370c5dSAlex Lorenz //===----------------------------------------------------------------------===// 991370c5dSAlex Lorenz // 1091370c5dSAlex Lorenz // This file implements the lexing of machine instructions. 1191370c5dSAlex Lorenz // 1291370c5dSAlex Lorenz //===----------------------------------------------------------------------===// 1391370c5dSAlex Lorenz 1491370c5dSAlex Lorenz #include "MILexer.h" 15b29554daSAlex Lorenz #include "llvm/ADT/StringExtras.h" 16cb268d46SAlex Lorenz #include "llvm/ADT/StringSwitch.h" 1791370c5dSAlex Lorenz #include "llvm/ADT/Twine.h" 1891370c5dSAlex Lorenz #include <cctype> 1991370c5dSAlex Lorenz 2091370c5dSAlex Lorenz using namespace llvm; 2191370c5dSAlex Lorenz 2291370c5dSAlex Lorenz namespace { 2391370c5dSAlex Lorenz 2491370c5dSAlex Lorenz /// This class provides a way to iterate and get characters from the source 2591370c5dSAlex Lorenz /// string. 2691370c5dSAlex Lorenz class Cursor { 2791370c5dSAlex Lorenz const char *Ptr; 2891370c5dSAlex Lorenz const char *End; 2991370c5dSAlex Lorenz 3091370c5dSAlex Lorenz public: 316c6c46e4SAlex Lorenz Cursor(NoneType) : Ptr(nullptr), End(nullptr) {} 326c6c46e4SAlex Lorenz 3391370c5dSAlex Lorenz explicit Cursor(StringRef Str) { 3491370c5dSAlex Lorenz Ptr = Str.data(); 3591370c5dSAlex Lorenz End = Ptr + Str.size(); 3691370c5dSAlex Lorenz } 3791370c5dSAlex Lorenz 3891370c5dSAlex Lorenz bool isEOF() const { return Ptr == End; } 3991370c5dSAlex Lorenz 40c267b5f5SNAKAMURA Takumi char peek(int I = 0) const { return End - Ptr <= I ? 0 : Ptr[I]; } 4191370c5dSAlex Lorenz 4233f0aef3SAlex Lorenz void advance(unsigned I = 1) { Ptr += I; } 4391370c5dSAlex Lorenz 4491370c5dSAlex Lorenz StringRef remaining() const { return StringRef(Ptr, End - Ptr); } 4591370c5dSAlex Lorenz 4691370c5dSAlex Lorenz StringRef upto(Cursor C) const { 4791370c5dSAlex Lorenz assert(C.Ptr >= Ptr && C.Ptr <= End); 4891370c5dSAlex Lorenz return StringRef(Ptr, C.Ptr - Ptr); 4991370c5dSAlex Lorenz } 5091370c5dSAlex Lorenz 5191370c5dSAlex Lorenz StringRef::iterator location() const { return Ptr; } 526c6c46e4SAlex Lorenz 536c6c46e4SAlex Lorenz operator bool() const { return Ptr != nullptr; } 5491370c5dSAlex Lorenz }; 5591370c5dSAlex Lorenz 5691370c5dSAlex Lorenz } // end anonymous namespace 5791370c5dSAlex Lorenz 5891370c5dSAlex Lorenz /// Skip the leading whitespace characters and return the updated cursor. 5991370c5dSAlex Lorenz static Cursor skipWhitespace(Cursor C) { 6091370c5dSAlex Lorenz while (isspace(C.peek())) 6191370c5dSAlex Lorenz C.advance(); 6291370c5dSAlex Lorenz return C; 6391370c5dSAlex Lorenz } 6491370c5dSAlex Lorenz 65484903ecSAlex Lorenz /// Return true if the given character satisfies the following regular 66484903ecSAlex Lorenz /// expression: [-a-zA-Z$._0-9] 6791370c5dSAlex Lorenz static bool isIdentifierChar(char C) { 68484903ecSAlex Lorenz return isalpha(C) || isdigit(C) || C == '_' || C == '-' || C == '.' || 69484903ecSAlex Lorenz C == '$'; 7091370c5dSAlex Lorenz } 7191370c5dSAlex Lorenz 72b29554daSAlex Lorenz void MIToken::unescapeQuotedStringValue(std::string &Str) const { 73b29554daSAlex Lorenz assert(isStringValueQuoted() && "String value isn't quoted"); 74b29554daSAlex Lorenz StringRef Value = Range.drop_front(StringOffset); 75b29554daSAlex Lorenz assert(Value.front() == '"' && Value.back() == '"'); 76b29554daSAlex Lorenz Cursor C = Cursor(Value.substr(1, Value.size() - 2)); 77b29554daSAlex Lorenz 78b29554daSAlex Lorenz Str.clear(); 79b29554daSAlex Lorenz Str.reserve(C.remaining().size()); 80b29554daSAlex Lorenz while (!C.isEOF()) { 81b29554daSAlex Lorenz char Char = C.peek(); 82b29554daSAlex Lorenz if (Char == '\\') { 83b29554daSAlex Lorenz if (C.peek(1) == '\\') { 84b29554daSAlex Lorenz // Two '\' become one 85b29554daSAlex Lorenz Str += '\\'; 86b29554daSAlex Lorenz C.advance(2); 87b29554daSAlex Lorenz continue; 88b29554daSAlex Lorenz } 89b29554daSAlex Lorenz if (isxdigit(C.peek(1)) && isxdigit(C.peek(2))) { 90b29554daSAlex Lorenz Str += hexDigitValue(C.peek(1)) * 16 + hexDigitValue(C.peek(2)); 91b29554daSAlex Lorenz C.advance(3); 92b29554daSAlex Lorenz continue; 93b29554daSAlex Lorenz } 94b29554daSAlex Lorenz } 95b29554daSAlex Lorenz Str += Char; 96b29554daSAlex Lorenz C.advance(); 97b29554daSAlex Lorenz } 98b29554daSAlex Lorenz } 99b29554daSAlex Lorenz 100b29554daSAlex Lorenz /// Lex a string constant using the following regular expression: \"[^\"]*\" 101b29554daSAlex Lorenz static Cursor lexStringConstant( 102b29554daSAlex Lorenz Cursor C, 103b29554daSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 104b29554daSAlex Lorenz assert(C.peek() == '"'); 105b29554daSAlex Lorenz for (C.advance(); C.peek() != '"'; C.advance()) { 106b29554daSAlex Lorenz if (C.isEOF()) { 107b29554daSAlex Lorenz ErrorCallback( 108b29554daSAlex Lorenz C.location(), 109b29554daSAlex Lorenz "end of machine instruction reached before the closing '\"'"); 110b29554daSAlex Lorenz return None; 111b29554daSAlex Lorenz } 112b29554daSAlex Lorenz } 113b29554daSAlex Lorenz C.advance(); 114b29554daSAlex Lorenz return C; 115b29554daSAlex Lorenz } 116b29554daSAlex Lorenz 117cb268d46SAlex Lorenz static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { 118cb268d46SAlex Lorenz return StringSwitch<MIToken::TokenKind>(Identifier) 119cb268d46SAlex Lorenz .Case("_", MIToken::underscore) 120cb268d46SAlex Lorenz .Case("implicit", MIToken::kw_implicit) 121cb268d46SAlex Lorenz .Case("implicit-def", MIToken::kw_implicit_define) 122cbbfd0b1SAlex Lorenz .Case("dead", MIToken::kw_dead) 123495ad879SAlex Lorenz .Case("killed", MIToken::kw_killed) 1244d026b89SAlex Lorenz .Case("undef", MIToken::kw_undef) 125e5a44660SAlex Lorenz .Case("frame-setup", MIToken::kw_frame_setup) 12646d760d1SAlex Lorenz .Case("debug-location", MIToken::kw_debug_location) 127*8cfc6867SAlex Lorenz .Case(".cfi_offset", MIToken::kw_cfi_offset) 128f4baeb51SAlex Lorenz .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) 129cb268d46SAlex Lorenz .Default(MIToken::Identifier); 130cb268d46SAlex Lorenz } 131cb268d46SAlex Lorenz 1326c6c46e4SAlex Lorenz static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) { 133f4baeb51SAlex Lorenz if (!isalpha(C.peek()) && C.peek() != '_' && C.peek() != '.') 1346c6c46e4SAlex Lorenz return None; 13591370c5dSAlex Lorenz auto Range = C; 13691370c5dSAlex Lorenz while (isIdentifierChar(C.peek())) 13791370c5dSAlex Lorenz C.advance(); 13812b554e6SAlex Lorenz auto Identifier = Range.upto(C); 139cb268d46SAlex Lorenz Token = MIToken(getIdentifierKind(Identifier), Identifier); 14091370c5dSAlex Lorenz return C; 14191370c5dSAlex Lorenz } 14291370c5dSAlex Lorenz 1436c6c46e4SAlex Lorenz static Cursor maybeLexMachineBasicBlock( 14433f0aef3SAlex Lorenz Cursor C, MIToken &Token, 14533f0aef3SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 1466c6c46e4SAlex Lorenz if (!C.remaining().startswith("%bb.")) 1476c6c46e4SAlex Lorenz return None; 14833f0aef3SAlex Lorenz auto Range = C; 14933f0aef3SAlex Lorenz C.advance(4); // Skip '%bb.' 15033f0aef3SAlex Lorenz if (!isdigit(C.peek())) { 15133f0aef3SAlex Lorenz Token = MIToken(MIToken::Error, C.remaining()); 15233f0aef3SAlex Lorenz ErrorCallback(C.location(), "expected a number after '%bb.'"); 15333f0aef3SAlex Lorenz return C; 15433f0aef3SAlex Lorenz } 15533f0aef3SAlex Lorenz auto NumberRange = C; 15633f0aef3SAlex Lorenz while (isdigit(C.peek())) 15733f0aef3SAlex Lorenz C.advance(); 15833f0aef3SAlex Lorenz StringRef Number = NumberRange.upto(C); 15933f0aef3SAlex Lorenz unsigned StringOffset = 4 + Number.size(); // Drop '%bb.<id>' 16033f0aef3SAlex Lorenz if (C.peek() == '.') { 16133f0aef3SAlex Lorenz C.advance(); // Skip '.' 16233f0aef3SAlex Lorenz ++StringOffset; 16333f0aef3SAlex Lorenz while (isIdentifierChar(C.peek())) 16433f0aef3SAlex Lorenz C.advance(); 16533f0aef3SAlex Lorenz } 16633f0aef3SAlex Lorenz Token = MIToken(MIToken::MachineBasicBlock, Range.upto(C), APSInt(Number), 16733f0aef3SAlex Lorenz StringOffset); 16833f0aef3SAlex Lorenz return C; 16933f0aef3SAlex Lorenz } 17033f0aef3SAlex Lorenz 17131d70683SAlex Lorenz static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule, 17231d70683SAlex Lorenz MIToken::TokenKind Kind) { 17331d70683SAlex Lorenz if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size()))) 17431d70683SAlex Lorenz return None; 17531d70683SAlex Lorenz auto Range = C; 17631d70683SAlex Lorenz C.advance(Rule.size()); 17731d70683SAlex Lorenz auto NumberRange = C; 17831d70683SAlex Lorenz while (isdigit(C.peek())) 17931d70683SAlex Lorenz C.advance(); 18031d70683SAlex Lorenz Token = MIToken(Kind, Range.upto(C), APSInt(NumberRange.upto(C))); 18131d70683SAlex Lorenz return C; 18231d70683SAlex Lorenz } 18331d70683SAlex Lorenz 1847feaf7c6SAlex Lorenz static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule, 1857feaf7c6SAlex Lorenz MIToken::TokenKind Kind) { 1867feaf7c6SAlex Lorenz if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size()))) 1877feaf7c6SAlex Lorenz return None; 1887feaf7c6SAlex Lorenz auto Range = C; 1897feaf7c6SAlex Lorenz C.advance(Rule.size()); 1907feaf7c6SAlex Lorenz auto NumberRange = C; 1917feaf7c6SAlex Lorenz while (isdigit(C.peek())) 1927feaf7c6SAlex Lorenz C.advance(); 1937feaf7c6SAlex Lorenz StringRef Number = NumberRange.upto(C); 1947feaf7c6SAlex Lorenz unsigned StringOffset = Rule.size() + Number.size(); 1957feaf7c6SAlex Lorenz if (C.peek() == '.') { 1967feaf7c6SAlex Lorenz C.advance(); 1977feaf7c6SAlex Lorenz ++StringOffset; 1987feaf7c6SAlex Lorenz while (isIdentifierChar(C.peek())) 1997feaf7c6SAlex Lorenz C.advance(); 2007feaf7c6SAlex Lorenz } 2017feaf7c6SAlex Lorenz Token = MIToken(Kind, Range.upto(C), APSInt(Number), StringOffset); 2027feaf7c6SAlex Lorenz return C; 2037feaf7c6SAlex Lorenz } 2047feaf7c6SAlex Lorenz 20531d70683SAlex Lorenz static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) { 20631d70683SAlex Lorenz return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex); 20731d70683SAlex Lorenz } 20831d70683SAlex Lorenz 2097feaf7c6SAlex Lorenz static Cursor maybeLexStackObject(Cursor C, MIToken &Token) { 2107feaf7c6SAlex Lorenz return maybeLexIndexAndName(C, Token, "%stack.", MIToken::StackObject); 2117feaf7c6SAlex Lorenz } 2127feaf7c6SAlex Lorenz 2137feaf7c6SAlex Lorenz static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) { 2147feaf7c6SAlex Lorenz return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject); 2157feaf7c6SAlex Lorenz } 2167feaf7c6SAlex Lorenz 217ab980499SAlex Lorenz static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) { 218ab980499SAlex Lorenz return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem); 219ab980499SAlex Lorenz } 220ab980499SAlex Lorenz 22153464510SAlex Lorenz static Cursor lexVirtualRegister(Cursor C, MIToken &Token) { 22253464510SAlex Lorenz auto Range = C; 22353464510SAlex Lorenz C.advance(); // Skip '%' 22453464510SAlex Lorenz auto NumberRange = C; 22553464510SAlex Lorenz while (isdigit(C.peek())) 22653464510SAlex Lorenz C.advance(); 22753464510SAlex Lorenz Token = MIToken(MIToken::VirtualRegister, Range.upto(C), 22853464510SAlex Lorenz APSInt(NumberRange.upto(C))); 22953464510SAlex Lorenz return C; 23053464510SAlex Lorenz } 23153464510SAlex Lorenz 2326c6c46e4SAlex Lorenz static Cursor maybeLexRegister(Cursor C, MIToken &Token) { 2336c6c46e4SAlex Lorenz if (C.peek() != '%') 2346c6c46e4SAlex Lorenz return None; 23553464510SAlex Lorenz if (isdigit(C.peek(1))) 23653464510SAlex Lorenz return lexVirtualRegister(C, Token); 237f3db51deSAlex Lorenz auto Range = C; 238f3db51deSAlex Lorenz C.advance(); // Skip '%' 239f3db51deSAlex Lorenz while (isIdentifierChar(C.peek())) 240f3db51deSAlex Lorenz C.advance(); 24133f0aef3SAlex Lorenz Token = MIToken(MIToken::NamedRegister, Range.upto(C), 24233f0aef3SAlex Lorenz /*StringOffset=*/1); // Drop the '%' 243f3db51deSAlex Lorenz return C; 244f3db51deSAlex Lorenz } 245f3db51deSAlex Lorenz 2466ede3744SAlex Lorenz static Cursor lexName( 2476ede3744SAlex Lorenz Cursor C, MIToken &Token, MIToken::TokenKind Type, 2486ede3744SAlex Lorenz MIToken::TokenKind QuotedType, unsigned PrefixLength, 2496ede3744SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 2506ede3744SAlex Lorenz auto Range = C; 2516ede3744SAlex Lorenz C.advance(PrefixLength); 2526ede3744SAlex Lorenz if (C.peek() == '"') { 2536ede3744SAlex Lorenz if (Cursor R = lexStringConstant(C, ErrorCallback)) { 2546ede3744SAlex Lorenz Token = MIToken(QuotedType, Range.upto(R), PrefixLength); 2556ede3744SAlex Lorenz return R; 2566ede3744SAlex Lorenz } 2576ede3744SAlex Lorenz Token = MIToken(MIToken::Error, Range.remaining()); 2586ede3744SAlex Lorenz return Range; 2596ede3744SAlex Lorenz } 2606ede3744SAlex Lorenz while (isIdentifierChar(C.peek())) 2616ede3744SAlex Lorenz C.advance(); 2626ede3744SAlex Lorenz Token = MIToken(Type, Range.upto(C), PrefixLength); 2636ede3744SAlex Lorenz return C; 2646ede3744SAlex Lorenz } 2656ede3744SAlex Lorenz 266c1fbb354SAlex Lorenz static Cursor maybeLexGlobalValue( 267c1fbb354SAlex Lorenz Cursor C, MIToken &Token, 268c1fbb354SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 269c1fbb354SAlex Lorenz if (C.peek() != '@') 270c1fbb354SAlex Lorenz return None; 271c1fbb354SAlex Lorenz if (!isdigit(C.peek(1))) 272c1fbb354SAlex Lorenz return lexName(C, Token, MIToken::NamedGlobalValue, 273c1fbb354SAlex Lorenz MIToken::QuotedNamedGlobalValue, /*PrefixLength=*/1, 274c1fbb354SAlex Lorenz ErrorCallback); 275c1fbb354SAlex Lorenz auto Range = C; 276c1fbb354SAlex Lorenz C.advance(1); // Skip the '@' 277c1fbb354SAlex Lorenz auto NumberRange = C; 278c1fbb354SAlex Lorenz while (isdigit(C.peek())) 279c1fbb354SAlex Lorenz C.advance(); 280c1fbb354SAlex Lorenz Token = 281c1fbb354SAlex Lorenz MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C))); 282c1fbb354SAlex Lorenz return C; 283c1fbb354SAlex Lorenz } 284c1fbb354SAlex Lorenz 2856ede3744SAlex Lorenz static Cursor maybeLexExternalSymbol( 2866ede3744SAlex Lorenz Cursor C, MIToken &Token, 2876ede3744SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 2886ede3744SAlex Lorenz if (C.peek() != '$') 2896ede3744SAlex Lorenz return None; 2906ede3744SAlex Lorenz return lexName(C, Token, MIToken::ExternalSymbol, 2916ede3744SAlex Lorenz MIToken::QuotedExternalSymbol, 2926ede3744SAlex Lorenz /*PrefixLength=*/1, ErrorCallback); 2936ede3744SAlex Lorenz } 2946ede3744SAlex Lorenz 2956c6c46e4SAlex Lorenz static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) { 2966c6c46e4SAlex Lorenz if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1)))) 2976c6c46e4SAlex Lorenz return None; 298240fc1e0SAlex Lorenz auto Range = C; 299240fc1e0SAlex Lorenz C.advance(); 300240fc1e0SAlex Lorenz while (isdigit(C.peek())) 301240fc1e0SAlex Lorenz C.advance(); 302240fc1e0SAlex Lorenz StringRef StrVal = Range.upto(C); 303240fc1e0SAlex Lorenz Token = MIToken(MIToken::IntegerLiteral, StrVal, APSInt(StrVal)); 304240fc1e0SAlex Lorenz return C; 305240fc1e0SAlex Lorenz } 306240fc1e0SAlex Lorenz 307f3db51deSAlex Lorenz static MIToken::TokenKind symbolToken(char C) { 308f3db51deSAlex Lorenz switch (C) { 309f3db51deSAlex Lorenz case ',': 310f3db51deSAlex Lorenz return MIToken::comma; 311f3db51deSAlex Lorenz case '=': 312f3db51deSAlex Lorenz return MIToken::equal; 3132eacca86SAlex Lorenz case ':': 3142eacca86SAlex Lorenz return MIToken::colon; 31535e44469SAlex Lorenz case '!': 31635e44469SAlex Lorenz return MIToken::exclaim; 317f3db51deSAlex Lorenz default: 318f3db51deSAlex Lorenz return MIToken::Error; 319f3db51deSAlex Lorenz } 320f3db51deSAlex Lorenz } 321f3db51deSAlex Lorenz 3226c6c46e4SAlex Lorenz static Cursor maybeLexSymbol(Cursor C, MIToken &Token) { 3236c6c46e4SAlex Lorenz auto Kind = symbolToken(C.peek()); 3246c6c46e4SAlex Lorenz if (Kind == MIToken::Error) 3256c6c46e4SAlex Lorenz return None; 326f3db51deSAlex Lorenz auto Range = C; 327f3db51deSAlex Lorenz C.advance(); 328f3db51deSAlex Lorenz Token = MIToken(Kind, Range.upto(C)); 329f3db51deSAlex Lorenz return C; 330f3db51deSAlex Lorenz } 331f3db51deSAlex Lorenz 33291370c5dSAlex Lorenz StringRef llvm::lexMIToken( 33391370c5dSAlex Lorenz StringRef Source, MIToken &Token, 33491370c5dSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 33591370c5dSAlex Lorenz auto C = skipWhitespace(Cursor(Source)); 33691370c5dSAlex Lorenz if (C.isEOF()) { 33791370c5dSAlex Lorenz Token = MIToken(MIToken::Eof, C.remaining()); 33891370c5dSAlex Lorenz return C.remaining(); 33991370c5dSAlex Lorenz } 34091370c5dSAlex Lorenz 3416c6c46e4SAlex Lorenz if (Cursor R = maybeLexIdentifier(C, Token)) 3426c6c46e4SAlex Lorenz return R.remaining(); 3436c6c46e4SAlex Lorenz if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback)) 3446c6c46e4SAlex Lorenz return R.remaining(); 34531d70683SAlex Lorenz if (Cursor R = maybeLexJumpTableIndex(C, Token)) 34631d70683SAlex Lorenz return R.remaining(); 3477feaf7c6SAlex Lorenz if (Cursor R = maybeLexStackObject(C, Token)) 3487feaf7c6SAlex Lorenz return R.remaining(); 3497feaf7c6SAlex Lorenz if (Cursor R = maybeLexFixedStackObject(C, Token)) 3507feaf7c6SAlex Lorenz return R.remaining(); 351ab980499SAlex Lorenz if (Cursor R = maybeLexConstantPoolItem(C, Token)) 352ab980499SAlex Lorenz return R.remaining(); 3536c6c46e4SAlex Lorenz if (Cursor R = maybeLexRegister(C, Token)) 3546c6c46e4SAlex Lorenz return R.remaining(); 355b29554daSAlex Lorenz if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback)) 3566c6c46e4SAlex Lorenz return R.remaining(); 3576ede3744SAlex Lorenz if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback)) 3586ede3744SAlex Lorenz return R.remaining(); 3596c6c46e4SAlex Lorenz if (Cursor R = maybeLexIntegerLiteral(C, Token)) 3606c6c46e4SAlex Lorenz return R.remaining(); 3616c6c46e4SAlex Lorenz if (Cursor R = maybeLexSymbol(C, Token)) 3626c6c46e4SAlex Lorenz return R.remaining(); 3636c6c46e4SAlex Lorenz 36491370c5dSAlex Lorenz Token = MIToken(MIToken::Error, C.remaining()); 36591370c5dSAlex Lorenz ErrorCallback(C.location(), 3666c6c46e4SAlex Lorenz Twine("unexpected character '") + Twine(C.peek()) + "'"); 36791370c5dSAlex Lorenz return C.remaining(); 36891370c5dSAlex Lorenz } 369