This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [patch, fortran] Make frontend walker more general
On Tue, Sep 14, 2010 at 12:08:12AM +0200, Mikael Morin wrote:
> Your walker looks like :
>
> void walk_code (gfc_code *c, void (*handler)(gfc_code *))
> {
> if (c == NULL)
> return;
>
> (*handler) (c);
> walk_code (c->next);
> }
>
> your handler like :
>
> void handler (gfc_code *c)
> {
> switch (c->op)
> {
> case EXEC_ASSIGN:
> /* Do stuff */
> break;
>
> case EXEC_CALL:
> /* Do other stuff */
> break;
>
> default:
> default_handler (c);
> break;
> }
> }
I meant something like:
typedef int (*walk_code_fn_t) (gfc_code **, int *, void *);
typedef int (*walk_expr_fn_t) (gfc_expr **, int *, void *);
#define WALK_SUBEXPR(NODE) do { result = walk_expr (&(NODE), exprfn, data); if (result) return result; } while (0)
#define WALK_SUBEXPR_TAIL(NODE) e = &(NODE), continue
int
walk_expr (gfc_expr **e, walk_expr_fn_t exprfn, void *data)
{
while (*e)
{
int walk_subtrees = 1;
gfc_actual_arglist *a;
int result = exprfn (e, &walk_subtrees, data);
if (result)
return result;
if (walk_subtrees)
switch ((*e)->expr_type)
{
case EXPR_OP:
WALK_SUBEXPR ((*e)->value.op1);
WALK_SUBEXPR_TAIL ((*e)->value.op2);
break;
case EXPR_FUNCTION:
for (a = (*e)->value.function.actual; a; a = a->next)
WALK_SUBEXPR (a->expr);
break;
case EXPR_COMPCALL:
case EXPR_PPC:
for (a = (*e)->value.compcall.actual; a; a = a->next)
WALK_SUBEXPR (a->expr);
break;
default:
break;
}
return 0;
}
}
#define WALK_SUBCODE(NODE) do { result = walk_code (&(NODE), codefn, exprfn, data); if (result) return result; } while (0)
int
walk_code (gfc_code **c, walk_code_fn_t codefn, walk_expr_fn_t exprfn, void *data)
{
while (*c)
{
int walk_subtrees = 1;
int result = codefn (c, &walk_subtrees, data);
if (result)
return result;
if (walk_subtrees)
{
gfc_code *b;
for (b = (*c)->block; b; b = b->block)
WALK_SUBCODE (b->next);
switch ((*c)->code)
{
...
case EXEC_DO:
WALK_SUBEXPR ((*c)->ext.iterator->start);
WALK_SUBEXPR ((*c)->ext.iterator->end);
WALK_SUBEXPR ((*c)->ext.iterator->step);
break;
...
case EXEC_OMP_DO:
case EXEC_OMP_PARALLEL:
case EXEC_OMP_PARALLEL_DO:
case EXEC_OMP_PARALLEL_SECTIONS:
case EXEC_OMP_PARALLEL_WORKSHARE:
case EXEC_OMP_SECTIONS:
case EXEC_OMP_SINGLE:
case EXEC_OMP_WORKSHARE:
case EXEC_OMP_END_SINGLE:
case EXEC_OMP_TASK:
if ((*c)->ext.omp_clauses)
{
WALK_SUBEXPR ((c)->ext.omp_clauses->if_expr);
WALK_SUBEXPR ((c)->ext.omp_clauses->num_threads);
WALK_SUBEXPR ((c)->ext.omp_clauses->chunk_size);
}
break;
}
}
c = &(*c)->next;
}
}
Jakub