Commit ada55151 by Nathan Sidwell Committed by Nathan Sidwell

vec.h, vec.c: New, type safe vector API.

	* vec.h, vec.c: New, type safe vector API.
	* Makefile.in (OBJS-common): Add vec.o.
	(vec.o): New target.
	(gengtype-lex.o): Depend on vec.h.

From-SVN: r83769
parent 2851dd68
2004-06-28 Nathan Sidwell <nathan@codesourcery.com>
* vec.h, vec.c: New, type safe vector API.
* Makefile.in (OBJS-common): Add vec.o.
(vec.o): New target.
(gengtype-lex.o): Depend on vec.h.
2004-06-28 Paolo Bonzini <bonzini@gnu.org> 2004-06-28 Paolo Bonzini <bonzini@gnu.org>
* fold-const.c (fold_cond_expr_with_comparison): Add ARG1 * fold-const.c (fold_cond_expr_with_comparison): Add ARG1
......
...@@ -914,7 +914,7 @@ OBJS-common = \ ...@@ -914,7 +914,7 @@ OBJS-common = \
sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \ sbitmap.o sched-deps.o sched-ebb.o sched-rgn.o sched-vis.o sdbout.o \
simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \ simplify-rtx.o sreal.o stmt.o stor-layout.o stringpool.o \
targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \ targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \
varasm.o varray.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \ varasm.o varray.o vec.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \ et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o
...@@ -1990,6 +1990,7 @@ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS ...@@ -1990,6 +1990,7 @@ global.o : global.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS
toplev.h $(TM_P_H) toplev.h $(TM_P_H)
varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h $(GGC_H) errors.h \ varray.o : varray.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) varray.h $(GGC_H) errors.h \
$(HASHTAB_H) $(HASHTAB_H)
vec.o : vec.c $(CONFIG_H) coretypes.h vec.h ggc.h errors.h
ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h \ ra.o : ra.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TM_P_H) insn-config.h \
$(RECOG_H) $(INTEGRATE_H) function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \ $(RECOG_H) $(INTEGRATE_H) function.h $(REGS_H) $(OBSTACK_H) hard-reg-set.h \
$(BASIC_BLOCK_H) $(DF_H) $(EXPR_H) output.h toplev.h $(FLAGS_H) reload.h $(RA_H) $(BASIC_BLOCK_H) $(DF_H) $(EXPR_H) output.h toplev.h $(FLAGS_H) reload.h $(RA_H)
...@@ -2515,7 +2516,7 @@ gengtype.o : gengtype.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H) ...@@ -2515,7 +2516,7 @@ gengtype.o : gengtype.c gengtype.h $(BCONFIG_H) $(SYSTEM_H) coretypes.h $(GTM_H)
real.h $(RTL_BASE_H) gtyp-gen.h real.h $(RTL_BASE_H) gtyp-gen.h
gengtype-lex.o : gengtype-lex.c gengtype.h gengtype-yacc.h \ gengtype-lex.o : gengtype-lex.c gengtype.h gengtype-yacc.h \
$(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) $(BCONFIG_H) coretypes.h $(GTM_H) $(SYSTEM_H) vec.h
$(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \ $(CC_FOR_BUILD) -c $(BUILD_CFLAGS) $(BUILD_CPPFLAGS) $(INCLUDES) \
$< $(OUTPUT_OPTION) $< $(OUTPUT_OPTION)
......
...@@ -30,6 +30,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -30,6 +30,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "gengtype.h" #include "gengtype.h"
#include "gengtype-yacc.h" #include "gengtype-yacc.h"
#define YY_INPUT(BUF,RESULT,SIZE) ((RESULT) = macro_input (BUF,SIZE))
static unsigned macro_input (char *buffer, unsigned);
static void push_macro_expansion (const char *, unsigned,
const char *, unsigned);
static void update_lineno (const char *l, size_t len); static void update_lineno (const char *l, size_t len);
struct fileloc lexer_line; struct fileloc lexer_line;
...@@ -218,6 +223,35 @@ ITYPE {IWORD}({WS}{IWORD})* ...@@ -218,6 +223,35 @@ ITYPE {IWORD}({WS}{IWORD})*
return ENT_YACCUNION; return ENT_YACCUNION;
} }
^"DEF_VEC_"[[:alnum:]_]*{WS}?"("{WS}?{ID}{WS}?")" {
char *macro, *arg;
unsigned macro_len, arg_len;
char *ptr = yytext;
type_p t;
/* Locate the macro and argument strings. */
macro = ptr;
while (*ptr != '(' && !ISSPACE (*ptr))
ptr++;
macro_len = ptr - macro;
while (*ptr == '(' || ISSPACE (*ptr))
ptr++;
arg = ptr;
while (*ptr != ')' && !ISSPACE (*ptr))
ptr++;
arg_len = ptr - arg;
/* Push the macro for later expansion. */
push_macro_expansion (macro, macro_len, arg, arg_len);
/* Create the struct and typedef. */
ptr = xmemdup ("VEC_", 4, 4 + arg_len + 1);
memcpy (&ptr[4], arg, arg_len);
ptr[4 + arg_len] = 0;
t = find_structure (ptr, 0);
do_typedef (ptr, t, &lexer_line);
}
<in_struct>{ <in_struct>{
"/*" { BEGIN(in_struct_comment); } "/*" { BEGIN(in_struct_comment); }
...@@ -229,7 +263,6 @@ ITYPE {IWORD}({WS}{IWORD})* ...@@ -229,7 +263,6 @@ ITYPE {IWORD}({WS}{IWORD})*
{WS} { update_lineno (yytext, yyleng); } {WS} { update_lineno (yytext, yyleng); }
"const"/[^[:alnum:]_] /* don't care */ "const"/[^[:alnum:]_] /* don't care */
"GTY"/[^[:alnum:]_] { return GTY_TOKEN; } "GTY"/[^[:alnum:]_] { return GTY_TOKEN; }
"union"/[^[:alnum:]_] { return UNION; } "union"/[^[:alnum:]_] { return UNION; }
"struct"/[^[:alnum:]_] { return STRUCT; } "struct"/[^[:alnum:]_] { return STRUCT; }
...@@ -254,6 +287,28 @@ ITYPE {IWORD}({WS}{IWORD})* ...@@ -254,6 +287,28 @@ ITYPE {IWORD}({WS}{IWORD})*
return SCALAR; return SCALAR;
} }
"VEC"{WS}?"("{WS}?{ID}{WS}?")" {
char *macro, *arg;
unsigned macro_len, arg_len;
char *ptr = yytext;
macro = ptr;
while (*ptr != '(' && !ISSPACE (*ptr))
ptr++;
macro_len = ptr - macro;
while (*ptr == '(' || ISSPACE (*ptr))
ptr++;
arg = ptr;
while (*ptr != ')' && !ISSPACE (*ptr))
ptr++;
arg_len = ptr - arg;
ptr = xmemdup (macro, macro_len, macro_len + arg_len + 2);
ptr[macro_len] = '_';
memcpy (&ptr[macro_len+1], arg, arg_len);
yylval.s = ptr;
return ID;
}
{ID}/[^[:alnum:]_] { {ID}/[^[:alnum:]_] {
yylval.s = xmemdup (yytext, yyleng, yyleng+1); yylval.s = xmemdup (yytext, yyleng, yyleng+1);
return ID; return ID;
...@@ -340,6 +395,93 @@ ITYPE {IWORD}({WS}{IWORD})* ...@@ -340,6 +395,93 @@ ITYPE {IWORD}({WS}{IWORD})*
%% %%
/* Deal with the expansion caused by the DEF_VEC_x macros. */
typedef struct macro
{
const char *name;
const char *expansion;
struct macro *next;
} macro_t;
static const macro_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;
/* Push macro NAME (NAME_LEN) with argument ARG (ARG_LEN) onto the
expansion queue. We ensure NAME is known at this point. */
static void
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 = xmalloc (sizeof (*expansion));
expansion->next = macro_expns;
expansion->name = xmemdup (arg, arg_len, arg_len+1);
expansion->expansion = macro_defs[ix].expansion;
macro_expns = expansion;
return;
}
error_at_line (&lexer_line, "unrecognized macro `%.*s(%.*s)'",
name_len, name, arg_len, arg);
}
/* 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->expansion; *expn; expn++)
{
if (*expn == '#')
{
if (buffer[result-1] == ' ' && buffer[result-2] == '_')
result--;
len = strlen (macro_expns->name);
memcpy (&buffer[result], macro_expns->name, len);
result += len;
}
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;
}
return result;
}
void void
yyerror (const char *s) yyerror (const char *s)
{ {
......
/* Vector API for GNU compiler.
Copyright (C) 2004 Free Software Foundation, Inc.
Contributed by Nathan Sidwell <nathan@codesourcery.com>
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
GCC 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 General Public License
for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA. */
#include "config.h"
#include "system.h"
#include "ggc.h"
#include "vec.h"
#include "errors.h"
#include "coretypes.h"
#include "tree.h"
struct vec_prefix
{
size_t num;
size_t alloc;
void *vec[1];
};
/* Ensure there are at least RESERVE free slots in VEC, if RESERVE !=
~0u. If RESERVE == ~0u increase the current allocation
exponentially. VEC can be NULL, to create a new vector. */
void *
vec_p_reserve (void *vec, size_t reserve)
{
return vec_o_reserve (vec, reserve,
offsetof (struct vec_prefix, vec), sizeof (void *));
}
/* Ensure there are at least RESERVE free slots in VEC, if RESERVE !=
~0u. If RESERVE == ~0u, increase the current allocation
exponentially. VEC can be NULL, in which case a new vector is
created. The vector's trailing array is at VEC_OFFSET offset and
consistes of ELT_SIZE sized elements. */
void *
vec_o_reserve (void *vec, size_t reserve, size_t vec_offset, size_t elt_size)
{
struct vec_prefix *pfx = vec;
size_t alloc;
if (reserve + 1)
alloc = (pfx ? pfx->num : 0) + reserve;
else
alloc = pfx ? pfx->alloc * 2 : 4;
if (!pfx || pfx->alloc < alloc)
{
vec = ggc_realloc (vec, vec_offset + alloc * elt_size);
((struct vec_prefix *)vec)->alloc = alloc;
if (!pfx)
((struct vec_prefix *)vec)->num = 0;
}
return vec;
}
/* Allocate a structure which contains a vector as a trailing element.
The vector is at STRUCT_OFFSET offset within the struct and the
vector's array is at VEC_OFFSET offset within the vector. */
void *
vec_embedded_alloc (size_t struct_offset, size_t vec_offset,
size_t elt_size, size_t reserve)
{
void *ptr = ggc_alloc (struct_offset + vec_offset + elt_size * reserve);
struct vec_prefix *pfx = (struct vec_prefix *)((char *)ptr + struct_offset);
pfx->num = 0;
pfx->alloc = reserve;
return ptr;
}
#if ENABLE_CHECKING
/* Issue a vector domain error, and then fall over. */
void
vec_assert_fail (const char *op, const char *struct_name,
const char *file, size_t line, const char *function)
{
internal_error ("vector %s %s domain error, in %s at %s:%u",
struct_name, op, function, function,
trim_filename (file), line);
}
#endif
This diff is collapsed. Click to expand it.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment