This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch 3/8] Improve kludges for VEC handling


This patch may be somewhat more controversial.  It wipes out the
existing logic for handling VEC types in gengtype (which made some
pretensions to being general) and replaces it with hardcoded logic
mostly within gengtype.c.  The up side of this is that we get rid of
the confusing "macro expansion" goo within gengtype-lex.l, we replace
a number of messy lexical rules with simpler ones, and there are no
longer any #if IN_GENGTYPE blocks inside vec.h.  The down side is that
gengtype now has to be updated by hand to take account of changes to
the types defined by the VEC macros.

In the original plan, this was to be a temporary state of affairs
until gengtype was wired up to cpplib, at which point it could do
*real* macro expansion and would not need to have any hardcoded
knowledge of the innards of VECs.  I claim that even if that never
happens, the state of affairs after this patch is superior to the
state of affairs beforehand, because only a few categories of changes
to vec.h will actually require changing gengtype, and it's unlikely
that anyone will make such changes now that the VEC API has
stabilized; whereas beforehand, any modification to vec.h caused
gengtype to be recompiled.  Furthermore, if it is necessary to change
gengtype, the new code is much easier to comprehend than the old
code.  And finally, in this state no one can possibly be confused into
thinking that gengtype actually has a macro expander inside.

I had to update dependencies in the Makefile anyway, so this patch
also includes the removal of all unnecessary #includes from all the
files comprising gengtype.  In particular, none of them contain any
uses of the things defined in coretypes.h nor tm.h.

        * vec.h: Remove all #if IN_GENGTYPE blocks.
	Add comment saying that changes may require adjustments to gengtype.
        * gengtype.c: Don't include coretypes.h or tm.h.
	Add comment to inclusion of errors.h.
	(note_def_vec, note_def_vec_alloc): New functions.
	* gengtype.h: Declare new functions.
	* gengtype-lex.l: Don't include coretypes.h.
	(YY_INPUT, macro_input, push_macro_expansion, mangle_macro_name):
	Delete.
	(update_lineno): Remove unnecessary prototype.
	(DEF_VEC_* rules): Simplify using note_def_vec / note_def_vec_alloc.
	(VEC rule): Just return VEC_TOKEN.
	* gengtype-yacc.y (VEC_TOKEN): New token type.
	(type): Add a production for VEC(a,b).
	* Makefile.in: Update dependencies.

Index: S-vn-gtsmall/gcc/gengtype-lex.l
===================================================================
--- S-vn-gtsmall.orig/gcc/gengtype-lex.l	2007-03-17 16:08:35.000000000 -0700
+++ S-vn-gtsmall/gcc/gengtype-lex.l	2007-03-17 16:08:39.000000000 -0700
@@ -21,7 +21,6 @@
 
 %{
 #include "bconfig.h"
-#include "coretypes.h"
 #include "system.h"
 
 #define malloc xmalloc
@@ -30,15 +29,6 @@
 #include "gengtype.h"
 #include "gengtype-yacc.h"
 
-#define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE))
-
-static unsigned macro_input (char *buffer, unsigned);
-static const char *push_macro_expansion (const char *, unsigned,
-					 const char *, unsigned);
-static char *mangle_macro_name (const char *, unsigned,
-       			        const char *, unsigned);
-static void update_lineno (const char *l, size_t len);
-
 struct fileloc lexer_line;
 int lexer_toplevel_done;
 
@@ -199,40 +189,52 @@
   return ENT_EXTERNSTATIC;
 }
 
-^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
-  char *macro, *arg;
-  unsigned macro_len, arg_len;
-  char *ptr = yytext;
-  const char *additional;
-  type_p t;
-
-  /* Find the macro name.  */
-  for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
-    continue;
-  for (macro_len = ptr - macro; !(ISALNUM (*ptr) || *ptr == '_'); ptr++)
-    continue;
-
-  /* Find the argument(s).  */
-  for (arg = ptr; *ptr != ')'; ptr++)
-    continue;
-  arg_len = ptr - arg;
-
-  /* Create the struct and typedef.  */
-  ptr = mangle_macro_name ("VEC", 3, arg, arg_len);
-
-  t = find_structure (ptr, 0);
-  do_typedef (ptr, t, &lexer_line);
-
-  /* Push the macro for later expansion.  */
-  additional = push_macro_expansion (macro, macro_len, arg, arg_len);
+^"DEF_VEC_"[IPO]{WS}?"("{WS}?{ID}{WS}?")" {
+  /* Definition of a generic VEC structure.  If the letter after
+     DEF_VEC_ is "I", the structure definition is slightly different
+     than if it is "P" or "O".  */
+
+  char *p = yytext + sizeof("DEF_VEC_") - 1;
+  char *q;
+  const char *type;
+  bool is_I = (*p == 'I');
+
+  /* Extract the argument to the macro.  */
+  p++;
+  while (!ISALNUM(*p) && *p != '_') p++;
+  q = p;
+  while (ISALNUM(*q) || *q == '_') q++;
+  type = xmemdup (p, q - p, q - p + 1);
+
+  note_def_vec (type, is_I, &lexer_line);
+  note_def_vec_alloc (type, "none", &lexer_line);
+}
+
+^"DEF_VEC_ALLOC_"[IPO]{WS}?"("{WS}?{ID}{WS}?","{WS}?{ID}{WS}?")" {
+  /* Definition of an allocation strategy for a VEC structure.  For
+     purposes of gengtype, this just declares a wrapper structure.  */
+
+  char *p = yytext + sizeof("DEF_VEC_ALLOC_I") - 1;
+  char *q;
+  char *type, *astrat;
+
+  /* Extract the two arguments to the macro.  */
+  while (!ISALNUM(*p) && *p != '_') p++;
+  q = p;
+  while (ISALNUM(*q) || *q == '_') q++;
+  type = alloca (q - p + 1);
+  memcpy (type, p, q - p);
+  type[q - p] = '\0';
+  p = q;
+
+  while (!ISALNUM(*p) && *p != '_') p++;
+  q = p;
+  while (ISALNUM(*q) || *q == '_') q++;
+  astrat = alloca (q - p + 1);
+  memcpy (astrat, p, q - p);
+  astrat[q - p] = '\0';
 
-  if (additional)
-    {
-      ptr = mangle_macro_name (ptr, strlen (ptr),
-			       additional, strlen (additional));
-      t = find_structure (ptr, 0);
-      do_typedef (ptr, t, &lexer_line);
-    }
+  note_def_vec_alloc (type, astrat, &lexer_line);
 }
 
 <in_struct>{
@@ -243,6 +245,7 @@
 
 "const"/[^[:alnum:]_]		/* don't care */
 "GTY"/[^[:alnum:]_]		{ return GTY_TOKEN; }
+"VEC"/[^[:alnum:]_]		{ return VEC_TOKEN; }
 "union"/[^[:alnum:]_]		{ return UNION; }
 "struct"/[^[:alnum:]_]		{ return STRUCT; }
 "enum"/[^[:alnum:]_]		{ return ENUM; }
@@ -266,26 +269,6 @@
   return SCALAR;
 }
 
-"VEC"{WS}?"("{WS}?{ID}{WS}?(","{WS}?{ID}{WS}?)*")" {
-  char *macro, *arg;
-  unsigned macro_len, arg_len;
-  char *ptr = yytext;
-
-  /* Find the macro name */
-  for (macro = ptr; *ptr != '(' && !ISSPACE (*ptr); ptr++)
-    continue;
-  for (macro_len = ptr - macro; !(ISALNUM(*ptr) || *ptr == '_'); ptr++)
-    continue;
-
-  /* Find the arguments.  */
-  for (arg = ptr; *ptr != ')'; ptr++)
-    continue;
-  arg_len = ptr - arg;
-
-  ptr = mangle_macro_name (macro, macro_len, arg, arg_len);
-  yylval.s = ptr;
-  return ID;
-}
 
 {ID}/[^[:alnum:]_]		{
   yylval.s = (const char *) xmemdup (yytext, yyleng, yyleng+1);
@@ -353,176 +336,6 @@
 
 %%
 
-/* Deal with the expansion caused by the DEF_VEC_x macros.  */
-
-/* Mangle a macro and argument list as done by cpp concatenation in
-   the compiler proper.  */
-static char *
-mangle_macro_name (const char *macro, unsigned macro_len,
-		   const char *arg, unsigned arg_len)
-{
-  char *ptr = (char *) xmemdup (macro, macro_len, macro_len + arg_len + 2);
-
-  /* Now copy and concatenate each argument */
-  while (arg_len)
-    {
-      ptr[macro_len++] = '_';
-      for (; arg_len && (ISALNUM(*arg) || *arg == '_'); arg_len--)
-        ptr[macro_len++] = *arg++;
-      for (; arg_len && !(ISALNUM(*arg) || *arg == '_'); arg_len--)
-        arg++;
-    }
-  ptr[macro_len] = 0;
-
-  return ptr;
-}
-
-typedef struct macro_def
-{
-  const char *name;
-  const char *expansion;
-  const char *additional;
-} macro_def_t;
-
-typedef struct macro
-{
-  const macro_def_t *def;
-  struct macro *next;
-  const char *args[10];
-} macro_t;
-
-static const macro_def_t macro_defs[] = 
-{
-#define IN_GENGTYPE 1
-#include "vec.h"
-  {NULL, NULL, NULL}
-};
-
-/* Chain of macro expansions to do at end of scanning.  */
-static macro_t *macro_expns;
-static macro_t *macro_expns_end;
-
-/* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
-   expansion queue.  We ensure NAME is known at this point.  */
-
-static const char *
-push_macro_expansion (const char *name, unsigned name_len,
-		      const char *arg, unsigned arg_len)
-{
-  unsigned ix;
-
-  for (ix = 0; macro_defs[ix].name; ix++)
-    if (strlen (macro_defs[ix].name) == name_len
-        && !memcmp (name, macro_defs[ix].name, name_len))
-      {
-        macro_t *expansion = XNEW (macro_t);
-        char *args;
-	unsigned argno, last_arg;
-
-	expansion->def = &macro_defs[ix];
-	expansion->next = NULL;
-	args = (char *) xmemdup (arg, arg_len, arg_len+1);
-	args[arg_len] = 0;
-        for (argno = 0; *args;)
-	  {
-   	    expansion->args[argno++] = args;
-	    while (*args && (ISALNUM (*args) || *args == '_'))
-	      args++;
-	    if (argno == 1)
-	      expansion->args[argno++] = "base";
-	    if (!*args)
-	      break;
-	    *args++ = 0;
-	    while (*args && !(ISALNUM (*args) || *args == '_'))
-	      args++;
-          }
-	last_arg = argno;
-        for (; argno != 10; argno++)
-	  expansion->args[argno] = NULL;
-	if (macro_expns_end)
-          macro_expns_end->next = expansion;
-	else
-	  macro_expns = expansion;
-	macro_expns_end = expansion;
-	if (macro_defs[ix].additional)
-	  {
-	    macro_t *expn2 = XNEW (macro_t);
-            memcpy (expn2, expansion, sizeof (*expn2));
-	    expansion = expn2;
-	    expansion->def += 1;
-	    expansion->args[last_arg++] = macro_defs[ix].additional;
-	    macro_expns_end->next = expansion;
-	    macro_expns_end = expansion;
-	  }
-        if (last_arg > 2 && strcmp (expansion->args[last_arg - 1], "heap"))
-	  expansion->args[last_arg++] = "GTY (())";
-	return macro_defs[ix].additional;
-      }
-  error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
-		 name_len, name, arg_len, arg);
-  return NULL;
-}
-
-/* Attempt to read some input.  Use fread until we're at the end of
-   file.  At end of file expand the next queued macro.  We presume the
-   buffer is large enough for the entire expansion.  */
-
-static unsigned
-macro_input (char *buffer, unsigned size)
-{
-  unsigned result;
-
-  result = fread (buffer, 1, size, yyin);
-  if (result)
-    /*NOP*/;
-  else if (ferror (yyin))
-    YY_FATAL_ERROR ("read of source file failed");
-  else if (macro_expns)
-    {
-      const char *expn;
-      unsigned len;
-
-      for (expn = macro_expns->def->expansion; *expn; expn++)
-        {
-	  if (*expn == '#')
-	    {
-	      int argno;
-
-	      argno = expn[1] - '0';
-	      expn += 1;
-
-	      /* Remove inserted space? */
-	      if (buffer[result-1] == ' ' && buffer[result-2] == '_')
-	        result--;
-
-	      /* Insert the argument value */
-	      if (macro_expns->args[argno])
-	        {
-		  len = strlen (macro_expns->args[argno]);
-		  memcpy (&buffer[result], macro_expns->args[argno], len);
-		  result += len;
-		}
-
-	      /* Skip next space? */
-	      if (expn[1] == ' ' && expn[2] == '_')
-	        expn++;
-	    }
-	  else
-	    {
-	      buffer[result++] = *expn;
-	      if (*expn == ';' || *expn == '{')
-	        buffer[result++] = '\n';
-	    }
-        }
-      if (result > size)
-        YY_FATAL_ERROR ("buffer too small to expand macro");
-      macro_expns = macro_expns->next;
-      if (!macro_expns)
-        macro_expns_end = NULL;
-    }
-  return result;
-}
-
 void
 yyerror (const char *s)
 {
Index: S-vn-gtsmall/gcc/gengtype.c
===================================================================
--- S-vn-gtsmall.orig/gcc/gengtype.c	2007-03-17 16:08:30.000000000 -0700
+++ S-vn-gtsmall/gcc/gengtype.c	2007-03-17 16:08:39.000000000 -0700
@@ -21,11 +21,9 @@
 
 #include "bconfig.h"
 #include "system.h"
-#include "coretypes.h"
-#include "tm.h"
 #include "gengtype.h"
 #include "gtyp-gen.h"
-#include "errors.h"
+#include "errors.h"	/* for fatal */
 
 /* Nonzero iff an error has occurred.  */
 static int hit_error = 0;
@@ -2996,6 +2994,86 @@
 		     "gt_pch_scalar_rtab");
 }
 
+/* Record the definition of a generic VEC structure, as if we had expanded
+   the macros in vec.h:
+
+   typedef struct VEC_<type>_base GTY(()) {
+   unsigned num;
+   unsigned alloc;
+   <type> GTY((length ("%h.num"))) vec[1];
+   } VEC_<type>_base
+
+   where the GTY(()) tags are only present if is_scalar is _false_.  */
+
+void
+note_def_vec (const char *typename, bool is_scalar, struct fileloc *pos)
+{
+  pair_p f, fields;
+  type_p t;
+  options_p o;
+  const char *name = concat ("VEC_", typename, "_base", (char *)0);
+
+  if (is_scalar)
+    {
+      t = create_scalar_type (typename, strlen (typename));
+      o = 0;
+    }
+  else
+    {
+      t = resolve_typedef (typename, pos);
+      o = create_option (0, "length", "%h.num");
+    }
+
+  /* We assemble the field list in reverse order.  */
+  f = XNEW (struct pair);
+  f->type = adjust_field_type (create_array (t, "1"), o);
+  f->name = "vec";
+  f->opt = o;
+  f->line = *pos;
+  f->next = 0;
+  fields = f;
+
+  f = XNEW (struct pair);
+  f->type = adjust_field_type (create_scalar_type ("unsigned", 8), 0);
+  f->name = "alloc";
+  f->opt = 0;
+  f->line = *pos;
+  f->next = fields;
+  fields = f;
+
+  f = XNEW (struct pair);
+  f->type = adjust_field_type (create_scalar_type ("unsigned", 8), 0);
+  f->name = "num";
+  f->opt = 0;
+  f->line = *pos;
+  f->next = fields;
+  fields = f;
+
+  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 = XNEW (struct pair);
+  field->name = "base";
+  field->type = adjust_field_type (resolve_typedef (basename, pos), 0);
+  field->line = *pos;
+  field->next = 0;
+
+  do_typedef (astratname, new_structure (astratname, 0, pos, field, 0), pos);
+}
+
 
 extern int main (int argc, char **argv);
 int
Index: S-vn-gtsmall/gcc/gengtype.h
===================================================================
--- S-vn-gtsmall.orig/gcc/gengtype.h	2007-03-17 16:08:30.000000000 -0700
+++ S-vn-gtsmall/gcc/gengtype.h	2007-03-17 16:08:39.000000000 -0700
@@ -144,6 +144,10 @@
 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 *typename, 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, most automatically generated.  */
 extern int yylex (void);
Index: S-vn-gtsmall/gcc/vec.h
===================================================================
--- S-vn-gtsmall.orig/gcc/vec.h	2007-03-17 16:05:49.000000000 -0700
+++ S-vn-gtsmall/gcc/vec.h	2007-03-17 16:08:39.000000000 -0700
@@ -417,7 +417,6 @@
 #define VEC_lower_bound(T,V,O,LT)    \
        (VEC_OP(T,base,lower_bound)(VEC_BASE(V),O,LT VEC_CHECK_INFO))
 
-#if !IN_GENGTYPE
 /* Reallocate an array of elements with prefix.  */
 extern void *vec_gc_p_reserve (void *, int MEM_STAT_DECL);
 extern void *vec_gc_p_reserve_exact (void *, int MEM_STAT_DECL);
@@ -451,14 +450,12 @@
 #define VEC_ASSERT(EXPR,OP,T,A) (void)(EXPR)
 #endif
 
+/* Note: gengtype has hardwired knowledge of the expansions of the
+   VEC, DEF_VEC_*, and DEF_VEC_ALLOC_* macros.  If you change the
+   expansions of these macros you may need to change gengtype too.  */
+
 #define VEC(T,A) VEC_##T##_##A
 #define VEC_OP(T,A,OP) VEC_##T##_##A##_##OP
-#else  /* IN_GENGTYPE */
-#define VEC(T,A) VEC_ T _ A
-#define VEC_STRINGIFY(X) VEC_STRINGIFY_(X)
-#define VEC_STRINGIFY_(X) #X
-#undef GTY
-#endif /* IN_GENGTYPE */
 
 /* Base of vector type, not user visible.  */     
 #define VEC_T(T,B)							  \
@@ -488,10 +485,6 @@
 #define VEC_BASE(P)  ((P) ? &(P)->base : 0)
 
 /* Vector of integer-like object.  */
-#if IN_GENGTYPE
-{"DEF_VEC_I", VEC_STRINGIFY (VEC_T(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_I", VEC_STRINGIFY (VEC_TA (#0,#1,#2,#3)) ";", NULL},
-#else
 #define DEF_VEC_I(T)							  \
 static inline void VEC_OP (T,must_be,integral_type) (void) 		  \
 {									  \
@@ -506,13 +499,8 @@
 VEC_TA_GTY(T,base,A,);							  \
 DEF_VEC_ALLOC_FUNC_I(T,A)						  \
 struct vec_swallow_trailing_semi
-#endif
 
 /* Vector of pointer to object.  */
-#if IN_GENGTYPE
-{"DEF_VEC_P", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_P", VEC_STRINGIFY (VEC_TA_GTY (#0,#1,#2,#3)) ";", NULL},
-#else
 #define DEF_VEC_P(T) 							  \
 static inline void VEC_OP (T,must_be,pointer_type) (void) 		  \
 {									  \
@@ -527,7 +515,6 @@
 VEC_TA_GTY(T,base,A,);							  \
 DEF_VEC_ALLOC_FUNC_P(T,A)						  \
 struct vec_swallow_trailing_semi
-#endif
 
 #define DEF_VEC_FUNC_P(T)						  \
 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)   \
@@ -809,10 +796,6 @@
 }
 
 /* Vector of object.  */
-#if IN_GENGTYPE
-{"DEF_VEC_O", VEC_STRINGIFY (VEC_T_GTY(#0,#1)) ";", "none"},
-{"DEF_VEC_ALLOC_O", VEC_STRINGIFY (VEC_TA_GTY(#0,#1,#2,#3)) ";", NULL},
-#else
 #define DEF_VEC_O(T)							  \
 VEC_T_GTY(T,base);							  \
 VEC_TA_GTY(T,base,none,);						  \
@@ -822,7 +805,6 @@
 VEC_TA_GTY(T,base,A,);							  \
 DEF_VEC_ALLOC_FUNC_O(T,A)						  \
 struct vec_swallow_trailing_semi
-#endif
 
 #define DEF_VEC_FUNC_O(T)						  \
 static inline unsigned VEC_OP (T,base,length) (const VEC(T,base) *vec_)	  \
Index: S-vn-gtsmall/gcc/Makefile.in
===================================================================
--- S-vn-gtsmall.orig/gcc/Makefile.in	2007-03-17 16:07:11.000000000 -0700
+++ S-vn-gtsmall/gcc/Makefile.in	2007-03-17 16:08:39.000000000 -0700
@@ -3136,11 +3136,11 @@
   $(SYSTEM_H) coretypes.h $(GTM_H) errors.h gensupport.h
 build/gengenrtl.o : gengenrtl.c $(BCONFIG_H) $(SYSTEM_H) rtl.def
 build/gengtype-lex.o : gengtype-lex.c gengtype.h gengtype-yacc.h	\
-  $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) vec.h
+  $(BCONFIG_H) $(SYSTEM_H)
 build/gengtype-yacc.o : gengtype-yacc.c gengtype.h $(BCONFIG_H)		\
-  $(SYSTEM_H) coretypes.h $(GTM_H)
-build/gengtype.o : gengtype.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h	\
-  $(GTM_H) gengtype.h gtyp-gen.h rtl.def insn-notes.def errors.h
+  $(SYSTEM_H)
+build/gengtype.o : gengtype.c $(BCONFIG_H) $(SYSTEM_H) gengtype.h 	\
+  gtyp-gen.h rtl.def insn-notes.def errors.h
 build/genmddeps.o: genmddeps.c $(BCONFIG_H) $(SYSTEM_H) coretypes.h	\
   $(GTM_H) $(RTL_BASE_H) errors.h gensupport.h
 build/genmodes.o : genmodes.c $(BCONFIG_H) $(SYSTEM_H) errors.h		\
Index: S-vn-gtsmall/gcc/gengtype-yacc.y
===================================================================
--- S-vn-gtsmall.orig/gcc/gengtype-yacc.y	2007-03-17 16:08:30.000000000 -0700
+++ S-vn-gtsmall/gcc/gengtype-yacc.y	2007-03-17 16:08:39.000000000 -0700
@@ -39,6 +39,7 @@
 %token <t>ENT_STRUCT
 %token ENT_EXTERNSTATIC
 %token GTY_TOKEN
+%token VEC_TOKEN
 %token UNION
 %token STRUCT
 %token ENUM
@@ -160,6 +161,9 @@
          { $$ = $1; }
       | ID
          { $$ = resolve_typedef ($1, &lexer_line); }
+      | VEC_TOKEN '(' ID ',' ID ')'
+         { $$ = resolve_typedef (concat ("VEC_", $3, "_", $5, (char *)0),
+	      			 &lexer_line); }
       | type '*'
          { $$ = create_pointer ($1); }
       | STRUCT ID '{' struct_fields '}'

--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]