X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTableGen%2FTGLexer.cpp;h=63b85842d6a9e68910ecd32eb78be621abbb1ed7;hb=a19abeb7abaa80b946c593164a08c3d230183a95;hp=8c1b4290548de11577138afb7d30f658978a1f45;hpb=a1b1b79be15c4b79a4282f148085ebad1cf877ca;p=oota-llvm.git diff --git a/lib/TableGen/TGLexer.cpp b/lib/TableGen/TGLexer.cpp index 8c1b4290548..63b85842d6a 100644 --- a/lib/TableGen/TGLexer.cpp +++ b/lib/TableGen/TGLexer.cpp @@ -12,24 +12,25 @@ //===----------------------------------------------------------------------===// #include "TGLexer.h" -#include "llvm/TableGen/Error.h" -#include "llvm/Support/SourceMgr.h" -#include "llvm/Support/MemoryBuffer.h" -#include "llvm/Config/config.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/ADT/Twine.h" +#include "llvm/Config/config.h" // for strtoull()/strtoll() define +#include "llvm/Support/MemoryBuffer.h" +#include "llvm/Support/SourceMgr.h" +#include "llvm/TableGen/Error.h" #include +#include #include #include #include -#include + using namespace llvm; TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) { - CurBuffer = 0; - CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); - CurPtr = CurBuf->getBufferStart(); - TokStart = 0; + CurBuffer = SrcMgr.getMainFileID(); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(); + CurPtr = CurBuf.begin(); + TokStart = nullptr; } SMLoc TGLexer::getLoc() const { @@ -51,7 +52,7 @@ int TGLexer::getNextChar() { case 0: { // A nul character in the stream is either the end of the current buffer or // a random nul in the file. Disambiguate that here. - if (CurPtr-1 != CurBuf->getBufferEnd()) + if (CurPtr-1 != CurBuf.end()) return 0; // Just whitespace. // If this is the end of an included file, pop the parent file off the @@ -59,7 +60,7 @@ int TGLexer::getNextChar() { SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); if (ParentIncludeLoc != SMLoc()) { CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); - CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(); CurPtr = ParentIncludeLoc.getPointer(); return getNextChar(); } @@ -80,6 +81,10 @@ int TGLexer::getNextChar() { } } +int TGLexer::peekNextChar(int Index) { + return *(CurPtr + Index); +} + tgtok::TokKind TGLexer::LexToken() { TokStart = CurPtr; // This always consumes at least one character. @@ -87,10 +92,10 @@ tgtok::TokKind TGLexer::LexToken() { switch (CurChar) { default: - // Handle letters: [a-zA-Z_#] - if (isalpha(CurChar) || CurChar == '_' || CurChar == '#') + // Handle letters: [a-zA-Z_] + if (isalpha(CurChar) || CurChar == '_') return LexIdentifier(); - + // Unknown character, emit an error. return ReturnError(TokStart, "Unexpected character"); case EOF: return tgtok::Eof; @@ -107,6 +112,7 @@ tgtok::TokKind TGLexer::LexToken() { case ')': return tgtok::r_paren; case '=': return tgtok::equal; case '?': return tgtok::question; + case '#': return tgtok::paste; case 0: case ' ': @@ -128,8 +134,44 @@ tgtok::TokKind TGLexer::LexToken() { return LexToken(); case '-': case '+': case '0': case '1': case '2': case '3': case '4': case '5': case '6': - case '7': case '8': case '9': + case '7': case '8': case '9': { + int NextChar = 0; + if (isdigit(CurChar)) { + // Allow identifiers to start with a number if it is followed by + // an identifier. This can happen with paste operations like + // foo#8i. + int i = 0; + do { + NextChar = peekNextChar(i++); + } while (isdigit(NextChar)); + + if (NextChar == 'x' || NextChar == 'b') { + // If this is [0-9]b[01] or [0-9]x[0-9A-fa-f] this is most + // likely a number. + int NextNextChar = peekNextChar(i); + switch (NextNextChar) { + default: + break; + case '0': case '1': + if (NextChar == 'b') + return LexNumber(); + // Fallthrough + case '2': case '3': case '4': case '5': + case '6': case '7': case '8': case '9': + case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': + case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': + if (NextChar == 'x') + return LexNumber(); + break; + } + } + } + + if (isalpha(NextChar) || NextChar == '_') + return LexIdentifier(); + return LexNumber(); + } case '"': return LexString(); case '$': return LexVarName(); case '[': return LexBracket(); @@ -145,7 +187,7 @@ tgtok::TokKind TGLexer::LexString() { while (*CurPtr != '"') { // If we hit the end of the buffer, report an error. - if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) + if (*CurPtr == 0 && CurPtr == CurBuf.end()) return ReturnError(StrStart, "End of file in string literal"); if (*CurPtr == '\n' || *CurPtr == '\r') @@ -178,7 +220,7 @@ tgtok::TokKind TGLexer::LexString() { // If we hit the end of the buffer, report an error. case '\0': - if (CurPtr == CurBuf->getBufferEnd()) + if (CurPtr == CurBuf.end()) return ReturnError(StrStart, "End of file in string literal"); // FALL THROUGH default: @@ -210,8 +252,7 @@ tgtok::TokKind TGLexer::LexIdentifier() { const char *IdentStart = TokStart; // Match the rest of the identifier regex: [0-9a-zA-Z_#]* - while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' || - *CurPtr == '#') + while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') ++CurPtr; // Check to see if this identifier is a keyword. @@ -232,6 +273,7 @@ tgtok::TokKind TGLexer::LexIdentifier() { .Case("dag", tgtok::Dag) .Case("class", tgtok::Class) .Case("def", tgtok::Def) + .Case("foreach", tgtok::Foreach) .Case("defm", tgtok::Defm) .Case("multiclass", tgtok::MultiClass) .Case("field", tgtok::Field) @@ -262,15 +304,23 @@ bool TGLexer::LexInclude() { CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr), IncludedFile); - if (CurBuffer == -1) { + if (!CurBuffer) { PrintError(getLoc(), "Could not find include file '" + Filename + "'"); return true; } - Dependencies.push_back(IncludedFile); + DependenciesMapTy::const_iterator Found = Dependencies.find(IncludedFile); + if (Found != Dependencies.end()) { + PrintError(getLoc(), + "File '" + IncludedFile + "' has already been included."); + SrcMgr.PrintMessage(Found->second, SourceMgr::DK_Note, + "previously included here"); + return true; + } + Dependencies.insert(std::make_pair(IncludedFile, getLoc())); // Save the line number and lex buffer of the includer. - CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); - CurPtr = CurBuf->getBufferStart(); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer)->getBuffer(); + CurPtr = CurBuf.begin(); return false; } @@ -283,7 +333,7 @@ void TGLexer::SkipBCPLComment() { return; // Newline is end of comment. case 0: // If this is the end of the buffer, end the comment. - if (CurPtr == CurBuf->getBufferEnd()) + if (CurPtr == CurBuf.end()) return; break; } @@ -339,12 +389,12 @@ tgtok::TokKind TGLexer::LexNumber() { return ReturnError(TokStart, "Invalid hexadecimal number"); errno = 0; - CurIntVal = strtoll(NumStart, 0, 16); + CurIntVal = strtoll(NumStart, nullptr, 16); if (errno == EINVAL) return ReturnError(TokStart, "Invalid hexadecimal number"); if (errno == ERANGE) { errno = 0; - CurIntVal = (int64_t)strtoull(NumStart, 0, 16); + CurIntVal = (int64_t)strtoull(NumStart, nullptr, 16); if (errno == EINVAL) return ReturnError(TokStart, "Invalid hexadecimal number"); if (errno == ERANGE) @@ -360,8 +410,8 @@ tgtok::TokKind TGLexer::LexNumber() { // Requires at least one binary digit. if (CurPtr == NumStart) return ReturnError(CurPtr-2, "Invalid binary number"); - CurIntVal = strtoll(NumStart, 0, 2); - return tgtok::IntVal; + CurIntVal = strtoll(NumStart, nullptr, 2); + return tgtok::BinaryIntVal; } } @@ -375,7 +425,7 @@ tgtok::TokKind TGLexer::LexNumber() { while (isdigit(CurPtr[0])) ++CurPtr; - CurIntVal = strtoll(TokStart, 0, 10); + CurIntVal = strtoll(TokStart, nullptr, 10); return tgtok::IntVal; } @@ -420,6 +470,8 @@ tgtok::TokKind TGLexer::LexExclaim() { .Case("head", tgtok::XHead) .Case("tail", tgtok::XTail) .Case("con", tgtok::XConcat) + .Case("add", tgtok::XADD) + .Case("and", tgtok::XAND) .Case("shl", tgtok::XSHL) .Case("sra", tgtok::XSRA) .Case("srl", tgtok::XSRL) @@ -427,6 +479,7 @@ tgtok::TokKind TGLexer::LexExclaim() { .Case("empty", tgtok::XEmpty) .Case("subst", tgtok::XSubst) .Case("foreach", tgtok::XForEach) + .Case("listconcat", tgtok::XListConcat) .Case("strconcat", tgtok::XStrConcat) .Default(tgtok::Error);