1a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//===- AsmLexer.cpp - Lexer for Assembly Files ----------------------------===//
2a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//
3a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//                     The LLVM Compiler Infrastructure
4a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//
5a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner// This file is distributed under the University of Illinois Open Source
6a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner// License. See LICENSE.TXT for details.
7a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//
8a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//===----------------------------------------------------------------------===//
9a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//
10a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner// This class implements the lexer for assembly files.
11a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//
12a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner//===----------------------------------------------------------------------===//
13a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
14be343b3ca3f53d5d5e29f3591af8b9bb831daa98Chris Lattner#include "llvm/MC/MCParser/AsmLexer.h"
15fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan#include "llvm/Support/SMLoc.h"
16a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner#include "llvm/Support/MemoryBuffer.h"
179823ca971d5cb475401e59fde244caf5087c74a1Kevin Enderby#include "llvm/MC/MCAsmInfo.h"
18476b242fe7a61e5f9ac6214b0bc5c680d24f152eNick Lewycky#include <cctype>
194651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner#include <cerrno>
2066b9f29df22a84f25007c1a84b4d0bb8060552b9Duncan Sands#include <cstdio>
214506bd2cfd3e75535670890031eec26e216993b8Chris Lattner#include <cstdlib>
22a59e8779964992457ada1af6a5f48068523cfd42Chris Lattnerusing namespace llvm;
23a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
24fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean CallananAsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI)  {
25fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  CurBuf = NULL;
26fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  CurPtr = NULL;
276148225b9590f18fcb6a1d3151d3158b316965e0Jim Grosbach  isAtStartOfLine = true;
28faf32c102db556e367af1e5bca7359160840d2d0Chris Lattner}
29faf32c102db556e367af1e5bca7359160840d2d0Chris Lattner
30faf32c102db556e367af1e5bca7359160840d2d0Chris LattnerAsmLexer::~AsmLexer() {
31a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner}
32a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
33fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callananvoid AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) {
34fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  CurBuf = buf;
35de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
36fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  if (ptr)
37fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan    CurPtr = ptr;
38fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  else
39fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan    CurPtr = CurBuf->getBufferStart();
40de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
41fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  TokStart = 0;
42fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan}
43fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan
444651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner/// ReturnError - Set the error to the specified string at the specified
453f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar/// location.  This is defined to always return AsmToken::Error.
46cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::ReturnError(const char *Loc, const std::string &Msg) {
4779036e421f22cf3f661386c560fda36aa5bd04ccSean Callanan  SetError(SMLoc::getFromPointer(Loc), Msg);
48de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
493f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  return AsmToken(AsmToken::Error, StringRef(Loc, 0));
504651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner}
514651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
52a59e8779964992457ada1af6a5f48068523cfd42Chris Lattnerint AsmLexer::getNextChar() {
53a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  char CurChar = *CurPtr++;
54a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  switch (CurChar) {
55a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  default:
56a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    return (unsigned char)CurChar;
57fd0b0288e2ee5ccf3f1d47090542710c67a77cf7Sean Callanan  case 0:
58a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    // A nul character in the stream is either the end of the current buffer or
59a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    // a random nul in the file.  Disambiguate that here.
60a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    if (CurPtr-1 != CurBuf->getBufferEnd())
61a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner      return 0;  // Just whitespace.
62de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
63a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    // Otherwise, return end of file.
64de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach    --CurPtr;  // Another call to lex will return EOF again.
65a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    return EOF;
66a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  }
67a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner}
68a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner
694f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)?
704f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar///
714f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar/// The leading integral digit sequence and dot should have already been
724f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar/// consumed, some or all of the fractional digit sequence *can* have been
734f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar/// consumed.
744f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel DunbarAsmToken AsmLexer::LexFloatLiteral() {
754f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  // Skip the fractional digit sequence.
764f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  while (isdigit(*CurPtr))
774f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    ++CurPtr;
784f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar
794f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  // Check for exponent; we intentionally accept a slighlty wider set of
804f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  // literals here and rely on the upstream client to reject invalid ones (e.g.,
814f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  // "1e+").
824f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  if (*CurPtr == 'e' || *CurPtr == 'E') {
834f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    ++CurPtr;
844f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    if (*CurPtr == '-' || *CurPtr == '+')
854f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar      ++CurPtr;
864f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    while (isdigit(*CurPtr))
874f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar      ++CurPtr;
884f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  }
894f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar
904f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar  return AsmToken(AsmToken::Real,
914f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar                  StringRef(TokStart, CurPtr - TokStart));
924f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar}
934f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar
945fe03c023cd47a718759a3a4dc1d8e33297ae0fcDaniel Dunbar/// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
9554f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbarstatic bool IsIdentifierChar(char c) {
9654f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar  return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@';
9754f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar}
98cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::LexIdentifier() {
9954f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar  // Check for floating point literals.
10054f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar  if (CurPtr[-1] == '.' && isdigit(*CurPtr)) {
1014f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    // Disambiguate a .1243foo identifier from a floating literal.
10254f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar    while (isdigit(*CurPtr))
10354f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar      ++CurPtr;
1044f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    if (*CurPtr == 'e' || *CurPtr == 'E' || !IsIdentifierChar(*CurPtr))
1054f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar      return LexFloatLiteral();
10654f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar  }
10754f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar
10854f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar  while (IsIdentifierChar(*CurPtr))
1094651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    ++CurPtr;
110de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
111d305035155ef3d138e102434bf5a733ea2e32405Chris Lattner  // Handle . as a special case.
1125fe03c023cd47a718759a3a4dc1d8e33297ae0fcDaniel Dunbar  if (CurPtr == TokStart+1 && TokStart[0] == '.')
1135fe03c023cd47a718759a3a4dc1d8e33297ae0fcDaniel Dunbar    return AsmToken(AsmToken::Dot, StringRef(TokStart, 1));
114de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
1153f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  return AsmToken(AsmToken::Identifier, StringRef(TokStart, CurPtr - TokStart));
1164651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner}
1174651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
1184651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner/// LexSlash: Slash: /
1194651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///           C-Style Comment: /* ... */
120cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::LexSlash() {
121383a4a8db04456b8e5a59a35b3f967c4aa9c90cfDaniel Dunbar  switch (*CurPtr) {
122383a4a8db04456b8e5a59a35b3f967c4aa9c90cfDaniel Dunbar  case '*': break; // C style comment.
123383a4a8db04456b8e5a59a35b3f967c4aa9c90cfDaniel Dunbar  case '/': return ++CurPtr, LexLineComment();
124bdf90d679befafe70b93082042266ba58a9ad0b2Daniel Dunbar  default:  return AsmToken(AsmToken::Slash, StringRef(CurPtr-1, 1));
125383a4a8db04456b8e5a59a35b3f967c4aa9c90cfDaniel Dunbar  }
1264651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
1274651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // C Style comment.
1284651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  ++CurPtr;  // skip the star.
1294651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  while (1) {
1304651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    int CurChar = getNextChar();
1314651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    switch (CurChar) {
1324651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case EOF:
13327aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner      return ReturnError(TokStart, "unterminated comment");
1344651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    case '*':
1354651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      // End of the comment?
1364651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      if (CurPtr[0] != '/') break;
137de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
1384651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      ++CurPtr;   // End the */.
1394651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      return LexToken();
1404651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    }
1414651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  }
1424651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner}
1434651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
144383a4a8db04456b8e5a59a35b3f967c4aa9c90cfDaniel Dunbar/// LexLineComment: Comment: #[^\n]*
145383a4a8db04456b8e5a59a35b3f967c4aa9c90cfDaniel Dunbar///                        : //[^\n]*
146cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::LexLineComment() {
147cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar  // FIXME: This is broken if we happen to a comment at the end of a file, which
148cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar  // was .included, and which doesn't end with a newline.
1494651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  int CurChar = getNextChar();
1500ecd825e54f2235c133b44c967a612551633106cChris Lattner  while (CurChar != '\n' && CurChar != '\r' && CurChar != EOF)
1514651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    CurChar = getNextChar();
152de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
1534651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  if (CurChar == EOF)
1543f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0));
1553f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0));
1564651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner}
1574651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
158a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattnerstatic void SkipIgnoredIntegerSuffix(const char *&CurPtr) {
159a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner  if (CurPtr[0] == 'L' && CurPtr[1] == 'L')
160a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    CurPtr += 2;
161a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner  if (CurPtr[0] == 'U' && CurPtr[1] == 'L' && CurPtr[2] == 'L')
162a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    CurPtr += 3;
163a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner}
164a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner
1654651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner/// LexDigit: First character is [0-9].
1664651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///   Local Label: [0-9][:]
1674651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///   Forward/Backward Label: [0-9][fb]
1684651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///   Binary integer: 0b[01]+
1694651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///   Octal integer: 0[0-7]+
1704651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///   Hex integer: 0x[0-9a-fA-F]+
1714651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner///   Decimal integer: [1-9][0-9]*
172cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::LexDigit() {
1734651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // Decimal integer: [1-9][0-9]*
174facb34b41cea284b5a0b4992ff619e5cfd5e6a22Daniel Dunbar  if (CurPtr[-1] != '0' || CurPtr[0] == '.') {
1754651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    while (isdigit(*CurPtr))
1764651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      ++CurPtr;
17754f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar
17854f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar    // Check for floating point literals.
1794f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar    if (*CurPtr == '.' || *CurPtr == 'e') {
18054f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar      ++CurPtr;
1814f2afe3d399eb9485dc605f3cc3a6382dcae757aDaniel Dunbar      return LexFloatLiteral();
18254f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar    }
18354f0a625b0eb9afeece652a8462755010d237c78Daniel Dunbar
184d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner    StringRef Result(TokStart, CurPtr - TokStart);
185a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner
186d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner    long long Value;
1873a151be8d5f85ca12737f5664ef91192014a4f77Chris Lattner    if (Result.getAsInteger(10, Value)) {
1887ab3cc32d6bd3c3166184e27713c91f5317c7f85Chris Lattner      // Allow positive values that are too large to fit into a signed 64-bit
1897ab3cc32d6bd3c3166184e27713c91f5317c7f85Chris Lattner      // integer, but that do fit in an unsigned one, we just convert them over.
1907ab3cc32d6bd3c3166184e27713c91f5317c7f85Chris Lattner      unsigned long long UValue;
1917ab3cc32d6bd3c3166184e27713c91f5317c7f85Chris Lattner      if (Result.getAsInteger(10, UValue))
1927ab3cc32d6bd3c3166184e27713c91f5317c7f85Chris Lattner        return ReturnError(TokStart, "invalid decimal number");
1937ab3cc32d6bd3c3166184e27713c91f5317c7f85Chris Lattner      Value = (long long)UValue;
1943a151be8d5f85ca12737f5664ef91192014a4f77Chris Lattner    }
195de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
196a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
197a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    // suffixes on integer literals.
198a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    SkipIgnoredIntegerSuffix(CurPtr);
199de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
200d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner    return AsmToken(AsmToken::Integer, Result, Value);
2014651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  }
202de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
2034651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  if (*CurPtr == 'b') {
2044651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    ++CurPtr;
205ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby    // See if we actually have "0b" as part of something like "jmp 0b\n"
2069f2ad11624ebc73963007ee02958a9b41962422fKevin Enderby    if (!isdigit(CurPtr[0])) {
207ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby      --CurPtr;
208ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby      StringRef Result(TokStart, CurPtr - TokStart);
209ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby      return AsmToken(AsmToken::Integer, Result, 0);
210ebe7fcd041e1e9c3a0c535b26d8cdb45805bbeb8Kevin Enderby    }
2114651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    const char *NumStart = CurPtr;
2124651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    while (CurPtr[0] == '0' || CurPtr[0] == '1')
2134651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      ++CurPtr;
214de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
2154651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    // Requires at least one binary digit.
2164651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    if (CurPtr == NumStart)
21705f9e4e8bd2347826c50ec391ea4ec8caffe45efEric Christopher      return ReturnError(TokStart, "invalid binary number");
218de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
219d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner    StringRef Result(TokStart, CurPtr - TokStart);
220de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
221d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner    long long Value;
222a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    if (Result.substr(2).getAsInteger(2, Value))
22305f9e4e8bd2347826c50ec391ea4ec8caffe45efEric Christopher      return ReturnError(TokStart, "invalid binary number");
224de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
225a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
226a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    // suffixes on integer literals.
227a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    SkipIgnoredIntegerSuffix(CurPtr);
228de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
229d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner    return AsmToken(AsmToken::Integer, Result, Value);
2304651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  }
231de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
2324651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  if (*CurPtr == 'x') {
2334651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    ++CurPtr;
2344651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    const char *NumStart = CurPtr;
2354651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    while (isxdigit(CurPtr[0]))
2364651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      ++CurPtr;
237de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
2384651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    // Requires at least one hex digit.
2394651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    if (CurPtr == NumStart)
24005f9e4e8bd2347826c50ec391ea4ec8caffe45efEric Christopher      return ReturnError(CurPtr-2, "invalid hexadecimal number");
24103949c9db3e8f02d6ec7cd53782507e3a4e9e4fcChris Lattner
24203949c9db3e8f02d6ec7cd53782507e3a4e9e4fcChris Lattner    unsigned long long Result;
24303949c9db3e8f02d6ec7cd53782507e3a4e9e4fcChris Lattner    if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
24405f9e4e8bd2347826c50ec391ea4ec8caffe45efEric Christopher      return ReturnError(TokStart, "invalid hexadecimal number");
245de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
246a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
247a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    // suffixes on integer literals.
248a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner    SkipIgnoredIntegerSuffix(CurPtr);
249de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
2503f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
25103949c9db3e8f02d6ec7cd53782507e3a4e9e4fcChris Lattner                    (int64_t)Result);
2524651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  }
253de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
2544651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // Must be an octal number, it starts with 0.
255120fd2dd6dd00dfab002ad4d6a39e0445dd6894dEric Christopher  while (*CurPtr >= '0' && *CurPtr <= '9')
2564651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    ++CurPtr;
257de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
258d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner  StringRef Result(TokStart, CurPtr - TokStart);
259d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner  long long Value;
260d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner  if (Result.getAsInteger(8, Value))
26105f9e4e8bd2347826c50ec391ea4ec8caffe45efEric Christopher    return ReturnError(TokStart, "invalid octal number");
262de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
263a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner  // The darwin/x86 (and x86-64) assembler accepts and ignores ULL and LL
264a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner  // suffixes on integer literals.
265a78c67e9bbf6ff0253945f3ba5bc178ece76d886Chris Lattner  SkipIgnoredIntegerSuffix(CurPtr);
266de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
267d5a7e357a22b2e916a5b5e9d200ad284b95e35f1Chris Lattner  return AsmToken(AsmToken::Integer, Result, Value);
2684651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner}
2694651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
2707529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky/// LexSingleQuote: Integer: 'b'
2717529b164104f802b59fbf96f5a88d9709ac3ff1aRoman DivackyAsmToken AsmLexer::LexSingleQuote() {
2727529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  int CurChar = getNextChar();
2737529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
2747529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  if (CurChar == '\\')
2757529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    CurChar = getNextChar();
2767529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
2777529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  if (CurChar == EOF)
2787529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    return ReturnError(TokStart, "unterminated single quote");
2797529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
2807529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  CurChar = getNextChar();
2817529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
2827529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  if (CurChar != '\'')
2837529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    return ReturnError(TokStart, "single quote way too long");
2847529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
2857529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  // The idea here being that 'c' is basically just an integral
2867529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  // constant.
2877529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  StringRef Res = StringRef(TokStart,CurPtr - TokStart);
2887529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  long long Value;
2897529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
2907529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  if (Res.startswith("\'\\")) {
2917529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    char theChar = Res[2];
2927529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    switch (theChar) {
2937529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky      default: Value = theChar; break;
2947529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky      case '\'': Value = '\''; break;
2957529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky      case 't': Value = '\t'; break;
2967529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky      case 'n': Value = '\n'; break;
2977529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky      case 'b': Value = '\b'; break;
2987529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    }
2997529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  } else
3007529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky    Value = TokStart[1];
3017529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
302de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach  return AsmToken(AsmToken::Integer, Res, Value);
3037529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky}
3047529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
3057529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky
30610a907d70fb54c40eecabb889e81c79b44092221Chris Lattner/// LexQuote: String: "..."
307cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::LexQuote() {
30810a907d70fb54c40eecabb889e81c79b44092221Chris Lattner  int CurChar = getNextChar();
30910a907d70fb54c40eecabb889e81c79b44092221Chris Lattner  // TODO: does gas allow multiline string constants?
31010a907d70fb54c40eecabb889e81c79b44092221Chris Lattner  while (CurChar != '"') {
31110a907d70fb54c40eecabb889e81c79b44092221Chris Lattner    if (CurChar == '\\') {
31210a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      // Allow \", etc.
31310a907d70fb54c40eecabb889e81c79b44092221Chris Lattner      CurChar = getNextChar();
31410a907d70fb54c40eecabb889e81c79b44092221Chris Lattner    }
315de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
31614ee48a5bae352780b767a14bd97e8e91800a95bChris Lattner    if (CurChar == EOF)
31714ee48a5bae352780b767a14bd97e8e91800a95bChris Lattner      return ReturnError(TokStart, "unterminated string constant");
31810a907d70fb54c40eecabb889e81c79b44092221Chris Lattner
31910a907d70fb54c40eecabb889e81c79b44092221Chris Lattner    CurChar = getNextChar();
32010a907d70fb54c40eecabb889e81c79b44092221Chris Lattner  }
321de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
3223f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  return AsmToken(AsmToken::String, StringRef(TokStart, CurPtr - TokStart));
32310a907d70fb54c40eecabb889e81c79b44092221Chris Lattner}
32410a907d70fb54c40eecabb889e81c79b44092221Chris Lattner
325ff4bc460c52c1f285d8a56da173641bf92d49e3fChris LattnerStringRef AsmLexer::LexUntilEndOfStatement() {
326ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner  TokStart = CurPtr;
327ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner
328d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach  while (!isAtStartOfComment(*CurPtr) &&    // Start of line comment.
329d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach         !isAtStatementSeparator(CurPtr) && // End of statement marker.
330ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner         *CurPtr != '\n' &&
331ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner         *CurPtr != '\r' &&
3329823ca971d5cb475401e59fde244caf5087c74a1Kevin Enderby         (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
333ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner    ++CurPtr;
3349823ca971d5cb475401e59fde244caf5087c74a1Kevin Enderby  }
335ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner  return StringRef(TokStart, CurPtr-TokStart);
336ff4bc460c52c1f285d8a56da173641bf92d49e3fChris Lattner}
3374651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner
338f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin EnderbyStringRef AsmLexer::LexUntilEndOfLine() {
339f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby  TokStart = CurPtr;
340f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby
341f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby  while (*CurPtr != '\n' &&
342f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby         *CurPtr != '\r' &&
343f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby         (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) {
344f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    ++CurPtr;
345f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby  }
346f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby  return StringRef(TokStart, CurPtr-TokStart);
347f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby}
348f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby
349b5db83084073d74501f3e2a7684d28240a047b92Kevin Enderbybool AsmLexer::isAtStartOfComment(char Char) {
350cec545097cf1a81c0936cf62e39a81940d9f720fChris Lattner  // FIXME: This won't work for multi-character comment indicators like "//".
351cec545097cf1a81c0936cf62e39a81940d9f720fChris Lattner  return Char == *MAI.getCommentString();
352b5db83084073d74501f3e2a7684d28240a047b92Kevin Enderby}
353b5db83084073d74501f3e2a7684d28240a047b92Kevin Enderby
354d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbachbool AsmLexer::isAtStatementSeparator(const char *Ptr) {
355d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach  return strncmp(Ptr, MAI.getSeparatorString(),
356d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach                 strlen(MAI.getSeparatorString())) == 0;
357d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach}
358d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach
359cb358b63a742c72f440ea008f14d65e049e725adDaniel DunbarAsmToken AsmLexer::LexToken() {
360a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  TokStart = CurPtr;
361a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  // This always consumes at least one character.
362a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  int CurChar = getNextChar();
363de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
364f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby  if (isAtStartOfComment(CurChar)) {
365f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    // If this comment starts with a '#', then return the Hash token and let
366f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    // the assembler parser see if it can be parsed as a cpp line filename
367f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    // comment. We do this only if we are at the start of a line.
368f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    if (CurChar == '#' && isAtStartOfLine)
369f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby      return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
370f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    isAtStartOfLine = true;
371b5db83084073d74501f3e2a7684d28240a047b92Kevin Enderby    return LexLineComment();
372f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby  }
373d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach  if (isAtStatementSeparator(TokStart)) {
374d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach    CurPtr += strlen(MAI.getSeparatorString()) - 1;
375d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach    return AsmToken(AsmToken::EndOfStatement,
376d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach                    StringRef(TokStart, strlen(MAI.getSeparatorString())));
377d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach  }
3789823ca971d5cb475401e59fde244caf5087c74a1Kevin Enderby
37970796ca867132fd8c767301061afb9760cd69167Jim Grosbach  // If we're missing a newline at EOF, make sure we still get an
38070796ca867132fd8c767301061afb9760cd69167Jim Grosbach  // EndOfStatement token before the Eof token.
38170796ca867132fd8c767301061afb9760cd69167Jim Grosbach  if (CurChar == EOF && !isAtStartOfLine) {
38270796ca867132fd8c767301061afb9760cd69167Jim Grosbach    isAtStartOfLine = true;
38370796ca867132fd8c767301061afb9760cd69167Jim Grosbach    return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
38470796ca867132fd8c767301061afb9760cd69167Jim Grosbach  }
38570796ca867132fd8c767301061afb9760cd69167Jim Grosbach
38670796ca867132fd8c767301061afb9760cd69167Jim Grosbach  isAtStartOfLine = false;
387a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  switch (CurChar) {
388a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  default:
3895fe03c023cd47a718759a3a4dc1d8e33297ae0fcDaniel Dunbar    // Handle identifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
3905fe03c023cd47a718759a3a4dc1d8e33297ae0fcDaniel Dunbar    if (isalpha(CurChar) || CurChar == '_' || CurChar == '.')
3914651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner      return LexIdentifier();
392de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
393a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    // Unknown character, emit an error.
39427aa7d259b416a9d1bf837ed2c3c11463367b11cChris Lattner    return ReturnError(TokStart, "invalid character in input");
3953f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case EOF: return AsmToken(AsmToken::Eof, StringRef(TokStart, 0));
396a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  case 0:
397a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  case ' ':
398a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  case '\t':
399a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    // Ignore whitespace.
400a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner    return LexToken();
4014651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  case '\n': // FALL THROUGH.
402d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach  case '\r':
403f1c21a8da6ed27a6ab4944e30bbeb4bd3ee08a71Kevin Enderby    isAtStartOfLine = true;
404d31d304f83f9c8df6870057509414b8d004bc8daJim Grosbach    return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 1));
4053f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case ':': return AsmToken(AsmToken::Colon, StringRef(TokStart, 1));
4063f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case '+': return AsmToken(AsmToken::Plus, StringRef(TokStart, 1));
4073f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case '-': return AsmToken(AsmToken::Minus, StringRef(TokStart, 1));
4083f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case '~': return AsmToken(AsmToken::Tilde, StringRef(TokStart, 1));
4093f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case '(': return AsmToken(AsmToken::LParen, StringRef(TokStart, 1));
4103f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case ')': return AsmToken(AsmToken::RParen, StringRef(TokStart, 1));
411fb0f0dedd74dab13737a77671a724ee88465f5daKevin Enderby  case '[': return AsmToken(AsmToken::LBrac, StringRef(TokStart, 1));
412fb0f0dedd74dab13737a77671a724ee88465f5daKevin Enderby  case ']': return AsmToken(AsmToken::RBrac, StringRef(TokStart, 1));
413fb0f0dedd74dab13737a77671a724ee88465f5daKevin Enderby  case '{': return AsmToken(AsmToken::LCurly, StringRef(TokStart, 1));
414fb0f0dedd74dab13737a77671a724ee88465f5daKevin Enderby  case '}': return AsmToken(AsmToken::RCurly, StringRef(TokStart, 1));
4153f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case '*': return AsmToken(AsmToken::Star, StringRef(TokStart, 1));
4163f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case ',': return AsmToken(AsmToken::Comma, StringRef(TokStart, 1));
4175fe03c023cd47a718759a3a4dc1d8e33297ae0fcDaniel Dunbar  case '$': return AsmToken(AsmToken::Dollar, StringRef(TokStart, 1));
418924c5e58f2a7c89019000e7dee3391dcebdf8a21Matt Fleming  case '@': return AsmToken(AsmToken::At, StringRef(TokStart, 1));
419653664471333f316020e96dd3d664f4984f66a65Rafael Espindola  case '\\': return AsmToken(AsmToken::BackSlash, StringRef(TokStart, 1));
420de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach  case '=':
421475839e9a97a0c0282e107d14fd1dc6e5f223435Daniel Dunbar    if (*CurPtr == '=')
4223f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar      return ++CurPtr, AsmToken(AsmToken::EqualEqual, StringRef(TokStart, 2));
4233f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    return AsmToken(AsmToken::Equal, StringRef(TokStart, 1));
424de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach  case '|':
425475839e9a97a0c0282e107d14fd1dc6e5f223435Daniel Dunbar    if (*CurPtr == '|')
4263f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar      return ++CurPtr, AsmToken(AsmToken::PipePipe, StringRef(TokStart, 2));
4273f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    return AsmToken(AsmToken::Pipe, StringRef(TokStart, 1));
4283f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar  case '^': return AsmToken(AsmToken::Caret, StringRef(TokStart, 1));
429de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach  case '&':
430475839e9a97a0c0282e107d14fd1dc6e5f223435Daniel Dunbar    if (*CurPtr == '&')
4313f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar      return ++CurPtr, AsmToken(AsmToken::AmpAmp, StringRef(TokStart, 2));
4323f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    return AsmToken(AsmToken::Amp, StringRef(TokStart, 1));
433de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach  case '!':
434475839e9a97a0c0282e107d14fd1dc6e5f223435Daniel Dunbar    if (*CurPtr == '=')
4353f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar      return ++CurPtr, AsmToken(AsmToken::ExclaimEqual, StringRef(TokStart, 2));
4363f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    return AsmToken(AsmToken::Exclaim, StringRef(TokStart, 1));
4377b4608dfa018455021050ccd31d3c49aaecf7ff6Kevin Enderby  case '%': return AsmToken(AsmToken::Percent, StringRef(TokStart, 1));
4384651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  case '/': return LexSlash();
4399823ca971d5cb475401e59fde244caf5087c74a1Kevin Enderby  case '#': return AsmToken(AsmToken::Hash, StringRef(TokStart, 1));
4407529b164104f802b59fbf96f5a88d9709ac3ff1aRoman Divacky  case '\'': return LexSingleQuote();
44110a907d70fb54c40eecabb889e81c79b44092221Chris Lattner  case '"': return LexQuote();
4424651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  case '0': case '1': case '2': case '3': case '4':
4434651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  case '5': case '6': case '7': case '8': case '9':
4444651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner    return LexDigit();
4458dfbe6c853e3e48b6e7b5957a4e028835ffe4400Chris Lattner  case '<':
446475839e9a97a0c0282e107d14fd1dc6e5f223435Daniel Dunbar    switch (*CurPtr) {
447de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach    case '<': return ++CurPtr, AsmToken(AsmToken::LessLess,
448cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar                                        StringRef(TokStart, 2));
449de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach    case '=': return ++CurPtr, AsmToken(AsmToken::LessEqual,
450cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar                                        StringRef(TokStart, 2));
451de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach    case '>': return ++CurPtr, AsmToken(AsmToken::LessGreater,
452cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar                                        StringRef(TokStart, 2));
4533f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    default: return AsmToken(AsmToken::Less, StringRef(TokStart, 1));
4548dfbe6c853e3e48b6e7b5957a4e028835ffe4400Chris Lattner    }
4558dfbe6c853e3e48b6e7b5957a4e028835ffe4400Chris Lattner  case '>':
456475839e9a97a0c0282e107d14fd1dc6e5f223435Daniel Dunbar    switch (*CurPtr) {
457de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach    case '>': return ++CurPtr, AsmToken(AsmToken::GreaterGreater,
458cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar                                        StringRef(TokStart, 2));
459de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach    case '=': return ++CurPtr, AsmToken(AsmToken::GreaterEqual,
460cb358b63a742c72f440ea008f14d65e049e725adDaniel Dunbar                                        StringRef(TokStart, 2));
4613f87233d700eb4316cfaad59477834d2f5a2503bDaniel Dunbar    default: return AsmToken(AsmToken::Greater, StringRef(TokStart, 1));
4628dfbe6c853e3e48b6e7b5957a4e028835ffe4400Chris Lattner    }
463de2f5f423bc87f6f1ee0d02862b00cc32940a93aJim Grosbach
4644651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // TODO: Quoted identifiers (objc methods etc)
4654651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // local labels: [0-9][:]
4664651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // Forward/backward labels: [0-9][fb]
4674651bca31bdad27184fa0d36640bf5ef1d83cf5cChris Lattner  // Integers, fp constants, character constants.
468a59e8779964992457ada1af6a5f48068523cfd42Chris Lattner  }
46966b9f29df22a84f25007c1a84b4d0bb8060552b9Duncan Sands}
470