TGLexer.cpp revision 63f97201dc9dcebbe84d1b73113166c64212b4b8
1a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===- TGLexer.cpp - Lexer for TableGen -----------------------------------===// 2a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 3a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// The LLVM Compiler Infrastructure 4a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 5a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// This file is distributed under the University of Illinois Open Source 6a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// License. See LICENSE.TXT for details. 7a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 8a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===// 9a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 10a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// Implement the Lexer for TableGen. 11a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner// 12a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner//===----------------------------------------------------------------------===// 13a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 146aaca046d2896d8396314f4b1b6ad7a000034330Chris Lattner#include "TGLexer.h" 15a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Support/Streams.h" 16a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Support/MemoryBuffer.h" 17a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <ostream> 18a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include "llvm/Config/config.h" 19a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cctype> 20a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cstdio> 21a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cstdlib> 22a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cstring> 23a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner#include <cerrno> 24a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerusing namespace llvm; 25a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 26a8058744229a44e80f90c8530bb7fe47cbab1b70Chris LattnerTGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) { 27a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = CurBuf->getBufferStart(); 28a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner TokStart = 0; 29a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 30a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 31a8058744229a44e80f90c8530bb7fe47cbab1b70Chris LattnerTGLexer::~TGLexer() { 32a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (!IncludeStack.empty()) { 33a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner delete IncludeStack.back().Buffer; 34a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner IncludeStack.pop_back(); 35a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 36a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner delete CurBuf; 37a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 38a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 39a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// ReturnError - Set the error to the specified string at the specified 40c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// location. This is defined to always return tgtok::Error. 41c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnertgtok::TokKind TGLexer::ReturnError(const char *Loc, const std::string &Msg) { 42c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner PrintError(Loc, Msg); 43c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return tgtok::Error; 44c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner} 45c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 46a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid TGLexer::PrintIncludeStack(std::ostream &OS) const { 47c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i) 48a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier() 49a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner << ":" << IncludeStack[i].LineNo << ":\n"; 50a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner OS << "Parsing " << CurBuf->getBufferIdentifier() << ":" 51a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner << CurLineNo << ": "; 52a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 53c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 54a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// PrintError - Print the error at the specified location. 55a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid TGLexer::PrintError(const char *ErrorLoc, const std::string &Msg) const { 56a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner PrintIncludeStack(*cerr.stream()); 57a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner cerr << Msg << "\n"; 58a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner assert(ErrorLoc && "Location not specified!"); 59a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 60a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Scan backward to find the start of the line. 61c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner const char *LineStart = ErrorLoc; 62c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner while (LineStart != CurBuf->getBufferStart() && 63c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner LineStart[-1] != '\n' && LineStart[-1] != '\r') 64c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner --LineStart; 65c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Get the end of the line. 66c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner const char *LineEnd = ErrorLoc; 67c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner while (LineEnd != CurBuf->getBufferEnd() && 68c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner LineEnd[0] != '\n' && LineEnd[0] != '\r') 69c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner ++LineEnd; 70c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Print out the line. 71c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner cerr << std::string(LineStart, LineEnd) << "\n"; 72c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // Print out spaces before the carat. 73c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner for (const char *Pos = LineStart; Pos != ErrorLoc; ++Pos) 74c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner cerr << (*Pos == '\t' ? '\t' : ' '); 75c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner cerr << "^\n"; 76c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner} 77c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 78c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnerint TGLexer::getNextChar() { 79c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner char CurChar = *CurPtr++; 80c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner switch (CurChar) { 81c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner default: 82c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return (unsigned char)CurChar; 83c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner case 0: 84c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // A nul character in the stream is either the end of the current buffer or 85a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // a random nul in the file. Disambiguate that here. 86a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr-1 != CurBuf->getBufferEnd()) 87a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return 0; // Just whitespace. 88a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 89c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattner // If this is the end of an included file, pop the parent file off the 90a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // include stack. 91a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!IncludeStack.empty()) { 92a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner delete CurBuf; 93a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurBuf = IncludeStack.back().Buffer; 94a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurLineNo = IncludeStack.back().LineNo; 95a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = IncludeStack.back().CurPtr; 96a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner IncludeStack.pop_back(); 97a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return getNextChar(); 98a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 99a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 100a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, return end of file. 101a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner --CurPtr; // Another call to lex will return EOF again. 102a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return EOF; 103a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 104a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 105a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Handle the newline character by ignoring it and incrementing the line 106a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // count. However, be careful about 'dos style' files with \n\r in them. 107a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Only treat a \n\r or \r\n as a single line. 108a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if ((*CurPtr == '\n' || (*CurPtr == '\r')) && 109a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner *CurPtr != CurChar) 110a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // Eat the two char newline sequence. 111a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 112a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurLineNo; 113a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return '\n'; 114a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 115a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 116a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 117c1819188b6c971b91c680a9a3c077b84a110e5fdChris Lattnertgtok::TokKind TGLexer::LexToken() { 118a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner TokStart = CurPtr; 119a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // This always consumes at least one character. 120a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int CurChar = getNextChar(); 121a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 122a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 123a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner default: 124a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Handle letters: [a-zA-Z_] 125a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (isalpha(CurChar) || CurChar == '_') 126a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexIdentifier(); 127a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 128a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Unknown character, emit an error. 129a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(TokStart, "Unexpected character"); 130a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case EOF: return tgtok::Eof; 131a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ':': return tgtok::colon; 132a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ';': return tgtok::semi; 133a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '.': return tgtok::period; 134a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ',': return tgtok::comma; 135a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '<': return tgtok::less; 136a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '>': return tgtok::greater; 137a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ']': return tgtok::r_square; 138a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '{': return tgtok::l_brace; 139a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '}': return tgtok::r_brace; 140a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '(': return tgtok::l_paren; 141a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ')': return tgtok::r_paren; 142a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '=': return tgtok::equal; 143a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '?': return tgtok::question; 144a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 145a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case 0: 146a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case ' ': 147a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\t': 148a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 149a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 150a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Ignore whitespace. 151a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexToken(); 152a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '/': 153a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the start of a // comment, skip until the end of the line or 154a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // the end of the buffer. 155a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (*CurPtr == '/') 156a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner SkipBCPLComment(); 157a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner else if (*CurPtr == '*') { 158a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (SkipCComment()) 159a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::Error; 160a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } else // Otherwise, this is an error. 161a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(TokStart, "Unexpected character"); 162a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexToken(); 163a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '-': case '+': 164a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '0': case '1': case '2': case '3': case '4': case '5': case '6': 165a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '7': case '8': case '9': 166a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return LexNumber(); 167a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '"': return LexString(); 168a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '$': return LexVarName(); 169a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '[': return LexBracket(); 170a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '!': return LexExclaim(); 171a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 172c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner} 173c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 174c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner/// LexString - Lex "[^"]*" 175c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnertgtok::TokKind TGLexer::LexString() { 176c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner const char *StrStart = CurPtr; 177a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 178a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (*CurPtr != '"') { 179a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If we hit the end of the buffer, report an error. 180a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) 181a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(StrStart, "End of file in string literal"); 182a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 183a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (*CurPtr == '\n' || *CurPtr == '\r') 184a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(StrStart, "End of line in string literal"); 185a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 186a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 187a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 188a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 189a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurStrVal.assign(StrStart, CurPtr); 190a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 191a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::StrVal; 192a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 193a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 194a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnertgtok::TokKind TGLexer::LexVarName() { 195a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isalpha(CurPtr[0]) && CurPtr[0] != '_') 196a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(TokStart, "Invalid variable name"); 197a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 198a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, we're ok, consume the rest of the characters. 199a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *VarNameStart = CurPtr++; 200a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 201a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') 202a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 203a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 204a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurStrVal.assign(VarNameStart, CurPtr); 205a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::VarName; 206a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 207a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 208a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 209a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnertgtok::TokKind TGLexer::LexIdentifier() { 210a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // The first letter is [a-zA-Z_]. 211a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *IdentStart = TokStart; 212a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 213a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Match the rest of the identifier regex: [0-9a-zA-Z_]* 214a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') 215a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 216a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 217a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check to see if this identifier is a keyword. 218a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner unsigned Len = CurPtr-IdentStart; 219a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 220a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(IdentStart, "int", 3)) return tgtok::Int; 221a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(IdentStart, "bit", 3)) return tgtok::Bit; 222a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 4 && !memcmp(IdentStart, "bits", 4)) return tgtok::Bits; 223a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 6 && !memcmp(IdentStart, "string", 6)) return tgtok::String; 224a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 4 && !memcmp(IdentStart, "list", 4)) return tgtok::List; 225a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 4 && !memcmp(IdentStart, "code", 4)) return tgtok::Code; 226a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(IdentStart, "dag", 3)) return tgtok::Dag; 227a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 228a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 5 && !memcmp(IdentStart, "class", 5)) return tgtok::Class; 229a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(IdentStart, "def", 3)) return tgtok::Def; 230a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 4 && !memcmp(IdentStart, "defm", 4)) return tgtok::Defm; 231a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 10 && !memcmp(IdentStart, "multiclass", 10)) 232a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::MultiClass; 233a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 5 && !memcmp(IdentStart, "field", 5)) return tgtok::Field; 234a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(IdentStart, "let", 3)) return tgtok::Let; 235a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 2 && !memcmp(IdentStart, "in", 2)) return tgtok::In; 236a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 237a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 7 && !memcmp(IdentStart, "include", 7)) { 238a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (LexInclude()) return tgtok::Error; 239a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return Lex(); 240a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 241c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 242a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurStrVal.assign(IdentStart, CurPtr); 243a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::Id; 244a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 245c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 246a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexInclude - We just read the "include" token. Get the string token that 247a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// comes next and enter the include. 248a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::LexInclude() { 249a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // The token after the include must be a string. 250a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner tgtok::TokKind Tok = LexToken(); 251a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Tok == tgtok::Error) return true; 252a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Tok != tgtok::StrVal) { 253a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner PrintError(getLoc(), "Expected filename after include"); 254a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 255a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 256a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 257a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Get the string. 258a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner std::string Filename = CurStrVal; 259a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 260a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Try to find the file. 261a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner MemoryBuffer *NewBuf = MemoryBuffer::getFile(Filename.c_str()); 262a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 263c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner // If the file didn't exist directly, see if it's in an include path. 264a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) { 265a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner std::string IncFile = IncludeDirectories[i] + "/" + Filename; 266a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner NewBuf = MemoryBuffer::getFile(IncFile.c_str()); 267a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 268a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 269a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (NewBuf == 0) { 270a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner PrintError(getLoc(), "Could not find include file '" + Filename + "'"); 271a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 272a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 273a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 274a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Save the line number and lex buffer of the includer. 275a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner IncludeStack.push_back(IncludeRec(CurBuf, CurPtr, CurLineNo)); 276a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 277a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurLineNo = 1; // Reset line numbering. 278a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurBuf = NewBuf; 279a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurPtr = CurBuf->getBufferStart(); 280a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return false; 281a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 282a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 283a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnervoid TGLexer::SkipBCPLComment() { 284a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // skip the second slash. 285a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 286a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (*CurPtr) { 287a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\n': 288a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '\r': 289a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return; // Newline is end of comment. 290a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case 0: 291a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // If this is the end of the buffer, end the comment. 292a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr == CurBuf->getBufferEnd()) 293a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return; 294a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 295a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 296a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Otherwise, skip the character. 297c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner ++CurPtr; 298a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 299a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 300a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 301a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// SkipCComment - This skips C-style /**/ comments. The only difference from C 302a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// is that we allow nesting. 303a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnerbool TGLexer::SkipCComment() { 304a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // skip the star. 305c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner unsigned CommentDepth = 1; 306a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 307a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 308a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int CurChar = getNextChar(); 309a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner switch (CurChar) { 310a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case EOF: 311a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner PrintError(TokStart, "Unterminated comment!"); 312a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return true; 313a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '*': 314a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // End of the comment? 315a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '/') break; 316a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 317a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; // End the */. 318a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (--CommentDepth == 0) 319a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return false; 320a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 321a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner case '/': 322a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Start of a nested comment? 323a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '*') break; 324a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 325a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CommentDepth; 326a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner break; 327a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 328a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 329a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 330a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 331a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexNumber - Lex: 332a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// [-+]?[0-9]+ 333a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// 0x[0-9a-fA-F]+ 334a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// 0b[01]+ 335a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnertgtok::TokKind TGLexer::LexNumber() { 336a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[-1] == '0') { 337a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] == 'x') { 338a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 339c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner const char *NumStart = CurPtr; 340c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner while (isxdigit(CurPtr[0])) 341c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner ++CurPtr; 342c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner 343a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Requires at least one hex digit. 344a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr == NumStart) 345a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(CurPtr-2, "Invalid hexadecimal number"); 346a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 347a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner errno = 0; 348a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurIntVal = strtoll(NumStart, 0, 16); 349a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (errno == EINVAL) 350c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return ReturnError(CurPtr-2, "Invalid hexadecimal number"); 351c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner if (errno == ERANGE) { 352c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner errno = 0; 353c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner CurIntVal = (int64_t)strtoull(NumStart, 0, 16); 354a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (errno == EINVAL) 355a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(CurPtr-2, "Invalid hexadecimal number"); 356a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (errno == ERANGE) 357a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(CurPtr-2, "Hexadecimal number out of range"); 358a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 359a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::IntVal; 360a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } else if (CurPtr[0] == 'b') { 361a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 362a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *NumStart = CurPtr; 363a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (CurPtr[0] == '0' || CurPtr[0] == '1') 364a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 365a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 366a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Requires at least one binary digit. 367a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr == NumStart) 368a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(CurPtr-2, "Invalid binary number"); 369a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurIntVal = strtoll(NumStart, 0, 2); 370a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::IntVal; 371a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 372a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 373a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 374a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check for a sign without a digit. 375a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isdigit(CurPtr[0])) { 376a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[-1] == '-') 377a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::minus; 378a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner else if (CurPtr[-1] == '+') 379a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::plus; 380a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 381a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 382a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isdigit(CurPtr[0])) 383a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 384a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurIntVal = strtoll(TokStart, 0, 10); 385a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::IntVal; 386a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 387a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 388a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexBracket - We just read '['. If this is a code block, return it, 389a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// otherwise return the bracket. Match: '[' and '[{ ( [^}]+ | }[^]] )* }]' 390a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattnertgtok::TokKind TGLexer::LexBracket() { 391a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (CurPtr[0] != '{') 392c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattner return tgtok::l_square; 393a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 394a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *CodeStart = CurPtr; 395a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (1) { 396a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner int Char = getNextChar(); 397a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == EOF) break; 398a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 399a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char != '}') continue; 400a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 401a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner Char = getNextChar(); 402a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == EOF) break; 403a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Char == ']') { 404a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner CurStrVal.assign(CodeStart, CurPtr-2); 405a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return tgtok::CodeFragment; 406a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 407a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner } 408a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 409a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(CodeStart-2, "Unterminated Code Block"); 410a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 411a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 412a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner/// LexExclaim - Lex '!' and '![a-zA-Z]+'. 413c8a9bbcbc777f5071ed67879b9f6f3b02c5d1e34Chris Lattnertgtok::TokKind TGLexer::LexExclaim() { 414a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (!isalpha(*CurPtr)) 415a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(CurPtr-1, "Invalid \"!operator\""); 416a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 417a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner const char *Start = CurPtr++; 418a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner while (isalpha(*CurPtr)) 419a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner ++CurPtr; 420a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 421a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner // Check to see which operator this is. 422a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner unsigned Len = CurPtr-Start; 423a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 424a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat; 425a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA; 426a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL; 427a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL; 428a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat; 429a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 430a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner return ReturnError(Start-1, "Unknown operator"); 431a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner} 432a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner 433a8058744229a44e80f90c8530bb7fe47cbab1b70Chris Lattner