1*9880d681SAndroid Build Coastguard Worker //===- MILexer.cpp - Machine instructions lexer implementation ----------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the lexing of machine instructions.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "MILexer.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/None.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringExtras.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/StringSwitch.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/ADT/Twine.h"
19*9880d681SAndroid Build Coastguard Worker #include <cctype>
20*9880d681SAndroid Build Coastguard Worker
21*9880d681SAndroid Build Coastguard Worker using namespace llvm;
22*9880d681SAndroid Build Coastguard Worker
23*9880d681SAndroid Build Coastguard Worker namespace {
24*9880d681SAndroid Build Coastguard Worker
25*9880d681SAndroid Build Coastguard Worker typedef function_ref<void(StringRef::iterator Loc, const Twine &)>
26*9880d681SAndroid Build Coastguard Worker ErrorCallbackType;
27*9880d681SAndroid Build Coastguard Worker
28*9880d681SAndroid Build Coastguard Worker /// This class provides a way to iterate and get characters from the source
29*9880d681SAndroid Build Coastguard Worker /// string.
30*9880d681SAndroid Build Coastguard Worker class Cursor {
31*9880d681SAndroid Build Coastguard Worker const char *Ptr;
32*9880d681SAndroid Build Coastguard Worker const char *End;
33*9880d681SAndroid Build Coastguard Worker
34*9880d681SAndroid Build Coastguard Worker public:
Cursor(NoneType)35*9880d681SAndroid Build Coastguard Worker Cursor(NoneType) : Ptr(nullptr), End(nullptr) {}
36*9880d681SAndroid Build Coastguard Worker
Cursor(StringRef Str)37*9880d681SAndroid Build Coastguard Worker explicit Cursor(StringRef Str) {
38*9880d681SAndroid Build Coastguard Worker Ptr = Str.data();
39*9880d681SAndroid Build Coastguard Worker End = Ptr + Str.size();
40*9880d681SAndroid Build Coastguard Worker }
41*9880d681SAndroid Build Coastguard Worker
isEOF() const42*9880d681SAndroid Build Coastguard Worker bool isEOF() const { return Ptr == End; }
43*9880d681SAndroid Build Coastguard Worker
peek(int I=0) const44*9880d681SAndroid Build Coastguard Worker char peek(int I = 0) const { return End - Ptr <= I ? 0 : Ptr[I]; }
45*9880d681SAndroid Build Coastguard Worker
advance(unsigned I=1)46*9880d681SAndroid Build Coastguard Worker void advance(unsigned I = 1) { Ptr += I; }
47*9880d681SAndroid Build Coastguard Worker
remaining() const48*9880d681SAndroid Build Coastguard Worker StringRef remaining() const { return StringRef(Ptr, End - Ptr); }
49*9880d681SAndroid Build Coastguard Worker
upto(Cursor C) const50*9880d681SAndroid Build Coastguard Worker StringRef upto(Cursor C) const {
51*9880d681SAndroid Build Coastguard Worker assert(C.Ptr >= Ptr && C.Ptr <= End);
52*9880d681SAndroid Build Coastguard Worker return StringRef(Ptr, C.Ptr - Ptr);
53*9880d681SAndroid Build Coastguard Worker }
54*9880d681SAndroid Build Coastguard Worker
location() const55*9880d681SAndroid Build Coastguard Worker StringRef::iterator location() const { return Ptr; }
56*9880d681SAndroid Build Coastguard Worker
operator bool() const57*9880d681SAndroid Build Coastguard Worker operator bool() const { return Ptr != nullptr; }
58*9880d681SAndroid Build Coastguard Worker };
59*9880d681SAndroid Build Coastguard Worker
60*9880d681SAndroid Build Coastguard Worker } // end anonymous namespace
61*9880d681SAndroid Build Coastguard Worker
reset(TokenKind Kind,StringRef Range)62*9880d681SAndroid Build Coastguard Worker MIToken &MIToken::reset(TokenKind Kind, StringRef Range) {
63*9880d681SAndroid Build Coastguard Worker this->Kind = Kind;
64*9880d681SAndroid Build Coastguard Worker this->Range = Range;
65*9880d681SAndroid Build Coastguard Worker return *this;
66*9880d681SAndroid Build Coastguard Worker }
67*9880d681SAndroid Build Coastguard Worker
setStringValue(StringRef StrVal)68*9880d681SAndroid Build Coastguard Worker MIToken &MIToken::setStringValue(StringRef StrVal) {
69*9880d681SAndroid Build Coastguard Worker StringValue = StrVal;
70*9880d681SAndroid Build Coastguard Worker return *this;
71*9880d681SAndroid Build Coastguard Worker }
72*9880d681SAndroid Build Coastguard Worker
setOwnedStringValue(std::string StrVal)73*9880d681SAndroid Build Coastguard Worker MIToken &MIToken::setOwnedStringValue(std::string StrVal) {
74*9880d681SAndroid Build Coastguard Worker StringValueStorage = std::move(StrVal);
75*9880d681SAndroid Build Coastguard Worker StringValue = StringValueStorage;
76*9880d681SAndroid Build Coastguard Worker return *this;
77*9880d681SAndroid Build Coastguard Worker }
78*9880d681SAndroid Build Coastguard Worker
setIntegerValue(APSInt IntVal)79*9880d681SAndroid Build Coastguard Worker MIToken &MIToken::setIntegerValue(APSInt IntVal) {
80*9880d681SAndroid Build Coastguard Worker this->IntVal = std::move(IntVal);
81*9880d681SAndroid Build Coastguard Worker return *this;
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker /// Skip the leading whitespace characters and return the updated cursor.
skipWhitespace(Cursor C)85*9880d681SAndroid Build Coastguard Worker static Cursor skipWhitespace(Cursor C) {
86*9880d681SAndroid Build Coastguard Worker while (isblank(C.peek()))
87*9880d681SAndroid Build Coastguard Worker C.advance();
88*9880d681SAndroid Build Coastguard Worker return C;
89*9880d681SAndroid Build Coastguard Worker }
90*9880d681SAndroid Build Coastguard Worker
isNewlineChar(char C)91*9880d681SAndroid Build Coastguard Worker static bool isNewlineChar(char C) { return C == '\n' || C == '\r'; }
92*9880d681SAndroid Build Coastguard Worker
93*9880d681SAndroid Build Coastguard Worker /// Skip a line comment and return the updated cursor.
skipComment(Cursor C)94*9880d681SAndroid Build Coastguard Worker static Cursor skipComment(Cursor C) {
95*9880d681SAndroid Build Coastguard Worker if (C.peek() != ';')
96*9880d681SAndroid Build Coastguard Worker return C;
97*9880d681SAndroid Build Coastguard Worker while (!isNewlineChar(C.peek()) && !C.isEOF())
98*9880d681SAndroid Build Coastguard Worker C.advance();
99*9880d681SAndroid Build Coastguard Worker return C;
100*9880d681SAndroid Build Coastguard Worker }
101*9880d681SAndroid Build Coastguard Worker
102*9880d681SAndroid Build Coastguard Worker /// Return true if the given character satisfies the following regular
103*9880d681SAndroid Build Coastguard Worker /// expression: [-a-zA-Z$._0-9]
isIdentifierChar(char C)104*9880d681SAndroid Build Coastguard Worker static bool isIdentifierChar(char C) {
105*9880d681SAndroid Build Coastguard Worker return isalpha(C) || isdigit(C) || C == '_' || C == '-' || C == '.' ||
106*9880d681SAndroid Build Coastguard Worker C == '$';
107*9880d681SAndroid Build Coastguard Worker }
108*9880d681SAndroid Build Coastguard Worker
109*9880d681SAndroid Build Coastguard Worker /// Unescapes the given string value.
110*9880d681SAndroid Build Coastguard Worker ///
111*9880d681SAndroid Build Coastguard Worker /// Expects the string value to be quoted.
unescapeQuotedString(StringRef Value)112*9880d681SAndroid Build Coastguard Worker static std::string unescapeQuotedString(StringRef Value) {
113*9880d681SAndroid Build Coastguard Worker assert(Value.front() == '"' && Value.back() == '"');
114*9880d681SAndroid Build Coastguard Worker Cursor C = Cursor(Value.substr(1, Value.size() - 2));
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker std::string Str;
117*9880d681SAndroid Build Coastguard Worker Str.reserve(C.remaining().size());
118*9880d681SAndroid Build Coastguard Worker while (!C.isEOF()) {
119*9880d681SAndroid Build Coastguard Worker char Char = C.peek();
120*9880d681SAndroid Build Coastguard Worker if (Char == '\\') {
121*9880d681SAndroid Build Coastguard Worker if (C.peek(1) == '\\') {
122*9880d681SAndroid Build Coastguard Worker // Two '\' become one
123*9880d681SAndroid Build Coastguard Worker Str += '\\';
124*9880d681SAndroid Build Coastguard Worker C.advance(2);
125*9880d681SAndroid Build Coastguard Worker continue;
126*9880d681SAndroid Build Coastguard Worker }
127*9880d681SAndroid Build Coastguard Worker if (isxdigit(C.peek(1)) && isxdigit(C.peek(2))) {
128*9880d681SAndroid Build Coastguard Worker Str += hexDigitValue(C.peek(1)) * 16 + hexDigitValue(C.peek(2));
129*9880d681SAndroid Build Coastguard Worker C.advance(3);
130*9880d681SAndroid Build Coastguard Worker continue;
131*9880d681SAndroid Build Coastguard Worker }
132*9880d681SAndroid Build Coastguard Worker }
133*9880d681SAndroid Build Coastguard Worker Str += Char;
134*9880d681SAndroid Build Coastguard Worker C.advance();
135*9880d681SAndroid Build Coastguard Worker }
136*9880d681SAndroid Build Coastguard Worker return Str;
137*9880d681SAndroid Build Coastguard Worker }
138*9880d681SAndroid Build Coastguard Worker
139*9880d681SAndroid Build Coastguard Worker /// Lex a string constant using the following regular expression: \"[^\"]*\"
lexStringConstant(Cursor C,ErrorCallbackType ErrorCallback)140*9880d681SAndroid Build Coastguard Worker static Cursor lexStringConstant(Cursor C, ErrorCallbackType ErrorCallback) {
141*9880d681SAndroid Build Coastguard Worker assert(C.peek() == '"');
142*9880d681SAndroid Build Coastguard Worker for (C.advance(); C.peek() != '"'; C.advance()) {
143*9880d681SAndroid Build Coastguard Worker if (C.isEOF() || isNewlineChar(C.peek())) {
144*9880d681SAndroid Build Coastguard Worker ErrorCallback(
145*9880d681SAndroid Build Coastguard Worker C.location(),
146*9880d681SAndroid Build Coastguard Worker "end of machine instruction reached before the closing '\"'");
147*9880d681SAndroid Build Coastguard Worker return None;
148*9880d681SAndroid Build Coastguard Worker }
149*9880d681SAndroid Build Coastguard Worker }
150*9880d681SAndroid Build Coastguard Worker C.advance();
151*9880d681SAndroid Build Coastguard Worker return C;
152*9880d681SAndroid Build Coastguard Worker }
153*9880d681SAndroid Build Coastguard Worker
lexName(Cursor C,MIToken & Token,MIToken::TokenKind Type,unsigned PrefixLength,ErrorCallbackType ErrorCallback)154*9880d681SAndroid Build Coastguard Worker static Cursor lexName(Cursor C, MIToken &Token, MIToken::TokenKind Type,
155*9880d681SAndroid Build Coastguard Worker unsigned PrefixLength, ErrorCallbackType ErrorCallback) {
156*9880d681SAndroid Build Coastguard Worker auto Range = C;
157*9880d681SAndroid Build Coastguard Worker C.advance(PrefixLength);
158*9880d681SAndroid Build Coastguard Worker if (C.peek() == '"') {
159*9880d681SAndroid Build Coastguard Worker if (Cursor R = lexStringConstant(C, ErrorCallback)) {
160*9880d681SAndroid Build Coastguard Worker StringRef String = Range.upto(R);
161*9880d681SAndroid Build Coastguard Worker Token.reset(Type, String)
162*9880d681SAndroid Build Coastguard Worker .setOwnedStringValue(
163*9880d681SAndroid Build Coastguard Worker unescapeQuotedString(String.drop_front(PrefixLength)));
164*9880d681SAndroid Build Coastguard Worker return R;
165*9880d681SAndroid Build Coastguard Worker }
166*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::Error, Range.remaining());
167*9880d681SAndroid Build Coastguard Worker return Range;
168*9880d681SAndroid Build Coastguard Worker }
169*9880d681SAndroid Build Coastguard Worker while (isIdentifierChar(C.peek()))
170*9880d681SAndroid Build Coastguard Worker C.advance();
171*9880d681SAndroid Build Coastguard Worker Token.reset(Type, Range.upto(C))
172*9880d681SAndroid Build Coastguard Worker .setStringValue(Range.upto(C).drop_front(PrefixLength));
173*9880d681SAndroid Build Coastguard Worker return C;
174*9880d681SAndroid Build Coastguard Worker }
175*9880d681SAndroid Build Coastguard Worker
maybeLexIntegerType(Cursor C,MIToken & Token)176*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexIntegerType(Cursor C, MIToken &Token) {
177*9880d681SAndroid Build Coastguard Worker if (C.peek() != 'i' || !isdigit(C.peek(1)))
178*9880d681SAndroid Build Coastguard Worker return None;
179*9880d681SAndroid Build Coastguard Worker auto Range = C;
180*9880d681SAndroid Build Coastguard Worker C.advance(); // Skip 'i'
181*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
182*9880d681SAndroid Build Coastguard Worker C.advance();
183*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::IntegerType, Range.upto(C));
184*9880d681SAndroid Build Coastguard Worker return C;
185*9880d681SAndroid Build Coastguard Worker }
186*9880d681SAndroid Build Coastguard Worker
getIdentifierKind(StringRef Identifier)187*9880d681SAndroid Build Coastguard Worker static MIToken::TokenKind getIdentifierKind(StringRef Identifier) {
188*9880d681SAndroid Build Coastguard Worker return StringSwitch<MIToken::TokenKind>(Identifier)
189*9880d681SAndroid Build Coastguard Worker .Case("_", MIToken::underscore)
190*9880d681SAndroid Build Coastguard Worker .Case("implicit", MIToken::kw_implicit)
191*9880d681SAndroid Build Coastguard Worker .Case("implicit-def", MIToken::kw_implicit_define)
192*9880d681SAndroid Build Coastguard Worker .Case("def", MIToken::kw_def)
193*9880d681SAndroid Build Coastguard Worker .Case("dead", MIToken::kw_dead)
194*9880d681SAndroid Build Coastguard Worker .Case("killed", MIToken::kw_killed)
195*9880d681SAndroid Build Coastguard Worker .Case("undef", MIToken::kw_undef)
196*9880d681SAndroid Build Coastguard Worker .Case("internal", MIToken::kw_internal)
197*9880d681SAndroid Build Coastguard Worker .Case("early-clobber", MIToken::kw_early_clobber)
198*9880d681SAndroid Build Coastguard Worker .Case("debug-use", MIToken::kw_debug_use)
199*9880d681SAndroid Build Coastguard Worker .Case("tied-def", MIToken::kw_tied_def)
200*9880d681SAndroid Build Coastguard Worker .Case("frame-setup", MIToken::kw_frame_setup)
201*9880d681SAndroid Build Coastguard Worker .Case("debug-location", MIToken::kw_debug_location)
202*9880d681SAndroid Build Coastguard Worker .Case(".cfi_same_value", MIToken::kw_cfi_same_value)
203*9880d681SAndroid Build Coastguard Worker .Case(".cfi_offset", MIToken::kw_cfi_offset)
204*9880d681SAndroid Build Coastguard Worker .Case(".cfi_def_cfa_register", MIToken::kw_cfi_def_cfa_register)
205*9880d681SAndroid Build Coastguard Worker .Case(".cfi_def_cfa_offset", MIToken::kw_cfi_def_cfa_offset)
206*9880d681SAndroid Build Coastguard Worker .Case(".cfi_def_cfa", MIToken::kw_cfi_def_cfa)
207*9880d681SAndroid Build Coastguard Worker .Case("blockaddress", MIToken::kw_blockaddress)
208*9880d681SAndroid Build Coastguard Worker .Case("target-index", MIToken::kw_target_index)
209*9880d681SAndroid Build Coastguard Worker .Case("half", MIToken::kw_half)
210*9880d681SAndroid Build Coastguard Worker .Case("float", MIToken::kw_float)
211*9880d681SAndroid Build Coastguard Worker .Case("double", MIToken::kw_double)
212*9880d681SAndroid Build Coastguard Worker .Case("x86_fp80", MIToken::kw_x86_fp80)
213*9880d681SAndroid Build Coastguard Worker .Case("fp128", MIToken::kw_fp128)
214*9880d681SAndroid Build Coastguard Worker .Case("ppc_fp128", MIToken::kw_ppc_fp128)
215*9880d681SAndroid Build Coastguard Worker .Case("target-flags", MIToken::kw_target_flags)
216*9880d681SAndroid Build Coastguard Worker .Case("volatile", MIToken::kw_volatile)
217*9880d681SAndroid Build Coastguard Worker .Case("non-temporal", MIToken::kw_non_temporal)
218*9880d681SAndroid Build Coastguard Worker .Case("invariant", MIToken::kw_invariant)
219*9880d681SAndroid Build Coastguard Worker .Case("align", MIToken::kw_align)
220*9880d681SAndroid Build Coastguard Worker .Case("stack", MIToken::kw_stack)
221*9880d681SAndroid Build Coastguard Worker .Case("got", MIToken::kw_got)
222*9880d681SAndroid Build Coastguard Worker .Case("jump-table", MIToken::kw_jump_table)
223*9880d681SAndroid Build Coastguard Worker .Case("constant-pool", MIToken::kw_constant_pool)
224*9880d681SAndroid Build Coastguard Worker .Case("call-entry", MIToken::kw_call_entry)
225*9880d681SAndroid Build Coastguard Worker .Case("liveout", MIToken::kw_liveout)
226*9880d681SAndroid Build Coastguard Worker .Case("address-taken", MIToken::kw_address_taken)
227*9880d681SAndroid Build Coastguard Worker .Case("landing-pad", MIToken::kw_landing_pad)
228*9880d681SAndroid Build Coastguard Worker .Case("liveins", MIToken::kw_liveins)
229*9880d681SAndroid Build Coastguard Worker .Case("successors", MIToken::kw_successors)
230*9880d681SAndroid Build Coastguard Worker .Default(MIToken::Identifier);
231*9880d681SAndroid Build Coastguard Worker }
232*9880d681SAndroid Build Coastguard Worker
maybeLexIdentifier(Cursor C,MIToken & Token)233*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexIdentifier(Cursor C, MIToken &Token) {
234*9880d681SAndroid Build Coastguard Worker if (!isalpha(C.peek()) && C.peek() != '_' && C.peek() != '.')
235*9880d681SAndroid Build Coastguard Worker return None;
236*9880d681SAndroid Build Coastguard Worker auto Range = C;
237*9880d681SAndroid Build Coastguard Worker while (isIdentifierChar(C.peek()))
238*9880d681SAndroid Build Coastguard Worker C.advance();
239*9880d681SAndroid Build Coastguard Worker auto Identifier = Range.upto(C);
240*9880d681SAndroid Build Coastguard Worker Token.reset(getIdentifierKind(Identifier), Identifier)
241*9880d681SAndroid Build Coastguard Worker .setStringValue(Identifier);
242*9880d681SAndroid Build Coastguard Worker return C;
243*9880d681SAndroid Build Coastguard Worker }
244*9880d681SAndroid Build Coastguard Worker
maybeLexMachineBasicBlock(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)245*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexMachineBasicBlock(Cursor C, MIToken &Token,
246*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
247*9880d681SAndroid Build Coastguard Worker bool IsReference = C.remaining().startswith("%bb.");
248*9880d681SAndroid Build Coastguard Worker if (!IsReference && !C.remaining().startswith("bb."))
249*9880d681SAndroid Build Coastguard Worker return None;
250*9880d681SAndroid Build Coastguard Worker auto Range = C;
251*9880d681SAndroid Build Coastguard Worker unsigned PrefixLength = IsReference ? 4 : 3;
252*9880d681SAndroid Build Coastguard Worker C.advance(PrefixLength); // Skip '%bb.' or 'bb.'
253*9880d681SAndroid Build Coastguard Worker if (!isdigit(C.peek())) {
254*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::Error, C.remaining());
255*9880d681SAndroid Build Coastguard Worker ErrorCallback(C.location(), "expected a number after '%bb.'");
256*9880d681SAndroid Build Coastguard Worker return C;
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker auto NumberRange = C;
259*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
260*9880d681SAndroid Build Coastguard Worker C.advance();
261*9880d681SAndroid Build Coastguard Worker StringRef Number = NumberRange.upto(C);
262*9880d681SAndroid Build Coastguard Worker unsigned StringOffset = PrefixLength + Number.size(); // Drop '%bb.<id>'
263*9880d681SAndroid Build Coastguard Worker if (C.peek() == '.') {
264*9880d681SAndroid Build Coastguard Worker C.advance(); // Skip '.'
265*9880d681SAndroid Build Coastguard Worker ++StringOffset;
266*9880d681SAndroid Build Coastguard Worker while (isIdentifierChar(C.peek()))
267*9880d681SAndroid Build Coastguard Worker C.advance();
268*9880d681SAndroid Build Coastguard Worker }
269*9880d681SAndroid Build Coastguard Worker Token.reset(IsReference ? MIToken::MachineBasicBlock
270*9880d681SAndroid Build Coastguard Worker : MIToken::MachineBasicBlockLabel,
271*9880d681SAndroid Build Coastguard Worker Range.upto(C))
272*9880d681SAndroid Build Coastguard Worker .setIntegerValue(APSInt(Number))
273*9880d681SAndroid Build Coastguard Worker .setStringValue(Range.upto(C).drop_front(StringOffset));
274*9880d681SAndroid Build Coastguard Worker return C;
275*9880d681SAndroid Build Coastguard Worker }
276*9880d681SAndroid Build Coastguard Worker
maybeLexIndex(Cursor C,MIToken & Token,StringRef Rule,MIToken::TokenKind Kind)277*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexIndex(Cursor C, MIToken &Token, StringRef Rule,
278*9880d681SAndroid Build Coastguard Worker MIToken::TokenKind Kind) {
279*9880d681SAndroid Build Coastguard Worker if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size())))
280*9880d681SAndroid Build Coastguard Worker return None;
281*9880d681SAndroid Build Coastguard Worker auto Range = C;
282*9880d681SAndroid Build Coastguard Worker C.advance(Rule.size());
283*9880d681SAndroid Build Coastguard Worker auto NumberRange = C;
284*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
285*9880d681SAndroid Build Coastguard Worker C.advance();
286*9880d681SAndroid Build Coastguard Worker Token.reset(Kind, Range.upto(C)).setIntegerValue(APSInt(NumberRange.upto(C)));
287*9880d681SAndroid Build Coastguard Worker return C;
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker
maybeLexIndexAndName(Cursor C,MIToken & Token,StringRef Rule,MIToken::TokenKind Kind)290*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexIndexAndName(Cursor C, MIToken &Token, StringRef Rule,
291*9880d681SAndroid Build Coastguard Worker MIToken::TokenKind Kind) {
292*9880d681SAndroid Build Coastguard Worker if (!C.remaining().startswith(Rule) || !isdigit(C.peek(Rule.size())))
293*9880d681SAndroid Build Coastguard Worker return None;
294*9880d681SAndroid Build Coastguard Worker auto Range = C;
295*9880d681SAndroid Build Coastguard Worker C.advance(Rule.size());
296*9880d681SAndroid Build Coastguard Worker auto NumberRange = C;
297*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
298*9880d681SAndroid Build Coastguard Worker C.advance();
299*9880d681SAndroid Build Coastguard Worker StringRef Number = NumberRange.upto(C);
300*9880d681SAndroid Build Coastguard Worker unsigned StringOffset = Rule.size() + Number.size();
301*9880d681SAndroid Build Coastguard Worker if (C.peek() == '.') {
302*9880d681SAndroid Build Coastguard Worker C.advance();
303*9880d681SAndroid Build Coastguard Worker ++StringOffset;
304*9880d681SAndroid Build Coastguard Worker while (isIdentifierChar(C.peek()))
305*9880d681SAndroid Build Coastguard Worker C.advance();
306*9880d681SAndroid Build Coastguard Worker }
307*9880d681SAndroid Build Coastguard Worker Token.reset(Kind, Range.upto(C))
308*9880d681SAndroid Build Coastguard Worker .setIntegerValue(APSInt(Number))
309*9880d681SAndroid Build Coastguard Worker .setStringValue(Range.upto(C).drop_front(StringOffset));
310*9880d681SAndroid Build Coastguard Worker return C;
311*9880d681SAndroid Build Coastguard Worker }
312*9880d681SAndroid Build Coastguard Worker
maybeLexJumpTableIndex(Cursor C,MIToken & Token)313*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexJumpTableIndex(Cursor C, MIToken &Token) {
314*9880d681SAndroid Build Coastguard Worker return maybeLexIndex(C, Token, "%jump-table.", MIToken::JumpTableIndex);
315*9880d681SAndroid Build Coastguard Worker }
316*9880d681SAndroid Build Coastguard Worker
maybeLexStackObject(Cursor C,MIToken & Token)317*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexStackObject(Cursor C, MIToken &Token) {
318*9880d681SAndroid Build Coastguard Worker return maybeLexIndexAndName(C, Token, "%stack.", MIToken::StackObject);
319*9880d681SAndroid Build Coastguard Worker }
320*9880d681SAndroid Build Coastguard Worker
maybeLexFixedStackObject(Cursor C,MIToken & Token)321*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexFixedStackObject(Cursor C, MIToken &Token) {
322*9880d681SAndroid Build Coastguard Worker return maybeLexIndex(C, Token, "%fixed-stack.", MIToken::FixedStackObject);
323*9880d681SAndroid Build Coastguard Worker }
324*9880d681SAndroid Build Coastguard Worker
maybeLexConstantPoolItem(Cursor C,MIToken & Token)325*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexConstantPoolItem(Cursor C, MIToken &Token) {
326*9880d681SAndroid Build Coastguard Worker return maybeLexIndex(C, Token, "%const.", MIToken::ConstantPoolItem);
327*9880d681SAndroid Build Coastguard Worker }
328*9880d681SAndroid Build Coastguard Worker
maybeLexSubRegisterIndex(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)329*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexSubRegisterIndex(Cursor C, MIToken &Token,
330*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
331*9880d681SAndroid Build Coastguard Worker const StringRef Rule = "%subreg.";
332*9880d681SAndroid Build Coastguard Worker if (!C.remaining().startswith(Rule))
333*9880d681SAndroid Build Coastguard Worker return None;
334*9880d681SAndroid Build Coastguard Worker return lexName(C, Token, MIToken::SubRegisterIndex, Rule.size(),
335*9880d681SAndroid Build Coastguard Worker ErrorCallback);
336*9880d681SAndroid Build Coastguard Worker }
337*9880d681SAndroid Build Coastguard Worker
maybeLexIRBlock(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)338*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexIRBlock(Cursor C, MIToken &Token,
339*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
340*9880d681SAndroid Build Coastguard Worker const StringRef Rule = "%ir-block.";
341*9880d681SAndroid Build Coastguard Worker if (!C.remaining().startswith(Rule))
342*9880d681SAndroid Build Coastguard Worker return None;
343*9880d681SAndroid Build Coastguard Worker if (isdigit(C.peek(Rule.size())))
344*9880d681SAndroid Build Coastguard Worker return maybeLexIndex(C, Token, Rule, MIToken::IRBlock);
345*9880d681SAndroid Build Coastguard Worker return lexName(C, Token, MIToken::NamedIRBlock, Rule.size(), ErrorCallback);
346*9880d681SAndroid Build Coastguard Worker }
347*9880d681SAndroid Build Coastguard Worker
maybeLexIRValue(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)348*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexIRValue(Cursor C, MIToken &Token,
349*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
350*9880d681SAndroid Build Coastguard Worker const StringRef Rule = "%ir.";
351*9880d681SAndroid Build Coastguard Worker if (!C.remaining().startswith(Rule))
352*9880d681SAndroid Build Coastguard Worker return None;
353*9880d681SAndroid Build Coastguard Worker if (isdigit(C.peek(Rule.size())))
354*9880d681SAndroid Build Coastguard Worker return maybeLexIndex(C, Token, Rule, MIToken::IRValue);
355*9880d681SAndroid Build Coastguard Worker return lexName(C, Token, MIToken::NamedIRValue, Rule.size(), ErrorCallback);
356*9880d681SAndroid Build Coastguard Worker }
357*9880d681SAndroid Build Coastguard Worker
lexVirtualRegister(Cursor C,MIToken & Token)358*9880d681SAndroid Build Coastguard Worker static Cursor lexVirtualRegister(Cursor C, MIToken &Token) {
359*9880d681SAndroid Build Coastguard Worker auto Range = C;
360*9880d681SAndroid Build Coastguard Worker C.advance(); // Skip '%'
361*9880d681SAndroid Build Coastguard Worker auto NumberRange = C;
362*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
363*9880d681SAndroid Build Coastguard Worker C.advance();
364*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::VirtualRegister, Range.upto(C))
365*9880d681SAndroid Build Coastguard Worker .setIntegerValue(APSInt(NumberRange.upto(C)));
366*9880d681SAndroid Build Coastguard Worker return C;
367*9880d681SAndroid Build Coastguard Worker }
368*9880d681SAndroid Build Coastguard Worker
maybeLexRegister(Cursor C,MIToken & Token)369*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexRegister(Cursor C, MIToken &Token) {
370*9880d681SAndroid Build Coastguard Worker if (C.peek() != '%')
371*9880d681SAndroid Build Coastguard Worker return None;
372*9880d681SAndroid Build Coastguard Worker if (isdigit(C.peek(1)))
373*9880d681SAndroid Build Coastguard Worker return lexVirtualRegister(C, Token);
374*9880d681SAndroid Build Coastguard Worker auto Range = C;
375*9880d681SAndroid Build Coastguard Worker C.advance(); // Skip '%'
376*9880d681SAndroid Build Coastguard Worker while (isIdentifierChar(C.peek()))
377*9880d681SAndroid Build Coastguard Worker C.advance();
378*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::NamedRegister, Range.upto(C))
379*9880d681SAndroid Build Coastguard Worker .setStringValue(Range.upto(C).drop_front(1)); // Drop the '%'
380*9880d681SAndroid Build Coastguard Worker return C;
381*9880d681SAndroid Build Coastguard Worker }
382*9880d681SAndroid Build Coastguard Worker
maybeLexGlobalValue(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)383*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexGlobalValue(Cursor C, MIToken &Token,
384*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
385*9880d681SAndroid Build Coastguard Worker if (C.peek() != '@')
386*9880d681SAndroid Build Coastguard Worker return None;
387*9880d681SAndroid Build Coastguard Worker if (!isdigit(C.peek(1)))
388*9880d681SAndroid Build Coastguard Worker return lexName(C, Token, MIToken::NamedGlobalValue, /*PrefixLength=*/1,
389*9880d681SAndroid Build Coastguard Worker ErrorCallback);
390*9880d681SAndroid Build Coastguard Worker auto Range = C;
391*9880d681SAndroid Build Coastguard Worker C.advance(1); // Skip the '@'
392*9880d681SAndroid Build Coastguard Worker auto NumberRange = C;
393*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
394*9880d681SAndroid Build Coastguard Worker C.advance();
395*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::GlobalValue, Range.upto(C))
396*9880d681SAndroid Build Coastguard Worker .setIntegerValue(APSInt(NumberRange.upto(C)));
397*9880d681SAndroid Build Coastguard Worker return C;
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker
maybeLexExternalSymbol(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)400*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexExternalSymbol(Cursor C, MIToken &Token,
401*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
402*9880d681SAndroid Build Coastguard Worker if (C.peek() != '$')
403*9880d681SAndroid Build Coastguard Worker return None;
404*9880d681SAndroid Build Coastguard Worker return lexName(C, Token, MIToken::ExternalSymbol, /*PrefixLength=*/1,
405*9880d681SAndroid Build Coastguard Worker ErrorCallback);
406*9880d681SAndroid Build Coastguard Worker }
407*9880d681SAndroid Build Coastguard Worker
isValidHexFloatingPointPrefix(char C)408*9880d681SAndroid Build Coastguard Worker static bool isValidHexFloatingPointPrefix(char C) {
409*9880d681SAndroid Build Coastguard Worker return C == 'H' || C == 'K' || C == 'L' || C == 'M';
410*9880d681SAndroid Build Coastguard Worker }
411*9880d681SAndroid Build Coastguard Worker
maybeLexHexFloatingPointLiteral(Cursor C,MIToken & Token)412*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexHexFloatingPointLiteral(Cursor C, MIToken &Token) {
413*9880d681SAndroid Build Coastguard Worker if (C.peek() != '0' || C.peek(1) != 'x')
414*9880d681SAndroid Build Coastguard Worker return None;
415*9880d681SAndroid Build Coastguard Worker Cursor Range = C;
416*9880d681SAndroid Build Coastguard Worker C.advance(2); // Skip '0x'
417*9880d681SAndroid Build Coastguard Worker if (isValidHexFloatingPointPrefix(C.peek()))
418*9880d681SAndroid Build Coastguard Worker C.advance();
419*9880d681SAndroid Build Coastguard Worker while (isxdigit(C.peek()))
420*9880d681SAndroid Build Coastguard Worker C.advance();
421*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::FloatingPointLiteral, Range.upto(C));
422*9880d681SAndroid Build Coastguard Worker return C;
423*9880d681SAndroid Build Coastguard Worker }
424*9880d681SAndroid Build Coastguard Worker
lexFloatingPointLiteral(Cursor Range,Cursor C,MIToken & Token)425*9880d681SAndroid Build Coastguard Worker static Cursor lexFloatingPointLiteral(Cursor Range, Cursor C, MIToken &Token) {
426*9880d681SAndroid Build Coastguard Worker C.advance();
427*9880d681SAndroid Build Coastguard Worker // Skip over [0-9]*([eE][-+]?[0-9]+)?
428*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
429*9880d681SAndroid Build Coastguard Worker C.advance();
430*9880d681SAndroid Build Coastguard Worker if ((C.peek() == 'e' || C.peek() == 'E') &&
431*9880d681SAndroid Build Coastguard Worker (isdigit(C.peek(1)) ||
432*9880d681SAndroid Build Coastguard Worker ((C.peek(1) == '-' || C.peek(1) == '+') && isdigit(C.peek(2))))) {
433*9880d681SAndroid Build Coastguard Worker C.advance(2);
434*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
435*9880d681SAndroid Build Coastguard Worker C.advance();
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::FloatingPointLiteral, Range.upto(C));
438*9880d681SAndroid Build Coastguard Worker return C;
439*9880d681SAndroid Build Coastguard Worker }
440*9880d681SAndroid Build Coastguard Worker
maybeLexNumericalLiteral(Cursor C,MIToken & Token)441*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexNumericalLiteral(Cursor C, MIToken &Token) {
442*9880d681SAndroid Build Coastguard Worker if (!isdigit(C.peek()) && (C.peek() != '-' || !isdigit(C.peek(1))))
443*9880d681SAndroid Build Coastguard Worker return None;
444*9880d681SAndroid Build Coastguard Worker auto Range = C;
445*9880d681SAndroid Build Coastguard Worker C.advance();
446*9880d681SAndroid Build Coastguard Worker while (isdigit(C.peek()))
447*9880d681SAndroid Build Coastguard Worker C.advance();
448*9880d681SAndroid Build Coastguard Worker if (C.peek() == '.')
449*9880d681SAndroid Build Coastguard Worker return lexFloatingPointLiteral(Range, C, Token);
450*9880d681SAndroid Build Coastguard Worker StringRef StrVal = Range.upto(C);
451*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::IntegerLiteral, StrVal).setIntegerValue(APSInt(StrVal));
452*9880d681SAndroid Build Coastguard Worker return C;
453*9880d681SAndroid Build Coastguard Worker }
454*9880d681SAndroid Build Coastguard Worker
getMetadataKeywordKind(StringRef Identifier)455*9880d681SAndroid Build Coastguard Worker static MIToken::TokenKind getMetadataKeywordKind(StringRef Identifier) {
456*9880d681SAndroid Build Coastguard Worker return StringSwitch<MIToken::TokenKind>(Identifier)
457*9880d681SAndroid Build Coastguard Worker .Case("!tbaa", MIToken::md_tbaa)
458*9880d681SAndroid Build Coastguard Worker .Case("!alias.scope", MIToken::md_alias_scope)
459*9880d681SAndroid Build Coastguard Worker .Case("!noalias", MIToken::md_noalias)
460*9880d681SAndroid Build Coastguard Worker .Case("!range", MIToken::md_range)
461*9880d681SAndroid Build Coastguard Worker .Default(MIToken::Error);
462*9880d681SAndroid Build Coastguard Worker }
463*9880d681SAndroid Build Coastguard Worker
maybeLexExlaim(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)464*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexExlaim(Cursor C, MIToken &Token,
465*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
466*9880d681SAndroid Build Coastguard Worker if (C.peek() != '!')
467*9880d681SAndroid Build Coastguard Worker return None;
468*9880d681SAndroid Build Coastguard Worker auto Range = C;
469*9880d681SAndroid Build Coastguard Worker C.advance(1);
470*9880d681SAndroid Build Coastguard Worker if (isdigit(C.peek()) || !isIdentifierChar(C.peek())) {
471*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::exclaim, Range.upto(C));
472*9880d681SAndroid Build Coastguard Worker return C;
473*9880d681SAndroid Build Coastguard Worker }
474*9880d681SAndroid Build Coastguard Worker while (isIdentifierChar(C.peek()))
475*9880d681SAndroid Build Coastguard Worker C.advance();
476*9880d681SAndroid Build Coastguard Worker StringRef StrVal = Range.upto(C);
477*9880d681SAndroid Build Coastguard Worker Token.reset(getMetadataKeywordKind(StrVal), StrVal);
478*9880d681SAndroid Build Coastguard Worker if (Token.isError())
479*9880d681SAndroid Build Coastguard Worker ErrorCallback(Token.location(),
480*9880d681SAndroid Build Coastguard Worker "use of unknown metadata keyword '" + StrVal + "'");
481*9880d681SAndroid Build Coastguard Worker return C;
482*9880d681SAndroid Build Coastguard Worker }
483*9880d681SAndroid Build Coastguard Worker
symbolToken(char C)484*9880d681SAndroid Build Coastguard Worker static MIToken::TokenKind symbolToken(char C) {
485*9880d681SAndroid Build Coastguard Worker switch (C) {
486*9880d681SAndroid Build Coastguard Worker case ',':
487*9880d681SAndroid Build Coastguard Worker return MIToken::comma;
488*9880d681SAndroid Build Coastguard Worker case '=':
489*9880d681SAndroid Build Coastguard Worker return MIToken::equal;
490*9880d681SAndroid Build Coastguard Worker case ':':
491*9880d681SAndroid Build Coastguard Worker return MIToken::colon;
492*9880d681SAndroid Build Coastguard Worker case '(':
493*9880d681SAndroid Build Coastguard Worker return MIToken::lparen;
494*9880d681SAndroid Build Coastguard Worker case ')':
495*9880d681SAndroid Build Coastguard Worker return MIToken::rparen;
496*9880d681SAndroid Build Coastguard Worker case '{':
497*9880d681SAndroid Build Coastguard Worker return MIToken::lbrace;
498*9880d681SAndroid Build Coastguard Worker case '}':
499*9880d681SAndroid Build Coastguard Worker return MIToken::rbrace;
500*9880d681SAndroid Build Coastguard Worker case '+':
501*9880d681SAndroid Build Coastguard Worker return MIToken::plus;
502*9880d681SAndroid Build Coastguard Worker case '-':
503*9880d681SAndroid Build Coastguard Worker return MIToken::minus;
504*9880d681SAndroid Build Coastguard Worker case '<':
505*9880d681SAndroid Build Coastguard Worker return MIToken::less;
506*9880d681SAndroid Build Coastguard Worker case '>':
507*9880d681SAndroid Build Coastguard Worker return MIToken::greater;
508*9880d681SAndroid Build Coastguard Worker default:
509*9880d681SAndroid Build Coastguard Worker return MIToken::Error;
510*9880d681SAndroid Build Coastguard Worker }
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker
maybeLexSymbol(Cursor C,MIToken & Token)513*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexSymbol(Cursor C, MIToken &Token) {
514*9880d681SAndroid Build Coastguard Worker MIToken::TokenKind Kind;
515*9880d681SAndroid Build Coastguard Worker unsigned Length = 1;
516*9880d681SAndroid Build Coastguard Worker if (C.peek() == ':' && C.peek(1) == ':') {
517*9880d681SAndroid Build Coastguard Worker Kind = MIToken::coloncolon;
518*9880d681SAndroid Build Coastguard Worker Length = 2;
519*9880d681SAndroid Build Coastguard Worker } else
520*9880d681SAndroid Build Coastguard Worker Kind = symbolToken(C.peek());
521*9880d681SAndroid Build Coastguard Worker if (Kind == MIToken::Error)
522*9880d681SAndroid Build Coastguard Worker return None;
523*9880d681SAndroid Build Coastguard Worker auto Range = C;
524*9880d681SAndroid Build Coastguard Worker C.advance(Length);
525*9880d681SAndroid Build Coastguard Worker Token.reset(Kind, Range.upto(C));
526*9880d681SAndroid Build Coastguard Worker return C;
527*9880d681SAndroid Build Coastguard Worker }
528*9880d681SAndroid Build Coastguard Worker
maybeLexNewline(Cursor C,MIToken & Token)529*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexNewline(Cursor C, MIToken &Token) {
530*9880d681SAndroid Build Coastguard Worker if (!isNewlineChar(C.peek()))
531*9880d681SAndroid Build Coastguard Worker return None;
532*9880d681SAndroid Build Coastguard Worker auto Range = C;
533*9880d681SAndroid Build Coastguard Worker C.advance();
534*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::Newline, Range.upto(C));
535*9880d681SAndroid Build Coastguard Worker return C;
536*9880d681SAndroid Build Coastguard Worker }
537*9880d681SAndroid Build Coastguard Worker
maybeLexEscapedIRValue(Cursor C,MIToken & Token,ErrorCallbackType ErrorCallback)538*9880d681SAndroid Build Coastguard Worker static Cursor maybeLexEscapedIRValue(Cursor C, MIToken &Token,
539*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
540*9880d681SAndroid Build Coastguard Worker if (C.peek() != '`')
541*9880d681SAndroid Build Coastguard Worker return None;
542*9880d681SAndroid Build Coastguard Worker auto Range = C;
543*9880d681SAndroid Build Coastguard Worker C.advance();
544*9880d681SAndroid Build Coastguard Worker auto StrRange = C;
545*9880d681SAndroid Build Coastguard Worker while (C.peek() != '`') {
546*9880d681SAndroid Build Coastguard Worker if (C.isEOF() || isNewlineChar(C.peek())) {
547*9880d681SAndroid Build Coastguard Worker ErrorCallback(
548*9880d681SAndroid Build Coastguard Worker C.location(),
549*9880d681SAndroid Build Coastguard Worker "end of machine instruction reached before the closing '`'");
550*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::Error, Range.remaining());
551*9880d681SAndroid Build Coastguard Worker return C;
552*9880d681SAndroid Build Coastguard Worker }
553*9880d681SAndroid Build Coastguard Worker C.advance();
554*9880d681SAndroid Build Coastguard Worker }
555*9880d681SAndroid Build Coastguard Worker StringRef Value = StrRange.upto(C);
556*9880d681SAndroid Build Coastguard Worker C.advance();
557*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::QuotedIRValue, Range.upto(C)).setStringValue(Value);
558*9880d681SAndroid Build Coastguard Worker return C;
559*9880d681SAndroid Build Coastguard Worker }
560*9880d681SAndroid Build Coastguard Worker
lexMIToken(StringRef Source,MIToken & Token,ErrorCallbackType ErrorCallback)561*9880d681SAndroid Build Coastguard Worker StringRef llvm::lexMIToken(StringRef Source, MIToken &Token,
562*9880d681SAndroid Build Coastguard Worker ErrorCallbackType ErrorCallback) {
563*9880d681SAndroid Build Coastguard Worker auto C = skipComment(skipWhitespace(Cursor(Source)));
564*9880d681SAndroid Build Coastguard Worker if (C.isEOF()) {
565*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::Eof, C.remaining());
566*9880d681SAndroid Build Coastguard Worker return C.remaining();
567*9880d681SAndroid Build Coastguard Worker }
568*9880d681SAndroid Build Coastguard Worker
569*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexIntegerType(C, Token))
570*9880d681SAndroid Build Coastguard Worker return R.remaining();
571*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexMachineBasicBlock(C, Token, ErrorCallback))
572*9880d681SAndroid Build Coastguard Worker return R.remaining();
573*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexIdentifier(C, Token))
574*9880d681SAndroid Build Coastguard Worker return R.remaining();
575*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexJumpTableIndex(C, Token))
576*9880d681SAndroid Build Coastguard Worker return R.remaining();
577*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexStackObject(C, Token))
578*9880d681SAndroid Build Coastguard Worker return R.remaining();
579*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexFixedStackObject(C, Token))
580*9880d681SAndroid Build Coastguard Worker return R.remaining();
581*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexConstantPoolItem(C, Token))
582*9880d681SAndroid Build Coastguard Worker return R.remaining();
583*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexSubRegisterIndex(C, Token, ErrorCallback))
584*9880d681SAndroid Build Coastguard Worker return R.remaining();
585*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexIRBlock(C, Token, ErrorCallback))
586*9880d681SAndroid Build Coastguard Worker return R.remaining();
587*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexIRValue(C, Token, ErrorCallback))
588*9880d681SAndroid Build Coastguard Worker return R.remaining();
589*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexRegister(C, Token))
590*9880d681SAndroid Build Coastguard Worker return R.remaining();
591*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexGlobalValue(C, Token, ErrorCallback))
592*9880d681SAndroid Build Coastguard Worker return R.remaining();
593*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexExternalSymbol(C, Token, ErrorCallback))
594*9880d681SAndroid Build Coastguard Worker return R.remaining();
595*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexHexFloatingPointLiteral(C, Token))
596*9880d681SAndroid Build Coastguard Worker return R.remaining();
597*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexNumericalLiteral(C, Token))
598*9880d681SAndroid Build Coastguard Worker return R.remaining();
599*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexExlaim(C, Token, ErrorCallback))
600*9880d681SAndroid Build Coastguard Worker return R.remaining();
601*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexSymbol(C, Token))
602*9880d681SAndroid Build Coastguard Worker return R.remaining();
603*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexNewline(C, Token))
604*9880d681SAndroid Build Coastguard Worker return R.remaining();
605*9880d681SAndroid Build Coastguard Worker if (Cursor R = maybeLexEscapedIRValue(C, Token, ErrorCallback))
606*9880d681SAndroid Build Coastguard Worker return R.remaining();
607*9880d681SAndroid Build Coastguard Worker
608*9880d681SAndroid Build Coastguard Worker Token.reset(MIToken::Error, C.remaining());
609*9880d681SAndroid Build Coastguard Worker ErrorCallback(C.location(),
610*9880d681SAndroid Build Coastguard Worker Twine("unexpected character '") + Twine(C.peek()) + "'");
611*9880d681SAndroid Build Coastguard Worker return C.remaining();
612*9880d681SAndroid Build Coastguard Worker }
613