OSDN Git Service

Sun Sep 28 12:00:52 1997 Mark Mitchell <mmitchell@usa.net>
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Sep 1997 19:59:54 +0000 (19:59 +0000)
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 28 Sep 1997 19:59:54 +0000 (19:59 +0000)
        * cplus-dem.c (demangle_template): Add new parameter.  Handle new
        template-function mangling.
        (consume_count_with_underscores): New function.
        (demangle_signature): Handle new name-mangling scheme.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@15780 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cplus-dem.c
gcc/invoke.texi

index b326a90..34b41b5 100644 (file)
@@ -1,3 +1,10 @@
+Sun Sep 28 12:00:52 1997  Mark Mitchell  <mmitchell@usa.net>
+
+        * cplus-dem.c (demangle_template): Add new parameter.  Handle new
+        template-function mangling.
+        (consume_count_with_underscores): New function.
+        (demangle_signature): Handle new name-mangling scheme.
+
 Sun Sep 28 01:55:04 1997  Philippe De Muyter  <phdm@info.ucl.ac.be>
 
        * flow.c (print_rtl_with_bb): Cast alloca return values for variables
index 5794a5b..055ab08 100644 (file)
@@ -102,6 +102,8 @@ struct work_stuff
   int destructor;
   int static_type;     /* A static member function */
   int const_type;      /* A const member function */
+  char **tmpl_argvec;   /* Template function arguments. */
+  int ntmpl_args;       /* The number of template function arguments. */
 };
 
 #define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI)
@@ -222,7 +224,7 @@ demangle_method_args PARAMS ((struct work_stuff *work, const char **, string *))
 
 static int
 demangle_template PARAMS ((struct work_stuff *work, const char **, string *,
-                          string *));
+                          string *, int));
 
 static int
 arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **,
@@ -294,6 +296,9 @@ get_count PARAMS ((const char **, int *));
 static int
 consume_count PARAMS ((const char **));
 
+static int 
+consume_count_with_underscores PARAMS ((const char**));
+
 static int
 demangle_args PARAMS ((struct work_stuff *, const char **, string *));
 
@@ -336,6 +341,42 @@ consume_count (type)
   return (count);
 }
 
+
+/* Like consume_count, but for counts that are preceeded and followed
+   by '_' if they are greater than 10.  Also, -1 is returned for
+   failure, since 0 can be a valid value.  */
+
+static int
+consume_count_with_underscores (mangled)
+     const char **mangled;
+{
+  int idx;
+
+  if (**mangled == '_')
+    {
+      (*mangled)++;
+      if (!isdigit (**mangled))
+       return -1;
+
+      idx = consume_count (mangled);
+      if (**mangled != '_')
+       /* The trailing underscore was missing. */
+       return -1;
+           
+      (*mangled)++;
+    }
+  else
+    {
+      if (**mangled < '0' || **mangled > '9')
+       return -1;
+           
+      idx = **mangled - '0';
+      (*mangled)++;
+    }
+
+  return idx;
+}
+
 int
 cplus_demangle_opname (opname, result, options)
      const char *opname;
@@ -580,7 +621,17 @@ mop_up (work, declp, success)
     {
       free ((char *) work -> typevec);
     }
-  
+  if (work->tmpl_argvec)
+    {
+      int i;
+
+      for (i = 0; i < work->ntmpl_args; i++)
+       if (work->tmpl_argvec[i])
+         free ((char*) work->tmpl_argvec[i]);
+      
+      free ((char*) work->tmpl_argvec);
+    }
+
   /* If demangling was successful, ensure that the demangled string is null
      terminated and return it.  Otherwise, free the demangling decl.  */
   
@@ -635,6 +686,7 @@ demangle_signature (work, mangled, declp)
   int success = 1;
   int func_done = 0;
   int expect_func = 0;
+  int expect_return_type = 0;
   const char *oldmangled = NULL;
   string trawname;
   string tname;
@@ -726,7 +778,7 @@ demangle_signature (work, mangled, declp)
            {
              oldmangled = *mangled;
            }
-         success = demangle_template (work, mangled, &tname, &trawname);
+         success = demangle_template (work, mangled, &tname, &trawname, 1);
          if (success)
            {
              remember_type (work, oldmangled, *mangled - oldmangled);
@@ -751,14 +803,42 @@ demangle_signature (work, mangled, declp)
          break;
 
        case '_':
-         /* At the outermost level, we cannot have a return type specified,
-            so if we run into another '_' at this point we are dealing with
-            a mangled name that is either bogus, or has been mangled by
-            some algorithm we don't know how to deal with.  So just
-            reject the entire demangling.  */
-         success = 0;
+         if (GNU_DEMANGLING && expect_return_type) 
+           {
+             /* Read the return type. */
+             string return_type;
+             string_init (&return_type);
+
+             (*mangled)++;
+             success = do_type (work, mangled, &return_type);
+             APPEND_BLANK (&return_type);
+
+             string_prepends (declp, &return_type);
+             string_delete (&return_type);
+             break;
+           }
+         else
+           /* At the outermost level, we cannot have a return type specified,
+              so if we run into another '_' at this point we are dealing with
+              a mangled name that is either bogus, or has been mangled by
+              some algorithm we don't know how to deal with.  So just
+              reject the entire demangling.  */
+           success = 0;
          break;
 
+       case 'H':
+         if (GNU_DEMANGLING) 
+           {
+             /* A G++ template function.  Read the template arguments. */
+             success = demangle_template (work, mangled, declp, 0, 0);
+             expect_return_type = 1;
+             (*mangled)++;
+             break;
+           }
+         else
+           /* fall through */
+           ;
+
        default:
          if (AUTO_DEMANGLING || GNU_DEMANGLING)
            {
@@ -785,6 +865,10 @@ demangle_signature (work, mangled, declp)
          {
            func_done = 1;
            success = demangle_args (work, mangled, declp);
+           /* Since template include the mangling of their return types,
+              we must set expect_func to 0 so that we don't try do
+              demangle more arguments the next time we get here.  */
+           expect_func = 0;
          }
       }
     }
@@ -838,11 +922,12 @@ demangle_method_args (work, mangled, declp)
 #endif
 
 static int
-demangle_template (work, mangled, tname, trawname)
+demangle_template (work, mangled, tname, trawname, is_type)
      struct work_stuff *work;
      const char **mangled;
      string *tname;
      string *trawname;
+     int is_type;
 {
   int i;
   int is_pointer;
@@ -857,31 +942,43 @@ demangle_template (work, mangled, tname, trawname)
   const char *old_p;
   const char *start;
   int symbol_len;
-  int is_java_array;
+  int is_java_array = 0;
   string temp;
 
   (*mangled)++;
-  start = *mangled;
-  /* get template name */
-  if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
+  if (is_type)
     {
-      return (0);
-    }
-  if (trawname)
-    string_appendn (trawname, *mangled, r);
-  is_java_array = (work -> options & DMGL_JAVA)
-    && strncmp (*mangled, "JArray1Z", 8) == 0;
-  if (! is_java_array)
-    {
-      string_appendn (tname, *mangled, r);
-      string_append (tname, "<");
+      start = *mangled;
+      /* get template name */
+      if ((r = consume_count (mangled)) == 0 || strlen (*mangled) < r)
+       {
+         return (0);
+       }
+      if (trawname)
+       string_appendn (trawname, *mangled, r);
+      is_java_array = (work -> options & DMGL_JAVA)
+       && strncmp (*mangled, "JArray1Z", 8) == 0;
+      if (! is_java_array)
+       {
+         string_appendn (tname, *mangled, r);
+       }
+      *mangled += r;
     }
-  *mangled += r;
+  if (!is_java_array)
+    string_append (tname, "<");
   /* get size of template parameter list */
   if (!get_count (mangled, &r))
     {
       return (0);
     }
+  if (!is_type)
+    {
+      /* Create an array for saving the template argument values. */
+      work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *));
+      work->ntmpl_args = r;
+      for (i = 0; i < r; i++)
+       work->tmpl_argvec[i] = 0;
+    }
   for (i = 0; i < r; i++)
     {
       if (need_comma)
@@ -897,6 +994,15 @@ demangle_template (work, mangled, tname, trawname)
          if (success)
            {
              string_appends (tname, &temp);
+
+             if (!is_type)
+               {
+                 /* Save the template argument. */
+                 int len = temp.p - temp.b;
+                 work->tmpl_argvec[i] = xmalloc (len + 1);
+                 memcpy (work->tmpl_argvec[i], temp.b, len);
+                 work->tmpl_argvec[i][len] = '\0';
+               }
            }
          string_delete(&temp);
          if (!success)
@@ -906,6 +1012,9 @@ demangle_template (work, mangled, tname, trawname)
        }
       else
        {
+         string  param;
+         string* s;
+
          /* otherwise, value parameter */
          old_p  = *mangled;
          is_pointer = 0;
@@ -919,7 +1028,7 @@ demangle_template (work, mangled, tname, trawname)
          /*
            if (success)
            {
-           string_appends (tname, &temp);
+           string_appends (s, &temp);
            }
            */
          string_delete(&temp);
@@ -928,8 +1037,17 @@ demangle_template (work, mangled, tname, trawname)
              break;
            }
          /*
-           string_append (tname, "=");
+           string_append (s, "=");
            */
+
+         if (!is_type)
+           {
+             s = &param;
+             string_init (s);
+           }
+         else
+           s = tname;
+
          while (*old_p && !done)
            {   
              switch (*old_p)
@@ -983,16 +1101,41 @@ demangle_template (work, mangled, tname, trawname)
                  done = is_integral = 1;
                }
            }
-         if (is_integral)
+         if (**mangled == 'Y')
+           {
+             /* The next argument is a template parameter. */
+             int idx;
+
+             (*mangled)++;
+             idx = consume_count_with_underscores (mangled);
+             if (idx == -1 
+                 || (work->tmpl_argvec && idx >= work->ntmpl_args)
+                 || consume_count_with_underscores (mangled) == -1)
+               {
+                 success = 0;
+                 if (!is_type)
+                   string_delete (s);
+                 break;
+               }
+             if (work->tmpl_argvec)
+               string_append (s, work->tmpl_argvec[idx]);
+             else
+               {
+                 char buf[10];
+                 sprintf(buf, "T%d", idx);
+                 string_append (s, buf);
+               }
+           }
+         else if (is_integral)
            {
              if (**mangled == 'm')
                {
-                 string_appendn (tname, "-", 1);
+                 string_appendn (s, "-", 1);
                  (*mangled)++;
                }
              while (isdigit (**mangled))       
                {
-                 string_appendn (tname, *mangled, 1);
+                 string_appendn (s, *mangled, 1);
                  (*mangled)++;
                }
            }
@@ -1002,28 +1145,30 @@ demangle_template (work, mangled, tname, trawname)
              int val;
               if (**mangled == 'm')
                 {
-                  string_appendn (tname, "-", 1);
+                  string_appendn (s, "-", 1);
                   (*mangled)++;
                 }
-             string_appendn (tname, "'", 1);
+             string_appendn (s, "'", 1);
               val = consume_count(mangled);
              if (val == 0)
                {
                  success = 0;
+                 if (!is_type)
+                   string_delete (s);
                  break;
                 }
               tmp[0] = (char)val;
               tmp[1] = '\0';
-              string_appendn (tname, &tmp[0], 1);
-             string_appendn (tname, "'", 1);
+              string_appendn (s, &tmp[0], 1);
+             string_appendn (s, "'", 1);
            }
          else if (is_bool)
            {
              int val = consume_count (mangled);
              if (val == 0)
-               string_appendn (tname, "false", 5);
+               string_appendn (s, "false", 5);
              else if (val == 1)
-               string_appendn (tname, "true", 4);
+               string_appendn (s, "true", 4);
              else
                success = 0;
            }
@@ -1031,31 +1176,31 @@ demangle_template (work, mangled, tname, trawname)
            {
              if (**mangled == 'm')
                {
-                 string_appendn (tname, "-", 1);
+                 string_appendn (s, "-", 1);
                  (*mangled)++;
                }
              while (isdigit (**mangled))       
                {
-                 string_appendn (tname, *mangled, 1);
+                 string_appendn (s, *mangled, 1);
                  (*mangled)++;
                }
              if (**mangled == '.') /* fraction */
                {
-                 string_appendn (tname, ".", 1);
+                 string_appendn (s, ".", 1);
                  (*mangled)++;
                  while (isdigit (**mangled))   
                    {
-                     string_appendn (tname, *mangled, 1);
+                     string_appendn (s, *mangled, 1);
                      (*mangled)++;
                    }
                }
              if (**mangled == 'e') /* exponent */
                {
-                 string_appendn (tname, "e", 1);
+                 string_appendn (s, "e", 1);
                  (*mangled)++;
                  while (isdigit (**mangled))   
                    {
-                     string_appendn (tname, *mangled, 1);
+                     string_appendn (s, *mangled, 1);
                      (*mangled)++;
                    }
                }
@@ -1066,28 +1211,40 @@ demangle_template (work, mangled, tname, trawname)
              if (symbol_len == 0)
                {
                  success = 0;
+                 if (!is_type)
+                   string_delete (s);
                  break;
                }
              if (symbol_len == 0)
-               string_appendn (tname, "0", 1);
+               string_appendn (s, "0", 1);
              else
                {
                  char *p = xmalloc (symbol_len + 1), *q;
                  strncpy (p, *mangled, symbol_len);
                  p [symbol_len] = '\0';
                  q = cplus_demangle (p, work->options);
-                 string_appendn (tname, "&", 1);
+                 string_appendn (s, "&", 1);
                  if (q)
                    {
-                     string_append (tname, q);
+                     string_append (s, q);
                      free (q);
                    }
                  else
-                   string_append (tname, p);
+                   string_append (s, p);
                  free (p);
                }
              *mangled += symbol_len;
            }
+         if (!is_type)
+           {
+             int len = s->p - s->b;
+             work->tmpl_argvec[i] = xmalloc (len + 1);
+             memcpy (work->tmpl_argvec[i], s->b, len);
+             work->tmpl_argvec[i][len] = '\0';
+             
+             string_appends (tname, s);
+             string_delete (s);
+           }
        }
       need_comma = 1;
     }
@@ -1526,7 +1683,7 @@ gnu_special (work, mangled, declp)
              success = demangle_qualified (work, mangled, declp, 0, 1);
              break;
            case 't':
-             success = demangle_template (work, mangled, declp, 0);
+             success = demangle_template (work, mangled, declp, 0, 1);
              break;
            default:
              if (isdigit(*mangled[0]))
@@ -1571,7 +1728,7 @@ gnu_special (work, mangled, declp)
          success = demangle_qualified (work, mangled, declp, 0, 1);
          break;
        case 't':
-         success = demangle_template (work, mangled, declp, 0);
+         success = demangle_template (work, mangled, declp, 0, 1);
          break;
        default:
          n = consume_count (mangled);
@@ -1623,7 +1780,7 @@ gnu_special (work, mangled, declp)
          success = demangle_qualified (work, mangled, declp, 0, 1);
          break;
        case 't':
-         success = demangle_template (work, mangled, declp, 0);
+         success = demangle_template (work, mangled, declp, 0, 1);
          break;
        default:
          success = demangle_fund_type (work, mangled, declp);
@@ -1825,7 +1982,12 @@ demangle_qualified (work, mangled, result, isfuncname, append)
        *mangled = *mangled + 1;
       if (*mangled[0] == 't')
        {
-         success = demangle_template(work, mangled, &temp, 0);
+         success = demangle_template(work, mangled, &temp, 0, 1);
+         if (!success) break;
+       }
+      else if (*mangled[0] == 'X')
+       {
+         success = do_type (work, mangled, &temp);
          if (!success) break;
        }
       else
@@ -2064,7 +2226,7 @@ do_type (work, mangled, result)
              {
                string temp;
                string_init (&temp);
-               success = demangle_template (work, mangled, &temp, NULL);
+               success = demangle_template (work, mangled, &temp, NULL, 1);
                if (success)
                  {
                    string_prependn (&decl, temp.b, temp.p - temp.b);
@@ -2152,6 +2314,37 @@ do_type (work, mangled, result)
       success = demangle_qualified (work, mangled, result, 0, 1);
       break;
 
+    case 'X':
+    case 'Y':
+      /* A template parm.  We substitute the corresponding argument. */
+      {
+       int idx;
+       int lvl;
+
+       (*mangled)++;
+       idx = consume_count_with_underscores (mangled);
+
+       if (idx == -1 
+           || (work->tmpl_argvec && idx >= work->ntmpl_args)
+           || consume_count_with_underscores (mangled) == -1)
+         {
+           success = 0;
+           break;
+         }
+
+       if (work->tmpl_argvec)
+         string_append (result, work->tmpl_argvec[idx]);
+       else
+         {
+           char buf[10];
+           sprintf(buf, "T%d", idx);
+           string_append (result, buf);
+         }
+
+       success = 1;
+      }
+    break;
+
     default:
       success = demangle_fund_type (work, mangled, result);
       break;
@@ -2326,7 +2519,7 @@ demangle_fund_type (work, mangled, result)
       }
       break;
     case 't':
-      success = demangle_template(work,mangled, result, 0);
+      success = demangle_template(work,mangled, result, 0, 1);
       break;
     default:
       success = 0;
index 7332f62..0437f25 100644 (file)
@@ -104,8 +104,9 @@ in the following sections.
 @smallexample
 -fall-virtual  -fdollars-in-identifiers  -felide-constructors
 -fenum-int-equiv -fexternal-templates  -ffor-scope -fno-for-scope
--fhandle-signatures -fmemoize-lookups  -fno-default-inline -fno-gnu-keywords
--fnonnull-objects  -foperator-names  -fstrict-prototype -fthis-is-variable
+-fhandle-signatures -fmemoize-lookups  -fname-mangling-version-@var{n}
+-fno-default-inline -fno-gnu-keywords -fnonnull-objects -fguiding-decls
+-foperator-names  -fstrict-prototype -fthis-is-variable 
 -ftemplate-depth-@var{n} -nostdinc++ -traditional  +e@var{n}
 @end smallexample
 
@@ -925,11 +926,15 @@ Cause template instantiations to obey @samp{#pragma interface} and
 to the location of the template definition.  @xref{Template
 Instantiation}, for more information.
 
+This option is deprecated.
+
 @item -falt-external-templates
 Similar to -fexternal-templates, but template instances are emitted or
 not according to the place where they are first instantiated.
 @xref{Template Instantiation}, for more information.
 
+This option is deprecated.
+
 @item -ffor-scope
 @item -fno-for-scope
 If -ffor-scope is specified, the scope of variables declared in
@@ -952,6 +957,18 @@ words as identifiers.  You can use the keywords @code{__classof__},
 @code{__typeof__} instead.  @samp{-ansi} implies
 @samp{-fno-gnu-keywords}.
 
+@item -fguiding-decls
+Treat a function declaration with the same type as a potential function
+template instantiation as though it declares that instantiation, not a
+normal function.  If a definition is given for the function later in the
+translation unit (or another translation unit if the target supports
+weak symbols), that definition will be used; otherwise the template will
+be instantiated.  This behavior reflects the C++ language prior to
+September 1996, when guiding declarations were removed.
+
+This option implies @samp{-fname-mangling-version-0}, and will not work
+with other name mangling versions.
+
 @item -fno-implicit-templates
 Never emit code for templates which are instantiated implicitly (i.e. by
 use); only emit code for explicit instantiations.  @xref{Template
@@ -1029,6 +1046,17 @@ overridden with @samp{-fno-strict-prototype}.
 
 This flag no longer affects declarations with C++ linkage.
 
+@item -fname-mangling-version-@var{n}
+Control the way in which names are mangled.  Version 0 is compatible
+with versions of g++ before 2.8.  Version 1 is the default.  Version 1
+will allow correct mangling of function templates.  For example, 
+version 0 mangling does not mangle foo<int, double> and foo<int, char>
+given this declaration:
+
+@example
+template <class T, class U> void foo(T t);
+@end example
+
 @item -fno-nonnull-objects
 Don't assume that a reference is initialized to refer to a valid object.
 Although the current C++ Working Paper prohibits null references, some