let visit_statement ~v_expr ~v_ldecl ~self stmt = 
  let body = match stmt.stmt_t with
    CTTstmtNull -> CTTstmtNull
  | CTTstmtExpr(e) -> CTTstmtExpr(v_expr e)
  | CTTstmtLabeled(l,s) -> CTTstmtLabeled(l,self s)
  | CTTstmtCase_Labeled(l,s) -> CTTstmtCase_Labeled(l,self s)
  | CTTstmtDefault_Labeled(s) -> CTTstmtDefault_Labeled(self s)
  | CTTstmtCompound(dcls, stmts) -> 
      let dcls = list_map_ordered v_ldecl dcls in
      let stmts = list_map_ordered self stmts in
      CTTstmtCompound(dcls, stmts)
  | CTTstmtIf(e,s_th,s_el) -> 
      let e = v_expr e in
      let s_th = self s_th in
      let s_el = Option.map self s_el in
      CTTstmtIf(e, s_th, s_el)
  | CTTstmtSwitch(e,s) ->
      let e = v_expr e in
      CTTstmtSwitch(e, self s)
  | CTTstmtWhile(e,s) -> 
      let e = v_expr e in
      CTTstmtWhile(e, self s)
  | CTTstmtDoWhile(s,e) ->
      let s = self s in
      let e = v_expr e in
      CTTstmtDoWhile(s, e)
  | CTTstmtFor(e1,e2,e3,s) ->
      let e1 = Option.map v_expr e1 in
      let e2 = Option.map v_expr e2 in
      let e3 = Option.map v_expr e3 in
      CTTstmtFor(e1, e2, e3, self s)
  | CTTstmtGoto(_) | CTTstmtContinue | CTTstmtBreak as st -> st
  | CTTstmtReturn(e) -> CTTstmtReturn(Option.map v_expr e)
  in
  { stmt with stmt_t = body }