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 11782a1cfdcSAlex Lorenz static Cursor lexName( 11882a1cfdcSAlex Lorenz Cursor C, MIToken &Token, MIToken::TokenKind Type, 11982a1cfdcSAlex Lorenz MIToken::TokenKind QuotedType, unsigned PrefixLength, 12082a1cfdcSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 12182a1cfdcSAlex Lorenz auto Range = C; 12282a1cfdcSAlex Lorenz C.advance(PrefixLength); 12382a1cfdcSAlex Lorenz if (C.peek() == '"') { 12482a1cfdcSAlex Lorenz if (Cursor R = lexStringConstant(C, ErrorCallback)) { 12582a1cfdcSAlex Lorenz Token = MIToken(QuotedType, Range.upto(R), PrefixLength); 12682a1cfdcSAlex Lorenz return R; 12782a1cfdcSAlex Lorenz } 12882a1cfdcSAlex Lorenz Token = MIToken(MIToken::Error, Range.remaining()); 12982a1cfdcSAlex Lorenz return Range; 13082a1cfdcSAlex Lorenz } 13182a1cfdcSAlex Lorenz while (isIdentifierChar(C.peek())) 13282a1cfdcSAlex Lorenz C.advance(); 13382a1cfdcSAlex Lorenz Token = MIToken(Type, Range.upto(C), PrefixLength); 13482a1cfdcSAlex Lorenz return C; 13582a1cfdcSAlex Lorenz } 13682a1cfdcSAlex Lorenz 137cb268d46SAlex Lorenz static MIToken::TokenKind getIdentifierKind(StringRef Identifier) { 138cb268d46SAlex Lorenz return StringSwitch<MIToken::TokenKind>(Identifier) 139cb268d46SAlex Lorenz .Case("_", MIToken::underscore) 140cb268d46SAlex Lorenz .Case("implicit", MIToken::kw_implicit) 141cb268d46SAlex Lorenz .Case("implicit-def", MIToken::kw_implicit_define) 142cbbfd0b1SAlex Lorenz .Case("dead", MIToken::kw_dead) 143495ad879SAlex Lorenz .Case("killed", MIToken::kw_killed) 1444d026b89SAlex Lorenz .Case("undef", MIToken::kw_undef) 145e5a44660SAlex Lorenz .Case("frame-setup", MIToken::kw_frame_setup) 14646d760d1SAlex Lorenz .Case("debug-location", MIToken::kw_debug_location) 1478cfc6867SAlex Lorenz .Case(".cfi_offset", MIToken::kw_cfi_offset) 1485b0d5f6fSAlex Lorenz .Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register) 149f4baeb51SAlex Lorenz .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset) 150*b139323fSAlex Lorenz .Case(".cfi_def_cfa", MIToken::kw_cfi_def_cfa) 151deb53490SAlex Lorenz .Case("blockaddress", MIToken::kw_blockaddress) 152ef5c196fSAlex Lorenz .Case("target-index", MIToken::kw_target_index) 153cb268d46SAlex Lorenz .Default(MIToken::Identifier); 154cb268d46SAlex Lorenz } 155cb268d46SAlex Lorenz 1566c6c46e4SAlex Lorenz static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) { 157f4baeb51SAlex Lorenz if (!isalpha(C.peek()) && C.peek() != '_' && C.peek() != '.') 1586c6c46e4SAlex Lorenz return None; 15991370c5dSAlex Lorenz auto Range = C; 16091370c5dSAlex Lorenz while (isIdentifierChar(C.peek())) 16191370c5dSAlex Lorenz C.advance(); 16212b554e6SAlex Lorenz auto Identifier = Range.upto(C); 163cb268d46SAlex Lorenz Token = MIToken(getIdentifierKind(Identifier), Identifier); 16491370c5dSAlex Lorenz return C; 16591370c5dSAlex Lorenz } 16691370c5dSAlex Lorenz 1676c6c46e4SAlex Lorenz static Cursor maybeLexMachineBasicBlock( 16833f0aef3SAlex Lorenz Cursor C, MIToken &Token, 16933f0aef3SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 1706c6c46e4SAlex Lorenz if (!C.remaining().startswith("%bb.")) 1716c6c46e4SAlex Lorenz return None; 17233f0aef3SAlex Lorenz auto Range = C; 17333f0aef3SAlex Lorenz C.advance(4); // Skip '%bb.' 17433f0aef3SAlex Lorenz if (!isdigit(C.peek())) { 17533f0aef3SAlex Lorenz Token = MIToken(MIToken::Error, C.remaining()); 17633f0aef3SAlex Lorenz ErrorCallback(C.location(), "expected a number after '%bb.'"); 17733f0aef3SAlex Lorenz return C; 17833f0aef3SAlex Lorenz } 17933f0aef3SAlex Lorenz auto NumberRange = C; 18033f0aef3SAlex Lorenz while (isdigit(C.peek())) 18133f0aef3SAlex Lorenz C.advance(); 18233f0aef3SAlex Lorenz StringRef Number = NumberRange.upto(C); 18333f0aef3SAlex Lorenz unsigned StringOffset = 4 + Number.size(); // Drop '%bb.<id>' 18433f0aef3SAlex Lorenz if (C.peek() == '.') { 18533f0aef3SAlex Lorenz C.advance(); // Skip '.' 18633f0aef3SAlex Lorenz ++StringOffset; 18733f0aef3SAlex Lorenz while (isIdentifierChar(C.peek())) 18833f0aef3SAlex Lorenz C.advance(); 18933f0aef3SAlex Lorenz } 19033f0aef3SAlex Lorenz Token = MIToken(MIToken::MachineBasicBlock, Range.upto(C), APSInt(Number), 19133f0aef3SAlex Lorenz StringOffset); 19233f0aef3SAlex Lorenz return C; 19333f0aef3SAlex Lorenz } 19433f0aef3SAlex Lorenz 19531d70683SAlex Lorenz static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule, 19631d70683SAlex Lorenz MIToken::TokenKind Kind) { 19731d70683SAlex Lorenz if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size()))) 19831d70683SAlex Lorenz return None; 19931d70683SAlex Lorenz auto Range = C; 20031d70683SAlex Lorenz C.advance(Rule.size()); 20131d70683SAlex Lorenz auto NumberRange = C; 20231d70683SAlex Lorenz while (isdigit(C.peek())) 20331d70683SAlex Lorenz C.advance(); 20431d70683SAlex Lorenz Token = MIToken(Kind, Range.upto(C), APSInt(NumberRange.upto(C))); 20531d70683SAlex Lorenz return C; 20631d70683SAlex Lorenz } 20731d70683SAlex Lorenz 2087feaf7c6SAlex Lorenz static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule, 2097feaf7c6SAlex Lorenz MIToken::TokenKind Kind) { 2107feaf7c6SAlex Lorenz if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size()))) 2117feaf7c6SAlex Lorenz return None; 2127feaf7c6SAlex Lorenz auto Range = C; 2137feaf7c6SAlex Lorenz C.advance(Rule.size()); 2147feaf7c6SAlex Lorenz auto NumberRange = C; 2157feaf7c6SAlex Lorenz while (isdigit(C.peek())) 2167feaf7c6SAlex Lorenz C.advance(); 2177feaf7c6SAlex Lorenz StringRef Number = NumberRange.upto(C); 2187feaf7c6SAlex Lorenz unsigned StringOffset = Rule.size() + Number.size(); 2197feaf7c6SAlex Lorenz if (C.peek() == '.') { 2207feaf7c6SAlex Lorenz C.advance(); 2217feaf7c6SAlex Lorenz ++StringOffset; 2227feaf7c6SAlex Lorenz while (isIdentifierChar(C.peek())) 2237feaf7c6SAlex Lorenz C.advance(); 2247feaf7c6SAlex Lorenz } 2257feaf7c6SAlex Lorenz Token = MIToken(Kind, Range.upto(C), APSInt(Number), StringOffset); 2267feaf7c6SAlex Lorenz return C; 2277feaf7c6SAlex Lorenz } 2287feaf7c6SAlex Lorenz 22931d70683SAlex Lorenz static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) { 23031d70683SAlex Lorenz return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex); 23131d70683SAlex Lorenz } 23231d70683SAlex Lorenz 2337feaf7c6SAlex Lorenz static Cursor maybeLexStackObject(Cursor C, MIToken &Token) { 2347feaf7c6SAlex Lorenz return maybeLexIndexAndName(C, Token, "%stack.", MIToken::StackObject); 2357feaf7c6SAlex Lorenz } 2367feaf7c6SAlex Lorenz 2377feaf7c6SAlex Lorenz static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) { 2387feaf7c6SAlex Lorenz return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject); 2397feaf7c6SAlex Lorenz } 2407feaf7c6SAlex Lorenz 241ab980499SAlex Lorenz static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) { 242ab980499SAlex Lorenz return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem); 243ab980499SAlex Lorenz } 244ab980499SAlex Lorenz 245deb53490SAlex Lorenz static Cursor maybeLexIRBlock( 246deb53490SAlex Lorenz Cursor C, MIToken &Token, 247deb53490SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 248deb53490SAlex Lorenz const StringRef Rule = "%ir-block."; 249deb53490SAlex Lorenz if (!C.remaining().startswith(Rule)) 250deb53490SAlex Lorenz return None; 251deb53490SAlex Lorenz if (isdigit(C.peek(Rule.size()))) 252deb53490SAlex Lorenz return maybeLexIndex(C, Token, Rule, MIToken::IRBlock); 253deb53490SAlex Lorenz return lexName(C, Token, MIToken::NamedIRBlock, MIToken::QuotedNamedIRBlock, 254deb53490SAlex Lorenz Rule.size(), ErrorCallback); 2558a1915b0SAlex Lorenz } 2568a1915b0SAlex Lorenz 25753464510SAlex Lorenz static Cursor lexVirtualRegister(Cursor C, MIToken &Token) { 25853464510SAlex Lorenz auto Range = C; 25953464510SAlex Lorenz C.advance(); // Skip '%' 26053464510SAlex Lorenz auto NumberRange = C; 26153464510SAlex Lorenz while (isdigit(C.peek())) 26253464510SAlex Lorenz C.advance(); 26353464510SAlex Lorenz Token = MIToken(MIToken::VirtualRegister, Range.upto(C), 26453464510SAlex Lorenz APSInt(NumberRange.upto(C))); 26553464510SAlex Lorenz return C; 26653464510SAlex Lorenz } 26753464510SAlex Lorenz 2686c6c46e4SAlex Lorenz static Cursor maybeLexRegister(Cursor C, MIToken &Token) { 2696c6c46e4SAlex Lorenz if (C.peek() != '%') 2706c6c46e4SAlex Lorenz return None; 27153464510SAlex Lorenz if (isdigit(C.peek(1))) 27253464510SAlex Lorenz return lexVirtualRegister(C, Token); 273f3db51deSAlex Lorenz auto Range = C; 274f3db51deSAlex Lorenz C.advance(); // Skip '%' 275f3db51deSAlex Lorenz while (isIdentifierChar(C.peek())) 276f3db51deSAlex Lorenz C.advance(); 27733f0aef3SAlex Lorenz Token = MIToken(MIToken::NamedRegister, Range.upto(C), 27833f0aef3SAlex Lorenz /*StringOffset=*/1); // Drop the '%' 279f3db51deSAlex Lorenz return C; 280f3db51deSAlex Lorenz } 281f3db51deSAlex Lorenz 282c1fbb354SAlex Lorenz static Cursor maybeLexGlobalValue( 283c1fbb354SAlex Lorenz Cursor C, MIToken &Token, 284c1fbb354SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 285c1fbb354SAlex Lorenz if (C.peek() != '@') 286c1fbb354SAlex Lorenz return None; 287c1fbb354SAlex Lorenz if (!isdigit(C.peek(1))) 288c1fbb354SAlex Lorenz return lexName(C, Token, MIToken::NamedGlobalValue, 289c1fbb354SAlex Lorenz MIToken::QuotedNamedGlobalValue, /*PrefixLength=*/1, 290c1fbb354SAlex Lorenz ErrorCallback); 291c1fbb354SAlex Lorenz auto Range = C; 292c1fbb354SAlex Lorenz C.advance(1); // Skip the '@' 293c1fbb354SAlex Lorenz auto NumberRange = C; 294c1fbb354SAlex Lorenz while (isdigit(C.peek())) 295c1fbb354SAlex Lorenz C.advance(); 296c1fbb354SAlex Lorenz Token = 297c1fbb354SAlex Lorenz MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C))); 298c1fbb354SAlex Lorenz return C; 299c1fbb354SAlex Lorenz } 300c1fbb354SAlex Lorenz 3016ede3744SAlex Lorenz static Cursor maybeLexExternalSymbol( 3026ede3744SAlex Lorenz Cursor C, MIToken &Token, 3036ede3744SAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 3046ede3744SAlex Lorenz if (C.peek() != '$') 3056ede3744SAlex Lorenz return None; 3066ede3744SAlex Lorenz return lexName(C, Token, MIToken::ExternalSymbol, 3076ede3744SAlex Lorenz MIToken::QuotedExternalSymbol, 3086ede3744SAlex Lorenz /*PrefixLength=*/1, ErrorCallback); 3096ede3744SAlex Lorenz } 3106ede3744SAlex Lorenz 3116c6c46e4SAlex Lorenz static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) { 3126c6c46e4SAlex Lorenz if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1)))) 3136c6c46e4SAlex Lorenz return None; 314240fc1e0SAlex Lorenz auto Range = C; 315240fc1e0SAlex Lorenz C.advance(); 316240fc1e0SAlex Lorenz while (isdigit(C.peek())) 317240fc1e0SAlex Lorenz C.advance(); 318240fc1e0SAlex Lorenz StringRef StrVal = Range.upto(C); 319240fc1e0SAlex Lorenz Token = MIToken(MIToken::IntegerLiteral, StrVal, APSInt(StrVal)); 320240fc1e0SAlex Lorenz return C; 321240fc1e0SAlex Lorenz } 322240fc1e0SAlex Lorenz 323f3db51deSAlex Lorenz static MIToken::TokenKind symbolToken(char C) { 324f3db51deSAlex Lorenz switch (C) { 325f3db51deSAlex Lorenz case ',': 326f3db51deSAlex Lorenz return MIToken::comma; 327f3db51deSAlex Lorenz case '=': 328f3db51deSAlex Lorenz return MIToken::equal; 3292eacca86SAlex Lorenz case ':': 3302eacca86SAlex Lorenz return MIToken::colon; 33135e44469SAlex Lorenz case '!': 33235e44469SAlex Lorenz return MIToken::exclaim; 333deb53490SAlex Lorenz case '(': 334deb53490SAlex Lorenz return MIToken::lparen; 335deb53490SAlex Lorenz case ')': 336deb53490SAlex Lorenz return MIToken::rparen; 337f3db51deSAlex Lorenz default: 338f3db51deSAlex Lorenz return MIToken::Error; 339f3db51deSAlex Lorenz } 340f3db51deSAlex Lorenz } 341f3db51deSAlex Lorenz 3426c6c46e4SAlex Lorenz static Cursor maybeLexSymbol(Cursor C, MIToken &Token) { 3436c6c46e4SAlex Lorenz auto Kind = symbolToken(C.peek()); 3446c6c46e4SAlex Lorenz if (Kind == MIToken::Error) 3456c6c46e4SAlex Lorenz return None; 346f3db51deSAlex Lorenz auto Range = C; 347f3db51deSAlex Lorenz C.advance(); 348f3db51deSAlex Lorenz Token = MIToken(Kind, Range.upto(C)); 349f3db51deSAlex Lorenz return C; 350f3db51deSAlex Lorenz } 351f3db51deSAlex Lorenz 35291370c5dSAlex Lorenz StringRef llvm::lexMIToken( 35391370c5dSAlex Lorenz StringRef Source, MIToken &Token, 35491370c5dSAlex Lorenz function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) { 35591370c5dSAlex Lorenz auto C = skipWhitespace(Cursor(Source)); 35691370c5dSAlex Lorenz if (C.isEOF()) { 35791370c5dSAlex Lorenz Token = MIToken(MIToken::Eof, C.remaining()); 35891370c5dSAlex Lorenz return C.remaining(); 35991370c5dSAlex Lorenz } 36091370c5dSAlex Lorenz 3616c6c46e4SAlex Lorenz if (Cursor R = maybeLexIdentifier(C, Token)) 3626c6c46e4SAlex Lorenz return R.remaining(); 3636c6c46e4SAlex Lorenz if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback)) 3646c6c46e4SAlex Lorenz return R.remaining(); 36531d70683SAlex Lorenz if (Cursor R = maybeLexJumpTableIndex(C, Token)) 36631d70683SAlex Lorenz return R.remaining(); 3677feaf7c6SAlex Lorenz if (Cursor R = maybeLexStackObject(C, Token)) 3687feaf7c6SAlex Lorenz return R.remaining(); 3697feaf7c6SAlex Lorenz if (Cursor R = maybeLexFixedStackObject(C, Token)) 3707feaf7c6SAlex Lorenz return R.remaining(); 371ab980499SAlex Lorenz if (Cursor R = maybeLexConstantPoolItem(C, Token)) 372ab980499SAlex Lorenz return R.remaining(); 373deb53490SAlex Lorenz if (Cursor R = maybeLexIRBlock(C, Token, ErrorCallback)) 3748a1915b0SAlex Lorenz return R.remaining(); 3756c6c46e4SAlex Lorenz if (Cursor R = maybeLexRegister(C, Token)) 3766c6c46e4SAlex Lorenz return R.remaining(); 377b29554daSAlex Lorenz if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback)) 3786c6c46e4SAlex Lorenz return R.remaining(); 3796ede3744SAlex Lorenz if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback)) 3806ede3744SAlex Lorenz return R.remaining(); 3816c6c46e4SAlex Lorenz if (Cursor R = maybeLexIntegerLiteral(C, Token)) 3826c6c46e4SAlex Lorenz return R.remaining(); 3836c6c46e4SAlex Lorenz if (Cursor R = maybeLexSymbol(C, Token)) 3846c6c46e4SAlex Lorenz return R.remaining(); 3856c6c46e4SAlex Lorenz 38691370c5dSAlex Lorenz Token = MIToken(MIToken::Error, C.remaining()); 38791370c5dSAlex Lorenz ErrorCallback(C.location(), 3886c6c46e4SAlex Lorenz Twine("unexpected character '") + Twine(C.peek()) + "'"); 38991370c5dSAlex Lorenz return C.remaining(); 39091370c5dSAlex Lorenz } 391