* script.cc (Token::integer_value): Accept trailing M/m/K/k
authorIan Lance Taylor <ian@airs.com>
Wed, 29 Jun 2011 21:57:51 +0000 (21:57 +0000)
committerIan Lance Taylor <ian@airs.com>
Wed, 29 Jun 2011 21:57:51 +0000 (21:57 +0000)
modifier.
(Lex::gather_token): Accept trailing M/m/K/k for integers.

gold/ChangeLog
gold/script.cc

index e929226fe1197f4fc8a20cc0f13df1f1107b3f38..ae2142716aad46f55ffe5440bba99f1751d7970b 100644 (file)
@@ -1,5 +1,6 @@
 2011-06-29  Ian Lance Taylor  <iant@google.com>
 
+       PR gold/12652
        * script.cc (Token::integer_value): Accept trailing M/m/K/k
        modifier.
        (Lex::gather_token): Accept trailing M/m/K/k for integers.
index 33a89816b8dd21327db33c30ab668bd4d8d49481..7df0c9e9dcc297b41fbcb84c002536b5ee57e2cd 100644 (file)
@@ -146,13 +146,7 @@ class Token
   }
 
   uint64_t
-  integer_value() const
-  {
-    gold_assert(this->classification_ == TOKEN_INTEGER);
-    // Null terminate.
-    std::string s(this->value_, this->value_length_);
-    return strtoull(s.c_str(), NULL, 0);
-  }
+  integer_value() const;
 
  private:
   // The token classification.
@@ -171,6 +165,35 @@ class Token
   int charpos_;
 };
 
+// Return the value of a TOKEN_INTEGER.
+
+uint64_t
+Token::integer_value() const
+{
+  gold_assert(this->classification_ == TOKEN_INTEGER);
+
+  size_t len = this->value_length_;
+
+  uint64_t multiplier = 1;
+  char last = this->value_[len - 1];
+  if (last == 'm' || last == 'M')
+    {
+      multiplier = 1024 * 1024;
+      --len;
+    }
+  else if (last == 'k' || last == 'K')
+    {
+      multiplier = 1024;
+      --len;
+    }
+
+  char *end;
+  uint64_t ret = strtoull(this->value_, &end, 0);
+  gold_assert(static_cast<size_t>(end - this->value_) == len);
+
+  return ret * multiplier;
+}
+
 // This class handles lexing a file into a sequence of tokens.
 
 class Lex
@@ -474,9 +497,7 @@ Lex::can_continue_name(const char* c)
 // For a number we accept 0x followed by hex digits, or any sequence
 // of digits.  The old linker accepts leading '$' for hex, and
 // trailing HXBOD.  Those are for MRI compatibility and we don't
-// accept them.  The old linker also accepts trailing MK for mega or
-// kilo.  FIXME: Those are mentioned in the documentation, and we
-// should accept them.
+// accept them.
 
 // Return whether C1 C2 C3 can start a hex number.
 
@@ -703,8 +724,15 @@ Lex::gather_token(Token::Classification classification,
                  const char** pp)
 {
   const char* new_match = NULL;
-  while ((new_match = (this->*can_continue_fn)(match)))
+  while ((new_match = (this->*can_continue_fn)(match)) != NULL)
     match = new_match;
+
+  // A special case: integers may be followed by a single M or K,
+  // case-insensitive.
+  if (classification == Token::TOKEN_INTEGER
+      && (*match == 'm' || *match == 'M' || *match == 'k' || *match == 'K'))
+    ++match;
+
   *pp = match;
   return this->make_token(classification, start, match - start, start);
 }