1*9880d681SAndroid Build Coastguard Worker //===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===//
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 class implements the lexer for assembly files.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCParser/AsmLexer.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/MC/MCAsmInfo.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/MemoryBuffer.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Support/SMLoc.h"
18*9880d681SAndroid Build Coastguard Worker #include <cctype>
19*9880d681SAndroid Build Coastguard Worker #include <cerrno>
20*9880d681SAndroid Build Coastguard Worker #include <cstdio>
21*9880d681SAndroid Build Coastguard Worker #include <cstdlib>
22*9880d681SAndroid Build Coastguard Worker using namespace llvm;
23*9880d681SAndroid Build Coastguard Worker
AsmLexer(const MCAsmInfo & MAI)24*9880d681SAndroid Build Coastguard Worker AsmLexer::AsmLexer(const MCAsmInfo &MAI) : MAI(MAI) {
25*9880d681SAndroid Build Coastguard Worker CurPtr = nullptr;
26*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = true;
27*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = true;
28*9880d681SAndroid Build Coastguard Worker AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@");
29*9880d681SAndroid Build Coastguard Worker }
30*9880d681SAndroid Build Coastguard Worker
~AsmLexer()31*9880d681SAndroid Build Coastguard Worker AsmLexer::~AsmLexer() {
32*9880d681SAndroid Build Coastguard Worker }
33*9880d681SAndroid Build Coastguard Worker
setBuffer(StringRef Buf,const char * ptr)34*9880d681SAndroid Build Coastguard Worker void AsmLexer::setBuffer(StringRef Buf, const char *ptr) {
35*9880d681SAndroid Build Coastguard Worker CurBuf = Buf;
36*9880d681SAndroid Build Coastguard Worker
37*9880d681SAndroid Build Coastguard Worker if (ptr)
38*9880d681SAndroid Build Coastguard Worker CurPtr = ptr;
39*9880d681SAndroid Build Coastguard Worker else
40*9880d681SAndroid Build Coastguard Worker CurPtr = CurBuf.begin();
41*9880d681SAndroid Build Coastguard Worker
42*9880d681SAndroid Build Coastguard Worker TokStart = nullptr;
43*9880d681SAndroid Build Coastguard Worker }
44*9880d681SAndroid Build Coastguard Worker
45*9880d681SAndroid Build Coastguard Worker /// ReturnError - Set the error to the specified string at the specified
46*9880d681SAndroid Build Coastguard Worker /// location. This is defined to always return AsmToken::Error.
ReturnError(const char * Loc,const std::string & Msg)47*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
48*9880d681SAndroid Build Coastguard Worker SetError(SMLoc::getFromPointer(Loc), Msg);
49*9880d681SAndroid Build Coastguard Worker
50*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Error, StringRef(Loc, CurPtr - Loc));
51*9880d681SAndroid Build Coastguard Worker }
52*9880d681SAndroid Build Coastguard Worker
getNextChar()53*9880d681SAndroid Build Coastguard Worker int AsmLexer::getNextChar() {
54*9880d681SAndroid Build Coastguard Worker if (CurPtr == CurBuf.end())
55*9880d681SAndroid Build Coastguard Worker return EOF;
56*9880d681SAndroid Build Coastguard Worker return (unsigned char)*CurPtr++;
57*9880d681SAndroid Build Coastguard Worker }
58*9880d681SAndroid Build Coastguard Worker
59*9880d681SAndroid Build Coastguard Worker /// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)?
60*9880d681SAndroid Build Coastguard Worker ///
61*9880d681SAndroid Build Coastguard Worker /// The leading integral digit sequence and dot should have already been
62*9880d681SAndroid Build Coastguard Worker /// consumed, some or all of the fractional digit sequence *can* have been
63*9880d681SAndroid Build Coastguard Worker /// consumed.
LexFloatLiteral()64*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexFloatLiteral() {
65*9880d681SAndroid Build Coastguard Worker // Skip the fractional digit sequence.
66*9880d681SAndroid Build Coastguard Worker while (isdigit(*CurPtr))
67*9880d681SAndroid Build Coastguard Worker ++CurPtr;
68*9880d681SAndroid Build Coastguard Worker
69*9880d681SAndroid Build Coastguard Worker // Check for exponent; we intentionally accept a slighlty wider set of
70*9880d681SAndroid Build Coastguard Worker // literals here and rely on the upstream client to reject invalid ones (e.g.,
71*9880d681SAndroid Build Coastguard Worker // "1e+").
72*9880d681SAndroid Build Coastguard Worker if (*CurPtr == 'e' || *CurPtr == 'E') {
73*9880d681SAndroid Build Coastguard Worker ++CurPtr;
74*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '-' || *CurPtr == '+')
75*9880d681SAndroid Build Coastguard Worker ++CurPtr;
76*9880d681SAndroid Build Coastguard Worker while (isdigit(*CurPtr))
77*9880d681SAndroid Build Coastguard Worker ++CurPtr;
78*9880d681SAndroid Build Coastguard Worker }
79*9880d681SAndroid Build Coastguard Worker
80*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Real,
81*9880d681SAndroid Build Coastguard Worker StringRef(TokStart, CurPtr - TokStart));
82*9880d681SAndroid Build Coastguard Worker }
83*9880d681SAndroid Build Coastguard Worker
84*9880d681SAndroid Build Coastguard Worker /// LexHexFloatLiteral matches essentially (.[0-9a-fA-F]*)?[pP][+-]?[0-9a-fA-F]+
85*9880d681SAndroid Build Coastguard Worker /// while making sure there are enough actual digits around for the constant to
86*9880d681SAndroid Build Coastguard Worker /// be valid.
87*9880d681SAndroid Build Coastguard Worker ///
88*9880d681SAndroid Build Coastguard Worker /// The leading "0x[0-9a-fA-F]*" (i.e. integer part) has already been consumed
89*9880d681SAndroid Build Coastguard Worker /// before we get here.
LexHexFloatLiteral(bool NoIntDigits)90*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) {
91*9880d681SAndroid Build Coastguard Worker assert((*CurPtr == 'p' || *CurPtr == 'P' || *CurPtr == '.') &&
92*9880d681SAndroid Build Coastguard Worker "unexpected parse state in floating hex");
93*9880d681SAndroid Build Coastguard Worker bool NoFracDigits = true;
94*9880d681SAndroid Build Coastguard Worker
95*9880d681SAndroid Build Coastguard Worker // Skip the fractional part if there is one
96*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '.') {
97*9880d681SAndroid Build Coastguard Worker ++CurPtr;
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker const char *FracStart = CurPtr;
100*9880d681SAndroid Build Coastguard Worker while (isxdigit(*CurPtr))
101*9880d681SAndroid Build Coastguard Worker ++CurPtr;
102*9880d681SAndroid Build Coastguard Worker
103*9880d681SAndroid Build Coastguard Worker NoFracDigits = CurPtr == FracStart;
104*9880d681SAndroid Build Coastguard Worker }
105*9880d681SAndroid Build Coastguard Worker
106*9880d681SAndroid Build Coastguard Worker if (NoIntDigits && NoFracDigits)
107*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
108*9880d681SAndroid Build Coastguard Worker "expected at least one significand digit");
109*9880d681SAndroid Build Coastguard Worker
110*9880d681SAndroid Build Coastguard Worker // Make sure we do have some kind of proper exponent part
111*9880d681SAndroid Build Coastguard Worker if (*CurPtr != 'p' && *CurPtr != 'P')
112*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
113*9880d681SAndroid Build Coastguard Worker "expected exponent part 'p'");
114*9880d681SAndroid Build Coastguard Worker ++CurPtr;
115*9880d681SAndroid Build Coastguard Worker
116*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '+' || *CurPtr == '-')
117*9880d681SAndroid Build Coastguard Worker ++CurPtr;
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker // N.b. exponent digits are *not* hex
120*9880d681SAndroid Build Coastguard Worker const char *ExpStart = CurPtr;
121*9880d681SAndroid Build Coastguard Worker while (isdigit(*CurPtr))
122*9880d681SAndroid Build Coastguard Worker ++CurPtr;
123*9880d681SAndroid Build Coastguard Worker
124*9880d681SAndroid Build Coastguard Worker if (CurPtr == ExpStart)
125*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid hexadecimal floating-point constant: "
126*9880d681SAndroid Build Coastguard Worker "expected at least one exponent digit");
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
129*9880d681SAndroid Build Coastguard Worker }
130*9880d681SAndroid Build Coastguard Worker
131*9880d681SAndroid Build Coastguard Worker /// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@?]*
IsIdentifierChar(char c,bool AllowAt)132*9880d681SAndroid Build Coastguard Worker static bool IsIdentifierChar(char c, bool AllowAt) {
133*9880d681SAndroid Build Coastguard Worker return isalnum(c) || c == '_' || c == '$' || c == '.' ||
134*9880d681SAndroid Build Coastguard Worker (c == '@' && AllowAt) || c == '?';
135*9880d681SAndroid Build Coastguard Worker }
LexIdentifier()136*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexIdentifier() {
137*9880d681SAndroid Build Coastguard Worker // Check for floating point literals.
138*9880d681SAndroid Build Coastguard Worker if (CurPtr[-1] == '.' && isdigit(*CurPtr)) {
139*9880d681SAndroid Build Coastguard Worker // Disambiguate a .1243foo identifier from a floating literal.
140*9880d681SAndroid Build Coastguard Worker while (isdigit(*CurPtr))
141*9880d681SAndroid Build Coastguard Worker ++CurPtr;
142*9880d681SAndroid Build Coastguard Worker if (*CurPtr == 'e' || *CurPtr == 'E' ||
143*9880d681SAndroid Build Coastguard Worker !IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
144*9880d681SAndroid Build Coastguard Worker return LexFloatLiteral();
145*9880d681SAndroid Build Coastguard Worker }
146*9880d681SAndroid Build Coastguard Worker
147*9880d681SAndroid Build Coastguard Worker while (IsIdentifierChar(*CurPtr, AllowAtInIdentifier))
148*9880d681SAndroid Build Coastguard Worker ++CurPtr;
149*9880d681SAndroid Build Coastguard Worker
150*9880d681SAndroid Build Coastguard Worker // Handle . as a special case.
151*9880d681SAndroid Build Coastguard Worker if (CurPtr == TokStart+1 && TokStart[0] == '.')
152*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Dot, StringRef(TokStart, 1));
153*9880d681SAndroid Build Coastguard Worker
154*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
155*9880d681SAndroid Build Coastguard Worker }
156*9880d681SAndroid Build Coastguard Worker
157*9880d681SAndroid Build Coastguard Worker /// LexSlash: Slash: /
158*9880d681SAndroid Build Coastguard Worker /// C-Style Comment: /* ... */
LexSlash()159*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexSlash() {
160*9880d681SAndroid Build Coastguard Worker switch (*CurPtr) {
161*9880d681SAndroid Build Coastguard Worker case '*':
162*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = false;
163*9880d681SAndroid Build Coastguard Worker break; // C style comment.
164*9880d681SAndroid Build Coastguard Worker case '/':
165*9880d681SAndroid Build Coastguard Worker ++CurPtr;
166*9880d681SAndroid Build Coastguard Worker return LexLineComment();
167*9880d681SAndroid Build Coastguard Worker default:
168*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = false;
169*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Slash, StringRef(TokStart, 1));
170*9880d681SAndroid Build Coastguard Worker }
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker // C Style comment.
173*9880d681SAndroid Build Coastguard Worker ++CurPtr; // skip the star.
174*9880d681SAndroid Build Coastguard Worker while (CurPtr != CurBuf.end()) {
175*9880d681SAndroid Build Coastguard Worker switch (*CurPtr++) {
176*9880d681SAndroid Build Coastguard Worker case '*':
177*9880d681SAndroid Build Coastguard Worker // End of the comment?
178*9880d681SAndroid Build Coastguard Worker if (*CurPtr != '/')
179*9880d681SAndroid Build Coastguard Worker break;
180*9880d681SAndroid Build Coastguard Worker ++CurPtr; // End the */.
181*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Comment,
182*9880d681SAndroid Build Coastguard Worker StringRef(TokStart, CurPtr - TokStart));
183*9880d681SAndroid Build Coastguard Worker }
184*9880d681SAndroid Build Coastguard Worker }
185*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "unterminated comment");
186*9880d681SAndroid Build Coastguard Worker }
187*9880d681SAndroid Build Coastguard Worker
188*9880d681SAndroid Build Coastguard Worker /// LexLineComment: Comment: #[^\n]*
189*9880d681SAndroid Build Coastguard Worker /// : //[^\n]*
LexLineComment()190*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexLineComment() {
191*9880d681SAndroid Build Coastguard Worker // Mark This as an end of statement with a body of the
192*9880d681SAndroid Build Coastguard Worker // comment. While it would be nicer to leave this two tokens,
193*9880d681SAndroid Build Coastguard Worker // backwards compatability with TargetParsers makes keeping this in this form
194*9880d681SAndroid Build Coastguard Worker // better.
195*9880d681SAndroid Build Coastguard Worker int CurChar = getNextChar();
196*9880d681SAndroid Build Coastguard Worker while (CurChar != '\n' && CurChar != '\r' && CurChar != EOF)
197*9880d681SAndroid Build Coastguard Worker CurChar = getNextChar();
198*9880d681SAndroid Build Coastguard Worker
199*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = true;
200*9880d681SAndroid Build Coastguard Worker // Whis is a whole line comment. leave newline
201*9880d681SAndroid Build Coastguard Worker if (IsAtStartOfStatement)
202*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::EndOfStatement,
203*9880d681SAndroid Build Coastguard Worker StringRef(TokStart, CurPtr - TokStart));
204*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = true;
205*9880d681SAndroid Build Coastguard Worker
206*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::EndOfStatement,
207*9880d681SAndroid Build Coastguard Worker StringRef(TokStart, CurPtr - 1 - TokStart));
208*9880d681SAndroid Build Coastguard Worker }
209*9880d681SAndroid Build Coastguard Worker
SkipIgnoredIntegerSuffix(const char * & CurPtr)210*9880d681SAndroid Build Coastguard Worker static void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
211*9880d681SAndroid Build Coastguard Worker // Skip ULL, UL, U, L and LL suffices.
212*9880d681SAndroid Build Coastguard Worker if (CurPtr[0] == 'U')
213*9880d681SAndroid Build Coastguard Worker ++CurPtr;
214*9880d681SAndroid Build Coastguard Worker if (CurPtr[0] == 'L')
215*9880d681SAndroid Build Coastguard Worker ++CurPtr;
216*9880d681SAndroid Build Coastguard Worker if (CurPtr[0] == 'L')
217*9880d681SAndroid Build Coastguard Worker ++CurPtr;
218*9880d681SAndroid Build Coastguard Worker }
219*9880d681SAndroid Build Coastguard Worker
220*9880d681SAndroid Build Coastguard Worker // Look ahead to search for first non-hex digit, if it's [hH], then we treat the
221*9880d681SAndroid Build Coastguard Worker // integer as a hexadecimal, possibly with leading zeroes.
doLookAhead(const char * & CurPtr,unsigned DefaultRadix)222*9880d681SAndroid Build Coastguard Worker static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) {
223*9880d681SAndroid Build Coastguard Worker const char *FirstHex = nullptr;
224*9880d681SAndroid Build Coastguard Worker const char *LookAhead = CurPtr;
225*9880d681SAndroid Build Coastguard Worker while (1) {
226*9880d681SAndroid Build Coastguard Worker if (isdigit(*LookAhead)) {
227*9880d681SAndroid Build Coastguard Worker ++LookAhead;
228*9880d681SAndroid Build Coastguard Worker } else if (isxdigit(*LookAhead)) {
229*9880d681SAndroid Build Coastguard Worker if (!FirstHex)
230*9880d681SAndroid Build Coastguard Worker FirstHex = LookAhead;
231*9880d681SAndroid Build Coastguard Worker ++LookAhead;
232*9880d681SAndroid Build Coastguard Worker } else {
233*9880d681SAndroid Build Coastguard Worker break;
234*9880d681SAndroid Build Coastguard Worker }
235*9880d681SAndroid Build Coastguard Worker }
236*9880d681SAndroid Build Coastguard Worker bool isHex = *LookAhead == 'h' || *LookAhead == 'H';
237*9880d681SAndroid Build Coastguard Worker CurPtr = isHex || !FirstHex ? LookAhead : FirstHex;
238*9880d681SAndroid Build Coastguard Worker if (isHex)
239*9880d681SAndroid Build Coastguard Worker return 16;
240*9880d681SAndroid Build Coastguard Worker return DefaultRadix;
241*9880d681SAndroid Build Coastguard Worker }
242*9880d681SAndroid Build Coastguard Worker
intToken(StringRef Ref,APInt & Value)243*9880d681SAndroid Build Coastguard Worker static AsmToken intToken(StringRef Ref, APInt &Value)
244*9880d681SAndroid Build Coastguard Worker {
245*9880d681SAndroid Build Coastguard Worker if (Value.isIntN(64))
246*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Integer, Ref, Value);
247*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::BigNum, Ref, Value);
248*9880d681SAndroid Build Coastguard Worker }
249*9880d681SAndroid Build Coastguard Worker
250*9880d681SAndroid Build Coastguard Worker /// LexDigit: First character is [0-9].
251*9880d681SAndroid Build Coastguard Worker /// Local Label: [0-9][:]
252*9880d681SAndroid Build Coastguard Worker /// Forward/Backward Label: [0-9][fb]
253*9880d681SAndroid Build Coastguard Worker /// Binary integer: 0b[01]+
254*9880d681SAndroid Build Coastguard Worker /// Octal integer: 0[0-7]+
255*9880d681SAndroid Build Coastguard Worker /// Hex integer: 0x[0-9a-fA-F]+ or [0x]?[0-9][0-9a-fA-F]*[hH]
256*9880d681SAndroid Build Coastguard Worker /// Decimal integer: [1-9][0-9]*
LexDigit()257*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexDigit() {
258*9880d681SAndroid Build Coastguard Worker // Decimal integer: [1-9][0-9]*
259*9880d681SAndroid Build Coastguard Worker if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
260*9880d681SAndroid Build Coastguard Worker unsigned Radix = doLookAhead(CurPtr, 10);
261*9880d681SAndroid Build Coastguard Worker bool isHex = Radix == 16;
262*9880d681SAndroid Build Coastguard Worker // Check for floating point literals.
263*9880d681SAndroid Build Coastguard Worker if (!isHex && (*CurPtr == '.' || *CurPtr == 'e')) {
264*9880d681SAndroid Build Coastguard Worker ++CurPtr;
265*9880d681SAndroid Build Coastguard Worker return LexFloatLiteral();
266*9880d681SAndroid Build Coastguard Worker }
267*9880d681SAndroid Build Coastguard Worker
268*9880d681SAndroid Build Coastguard Worker StringRef Result(TokStart, CurPtr - TokStart);
269*9880d681SAndroid Build Coastguard Worker
270*9880d681SAndroid Build Coastguard Worker APInt Value(128, 0, true);
271*9880d681SAndroid Build Coastguard Worker if (Result.getAsInteger(Radix, Value))
272*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, !isHex ? "invalid decimal number" :
273*9880d681SAndroid Build Coastguard Worker "invalid hexdecimal number");
274*9880d681SAndroid Build Coastguard Worker
275*9880d681SAndroid Build Coastguard Worker // Consume the [bB][hH].
276*9880d681SAndroid Build Coastguard Worker if (Radix == 2 || Radix == 16)
277*9880d681SAndroid Build Coastguard Worker ++CurPtr;
278*9880d681SAndroid Build Coastguard Worker
279*9880d681SAndroid Build Coastguard Worker // The darwin/x86 (and x86-64) assembler accepts and ignores type
280*9880d681SAndroid Build Coastguard Worker // suffices on integer literals.
281*9880d681SAndroid Build Coastguard Worker SkipIgnoredIntegerSuffix(CurPtr);
282*9880d681SAndroid Build Coastguard Worker
283*9880d681SAndroid Build Coastguard Worker return intToken(Result, Value);
284*9880d681SAndroid Build Coastguard Worker }
285*9880d681SAndroid Build Coastguard Worker
286*9880d681SAndroid Build Coastguard Worker if ((*CurPtr == 'b') || (*CurPtr == 'B')) {
287*9880d681SAndroid Build Coastguard Worker ++CurPtr;
288*9880d681SAndroid Build Coastguard Worker // See if we actually have "0b" as part of something like "jmp 0b\n"
289*9880d681SAndroid Build Coastguard Worker if (!isdigit(CurPtr[0])) {
290*9880d681SAndroid Build Coastguard Worker --CurPtr;
291*9880d681SAndroid Build Coastguard Worker StringRef Result(TokStart, CurPtr - TokStart);
292*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Integer, Result, 0);
293*9880d681SAndroid Build Coastguard Worker }
294*9880d681SAndroid Build Coastguard Worker const char *NumStart = CurPtr;
295*9880d681SAndroid Build Coastguard Worker while (CurPtr[0] == '0' || CurPtr[0] == '1')
296*9880d681SAndroid Build Coastguard Worker ++CurPtr;
297*9880d681SAndroid Build Coastguard Worker
298*9880d681SAndroid Build Coastguard Worker // Requires at least one binary digit.
299*9880d681SAndroid Build Coastguard Worker if (CurPtr == NumStart)
300*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid binary number");
301*9880d681SAndroid Build Coastguard Worker
302*9880d681SAndroid Build Coastguard Worker StringRef Result(TokStart, CurPtr - TokStart);
303*9880d681SAndroid Build Coastguard Worker
304*9880d681SAndroid Build Coastguard Worker APInt Value(128, 0, true);
305*9880d681SAndroid Build Coastguard Worker if (Result.substr(2).getAsInteger(2, Value))
306*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid binary number");
307*9880d681SAndroid Build Coastguard Worker
308*9880d681SAndroid Build Coastguard Worker // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
309*9880d681SAndroid Build Coastguard Worker // suffixes on integer literals.
310*9880d681SAndroid Build Coastguard Worker SkipIgnoredIntegerSuffix(CurPtr);
311*9880d681SAndroid Build Coastguard Worker
312*9880d681SAndroid Build Coastguard Worker return intToken(Result, Value);
313*9880d681SAndroid Build Coastguard Worker }
314*9880d681SAndroid Build Coastguard Worker
315*9880d681SAndroid Build Coastguard Worker if ((*CurPtr == 'x') || (*CurPtr == 'X')) {
316*9880d681SAndroid Build Coastguard Worker ++CurPtr;
317*9880d681SAndroid Build Coastguard Worker const char *NumStart = CurPtr;
318*9880d681SAndroid Build Coastguard Worker while (isxdigit(CurPtr[0]))
319*9880d681SAndroid Build Coastguard Worker ++CurPtr;
320*9880d681SAndroid Build Coastguard Worker
321*9880d681SAndroid Build Coastguard Worker // "0x.0p0" is valid, and "0x0p0" (but not "0xp0" for example, which will be
322*9880d681SAndroid Build Coastguard Worker // diagnosed by LexHexFloatLiteral).
323*9880d681SAndroid Build Coastguard Worker if (CurPtr[0] == '.' || CurPtr[0] == 'p' || CurPtr[0] == 'P')
324*9880d681SAndroid Build Coastguard Worker return LexHexFloatLiteral(NumStart == CurPtr);
325*9880d681SAndroid Build Coastguard Worker
326*9880d681SAndroid Build Coastguard Worker // Otherwise requires at least one hex digit.
327*9880d681SAndroid Build Coastguard Worker if (CurPtr == NumStart)
328*9880d681SAndroid Build Coastguard Worker return ReturnError(CurPtr-2, "invalid hexadecimal number");
329*9880d681SAndroid Build Coastguard Worker
330*9880d681SAndroid Build Coastguard Worker APInt Result(128, 0);
331*9880d681SAndroid Build Coastguard Worker if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
332*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid hexadecimal number");
333*9880d681SAndroid Build Coastguard Worker
334*9880d681SAndroid Build Coastguard Worker // Consume the optional [hH].
335*9880d681SAndroid Build Coastguard Worker if (*CurPtr == 'h' || *CurPtr == 'H')
336*9880d681SAndroid Build Coastguard Worker ++CurPtr;
337*9880d681SAndroid Build Coastguard Worker
338*9880d681SAndroid Build Coastguard Worker // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
339*9880d681SAndroid Build Coastguard Worker // suffixes on integer literals.
340*9880d681SAndroid Build Coastguard Worker SkipIgnoredIntegerSuffix(CurPtr);
341*9880d681SAndroid Build Coastguard Worker
342*9880d681SAndroid Build Coastguard Worker return intToken(StringRef(TokStart, CurPtr - TokStart), Result);
343*9880d681SAndroid Build Coastguard Worker }
344*9880d681SAndroid Build Coastguard Worker
345*9880d681SAndroid Build Coastguard Worker // Either octal or hexadecimal.
346*9880d681SAndroid Build Coastguard Worker APInt Value(128, 0, true);
347*9880d681SAndroid Build Coastguard Worker unsigned Radix = doLookAhead(CurPtr, 8);
348*9880d681SAndroid Build Coastguard Worker bool isHex = Radix == 16;
349*9880d681SAndroid Build Coastguard Worker StringRef Result(TokStart, CurPtr - TokStart);
350*9880d681SAndroid Build Coastguard Worker if (Result.getAsInteger(Radix, Value))
351*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, !isHex ? "invalid octal number" :
352*9880d681SAndroid Build Coastguard Worker "invalid hexdecimal number");
353*9880d681SAndroid Build Coastguard Worker
354*9880d681SAndroid Build Coastguard Worker // Consume the [hH].
355*9880d681SAndroid Build Coastguard Worker if (Radix == 16)
356*9880d681SAndroid Build Coastguard Worker ++CurPtr;
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
359*9880d681SAndroid Build Coastguard Worker // suffixes on integer literals.
360*9880d681SAndroid Build Coastguard Worker SkipIgnoredIntegerSuffix(CurPtr);
361*9880d681SAndroid Build Coastguard Worker
362*9880d681SAndroid Build Coastguard Worker return intToken(Result, Value);
363*9880d681SAndroid Build Coastguard Worker }
364*9880d681SAndroid Build Coastguard Worker
365*9880d681SAndroid Build Coastguard Worker /// LexSingleQuote: Integer: 'b'
LexSingleQuote()366*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexSingleQuote() {
367*9880d681SAndroid Build Coastguard Worker int CurChar = getNextChar();
368*9880d681SAndroid Build Coastguard Worker
369*9880d681SAndroid Build Coastguard Worker if (CurChar == '\\')
370*9880d681SAndroid Build Coastguard Worker CurChar = getNextChar();
371*9880d681SAndroid Build Coastguard Worker
372*9880d681SAndroid Build Coastguard Worker if (CurChar == EOF)
373*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "unterminated single quote");
374*9880d681SAndroid Build Coastguard Worker
375*9880d681SAndroid Build Coastguard Worker CurChar = getNextChar();
376*9880d681SAndroid Build Coastguard Worker
377*9880d681SAndroid Build Coastguard Worker if (CurChar != '\'')
378*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "single quote way too long");
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker // The idea here being that 'c' is basically just an integral
381*9880d681SAndroid Build Coastguard Worker // constant.
382*9880d681SAndroid Build Coastguard Worker StringRef Res = StringRef(TokStart,CurPtr - TokStart);
383*9880d681SAndroid Build Coastguard Worker long long Value;
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker if (Res.startswith("\'\\")) {
386*9880d681SAndroid Build Coastguard Worker char theChar = Res[2];
387*9880d681SAndroid Build Coastguard Worker switch (theChar) {
388*9880d681SAndroid Build Coastguard Worker default: Value = theChar; break;
389*9880d681SAndroid Build Coastguard Worker case '\'': Value = '\''; break;
390*9880d681SAndroid Build Coastguard Worker case 't': Value = '\t'; break;
391*9880d681SAndroid Build Coastguard Worker case 'n': Value = '\n'; break;
392*9880d681SAndroid Build Coastguard Worker case 'b': Value = '\b'; break;
393*9880d681SAndroid Build Coastguard Worker }
394*9880d681SAndroid Build Coastguard Worker } else
395*9880d681SAndroid Build Coastguard Worker Value = TokStart[1];
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Integer, Res, Value);
398*9880d681SAndroid Build Coastguard Worker }
399*9880d681SAndroid Build Coastguard Worker
400*9880d681SAndroid Build Coastguard Worker
401*9880d681SAndroid Build Coastguard Worker /// LexQuote: String: "..."
LexQuote()402*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexQuote() {
403*9880d681SAndroid Build Coastguard Worker int CurChar = getNextChar();
404*9880d681SAndroid Build Coastguard Worker // TODO: does gas allow multiline string constants?
405*9880d681SAndroid Build Coastguard Worker while (CurChar != '"') {
406*9880d681SAndroid Build Coastguard Worker if (CurChar == '\\') {
407*9880d681SAndroid Build Coastguard Worker // Allow \", etc.
408*9880d681SAndroid Build Coastguard Worker CurChar = getNextChar();
409*9880d681SAndroid Build Coastguard Worker }
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker if (CurChar == EOF)
412*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "unterminated string constant");
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker CurChar = getNextChar();
415*9880d681SAndroid Build Coastguard Worker }
416*9880d681SAndroid Build Coastguard Worker
417*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
418*9880d681SAndroid Build Coastguard Worker }
419*9880d681SAndroid Build Coastguard Worker
LexUntilEndOfStatement()420*9880d681SAndroid Build Coastguard Worker StringRef AsmLexer::LexUntilEndOfStatement() {
421*9880d681SAndroid Build Coastguard Worker TokStart = CurPtr;
422*9880d681SAndroid Build Coastguard Worker
423*9880d681SAndroid Build Coastguard Worker while (!isAtStartOfComment(CurPtr) && // Start of line comment.
424*9880d681SAndroid Build Coastguard Worker !isAtStatementSeparator(CurPtr) && // End of statement marker.
425*9880d681SAndroid Build Coastguard Worker *CurPtr != '\n' && *CurPtr != '\r' && CurPtr != CurBuf.end()) {
426*9880d681SAndroid Build Coastguard Worker ++CurPtr;
427*9880d681SAndroid Build Coastguard Worker }
428*9880d681SAndroid Build Coastguard Worker return StringRef(TokStart, CurPtr-TokStart);
429*9880d681SAndroid Build Coastguard Worker }
430*9880d681SAndroid Build Coastguard Worker
LexUntilEndOfLine()431*9880d681SAndroid Build Coastguard Worker StringRef AsmLexer::LexUntilEndOfLine() {
432*9880d681SAndroid Build Coastguard Worker TokStart = CurPtr;
433*9880d681SAndroid Build Coastguard Worker
434*9880d681SAndroid Build Coastguard Worker while (*CurPtr != '\n' && *CurPtr != '\r' && CurPtr != CurBuf.end()) {
435*9880d681SAndroid Build Coastguard Worker ++CurPtr;
436*9880d681SAndroid Build Coastguard Worker }
437*9880d681SAndroid Build Coastguard Worker return StringRef(TokStart, CurPtr-TokStart);
438*9880d681SAndroid Build Coastguard Worker }
439*9880d681SAndroid Build Coastguard Worker
peekTokens(MutableArrayRef<AsmToken> Buf,bool ShouldSkipSpace)440*9880d681SAndroid Build Coastguard Worker size_t AsmLexer::peekTokens(MutableArrayRef<AsmToken> Buf,
441*9880d681SAndroid Build Coastguard Worker bool ShouldSkipSpace) {
442*9880d681SAndroid Build Coastguard Worker const char *SavedTokStart = TokStart;
443*9880d681SAndroid Build Coastguard Worker const char *SavedCurPtr = CurPtr;
444*9880d681SAndroid Build Coastguard Worker bool SavedAtStartOfLine = IsAtStartOfLine;
445*9880d681SAndroid Build Coastguard Worker bool SavedAtStartOfStatement = IsAtStartOfStatement;
446*9880d681SAndroid Build Coastguard Worker bool SavedSkipSpace = SkipSpace;
447*9880d681SAndroid Build Coastguard Worker
448*9880d681SAndroid Build Coastguard Worker std::string SavedErr = getErr();
449*9880d681SAndroid Build Coastguard Worker SMLoc SavedErrLoc = getErrLoc();
450*9880d681SAndroid Build Coastguard Worker
451*9880d681SAndroid Build Coastguard Worker SkipSpace = ShouldSkipSpace;
452*9880d681SAndroid Build Coastguard Worker
453*9880d681SAndroid Build Coastguard Worker size_t ReadCount;
454*9880d681SAndroid Build Coastguard Worker for (ReadCount = 0; ReadCount < Buf.size(); ++ReadCount) {
455*9880d681SAndroid Build Coastguard Worker AsmToken Token = LexToken();
456*9880d681SAndroid Build Coastguard Worker
457*9880d681SAndroid Build Coastguard Worker Buf[ReadCount] = Token;
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker if (Token.is(AsmToken::Eof))
460*9880d681SAndroid Build Coastguard Worker break;
461*9880d681SAndroid Build Coastguard Worker }
462*9880d681SAndroid Build Coastguard Worker
463*9880d681SAndroid Build Coastguard Worker SetError(SavedErrLoc, SavedErr);
464*9880d681SAndroid Build Coastguard Worker
465*9880d681SAndroid Build Coastguard Worker SkipSpace = SavedSkipSpace;
466*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = SavedAtStartOfLine;
467*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = SavedAtStartOfStatement;
468*9880d681SAndroid Build Coastguard Worker CurPtr = SavedCurPtr;
469*9880d681SAndroid Build Coastguard Worker TokStart = SavedTokStart;
470*9880d681SAndroid Build Coastguard Worker
471*9880d681SAndroid Build Coastguard Worker return ReadCount;
472*9880d681SAndroid Build Coastguard Worker }
473*9880d681SAndroid Build Coastguard Worker
isAtStartOfComment(const char * Ptr)474*9880d681SAndroid Build Coastguard Worker bool AsmLexer::isAtStartOfComment(const char *Ptr) {
475*9880d681SAndroid Build Coastguard Worker const char *CommentString = MAI.getCommentString();
476*9880d681SAndroid Build Coastguard Worker
477*9880d681SAndroid Build Coastguard Worker if (CommentString[1] == '\0')
478*9880d681SAndroid Build Coastguard Worker return CommentString[0] == Ptr[0];
479*9880d681SAndroid Build Coastguard Worker
480*9880d681SAndroid Build Coastguard Worker // FIXME: special case for the bogus "##" comment string in X86MCAsmInfoDarwin
481*9880d681SAndroid Build Coastguard Worker if (CommentString[1] == '#')
482*9880d681SAndroid Build Coastguard Worker return CommentString[0] == Ptr[0];
483*9880d681SAndroid Build Coastguard Worker
484*9880d681SAndroid Build Coastguard Worker return strncmp(Ptr, CommentString, strlen(CommentString)) == 0;
485*9880d681SAndroid Build Coastguard Worker }
486*9880d681SAndroid Build Coastguard Worker
isAtStatementSeparator(const char * Ptr)487*9880d681SAndroid Build Coastguard Worker bool AsmLexer::isAtStatementSeparator(const char *Ptr) {
488*9880d681SAndroid Build Coastguard Worker return strncmp(Ptr, MAI.getSeparatorString(),
489*9880d681SAndroid Build Coastguard Worker strlen(MAI.getSeparatorString())) == 0;
490*9880d681SAndroid Build Coastguard Worker }
491*9880d681SAndroid Build Coastguard Worker
LexToken()492*9880d681SAndroid Build Coastguard Worker AsmToken AsmLexer::LexToken() {
493*9880d681SAndroid Build Coastguard Worker TokStart = CurPtr;
494*9880d681SAndroid Build Coastguard Worker // This always consumes at least one character.
495*9880d681SAndroid Build Coastguard Worker int CurChar = getNextChar();
496*9880d681SAndroid Build Coastguard Worker
497*9880d681SAndroid Build Coastguard Worker if (CurChar == '#' && IsAtStartOfStatement) {
498*9880d681SAndroid Build Coastguard Worker // If this starts with a '#', this may be a cpp
499*9880d681SAndroid Build Coastguard Worker // hash directive and otherwise a line comment.
500*9880d681SAndroid Build Coastguard Worker AsmToken TokenBuf[2];
501*9880d681SAndroid Build Coastguard Worker MutableArrayRef<AsmToken> Buf(TokenBuf, 2);
502*9880d681SAndroid Build Coastguard Worker size_t num = peekTokens(Buf, true);
503*9880d681SAndroid Build Coastguard Worker // There cannot be a space preceeding this
504*9880d681SAndroid Build Coastguard Worker if (IsAtStartOfLine && num == 2 && TokenBuf[0].is(AsmToken::Integer) &&
505*9880d681SAndroid Build Coastguard Worker TokenBuf[1].is(AsmToken::String)) {
506*9880d681SAndroid Build Coastguard Worker CurPtr = TokStart; // reset curPtr;
507*9880d681SAndroid Build Coastguard Worker StringRef s = LexUntilEndOfLine();
508*9880d681SAndroid Build Coastguard Worker UnLex(TokenBuf[1]);
509*9880d681SAndroid Build Coastguard Worker UnLex(TokenBuf[0]);
510*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::HashDirective, s);
511*9880d681SAndroid Build Coastguard Worker }
512*9880d681SAndroid Build Coastguard Worker return LexLineComment();
513*9880d681SAndroid Build Coastguard Worker }
514*9880d681SAndroid Build Coastguard Worker
515*9880d681SAndroid Build Coastguard Worker if (isAtStartOfComment(TokStart))
516*9880d681SAndroid Build Coastguard Worker return LexLineComment();
517*9880d681SAndroid Build Coastguard Worker
518*9880d681SAndroid Build Coastguard Worker if (isAtStatementSeparator(TokStart)) {
519*9880d681SAndroid Build Coastguard Worker CurPtr += strlen(MAI.getSeparatorString()) - 1;
520*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = true;
521*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = true;
522*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::EndOfStatement,
523*9880d681SAndroid Build Coastguard Worker StringRef(TokStart, strlen(MAI.getSeparatorString())));
524*9880d681SAndroid Build Coastguard Worker }
525*9880d681SAndroid Build Coastguard Worker
526*9880d681SAndroid Build Coastguard Worker // If we're missing a newline at EOF, make sure we still get an
527*9880d681SAndroid Build Coastguard Worker // EndOfStatement token before the Eof token.
528*9880d681SAndroid Build Coastguard Worker if (CurChar == EOF && !IsAtStartOfStatement) {
529*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = true;
530*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = true;
531*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
532*9880d681SAndroid Build Coastguard Worker }
533*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = false;
534*9880d681SAndroid Build Coastguard Worker bool OldIsAtStartOfStatement = IsAtStartOfStatement;
535*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = false;
536*9880d681SAndroid Build Coastguard Worker switch (CurChar) {
537*9880d681SAndroid Build Coastguard Worker default:
538*9880d681SAndroid Build Coastguard Worker // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
539*9880d681SAndroid Build Coastguard Worker if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
540*9880d681SAndroid Build Coastguard Worker return LexIdentifier();
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // Unknown character, emit an error.
543*9880d681SAndroid Build Coastguard Worker return ReturnError(TokStart, "invalid character in input");
544*9880d681SAndroid Build Coastguard Worker case EOF:
545*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = true;
546*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = true;
547*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
548*9880d681SAndroid Build Coastguard Worker case 0:
549*9880d681SAndroid Build Coastguard Worker case ' ':
550*9880d681SAndroid Build Coastguard Worker case '\t':
551*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = OldIsAtStartOfStatement;
552*9880d681SAndroid Build Coastguard Worker while (*CurPtr == ' ' || *CurPtr == '\t')
553*9880d681SAndroid Build Coastguard Worker CurPtr++;
554*9880d681SAndroid Build Coastguard Worker if (SkipSpace)
555*9880d681SAndroid Build Coastguard Worker return LexToken(); // Ignore whitespace.
556*9880d681SAndroid Build Coastguard Worker else
557*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Space, StringRef(TokStart, CurPtr - TokStart));
558*9880d681SAndroid Build Coastguard Worker case '\n':
559*9880d681SAndroid Build Coastguard Worker case '\r':
560*9880d681SAndroid Build Coastguard Worker IsAtStartOfLine = true;
561*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = true;
562*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
563*9880d681SAndroid Build Coastguard Worker case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
564*9880d681SAndroid Build Coastguard Worker case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
565*9880d681SAndroid Build Coastguard Worker case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
566*9880d681SAndroid Build Coastguard Worker case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1));
567*9880d681SAndroid Build Coastguard Worker case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1));
568*9880d681SAndroid Build Coastguard Worker case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1));
569*9880d681SAndroid Build Coastguard Worker case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1));
570*9880d681SAndroid Build Coastguard Worker case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1));
571*9880d681SAndroid Build Coastguard Worker case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1));
572*9880d681SAndroid Build Coastguard Worker case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1));
573*9880d681SAndroid Build Coastguard Worker case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
574*9880d681SAndroid Build Coastguard Worker case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
575*9880d681SAndroid Build Coastguard Worker case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
576*9880d681SAndroid Build Coastguard Worker case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1));
577*9880d681SAndroid Build Coastguard Worker case '\\': return AsmToken(AsmToken::BackSlash, StringRef(TokStart, 1));
578*9880d681SAndroid Build Coastguard Worker case '=':
579*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '=') {
580*9880d681SAndroid Build Coastguard Worker ++CurPtr;
581*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
582*9880d681SAndroid Build Coastguard Worker }
583*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
584*9880d681SAndroid Build Coastguard Worker case '|':
585*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '|') {
586*9880d681SAndroid Build Coastguard Worker ++CurPtr;
587*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
588*9880d681SAndroid Build Coastguard Worker }
589*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
590*9880d681SAndroid Build Coastguard Worker case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
591*9880d681SAndroid Build Coastguard Worker case '&':
592*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '&') {
593*9880d681SAndroid Build Coastguard Worker ++CurPtr;
594*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
595*9880d681SAndroid Build Coastguard Worker }
596*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
597*9880d681SAndroid Build Coastguard Worker case '!':
598*9880d681SAndroid Build Coastguard Worker if (*CurPtr == '=') {
599*9880d681SAndroid Build Coastguard Worker ++CurPtr;
600*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
601*9880d681SAndroid Build Coastguard Worker }
602*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
603*9880d681SAndroid Build Coastguard Worker case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
604*9880d681SAndroid Build Coastguard Worker case '/':
605*9880d681SAndroid Build Coastguard Worker IsAtStartOfStatement = OldIsAtStartOfStatement;
606*9880d681SAndroid Build Coastguard Worker return LexSlash();
607*9880d681SAndroid Build Coastguard Worker case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
608*9880d681SAndroid Build Coastguard Worker case '\'': return LexSingleQuote();
609*9880d681SAndroid Build Coastguard Worker case '"': return LexQuote();
610*9880d681SAndroid Build Coastguard Worker case '0': case '1': case '2': case '3': case '4':
611*9880d681SAndroid Build Coastguard Worker case '5': case '6': case '7': case '8': case '9':
612*9880d681SAndroid Build Coastguard Worker return LexDigit();
613*9880d681SAndroid Build Coastguard Worker case '<':
614*9880d681SAndroid Build Coastguard Worker switch (*CurPtr) {
615*9880d681SAndroid Build Coastguard Worker case '<':
616*9880d681SAndroid Build Coastguard Worker ++CurPtr;
617*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::LessLess, StringRef(TokStart, 2));
618*9880d681SAndroid Build Coastguard Worker case '=':
619*9880d681SAndroid Build Coastguard Worker ++CurPtr;
620*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::LessEqual, StringRef(TokStart, 2));
621*9880d681SAndroid Build Coastguard Worker case '>':
622*9880d681SAndroid Build Coastguard Worker ++CurPtr;
623*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::LessGreater, StringRef(TokStart, 2));
624*9880d681SAndroid Build Coastguard Worker default:
625*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
626*9880d681SAndroid Build Coastguard Worker }
627*9880d681SAndroid Build Coastguard Worker case '>':
628*9880d681SAndroid Build Coastguard Worker switch (*CurPtr) {
629*9880d681SAndroid Build Coastguard Worker case '>':
630*9880d681SAndroid Build Coastguard Worker ++CurPtr;
631*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::GreaterGreater, StringRef(TokStart, 2));
632*9880d681SAndroid Build Coastguard Worker case '=':
633*9880d681SAndroid Build Coastguard Worker ++CurPtr;
634*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::GreaterEqual, StringRef(TokStart, 2));
635*9880d681SAndroid Build Coastguard Worker default:
636*9880d681SAndroid Build Coastguard Worker return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
637*9880d681SAndroid Build Coastguard Worker }
638*9880d681SAndroid Build Coastguard Worker
639*9880d681SAndroid Build Coastguard Worker // TODO: Quoted identifiers (objc methods etc)
640*9880d681SAndroid Build Coastguard Worker // local labels: [0-9][:]
641*9880d681SAndroid Build Coastguard Worker // Forward/backward labels: [0-9][fb]
642*9880d681SAndroid Build Coastguard Worker // Integers, fp constants, character constants.
643*9880d681SAndroid Build Coastguard Worker }
644*9880d681SAndroid Build Coastguard Worker }
645