MC/AsmParser: Handle exponents in floating point literals.
authorDaniel Dunbar <daniel@zuster.org>
Mon, 27 Sep 2010 20:12:52 +0000 (20:12 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Mon, 27 Sep 2010 20:12:52 +0000 (20:12 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@114861 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCParser/AsmLexer.h
lib/MC/MCParser/AsmLexer.cpp
test/MC/AsmParser/floating-literals.s

index 21878899cac1ebdaea44a5409754cffc1ca14829..439ecb91e5a89bf1d2686053863d39431530d381 100644 (file)
@@ -61,6 +61,7 @@ private:
   AsmToken LexLineComment();
   AsmToken LexDigit();
   AsmToken LexQuote();
+  AsmToken LexFloatLiteral();
 };
   
 } // end namespace llvm
index 1a71d2437df43bd48bb3e4706a9e9ebb61b340bf..7ca1cccc98c21fd4c870e08fbe3cfa79dc5f9b84 100644 (file)
@@ -64,6 +64,31 @@ int AsmLexer::getNextChar() {
   }
 }
 
+/// LexFloatLiteral: [0-9]*[.][0-9]*([eE][+-]?[0-9]*)?
+///
+/// The leading integral digit sequence and dot should have already been
+/// consumed, some or all of the fractional digit sequence *can* have been
+/// consumed.
+AsmToken AsmLexer::LexFloatLiteral() {
+  // Skip the fractional digit sequence.
+  while (isdigit(*CurPtr))
+    ++CurPtr;
+
+  // Check for exponent; we intentionally accept a slighlty wider set of
+  // literals here and rely on the upstream client to reject invalid ones (e.g.,
+  // "1e+").
+  if (*CurPtr == 'e' || *CurPtr == 'E') {
+    ++CurPtr;
+    if (*CurPtr == '-' || *CurPtr == '+')
+      ++CurPtr;
+    while (isdigit(*CurPtr))
+      ++CurPtr;
+  }
+
+  return AsmToken(AsmToken::Real,
+                  StringRef(TokStart, CurPtr - TokStart));
+}
+
 /// LexIdentifier: [a-zA-Z_.][a-zA-Z0-9_$.@]*
 static bool IsIdentifierChar(char c) {
   return isalnum(c) || c == '_' || c == '$' || c == '.' || c == '@';
@@ -71,12 +96,11 @@ static bool IsIdentifierChar(char c) {
 AsmToken AsmLexer::LexIdentifier() {
   // Check for floating point literals.
   if (CurPtr[-1] == '.' && isdigit(*CurPtr)) {
+    // Disambiguate a .1243foo identifier from a floating literal.
     while (isdigit(*CurPtr))
       ++CurPtr;
-    if (!IsIdentifierChar(*CurPtr)) {
-      return AsmToken(AsmToken::Real,
-                      StringRef(TokStart, CurPtr - TokStart));
-    }
+    if (*CurPtr == 'e' || *CurPtr == 'E' || !IsIdentifierChar(*CurPtr))
+      return LexFloatLiteral();
   }
 
   while (IsIdentifierChar(*CurPtr))
@@ -150,12 +174,9 @@ AsmToken AsmLexer::LexDigit() {
       ++CurPtr;
 
     // Check for floating point literals.
-    if (*CurPtr == '.') {
+    if (*CurPtr == '.' || *CurPtr == 'e') {
       ++CurPtr;
-      while (isdigit(*CurPtr))
-        ++CurPtr;
-
-      return AsmToken(AsmToken::Real, StringRef(TokStart, CurPtr - TokStart));
+      return LexFloatLiteral();
     }
 
     StringRef Result(TokStart, CurPtr - TokStart);
index dbeb81fb9eecc4921f31fef4c97a8ca7137d01dc..b8e6e3cc80061b529e8cee19e730f687564edb67 100644 (file)
 
 # CHECK: .quad  0
 .double 0.0
+
+# CHECK: .quad  -4570379565595099136
+.double -1.2e3
+# CHECK: .quad  -4690170861623122860
+.double -1.2e-5
+# CHECK: .quad  -4465782973978902528
+.double -1.2e+10
+# CHECK: .quad  4681608360884174848
+.double 1e5
+# CHECK: .quad  4681608360884174848
+.double 1.e5
+# CHECK: .quad  4611686018427387904
+.double 2.
+
+// APFloat should reject these with an error, not crash:
+//.double -1.2e+
+//.double -1.2e