This will be needed for .octa support, but we don't want to just use the
existing AsmLexer::Integer for it and then have to litter all its users
with explicit checks for the size, and make them use the new get APIntVal()
method.
So let the lexer produce an AsmLexer::Integer as before for numbers which
are small enough — which appears to cover what was previously a nasty
special case handling of numbers which don't fit in int64_t but *do* fit
in uint64_t.
Where the number is too large even for that, produce an AsmLexer::BigNum
instead. We do nothing with these except complain about them for now,
but that will be changed shortly...
Based on a patch from PaX Team <pageexec@freemail.hu>
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@200613
91177308-0d34-0410-b5e6-
96231b3b80d8
#ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
#define LLVM_MC_MCPARSER_MCASMLEXER_H
#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"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/DataTypes.h"
// Integer values.
Integer,
// Integer values.
Integer,
+ BigNum, // larger than 64 bits
/// a memory buffer owned by the source manager.
StringRef Str;
/// a memory buffer owned by the source manager.
StringRef Str;
- AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
+ AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal)
: Kind(_Kind), Str(_Str), IntVal(_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; }
TokenKind getKind() const { return Kind; }
bool is(TokenKind K) const { return Kind == K; }
// as a single token, then diagnose as an invalid number).
int64_t getIntVal() const {
assert(Kind == Integer && "This token isn't an integer!");
// 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!");
+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]
/// LexDigit: First character is [0-9].
/// Local Label: [0-9][:]
/// Forward/Backward Label: [0-9][fb]
StringRef Result(TokStart, CurPtr - TokStart);
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");
"invalid hexdecimal number");
- Value = (long long)UValue;
- }
// Consume the [bB][hH].
if (Radix == 2 || Radix == 16)
// Consume the [bB][hH].
if (Radix == 2 || Radix == 16)
// suffices on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
// suffices on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, Result, Value);
+ return intToken(Result, Value);
StringRef Result(TokStart, CurPtr - TokStart);
StringRef Result(TokStart, CurPtr - TokStart);
+ APInt Value(128, 0, true);
if (Result.substr(2).getAsInteger(2, Value))
return ReturnError(TokStart, "invalid binary number");
if (Result.substr(2).getAsInteger(2, Value))
return ReturnError(TokStart, "invalid binary number");
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, Result, Value);
+ return intToken(Result, Value);
if (CurPtr == NumStart)
return ReturnError(CurPtr-2, "invalid hexadecimal number");
if (CurPtr == NumStart)
return ReturnError(CurPtr-2, "invalid hexadecimal number");
- unsigned long long Result;
if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
return ReturnError(TokStart, "invalid hexadecimal number");
if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
return ReturnError(TokStart, "invalid hexadecimal number");
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
// 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.
}
// Either octal or hexadecimal.
+ APInt Value(128, 0, true);
unsigned Radix = doLookAhead(CurPtr, 8);
bool isHex = Radix == 16;
StringRef Result(TokStart, CurPtr - TokStart);
unsigned Radix = doLookAhead(CurPtr, 8);
bool isHex = Radix == 16;
StringRef Result(TokStart, CurPtr - TokStart);
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
// suffixes on integer literals.
SkipIgnoredIntegerSuffix(CurPtr);
- return AsmToken(AsmToken::Integer, Result, Value);
+ return intToken(Result, Value);
}
/// LexSingleQuote: Integer: 'b'
}
/// LexSingleQuote: Integer: 'b'
Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
return false;
}
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();
case AsmToken::Integer: {
SMLoc Loc = getTok().getLoc();
int64_t IntVal = getTok().getIntVal();