X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FTGLexer.cpp;h=82d2b6491aaca36ec8bd6659e312214a9eef127c;hb=8b8515c225c799e9df69bde8ffffa3c72cec9445;hp=2af35b05d6d834dbe00dfee8507432427be678d2;hpb=ae9f3a3b7c915f725aef5a7250e88eaeddda03c6;p=oota-llvm.git diff --git a/utils/TableGen/TGLexer.cpp b/utils/TableGen/TGLexer.cpp index 2af35b05d6d..82d2b6491aa 100644 --- a/utils/TableGen/TGLexer.cpp +++ b/utils/TableGen/TGLexer.cpp @@ -12,73 +12,53 @@ //===----------------------------------------------------------------------===// #include "TGLexer.h" -#include "llvm/Support/Streams.h" +#include "llvm/Support/SourceMgr.h" #include "llvm/Support/MemoryBuffer.h" -#include #include "llvm/Config/config.h" +#include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Twine.h" #include +#include #include #include +#include using namespace llvm; -TGLexer::TGLexer(MemoryBuffer *StartBuf) : CurLineNo(1), CurBuf(StartBuf) { +TGLexer::TGLexer(SourceMgr &SM) : SrcMgr(SM) { + CurBuffer = 0; + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); CurPtr = CurBuf->getBufferStart(); TokStart = 0; } -TGLexer::~TGLexer() { - while (!IncludeStack.empty()) { - delete IncludeStack.back().Buffer; - IncludeStack.pop_back(); - } - delete CurBuf; +SMLoc TGLexer::getLoc() const { + return SMLoc::getFromPointer(TokStart); } + /// ReturnError - Set the error to the specified string at the specified /// location. This is defined to always return tgtok::Error. -tgtok::TokKind TGLexer::ReturnError(const char *Loc, const std::string &Msg) { +tgtok::TokKind TGLexer::ReturnError(const char *Loc, const Twine &Msg) { PrintError(Loc, Msg); return tgtok::Error; } -void TGLexer::PrintIncludeStack(std::ostream &OS) const { - for (unsigned i = 0, e = IncludeStack.size(); i != e; ++i) - OS << "Included from " << IncludeStack[i].Buffer->getBufferIdentifier() - << ":" << IncludeStack[i].LineNo << ":\n"; - OS << "Parsing " << CurBuf->getBufferIdentifier() << ":" - << CurLineNo << ": "; + +void TGLexer::PrintError(const char *Loc, const Twine &Msg) const { + SrcMgr.PrintMessage(SMLoc::getFromPointer(Loc), Msg, "error"); } -/// PrintError - Print the error at the specified location. -void TGLexer::PrintError(const char *ErrorLoc, const std::string &Msg) const { - PrintIncludeStack(*cerr.stream()); - cerr << Msg << "\n"; - assert(ErrorLoc && "Location not specified!"); - - // Scan backward to find the start of the line. - const char *LineStart = ErrorLoc; - while (LineStart != CurBuf->getBufferStart() && - LineStart[-1] != '\n' && LineStart[-1] != '\r') - --LineStart; - // Get the end of the line. - const char *LineEnd = ErrorLoc; - while (LineEnd != CurBuf->getBufferEnd() && - LineEnd[0] != '\n' && LineEnd[0] != '\r') - ++LineEnd; - // Print out the line. - cerr << std::string(LineStart, LineEnd) << "\n"; - // Print out spaces before the carat. - for (const char *Pos = LineStart; Pos != ErrorLoc; ++Pos) - cerr << (*Pos == '\t' ? '\t' : ' '); - cerr << "^\n"; +void TGLexer::PrintError(SMLoc Loc, const Twine &Msg) const { + SrcMgr.PrintMessage(Loc, Msg, "error"); } + int TGLexer::getNextChar() { char CurChar = *CurPtr++; switch (CurChar) { default: return (unsigned char)CurChar; - case 0: + 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()) @@ -86,18 +66,18 @@ int TGLexer::getNextChar() { // If this is the end of an included file, pop the parent file off the // include stack. - if (!IncludeStack.empty()) { - delete CurBuf; - CurBuf = IncludeStack.back().Buffer; - CurLineNo = IncludeStack.back().LineNo; - CurPtr = IncludeStack.back().CurPtr; - IncludeStack.pop_back(); + SMLoc ParentIncludeLoc = SrcMgr.getParentIncludeLoc(CurBuffer); + if (ParentIncludeLoc != SMLoc()) { + CurBuffer = SrcMgr.FindBufferContainingLoc(ParentIncludeLoc); + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); + CurPtr = ParentIncludeLoc.getPointer(); return getNextChar(); } // Otherwise, return end of file. --CurPtr; // Another call to lex will return EOF again. return EOF; + } case '\n': case '\r': // Handle the newline character by ignoring it and incrementing the line @@ -106,8 +86,6 @@ int TGLexer::getNextChar() { if ((*CurPtr == '\n' || (*CurPtr == '\r')) && *CurPtr != CurChar) ++CurPtr; // Eat the two char newline sequence. - - ++CurLineNo; return '\n'; } } @@ -119,8 +97,8 @@ tgtok::TokKind TGLexer::LexToken() { switch (CurChar) { default: - // Handle letters: [a-zA-Z_] - if (isalpha(CurChar) || CurChar == '_') + // Handle letters: [a-zA-Z_#] + if (isalpha(CurChar) || CurChar == '_' || CurChar == '#') return LexIdentifier(); // Unknown character, emit an error. @@ -173,6 +151,8 @@ tgtok::TokKind TGLexer::LexToken() { tgtok::TokKind TGLexer::LexString() { const char *StrStart = CurPtr; + CurStrVal = ""; + while (*CurPtr != '"') { // If we hit the end of the buffer, report an error. if (*CurPtr == 0 && CurPtr == CurBuf->getBufferEnd()) @@ -181,10 +161,41 @@ tgtok::TokKind TGLexer::LexString() { if (*CurPtr == '\n' || *CurPtr == '\r') return ReturnError(StrStart, "End of line in string literal"); + if (*CurPtr != '\\') { + CurStrVal += *CurPtr++; + continue; + } + ++CurPtr; + + switch (*CurPtr) { + case '\\': case '\'': case '"': + // These turn into their literal character. + CurStrVal += *CurPtr++; + break; + case 't': + CurStrVal += '\t'; + ++CurPtr; + break; + case 'n': + CurStrVal += '\n'; + ++CurPtr; + break; + + case '\n': + case '\r': + return ReturnError(CurPtr, "escaped newlines not supported in tblgen"); + + // If we hit the end of the buffer, report an error. + case '\0': + if (CurPtr == CurBuf->getBufferEnd()) + return ReturnError(StrStart, "End of file in string literal"); + // FALL THROUGH + default: + return ReturnError(CurPtr, "invalid escape in string literal"); + } } - CurStrVal.assign(StrStart, CurPtr); ++CurPtr; return tgtok::StrVal; } @@ -205,13 +216,15 @@ tgtok::TokKind TGLexer::LexVarName() { tgtok::TokKind TGLexer::LexIdentifier() { - // The first letter is [a-zA-Z_]. + // The first letter is [a-zA-Z_#]. const char *IdentStart = TokStart; - // Match the rest of the identifier regex: [0-9a-zA-Z_]* - while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_') + // Match the rest of the identifier regex: [0-9a-zA-Z_#]* + while (isalpha(*CurPtr) || isdigit(*CurPtr) || *CurPtr == '_' || + *CurPtr == '#') ++CurPtr; + // Check to see if this identifier is a keyword. unsigned Len = CurPtr-IdentStart; @@ -255,25 +268,15 @@ bool TGLexer::LexInclude() { // Get the string. std::string Filename = CurStrVal; - // Try to find the file. - MemoryBuffer *NewBuf = MemoryBuffer::getFile(&Filename[0], Filename.size()); - - // If the file didn't exist directly, see if it's in an include path. - for (unsigned i = 0, e = IncludeDirectories.size(); i != e && !NewBuf; ++i) { - std::string IncFile = IncludeDirectories[i] + "/" + Filename; - NewBuf = MemoryBuffer::getFile(&IncFile[0], IncFile.size()); - } - - if (NewBuf == 0) { + + CurBuffer = SrcMgr.AddIncludeFile(Filename, SMLoc::getFromPointer(CurPtr)); + if (CurBuffer == -1) { PrintError(getLoc(), "Could not find include file '" + Filename + "'"); return true; } // Save the line number and lex buffer of the includer. - IncludeStack.push_back(IncludeRec(CurBuf, CurPtr, CurLineNo)); - - CurLineNo = 1; // Reset line numbering. - CurBuf = NewBuf; + CurBuf = SrcMgr.getMemoryBuffer(CurBuffer); CurPtr = CurBuf->getBufferStart(); return false; } @@ -340,9 +343,20 @@ tgtok::TokKind TGLexer::LexNumber() { // Requires at least one hex digit. if (CurPtr == NumStart) - return ReturnError(CurPtr-2, "Invalid hexadecimal number"); + return ReturnError(TokStart, "Invalid hexadecimal number"); + errno = 0; CurIntVal = strtoll(NumStart, 0, 16); + if (errno == EINVAL) + return ReturnError(TokStart, "Invalid hexadecimal number"); + if (errno == ERANGE) { + errno = 0; + CurIntVal = (int64_t)strtoull(NumStart, 0, 16); + if (errno == EINVAL) + return ReturnError(TokStart, "Invalid hexadecimal number"); + if (errno == ERANGE) + return ReturnError(TokStart, "Hexadecimal number out of range"); + } return tgtok::IntVal; } else if (CurPtr[0] == 'b') { ++CurPtr; @@ -399,21 +413,30 @@ tgtok::TokKind TGLexer::LexBracket() { /// LexExclaim - Lex '!' and '![a-zA-Z]+'. tgtok::TokKind TGLexer::LexExclaim() { if (!isalpha(*CurPtr)) - return ReturnError(CurPtr-1, "Invalid \"!operator\""); + return ReturnError(CurPtr - 1, "Invalid \"!operator\""); const char *Start = CurPtr++; while (isalpha(*CurPtr)) ++CurPtr; // Check to see which operator this is. - unsigned Len = CurPtr-Start; - - if (Len == 3 && !memcmp(Start, "con", 3)) return tgtok::XConcat; - if (Len == 3 && !memcmp(Start, "sra", 3)) return tgtok::XSRA; - if (Len == 3 && !memcmp(Start, "srl", 3)) return tgtok::XSRL; - if (Len == 3 && !memcmp(Start, "shl", 3)) return tgtok::XSHL; - if (Len == 9 && !memcmp(Start, "strconcat", 9)) return tgtok::XStrConcat; - - return ReturnError(Start-1, "Unknown operator"); + tgtok::TokKind Kind = + StringSwitch(StringRef(Start, CurPtr - Start)) + .Case("eq", tgtok::XEq) + .Case("if", tgtok::XIf) + .Case("head", tgtok::XHead) + .Case("tail", tgtok::XTail) + .Case("con", tgtok::XConcat) + .Case("shl", tgtok::XSHL) + .Case("sra", tgtok::XSRA) + .Case("srl", tgtok::XSRL) + .Case("cast", tgtok::XCast) + .Case("empty", tgtok::XEmpty) + .Case("subst", tgtok::XSubst) + .Case("foreach", tgtok::XForEach) + .Case("strconcat", tgtok::XStrConcat) + .Default(tgtok::Error); + + return Kind != tgtok::Error ? Kind : ReturnError(Start-1, "Unknown operator"); }