]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Update libiberty demangler.
authorMark Wielaard <mark@klomp.org>
Wed, 12 Apr 2017 13:01:29 +0000 (13:01 +0000)
committerMark Wielaard <mark@klomp.org>
Wed, 12 Apr 2017 13:01:29 +0000 (13:01 +0000)
Update the libiberty demangler using the auxprogs/update-demangler
script to the gcc svn r246502 revision. Replaces our rust demangling
with the upstream variant (which is basically the same code in a
separate file). Adds handling of inheriting constructor. Handle
noexcept and throw-spec. Demangle Dc as decltype(auto). And various
(crasher) bug fixes.

Bug 378673.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16302

15 files changed:
NEWS
auxprogs/update-demangler
coregrind/Makefile.am
coregrind/m_demangle/ansidecl.h
coregrind/m_demangle/cp-demangle.c
coregrind/m_demangle/cp-demangle.h
coregrind/m_demangle/cplus-dem.c
coregrind/m_demangle/d-demangle.c
coregrind/m_demangle/demangle.c
coregrind/m_demangle/demangle.h
coregrind/m_demangle/dyn-string.c
coregrind/m_demangle/dyn-string.h
coregrind/m_demangle/rust-demangle.c [new file with mode: 0644]
coregrind/m_demangle/safe-ctype.c
coregrind/m_demangle/safe-ctype.h

diff --git a/NEWS b/NEWS
index a5392eef24c75754572cfa6815428b492c869684..24c38e03c811da220eaa73e912c8274cb2895c7e 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -155,6 +155,7 @@ where XXXXXX is the bug number as listed below.
 377717  Fix massive space leak when reading compressed debuginfo sections
 377930  fcntl syscall wrapper is missing flock structure check
 378535  Valgrind reports INTERNAL ERROR in execve syscall wrapper
+378673  Update libiberty demangler
 
 Release 3.12.0 (20 October 2016)
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
index 18189b3b7527626ca832cbd932e3380f084c4c76..8c1bbaa40324e8bcc4e3dcf57c099e49081928e9 100755 (executable)
@@ -17,8 +17,8 @@ set -e
 #---------------------------------------------------------------------
 
 # You need to modify these revision numbers for your update.
-old_gcc_revision=r212125  # the revision of the previous update
-new_gcc_revision=r240068  # the revision for this update
+old_gcc_revision=r240068  # the revision of the previous update
+new_gcc_revision=r246502  # the revision for this update
 
 # Unless the organization of demangler related files has changed, no
 # changes below this line should be necessary.
@@ -56,6 +56,7 @@ cp    ../gcc-$old_gcc_revision/libiberty/cp-demangle.h .
 cp    ../gcc-$old_gcc_revision/libiberty/cplus-dem.c .
 cp    ../gcc-$old_gcc_revision/libiberty/dyn-string.c .
 cp    ../gcc-$old_gcc_revision/libiberty/d-demangle.c .
+cp    ../gcc-$old_gcc_revision/libiberty/rust-demangle.c .
 cp    ../gcc-$old_gcc_revision/libiberty/safe-ctype.c .
 cd ..
 
@@ -83,6 +84,7 @@ cp    ../gcc-$new_gcc_revision/libiberty/cp-demangle.h .
 cp    ../gcc-$new_gcc_revision/libiberty/cplus-dem.c .
 cp    ../gcc-$new_gcc_revision/libiberty/dyn-string.c .
 cp    ../gcc-$new_gcc_revision/libiberty/d-demangle.c .
+cp    ../gcc-$new_gcc_revision/libiberty/rust-demangle.c .
 cp    ../gcc-$new_gcc_revision/libiberty/safe-ctype.c .
 cd ..
 
index 41c5ef49319b0b986de5ecf7d2ef407e732d0656..f3e49169c36e3671a6e33160c1d7fd641850b8d1 100644 (file)
@@ -362,6 +362,7 @@ COREGRIND_SOURCES_COMMON = \
        m_demangle/demangle.c \
        m_demangle/dyn-string.c \
        m_demangle/d-demangle.c \
+       m_demangle/rust-demangle.c \
        m_demangle/safe-ctype.c \
        m_dispatch/dispatch-x86-linux.S \
        m_dispatch/dispatch-amd64-linux.S \
index 6e4bfc21f25fba689eeb896486328f45cdc537b4..6c0c837bf23cb4f16d1551cd488ed4910abb9df0 100644 (file)
@@ -1,5 +1,5 @@
 /* ANSI and traditional C compatability macros
-   Copyright (C) 1991-2015 Free Software Foundation, Inc.
+   Copyright (C) 1991-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
 This program is free software; you can redistribute it and/or modify
@@ -313,13 +313,39 @@ So instead we use the macro below and test it against specific values.  */
 #define ENUM_BITFIELD(TYPE) unsigned int
 #endif
 
-    /* This is used to mark a class or virtual function as final.  */
-#if __cplusplus >= 201103L
-#define GCC_FINAL final
+/* C++11 adds the ability to add "override" after an implementation of a
+   virtual function in a subclass, to:
+     (A) document that this is an override of a virtual function
+     (B) allow the compiler to issue a warning if it isn't (e.g. a mismatch
+         of the type signature).
+
+   Similarly, it allows us to add a "final" to indicate that no subclass
+   may subsequently override the vfunc.
+
+   Provide OVERRIDE and FINAL as macros, allowing us to get these benefits
+   when compiling with C++11 support, but without requiring C++11.
+
+   For gcc, use "-std=c++11" to enable C++11 support; gcc 6 onwards enables
+   this by default (actually GNU++14).  */
+
+#if __cplusplus >= 201103
+/* C++11 claims to be available: use it.  final/override were only
+   implemented in 4.7, though.  */
+# if GCC_VERSION < 4007
+#  define OVERRIDE
+#  define FINAL
+# else
+#  define OVERRIDE override
+#  define FINAL final
+# endif
 #elif GCC_VERSION >= 4007
-#define GCC_FINAL __final
+/* G++ 4.7 supports __final in C++98.  */
+# define OVERRIDE
+# define FINAL __final
 #else
-#define GCC_FINAL
+/* No C++11 support; leave the macros empty: */
+# define OVERRIDE
+# define FINAL
 #endif
 
 #ifdef __cplusplus
index a3f78ab1085bf6cdc886566e77410291c48d2146..4a3fa5d1678ddb20cbaa4f5fb86de820065fd82c 100644 (file)
@@ -1,6 +1,5 @@
 /* Demangler for g++ V3 ABI.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2014
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@wasabisystems.com>.
 
    This file is part of the libiberty library, which is part of GCC.
@@ -190,10 +189,10 @@ static struct demangle_component *d_mangled_name (struct d_info *, int);
 static struct demangle_component *d_type (struct d_info *);
 
 #define cplus_demangle_print d_print
-static char *d_print (int, const struct demangle_component *, int, size_t *);
+static char *d_print (int, struct demangle_component *, int, size_t *);
 
 #define cplus_demangle_print_callback d_print_callback
-static int d_print_callback (int, const struct demangle_component *,
+static int d_print_callback (int, struct demangle_component *,
                              demangle_callbackref, void *);
 
 #define cplus_demangle_init_info d_init_info
@@ -282,7 +281,7 @@ struct d_print_mod
      in which they appeared in the mangled string.  */
   struct d_print_mod *next;
   /* The modifier.  */
-  const struct demangle_component *mod;
+  struct demangle_component *mod;
   /* Whether this modifier was printed.  */
   int printed;
   /* The list of templates which applies to this modifier.  */
@@ -360,6 +359,9 @@ struct d_print_info
   struct d_print_mod *modifiers;
   /* Set to 1 if we saw a demangling error.  */
   int demangle_failure;
+  /* Non-zero if we're printing a lambda argument.  A template
+     parameter reference actually means 'auto'.  */
+  int is_lambda_arg;
   /* The current index into any template argument packs we are using
      for printing, or -1 to print the whole pack.  */
   int pack_index;
@@ -453,6 +455,8 @@ static struct demangle_component *d_operator_name (struct d_info *);
 
 static struct demangle_component *d_special_name (struct d_info *);
 
+static struct demangle_component *d_parmlist (struct d_info *);
+
 static int d_call_offset (struct d_info *, int);
 
 static struct demangle_component *d_ctor_dtor_name (struct d_info *);
@@ -543,7 +547,7 @@ static inline void d_append_string (struct d_print_info *, const char *);
 static inline char d_last_char (struct d_print_info *);
 
 static void
-d_print_comp (struct d_print_info *, int, const struct demangle_component *);
+d_print_comp (struct d_print_info *, int, struct demangle_component *);
 
 static void
 d_print_java_identifier (struct d_print_info *, const char *, int);
@@ -552,30 +556,56 @@ static void
 d_print_mod_list (struct d_print_info *, int, struct d_print_mod *, int);
 
 static void
-d_print_mod (struct d_print_info *, int, const struct demangle_component *);
+d_print_mod (struct d_print_info *, int, struct demangle_component *);
 
 static void
 d_print_function_type (struct d_print_info *, int,
-                       const struct demangle_component *,
+                       struct demangle_component *,
                        struct d_print_mod *);
 
 static void
 d_print_array_type (struct d_print_info *, int,
-                    const struct demangle_component *,
+                    struct demangle_component *,
                     struct d_print_mod *);
 
 static void
-d_print_expr_op (struct d_print_info *, int, const struct demangle_component *);
+d_print_expr_op (struct d_print_info *, int, struct demangle_component *);
 
 static void d_print_cast (struct d_print_info *, int,
-                         const struct demangle_component *);
+                         struct demangle_component *);
 static void d_print_conversion (struct d_print_info *, int,
-                               const struct demangle_component *);
+                               struct demangle_component *);
 
 static int d_demangle_callback (const char *, int,
                                 demangle_callbackref, void *);
 static char *d_demangle (const char *, int, size_t *);
 
+/* True iff TYPE is a demangling component representing a
+   function-type-qualifier.  */
+
+static int
+is_fnqual_component_type (enum demangle_component_type type)
+{
+  return (type == DEMANGLE_COMPONENT_RESTRICT_THIS
+         || type == DEMANGLE_COMPONENT_VOLATILE_THIS
+         || type == DEMANGLE_COMPONENT_CONST_THIS
+         || type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
+         || type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
+         || type == DEMANGLE_COMPONENT_NOEXCEPT
+         || type == DEMANGLE_COMPONENT_THROW_SPEC
+         || type == DEMANGLE_COMPONENT_REFERENCE_THIS);
+}
+
+#define FNQUAL_COMPONENT_CASE                          \
+    case DEMANGLE_COMPONENT_RESTRICT_THIS:             \
+    case DEMANGLE_COMPONENT_VOLATILE_THIS:             \
+    case DEMANGLE_COMPONENT_CONST_THIS:                        \
+    case DEMANGLE_COMPONENT_REFERENCE_THIS:            \
+    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:     \
+    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:          \
+    case DEMANGLE_COMPONENT_NOEXCEPT:                  \
+    case DEMANGLE_COMPONENT_THROW_SPEC
+
 #ifdef CP_DEMANGLE_DEBUG
 
 static void
@@ -841,6 +871,7 @@ cplus_demangle_fill_name (struct demangle_component *p, const char *s, int len)
 {
   if (p == NULL || s == NULL || len == 0)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_NAME;
   p->u.s_name.s = s;
   p->u.s_name.len = len;
@@ -856,6 +887,7 @@ cplus_demangle_fill_extended_operator (struct demangle_component *p, int args,
 {
   if (p == NULL || args < 0 || name == NULL)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_EXTENDED_OPERATOR;
   p->u.s_extended_operator.args = args;
   p->u.s_extended_operator.name = name;
@@ -875,6 +907,7 @@ cplus_demangle_fill_ctor (struct demangle_component *p,
       || (int) kind < gnu_v3_complete_object_ctor
       || (int) kind > gnu_v3_object_ctor_group)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_CTOR;
   p->u.s_ctor.kind = kind;
   p->u.s_ctor.name = name;
@@ -894,6 +927,7 @@ cplus_demangle_fill_dtor (struct demangle_component *p,
       || (int) kind < gnu_v3_deleting_dtor
       || (int) kind > gnu_v3_object_dtor_group)
     return 0;
+  p->d_printing = 0;
   p->type = DEMANGLE_COMPONENT_DTOR;
   p->u.s_dtor.kind = kind;
   p->u.s_dtor.name = name;
@@ -910,6 +944,7 @@ d_make_empty (struct d_info *di)
   if (di->next_comp >= di->num_comps)
     return NULL;
   p = &di->comps[di->next_comp];
+  p->d_printing = 0;
   ++di->next_comp;
   return p;
 }
@@ -1001,14 +1036,9 @@ d_make_comp (struct d_info *di, enum demangle_component_type type,
     case DEMANGLE_COMPONENT_RESTRICT:
     case DEMANGLE_COMPONENT_VOLATILE:
     case DEMANGLE_COMPONENT_CONST:
-    case DEMANGLE_COMPONENT_RESTRICT_THIS:
-    case DEMANGLE_COMPONENT_VOLATILE_THIS:
-    case DEMANGLE_COMPONENT_CONST_THIS:
-    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
-    case DEMANGLE_COMPONENT_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_ARGLIST:
     case DEMANGLE_COMPONENT_TEMPLATE_ARGLIST:
+    FNQUAL_COMPONENT_CASE:
       break;
 
       /* Other types should not be seen here.  */
@@ -1242,12 +1272,7 @@ has_return_type (struct demangle_component *dc)
       return 0;
     case DEMANGLE_COMPONENT_TEMPLATE:
       return ! is_ctor_dtor_or_conversion (d_left (dc));
-    case DEMANGLE_COMPONENT_RESTRICT_THIS:
-    case DEMANGLE_COMPONENT_VOLATILE_THIS:
-    case DEMANGLE_COMPONENT_CONST_THIS:
-    case DEMANGLE_COMPONENT_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+    FNQUAL_COMPONENT_CASE:
       return has_return_type (d_left (dc));
     }
 }
@@ -1304,13 +1329,12 @@ d_encoding (struct d_info *di, int top_level)
          while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
                 || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
                 || dc->type == DEMANGLE_COMPONENT_CONST_THIS
-                || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
                 || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
                 || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
            dc = d_left (dc);
 
          /* If the top level is a DEMANGLE_COMPONENT_LOCAL_NAME, then
-            there may be CV-qualifiers on its right argument which
+            there may be function-qualifiers on its right argument which
             really apply here; this happens when parsing a class
             which is local to a function.  */
          if (dc->type == DEMANGLE_COMPONENT_LOCAL_NAME)
@@ -1318,12 +1342,7 @@ d_encoding (struct d_info *di, int top_level)
              struct demangle_component *dcr;
 
              dcr = d_right (dc);
-             while (dcr->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-                    || dcr->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-                    || dcr->type == DEMANGLE_COMPONENT_CONST_THIS
-                    || dcr->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-                    || dcr->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-                    || dcr->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
+             while (is_fnqual_component_type (dcr->type))
                dcr = d_left (dcr);
              dc->u.s_binary.right = dcr;
            }
@@ -1597,6 +1616,8 @@ d_unqualified_name (struct d_info *di)
     ret = d_source_name (di);
   else if (IS_LOWER (peek))
     {
+      if (peek == 'o' && d_peek_next_char (di) == 'n')
+       d_advance (di, 2);
       ret = d_operator_name (di);
       if (ret != NULL && ret->type == DEMANGLE_COMPONENT_OPERATOR)
        {
@@ -2185,6 +2206,13 @@ d_ctor_dtor_name (struct d_info *di)
     case 'C':
       {
        enum gnu_v3_ctor_kinds kind;
+       int inheriting = 0;
+
+       if (d_peek_next_char (di) == 'I')
+         {
+           inheriting = 1;
+           d_advance (di, 1);
+         }
 
        switch (d_peek_next_char (di))
          {
@@ -2206,7 +2234,12 @@ d_ctor_dtor_name (struct d_info *di)
          default:
            return NULL;
          }
+
        d_advance (di, 2);
+
+       if (inheriting)
+         cplus_demangle_type (di);
+
        return d_make_ctor (di, kind, di->last_name);
       }
 
@@ -2244,6 +2277,24 @@ d_ctor_dtor_name (struct d_info *di)
     }
 }
 
+/* True iff we're looking at an order-insensitive type-qualifier, including
+   function-type-qualifiers.  */
+
+static int
+next_is_type_qual (struct d_info *di)
+{
+  char peek = d_peek_char (di);
+  if (peek == 'r' || peek == 'V' || peek == 'K')
+    return 1;
+  if (peek == 'D')
+    {
+      peek = d_peek_next_char (di);
+      if (peek == 'x' || peek == 'o' || peek == 'O' || peek == 'w')
+       return 1;
+    }
+  return 0;
+}
+
 /* <type> ::= <builtin-type>
           ::= <function-type>
           ::= <class-enum-type>
@@ -2329,9 +2380,7 @@ cplus_demangle_type (struct d_info *di)
      __vector, and it treats it as order-sensitive when mangling
      names.  */
 
-  peek = d_peek_char (di);
-  if (peek == 'r' || peek == 'V' || peek == 'K'
-      || (peek == 'D' && d_peek_next_char (di) == 'x'))
+  if (next_is_type_qual (di))
     {
       struct demangle_component **pret;
 
@@ -2366,6 +2415,7 @@ cplus_demangle_type (struct d_info *di)
 
   can_subst = 1;
 
+  peek = d_peek_char (di);
   switch (peek)
     {
     case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'g':
@@ -2566,7 +2616,11 @@ cplus_demangle_type (struct d_info *di)
          /* auto */
          ret = d_make_name (di, "auto", 4);
          break;
-         
+       case 'c':
+         /* decltype(auto) */
+         ret = d_make_name (di, "decltype(auto)", 14);
+         break;
+
        case 'f':
          /* 32-bit decimal floating point */
          ret = d_make_builtin_type (di, &cplus_demangle_builtin_types[26]);
@@ -2653,10 +2707,10 @@ d_cv_qualifiers (struct d_info *di,
 
   pstart = pret;
   peek = d_peek_char (di);
-  while (peek == 'r' || peek == 'V' || peek == 'K'
-        || (peek == 'D' && d_peek_next_char (di) == 'x'))
+  while (next_is_type_qual (di))
     {
       enum demangle_component_type t;
+      struct demangle_component *right = NULL;
 
       d_advance (di, 1);
       if (peek == 'r')
@@ -2682,12 +2736,41 @@ d_cv_qualifiers (struct d_info *di,
        }
       else
        {
-         t = DEMANGLE_COMPONENT_TRANSACTION_SAFE;
-         di->expansion += sizeof "transaction_safe";
-         d_advance (di, 1);
+         peek = d_next_char (di);
+         if (peek == 'x')
+           {
+             t = DEMANGLE_COMPONENT_TRANSACTION_SAFE;
+             di->expansion += sizeof "transaction_safe";
+           }
+         else if (peek == 'o'
+                  || peek == 'O')
+           {
+             t = DEMANGLE_COMPONENT_NOEXCEPT;
+             di->expansion += sizeof "noexcept";
+             if (peek == 'O')
+               {
+                 right = d_expression (di);
+                 if (right == NULL)
+                   return NULL;
+                 if (! d_check_char (di, 'E'))
+                   return NULL;
+               }
+           }
+         else if (peek == 'w')
+           {
+             t = DEMANGLE_COMPONENT_THROW_SPEC;
+             di->expansion += sizeof "throw";
+             right = d_parmlist (di);
+             if (right == NULL)
+               return NULL;
+             if (! d_check_char (di, 'E'))
+               return NULL;
+           }
+         else
+           return NULL;
        }
 
-      *pret = d_make_comp (di, t, NULL, NULL);
+      *pret = d_make_comp (di, t, NULL, right);
       if (*pret == NULL)
        return NULL;
       pret = &d_left (*pret);
@@ -3362,6 +3445,8 @@ d_expression_1 (struct d_info *di)
                first = d_expression_1 (di);
                second = d_expression_1 (di);
                third = d_expression_1 (di);
+               if (third == NULL)
+                 return NULL;
              }
            else if (code[0] == 'f')
              {
@@ -3369,6 +3454,8 @@ d_expression_1 (struct d_info *di)
                first = d_operator_name (di);
                second = d_expression_1 (di);
                third = d_expression_1 (di);
+               if (third == NULL)
+                 return NULL;
              }
            else if (code[0] == 'n')
              {
@@ -3546,7 +3633,11 @@ d_local_name (struct d_info *di)
     }
 }
 
-/* <discriminator> ::= _ <(non-negative) number>
+/* <discriminator> ::= _ <number>    # when number < 10
+                   ::= __ <number> _ # when number >= 10
+
+   <discriminator> ::= _ <number>    # when number >=10
+   is also accepted to support gcc versions that wrongly mangled that way.
 
    We demangle the discriminator, but we don't print it out.  FIXME:
    We should print it out in verbose mode.  */
@@ -3554,14 +3645,28 @@ d_local_name (struct d_info *di)
 static int
 d_discriminator (struct d_info *di)
 {
-  int discrim;
+  int discrim, num_underscores = 1;
 
   if (d_peek_char (di) != '_')
     return 1;
   d_advance (di, 1);
+  if (d_peek_char (di) == '_')
+    {
+      ++num_underscores;
+      d_advance (di, 1);
+    }
+
   discrim = d_number (di);
   if (discrim < 0)
     return 0;
+  if (num_underscores > 1 && discrim >= 10)
+    {
+      if (d_peek_char (di) == '_')
+       d_advance (di, 1);
+      else
+       return 0;
+    }
+
   return 1;
 }
 
@@ -3978,6 +4083,8 @@ d_count_templates_scopes (int *num_templates, int *num_scopes,
     case DEMANGLE_COMPONENT_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+    case DEMANGLE_COMPONENT_NOEXCEPT:
+    case DEMANGLE_COMPONENT_THROW_SPEC:
     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
     case DEMANGLE_COMPONENT_POINTER:
     case DEMANGLE_COMPONENT_COMPLEX:
@@ -4067,6 +4174,7 @@ d_print_init (struct d_print_info *dpi, demangle_callbackref callback,
   dpi->opaque = opaque;
 
   dpi->demangle_failure = 0;
+  dpi->is_lambda_arg = 0;
 
   dpi->component_stack = NULL;
 
@@ -4163,7 +4271,7 @@ d_last_char (struct d_print_info *dpi)
 CP_STATIC_IF_GLIBCPP_V3
 int
 cplus_demangle_print_callback (int options,
-                               const struct demangle_component *dc,
+                               struct demangle_component *dc,
                                demangle_callbackref callback, void *opaque)
 {
   struct d_print_info dpi;
@@ -4222,7 +4330,7 @@ cplus_demangle_print_callback (int options,
 
 CP_STATIC_IF_GLIBCPP_V3
 char *
-cplus_demangle_print (int options, const struct demangle_component *dc,
+cplus_demangle_print (int options, struct demangle_component *dc,
                       int estimate, size_t *palc)
 {
   struct d_growable_string dgs;
@@ -4382,7 +4490,7 @@ d_args_length (struct d_print_info *dpi, const struct demangle_component *dc)
 
 static void
 d_print_subexpr (struct d_print_info *dpi, int options,
-                const struct demangle_component *dc)
+                struct demangle_component *dc)
 {
   int simple = 0;
   if (dc->type == DEMANGLE_COMPONENT_NAME
@@ -4458,9 +4566,9 @@ d_get_saved_scope (struct d_print_info *dpi,
 
 static int
 d_maybe_print_fold_expression (struct d_print_info *dpi, int options,
-                              const struct demangle_component *dc)
+                              struct demangle_component *dc)
 {
-  const struct demangle_component *ops, *operator_, *op1, *op2;
+  struct demangle_component *ops, *operator_, *op1, *op2;
   int save_idx;
 
   const char *fold_code = d_left (dc)->u.s_operator.op->code;
@@ -4521,11 +4629,11 @@ d_maybe_print_fold_expression (struct d_print_info *dpi, int options,
 
 static void
 d_print_comp_inner (struct d_print_info *dpi, int options,
-                 const struct demangle_component *dc)
+                   struct demangle_component *dc)
 {
   /* Magic variable to let reference smashing skip over the next modifier
      without needing to modify *dc.  */
-  const struct demangle_component *mod_inner = NULL;
+  struct demangle_component *mod_inner = NULL;
 
   /* Variable used to store the current templates while a previously
      captured scope is used.  */
@@ -4608,12 +4716,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
            adpm[i].templates = dpi->templates;
            ++i;
 
-           if (typed_name->type != DEMANGLE_COMPONENT_RESTRICT_THIS
-               && typed_name->type != DEMANGLE_COMPONENT_VOLATILE_THIS
-               && typed_name->type != DEMANGLE_COMPONENT_CONST_THIS
-               && typed_name->type != DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS
-               && typed_name->type != DEMANGLE_COMPONENT_TRANSACTION_SAFE
-               && typed_name->type != DEMANGLE_COMPONENT_REFERENCE_THIS)
+           if (!is_fnqual_component_type (typed_name->type))
              break;
 
            typed_name = d_left (typed_name);
@@ -4650,13 +4753,7 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
                d_print_error (dpi);
                return;
              }
-           while (local_name->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-                  || local_name->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-                  || local_name->type == DEMANGLE_COMPONENT_CONST_THIS
-                  || local_name->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-                  || local_name->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-                  || (local_name->type
-                      == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))
+           while (is_fnqual_component_type (local_name->type))
              {
                if (i >= sizeof adpm / sizeof adpm[0])
                  {
@@ -4751,33 +4848,41 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       }
 
     case DEMANGLE_COMPONENT_TEMPLATE_PARAM:
-      {
-       struct d_print_template *hold_dpt;
-       struct demangle_component *a = d_lookup_template_argument (dpi, dc);
-
-       if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
-         a = d_index_template_argument (a, dpi->pack_index);
+      if (dpi->is_lambda_arg)
+       {
+         /* Show the template parm index, as that's how g++ displays
+            these, and future proofs us against potential
+            '[]<typename T> (T *a, T *b) {...}'.  */
+         d_append_buffer (dpi, "auto:", 5);
+         d_append_num (dpi, dc->u.s_number.number + 1);
+       }
+      else
+       {
+         struct d_print_template *hold_dpt;
+         struct demangle_component *a = d_lookup_template_argument (dpi, dc);
 
-       if (a == NULL)
-         {
-           d_print_error (dpi);
-           return;
-         }
+         if (a && a->type == DEMANGLE_COMPONENT_TEMPLATE_ARGLIST)
+           a = d_index_template_argument (a, dpi->pack_index);
 
-       /* While processing this parameter, we need to pop the list of
-          templates.  This is because the template parameter may
-          itself be a reference to a parameter of an outer
-          template.  */
+         if (a == NULL)
+           {
+             d_print_error (dpi);
+             return;
+           }
 
-       hold_dpt = dpi->templates;
-       dpi->templates = hold_dpt->next;
+         /* While processing this parameter, we need to pop the list
+            of templates.  This is because the template parameter may
+            itself be a reference to a parameter of an outer
+            template.  */
 
-       d_print_comp (dpi, options, a);
+         hold_dpt = dpi->templates;
+         dpi->templates = hold_dpt->next;
 
-       dpi->templates = hold_dpt;
+         d_print_comp (dpi, options, a);
 
-       return;
-      }
+         dpi->templates = hold_dpt;
+       }
+      return;
 
     case DEMANGLE_COMPONENT_CTOR:
       d_print_comp (dpi, options, dc->u.s_ctor.name);
@@ -4913,8 +5018,9 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
     case DEMANGLE_COMPONENT_RVALUE_REFERENCE:
       {
        /* Handle reference smashing: & + && = &.  */
-       const struct demangle_component *sub = d_left (dc);
-       if (sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
+       struct demangle_component *sub = d_left (dc);
+       if (!dpi->is_lambda_arg
+           && sub->type == DEMANGLE_COMPONENT_TEMPLATE_PARAM)
          {
            struct d_saved_scope *scope = d_get_saved_scope (dpi, sub);
            struct demangle_component *a;
@@ -4981,16 +5087,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
       }
       /* Fall through.  */
 
-    case DEMANGLE_COMPONENT_RESTRICT_THIS:
-    case DEMANGLE_COMPONENT_VOLATILE_THIS:
-    case DEMANGLE_COMPONENT_CONST_THIS:
-    case DEMANGLE_COMPONENT_REFERENCE_THIS:
-    case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
     case DEMANGLE_COMPONENT_POINTER:
     case DEMANGLE_COMPONENT_COMPLEX:
     case DEMANGLE_COMPONENT_IMAGINARY:
-    case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+    FNQUAL_COMPONENT_CASE:
     modifier:
       {
        /* We keep a list of modifiers on the stack.  */
@@ -5589,7 +5690,11 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 
     case DEMANGLE_COMPONENT_LAMBDA:
       d_append_string (dpi, "{lambda(");
+      /* Generic lambda auto parms are mangled as the template type
+        parm they are.  */
+      dpi->is_lambda_arg++;
       d_print_comp (dpi, options, dc->u.s_unary_num.sub);
+      dpi->is_lambda_arg--;
       d_append_string (dpi, ")#");
       d_append_num (dpi, dc->u.s_unary_num.num + 1);
       d_append_char (dpi, '}');
@@ -5616,9 +5721,16 @@ d_print_comp_inner (struct d_print_info *dpi, int options,
 
 static void
 d_print_comp (struct d_print_info *dpi, int options,
-             const struct demangle_component *dc)
+             struct demangle_component *dc)
 {
   struct d_component_stack self;
+  if (dc == NULL || dc->d_printing > 1)
+    {
+      d_print_error (dpi);
+      return;
+    }
+  else
+    dc->d_printing++;
 
   self.dc = dc;
   self.parent = dpi->component_stack;
@@ -5627,6 +5739,7 @@ d_print_comp (struct d_print_info *dpi, int options,
   d_print_comp_inner (dpi, options, dc);
 
   dpi->component_stack = self.parent;
+  dc->d_printing--;
 }
 
 /* Print a Java dentifier.  For Java we try to handle encoded extended
@@ -5695,13 +5808,7 @@ d_print_mod_list (struct d_print_info *dpi, int options,
 
   if (mods->printed
       || (! suffix
-         && (mods->mod->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-             || mods->mod->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-             || mods->mod->type == DEMANGLE_COMPONENT_CONST_THIS
-             || mods->mod->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-             || mods->mod->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-             || (mods->mod->type
-                 == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS))))
+         && (is_fnqual_component_type (mods->mod->type))))
     {
       d_print_mod_list (dpi, options, mods->next, suffix);
       return;
@@ -5754,12 +5861,7 @@ d_print_mod_list (struct d_print_info *dpi, int options,
          dc = dc->u.s_unary_num.sub;
        }
 
-      while (dc->type == DEMANGLE_COMPONENT_RESTRICT_THIS
-            || dc->type == DEMANGLE_COMPONENT_VOLATILE_THIS
-            || dc->type == DEMANGLE_COMPONENT_CONST_THIS
-            || dc->type == DEMANGLE_COMPONENT_REFERENCE_THIS
-            || dc->type == DEMANGLE_COMPONENT_TRANSACTION_SAFE
-            || dc->type == DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS)
+      while (is_fnqual_component_type (dc->type))
        dc = d_left (dc);
 
       d_print_comp (dpi, options, dc);
@@ -5779,7 +5881,7 @@ d_print_mod_list (struct d_print_info *dpi, int options,
 
 static void
 d_print_mod (struct d_print_info *dpi, int options,
-             const struct demangle_component *mod)
+             struct demangle_component *mod)
 {
   switch (mod->type)
     {
@@ -5798,6 +5900,24 @@ d_print_mod (struct d_print_info *dpi, int options,
     case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
       d_append_string (dpi, " transaction_safe");
       return;
+    case DEMANGLE_COMPONENT_NOEXCEPT:
+      d_append_string (dpi, " noexcept");
+      if (d_right (mod))
+       {
+         d_append_char (dpi, '(');
+         d_print_comp (dpi, options, d_right (mod));
+         d_append_char (dpi, ')');
+       }
+      return;
+    case DEMANGLE_COMPONENT_THROW_SPEC:
+      d_append_string (dpi, " throw");
+      if (d_right (mod))
+       {
+         d_append_char (dpi, '(');
+         d_print_comp (dpi, options, d_right (mod));
+         d_append_char (dpi, ')');
+       }
+      return;
     case DEMANGLE_COMPONENT_VENDOR_TYPE_QUAL:
       d_append_char (dpi, ' ');
       d_print_comp (dpi, options, d_right (mod));
@@ -5853,7 +5973,7 @@ d_print_mod (struct d_print_info *dpi, int options,
 
 static void
 d_print_function_type (struct d_print_info *dpi, int options,
-                       const struct demangle_component *dc,
+                       struct demangle_component *dc,
                        struct d_print_mod *mods)
 {
   int need_paren;
@@ -5885,12 +6005,7 @@ d_print_function_type (struct d_print_info *dpi, int options,
          need_space = 1;
          need_paren = 1;
          break;
-       case DEMANGLE_COMPONENT_RESTRICT_THIS:
-       case DEMANGLE_COMPONENT_VOLATILE_THIS:
-       case DEMANGLE_COMPONENT_CONST_THIS:
-       case DEMANGLE_COMPONENT_REFERENCE_THIS:
-       case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
-       case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
+       FNQUAL_COMPONENT_CASE:
          break;
        default:
          break;
@@ -5936,7 +6051,7 @@ d_print_function_type (struct d_print_info *dpi, int options,
 
 static void
 d_print_array_type (struct d_print_info *dpi, int options,
-                    const struct demangle_component *dc,
+                    struct demangle_component *dc,
                     struct d_print_mod *mods)
 {
   int need_space;
@@ -5990,7 +6105,7 @@ d_print_array_type (struct d_print_info *dpi, int options,
 
 static void
 d_print_expr_op (struct d_print_info *dpi, int options,
-                 const struct demangle_component *dc)
+                 struct demangle_component *dc)
 {
   if (dc->type == DEMANGLE_COMPONENT_OPERATOR)
     d_append_buffer (dpi, dc->u.s_operator.op->name,
@@ -6003,7 +6118,7 @@ d_print_expr_op (struct d_print_info *dpi, int options,
 
 static void
 d_print_cast (struct d_print_info *dpi, int options,
-                   const struct demangle_component *dc)
+             struct demangle_component *dc)
 {
   d_print_comp (dpi, options, d_left (dc));
 }
@@ -6012,7 +6127,7 @@ d_print_cast (struct d_print_info *dpi, int options,
 
 static void
 d_print_conversion (struct d_print_info *dpi, int options,
-                   const struct demangle_component *dc)
+                   struct demangle_component *dc)
 {
   struct d_print_template dpt;
 
@@ -6451,7 +6566,6 @@ is_ctor_or_dtor (const char *mangled,
          case DEMANGLE_COMPONENT_CONST_THIS:
          case DEMANGLE_COMPONENT_REFERENCE_THIS:
          case DEMANGLE_COMPONENT_RVALUE_REFERENCE_THIS:
-         case DEMANGLE_COMPONENT_TRANSACTION_SAFE:
          default:
            dc = NULL;
            break;
index 197883e25602f4d8d506de50c6b5d6f800babc97..a2657755f11d5359794857eb43e61bbd1656ae49 100644 (file)
@@ -1,6 +1,5 @@
 /* Internal demangler interface for g++ V3 ABI.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2017 Free Software Foundation, Inc.
    Written by Ian Lance Taylor <ian@wasabisystems.com>.
 
    This file is part of the libiberty library, which is part of GCC.
index d00f79fa5427188c0c614edf84f096101174581c..9cdf40ba94acc18d2dd433d82e5a13b717776183 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-2017 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
@@ -342,6 +341,12 @@ const struct demangler_engine libiberty_demanglers[] =
     "DLANG style demangling"
   }
   ,
+  {
+    RUST_DEMANGLING_STYLE_STRING,
+    rust_demangling,
+    "Rust style demangling"
+  }
+  ,
   {
     NULL, unknown_demangling, NULL
   }
@@ -893,10 +898,26 @@ ML_(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;
     }
 
@@ -922,6 +943,27 @@ ML_(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 *
@@ -930,7 +972,7 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
   int len0;
   const char* p;
   char *d;
-  char *demangled;
+  char *demangled = NULL;
   
   /* Discard leading _ada_, which is used for library level subprograms.  */
   if (strncmp (mangled, "_ada_", 5) == 0)
@@ -1175,6 +1217,7 @@ ada_demangle (const char *mangled, int option ATTRIBUTE_UNUSED)
   return demangled;
 
  unknown:
+  XDELETEVEC (demangled);
   len0 = strlen (mangled);
   demangled = XNEWVEC (char, len0 + 3);
 
@@ -1672,12 +1715,13 @@ demangle_signature (struct work_stuff *work,
                                           0);
              if (!(work->constructor & 1))
                expect_return_type = 1;
-             (*mangled)++;
+             if (!**mangled)
+               success = 0;
+             else
+               (*mangled)++;
              break;
            }
-         else
-           /* fall through */
-           {;}
+         /* fall through */
 
        default:
          if (AUTO_DEMANGLING || GNU_DEMANGLING)
@@ -2153,6 +2197,8 @@ demangle_template (struct work_stuff *work, const char **mangled,
        {
          int idx;
          (*mangled)++;
+         if (**mangled == '\0')
+           return (0);
          (*mangled)++;
 
          idx = consume_count_with_underscores (mangled);
@@ -2997,7 +3043,7 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
   int success = 1;
   const char *p;
 
-  if ((*mangled)[0] == '_'
+  if ((*mangled)[0] == '_' && (*mangled)[1] != '\0'
       && strchr (cplus_markers, (*mangled)[1]) != NULL
       && (*mangled)[2] == '_')
     {
@@ -3011,7 +3057,7 @@ gnu_special (struct work_stuff *work, const char **mangled, string *declp)
                && (*mangled)[3] == 't'
                && (*mangled)[4] == '_')
               || ((*mangled)[1] == 'v'
-                  && (*mangled)[2] == 't'
+                  && (*mangled)[2] == 't' && (*mangled)[3] != '\0'
                   && strchr (cplus_markers, (*mangled)[3]) != NULL)))
     {
       /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>"
@@ -3781,11 +3827,12 @@ do_type (struct work_stuff *work, const char **mangled, string *result)
                    break;
                  }
 
-               if (*(*mangled)++ != 'F')
+               if (*(*mangled) != 'F')
                  {
                    success = 0;
                    break;
                  }
+               (*mangled)++;
              }
            if ((member && !demangle_nested_args (work, mangled, &decl))
                || **mangled != '_')
@@ -4042,6 +4089,7 @@ demangle_fund_type (struct work_stuff *work,
          success = 0;
          break;
        }
+      /* fall through */
     case 'I':
       (*mangled)++;
       if (**mangled == '_')
index 129999cbf313420a6d08d4378c01c70fd76addd8..f9a7f1df8d35d009e5b4a42f9f3e0024ff8d7824 100644 (file)
@@ -1,5 +1,5 @@
 /* Demangler for the D programming language
-   Copyright 2014, 2015, 2016 Free Software Foundation, Inc.
+   Copyright (C) 2014-2017 Free Software Foundation, Inc.
    Written by Iain Buclaw (ibuclaw@gdcproject.org)
 
 This file is part of the libiberty library.
index c8a9ca5d05fdbb985f445617a2d124de03af6bd9..4a0967b57db74e3c3f8c5b4cdea0b7c2dddf5953 100644 (file)
 #include "vg_libciface.h"
 #include "demangle.h"
 
-/* fwds */
-static Bool rust_is_mangled ( const HChar* );
-static void rust_demangle_sym ( HChar* );
-
 
 /*------------------------------------------------------------*/
 /*---                                                      ---*/
@@ -408,297 +404,6 @@ Bool VG_(maybe_Z_demangle) ( const HChar* sym,
 }
 
 
-/*------------------------------------------------------------*/
-/*--- DEMANGLE RUST NAMES                                  ---*/
-/*------------------------------------------------------------*/
-
-/*
- * Mangled Rust symbols look like this:
- *
- *     _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
- *
- * The original symbol is:
- *
- *     <std::sys::fd::FileDesc as core::ops::Drop>::drop
- *
- * The last component of the path is a 64-bit hash in lowercase hex, prefixed
- * with "h". Rust does not have a global namespace between crates, an illusion
- * which Rust maintains by using the hash to distinguish things that would
- * otherwise have the same symbol.
- *
- * Any path component not starting with a XID_Start character is prefixed with
- * "_".
- *
- * The following escape sequences are used:
- *
- *     ","  =>  $C$
- *     "@"  =>  $SP$
- *     "*"  =>  $BP$
- *     "&"  =>  $RF$
- *     "<"  =>  $LT$
- *     ">"  =>  $GT$
- *     "("  =>  $LP$
- *     ")"  =>  $RP$
- *     " "  =>  $u20$
- *     "\"" =>  $u22$
- *     "'"  =>  $u27$
- *     "+"  =>  $u2b$
- *     ";"  =>  $u3b$
- *     "["  =>  $u5b$
- *     "]"  =>  $u5d$
- *     "{"  =>  $u7b$
- *     "}"  =>  $u7d$
- *     "~"  =>  $u7e$
- *
- * A double ".." means "::" and a single "." means "-".
- *
- * The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$
- */
-
-static const HChar *hash_prefix = "::h";
-static const SizeT  hash_prefix_len = 3;
-static const SizeT  hash_len = 16;
-
-static Bool is_prefixed_hash(const HChar *start);
-static Bool looks_like_rust(const HChar *sym, SizeT len);
-static Bool unescape(const HChar **in, HChar **out,
-                     const HChar *seq, HChar value);
-
-/*
- * INPUT:
- *     sym: symbol that has been through BFD-demangling
- *
- * This function looks for the following indicators:
- *
- *  1. The hash must consist of "h" followed by 16 lowercase hex digits.
- *
- *  2. As a sanity check, the hash must use between 5 and 15 of the 16 possible
- *     hex digits. This is true of 99.9998% of hashes so once in your life you
- *     may see a false negative. The point is to notice path components that
- *     could be Rust hashes but are probably not, like "haaaaaaaaaaaaaaaa". In
- *     this case a false positive (non-Rust symbol has an important path
- *     component removed because it looks like a Rust hash) is worse than a
- *     false negative (the rare Rust symbol is not demangled) so this sets the
- *     balance in favor of false negatives.
- *
- *  3. There must be no characters other than a-zA-Z0-9 and _.:$
- *
- *  4. There must be no unrecognized $-sign sequences.
- *
- *  5. There must be no sequence of three or more dots in a row ("...").
- */
-static Bool rust_is_mangled(const HChar *sym)
-{
-   SizeT len, len_without_hash;
-
-   if (!sym)
-      return False;
-
-   len = VG_(strlen)(sym);
-   if (len <= hash_prefix_len + hash_len)
-      /* Not long enough to contain "::h" + hash + something else */
-      return False;
-
-   len_without_hash = len - (hash_prefix_len + hash_len);
-   if (!is_prefixed_hash(sym + len_without_hash))
-      return False;
-
-   return looks_like_rust(sym, len_without_hash);
-}
-
-/*
- * A hash is the prefix "::h" followed by 16 lowercase hex digits. The hex
- * digits must comprise between 5 and 15 (inclusive) distinct digits.
- */
-static Bool is_prefixed_hash(const HChar *str)
-{
-   const HChar *end;
-   Bool seen[16];
-   SizeT i;
-   Int count;
-
-   if (VG_(strncmp)(str, hash_prefix, hash_prefix_len))
-      return False;
-   str += hash_prefix_len;
-
-   VG_(memset)(seen, False, sizeof(seen));
-   for (end = str + hash_len; str < end; str++)
-      if (*str >= '0' && *str <= '9')
-         seen[*str - '0'] = True;
-      else if (*str >= 'a' && *str <= 'f')
-         seen[*str - 'a' + 10] = True;
-      else
-         return False;
-
-   /* Count how many distinct digits seen */
-   count = 0;
-   for (i = 0; i < 16; i++)
-      if (seen[i])
-         count++;
-
-   return count >= 5 && count <= 15;
-}
-
-static Bool looks_like_rust(const HChar *str, SizeT len)
-{
-   const HChar *end = str + len;
-
-   while (str < end) {
-      switch (*str) {
-      case '$':
-         if (!VG_(strncmp)(str, "$C$", 3))
-            str += 3;
-         else if (!VG_(strncmp)(str, "$SP$", 4)
-                  || !VG_(strncmp)(str, "$BP$", 4)
-                  || !VG_(strncmp)(str, "$RF$", 4)
-                  || !VG_(strncmp)(str, "$LT$", 4)
-                  || !VG_(strncmp)(str, "$GT$", 4)
-                  || !VG_(strncmp)(str, "$LP$", 4)
-                  || !VG_(strncmp)(str, "$RP$", 4))
-            str += 4;
-         else if (!VG_(strncmp)(str, "$u20$", 5)
-                  || !VG_(strncmp)(str, "$u22$", 5)
-                  || !VG_(strncmp)(str, "$u27$", 5)
-                  || !VG_(strncmp)(str, "$u2b$", 5)
-                  || !VG_(strncmp)(str, "$u3b$", 5)
-                  || !VG_(strncmp)(str, "$u5b$", 5)
-                  || !VG_(strncmp)(str, "$u5d$", 5)
-                  || !VG_(strncmp)(str, "$u7b$", 5)
-                  || !VG_(strncmp)(str, "$u7d$", 5)
-                  || !VG_(strncmp)(str, "$u7e$", 5))
-            str += 5;
-         else
-            return False;
-         break;
-      case '.':
-         /* Do not allow three or more consecutive dots */
-         if (!VG_(strncmp)(str, "...", 3))
-            return False;
-         /* Fall through */
-      case 'a' ... 'z':
-      case 'A' ... 'Z':
-      case '0' ... '9':
-      case '_':
-      case ':':
-         str++;
-         break;
-      default:
-         return False;
-      }
-   }
-
-   return True;
-}
-
-/*
- * INPUT:
- *     sym: symbol for which rust_is_mangled(sym) returns True
- *
- * The input is demangled in-place because the mangled name is always longer
- * than the demangled one.
- */
-static void rust_demangle_sym(HChar *sym)
-{
-   const HChar *in;
-   HChar *out;
-   const HChar *end;
-
-   if (!sym)
-      return;
-
-   const SizeT  sym_len     = VG_(strlen)(sym);
-   const HChar* never_after = sym + sym_len;
-
-   in = sym;
-   out = sym;
-   end = sym + sym_len - (hash_prefix_len + hash_len);
-
-   while (in < end) {
-      switch (*in) {
-      case '$':
-         if (!(unescape(&in, &out, "$C$", ',')
-               || unescape(&in, &out, "$SP$", '@')
-               || unescape(&in, &out, "$BP$", '*')
-               || unescape(&in, &out, "$RF$", '&')
-               || unescape(&in, &out, "$LT$", '<')
-               || unescape(&in, &out, "$GT$", '>')
-               || unescape(&in, &out, "$LP$", '(')
-               || unescape(&in, &out, "$RP$", ')')
-               || unescape(&in, &out, "$u20$", ' ')
-               || unescape(&in, &out, "$u22$", '\"')
-               || unescape(&in, &out, "$u27$", '\'')
-               || unescape(&in, &out, "$u2b$", '+')
-               || unescape(&in, &out, "$u3b$", ';')
-               || unescape(&in, &out, "$u5b$", '[')
-               || unescape(&in, &out, "$u5d$", ']')
-               || unescape(&in, &out, "$u7b$", '{')
-               || unescape(&in, &out, "$u7d$", '}')
-               || unescape(&in, &out, "$u7e$", '~'))) {
-            goto fail;
-         }
-         break;
-      case '_':
-         /*
-          * If this is the start of a path component and the next
-          * character is an escape sequence, ignore the
-          * underscore. The mangler inserts an underscore to make
-          * sure the path component begins with a XID_Start
-          * character.
-          */
-         if ((in == sym || in[-1] == ':') && in[1] == '$')
-            in++;
-         else
-            *out++ = *in++;
-         break;
-      case '.':
-         if (in[1] == '.') {
-            /* ".." becomes "::" */
-            *out++ = ':';
-            *out++ = ':';
-            in += 2;
-         } else {
-            /* "." becomes "-" */
-            *out++ = '-';
-            in++;
-         }
-         break;
-      case 'a' ... 'z':
-      case 'A' ... 'Z':
-      case '0' ... '9':
-      case ':':
-         *out++ = *in++;
-         break;
-      default:
-         goto fail;
-      }
-   }
-   goto done;
-
-  fail:
-   *out++ = '?'; /* This is pretty lame, but it's hard to do better. */
-  done:
-   *out++ = '\0';
-
-   vg_assert(out <= never_after);
-}
-
-static Bool unescape(const HChar **in, HChar **out,
-                     const HChar *seq, HChar value)
-{
-   SizeT len = VG_(strlen)(seq);
-
-   if (VG_(strncmp)(*in, seq, len))
-      return False;
-
-   **out = value;
-
-   *in += len;
-   *out += 1;
-
-   return True;
-}
-
-
 /*--------------------------------------------------------------------*/
 /*--- end                                                          ---*/
 /*--------------------------------------------------------------------*/
index b3439d957700e9e79e860093f825805e029886f8..f5a214362d0a402d0b7d0582d20cc8705d10e979 100644 (file)
@@ -1,5 +1,5 @@
 /* Defs for interface to demanglers.
-   Copyright (C) 1992-2015 Free Software Foundation, Inc.
+   Copyright (C) 1992-2017 Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public License
@@ -65,9 +65,10 @@ extern "C" {
 #define DMGL_GNU_V3     (1 << 14)
 #define DMGL_GNAT       (1 << 15)
 #define DMGL_DLANG      (1 << 16)
+#define DMGL_RUST       (1 << 17)      /* Rust wraps GNU_V3 style mangling.  */
 
 /* If none of these are set, use 'current_demangling_style' as the default. */
-#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG)
+#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG|DMGL_GNU_V3|DMGL_JAVA|DMGL_GNAT|DMGL_DLANG|DMGL_RUST)
 
 /* Enumeration of possible demangling styles.
 
@@ -90,7 +91,8 @@ extern enum demangling_styles
   gnu_v3_demangling = DMGL_GNU_V3,
   java_demangling = DMGL_JAVA,
   gnat_demangling = DMGL_GNAT,
-  dlang_demangling = DMGL_DLANG
+  dlang_demangling = DMGL_DLANG,
+  rust_demangling = DMGL_RUST
 } current_demangling_style;
 
 /* Define string names for the various demangling styles. */
@@ -106,6 +108,7 @@ extern enum demangling_styles
 #define JAVA_DEMANGLING_STYLE_STRING          "java"
 #define GNAT_DEMANGLING_STYLE_STRING          "gnat"
 #define DLANG_DEMANGLING_STYLE_STRING         "dlang"
+#define RUST_DEMANGLING_STYLE_STRING          "rust"
 
 /* Some macros to test what demangling style is active. */
 
@@ -120,6 +123,7 @@ extern enum demangling_styles
 #define JAVA_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_JAVA)
 #define GNAT_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNAT)
 #define DLANG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_DLANG)
+#define RUST_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_RUST)
 
 /* Provide information about the available demangle styles. This code is
    pulled from gdb into libiberty because it is useful to binutils also.  */
@@ -177,6 +181,27 @@ ada_demangle (const char *mangled, int options);
 extern char *
 dlang_demangle (const char *mangled, int options);
 
+/* Returns non-zero iff MANGLED is a rust mangled symbol.  MANGLED must
+   already have been demangled through cplus_demangle_v3.  If this function
+   returns non-zero then MANGLED can be demangled (in-place) using
+   RUST_DEMANGLE_SYM.  */
+extern int
+rust_is_mangled (const char *mangled);
+
+/* Demangles SYM (in-place) if RUST_IS_MANGLED returned non-zero for SYM.
+   If RUST_IS_MANGLED returned zero for SYM then RUST_DEMANGLE_SYM might
+   replace characters that cannot be demangled with '?' and might truncate
+   SYM.  After calling RUST_DEMANGLE_SYM SYM might be shorter, but never
+   larger.  */
+extern void
+rust_demangle_sym (char *sym);
+
+/* Demangles MANGLED if it was GNU_V3 and then RUST mangled, otherwise
+   returns NULL. Uses CPLUS_DEMANGLE_V3, RUST_IS_MANGLED and
+   RUST_DEMANGLE_SYM.  Returns a new string that is owned by the caller.  */
+extern char *
+rust_demangle (const char *mangled, int options);
+
 enum gnu_v3_ctor_kinds {
   gnu_v3_complete_object_ctor = 1,
   gnu_v3_base_object_ctor,
@@ -451,7 +476,9 @@ enum demangle_component_type
   /* A transaction-safe function type.  */
   DEMANGLE_COMPONENT_TRANSACTION_SAFE,
   /* A cloned function.  */
-  DEMANGLE_COMPONENT_CLONE
+  DEMANGLE_COMPONENT_CLONE,
+  DEMANGLE_COMPONENT_NOEXCEPT,
+  DEMANGLE_COMPONENT_THROW_SPEC
 };
 
 /* Types which are only used internally.  */
@@ -469,6 +496,11 @@ struct demangle_component
   /* The type of this component.  */
   enum demangle_component_type type;
 
+  /* Guard against recursive component printing.
+     Initialize to zero.  Private to d_print_comp.
+     All other fields are final after initialization.  */
+  int d_printing;
+
   union
   {
     /* For DEMANGLE_COMPONENT_NAME.  */
@@ -663,7 +695,7 @@ cplus_demangle_v3_components (const char *mangled, int options, void **mem);
 
 extern char *
 cplus_demangle_print (int options,
-                      const struct demangle_component *tree,
+                      struct demangle_component *tree,
                       int estimated_length,
                       size_t *p_allocated_size);
 
@@ -683,7 +715,7 @@ cplus_demangle_print (int options,
 
 extern int
 cplus_demangle_print_callback (int options,
-                               const struct demangle_component *tree,
+                               struct demangle_component *tree,
                                demangle_callbackref callback, void *opaque);
 
 #ifdef __cplusplus
index 0dbb3ac8893ae4ec78c81627ab390faefad3b687..9beba6e4682d0707011f3ec12f27fc4aa640c88b 100644 (file)
@@ -1,5 +1,5 @@
 /* An abstract string datatype.
-   Copyright (C) 1998, 1999, 2000, 2002, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
    Contributed by Mark Mitchell (mark@markmitchell.com).
 
 This file is part of GNU CC.
index 7c3684b7cf8a3ec89fb1ba29463ddf7c3da2fc63..6c0accc72460379e07be10b54d82442e2cc8c52e 100644 (file)
@@ -1,5 +1,5 @@
 /* An abstract string datatype.
-   Copyright (C) 1998-2015 Free Software Foundation, Inc.
+   Copyright (C) 1998-2017 Free Software Foundation, Inc.
    Contributed by Mark Mitchell (mark@markmitchell.com).
 
 This file is part of GCC.
diff --git a/coregrind/m_demangle/rust-demangle.c b/coregrind/m_demangle/rust-demangle.c
new file mode 100644 (file)
index 0000000..3bfde6d
--- /dev/null
@@ -0,0 +1,363 @@
+/* Demangler for the Rust programming language
+   Copyright (C) 2016-2017 Free Software Foundation, Inc.
+   Written by David Tolnay (dtolnay@gmail.com).
+
+This file is part of the libiberty library.
+Libiberty is free software; you can redistribute it and/or
+modify it under the terms of the GNU Library General Public
+License as published by the Free Software Foundation; either
+version 2 of the License, or (at your option) any later version.
+
+In addition to the permissions in the GNU Library General Public
+License, the Free Software Foundation gives you unlimited permission
+to link the compiled version of this file into combinations with other
+programs, and to distribute those combinations without any restriction
+coming from the use of this file.  (The Library Public License
+restrictions do apply in other respects; for example, they cover
+modification of the file, and distribution when not linked into a
+combined executable.)
+
+Libiberty is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Library General Public License for more details.
+
+You should have received a copy of the GNU Library General Public
+License along with libiberty; see the file COPYING.LIB.
+If not, see <http://www.gnu.org/licenses/>.  */
+
+
+#if 0 /* in valgrind */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include "safe-ctype.h"
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include <sys/types.h>
+#include <string.h>
+#include <stdio.h>
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#ifdef HAVE_STRING_H
+#include <string.h>
+#else
+extern size_t strlen(const char *s);
+extern int strncmp(const char *s1, const char *s2, size_t n);
+extern void *memset(void *s, int c, size_t n);
+#endif
+#endif /* ! in valgrind */
+
+#if 0 /* in valgrind */
+#include <demangle.h>
+#include "libiberty.h"
+#endif /* ! in valgrind */
+
+#include "vg_libciface.h"
+
+#include "ansidecl.h"
+#include "demangle.h"
+#include "safe-ctype.h"
+
+/* Mangled Rust symbols look like this:
+     _$LT$std..sys..fd..FileDesc$u20$as$u20$core..ops..Drop$GT$::drop::hc68340e1baa4987a
+
+   The original symbol is:
+     <std::sys::fd::FileDesc as core::ops::Drop>::drop
+
+   The last component of the path is a 64-bit hash in lowercase hex,
+   prefixed with "h". Rust does not have a global namespace between
+   crates, an illusion which Rust maintains by using the hash to
+   distinguish things that would otherwise have the same symbol.
+
+   Any path component not starting with a XID_Start character is
+   prefixed with "_".
+
+   The following escape sequences are used:
+
+   ","  =>  $C$
+   "@"  =>  $SP$
+   "*"  =>  $BP$
+   "&"  =>  $RF$
+   "<"  =>  $LT$
+   ">"  =>  $GT$
+   "("  =>  $LP$
+   ")"  =>  $RP$
+   " "  =>  $u20$
+   "\"" =>  $u22$
+   "'"  =>  $u27$
+   "+"  =>  $u2b$
+   ";"  =>  $u3b$
+   "["  =>  $u5b$
+   "]"  =>  $u5d$
+   "{"  =>  $u7b$
+   "}"  =>  $u7d$
+   "~"  =>  $u7e$
+
+   A double ".." means "::" and a single "." means "-".
+
+   The only characters allowed in the mangled symbol are a-zA-Z0-9 and _.:$  */
+
+static const char *hash_prefix = "::h";
+static const size_t hash_prefix_len = 3;
+static const size_t hash_len = 16;
+
+static int is_prefixed_hash (const char *start);
+static int looks_like_rust (const char *sym, size_t len);
+static int unescape (const char **in, char **out, const char *seq, char value);
+
+/* INPUT: sym: symbol that has been through C++ (gnu v3) demangling
+
+   This function looks for the following indicators:
+
+   1. The hash must consist of "h" followed by 16 lowercase hex digits.
+
+   2. As a sanity check, the hash must use between 5 and 15 of the 16
+      possible hex digits. This is true of 99.9998% of hashes so once
+      in your life you may see a false negative. The point is to
+      notice path components that could be Rust hashes but are
+      probably not, like "haaaaaaaaaaaaaaaa". In this case a false
+      positive (non-Rust symbol has an important path component
+      removed because it looks like a Rust hash) is worse than a false
+      negative (the rare Rust symbol is not demangled) so this sets
+      the balance in favor of false negatives.
+
+   3. There must be no characters other than a-zA-Z0-9 and _.:$
+
+   4. There must be no unrecognized $-sign sequences.
+
+   5. There must be no sequence of three or more dots in a row ("...").  */
+
+int
+rust_is_mangled (const char *sym)
+{
+  size_t len, len_without_hash;
+
+  if (!sym)
+    return 0;
+
+  len = strlen (sym);
+  if (len <= hash_prefix_len + hash_len)
+    /* Not long enough to contain "::h" + hash + something else */
+    return 0;
+
+  len_without_hash = len - (hash_prefix_len + hash_len);
+  if (!is_prefixed_hash (sym + len_without_hash))
+    return 0;
+
+  return looks_like_rust (sym, len_without_hash);
+}
+
+/* A hash is the prefix "::h" followed by 16 lowercase hex digits. The
+   hex digits must comprise between 5 and 15 (inclusive) distinct
+   digits.  */
+
+static int
+is_prefixed_hash (const char *str)
+{
+  const char *end;
+  char seen[16];
+  size_t i;
+  int count;
+
+  if (strncmp (str, hash_prefix, hash_prefix_len))
+    return 0;
+  str += hash_prefix_len;
+
+  memset (seen, 0, sizeof(seen));
+  for (end = str + hash_len; str < end; str++)
+    if (*str >= '0' && *str <= '9')
+      seen[*str - '0'] = 1;
+    else if (*str >= 'a' && *str <= 'f')
+      seen[*str - 'a' + 10] = 1;
+    else
+      return 0;
+
+  /* Count how many distinct digits seen */
+  count = 0;
+  for (i = 0; i < 16; i++)
+    if (seen[i])
+      count++;
+
+  return count >= 5 && count <= 15;
+}
+
+static int
+looks_like_rust (const char *str, size_t len)
+{
+  const char *end = str + len;
+
+  while (str < end)
+    switch (*str)
+      {
+      case '$':
+       if (!strncmp (str, "$C$", 3))
+         str += 3;
+       else if (!strncmp (str, "$SP$", 4)
+                || !strncmp (str, "$BP$", 4)
+                || !strncmp (str, "$RF$", 4)
+                || !strncmp (str, "$LT$", 4)
+                || !strncmp (str, "$GT$", 4)
+                || !strncmp (str, "$LP$", 4)
+                || !strncmp (str, "$RP$", 4))
+         str += 4;
+       else if (!strncmp (str, "$u20$", 5)
+                || !strncmp (str, "$u22$", 5)
+                || !strncmp (str, "$u27$", 5)
+                || !strncmp (str, "$u2b$", 5)
+                || !strncmp (str, "$u3b$", 5)
+                || !strncmp (str, "$u5b$", 5)
+                || !strncmp (str, "$u5d$", 5)
+                || !strncmp (str, "$u7b$", 5)
+                || !strncmp (str, "$u7d$", 5)
+                || !strncmp (str, "$u7e$", 5))
+         str += 5;
+       else
+         return 0;
+       break;
+      case '.':
+       /* Do not allow three or more consecutive dots */
+       if (!strncmp (str, "...", 3))
+         return 0;
+       /* Fall through */
+      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+      case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+      case 'y': case 'z':
+      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+      case 'Y': case 'Z':
+      case '0': case '1': case '2': case '3': case '4': case '5':
+      case '6': case '7': case '8': case '9':
+      case '_':
+      case ':':
+       str++;
+       break;
+      default:
+       return 0;
+      }
+
+  return 1;
+}
+
+/*
+  INPUT: sym: symbol for which rust_is_mangled(sym) returned 1.
+
+  The input is demangled in-place because the mangled name is always
+  longer than the demangled one.  */
+
+void
+rust_demangle_sym (char *sym)
+{
+  const char *in;
+  char *out;
+  const char *end;
+
+  if (!sym)
+    return;
+
+  in = sym;
+  out = sym;
+  end = sym + strlen (sym) - (hash_prefix_len + hash_len);
+
+  while (in < end)
+    switch (*in)
+      {
+      case '$':
+       if (!(unescape (&in, &out, "$C$", ',')
+             || unescape (&in, &out, "$SP$", '@')
+             || unescape (&in, &out, "$BP$", '*')
+             || unescape (&in, &out, "$RF$", '&')
+             || unescape (&in, &out, "$LT$", '<')
+             || unescape (&in, &out, "$GT$", '>')
+             || unescape (&in, &out, "$LP$", '(')
+             || unescape (&in, &out, "$RP$", ')')
+             || unescape (&in, &out, "$u20$", ' ')
+             || unescape (&in, &out, "$u22$", '\"')
+             || unescape (&in, &out, "$u27$", '\'')
+             || unescape (&in, &out, "$u2b$", '+')
+             || unescape (&in, &out, "$u3b$", ';')
+             || unescape (&in, &out, "$u5b$", '[')
+             || unescape (&in, &out, "$u5d$", ']')
+             || unescape (&in, &out, "$u7b$", '{')
+             || unescape (&in, &out, "$u7d$", '}')
+             || unescape (&in, &out, "$u7e$", '~'))) {
+         /* unexpected escape sequence, not looks_like_rust. */
+         goto fail;
+       }
+       break;
+      case '_':
+       /* If this is the start of a path component and the next
+          character is an escape sequence, ignore the underscore. The
+          mangler inserts an underscore to make sure the path
+          component begins with a XID_Start character. */
+       if ((in == sym || in[-1] == ':') && in[1] == '$')
+         in++;
+       else
+         *out++ = *in++;
+       break;
+      case '.':
+       if (in[1] == '.')
+         {
+           /* ".." becomes "::" */
+           *out++ = ':';
+           *out++ = ':';
+           in += 2;
+         }
+       else
+         {
+           /* "." becomes "-" */
+           *out++ = '-';
+           in++;
+         }
+       break;
+      case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
+      case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+      case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+      case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+      case 'y': case 'z':
+      case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+      case 'G': case 'H': case 'I': case 'J': case 'K': case 'L':
+      case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R':
+      case 'S': case 'T': case 'U': case 'V': case 'W': case 'X':
+      case 'Y': case 'Z':
+      case '0': case '1': case '2': case '3': case '4': case '5':
+      case '6': case '7': case '8': case '9':
+      case ':':
+       *out++ = *in++;
+       break;
+      default:
+       /* unexpected character in symbol, not looks_like_rust.  */
+       goto fail;
+      }
+  goto done;
+
+fail:
+  *out++ = '?'; /* This is pretty lame, but it's hard to do better. */
+done:
+  *out = '\0';
+}
+
+static int
+unescape (const char **in, char **out, const char *seq, char value)
+{
+  size_t len = strlen (seq);
+
+  if (strncmp (*in, seq, len))
+    return 0;
+
+  **out = value;
+
+  *in += len;
+  *out += 1;
+
+  return 1;
+}
index 7ac1c7a843ff170fdd029574c2481d248b8d8c72..d3247eddb86911c46a50c0a45f3f2fed9b8b5e46 100644 (file)
@@ -1,7 +1,6 @@
 /* <ctype.h> replacement macros.
 
-   Copyright (C) 2000, 2001, 2002, 2003, 2004,
-   2005 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
    Contributed by Zack Weinberg <zackw@stanford.edu>.
 
 This file is part of the libiberty library.
index 1f4465bf5a4c896ef508d75c5c42f3ac92f6bc23..472c897826cd1724277c7c58614cb2a261b73682 100644 (file)
@@ -1,6 +1,6 @@
 /* <ctype.h> replacement macros.
 
-   Copyright (C) 2000-2015 Free Software Foundation, Inc.
+   Copyright (C) 2000-2017 Free Software Foundation, Inc.
    Contributed by Zack Weinberg <zackw@stanford.edu>.
 
 This file is part of the libiberty library.