xref: /aosp_15_r20/external/llvm/lib/MC/MCParser/AsmLexer.cpp (revision 9880d6810fe72a1726cb53787c6711e909410d58)
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