let rec convert_statement ~env stmt = 
  let loc = stmt.stmt_pr.ctt_loc in
  let sbody = 
    match stmt.stmt_t with
      CTTstmtNull -> PstmtExpr None
    | CTTstmtExpr(e) -> PstmtExpr (Some (convert_expr ~env e))
    | CTTstmtLabeled(l,s) -> PstmtLabeled(l, convert_statement ~env s)
    | CTTstmtCase_Labeled(l,s) -> 
        PstmtCase_Labeled(const_expr_of_big_int l ~loc, convert_statement ~env s)
    | CTTstmtDefault_Labeled(s) ->
        PstmtDefault_Labeled(convert_statement ~env s)
    | CTTstmtCompound(d,s) ->
      let ld = 
        List.map
          (fun (lsclass, ty, id, init) ->
            let sq, dc = convert_declarator ~env ty id in
            let lsclasses = convert_local_storage_class lsclass in
            make_decl
              (PdeclVariable
                 (lsclasses @ sq,
                  [PinitDecl(dc, Option.map (convert_initializer ~env) init)])))
          d
      in
      let ls = List.map (convert_statement ~env) s in
      PstmtCompound(ld, ls)
    | CTTstmtIf(e1,s2,s3) ->
      PstmtIf(convert_expr ~env e1,
              convert_statement ~env s2,
              Option.map (convert_statement ~env) s3)
    | CTTstmtSwitch(e1,s) ->
        PstmtSwitch(convert_expr ~env e1, convert_statement ~env s)
    | CTTstmtWhile(e1,s) ->
        PstmtWhile(convert_expr ~env e1, convert_statement ~env s)
    | CTTstmtDoWhile(s,e1) ->
        PstmtDoWhile(convert_statement ~env s, convert_expr ~env e1)
    | CTTstmtFor(e1,e2,e3,s) ->
        PstmtFor(Option.map (convert_expr ~env)        e1,
                 Option.map (convert_expr ~env)        e2,
                 Option.map (convert_expr ~env)        e3,
                 convert_statement ~env s)
    | CTTstmtGoto(id) ->
        PstmtGoto(id)
    | CTTstmtContinue -> PstmtContinue
    | CTTstmtBreak -> PstmtBreak
    | CTTstmtReturn(e1) ->
        PstmtReturn(Option.map (convert_expr ~env) e1)
  in
  make_stmt sbody ~orig:stmt