diff --git a/include/llvm/MC/MCParser/MCAsmLexer.h b/include/llvm/MC/MCParser/MCAsmLexer.h index 8edf3a4423f..ceba3f05e1c 100644 --- a/include/llvm/MC/MCParser/MCAsmLexer.h +++ b/include/llvm/MC/MCParser/MCAsmLexer.h @@ -10,6 +10,7 @@ #ifndef LLVM_MC_MCPARSER_MCASMLEXER_H #define LLVM_MC_MCPARSER_MCASMLEXER_H +#include "llvm/ADT/APInt.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/DataTypes.h" @@ -30,6 +31,7 @@ public: // Integer values. Integer, + BigNum, // larger than 64 bits // Real values. Real, @@ -57,12 +59,14 @@ private: /// a memory buffer owned by the source manager. StringRef Str; - int64_t IntVal; + APInt IntVal; public: AsmToken() {} - AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0) + AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal) : Kind(_Kind), Str(_Str), IntVal(_IntVal) {} + AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0) + : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {} TokenKind getKind() const { return Kind; } bool is(TokenKind K) const { return Kind == K; } @@ -99,6 +103,12 @@ public: // as a single token, then diagnose as an invalid number). int64_t getIntVal() const { assert(Kind == Integer && "This token isn't an integer!"); + return IntVal.getZExtValue(); + } + + APInt getAPIntVal() const { + assert((Kind == Integer || Kind == BigNum) && + "This token isn't an integer!"); return IntVal; } }; diff --git a/lib/MC/MCParser/AsmLexer.cpp b/lib/MC/MCParser/AsmLexer.cpp index ed98f93758e..88f17617895 100644 --- a/lib/MC/MCParser/AsmLexer.cpp +++ b/lib/MC/MCParser/AsmLexer.cpp @@ -238,6 +238,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] @@ -258,16 +265,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) @@ -277,7 +278,7 @@ AsmToken AsmLexer::LexDigit() { // suffices on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } if (*CurPtr == 'b') { @@ -298,7 +299,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"); @@ -306,7 +307,7 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } if (*CurPtr == 'x') { @@ -324,7 +325,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"); @@ -336,12 +337,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); @@ -357,7 +357,7 @@ AsmToken AsmLexer::LexDigit() { // suffixes on integer literals. SkipIgnoredIntegerSuffix(CurPtr); - return AsmToken(AsmToken::Integer, Result, Value); + return intToken(Result, Value); } /// LexSingleQuote: Integer: 'b' diff --git a/lib/MC/MCParser/AsmParser.cpp b/lib/MC/MCParser/AsmParser.cpp index 9157ac4f67c..e236c170b79 100644 --- a/lib/MC/MCParser/AsmParser.cpp +++ b/lib/MC/MCParser/AsmParser.cpp @@ -854,6 +854,8 @@ bool AsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { Res = MCSymbolRefExpr::Create(Sym, Variant, getContext()); return false; } + case AsmToken::BigNum: + return TokError("literal value out of range for directive"); case AsmToken::Integer: { SMLoc Loc = getTok().getLoc(); int64_t IntVal = getTok().getIntVal();