llvm.org GIT mirror llvm / aac8e4e
MC: Add AsmLexer::BigNum token for integers greater than 64 bits 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 David Woodhouse 6 years ago
3 changed file(s) with 31 addition(s) and 19 deletion(s). Raw diff Collapse all Expand all
99 #ifndef LLVM_MC_MCPARSER_MCASMLEXER_H
1010 #define LLVM_MC_MCPARSER_MCASMLEXER_H
1111
12 #include "llvm/ADT/APInt.h"
1213 #include "llvm/ADT/StringRef.h"
1314 #include "llvm/Support/Compiler.h"
1415 #include "llvm/Support/DataTypes.h"
2930
3031 // Integer values.
3132 Integer,
33 BigNum, // larger than 64 bits
3234
3335 // Real values.
3436 Real,
5658 /// a memory buffer owned by the source manager.
5759 StringRef Str;
5860
59 int64_t IntVal;
61 APInt IntVal;
6062
6163 public:
6264 AsmToken() {}
65 AsmToken(TokenKind _Kind, StringRef _Str, APInt _IntVal)
66 : Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
6367 AsmToken(TokenKind _Kind, StringRef _Str, int64_t _IntVal = 0)
64 : Kind(_Kind), Str(_Str), IntVal(_IntVal) {}
68 : Kind(_Kind), Str(_Str), IntVal(64, _IntVal, true) {}
6569
6670 TokenKind getKind() const { return Kind; }
6771 bool is(TokenKind K) const { return Kind == K; }
98102 // as a single token, then diagnose as an invalid number).
99103 int64_t getIntVal() const {
100104 assert(Kind == Integer && "This token isn't an integer!");
105 return IntVal.getZExtValue();
106 }
107
108 APInt getAPIntVal() const {
109 assert((Kind == Integer || Kind == BigNum) &&
110 "This token isn't an integer!");
101111 return IntVal;
102112 }
103113 };
237237 return DefaultRadix;
238238 }
239239
240 static AsmToken intToken(StringRef Ref, APInt &Value)
241 {
242 if (Value.isIntN(64))
243 return AsmToken(AsmToken::Integer, Ref, Value);
244 return AsmToken(AsmToken::BigNum, Ref, Value);
245 }
246
240247 /// LexDigit: First character is [0-9].
241248 /// Local Label: [0-9][:]
242249 /// Forward/Backward Label: [0-9][fb]
257264
258265 StringRef Result(TokStart, CurPtr - TokStart);
259266
260 long long Value;
261 if (Result.getAsInteger(Radix, Value)) {
262 // Allow positive values that are too large to fit into a signed 64-bit
263 // integer, but that do fit in an unsigned one, we just convert them over.
264 unsigned long long UValue;
265 if (Result.getAsInteger(Radix, UValue))
266 return ReturnError(TokStart, !isHex ? "invalid decimal number" :
267 APInt Value(128, 0, true);
268 if (Result.getAsInteger(Radix, Value))
269 return ReturnError(TokStart, !isHex ? "invalid decimal number" :
267270 "invalid hexdecimal number");
268 Value = (long long)UValue;
269 }
270271
271272 // Consume the [bB][hH].
272273 if (Radix == 2 || Radix == 16)
276277 // suffices on integer literals.
277278 SkipIgnoredIntegerSuffix(CurPtr);
278279
279 return AsmToken(AsmToken::Integer, Result, Value);
280 return intToken(Result, Value);
280281 }
281282
282283 if (*CurPtr == 'b') {
297298
298299 StringRef Result(TokStart, CurPtr - TokStart);
299300
300 long long Value;
301 APInt Value(128, 0, true);
301302 if (Result.substr(2).getAsInteger(2, Value))
302303 return ReturnError(TokStart, "invalid binary number");
303304
305306 // suffixes on integer literals.
306307 SkipIgnoredIntegerSuffix(CurPtr);
307308
308 return AsmToken(AsmToken::Integer, Result, Value);
309 return intToken(Result, Value);
309310 }
310311
311312 if (*CurPtr == 'x') {
323324 if (CurPtr == NumStart)
324325 return ReturnError(CurPtr-2, "invalid hexadecimal number");
325326
326 unsigned long long Result;
327 APInt Result(128, 0);
327328 if (StringRef(TokStart, CurPtr - TokStart).getAsInteger(0, Result))
328329 return ReturnError(TokStart, "invalid hexadecimal number");
329330
335336 // suffixes on integer literals.
336337 SkipIgnoredIntegerSuffix(CurPtr);
337338
338 return AsmToken(AsmToken::Integer, StringRef(TokStart, CurPtr - TokStart),
339 (int64_t)Result);
339 return intToken(StringRef(TokStart, CurPtr - TokStart), Result);
340340 }
341341
342342 // Either octal or hexadecimal.
343 long long Value;
343 APInt Value(128, 0, true);
344344 unsigned Radix = doLookAhead(CurPtr, 8);
345345 bool isHex = Radix == 16;
346346 StringRef Result(TokStart, CurPtr - TokStart);
356356 // suffixes on integer literals.
357357 SkipIgnoredIntegerSuffix(CurPtr);
358358
359 return AsmToken(AsmToken::Integer, Result, Value);
359 return intToken(Result, Value);
360360 }
361361
362362 /// LexSingleQuote: Integer: 'b'
853853 Res = MCSymbolRefExpr::Create(Sym, Variant, getContext());
854854 return false;
855855 }
856 case AsmToken::BigNum:
857 return TokError("literal value out of range for directive");
856858 case AsmToken::Integer: {
857859 SMLoc Loc = getTok().getLoc();
858860 int64_t IntVal = getTok().getIntVal();