let get_stmt_annots config ~loop edges_before s l_post =
let add ((b_acc, (a_acc, e_acc)) as acc) b_list ca kind p before =
let add_to_acc k =
let a = prepare_annot before config s l_post ca p in
if before then
let b_acc = add_prop config b_acc k a in
(b_acc, (a_acc, e_acc))
else
let a_acc = add_prop config a_acc k a in
(b_acc, (a_acc, e_acc))
in
match is_annot_for_config config edges_before s b_list with
| TBRok | TBRpart -> add_to_acc kind
| TBRhyp -> add_to_acc Ahyp
| TBRno -> acc
in
let add_code_annot ca_before ca ((b_acc, (a_acc, e_acc)) as acc) =
match ca.annot_content with
| AInvariant (_b_list, loop_inv, _inv) ->
if loop_inv then acc
else begin
Wp_parameters.warning
"ignored 'invariant' (not implemented yet) : %a"
!Ast_printer.d_code_annotation ca;
acc
end
| AAssert (b_list,p) ->
add acc b_list ca Aboth p ca_before
| AAssigns (_b_list, _assigns) ->
if loop then acc
else
(Wp_parameters.warning "Loop assigns but not a loop. Ignored: %a"
!Ast_printer.d_code_annotation ca;
acc)
| AVariant (_v, _rel) ->
if loop then acc
else (Wp_parameters.warning "Variant outside a loop. Ignored: %a"
!Ast_printer.d_code_annotation ca;
acc)
| APragma _ ->
Wp_parameters.warning "Ignored annotation: %a"
!Ast_printer.d_code_annotation ca;
acc
| AStmtSpec spec ->
if ca_before then
let b_acc = add_stmt_spec_before config s spec b_acc in
let (a_acc, e_acc) =
add_stmt_spec_after config s l_post spec (a_acc, e_acc)
in (b_acc, (a_acc, e_acc))
else (Wp_parameters.warning ~once:true
"Ignoring specification rooted after statement %d" s.sid;
acc)
in
let do_annot a acc = match a with
| Before (User ca | AI (_, ca)) -> add_code_annot true ca acc
| After (User ca | AI (_, ca)) -> add_code_annot false ca acc
in
let before_acc, after_acc, exits_acc = empty_acc, empty_acc, empty_acc in
let acc = before_acc, (after_acc, exits_acc) in
Annotations.single_fold_stmt do_annot s acc