Use host_address_to_string in compile_cplus_instance::enter_scope
[deliverable/binutils-gdb.git] / libiberty / cplus-dem.c
index 3125a457b9d9800095ea863cacb0d0ba013c5f30..6d58bd899bf7d21144216db24d63376811d688fe 100644 (file)
@@ -1,6 +1,5 @@
 /* Demangler for GNU C++
-   Copyright 1989, 1991, 1994, 1995, 1996, 1997, 1998, 1999,
-   2000, 2001, 2002, 2003, 2004, 2010 Free Software Foundation, Inc.
+   Copyright (C) 1989-2018 Free Software Foundation, Inc.
    Written by James Clark (jjc@jclark.uucp)
    Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling
    Modified by Satish Pai (pai@apollo.hp.com) for HP demangling
@@ -322,6 +321,12 @@ const struct demangler_engine libiberty_demanglers[] =
     "DLANG style demangling"
   }
   ,
+  {
+    RUST_DEMANGLING_STYLE_STRING,
+    rust_demangling,
+    "Rust style demangling"
+  }
+  ,
   {
     NULL, unknown_demangling, NULL
   }
@@ -515,21 +520,17 @@ consume_count (const char **type)
 
   while (ISDIGIT ((unsigned char)**type))
     {
-      count *= 10;
-
-      /* Check for overflow.
-        We assume that count is represented using two's-complement;
-        no power of two is divisible by ten, so if an overflow occurs
-        when multiplying by ten, the result will not be a multiple of
-        ten.  */
-      if ((count % 10) != 0)
+      const int digit = **type - '0';
+      /* Check for overflow.  */
+      if (count > ((INT_MAX - digit) / 10))
        {
          while (ISDIGIT ((unsigned char) **type))
            (*type)++;
          return -1;
        }
 
-      count += **type - '0';
+      count *= 10;
+      count += digit;
       (*type)++;
     }
 
@@ -874,10 +875,26 @@ cplus_demangle (const char *mangled, int options)
     work->options |= (int) current_demangling_style & DMGL_STYLE_MASK;
 
   /* The V3 ABI demangling is implemented elsewhere.  */
-  if (GNU_V3_DEMANGLING || AUTO_DEMANGLING)
+  if (GNU_V3_DEMANGLING || RUST_DEMANGLING || AUTO_DEMANGLING)
     {
       ret = cplus_demangle_v3 (mangled, work->options);
-      if (ret || GNU_V3_DEMANGLING)
+      if (GNU_V3_DEMANGLING)
+       return ret;
+
+      if (ret)
+       {
+         /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.
+            The subtitutions are always smaller, so do in place changes.  */
+         if (rust_is_mangled (ret))
+           rust_demangle_sym (ret);
+         else if (RUST_DEMANGLING)
+           {
+             free (ret);
+             ret = NULL;
+           }
+       }
+
+      if (ret || RUST_DEMANGLING)
        return ret;
     }
 
@@ -903,6 +920,27 @@ cplus_demangle (const char *mangled, int options)
   return (ret);
 }
 
+char *
+rust_demangle (const char *mangled, int options)
+{
+  /* Rust symbols are GNU_V3 mangled plus some extra subtitutions.  */
+  char *ret = cplus_demangle_v3 (mangled, options);
+
+  /* The Rust subtitutions are always smaller, so do in place changes.  */
+  if (ret != NULL)
+    {
+      if (rust_is_mangled (ret))
+       rust_demangle_sym (ret);
+      else
+       {
+         free (ret);
+         ret = NULL;
+       }
+    }
+
+  return ret;
+}
+
 /* Demangle ada names.  The encoding is documented in gcc/ada/exp_dbug.ads.  */
 
 char *
@@ -3131,6 +3169,8 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
       delta = consume_count (mangled);
       if (delta == -1)
        success = 0;
+      else if (**mangled != '_')
+        success = 0;
       else
        {
          char *method = internal_cplus_demangle (work, ++*mangled);
This page took 0.024684 seconds and 4 git commands to generate.