mirror of
https://review.haiku-os.org/buildtools
synced 2025-01-19 12:51:22 +01:00
5873a060ca
* these are dependencies for gcc 4 Graphite engine build. * CLooG 0.18.0 includes ISL 0.11.1 which is the backend that the build script enables. * PPL is needed by GCC build even if it isn't the chosen backend.
574 lines
18 KiB
C
574 lines
18 KiB
C
|
|
/**-------------------------------------------------------------------**
|
|
** CLooG **
|
|
**-------------------------------------------------------------------**
|
|
** pprint.c **
|
|
**-------------------------------------------------------------------**
|
|
** First version: october 26th 2001 **
|
|
**-------------------------------------------------------------------**/
|
|
|
|
|
|
/******************************************************************************
|
|
* CLooG : the Chunky Loop Generator (experimental) *
|
|
******************************************************************************
|
|
* *
|
|
* Copyright (C) 2001-2005 Cedric Bastoul *
|
|
* *
|
|
* This library is free software; you can redistribute it and/or *
|
|
* modify it under the terms of the GNU Lesser General Public *
|
|
* License as published by the Free Software Foundation; either *
|
|
* version 2.1 of the License, or (at your option) any later version. *
|
|
* *
|
|
* This library 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 *
|
|
* Lesser General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU Lesser General Public *
|
|
* License along with this library; if not, write to the Free Software *
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
|
|
* Boston, MA 02110-1301 USA *
|
|
* *
|
|
* CLooG, the Chunky Loop Generator *
|
|
* Written by Cedric Bastoul, Cedric.Bastoul@inria.fr *
|
|
* *
|
|
******************************************************************************/
|
|
/* CAUTION: the english used for comments is probably the worst you ever read,
|
|
* please feel free to correct and improve it !
|
|
*/
|
|
|
|
/* June 22nd 2005: General adaptation for GMP.
|
|
* October 26th 2005: General adaptation from CloogDomain to Matrix data
|
|
* structure for all constraint systems.
|
|
* October 27th 2005: General adaptation from CloogEqual to Matrix data
|
|
* structure for equality spreading.
|
|
*/
|
|
|
|
# include <stdlib.h>
|
|
# include <stdio.h>
|
|
# include <string.h>
|
|
#include <assert.h>
|
|
# include "../include/cloog/cloog.h"
|
|
|
|
#ifdef OSL_SUPPORT
|
|
#include <osl/util.h>
|
|
#include <osl/body.h>
|
|
#include <osl/statement.h>
|
|
#include <osl/scop.h>
|
|
#endif
|
|
|
|
|
|
static void pprint_name(FILE *dst, struct clast_name *n);
|
|
static void pprint_term(struct cloogoptions *i, FILE *dst, struct clast_term *t);
|
|
static void pprint_sum(struct cloogoptions *opt,
|
|
FILE *dst, struct clast_reduction *r);
|
|
static void pprint_binary(struct cloogoptions *i,
|
|
FILE *dst, struct clast_binary *b);
|
|
static void pprint_minmax_f(struct cloogoptions *info,
|
|
FILE *dst, struct clast_reduction *r);
|
|
static void pprint_minmax_c(struct cloogoptions *info,
|
|
FILE *dst, struct clast_reduction *r);
|
|
static void pprint_reduction(struct cloogoptions *i,
|
|
FILE *dst, struct clast_reduction *r);
|
|
static void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e);
|
|
static void pprint_equation(struct cloogoptions *i,
|
|
FILE *dst, struct clast_equation *eq);
|
|
static void pprint_assignment(struct cloogoptions *i, FILE *dst,
|
|
struct clast_assignment *a);
|
|
static void pprint_user_stmt(struct cloogoptions *options, FILE *dst,
|
|
struct clast_user_stmt *u);
|
|
static void pprint_guard(struct cloogoptions *options, FILE *dst, int indent,
|
|
struct clast_guard *g);
|
|
static void pprint_for(struct cloogoptions *options, FILE *dst, int indent,
|
|
struct clast_for *f);
|
|
static void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
|
|
struct clast_stmt *s);
|
|
|
|
|
|
void pprint_name(FILE *dst, struct clast_name *n)
|
|
{
|
|
fprintf(dst, "%s", n->name);
|
|
}
|
|
|
|
/**
|
|
* This function returns a string containing the printing of a value (possibly
|
|
* an iterator or a parameter with its coefficient or a constant).
|
|
* - val is the coefficient or constant value,
|
|
* - name is a string containing the name of the iterator or of the parameter,
|
|
*/
|
|
void pprint_term(struct cloogoptions *i, FILE *dst, struct clast_term *t)
|
|
{
|
|
if (t->var) {
|
|
int group = t->var->type == clast_expr_red &&
|
|
((struct clast_reduction*) t->var)->n > 1;
|
|
if (cloog_int_is_one(t->val))
|
|
;
|
|
else if (cloog_int_is_neg_one(t->val))
|
|
fprintf(dst, "-");
|
|
else {
|
|
cloog_int_print(dst, t->val);
|
|
fprintf(dst, "*");
|
|
}
|
|
if (group)
|
|
fprintf(dst, "(");
|
|
pprint_expr(i, dst, t->var);
|
|
if (group)
|
|
fprintf(dst, ")");
|
|
} else
|
|
cloog_int_print(dst, t->val);
|
|
}
|
|
|
|
void pprint_sum(struct cloogoptions *opt, FILE *dst, struct clast_reduction *r)
|
|
{
|
|
int i;
|
|
struct clast_term *t;
|
|
|
|
assert(r->n >= 1);
|
|
assert(r->elts[0]->type == clast_expr_term);
|
|
t = (struct clast_term *) r->elts[0];
|
|
pprint_term(opt, dst, t);
|
|
|
|
for (i = 1; i < r->n; ++i) {
|
|
assert(r->elts[i]->type == clast_expr_term);
|
|
t = (struct clast_term *) r->elts[i];
|
|
if (cloog_int_is_pos(t->val))
|
|
fprintf(dst, "+");
|
|
pprint_term(opt, dst, t);
|
|
}
|
|
}
|
|
|
|
void pprint_binary(struct cloogoptions *i, FILE *dst, struct clast_binary *b)
|
|
{
|
|
const char *s1 = NULL, *s2 = NULL, *s3 = NULL;
|
|
int group = b->LHS->type == clast_expr_red &&
|
|
((struct clast_reduction*) b->LHS)->n > 1;
|
|
if (i->language == CLOOG_LANGUAGE_FORTRAN) {
|
|
switch (b->type) {
|
|
case clast_bin_fdiv:
|
|
s1 = "FLOOR(REAL(", s2 = ")/REAL(", s3 = "))";
|
|
break;
|
|
case clast_bin_cdiv:
|
|
s1 = "CEILING(REAL(", s2 = ")/REAL(", s3 = "))";
|
|
break;
|
|
case clast_bin_div:
|
|
if (group)
|
|
s1 = "(", s2 = ")/", s3 = "";
|
|
else
|
|
s1 = "", s2 = "/", s3 = "";
|
|
break;
|
|
case clast_bin_mod:
|
|
s1 = "MOD(", s2 = ", ", s3 = ")";
|
|
break;
|
|
}
|
|
} else {
|
|
switch (b->type) {
|
|
case clast_bin_fdiv:
|
|
s1 = "floord(", s2 = ",", s3 = ")";
|
|
break;
|
|
case clast_bin_cdiv:
|
|
s1 = "ceild(", s2 = ",", s3 = ")";
|
|
break;
|
|
case clast_bin_div:
|
|
if (group)
|
|
s1 = "(", s2 = ")/", s3 = "";
|
|
else
|
|
s1 = "", s2 = "/", s3 = "";
|
|
break;
|
|
case clast_bin_mod:
|
|
if (group)
|
|
s1 = "(", s2 = ")%", s3 = "";
|
|
else
|
|
s1 = "", s2 = "%", s3 = "";
|
|
break;
|
|
}
|
|
}
|
|
fprintf(dst, "%s", s1);
|
|
pprint_expr(i, dst, b->LHS);
|
|
fprintf(dst, "%s", s2);
|
|
cloog_int_print(dst, b->RHS);
|
|
fprintf(dst, "%s", s3);
|
|
}
|
|
|
|
void pprint_minmax_f(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
|
|
{
|
|
int i;
|
|
if (r->n == 0)
|
|
return;
|
|
fprintf(dst, r->type == clast_red_max ? "MAX(" : "MIN(");
|
|
pprint_expr(info, dst, r->elts[0]);
|
|
for (i = 1; i < r->n; ++i) {
|
|
fprintf(dst, ",");
|
|
pprint_expr(info, dst, r->elts[i]);
|
|
}
|
|
fprintf(dst, ")");
|
|
}
|
|
|
|
void pprint_minmax_c(struct cloogoptions *info, FILE *dst, struct clast_reduction *r)
|
|
{
|
|
int i;
|
|
for (i = 1; i < r->n; ++i)
|
|
fprintf(dst, r->type == clast_red_max ? "max(" : "min(");
|
|
if (r->n > 0)
|
|
pprint_expr(info, dst, r->elts[0]);
|
|
for (i = 1; i < r->n; ++i) {
|
|
fprintf(dst, ",");
|
|
pprint_expr(info, dst, r->elts[i]);
|
|
fprintf(dst, ")");
|
|
}
|
|
}
|
|
|
|
void pprint_reduction(struct cloogoptions *i, FILE *dst, struct clast_reduction *r)
|
|
{
|
|
switch (r->type) {
|
|
case clast_red_sum:
|
|
pprint_sum(i, dst, r);
|
|
break;
|
|
case clast_red_min:
|
|
case clast_red_max:
|
|
if (r->n == 1) {
|
|
pprint_expr(i, dst, r->elts[0]);
|
|
break;
|
|
}
|
|
if (i->language == CLOOG_LANGUAGE_FORTRAN)
|
|
pprint_minmax_f(i, dst, r);
|
|
else
|
|
pprint_minmax_c(i, dst, r);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
void pprint_expr(struct cloogoptions *i, FILE *dst, struct clast_expr *e)
|
|
{
|
|
if (!e)
|
|
return;
|
|
switch (e->type) {
|
|
case clast_expr_name:
|
|
pprint_name(dst, (struct clast_name*) e);
|
|
break;
|
|
case clast_expr_term:
|
|
pprint_term(i, dst, (struct clast_term*) e);
|
|
break;
|
|
case clast_expr_red:
|
|
pprint_reduction(i, dst, (struct clast_reduction*) e);
|
|
break;
|
|
case clast_expr_bin:
|
|
pprint_binary(i, dst, (struct clast_binary*) e);
|
|
break;
|
|
default:
|
|
assert(0);
|
|
}
|
|
}
|
|
|
|
void pprint_equation(struct cloogoptions *i, FILE *dst, struct clast_equation *eq)
|
|
{
|
|
pprint_expr(i, dst, eq->LHS);
|
|
if (eq->sign == 0)
|
|
fprintf(dst, " == ");
|
|
else if (eq->sign > 0)
|
|
fprintf(dst, " >= ");
|
|
else
|
|
fprintf(dst, " <= ");
|
|
pprint_expr(i, dst, eq->RHS);
|
|
}
|
|
|
|
void pprint_assignment(struct cloogoptions *i, FILE *dst,
|
|
struct clast_assignment *a)
|
|
{
|
|
if (a->LHS)
|
|
fprintf(dst, "%s = ", a->LHS);
|
|
pprint_expr(i, dst, a->RHS);
|
|
}
|
|
|
|
|
|
/**
|
|
* pprint_osl_body function:
|
|
* this function pretty-prints the OpenScop body of a given statement.
|
|
* It returns 1 if it succeeds to find an OpenScop body to print for
|
|
* that statement, 0 otherwise.
|
|
* \param[in] options CLooG Options.
|
|
* \param[in] dst Output stream.
|
|
* \param[in] u Statement to print the OpenScop body.
|
|
* \return 1 on success to pretty-print an OpenScop body for u, 0 otherwise.
|
|
*/
|
|
int pprint_osl_body(struct cloogoptions *options, FILE *dst,
|
|
struct clast_user_stmt *u) {
|
|
#ifdef OSL_SUPPORT
|
|
int i;
|
|
char *expr, *tmp;
|
|
struct clast_stmt *t;
|
|
osl_scop_p scop = options->scop;
|
|
osl_statement_p stmt;
|
|
osl_body_p body;
|
|
|
|
if ((scop != NULL) &&
|
|
(osl_statement_number(scop->statement) >= u->statement->number)) {
|
|
stmt = scop->statement;
|
|
|
|
/* Go to the convenient statement in the SCoP. */
|
|
for (i = 1; i < u->statement->number; i++)
|
|
stmt = stmt->next;
|
|
|
|
/* Ensure it has a printable body. */
|
|
if ((osl_generic_has_URI(stmt->body, OSL_URI_BODY)) &&
|
|
((body = stmt->body->data) != NULL) &&
|
|
(body->expression != NULL) &&
|
|
(body->iterators != NULL)) {
|
|
expr = osl_util_identifier_substitution(body->expression->string[0],
|
|
body->iterators->string);
|
|
tmp = expr;
|
|
/* Print the body expression, substituting the @...@ markers. */
|
|
while (*expr) {
|
|
if (*expr == '@') {
|
|
int iterator;
|
|
expr += sscanf(expr, "@%d", &iterator) + 2; /* 2 for the @s */
|
|
t = u->substitutions;
|
|
for (i = 0; i < iterator; i++)
|
|
t = t->next;
|
|
pprint_assignment(options, dst, (struct clast_assignment *)t);
|
|
} else {
|
|
fprintf(dst, "%c", *expr++);
|
|
}
|
|
}
|
|
fprintf(dst, "\n");
|
|
free(tmp);
|
|
return 1;
|
|
}
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
void pprint_user_stmt(struct cloogoptions *options, FILE *dst,
|
|
struct clast_user_stmt *u)
|
|
{
|
|
struct clast_stmt *t;
|
|
|
|
if (pprint_osl_body(options, dst, u))
|
|
return;
|
|
|
|
if (u->statement->name)
|
|
fprintf(dst, "%s", u->statement->name);
|
|
else
|
|
fprintf(dst, "S%d", u->statement->number);
|
|
fprintf(dst, "(");
|
|
for (t = u->substitutions; t; t = t->next) {
|
|
assert(CLAST_STMT_IS_A(t, stmt_ass));
|
|
pprint_assignment(options, dst, (struct clast_assignment *)t);
|
|
if (t->next)
|
|
fprintf(dst, ",");
|
|
}
|
|
fprintf(dst, ")");
|
|
if (options->language != CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst, ";");
|
|
fprintf(dst, "\n");
|
|
}
|
|
|
|
void pprint_guard(struct cloogoptions *options, FILE *dst, int indent,
|
|
struct clast_guard *g)
|
|
{
|
|
int k;
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst,"IF ");
|
|
else
|
|
fprintf(dst,"if ");
|
|
if (g->n > 1)
|
|
fprintf(dst,"(");
|
|
for (k = 0; k < g->n; ++k) {
|
|
if (k > 0) {
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst," .AND. ");
|
|
else
|
|
fprintf(dst," && ");
|
|
}
|
|
fprintf(dst,"(");
|
|
pprint_equation(options, dst, &g->eq[k]);
|
|
fprintf(dst,")");
|
|
}
|
|
if (g->n > 1)
|
|
fprintf(dst,")");
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst," THEN\n");
|
|
else
|
|
fprintf(dst," {\n");
|
|
|
|
pprint_stmt_list(options, dst, indent + INDENT_STEP, g->then);
|
|
|
|
fprintf(dst, "%*s", indent, "");
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst,"END IF\n");
|
|
else
|
|
fprintf(dst,"}\n");
|
|
}
|
|
|
|
void pprint_for(struct cloogoptions *options, FILE *dst, int indent,
|
|
struct clast_for *f)
|
|
{
|
|
if (options->language == CLOOG_LANGUAGE_C) {
|
|
if ((f->parallel & CLAST_PARALLEL_OMP) && !(f->parallel & CLAST_PARALLEL_MPI)) {
|
|
if (f->LB) {
|
|
fprintf(dst, "lbp=");
|
|
pprint_expr(options, dst, f->LB);
|
|
fprintf(dst, ";\n");
|
|
}
|
|
if (f->UB) {
|
|
fprintf(dst, "%*s", indent, "");
|
|
fprintf(dst, "ubp=");
|
|
pprint_expr(options, dst, f->UB);
|
|
fprintf(dst, ";\n");
|
|
}
|
|
fprintf(dst, "#pragma omp parallel for%s%s%s%s%s%s\n",
|
|
(f->private_vars)? " private(":"",
|
|
(f->private_vars)? f->private_vars: "",
|
|
(f->private_vars)? ")":"",
|
|
(f->reduction_vars)? " reduction(": "",
|
|
(f->reduction_vars)? f->reduction_vars: "",
|
|
(f->reduction_vars)? ")": "");
|
|
fprintf(dst, "%*s", indent, "");
|
|
}
|
|
if ((f->parallel & CLAST_PARALLEL_VEC) && !(f->parallel & CLAST_PARALLEL_OMP)
|
|
&& !(f->parallel & CLAST_PARALLEL_MPI)) {
|
|
if (f->LB) {
|
|
fprintf(dst, "lbv=");
|
|
pprint_expr(options, dst, f->LB);
|
|
fprintf(dst, ";\n");
|
|
}
|
|
if (f->UB) {
|
|
fprintf(dst, "%*s", indent, "");
|
|
fprintf(dst, "ubv=");
|
|
pprint_expr(options, dst, f->UB);
|
|
fprintf(dst, ";\n");
|
|
}
|
|
fprintf(dst, "%*s#pragma ivdep\n", indent, "");
|
|
fprintf(dst, "%*s#pragma vector always\n", indent, "");
|
|
fprintf(dst, "%*s", indent, "");
|
|
}
|
|
if (f->parallel & CLAST_PARALLEL_MPI) {
|
|
if (f->LB) {
|
|
fprintf(dst, "_lb_dist=");
|
|
pprint_expr(options, dst, f->LB);
|
|
fprintf(dst, ";\n");
|
|
}
|
|
if (f->UB) {
|
|
fprintf(dst, "%*s", indent, "");
|
|
fprintf(dst, "_ub_dist=");
|
|
pprint_expr(options, dst, f->UB);
|
|
fprintf(dst, ";\n");
|
|
}
|
|
fprintf(dst, "%*s", indent, "");
|
|
fprintf(dst, "polyrt_loop_dist(_lb_dist, _ub_dist, nprocs, my_rank, &lbp, &ubp);\n");
|
|
if (f->parallel & CLAST_PARALLEL_OMP) {
|
|
fprintf(dst, "#pragma omp parallel for%s%s%s%s%s%s\n",
|
|
(f->private_vars)? " private(":"",
|
|
(f->private_vars)? f->private_vars: "",
|
|
(f->private_vars)? ")":"",
|
|
(f->reduction_vars)? " reduction(": "",
|
|
(f->reduction_vars)? f->reduction_vars: "",
|
|
(f->reduction_vars)? ")": "");
|
|
}
|
|
fprintf(dst, "%*s", indent, "");
|
|
}
|
|
|
|
}
|
|
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst, "DO ");
|
|
else
|
|
fprintf(dst, "for (");
|
|
|
|
if (f->LB) {
|
|
fprintf(dst, "%s=", f->iterator);
|
|
if (f->parallel & (CLAST_PARALLEL_OMP | CLAST_PARALLEL_MPI)) {
|
|
fprintf(dst, "lbp");
|
|
}else if (f->parallel & CLAST_PARALLEL_VEC){
|
|
fprintf(dst, "lbv");
|
|
}else{
|
|
pprint_expr(options, dst, f->LB);
|
|
}
|
|
} else if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
cloog_die("unbounded loops not allowed in FORTRAN.\n");
|
|
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst,", ");
|
|
else
|
|
fprintf(dst,";");
|
|
|
|
if (f->UB) {
|
|
if (options->language != CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst,"%s<=", f->iterator);
|
|
|
|
if (f->parallel & (CLAST_PARALLEL_OMP | CLAST_PARALLEL_MPI)) {
|
|
fprintf(dst, "ubp");
|
|
}else if (f->parallel & CLAST_PARALLEL_VEC){
|
|
fprintf(dst, "ubv");
|
|
}else{
|
|
pprint_expr(options, dst, f->UB);
|
|
}
|
|
}else if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
cloog_die("unbounded loops not allowed in FORTRAN.\n");
|
|
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN) {
|
|
if (cloog_int_gt_si(f->stride, 1))
|
|
cloog_int_print(dst, f->stride);
|
|
fprintf(dst,"\n");
|
|
}
|
|
else {
|
|
if (cloog_int_gt_si(f->stride, 1)) {
|
|
fprintf(dst,";%s+=", f->iterator);
|
|
cloog_int_print(dst, f->stride);
|
|
fprintf(dst, ") {\n");
|
|
} else
|
|
fprintf(dst, ";%s++) {\n", f->iterator);
|
|
}
|
|
|
|
pprint_stmt_list(options, dst, indent + INDENT_STEP, f->body);
|
|
|
|
fprintf(dst, "%*s", indent, "");
|
|
if (options->language == CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst,"END DO\n") ;
|
|
else
|
|
fprintf(dst,"}\n") ;
|
|
}
|
|
|
|
void pprint_stmt_list(struct cloogoptions *options, FILE *dst, int indent,
|
|
struct clast_stmt *s)
|
|
{
|
|
for ( ; s; s = s->next) {
|
|
if (CLAST_STMT_IS_A(s, stmt_root))
|
|
continue;
|
|
fprintf(dst, "%*s", indent, "");
|
|
if (CLAST_STMT_IS_A(s, stmt_ass)) {
|
|
pprint_assignment(options, dst, (struct clast_assignment *) s);
|
|
if (options->language != CLOOG_LANGUAGE_FORTRAN)
|
|
fprintf(dst, ";");
|
|
fprintf(dst, "\n");
|
|
} else if (CLAST_STMT_IS_A(s, stmt_user)) {
|
|
pprint_user_stmt(options, dst, (struct clast_user_stmt *) s);
|
|
} else if (CLAST_STMT_IS_A(s, stmt_for)) {
|
|
pprint_for(options, dst, indent, (struct clast_for *) s);
|
|
} else if (CLAST_STMT_IS_A(s, stmt_guard)) {
|
|
pprint_guard(options, dst, indent, (struct clast_guard *) s);
|
|
} else if (CLAST_STMT_IS_A(s, stmt_block)) {
|
|
fprintf(dst, "{\n");
|
|
pprint_stmt_list(options, dst, indent + INDENT_STEP,
|
|
((struct clast_block *)s)->body);
|
|
fprintf(dst, "%*s", indent, "");
|
|
fprintf(dst, "}\n");
|
|
} else {
|
|
assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/******************************************************************************
|
|
* Pretty Printing (dirty) functions *
|
|
******************************************************************************/
|
|
|
|
void clast_pprint(FILE *foo, struct clast_stmt *root,
|
|
int indent, CloogOptions *options)
|
|
{
|
|
pprint_stmt_list(options, foo, indent, root);
|
|
}
|