- r_ref_info = 0;
- ptr->visit(*this);
- if(r_ref_info && r_ref_info->expression && r_ref_info->available)
- {
- if(iteration_body && !r_ref_info->trivial)
- {
- /* Don't inline non-trivial expressions which were assigned outside
- an iteration statement. The iteration may run multiple times, which
- would cause the expression to also be evaluated multiple times. */
- Block *i = r_ref_info->assign_scope;
- for(; (i && i!=iteration_body); i=i->parent) ;
- if(!i)
- return;
- }
-
- r_ref_info->outer_oper = outer_oper;
- if(r_ref_info->trivial)
- inline_expression(*r_ref_info->expression, ptr, outer_oper, r_ref_info->inner_oper, on_rhs);
- else
- {
- /* Record the inline point for a non-trivial expression but don't
- inline it yet. It might turn out it shouldn't be inlined after all. */
- r_ref_info->inline_point = &ptr;
- r_ref_info->inline_on_rhs = on_rhs;
- }
- }
- r_ref_info = 0;
-}
-
-void ExpressionInliner::inline_expression(Expression &expr, RefPtr<Expression> &ptr, const Operator *outer_oper, const Operator *inner_oper, bool on_rhs)
-{
- unsigned outer_precedence = (outer_oper ? outer_oper->precedence : 20);
- unsigned inner_precedence = (inner_oper ? inner_oper->precedence : 0);
-
- bool needs_parentheses = (inner_precedence>=outer_precedence);
- if(inner_oper && inner_oper==outer_oper)
- // Omit parentheses if the operator's natural grouping works out.
- needs_parentheses = (inner_oper->assoc!=Operator::ASSOCIATIVE && on_rhs!=(inner_oper->assoc==Operator::RIGHT_TO_LEFT));
-
- if(needs_parentheses)
- {
- RefPtr<ParenthesizedExpression> parexpr = new ParenthesizedExpression;
- parexpr->expression = expr.clone();
- ptr = parexpr;
- }
- else
- ptr = expr.clone();
-