c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * CDDL HEADER START
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * This file and its contents are supplied under the terms of the
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Common Development and Distribution License ("CDDL"), version 1.0.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * You may only use this file in accordance with the terms of version
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * 1.0 of the CDDL.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * A full copy of the text of the CDDL should have accompanied this
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * source. A copy of the CDDL is also available via the Internet at
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * http://www.illumos.org/license/CDDL.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * CDDL HEADER END
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Copyright (c) 2012, 2016 by Delphix. All rights reserved.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Syntactic sugar features are implemented by transforming the D parse tree
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * such that it only uses the subset of D that is supported by the rest of the
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * compiler / the kernel. A clause containing these language features is
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * referred to as a "super-clause", and its transformation typically entails
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * creating several "sub-clauses" to implement it. For diagnosability, the
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * sub-clauses will be printed if the "-xtree=8" flag is specified.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Currently, the only syntactic sugar feature is "if/else" statements. Each
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * basic block (e.g. the body of the "if" and "else" statements, and the
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * statements before and after) is turned into its own sub-clause, with a
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * predicate that causes it to be executed only if the code flows to this point.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Nested if/else statements are supported.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * This infrastructure is designed to accommodate other syntactic sugar features
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * in the future.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <sys/types.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <sys/wait.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <sys/sysmacros.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <assert.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <strings.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <stdlib.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <stdio.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <ctype.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_module.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_program.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_provider.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_printf.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_pid.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_grammar.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_ident.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_string.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens#include <dt_impl.h>
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrenstypedef struct dt_sugar_parse {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dtrace_hdl_t *dtsp_dtp; /* dtrace handle */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *dtsp_pdescs; /* probe descriptions */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens int dtsp_num_conditions; /* number of condition variables */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens int dtsp_num_ifs; /* number of "if" statements */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *dtsp_clause_list; /* list of clauses */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens} dt_sugar_parse_t;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void dt_sugar_visit_stmts(dt_sugar_parse_t *, dt_node_t *, int);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Return a node for "self->%error".
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Note that the "%" is part of the variable name, and is included so that
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * this variable name can not collide with any user-specified variable.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * This error variable is used to keep track of if there has been an error
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * in any of the sub-clauses, and is used to prevent execution of subsequent
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * sub-clauses following an error.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic dt_node_t *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_new_error_var(void)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dt_node_op2(DT_TOK_PTR, dt_node_ident(strdup("self")),
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_ident(strdup("%error"))));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Append this clause to the clause list.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_append_clause(dt_sugar_parse_t *dp, dt_node_t *clause)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp->dtsp_clause_list = dt_node_link(dp->dtsp_clause_list, clause);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Prepend this clause to the clause list.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_prepend_clause(dt_sugar_parse_t *dp, dt_node_t *clause)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp->dtsp_clause_list = dt_node_link(clause, dp->dtsp_clause_list);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Return a node for "this->%condition_<condid>", or NULL if condid==0.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Note that the "%" is part of the variable name, and is included so that
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * this variable name can not collide with any user-specified variable.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic dt_node_t *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_new_condition_var(int condid)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens char *str;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (condid == 0)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (NULL);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens assert(condid > 0);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens (void) asprintf(&str, "%%condition_%d", ABS(condid));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dt_node_op2(DT_TOK_PTR, dt_node_ident(strdup("this")),
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_ident(str)));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Return new clause to evaluate predicate and set newcond. condid is
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * the condition that we are already under, or 0 if none.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * The new clause will be of the form:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * dp_pdescs
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * /!self->%error/
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * this->%condition_<newcond> =
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * (this->%condition_<condid> && pred);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Note: if condid==0, we will instead do "... = (1 && pred)", to effectively
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * convert the pred to a boolean.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Note: Unless an error has been encountered, we always set the condition
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * variable (either to 0 or 1). This lets us avoid resetting the condition
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * variables back to 0 when the super-clause completes.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic dt_node_t *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_new_condition_impl(dt_sugar_parse_t *dp,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *pred, int condid, int newcond)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *value, *body, *newpred;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* predicate is !self->%error */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens newpred = dt_node_op1(DT_TOK_LNEG, dt_sugar_new_error_var());
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (condid == 0) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * value is (1 && pred)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Note, D doesn't allow a probe-local "this" variable to
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * be reused as a different type, even from a different probe.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Therefore, value can't simply be <pred>, because then
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * its type could be different when we reuse this condid
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * in a different meta-clause.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens value = dt_node_op2(DT_TOK_LAND, dt_node_int(1), pred);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens } else {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* value is (this->%condition_<condid> && pred) */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens value = dt_node_op2(DT_TOK_LAND,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_condition_var(condid), pred);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* body is "this->%condition_<retval> = <value>;" */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens body = dt_node_statement(dt_node_op2(DT_TOK_ASGN,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_condition_var(newcond), value));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dt_node_clause(dp->dtsp_pdescs, newpred, body));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Generate a new clause to evaluate predicate and set a new condition variable,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * whose ID will be returned. The new clause will be appended to
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * dp_first_new_clause.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic int
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_new_condition(dt_sugar_parse_t *dp, dt_node_t *pred, int condid)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp->dtsp_num_conditions++;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_append_clause(dp, dt_sugar_new_condition_impl(dp,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens pred, condid, dp->dtsp_num_conditions));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dp->dtsp_num_conditions);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Visit the specified node and all of its descendants. Currently this is only
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * used to count the number of "if" statements (dtsp_num_ifs).
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_visit_all(dt_sugar_parse_t *dp, dt_node_t *dnp)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *arg;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens switch (dnp->dn_kind) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_FREE:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_INT:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_STRING:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_SYM:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_TYPE:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_PROBE:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_PDESC:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_IDENT:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_FUNC:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_args; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_OP1:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_child);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_OP2:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_left);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_right);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dnp->dn_op == DT_TOK_LBRAC) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *ln = dnp->dn_right;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens while (ln->dn_list != NULL) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, ln->dn_list);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens ln = ln->dn_list;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_OP3:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_expr);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_left);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_right);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_DEXPR:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_DFUNC:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_expr);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_AGG:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_aggtup; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dnp->dn_aggfun)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_aggfun);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_CLAUSE:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_pdescs; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dnp->dn_pred != NULL)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_pred);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_acts; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_INLINE: {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens const dt_idnode_t *inp = dnp->dn_ident->di_iarg;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, inp->din_root);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_MEMBER:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dnp->dn_membexpr)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_membexpr);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_XLATOR:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_members; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_PROVIDER:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_probes; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_PROG:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_list; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens case DT_NODE_IF:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp->dtsp_num_ifs++;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, dnp->dn_conditional);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_body; arg != NULL; arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (arg = dnp->dn_alternate_body; arg != NULL;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens arg = arg->dn_list)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(dp, arg);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens break;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens default:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens (void) dnerror(dnp, D_UNKNOWN, "bad node %p, kind %d\n",
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens (void *)dnp, dnp->dn_kind);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Return a new clause which resets the error variable to zero:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * dp_pdescs{ self->%error = 0; }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * This clause will be executed at the beginning of each meta-clause, to
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * ensure the error variable is unset (in case the previous meta-clause
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * failed).
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic dt_node_t *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_new_clearerror_clause(dt_sugar_parse_t *dp)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *stmt = dt_node_statement(dt_node_op2(DT_TOK_ASGN,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_error_var(), dt_node_int(0)));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dt_node_clause(dp->dtsp_pdescs, NULL, stmt));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Evaluate the conditional, and recursively visit the body of the "if"
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * statement (and the "else", if present).
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_do_if(dt_sugar_parse_t *dp, dt_node_t *if_stmt, int precondition)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens int newid;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens assert(if_stmt->dn_kind == DT_NODE_IF);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* condition */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens newid = dt_sugar_new_condition(dp,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if_stmt->dn_conditional, precondition);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* body of if */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_stmts(dp, if_stmt->dn_body, newid);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Visit the body of the "else" statement, if present. Note that we
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * generate a new condition which is the inverse of the previous
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * condition.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (if_stmt->dn_alternate_body != NULL) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *pred =
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_op1(DT_TOK_LNEG, dt_sugar_new_condition_var(newid));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_stmts(dp, if_stmt->dn_alternate_body,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_condition(dp, pred, precondition));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Generate a new clause to evaluate the statements based on the condition.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * The new clause will be appended to dp_first_new_clause.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * dp_pdescs
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * /!self->%error && this->%condition_<condid>/
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * stmts
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_new_basic_block(dt_sugar_parse_t *dp, int condid, dt_node_t *stmts)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *pred = NULL;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (condid == 0) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Don't bother with !error on the first clause, because if
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * there is only one clause, we don't add the prelude to
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * zero out %error.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dp->dtsp_num_conditions != 0) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens pred = dt_node_op1(DT_TOK_LNEG,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_error_var());
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens } else {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens pred = dt_node_op2(DT_TOK_LAND,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_op1(DT_TOK_LNEG, dt_sugar_new_error_var()),
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_condition_var(condid));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_append_clause(dp,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_clause(dp->dtsp_pdescs, pred, stmts));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Visit all the statements in this list, and break them into basic blocks,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * generating new clauses for "if" and "else" statements.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic void
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_visit_stmts(dt_sugar_parse_t *dp, dt_node_t *stmts, int precondition)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *stmt;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *prev_stmt = NULL;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *next_stmt;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *first_stmt_in_basic_block = NULL;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens for (stmt = stmts; stmt != NULL; stmt = next_stmt) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens next_stmt = stmt->dn_list;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (stmt->dn_kind != DT_NODE_IF) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (first_stmt_in_basic_block == NULL)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens first_stmt_in_basic_block = stmt;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens prev_stmt = stmt;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens continue;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Remove this and following statements from the previous
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * clause.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (prev_stmt != NULL)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens prev_stmt->dn_list = NULL;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Generate clause for statements preceding the "if"
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (first_stmt_in_basic_block != NULL) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_basic_block(dp, precondition,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens first_stmt_in_basic_block);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_do_if(dp, stmt, precondition);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens first_stmt_in_basic_block = NULL;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens prev_stmt = stmt;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* generate clause for statements after last "if". */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (first_stmt_in_basic_block != NULL) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_basic_block(dp, precondition,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens first_stmt_in_basic_block);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Generate a new clause which will set the error variable when an error occurs.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Only one of these clauses is created per program (e.g. script file).
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * The clause is:
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * dtrace:::ERROR{ self->%error = 1; }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensstatic dt_node_t *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_sugar_makeerrorclause(void)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_node_t *acts, *pdesc;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens pdesc = dt_node_pdesc_by_name(strdup("dtrace:::ERROR"));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens acts = dt_node_statement(dt_node_op2(DT_TOK_ASGN,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_error_var(), dt_node_int(1)));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dt_node_clause(pdesc, NULL, acts));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens/*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * Transform the super-clause into straight-D, returning the new list of
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * sub-clauses.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_node_t *
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrensdt_compile_sugar(dtrace_hdl_t *dtp, dt_node_t *clause)
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens{
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_parse_t dp = { 0 };
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens int condid = 0;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp.dtsp_dtp = dtp;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp.dtsp_pdescs = clause->dn_pdescs;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /* make dt_node_int() generate an "int"-typed integer */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens yyintdecimal = B_TRUE;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens yyintsuffix[0] = '\0';
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens yyintprefix = 0;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_all(&dp, clause);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dp.dtsp_num_ifs == 0 && dp.dtsp_num_conditions == 0) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * There is nothing that modifies the number of clauses. Use
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * the existing clause as-is, with its predicate intact. This
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * ensures that in the absence of D sugar, the body of the
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * clause can create a variable that is referenced in the
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * predicate.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_append_clause(&dp, dt_node_clause(clause->dn_pdescs,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens clause->dn_pred, clause->dn_acts));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens } else {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (clause->dn_pred != NULL) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens condid = dt_sugar_new_condition(&dp,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens clause->dn_pred, condid);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (clause->dn_acts == NULL) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens /*
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * dt_sugar_visit_stmts() does not emit a clause with
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * an empty body (e.g. if there's an empty "if" body),
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * but we need the empty body here so that we
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens * continue to get the default tracing action.
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens */
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_basic_block(&dp, condid, NULL);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens } else {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_visit_stmts(&dp, clause->dn_acts, condid);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dp.dtsp_num_conditions != 0) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_prepend_clause(&dp,
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_new_clearerror_clause(&dp));
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens if (dp.dtsp_clause_list != NULL &&
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dp.dtsp_clause_list->dn_list != NULL && !dtp->dt_has_sugar) {
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dtp->dt_has_sugar = B_TRUE;
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens dt_sugar_prepend_clause(&dp, dt_sugar_makeerrorclause());
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens }
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens return (dp.dtsp_clause_list);
c3bd3abd8856e8e75d820f65c58031cd6cbac818Matthew Ahrens}