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)
126f4baeb51SAlex Lorenz       .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
127cb268d46SAlex Lorenz       .Default(MIToken::Identifier);
128cb268d46SAlex Lorenz }
129cb268d46SAlex Lorenz 
1306c6c46e4SAlex Lorenz static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) {
131f4baeb51SAlex Lorenz   if (!isalpha(C.peek()) && C.peek() != '_' && C.peek() != '.')
1326c6c46e4SAlex Lorenz     return None;
13391370c5dSAlex Lorenz   auto Range = C;
13491370c5dSAlex Lorenz   while (isIdentifierChar(C.peek()))
13591370c5dSAlex Lorenz     C.advance();
13612b554e6SAlex Lorenz   auto Identifier = Range.upto(C);
137cb268d46SAlex Lorenz   Token = MIToken(getIdentifierKind(Identifier), Identifier);
13891370c5dSAlex Lorenz   return C;
13991370c5dSAlex Lorenz }
14091370c5dSAlex Lorenz 
1416c6c46e4SAlex Lorenz static Cursor maybeLexMachineBasicBlock(
14233f0aef3SAlex Lorenz     Cursor C, MIToken &Token,
14333f0aef3SAlex Lorenz     function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
1446c6c46e4SAlex Lorenz   if (!C.remaining().startswith("%bb."))
1456c6c46e4SAlex Lorenz     return None;
14633f0aef3SAlex Lorenz   auto Range = C;
14733f0aef3SAlex Lorenz   C.advance(4); // Skip '%bb.'
14833f0aef3SAlex Lorenz   if (!isdigit(C.peek())) {
14933f0aef3SAlex Lorenz     Token = MIToken(MIToken::Error, C.remaining());
15033f0aef3SAlex Lorenz     ErrorCallback(C.location(), "expected a number after '%bb.'");
15133f0aef3SAlex Lorenz     return C;
15233f0aef3SAlex Lorenz   }
15333f0aef3SAlex Lorenz   auto NumberRange = C;
15433f0aef3SAlex Lorenz   while (isdigit(C.peek()))
15533f0aef3SAlex Lorenz     C.advance();
15633f0aef3SAlex Lorenz   StringRef Number = NumberRange.upto(C);
15733f0aef3SAlex Lorenz   unsigned StringOffset = 4 + Number.size(); // Drop '%bb.<id>'
15833f0aef3SAlex Lorenz   if (C.peek() == '.') {
15933f0aef3SAlex Lorenz     C.advance(); // Skip '.'
16033f0aef3SAlex Lorenz     ++StringOffset;
16133f0aef3SAlex Lorenz     while (isIdentifierChar(C.peek()))
16233f0aef3SAlex Lorenz       C.advance();
16333f0aef3SAlex Lorenz   }
16433f0aef3SAlex Lorenz   Token = MIToken(MIToken::MachineBasicBlock, Range.upto(C), APSInt(Number),
16533f0aef3SAlex Lorenz                   StringOffset);
16633f0aef3SAlex Lorenz   return C;
16733f0aef3SAlex Lorenz }
16833f0aef3SAlex Lorenz 
16931d70683SAlex Lorenz static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule,
17031d70683SAlex Lorenz                             MIToken::TokenKind Kind) {
17131d70683SAlex Lorenz   if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size())))
17231d70683SAlex Lorenz     return None;
17331d70683SAlex Lorenz   auto Range = C;
17431d70683SAlex Lorenz   C.advance(Rule.size());
17531d70683SAlex Lorenz   auto NumberRange = C;
17631d70683SAlex Lorenz   while (isdigit(C.peek()))
17731d70683SAlex Lorenz     C.advance();
17831d70683SAlex Lorenz   Token = MIToken(Kind, Range.upto(C), APSInt(NumberRange.upto(C)));
17931d70683SAlex Lorenz   return C;
18031d70683SAlex Lorenz }
18131d70683SAlex Lorenz 
1827feaf7c6SAlex Lorenz static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule,
1837feaf7c6SAlex Lorenz                                    MIToken::TokenKind Kind) {
1847feaf7c6SAlex Lorenz   if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size())))
1857feaf7c6SAlex Lorenz     return None;
1867feaf7c6SAlex Lorenz   auto Range = C;
1877feaf7c6SAlex Lorenz   C.advance(Rule.size());
1887feaf7c6SAlex Lorenz   auto NumberRange = C;
1897feaf7c6SAlex Lorenz   while (isdigit(C.peek()))
1907feaf7c6SAlex Lorenz     C.advance();
1917feaf7c6SAlex Lorenz   StringRef Number = NumberRange.upto(C);
1927feaf7c6SAlex Lorenz   unsigned StringOffset = Rule.size() + Number.size();
1937feaf7c6SAlex Lorenz   if (C.peek() == '.') {
1947feaf7c6SAlex Lorenz     C.advance();
1957feaf7c6SAlex Lorenz     ++StringOffset;
1967feaf7c6SAlex Lorenz     while (isIdentifierChar(C.peek()))
1977feaf7c6SAlex Lorenz       C.advance();
1987feaf7c6SAlex Lorenz   }
1997feaf7c6SAlex Lorenz   Token = MIToken(Kind, Range.upto(C), APSInt(Number), StringOffset);
2007feaf7c6SAlex Lorenz   return C;
2017feaf7c6SAlex Lorenz }
2027feaf7c6SAlex Lorenz 
20331d70683SAlex Lorenz static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) {
20431d70683SAlex Lorenz   return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex);
20531d70683SAlex Lorenz }
20631d70683SAlex Lorenz 
2077feaf7c6SAlex Lorenz static Cursor maybeLexStackObject(Cursor C, MIToken &Token) {
2087feaf7c6SAlex Lorenz   return maybeLexIndexAndName(C, Token, "%stack.", MIToken::StackObject);
2097feaf7c6SAlex Lorenz }
2107feaf7c6SAlex Lorenz 
2117feaf7c6SAlex Lorenz static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) {
2127feaf7c6SAlex Lorenz   return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject);
2137feaf7c6SAlex Lorenz }
2147feaf7c6SAlex Lorenz 
215ab980499SAlex Lorenz static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) {
216ab980499SAlex Lorenz   return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
217ab980499SAlex Lorenz }
218ab980499SAlex Lorenz 
21953464510SAlex Lorenz static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
22053464510SAlex Lorenz   auto Range = C;
22153464510SAlex Lorenz   C.advance(); // Skip '%'
22253464510SAlex Lorenz   auto NumberRange = C;
22353464510SAlex Lorenz   while (isdigit(C.peek()))
22453464510SAlex Lorenz     C.advance();
22553464510SAlex Lorenz   Token = MIToken(MIToken::VirtualRegister, Range.upto(C),
22653464510SAlex Lorenz                   APSInt(NumberRange.upto(C)));
22753464510SAlex Lorenz   return C;
22853464510SAlex Lorenz }
22953464510SAlex Lorenz 
2306c6c46e4SAlex Lorenz static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
2316c6c46e4SAlex Lorenz   if (C.peek() != '%')
2326c6c46e4SAlex Lorenz     return None;
23353464510SAlex Lorenz   if (isdigit(C.peek(1)))
23453464510SAlex Lorenz     return lexVirtualRegister(C, Token);
235f3db51deSAlex Lorenz   auto Range = C;
236f3db51deSAlex Lorenz   C.advance(); // Skip '%'
237f3db51deSAlex Lorenz   while (isIdentifierChar(C.peek()))
238f3db51deSAlex Lorenz     C.advance();
23933f0aef3SAlex Lorenz   Token = MIToken(MIToken::NamedRegister, Range.upto(C),
24033f0aef3SAlex Lorenz                   /*StringOffset=*/1); // Drop the '%'
241f3db51deSAlex Lorenz   return C;
242f3db51deSAlex Lorenz }
243f3db51deSAlex Lorenz 
2446ede3744SAlex Lorenz static Cursor lexName(
2456ede3744SAlex Lorenz     Cursor C, MIToken &Token, MIToken::TokenKind Type,
2466ede3744SAlex Lorenz     MIToken::TokenKind QuotedType, unsigned PrefixLength,
2476ede3744SAlex Lorenz     function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
2486ede3744SAlex Lorenz   auto Range = C;
2496ede3744SAlex Lorenz   C.advance(PrefixLength);
2506ede3744SAlex Lorenz   if (C.peek() == '"') {
2516ede3744SAlex Lorenz     if (Cursor R = lexStringConstant(C, ErrorCallback)) {
2526ede3744SAlex Lorenz       Token = MIToken(QuotedType, Range.upto(R), PrefixLength);
2536ede3744SAlex Lorenz       return R;
2546ede3744SAlex Lorenz     }
2556ede3744SAlex Lorenz     Token = MIToken(MIToken::Error, Range.remaining());
2566ede3744SAlex Lorenz     return Range;
2576ede3744SAlex Lorenz   }
2586ede3744SAlex Lorenz   while (isIdentifierChar(C.peek()))
2596ede3744SAlex Lorenz     C.advance();
2606ede3744SAlex Lorenz   Token = MIToken(Type, Range.upto(C), PrefixLength);
2616ede3744SAlex Lorenz   return C;
2626ede3744SAlex Lorenz }
2636ede3744SAlex Lorenz 
264c1fbb354SAlex Lorenz static Cursor maybeLexGlobalValue(
265c1fbb354SAlex Lorenz     Cursor C, MIToken &Token,
266c1fbb354SAlex Lorenz     function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
267c1fbb354SAlex Lorenz   if (C.peek() != '@')
268c1fbb354SAlex Lorenz     return None;
269c1fbb354SAlex Lorenz   if (!isdigit(C.peek(1)))
270c1fbb354SAlex Lorenz     return lexName(C, Token, MIToken::NamedGlobalValue,
271c1fbb354SAlex Lorenz                    MIToken::QuotedNamedGlobalValue, /*PrefixLength=*/1,
272c1fbb354SAlex Lorenz                    ErrorCallback);
273c1fbb354SAlex Lorenz   auto Range = C;
274c1fbb354SAlex Lorenz   C.advance(1); // Skip the '@'
275c1fbb354SAlex Lorenz   auto NumberRange = C;
276c1fbb354SAlex Lorenz   while (isdigit(C.peek()))
277c1fbb354SAlex Lorenz     C.advance();
278c1fbb354SAlex Lorenz   Token =
279c1fbb354SAlex Lorenz       MIToken(MIToken::GlobalValue, Range.upto(C), APSInt(NumberRange.upto(C)));
280c1fbb354SAlex Lorenz   return C;
281c1fbb354SAlex Lorenz }
282c1fbb354SAlex Lorenz 
2836ede3744SAlex Lorenz static Cursor maybeLexExternalSymbol(
2846ede3744SAlex Lorenz     Cursor C, MIToken &Token,
2856ede3744SAlex Lorenz     function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
2866ede3744SAlex Lorenz   if (C.peek() != '$')
2876ede3744SAlex Lorenz     return None;
2886ede3744SAlex Lorenz   return lexName(C, Token, MIToken::ExternalSymbol,
2896ede3744SAlex Lorenz                  MIToken::QuotedExternalSymbol,
2906ede3744SAlex Lorenz                  /*PrefixLength=*/1, ErrorCallback);
2916ede3744SAlex Lorenz }
2926ede3744SAlex Lorenz 
2936c6c46e4SAlex Lorenz static Cursor maybeLexIntegerLiteral(Cursor C, MIToken &Token) {
2946c6c46e4SAlex Lorenz   if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1))))
2956c6c46e4SAlex Lorenz     return None;
296240fc1e0SAlex Lorenz   auto Range = C;
297240fc1e0SAlex Lorenz   C.advance();
298240fc1e0SAlex Lorenz   while (isdigit(C.peek()))
299240fc1e0SAlex Lorenz     C.advance();
300240fc1e0SAlex Lorenz   StringRef StrVal = Range.upto(C);
301240fc1e0SAlex Lorenz   Token = MIToken(MIToken::IntegerLiteral, StrVal, APSInt(StrVal));
302240fc1e0SAlex Lorenz   return C;
303240fc1e0SAlex Lorenz }
304240fc1e0SAlex Lorenz 
305f3db51deSAlex Lorenz static MIToken::TokenKind symbolToken(char C) {
306f3db51deSAlex Lorenz   switch (C) {
307f3db51deSAlex Lorenz   case ',':
308f3db51deSAlex Lorenz     return MIToken::comma;
309f3db51deSAlex Lorenz   case '=':
310f3db51deSAlex Lorenz     return MIToken::equal;
3112eacca86SAlex Lorenz   case ':':
3122eacca86SAlex Lorenz     return MIToken::colon;
313*35e44469SAlex Lorenz   case '!':
314*35e44469SAlex Lorenz     return MIToken::exclaim;
315f3db51deSAlex Lorenz   default:
316f3db51deSAlex Lorenz     return MIToken::Error;
317f3db51deSAlex Lorenz   }
318f3db51deSAlex Lorenz }
319f3db51deSAlex Lorenz 
3206c6c46e4SAlex Lorenz static Cursor maybeLexSymbol(Cursor C, MIToken &Token) {
3216c6c46e4SAlex Lorenz   auto Kind = symbolToken(C.peek());
3226c6c46e4SAlex Lorenz   if (Kind == MIToken::Error)
3236c6c46e4SAlex Lorenz     return None;
324f3db51deSAlex Lorenz   auto Range = C;
325f3db51deSAlex Lorenz   C.advance();
326f3db51deSAlex Lorenz   Token = MIToken(Kind, Range.upto(C));
327f3db51deSAlex Lorenz   return C;
328f3db51deSAlex Lorenz }
329f3db51deSAlex Lorenz 
33091370c5dSAlex Lorenz StringRef llvm::lexMIToken(
33191370c5dSAlex Lorenz     StringRef Source, MIToken &Token,
33291370c5dSAlex Lorenz     function_ref<void(StringRef::iterator Loc, const Twine &)> ErrorCallback) {
33391370c5dSAlex Lorenz   auto C = skipWhitespace(Cursor(Source));
33491370c5dSAlex Lorenz   if (C.isEOF()) {
33591370c5dSAlex Lorenz     Token = MIToken(MIToken::Eof, C.remaining());
33691370c5dSAlex Lorenz     return C.remaining();
33791370c5dSAlex Lorenz   }
33891370c5dSAlex Lorenz 
3396c6c46e4SAlex Lorenz   if (Cursor R = maybeLexIdentifier(C, Token))
3406c6c46e4SAlex Lorenz     return R.remaining();
3416c6c46e4SAlex Lorenz   if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback))
3426c6c46e4SAlex Lorenz     return R.remaining();
34331d70683SAlex Lorenz   if (Cursor R = maybeLexJumpTableIndex(C, Token))
34431d70683SAlex Lorenz     return R.remaining();
3457feaf7c6SAlex Lorenz   if (Cursor R = maybeLexStackObject(C, Token))
3467feaf7c6SAlex Lorenz     return R.remaining();
3477feaf7c6SAlex Lorenz   if (Cursor R = maybeLexFixedStackObject(C, Token))
3487feaf7c6SAlex Lorenz     return R.remaining();
349ab980499SAlex Lorenz   if (Cursor R = maybeLexConstantPoolItem(C, Token))
350ab980499SAlex Lorenz     return R.remaining();
3516c6c46e4SAlex Lorenz   if (Cursor R = maybeLexRegister(C, Token))
3526c6c46e4SAlex Lorenz     return R.remaining();
353b29554daSAlex Lorenz   if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
3546c6c46e4SAlex Lorenz     return R.remaining();
3556ede3744SAlex Lorenz   if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback))
3566ede3744SAlex Lorenz     return R.remaining();
3576c6c46e4SAlex Lorenz   if (Cursor R = maybeLexIntegerLiteral(C, Token))
3586c6c46e4SAlex Lorenz     return R.remaining();
3596c6c46e4SAlex Lorenz   if (Cursor R = maybeLexSymbol(C, Token))
3606c6c46e4SAlex Lorenz     return R.remaining();
3616c6c46e4SAlex Lorenz 
36291370c5dSAlex Lorenz   Token = MIToken(MIToken::Error, C.remaining());
36391370c5dSAlex Lorenz   ErrorCallback(C.location(),
3646c6c46e4SAlex Lorenz                 Twine("unexpected character '") + Twine(C.peek()) + "'");
36591370c5dSAlex Lorenz   return C.remaining();
36691370c5dSAlex Lorenz }
367