[PATCH] D27817: [MIRParser] Add parsing hex literals of arbitrary size as unsigned integers

Krzysztof Parzyszek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Dec 15 09:25:29 PST 2016


kparzysz created this revision.
kparzysz added a reviewer: MatzeB.
kparzysz added a subscriber: llvm-commits.
kparzysz set the repository for this revision to rL LLVM.

The current code does not parse hex literals larger than 32-bit.  Add a function that will parse a HexLiteral as APInt.


Repository:
  rL LLVM

https://reviews.llvm.org/D27817

Files:
  lib/CodeGen/MIRParser/MIParser.cpp


Index: lib/CodeGen/MIRParser/MIParser.cpp
===================================================================
--- lib/CodeGen/MIRParser/MIParser.cpp
+++ lib/CodeGen/MIRParser/MIParser.cpp
@@ -197,6 +197,12 @@
   /// Return true if an error occurred.
   bool getUint64(uint64_t &Result);
 
+  /// Convert the hexadecimal literal in the current token into an unsigned
+  ///  APInt with a minimum bitwidth required to represent the value.
+  ///
+  /// Return true if the literal does not represent an integer value.
+  bool getHexUint(APInt &Result);
+
   /// If the current token is of the given kind, consume it and return false.
   /// Otherwise report an error and return true.
   bool expectAndConsume(MIToken::TokenKind TokenKind);
@@ -1160,16 +1166,10 @@
     return false;
   }
   if (Token.is(MIToken::HexLiteral)) {
-    StringRef S = Token.range();
-    assert(S[0] == '0' && tolower(S[1]) == 'x');
-    // This could be a floating point literal with a special prefix.
-    if (!isxdigit(S[2]))
+    APInt A;
+    if (getHexUint(A))
       return true;
-    StringRef V = S.substr(2);
-    unsigned BW = std::min<unsigned>(V.size()*4, 32);
-    APInt A(BW, V, 16);
-    APInt Limit = APInt(BW, std::numeric_limits<unsigned>::max());
-    if (A.ugt(Limit))
+    if (A.getBitWidth() > 32)
       return error("expected 32-bit integer (too large)");
     Result = A.getZExtValue();
     return false;
@@ -1823,10 +1823,35 @@
 }
 
 bool MIParser::getUint64(uint64_t &Result) {
-  assert(Token.hasIntegerValue());
-  if (Token.integerValue().getActiveBits() > 64)
-    return error("expected 64-bit integer (too large)");
-  Result = Token.integerValue().getZExtValue();
+  if (Token.hasIntegerValue()) {
+    if (Token.integerValue().getActiveBits() > 64)
+      return error("expected 64-bit integer (too large)");
+    Result = Token.integerValue().getZExtValue();
+    return false;
+  }
+  if (Token.is(MIToken::HexLiteral)) {
+    APInt A;
+    if (getHexUint(A))
+      return true;
+    if (A.getBitWidth() > 64)
+      return error("expected 64-bit integer (too large)");
+    Result = A.getZExtValue();
+    return false;
+  }
+  return true;
+}
+
+bool MIParser::getHexUint(APInt &Result) {
+  assert(Token.is(MIToken::HexLiteral));
+  StringRef S = Token.range();
+  assert(S[0] == '0' && tolower(S[1]) == 'x');
+  // This could be a floating point literal with a special prefix.
+  if (!isxdigit(S[2]))
+    return true;
+  StringRef V = S.substr(2);
+  APInt A(V.size()*4, V, 16);
+  Result = APInt(A.getActiveBits(),
+                 ArrayRef<uint64_t>(A.getRawData(), A.getNumWords()));
   return false;
 }
 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D27817.81602.patch
Type: text/x-patch
Size: 2631 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20161215/f98f8b8f/attachment.bin>


More information about the llvm-commits mailing list