Index: gcc/gcc/gengtype-parse.c
===================================================================
--- gcc/gcc/gengtype-parse.c	(revision 189950)
+++ gcc/gcc/gengtype-parse.c	(working copy)
@@ -77,9 +77,11 @@
   "struct",
   "enum",
   "VEC",
-  "DEF_VEC_[OP]",
+  "DEF_VEC_A",
+  "DEF_VEC_O",
+  "DEF_VEC_P"
   "DEF_VEC_I",
-  "DEF_VEC_ALLOC_[IOP]",
+  "DEF_VEC_ALLOC_[AIOP]",
   "...",
   "ptr_alias",
   "nested_ptr",
@@ -893,17 +895,37 @@
 
 /* Definition of a generic VEC structure:
 
-   'DEF_VEC_[IPO]' '(' id ')' ';'
+   'DEF_VEC_[AIOP]' '(' id ')' ';'
 
-   Scalar VECs require slightly different treatment than otherwise -
-   that's handled in note_def_vec, we just pass it along.*/
+*/
 static void
 def_vec (void)
 {
-  bool is_scalar = (token () == DEFVEC_I);
+  enum gc_vec_type_kind vec_type_kind;
   const char *type;
 
-  require2 (DEFVEC_OP, DEFVEC_I);
+  switch (token ())
+    {
+    case DEFVEC_A:
+      vec_type_kind = VEC_TYPE_ATOMIC;
+      advance ();
+      break;
+    case DEFVEC_I:
+      vec_type_kind = VEC_TYPE_INTEGRAL;
+      advance ();
+      break;
+    case DEFVEC_O:
+      vec_type_kind = VEC_TYPE_OBJECT;
+      advance ();
+      break;
+    case DEFVEC_P:
+      vec_type_kind = VEC_TYPE_POINTER;
+      advance ();
+      break;
+    default:
+      gcc_unreachable ();
+    }
+
   require ('(');
   type = require2 (ID, SCALAR);
   require (')');
@@ -912,13 +934,13 @@
   if (!type)
     return;
 
-  note_def_vec (type, is_scalar, &lexer_line);
+  note_def_vec (type, vec_type_kind, &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 ')' ';'
+   'DEF_VEC_ALLOC_[AIOP]' '(' id ',' id ')' ';'
 
    For purposes of gengtype, this just declares a wrapper structure.  */
 static void
@@ -964,7 +986,9 @@
 	  typedef_decl ();
 	  break;
 
-	case DEFVEC_OP:
+	case DEFVEC_A:
+	case DEFVEC_O:
+	case DEFVEC_P:
 	case DEFVEC_I:
 	  def_vec ();
 	  break;
Index: gcc/gcc/gengtype-lex.l
===================================================================
--- gcc/gcc/gengtype-lex.l	(revision 189950)
+++ gcc/gcc/gengtype-lex.l	(working copy)
@@ -92,15 +92,23 @@
   return STATIC;
 }
 
-^{HWS}DEF_VEC_[OP]/{EOID} {
+^{HWS}DEF_VEC_A/{EOID} {
   BEGIN(in_struct);
-  return DEFVEC_OP;
+  return DEFVEC_A;
 }
+^{HWS}DEF_VEC_O/{EOID} {
+  BEGIN(in_struct);
+  return DEFVEC_O;
+}
+^{HWS}DEF_VEC_P/{EOID} {
+  BEGIN(in_struct);
+  return DEFVEC_P;
+}
 ^{HWS}DEF_VEC_I/{EOID} {
   BEGIN(in_struct);
   return DEFVEC_I;
 }
-^{HWS}DEF_VEC_ALLOC_[IOP]/{EOID} {
+^{HWS}DEF_VEC_ALLOC_[AIOP]/{EOID} {
   BEGIN(in_struct);
   return DEFVEC_ALLOC;
 }
Index: gcc/gcc/gengtype.c
===================================================================
--- gcc/gcc/gengtype.c	(revision 189951)
+++ gcc/gcc/gengtype.c	(working copy)
@@ -4269,28 +4269,39 @@
 
    typedef struct VEC_<type>_base GTY(()) {
    struct vec_prefix prefix;
-   <type> GTY((length ("%h.prefix.num"))) vec[1];
+   <type> <GTY option> vec[1];
    } VEC_<type>_base
 
-   where the GTY(()) tags are only present if is_scalar is _false_.  */
-
+   where the <GTY option> depends on VEC_TYPE_KIND: it is GTY((atomic)) for
+   VEC_TYPE_ATOMIC, GTY((length ("%h.prefix.num"))) for VEC_TYPE_OBJECT and
+   VEC_TYPE_POINTER, and none for DEF_VEC_INTEGRAL.
+*/
 void
-note_def_vec (const char *type_name, bool is_scalar, struct fileloc *pos)
+note_def_vec (const char *type_name, enum gc_vec_type_kind vec_type_kind,
+	      struct fileloc *pos)
 {
   pair_p fields;
   type_p t;
   options_p o;
   const char *name = concat ("VEC_", type_name, "_base", (char *) 0);
 
-  if (is_scalar)
+  switch (vec_type_kind)
     {
+    case VEC_TYPE_ATOMIC:
+      t = resolve_typedef (type_name, pos);
+      o = create_string_option(0, "atomic", "");
+      break;
+    case VEC_TYPE_INTEGRAL:
       t = create_scalar_type (type_name);
-      o = 0;
-    }
-  else
-    {
+      o = NULL;
+      break;
+    case VEC_TYPE_OBJECT:
+    case VEC_TYPE_POINTER:
       t = resolve_typedef (type_name, pos);
       o = create_string_option (0, "length", "%h.prefix.num");
+      break;
+    default:
+      gcc_unreachable();
     }
   /* We assemble the field list in reverse order.  */
   fields = create_field_at (0, create_array (t, "1"), "vec", o, pos);
Index: gcc/gcc/gengtype.h
===================================================================
--- gcc/gcc/gengtype.h	(revision 189950)
+++ gcc/gcc/gengtype.h	(working copy)
@@ -233,6 +233,14 @@
   GC_POINTED_TO
 };
 
+/* A kind of vector data element type */
+enum gc_vec_type_kind {
+  VEC_TYPE_ATOMIC,	/* GC-managed type with no pointers in it */
+  VEC_TYPE_INTEGRAL,	/* Scalar */
+  VEC_TYPE_OBJECT,	/* GC-managed type with pointer in it */
+  VEC_TYPE_POINTER	/* Pointer */
+};
+
 /* We can have at most ten type parameters in parameterized structures.  */
 #define NUM_PARAM 10
 
@@ -424,7 +432,8 @@
 extern type_p adjust_field_type (type_p, options_p);
 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,
+extern void note_def_vec (const char *type_name,
+			  enum gc_vec_type_kind vec_type_kind,
 			  struct fileloc *pos);
 extern void note_def_vec_alloc (const char *type, const char *astrat,
 				struct fileloc *pos);
@@ -453,7 +462,9 @@
     STRUCT,
     ENUM,
     VEC_TOKEN,
-    DEFVEC_OP,
+    DEFVEC_A,
+    DEFVEC_O,
+    DEFVEC_P,
     DEFVEC_I,
     DEFVEC_ALLOC,
     ELLIPSIS,
