diff options
Diffstat (limited to 'lib/MC/MCParser/AsmLexer.cpp')
-rw-r--r-- | lib/MC/MCParser/AsmLexer.cpp | 96 |
1 files changed, 59 insertions, 37 deletions
diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index b49dd0104793..145ad4a56123 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -22,23 +22,23 @@ using namespace llvm; AsmLexer::AsmLexer(const MCAsmInfo &_MAI) : MAI(_MAI) { - CurBuf = NULL; - CurPtr = NULL; + CurPtr = nullptr; isAtStartOfLine = true; + AllowAtInIdentifier = !StringRef(MAI.getCommentString()).startswith("@"); } AsmLexer::~AsmLexer() { } -void AsmLexer::setBuffer(const MemoryBuffer *buf, const char *ptr) { - CurBuf = buf; +void AsmLexer::setBuffer(StringRef Buf, const char *ptr) { + CurBuf = Buf; if (ptr) CurPtr = ptr; else - CurPtr = CurBuf->getBufferStart(); + CurPtr = CurBuf.begin(); - TokStart = 0; + TokStart = nullptr; } /// ReturnError - Set the error to the specified string at the specified @@ -57,7 +57,7 @@ int AsmLexer::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. // Otherwise, return end of file. @@ -139,8 +139,9 @@ AsmToken AsmLexer::LexHexFloatLiteral(bool NoIntDigits) { } /// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@?]* -static bool IsIdentifierChar(char c) { - return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@' || c == '?'; +static bool IsIdentifierChar(char c, bool AllowAt) { + return isalnum(c) || c == '_' || c == '$' || c == '.' || + (c == '@' && AllowAt) || c == '?'; } AsmToken AsmLexer::LexIdentifier() { // Check for floating point literals. @@ -148,11 +149,12 @@ AsmToken AsmLexer::LexIdentifier() { // Disambiguate a .1243foo identifier from a floating literal. while (isdigit(*CurPtr)) ++CurPtr; - if (*CurPtr == 'e' || *CurPtr == 'E' || !IsIdentifierChar(*CurPtr)) + if (*CurPtr == 'e' || *CurPtr == 'E' || + !IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) return LexFloatLiteral(); } - while (IsIdentifierChar(*CurPtr)) + while (IsIdentifierChar(*CurPtr, AllowAtInIdentifier)) ++CurPtr; // Handle . as a special case. @@ -198,8 +200,8 @@ AsmToken AsmLexer::LexLineComment() { CurChar = getNextChar(); if (CurChar == EOF) - return AsmToken(AsmToken::Eof, StringRef(CurPtr, 0)); - return AsmToken(AsmToken::EndOfStatement, StringRef(CurPtr, 0)); + return AsmToken(AsmToken::Eof, StringRef(TokStart, 0)); + return AsmToken(AsmToken::EndOfStatement, StringRef(TokStart, 0)); } static void SkipIgnoredIntegerSuffix(const char *&CurPtr) { @@ -215,7 +217,7 @@ static void SkipIgnoredIntegerSuffix(const char *&CurPtr) { // Look ahead to search for first non-hex digit, if it's [hH], then we treat the // integer as a hexadecimal, possibly with leading zeroes. static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) { - const char *FirstHex = 0; + const char *FirstHex = nullptr; const char *LookAhead = CurPtr; while (1) { if (isdigit(*LookAhead)) { @@ -235,6 +237,13 @@ static unsigned doLookAhead(const char *&CurPtr, unsigned DefaultRadix) { return DefaultRadix; } +static AsmToken intToken(StringRef Ref, APInt &Value) +{ + if (Value.isIntN(64)) + return AsmToken(AsmToken::Integer, Ref, Value); + return AsmToken(AsmToken::BigNum, Ref, Value); +} + /// LexDigit: First character is [0-9]. /// Local Label: [0-9][:] /// Forward/Backward Label: [0-9][fb] @@ -255,16 +264,10 @@ AsmToken AsmLexer::LexDigit() { StringRef Result(TokStart, CurPtr - TokStart); - long long Value; - if (Result.getAsInteger(Radix, Value)) { - // Allow positive values that are too large to fit into a signed 64-bit - // integer, but that do fit in an unsigned one, we just convert them over. - unsigned long long UValue; - if (Result.getAsInteger(Radix, UValue)) - return ReturnError(TokStart, !isHex ? "invalid decimal number" : + APInt Value(128, 0, true); + if (Result.getAsInteger(Radix, Value)) + return ReturnError(TokStart, !isHex ? "invalid decimal number" : "invalid hexdecimal number"); - Value = (long long)UValue; - } // Consume the [bB][hH]. if (Radix == 2 || Radix == 16) @@ -274,7 +277,7 @@ AsmToken AsmLexer::LexDigit() { // suffices on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } if (*CurPtr == 'b') { @@ -295,7 +298,7 @@ AsmToken AsmLexer::LexDigit() { StringRef Result(TokStart, CurPtr - TokStart); - long long Value; + APInt Value(128, 0, true); if (Result.substr(2).getAsInteger(2, Value)) return ReturnError(TokStart, "invalid binary number"); @@ -303,7 +306,7 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } if (*CurPtr == 'x') { @@ -321,7 +324,7 @@ AsmToken AsmLexer::LexDigit() { if (CurPtr == NumStart) return ReturnError(CurPtr-2, "invalid hexadecimal number"); - unsigned long long Result; + APInt Result(128, 0); if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result)) return ReturnError(TokStart, "invalid hexadecimal number"); @@ -333,12 +336,11 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart), - (int64_t)Result); + return intToken(StringRef(TokStart, CurPtr - TokStart), Result); } // Either octal or hexadecimal. - long long Value; + APInt Value(128, 0, true); unsigned Radix = doLookAhead(CurPtr, 8); bool isHex = Radix == 16; StringRef Result(TokStart, CurPtr - TokStart); @@ -354,7 +356,7 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } /// LexSingleQuote: Integer: 'b' @@ -417,9 +419,8 @@ StringRef AsmLexer::LexUntilEndOfStatement() { while (!isAtStartOfComment(*CurPtr) && // Start of line comment. !isAtStatementSeparator(CurPtr) && // End of statement marker. - *CurPtr != '\n' && - *CurPtr != '\r' && - (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) { + *CurPtr != '\n' && *CurPtr != '\r' && + (*CurPtr != 0 || CurPtr != CurBuf.end())) { ++CurPtr; } return StringRef(TokStart, CurPtr-TokStart); @@ -428,14 +429,35 @@ StringRef AsmLexer::LexUntilEndOfStatement() { StringRef AsmLexer::LexUntilEndOfLine() { TokStart = CurPtr; - while (*CurPtr != '\n' && - *CurPtr != '\r' && - (*CurPtr != 0 || CurPtr != CurBuf->getBufferEnd())) { + while (*CurPtr != '\n' && *CurPtr != '\r' && + (*CurPtr != 0 || CurPtr != CurBuf.end())) { ++CurPtr; } return StringRef(TokStart, CurPtr-TokStart); } +const AsmToken AsmLexer::peekTok(bool ShouldSkipSpace) { + const char *SavedTokStart = TokStart; + const char *SavedCurPtr = CurPtr; + bool SavedAtStartOfLine = isAtStartOfLine; + bool SavedSkipSpace = SkipSpace; + + std::string SavedErr = getErr(); + SMLoc SavedErrLoc = getErrLoc(); + + SkipSpace = ShouldSkipSpace; + AsmToken Token = LexToken(); + + SetError(SavedErrLoc, SavedErr); + + SkipSpace = SavedSkipSpace; + isAtStartOfLine = SavedAtStartOfLine; + CurPtr = SavedCurPtr; + TokStart = SavedTokStart; + + return Token; +} + bool AsmLexer::isAtStartOfComment(char Char) { // FIXME: This won't work for multi-character comment indicators like "//". return Char == *MAI.getCommentString(); |