diff mbox

[cxx-conversion] Convert vec.[ch] to C++ [2/3] (issue6236043)

Message ID 20120523194918.E97031020B8@torture.tor.corp.google.com
State New
Headers show

Commit Message

Diego Novillo May 23, 2012, 7:49 p.m. UTC
Part 2 of the VEC C++ conversion.  This patch implements the gengtype
changes.

I extended gengtype to understand templated types.  These changes are
not as ugly as I thought they would be.  Gengtype has some hardwired
knowledge of VEC_*, which I renamed to vec_t.  I'm not even sure why
gengtype needs to care about vec_t in this way, but I was looking for
minimal changes, so I just did it.

The other change is more generic.  It allows gengtype to deal with
templated types.  There is a new function (filter_type_name) that
recognizes C++ special characters '<', '>' and ':'.  It turns them
into '_'.  This way, gengtype can generate a valid identifier for the
pre-processor.  It only does this in contexts where it needs a
pre-processor identifier.  For everything else, it emits the type
directly.  So, the functions emitted in gt-*.h files have proper
template type references.

2012-05-23   Diego Novillo  <dnovillo@google.com>

	* gengtype-lex.l (DEF_VEC_ALLOC_[IOP]/{EOID}): Remove.
	* gengtype-parse.c (token_names): Remove DEF_VEC_ALLOC_[IOP].
	(typedef_name): Emit vec_t<C1> instead of VEC_C1_C2.
	(def_vec_alloc): Remove.  Update all callers.
	* gengtype.c (filter_type_name): New.
	(output_mangled_typename): Call it.
	(write_func_for_structure): Likewise.
	(write_types): Likewise.
	(write_root): Likewise.
	(write_typed_alloc_def): Likewise.
	(note_def_vec): Emit vec_t<TYPE_NAME> instead of VEC_TYPE_NAME_base.
	(note_def_vec_alloc): Remove.
	* gengtype.h (note_def_vec_alloc): Remove.
	(DEFVEC_ALLOC): Remove token code.


--
This patch is available for review at http://codereview.appspot.com/6236043

Comments

Lawrence Crowl May 23, 2012, 9:57 p.m. UTC | #1
On 5/23/12, Diego Novillo <dnovillo@google.com> wrote:
> Part 2 of the VEC C++ conversion.  This patch implements the gengtype
> changes.

LGTM.
Richard Biener May 24, 2012, 8:24 a.m. UTC | #2
On Wed, May 23, 2012 at 9:49 PM, Diego Novillo <dnovillo@google.com> wrote:
>
> Part 2 of the VEC C++ conversion.  This patch implements the gengtype
> changes.
>
> I extended gengtype to understand templated types.  These changes are
> not as ugly as I thought they would be.  Gengtype has some hardwired
> knowledge of VEC_*, which I renamed to vec_t.  I'm not even sure why
> gengtype needs to care about vec_t in this way, but I was looking for
> minimal changes, so I just did it.
>
> The other change is more generic.  It allows gengtype to deal with
> templated types.  There is a new function (filter_type_name) that
> recognizes C++ special characters '<', '>' and ':'.  It turns them
> into '_'.  This way, gengtype can generate a valid identifier for the
> pre-processor.  It only does this in contexts where it needs a
> pre-processor identifier.  For everything else, it emits the type
> directly.  So, the functions emitted in gt-*.h files have proper
> template type references.

This is, of course, just a replacement of special-case handling for vec.h
with another special-case handling.  It does not show us how templated
structs should work with gengtype in general.  And no, I don't think
gengtype should keep the special-case for vec.h.

The point was to make all the gt_ggc_* functions function template
specializations so the code gengtype emits for walking a structs fields
would be just

   mark (field1);
   mark (field2);
 ...

and we could manually provide specializations for selected types
(well, the templates).  Add a GTY((template)) marker to make gengtype
not emit the specializations itself (or simply make it recognize template
types and do nothing for them).

Richard.

> 2012-05-23   Diego Novillo  <dnovillo@google.com>
>
>        * gengtype-lex.l (DEF_VEC_ALLOC_[IOP]/{EOID}): Remove.
>        * gengtype-parse.c (token_names): Remove DEF_VEC_ALLOC_[IOP].
>        (typedef_name): Emit vec_t<C1> instead of VEC_C1_C2.
>        (def_vec_alloc): Remove.  Update all callers.
>        * gengtype.c (filter_type_name): New.
>        (output_mangled_typename): Call it.
>        (write_func_for_structure): Likewise.
>        (write_types): Likewise.
>        (write_root): Likewise.
>        (write_typed_alloc_def): Likewise.
>        (note_def_vec): Emit vec_t<TYPE_NAME> instead of VEC_TYPE_NAME_base.
>        (note_def_vec_alloc): Remove.
>        * gengtype.h (note_def_vec_alloc): Remove.
>        (DEFVEC_ALLOC): Remove token code.
>
> diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
> index a71cce0..edfd4a1 100644
> --- a/gcc/gengtype-lex.l
> +++ b/gcc/gengtype-lex.l
> @@ -100,10 +100,6 @@ EOID       [^[:alnum:]_]
>   BEGIN(in_struct);
>   return DEFVEC_I;
>  }
> -^{HWS}DEF_VEC_ALLOC_[IOP]/{EOID} {
> -  BEGIN(in_struct);
> -  return DEFVEC_ALLOC;
> -}
>  }
>
>  <in_struct>{
> diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c
> index 89f14e8..4fc2b07 100644
> --- a/gcc/gengtype-parse.c
> +++ b/gcc/gengtype-parse.c
> @@ -79,7 +79,6 @@ static const char *const token_names[] = {
>   "VEC",
>   "DEF_VEC_[OP]",
>   "DEF_VEC_I",
> -  "DEF_VEC_ALLOC_[IOP]",
>   "...",
>   "ptr_alias",
>   "nested_ptr",
> @@ -227,7 +226,7 @@ typedef_name (void)
>       require (',');
>       c2 = require (ID);
>       require (')');
> -      r = concat ("VEC_", c1, "_", c2, (char *) 0);
> +      r = concat ("vec_t<", c1, ">", (char *) 0);
>       free (CONST_CAST (char *, c1));
>       free (CONST_CAST (char *, c2));
>       return r;
> @@ -916,31 +915,6 @@ def_vec (void)
>     return;
>
>   note_def_vec (type, is_scalar, &lexer_line);
> -  note_def_vec_alloc (type, "none", &lexer_line);
> -}
> -
> -/* Definition of an allocation strategy for a VEC structure:
> -
> -   'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';'
> -
> -   For purposes of gengtype, this just declares a wrapper structure.  */
> -static void
> -def_vec_alloc (void)
> -{
> -  const char *type, *astrat;
> -
> -  require (DEFVEC_ALLOC);
> -  require ('(');
> -  type = require2 (ID, SCALAR);
> -  require (',');
> -  astrat = require (ID);
> -  require (')');
> -  require (';');
> -
> -  if (!type || !astrat)
> -    return;
> -
> -  note_def_vec_alloc (type, astrat, &lexer_line);
>  }
>
>  /* Parse the file FNAME for GC-relevant declarations and definitions.
> @@ -972,10 +946,6 @@ parse_file (const char *fname)
>          def_vec ();
>          break;
>
> -       case DEFVEC_ALLOC:
> -         def_vec_alloc ();
> -         break;
> -
>        case EOF_TOKEN:
>          goto eof;
>
> diff --git a/gcc/gengtype.c b/gcc/gengtype.c
> index 814d9e0..82dca36 100644
> --- a/gcc/gengtype.c
> +++ b/gcc/gengtype.c
> @@ -2295,6 +2295,34 @@ struct walk_type_data
>   int loopcounter;
>  };
>
> +
> +/* Given a string TYPE_NAME, representing a C++ typename, return a valid
> +   pre-processor identifier to use in a #define directive.  This replaces
> +   special characters used in C++ identifiers like '>', '<' and ':' with
> +   '_'.
> +
> +   If no C++ special characters are found in TYPE_NAME, return
> +   TYPE_NAME.  Otherwise, return a copy of TYPE_NAME with the special
> +   characters replaced with '_'.  In this case, the caller is
> +   responsible for freeing the allocated string.  */
> +
> +static const char *
> +filter_type_name (const char *type_name)
> +{
> +  if (strchr (type_name, '<') || strchr (type_name, ':'))
> +    {
> +      size_t i;
> +      char *s = xstrdup (type_name);
> +      for (i = 0; i < strlen (s); i++)
> +       if (s[i] == '<' || s[i] == '>' || s[i] == ':')
> +         s[i] = '_';
> +      return s;
> +    }
> +  else
> +    return type_name;
> +}
> +
> +
>  /* Print a mangled name representing T to OF.  */
>
>  static void
> @@ -2321,8 +2349,13 @@ output_mangled_typename (outf_p of, const_type_p t)
>       case TYPE_STRUCT:
>       case TYPE_UNION:
>       case TYPE_LANG_STRUCT:
> -       oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag),
> -                t->u.s.tag);
> +       {
> +         const char *id_for_tag = filter_type_name (t->u.s.tag);
> +         oprintf (of, "%lu%s", (unsigned long) strlen (id_for_tag),
> +                  id_for_tag);
> +         if (id_for_tag != t->u.s.tag)
> +           free (CONST_CAST(char *, id_for_tag));
> +       }
>        break;
>       case TYPE_PARAM_STRUCT:
>        {
> @@ -3099,7 +3132,12 @@ write_func_for_structure (type_p orig_s, type_p s, type_p *param,
>   oprintf (d.of, "\n");
>   oprintf (d.of, "void\n");
>   if (param == NULL)
> -    oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
> +    {
> +      const char *id_for_tag = filter_type_name (orig_s->u.s.tag);
> +      oprintf (d.of, "gt_%sx_%s", wtd->prefix, id_for_tag);
> +      if (id_for_tag != orig_s->u.s.tag)
> +       free (CONST_CAST(char *, id_for_tag));
> +    }
>   else
>     {
>       oprintf (d.of, "gt_%s_", wtd->prefix);
> @@ -3230,16 +3268,19 @@ write_types (outf_p output_header, type_p structures, type_p param_structs,
>     if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
>       {
>        options_p opt;
> +       const char *s_id_for_tag;
>
>        if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
>          continue;
>
> +       s_id_for_tag = filter_type_name (s->u.s.tag);
> +
>        oprintf (output_header, "#define gt_%s_", wtd->prefix);
>        output_mangled_typename (output_header, s);
>        oprintf (output_header, "(X) do { \\\n");
>        oprintf (output_header,
>                 "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
> -                s->u.s.tag);
> +                s_id_for_tag);
>        oprintf (output_header, "  } while (0)\n");
>
>        for (opt = s->u.s.opt; opt; opt = opt->next)
> @@ -3249,9 +3290,14 @@ write_types (outf_p output_header, type_p structures, type_p param_structs,
>              const_type_p const t = (const_type_p) opt->info.type;
>              if (t->kind == TYPE_STRUCT
>                  || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
> -               oprintf (output_header,
> -                        "#define gt_%sx_%s gt_%sx_%s\n",
> -                        wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
> +               {
> +                 const char *t_id_for_tag = filter_type_name (t->u.s.tag);
> +                 oprintf (output_header,
> +                          "#define gt_%sx_%s gt_%sx_%s\n",
> +                          wtd->prefix, s->u.s.tag, wtd->prefix, t_id_for_tag);
> +                 if (t_id_for_tag != t->u.s.tag)
> +                   free (CONST_CAST(char *, t_id_for_tag));
> +               }
>              else
>                error_at_line (&s->u.s.line,
>                               "structure alias is not a structure");
> @@ -3263,7 +3309,10 @@ write_types (outf_p output_header, type_p structures, type_p param_structs,
>        /* Declare the marker procedure only once.  */
>        oprintf (output_header,
>                 "extern void gt_%sx_%s (void *);\n",
> -                wtd->prefix, s->u.s.tag);
> +                wtd->prefix, s_id_for_tag);
> +
> +       if (s_id_for_tag != s->u.s.tag)
> +         free (CONST_CAST(char *, s_id_for_tag));
>
>        if (s->u.s.line.file == NULL)
>          {
> @@ -3867,11 +3916,14 @@ write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
>
>        if (!has_length && UNION_OR_STRUCT_P (tp))
>          {
> -           oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
> +           const char *id_for_tag = filter_type_name (tp->u.s.tag);
> +           oprintf (f, "    &gt_ggc_mx_%s,\n", id_for_tag);
>            if (emit_pch)
> -             oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
> +             oprintf (f, "    &gt_pch_nx_%s", id_for_tag);
>            else
>              oprintf (f, "    NULL");
> +           if (id_for_tag != tp->u.s.tag)
> +             free (CONST_CAST(char *, id_for_tag));
>          }
>        else if (!has_length && tp->kind == TYPE_PARAM_STRUCT)
>          {
> @@ -4270,7 +4322,7 @@ note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
>   pair_p fields;
>   type_p t;
>   options_p o;
> -  const char *name = concat ("VEC_", type_name, "_base", (char *) 0);
> +  const char *name = concat ("vec_t<", type_name, ">", (char *) 0);
>
>   if (is_scalar)
>     {
> @@ -4289,25 +4341,6 @@ note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
>   do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
>  }
>
> -/* Record the definition of an allocation-specific VEC structure, as if
> -   we had expanded the macros in vec.h:
> -
> -   typedef struct VEC_<type>_<astrat> {
> -     VEC_<type>_base base;
> -   } VEC_<type>_<astrat>;
> -*/
> -void
> -note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
> -{
> -  const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0);
> -  const char *basename = concat ("VEC_", type, "_base", (char *) 0);
> -
> -  pair_p field = create_field_at (0, resolve_typedef (basename, pos),
> -                                 "base", 0, pos);
> -
> -  do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
> -}
> -
>  /* Returns the specifier keyword for a string or union type S, empty string
>    otherwise.  */
>
> @@ -4355,8 +4388,10 @@ write_typed_alloc_def (outf_p f,
>   bool two_args = variable_size && (quantity == vector);
>   bool third_arg = ((zone == specific_zone)
>                    && (variable_size || (quantity == vector)));
> +  const char *type_name_as_id;
>   gcc_assert (f != NULL);
> -  oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name);
> +  type_name_as_id = filter_type_name (type_name);
> +  oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name_as_id);
>   oprintf (f, "(%s%s%s%s%s) ",
>           (variable_size ? "SIZE" : ""),
>           (two_args ? ", " : ""),
> @@ -4373,6 +4408,8 @@ write_typed_alloc_def (outf_p f,
>   if (quantity == vector)
>     oprintf (f, ", n");
>   oprintf (f, " MEM_STAT_INFO)))\n");
> +  if (type_name_as_id != type_name)
> +    free (CONST_CAST(char *, type_name_as_id));
>  }
>
>  /* Writes a typed allocator definition into output F for a struct or
> diff --git a/gcc/gengtype.h b/gcc/gengtype.h
> index 964cc31..cc489e0 100644
> --- a/gcc/gengtype.h
> +++ b/gcc/gengtype.h
> @@ -422,8 +422,6 @@ extern void note_variable (const char *s, type_p t, options_p o,
>                           struct fileloc *pos);
>  extern void note_def_vec (const char *type_name, bool is_scalar,
>                          struct fileloc *pos);
> -extern void note_def_vec_alloc (const char *type, const char *astrat,
> -                               struct fileloc *pos);
>
>  /* Lexer and parser routines.  */
>  extern int yylex (const char **yylval);
> @@ -451,7 +449,6 @@ enum
>     VEC_TOKEN,
>     DEFVEC_OP,
>     DEFVEC_I,
> -    DEFVEC_ALLOC,
>     ELLIPSIS,
>     PTR_ALIAS,
>     NESTED_PTR,
>
> --
> This patch is available for review at http://codereview.appspot.com/6236043
Gabriel Dos Reis May 24, 2012, 1:36 p.m. UTC | #3
On Thu, May 24, 2012 at 3:24 AM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Wed, May 23, 2012 at 9:49 PM, Diego Novillo <dnovillo@google.com> wrote:
>>
>> Part 2 of the VEC C++ conversion.  This patch implements the gengtype
>> changes.
>>
>> I extended gengtype to understand templated types.  These changes are
>> not as ugly as I thought they would be.  Gengtype has some hardwired
>> knowledge of VEC_*, which I renamed to vec_t.  I'm not even sure why
>> gengtype needs to care about vec_t in this way, but I was looking for
>> minimal changes, so I just did it.
>>
>> The other change is more generic.  It allows gengtype to deal with
>> templated types.  There is a new function (filter_type_name) that
>> recognizes C++ special characters '<', '>' and ':'.  It turns them
>> into '_'.  This way, gengtype can generate a valid identifier for the
>> pre-processor.  It only does this in contexts where it needs a
>> pre-processor identifier.  For everything else, it emits the type
>> directly.  So, the functions emitted in gt-*.h files have proper
>> template type references.
>
> This is, of course, just a replacement of special-case handling for vec.h
> with another special-case handling.  It does not show us how templated
> structs should work with gengtype in general.  And no, I don't think
> gengtype should keep the special-case for vec.h.
>
> The point was to make all the gt_ggc_* functions function template
> specializations so the code gengtype emits for walking a structs fields
> would be just
>
>   mark (field1);
>   mark (field2);
>  ...
>
> and we could manually provide specializations for selected types
> (well, the templates).  Add a GTY((template)) marker to make gengtype
> not emit the specializations itself (or simply make it recognize template
> types and do nothing for them).

True, but as a preliminary step (and a member of a series of patches), it does
make sense and is good to have.

-- Gaby
Diego Novillo May 24, 2012, 2:13 p.m. UTC | #4
On 12-05-24 04:24 , Richard Guenther wrote:

> and we could manually provide specializations for selected types
> (well, the templates).  Add a GTY((template)) marker to make gengtype
> not emit the specializations itself (or simply make it recognize template
> types and do nothing for them).

Patience.  One patch at a time.


Diego.
diff mbox

Patch

diff --git a/gcc/gengtype-lex.l b/gcc/gengtype-lex.l
index a71cce0..edfd4a1 100644
--- a/gcc/gengtype-lex.l
+++ b/gcc/gengtype-lex.l
@@ -100,10 +100,6 @@  EOID	[^[:alnum:]_]
   BEGIN(in_struct);
   return DEFVEC_I;
 }
-^{HWS}DEF_VEC_ALLOC_[IOP]/{EOID} {
-  BEGIN(in_struct);
-  return DEFVEC_ALLOC;
-}
 }
 
 <in_struct>{
diff --git a/gcc/gengtype-parse.c b/gcc/gengtype-parse.c
index 89f14e8..4fc2b07 100644
--- a/gcc/gengtype-parse.c
+++ b/gcc/gengtype-parse.c
@@ -79,7 +79,6 @@  static const char *const token_names[] = {
   "VEC",
   "DEF_VEC_[OP]",
   "DEF_VEC_I",
-  "DEF_VEC_ALLOC_[IOP]",
   "...",
   "ptr_alias",
   "nested_ptr",
@@ -227,7 +226,7 @@  typedef_name (void)
       require (',');
       c2 = require (ID);
       require (')');
-      r = concat ("VEC_", c1, "_", c2, (char *) 0);
+      r = concat ("vec_t<", c1, ">", (char *) 0);
       free (CONST_CAST (char *, c1));
       free (CONST_CAST (char *, c2));
       return r;
@@ -916,31 +915,6 @@  def_vec (void)
     return;
 
   note_def_vec (type, is_scalar, &lexer_line);
-  note_def_vec_alloc (type, "none", &lexer_line);
-}
-
-/* Definition of an allocation strategy for a VEC structure:
-
-   'DEF_VEC_ALLOC_[IPO]' '(' id ',' id ')' ';'
-
-   For purposes of gengtype, this just declares a wrapper structure.  */
-static void
-def_vec_alloc (void)
-{
-  const char *type, *astrat;
-
-  require (DEFVEC_ALLOC);
-  require ('(');
-  type = require2 (ID, SCALAR);
-  require (',');
-  astrat = require (ID);
-  require (')');
-  require (';');
-
-  if (!type || !astrat)
-    return;
-
-  note_def_vec_alloc (type, astrat, &lexer_line);
 }
 
 /* Parse the file FNAME for GC-relevant declarations and definitions.
@@ -972,10 +946,6 @@  parse_file (const char *fname)
 	  def_vec ();
 	  break;
 
-	case DEFVEC_ALLOC:
-	  def_vec_alloc ();
-	  break;
-
 	case EOF_TOKEN:
 	  goto eof;
 
diff --git a/gcc/gengtype.c b/gcc/gengtype.c
index 814d9e0..82dca36 100644
--- a/gcc/gengtype.c
+++ b/gcc/gengtype.c
@@ -2295,6 +2295,34 @@  struct walk_type_data
   int loopcounter;
 };
 
+
+/* Given a string TYPE_NAME, representing a C++ typename, return a valid
+   pre-processor identifier to use in a #define directive.  This replaces
+   special characters used in C++ identifiers like '>', '<' and ':' with
+   '_'.
+
+   If no C++ special characters are found in TYPE_NAME, return
+   TYPE_NAME.  Otherwise, return a copy of TYPE_NAME with the special
+   characters replaced with '_'.  In this case, the caller is
+   responsible for freeing the allocated string.  */
+
+static const char *
+filter_type_name (const char *type_name)
+{
+  if (strchr (type_name, '<') || strchr (type_name, ':'))
+    {
+      size_t i;
+      char *s = xstrdup (type_name);
+      for (i = 0; i < strlen (s); i++)
+	if (s[i] == '<' || s[i] == '>' || s[i] == ':')
+	  s[i] = '_';
+      return s;
+    }
+  else
+    return type_name;
+}
+
+
 /* Print a mangled name representing T to OF.  */
 
 static void
@@ -2321,8 +2349,13 @@  output_mangled_typename (outf_p of, const_type_p t)
       case TYPE_STRUCT:
       case TYPE_UNION:
       case TYPE_LANG_STRUCT:
-	oprintf (of, "%lu%s", (unsigned long) strlen (t->u.s.tag),
-		 t->u.s.tag);
+	{
+	  const char *id_for_tag = filter_type_name (t->u.s.tag);
+	  oprintf (of, "%lu%s", (unsigned long) strlen (id_for_tag),
+		   id_for_tag);
+	  if (id_for_tag != t->u.s.tag)
+	    free (CONST_CAST(char *, id_for_tag));
+	}
 	break;
       case TYPE_PARAM_STRUCT:
 	{
@@ -3099,7 +3132,12 @@  write_func_for_structure (type_p orig_s, type_p s, type_p *param,
   oprintf (d.of, "\n");
   oprintf (d.of, "void\n");
   if (param == NULL)
-    oprintf (d.of, "gt_%sx_%s", wtd->prefix, orig_s->u.s.tag);
+    {
+      const char *id_for_tag = filter_type_name (orig_s->u.s.tag);
+      oprintf (d.of, "gt_%sx_%s", wtd->prefix, id_for_tag);
+      if (id_for_tag != orig_s->u.s.tag)
+	free (CONST_CAST(char *, id_for_tag));
+    }
   else
     {
       oprintf (d.of, "gt_%s_", wtd->prefix);
@@ -3230,16 +3268,19 @@  write_types (outf_p output_header, type_p structures, type_p param_structs,
     if (s->gc_used == GC_POINTED_TO || s->gc_used == GC_MAYBE_POINTED_TO)
       {
 	options_p opt;
+	const char *s_id_for_tag;
 
 	if (s->gc_used == GC_MAYBE_POINTED_TO && s->u.s.line.file == NULL)
 	  continue;
 
+	s_id_for_tag = filter_type_name (s->u.s.tag);
+
 	oprintf (output_header, "#define gt_%s_", wtd->prefix);
 	output_mangled_typename (output_header, s);
 	oprintf (output_header, "(X) do { \\\n");
 	oprintf (output_header,
 		 "  if (X != NULL) gt_%sx_%s (X);\\\n", wtd->prefix,
-		 s->u.s.tag);
+		 s_id_for_tag);
 	oprintf (output_header, "  } while (0)\n");
 
 	for (opt = s->u.s.opt; opt; opt = opt->next)
@@ -3249,9 +3290,14 @@  write_types (outf_p output_header, type_p structures, type_p param_structs,
 	      const_type_p const t = (const_type_p) opt->info.type;
 	      if (t->kind == TYPE_STRUCT
 		  || t->kind == TYPE_UNION || t->kind == TYPE_LANG_STRUCT)
-		oprintf (output_header,
-			 "#define gt_%sx_%s gt_%sx_%s\n",
-			 wtd->prefix, s->u.s.tag, wtd->prefix, t->u.s.tag);
+		{
+		  const char *t_id_for_tag = filter_type_name (t->u.s.tag);
+		  oprintf (output_header,
+			   "#define gt_%sx_%s gt_%sx_%s\n",
+			   wtd->prefix, s->u.s.tag, wtd->prefix, t_id_for_tag);
+		  if (t_id_for_tag != t->u.s.tag)
+		    free (CONST_CAST(char *, t_id_for_tag));
+		}
 	      else
 		error_at_line (&s->u.s.line,
 			       "structure alias is not a structure");
@@ -3263,7 +3309,10 @@  write_types (outf_p output_header, type_p structures, type_p param_structs,
 	/* Declare the marker procedure only once.  */
 	oprintf (output_header,
 		 "extern void gt_%sx_%s (void *);\n",
-		 wtd->prefix, s->u.s.tag);
+		 wtd->prefix, s_id_for_tag);
+
+	if (s_id_for_tag != s->u.s.tag)
+	  free (CONST_CAST(char *, s_id_for_tag));
 
 	if (s->u.s.line.file == NULL)
 	  {
@@ -3867,11 +3916,14 @@  write_root (outf_p f, pair_p v, type_p type, const char *name, int has_length,
 
 	if (!has_length && UNION_OR_STRUCT_P (tp))
 	  {
-	    oprintf (f, "    &gt_ggc_mx_%s,\n", tp->u.s.tag);
+	    const char *id_for_tag = filter_type_name (tp->u.s.tag);
+	    oprintf (f, "    &gt_ggc_mx_%s,\n", id_for_tag);
 	    if (emit_pch)
-	      oprintf (f, "    &gt_pch_nx_%s", tp->u.s.tag);
+	      oprintf (f, "    &gt_pch_nx_%s", id_for_tag);
 	    else
 	      oprintf (f, "    NULL");
+	    if (id_for_tag != tp->u.s.tag)
+	      free (CONST_CAST(char *, id_for_tag));
 	  }
 	else if (!has_length && tp->kind == TYPE_PARAM_STRUCT)
 	  {
@@ -4270,7 +4322,7 @@  note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
   pair_p fields;
   type_p t;
   options_p o;
-  const char *name = concat ("VEC_", type_name, "_base", (char *) 0);
+  const char *name = concat ("vec_t<", type_name, ">", (char *) 0);
 
   if (is_scalar)
     {
@@ -4289,25 +4341,6 @@  note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
   do_typedef (name, new_structure (name, 0, pos, fields, 0), pos);
 }
 
-/* Record the definition of an allocation-specific VEC structure, as if
-   we had expanded the macros in vec.h:
-
-   typedef struct VEC_<type>_<astrat> {
-     VEC_<type>_base base;
-   } VEC_<type>_<astrat>;
-*/
-void
-note_def_vec_alloc (const char *type, const char *astrat, struct fileloc *pos)
-{
-  const char *astratname = concat ("VEC_", type, "_", astrat, (char *) 0);
-  const char *basename = concat ("VEC_", type, "_base", (char *) 0);
-
-  pair_p field = create_field_at (0, resolve_typedef (basename, pos),
-				  "base", 0, pos);
-
-  do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
-}
-
 /* Returns the specifier keyword for a string or union type S, empty string
    otherwise.  */
 
@@ -4355,8 +4388,10 @@  write_typed_alloc_def (outf_p f,
   bool two_args = variable_size && (quantity == vector);
   bool third_arg = ((zone == specific_zone)
 		    && (variable_size || (quantity == vector)));
+  const char *type_name_as_id;
   gcc_assert (f != NULL);
-  oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name);
+  type_name_as_id = filter_type_name (type_name);
+  oprintf (f, "#define ggc_alloc_%s%s", allocator_type, type_name_as_id);
   oprintf (f, "(%s%s%s%s%s) ",
 	   (variable_size ? "SIZE" : ""),
 	   (two_args ? ", " : ""),
@@ -4373,6 +4408,8 @@  write_typed_alloc_def (outf_p f,
   if (quantity == vector)
     oprintf (f, ", n");
   oprintf (f, " MEM_STAT_INFO)))\n");
+  if (type_name_as_id != type_name)
+    free (CONST_CAST(char *, type_name_as_id));
 }
 
 /* Writes a typed allocator definition into output F for a struct or
diff --git a/gcc/gengtype.h b/gcc/gengtype.h
index 964cc31..cc489e0 100644
--- a/gcc/gengtype.h
+++ b/gcc/gengtype.h
@@ -422,8 +422,6 @@  extern void note_variable (const char *s, type_p t, options_p o,
 			   struct fileloc *pos);
 extern void note_def_vec (const char *type_name, bool is_scalar,
 			  struct fileloc *pos);
-extern void note_def_vec_alloc (const char *type, const char *astrat,
-				struct fileloc *pos);
 
 /* Lexer and parser routines.  */
 extern int yylex (const char **yylval);
@@ -451,7 +449,6 @@  enum
     VEC_TOKEN,
     DEFVEC_OP,
     DEFVEC_I,
-    DEFVEC_ALLOC,
     ELLIPSIS,
     PTR_ALIAS,
     NESTED_PTR,