|
|
@ -30,33 +30,6 @@ let fresh_decl_info decl_info =
|
|
|
|
{decl_info with Clang_ast_t.di_pointer= CAst_utils.get_fresh_pointer ()}
|
|
|
|
{decl_info with Clang_ast_t.di_pointer= CAst_utils.get_fresh_pointer ()}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let empty_decl_info =
|
|
|
|
|
|
|
|
{ Clang_ast_t.di_pointer= CAst_utils.get_invalid_pointer ()
|
|
|
|
|
|
|
|
; di_parent_pointer= None
|
|
|
|
|
|
|
|
; di_source_range= dummy_source_range ()
|
|
|
|
|
|
|
|
; di_owning_module= None
|
|
|
|
|
|
|
|
; di_is_hidden= false
|
|
|
|
|
|
|
|
; di_is_implicit= false
|
|
|
|
|
|
|
|
; di_is_used= true
|
|
|
|
|
|
|
|
; di_is_this_declaration_referenced= true
|
|
|
|
|
|
|
|
; di_is_invalid_decl= false
|
|
|
|
|
|
|
|
; di_attributes= []
|
|
|
|
|
|
|
|
; di_full_comment= None
|
|
|
|
|
|
|
|
; di_access= `None }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let empty_var_decl_info =
|
|
|
|
|
|
|
|
{ Clang_ast_t.vdi_storage_class= None
|
|
|
|
|
|
|
|
; vdi_tls_kind= `Tls_none
|
|
|
|
|
|
|
|
; vdi_is_global= false
|
|
|
|
|
|
|
|
; vdi_is_static_local= false
|
|
|
|
|
|
|
|
; vdi_is_module_private= false
|
|
|
|
|
|
|
|
; vdi_is_nrvo_variable= false
|
|
|
|
|
|
|
|
; vdi_is_const_expr= false
|
|
|
|
|
|
|
|
; vdi_init_expr= None
|
|
|
|
|
|
|
|
; vdi_parm_index_in_function= None }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let stmt_info_with_fresh_pointer stmt_info =
|
|
|
|
let stmt_info_with_fresh_pointer stmt_info =
|
|
|
|
{ Clang_ast_t.si_pointer= CAst_utils.get_fresh_pointer ()
|
|
|
|
{ Clang_ast_t.si_pointer= CAst_utils.get_fresh_pointer ()
|
|
|
|
; si_source_range= stmt_info.Clang_ast_t.si_source_range }
|
|
|
|
; si_source_range= stmt_info.Clang_ast_t.si_source_range }
|
|
|
@ -94,12 +67,6 @@ let create_char_star_type ?quals () = create_pointer_qual_type ?quals create_cha
|
|
|
|
|
|
|
|
|
|
|
|
let create_BOOL_type = builtin_to_qual_type `SChar
|
|
|
|
let create_BOOL_type = builtin_to_qual_type `SChar
|
|
|
|
|
|
|
|
|
|
|
|
let create_unsigned_long_type = builtin_to_qual_type `ULong
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let create_void_unsigned_long_type = function_type_ptr create_void_type
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let create_void_void_type = function_type_ptr create_void_type
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let create_class_qual_type ?quals typename =
|
|
|
|
let create_class_qual_type ?quals typename =
|
|
|
|
create_qual_type ?quals (Clang_ast_extend.ClassType typename)
|
|
|
|
create_qual_type ?quals (Clang_ast_extend.ClassType typename)
|
|
|
|
|
|
|
|
|
|
|
@ -168,13 +135,6 @@ let make_expr_info qt vk objc_kind =
|
|
|
|
|
|
|
|
|
|
|
|
let make_expr_info_with_objc_kind qt objc_kind = make_expr_info qt `LValue objc_kind
|
|
|
|
let make_expr_info_with_objc_kind qt objc_kind = make_expr_info qt `LValue objc_kind
|
|
|
|
|
|
|
|
|
|
|
|
let make_decl_ref_exp stmt_info expr_info drei =
|
|
|
|
|
|
|
|
let stmt_info =
|
|
|
|
|
|
|
|
{ Clang_ast_t.si_pointer= CAst_utils.get_fresh_pointer ()
|
|
|
|
|
|
|
|
; si_source_range= stmt_info.Clang_ast_t.si_source_range }
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
Clang_ast_t.DeclRefExpr (stmt_info, [], expr_info, drei)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let make_obj_c_message_expr_info_instance sel =
|
|
|
|
let make_obj_c_message_expr_info_instance sel =
|
|
|
|
{ Clang_ast_t.omei_selector= sel
|
|
|
|
{ Clang_ast_t.omei_selector= sel
|
|
|
@ -204,10 +164,6 @@ let make_decl_ref_qt k decl_ptr name is_hidden qt =
|
|
|
|
|
|
|
|
|
|
|
|
let make_decl_ref_no_qt k decl_ptr name is_hidden = make_decl_ref k decl_ptr name is_hidden None
|
|
|
|
let make_decl_ref_no_qt k decl_ptr name is_hidden = make_decl_ref k decl_ptr name is_hidden None
|
|
|
|
|
|
|
|
|
|
|
|
let make_decl_ref_invalid k name is_hidden qt =
|
|
|
|
|
|
|
|
make_decl_ref k (CAst_utils.get_invalid_pointer ()) name is_hidden (Some qt)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let make_decl_ref_expr_info decl_ref =
|
|
|
|
let make_decl_ref_expr_info decl_ref =
|
|
|
|
{Clang_ast_t.drti_decl_ref= Some decl_ref; drti_found_decl_ref= None}
|
|
|
|
{Clang_ast_t.drti_decl_ref= Some decl_ref; drti_found_decl_ref= None}
|
|
|
|
|
|
|
|
|
|
|
@ -220,11 +176,6 @@ let make_general_expr_info qt vk ok =
|
|
|
|
{Clang_ast_t.ei_qual_type= qt; ei_value_kind= vk; ei_object_kind= ok}
|
|
|
|
{Clang_ast_t.ei_qual_type= qt; ei_value_kind= vk; ei_object_kind= ok}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let make_ObjCBoolLiteralExpr stmt_info value =
|
|
|
|
|
|
|
|
let ei = make_expr_info create_BOOL_type in
|
|
|
|
|
|
|
|
Clang_ast_t.ObjCBoolLiteralExpr (fresh_stmt_info stmt_info, [], ei, value)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let make_message_expr param_qt selector decl_ref_exp stmt_info add_cast =
|
|
|
|
let make_message_expr param_qt selector decl_ref_exp stmt_info add_cast =
|
|
|
|
let stmt_info = stmt_info_with_fresh_pointer stmt_info in
|
|
|
|
let stmt_info = stmt_info_with_fresh_pointer stmt_info in
|
|
|
|
let parameters =
|
|
|
|
let parameters =
|
|
|
@ -292,22 +243,6 @@ let translate_dispatch_function stmt_info stmt_list n =
|
|
|
|
assert false
|
|
|
|
assert false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* Create declaration statement: qt vname = iexp *)
|
|
|
|
|
|
|
|
let make_DeclStmt stmt_info di qt vname old_vdi iexp =
|
|
|
|
|
|
|
|
let init_expr_opt, init_expr_l =
|
|
|
|
|
|
|
|
match iexp with
|
|
|
|
|
|
|
|
| Some iexp' ->
|
|
|
|
|
|
|
|
let ie = create_implicit_cast_expr stmt_info [iexp'] qt `IntegralCast in
|
|
|
|
|
|
|
|
(Some ie, [ie])
|
|
|
|
|
|
|
|
| None ->
|
|
|
|
|
|
|
|
(None, [])
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let var_decl_info = {old_vdi with Clang_ast_t.vdi_init_expr= init_expr_opt} in
|
|
|
|
|
|
|
|
let di = fresh_decl_info di in
|
|
|
|
|
|
|
|
let var_decl = Clang_ast_t.VarDecl (di, vname, qt, var_decl_info) in
|
|
|
|
|
|
|
|
Clang_ast_t.DeclStmt (stmt_info, init_expr_l, [var_decl])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let build_OpaqueValueExpr si source_expr ei =
|
|
|
|
let build_OpaqueValueExpr si source_expr ei =
|
|
|
|
let opaque_value_expr_info = {Clang_ast_t.ovei_source_expr= Some source_expr} in
|
|
|
|
let opaque_value_expr_info = {Clang_ast_t.ovei_source_expr= Some source_expr} in
|
|
|
|
Clang_ast_t.OpaqueValueExpr (si, [], ei, opaque_value_expr_info)
|
|
|
|
Clang_ast_t.OpaqueValueExpr (si, [], ei, opaque_value_expr_info)
|
|
|
@ -315,331 +250,6 @@ let build_OpaqueValueExpr si source_expr ei =
|
|
|
|
|
|
|
|
|
|
|
|
let pseudo_object_qt = make_objc_class_qual_type CFrontend_config.pseudo_object_type
|
|
|
|
let pseudo_object_qt = make_objc_class_qual_type CFrontend_config.pseudo_object_type
|
|
|
|
|
|
|
|
|
|
|
|
(* Create expression PseudoObjectExpr for 'o.m' *)
|
|
|
|
|
|
|
|
let build_PseudoObjectExpr qt_m o_cast_decl_ref_exp mname =
|
|
|
|
|
|
|
|
match o_cast_decl_ref_exp with
|
|
|
|
|
|
|
|
| Clang_ast_t.ImplicitCastExpr (si, _, ei, _) ->
|
|
|
|
|
|
|
|
let ove = build_OpaqueValueExpr si o_cast_decl_ref_exp ei in
|
|
|
|
|
|
|
|
let ei_opre = make_expr_info pseudo_object_qt in
|
|
|
|
|
|
|
|
let count_name = CAst_utils.make_name_decl CFrontend_config.count in
|
|
|
|
|
|
|
|
let pointer = si.Clang_ast_t.si_pointer in
|
|
|
|
|
|
|
|
let obj_c_property_ref_expr_info =
|
|
|
|
|
|
|
|
{ Clang_ast_t.oprei_kind=
|
|
|
|
|
|
|
|
`PropertyRef (make_decl_ref_no_qt `ObjCProperty pointer count_name false)
|
|
|
|
|
|
|
|
; oprei_is_super_receiver= false
|
|
|
|
|
|
|
|
; oprei_is_messaging_getter= true
|
|
|
|
|
|
|
|
; oprei_is_messaging_setter= false }
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let opre =
|
|
|
|
|
|
|
|
Clang_ast_t.ObjCPropertyRefExpr (si, [ove], ei_opre, obj_c_property_ref_expr_info)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let ome = make_message_expr qt_m mname o_cast_decl_ref_exp si false in
|
|
|
|
|
|
|
|
let poe_ei = make_general_expr_info qt_m `LValue `Ordinary in
|
|
|
|
|
|
|
|
Clang_ast_t.PseudoObjectExpr (si, [opre; ove; ome], poe_ei)
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let create_call stmt_info decl_pointer function_name qt parameters =
|
|
|
|
|
|
|
|
let expr_info_call =
|
|
|
|
|
|
|
|
{ Clang_ast_t.ei_qual_type= create_void_star_type
|
|
|
|
|
|
|
|
; ei_value_kind= `XValue
|
|
|
|
|
|
|
|
; ei_object_kind= `Ordinary }
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let expr_info_dre = make_expr_info_with_objc_kind qt `Ordinary in
|
|
|
|
|
|
|
|
let decl_ref = make_decl_ref_qt `Function decl_pointer function_name false qt in
|
|
|
|
|
|
|
|
let decl_ref_info = make_decl_ref_expr_info decl_ref in
|
|
|
|
|
|
|
|
let decl_ref_exp = Clang_ast_t.DeclRefExpr (stmt_info, [], expr_info_dre, decl_ref_info) in
|
|
|
|
|
|
|
|
let cast =
|
|
|
|
|
|
|
|
create_implicit_cast_expr (fresh_stmt_info stmt_info) [decl_ref_exp] qt `FunctionToPointerDecay
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
Clang_ast_t.CallExpr (stmt_info, cast :: parameters, expr_info_call)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* For a of type NSArray* Translate
|
|
|
|
|
|
|
|
[a enumerateObjectsUsingBlock:^(id object, NSUInteger idx, BOOL * stop) {
|
|
|
|
|
|
|
|
body_block
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
as follows:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
NSArray *objects = a;
|
|
|
|
|
|
|
|
void (^enumerateObjectsUsingBlock)(id, NSUInteger, BOOL* ) =
|
|
|
|
|
|
|
|
^(id object, NSUInteger idx, BOOL* stop) {
|
|
|
|
|
|
|
|
body_block
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
BOOL *stop = malloc(sizeof(BOOL));
|
|
|
|
|
|
|
|
*stop = NO;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (NSUInteger idx=0; idx<objects.count; idx++) {
|
|
|
|
|
|
|
|
id object= objects[idx];
|
|
|
|
|
|
|
|
enumerateObjectsUsingBlock(object, idx, stop);
|
|
|
|
|
|
|
|
if ( *stop ==YES) break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
free(stop);
|
|
|
|
|
|
|
|
*)
|
|
|
|
|
|
|
|
let translate_block_enumerate block_name stmt_info stmt_list ei =
|
|
|
|
|
|
|
|
let rec get_name_pointers lp =
|
|
|
|
|
|
|
|
match lp with
|
|
|
|
|
|
|
|
| [] ->
|
|
|
|
|
|
|
|
[]
|
|
|
|
|
|
|
|
| (Clang_ast_t.ParmVarDecl (di, name, qt, _)) :: lp' ->
|
|
|
|
|
|
|
|
(name.Clang_ast_t.ni_name, di.Clang_ast_t.di_pointer, qt) :: get_name_pointers lp'
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let build_idx_decl pidx =
|
|
|
|
|
|
|
|
match pidx with
|
|
|
|
|
|
|
|
| Clang_ast_t.ParmVarDecl (di_idx, name_idx, qt_idx, vdi) ->
|
|
|
|
|
|
|
|
let zero = create_integer_literal "0" in
|
|
|
|
|
|
|
|
(* qt_idx idx = 0; *)
|
|
|
|
|
|
|
|
let idx_decl_stmt =
|
|
|
|
|
|
|
|
make_DeclStmt (fresh_stmt_info stmt_info) di_idx qt_idx name_idx vdi (Some zero)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let idx_ei = make_expr_info qt_idx in
|
|
|
|
|
|
|
|
let pointer = di_idx.Clang_ast_t.di_pointer in
|
|
|
|
|
|
|
|
let idx_decl_ref = make_decl_ref_qt `Var pointer name_idx false qt_idx in
|
|
|
|
|
|
|
|
let idx_drei = make_decl_ref_expr_info idx_decl_ref in
|
|
|
|
|
|
|
|
let idx_decl_ref_exp = make_decl_ref_exp stmt_info idx_ei idx_drei in
|
|
|
|
|
|
|
|
let idx_cast =
|
|
|
|
|
|
|
|
create_implicit_cast_expr (fresh_stmt_info stmt_info) [idx_decl_ref_exp] qt_idx
|
|
|
|
|
|
|
|
`LValueToRValue
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(idx_decl_stmt, idx_decl_ref_exp, idx_cast, qt_idx)
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let cast_expr decl_ref qt =
|
|
|
|
|
|
|
|
let ei = make_expr_info qt in
|
|
|
|
|
|
|
|
let drei = make_decl_ref_expr_info decl_ref in
|
|
|
|
|
|
|
|
let decl_ref_exp = make_decl_ref_exp (fresh_stmt_info stmt_info) ei drei in
|
|
|
|
|
|
|
|
create_implicit_cast_expr (fresh_stmt_info stmt_info) [decl_ref_exp] qt `LValueToRValue
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* build statement BOOL *stop = malloc(sizeof(BOOL)); *)
|
|
|
|
|
|
|
|
let build_stop pstop =
|
|
|
|
|
|
|
|
match pstop with
|
|
|
|
|
|
|
|
| Clang_ast_t.ParmVarDecl (di, name, qt, vdi) ->
|
|
|
|
|
|
|
|
let qt_fun = create_void_unsigned_long_type in
|
|
|
|
|
|
|
|
let type_opt = Some create_BOOL_type in
|
|
|
|
|
|
|
|
let parameter =
|
|
|
|
|
|
|
|
Clang_ast_t.UnaryExprOrTypeTraitExpr
|
|
|
|
|
|
|
|
( fresh_stmt_info stmt_info
|
|
|
|
|
|
|
|
, []
|
|
|
|
|
|
|
|
, make_general_expr_info create_unsigned_long_type `RValue `Ordinary
|
|
|
|
|
|
|
|
, {Clang_ast_t.uttei_kind= `SizeOfWithSize 1; Clang_ast_t.uttei_qual_type= type_opt} )
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let pointer = di.Clang_ast_t.di_pointer in
|
|
|
|
|
|
|
|
let stmt_info = fresh_stmt_info stmt_info in
|
|
|
|
|
|
|
|
let malloc_name = CAst_utils.make_name_decl CFrontend_config.malloc in
|
|
|
|
|
|
|
|
let malloc = create_call stmt_info pointer malloc_name qt_fun [parameter] in
|
|
|
|
|
|
|
|
let init_exp =
|
|
|
|
|
|
|
|
create_implicit_cast_expr (fresh_stmt_info stmt_info) [malloc] qt `BitCast
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
make_DeclStmt (fresh_stmt_info stmt_info) di qt name vdi (Some init_exp)
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* BOOL *stop =NO; *)
|
|
|
|
|
|
|
|
let stop_equal_no pstop =
|
|
|
|
|
|
|
|
match pstop with
|
|
|
|
|
|
|
|
| Clang_ast_t.ParmVarDecl (di, name, qt, _) ->
|
|
|
|
|
|
|
|
let decl_ref = make_decl_ref_qt `Var di.Clang_ast_t.di_pointer name false qt in
|
|
|
|
|
|
|
|
let cast = cast_expr decl_ref qt in
|
|
|
|
|
|
|
|
let postfix_deref = {Clang_ast_t.uoi_kind= `Deref; uoi_is_postfix= true} in
|
|
|
|
|
|
|
|
let lhs =
|
|
|
|
|
|
|
|
Clang_ast_t.UnaryOperator (fresh_stmt_info stmt_info, [cast], ei, postfix_deref)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let bool_NO = make_ObjCBoolLiteralExpr stmt_info 0 in
|
|
|
|
|
|
|
|
let assign = {Clang_ast_t.boi_kind= `Assign} in
|
|
|
|
|
|
|
|
Clang_ast_t.BinaryOperator (fresh_stmt_info stmt_info, [lhs; bool_NO], ei, assign)
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* build statement free(stop); *)
|
|
|
|
|
|
|
|
let free_stop pstop =
|
|
|
|
|
|
|
|
match pstop with
|
|
|
|
|
|
|
|
| Clang_ast_t.ParmVarDecl (di, name, qt, _) ->
|
|
|
|
|
|
|
|
let qt_fun = create_void_void_type in
|
|
|
|
|
|
|
|
let decl_ref = make_decl_ref_qt `Var di.Clang_ast_t.di_pointer name false qt in
|
|
|
|
|
|
|
|
let cast = cast_expr decl_ref qt in
|
|
|
|
|
|
|
|
let free_name = CAst_utils.make_name_decl CFrontend_config.free in
|
|
|
|
|
|
|
|
let parameter =
|
|
|
|
|
|
|
|
create_implicit_cast_expr (fresh_stmt_info stmt_info) [cast] create_void_star_type
|
|
|
|
|
|
|
|
`BitCast
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let pointer = di.Clang_ast_t.di_pointer in
|
|
|
|
|
|
|
|
create_call (fresh_stmt_info stmt_info) pointer free_name qt_fun [parameter]
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* idx<a.count *)
|
|
|
|
|
|
|
|
let bin_op pidx array_decl_ref_exp =
|
|
|
|
|
|
|
|
let _, _, idx_cast, idx_qt = build_idx_decl pidx in
|
|
|
|
|
|
|
|
let rhs = build_PseudoObjectExpr idx_qt array_decl_ref_exp CFrontend_config.count in
|
|
|
|
|
|
|
|
let lt = {Clang_ast_t.boi_kind= `LT} in
|
|
|
|
|
|
|
|
let exp_info = make_expr_info create_int_type in
|
|
|
|
|
|
|
|
Clang_ast_t.BinaryOperator (fresh_stmt_info stmt_info, [idx_cast; rhs], exp_info, lt)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* idx++ *)
|
|
|
|
|
|
|
|
let un_op idx_decl_ref_expr qt_idx =
|
|
|
|
|
|
|
|
let idx_ei = make_expr_info qt_idx in
|
|
|
|
|
|
|
|
let postinc = {Clang_ast_t.uoi_kind= `PostInc; uoi_is_postfix= true} in
|
|
|
|
|
|
|
|
Clang_ast_t.UnaryOperator (fresh_stmt_info stmt_info, [idx_decl_ref_expr], idx_ei, postinc)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let get_ei_from_cast cast =
|
|
|
|
|
|
|
|
match cast with Clang_ast_t.ImplicitCastExpr (_, _, ei, _) -> ei | _ -> assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* id object = objects[idx]; *)
|
|
|
|
|
|
|
|
let build_object_DeclStmt pobj decl_ref_expr_array decl_ref_expr_idx =
|
|
|
|
|
|
|
|
let open Clang_ast_t in
|
|
|
|
|
|
|
|
match pobj with
|
|
|
|
|
|
|
|
| ParmVarDecl (di_obj, name_obj, qt_obj, _) ->
|
|
|
|
|
|
|
|
let poe_ei = make_general_expr_info qt_obj `RValue `Ordinary in
|
|
|
|
|
|
|
|
let ei_array = get_ei_from_cast decl_ref_expr_array in
|
|
|
|
|
|
|
|
let ove_array =
|
|
|
|
|
|
|
|
build_OpaqueValueExpr (fresh_stmt_info stmt_info) decl_ref_expr_array ei_array
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let ei_idx = get_ei_from_cast decl_ref_expr_idx in
|
|
|
|
|
|
|
|
let ove_idx = build_OpaqueValueExpr (fresh_stmt_info stmt_info) decl_ref_expr_idx ei_idx in
|
|
|
|
|
|
|
|
let objc_sre =
|
|
|
|
|
|
|
|
ObjCSubscriptRefExpr
|
|
|
|
|
|
|
|
( fresh_stmt_info stmt_info
|
|
|
|
|
|
|
|
, [ove_array; ove_idx]
|
|
|
|
|
|
|
|
, make_expr_info pseudo_object_qt
|
|
|
|
|
|
|
|
, {osrei_kind= `ArraySubscript; osrei_getter= None; osrei_setter= None} )
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let obj_c_message_expr_info =
|
|
|
|
|
|
|
|
make_obj_c_message_expr_info_instance CFrontend_config.object_at_indexed_subscript_m
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let ome =
|
|
|
|
|
|
|
|
ObjCMessageExpr
|
|
|
|
|
|
|
|
(fresh_stmt_info stmt_info, [ove_array; ove_idx], poe_ei, obj_c_message_expr_info)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let pseudo_obj_expr =
|
|
|
|
|
|
|
|
PseudoObjectExpr (fresh_stmt_info stmt_info, [objc_sre; ove_array; ove_idx; ome], poe_ei)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let vdi = {empty_var_decl_info with vdi_init_expr= Some pseudo_obj_expr} in
|
|
|
|
|
|
|
|
let var_decl = VarDecl (di_obj, name_obj, qt_obj, vdi) in
|
|
|
|
|
|
|
|
DeclStmt (fresh_stmt_info stmt_info, [pseudo_obj_expr], [var_decl])
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* NSArray *objects = a *)
|
|
|
|
|
|
|
|
let objects_array_DeclStmt init =
|
|
|
|
|
|
|
|
let di = {empty_decl_info with Clang_ast_t.di_pointer= CAst_utils.get_fresh_pointer ()} in
|
|
|
|
|
|
|
|
let qt = create_pointer_qual_type (make_objc_class_qual_type CFrontend_config.nsarray_cl) in
|
|
|
|
|
|
|
|
(* init should be ImplicitCastExpr of array a *)
|
|
|
|
|
|
|
|
let vdi = {empty_var_decl_info with Clang_ast_t.vdi_init_expr= Some init} in
|
|
|
|
|
|
|
|
let objects_name = CAst_utils.make_name_decl CFrontend_config.objects in
|
|
|
|
|
|
|
|
let var_decl = Clang_ast_t.VarDecl (di, objects_name, qt, vdi) in
|
|
|
|
|
|
|
|
( Clang_ast_t.DeclStmt (fresh_stmt_info stmt_info, [init], [var_decl])
|
|
|
|
|
|
|
|
, [(CFrontend_config.objects, di.Clang_ast_t.di_pointer, qt)] )
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let make_object_cast_decl_ref_expr objects =
|
|
|
|
|
|
|
|
match objects with
|
|
|
|
|
|
|
|
| Clang_ast_t.DeclStmt (si, _, [(Clang_ast_t.VarDecl (_, name, qt, _))]) ->
|
|
|
|
|
|
|
|
let decl_ref = make_decl_ref_qt `Var si.Clang_ast_t.si_pointer name false qt in
|
|
|
|
|
|
|
|
cast_expr decl_ref qt
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let build_cast_decl_ref_expr_from_parm p =
|
|
|
|
|
|
|
|
match p with
|
|
|
|
|
|
|
|
| Clang_ast_t.ParmVarDecl (di, name, qt, _) ->
|
|
|
|
|
|
|
|
let decl_ref = make_decl_ref_qt `Var di.Clang_ast_t.di_pointer name false qt in
|
|
|
|
|
|
|
|
cast_expr decl_ref qt
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let qual_block_name = CAst_utils.make_name_decl block_name in
|
|
|
|
|
|
|
|
let make_block_decl be =
|
|
|
|
|
|
|
|
match be with
|
|
|
|
|
|
|
|
| Clang_ast_t.BlockExpr (bsi, _, bei, _) ->
|
|
|
|
|
|
|
|
let di = {empty_decl_info with di_pointer= CAst_utils.get_fresh_pointer ()} in
|
|
|
|
|
|
|
|
let vdi = {empty_var_decl_info with Clang_ast_t.vdi_init_expr= Some be} in
|
|
|
|
|
|
|
|
let qt = bei.Clang_ast_t.ei_qual_type in
|
|
|
|
|
|
|
|
let var_decl = Clang_ast_t.VarDecl (di, qual_block_name, qt, vdi) in
|
|
|
|
|
|
|
|
( Clang_ast_t.DeclStmt (bsi, [be], [var_decl])
|
|
|
|
|
|
|
|
, [(block_name, di.Clang_ast_t.di_pointer, qt)] )
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
assert false
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let make_block_call block_qt object_cast idx_cast stop_cast =
|
|
|
|
|
|
|
|
let decl_ref = make_decl_ref_invalid `Var qual_block_name false block_qt in
|
|
|
|
|
|
|
|
let fun_cast = cast_expr decl_ref block_qt in
|
|
|
|
|
|
|
|
let ei_call = make_expr_info create_void_star_type in
|
|
|
|
|
|
|
|
Clang_ast_t.CallExpr
|
|
|
|
|
|
|
|
(fresh_stmt_info stmt_info, [fun_cast; object_cast; idx_cast; stop_cast], ei_call)
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
(* build statement "if (stop) break;" *)
|
|
|
|
|
|
|
|
let build_if_stop stop_cast =
|
|
|
|
|
|
|
|
let bool_qt = create_BOOL_type in
|
|
|
|
|
|
|
|
let ei = make_expr_info bool_qt in
|
|
|
|
|
|
|
|
let unary_op =
|
|
|
|
|
|
|
|
Clang_ast_t.UnaryOperator
|
|
|
|
|
|
|
|
( fresh_stmt_info stmt_info
|
|
|
|
|
|
|
|
, [stop_cast]
|
|
|
|
|
|
|
|
, ei
|
|
|
|
|
|
|
|
, {Clang_ast_t.uoi_kind= `Deref; uoi_is_postfix= true} )
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let cond =
|
|
|
|
|
|
|
|
create_implicit_cast_expr (fresh_stmt_info stmt_info) [unary_op] bool_qt `LValueToRValue
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let break_stmt = Clang_ast_t.BreakStmt (fresh_stmt_info stmt_info, []) in
|
|
|
|
|
|
|
|
Clang_ast_t.IfStmt
|
|
|
|
|
|
|
|
(fresh_stmt_info stmt_info, [dummy_stmt (); dummy_stmt (); cond; break_stmt; dummy_stmt ()])
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let translate params array_cast_decl_ref_exp block_decl block_qt =
|
|
|
|
|
|
|
|
match params with
|
|
|
|
|
|
|
|
| [pobj; pidx; pstop] ->
|
|
|
|
|
|
|
|
let objects_decl, op = objects_array_DeclStmt array_cast_decl_ref_exp in
|
|
|
|
|
|
|
|
let decl_stop = build_stop pstop in
|
|
|
|
|
|
|
|
let assign_stop = stop_equal_no pstop in
|
|
|
|
|
|
|
|
let objects = make_object_cast_decl_ref_expr objects_decl in
|
|
|
|
|
|
|
|
let idx_decl_stmt, idx_decl_ref_exp, idx_cast, qt_idx = build_idx_decl pidx in
|
|
|
|
|
|
|
|
let guard = bin_op pidx objects in
|
|
|
|
|
|
|
|
let incr = un_op idx_decl_ref_exp qt_idx in
|
|
|
|
|
|
|
|
let obj_assignment = build_object_DeclStmt pobj objects idx_cast in
|
|
|
|
|
|
|
|
let object_cast = build_cast_decl_ref_expr_from_parm pobj in
|
|
|
|
|
|
|
|
let stop_cast = build_cast_decl_ref_expr_from_parm pstop in
|
|
|
|
|
|
|
|
let call_block = make_block_call block_qt object_cast idx_cast stop_cast in
|
|
|
|
|
|
|
|
let if_stop = build_if_stop stop_cast in
|
|
|
|
|
|
|
|
let free_stop = free_stop pstop in
|
|
|
|
|
|
|
|
( [ objects_decl
|
|
|
|
|
|
|
|
; block_decl
|
|
|
|
|
|
|
|
; decl_stop
|
|
|
|
|
|
|
|
; assign_stop
|
|
|
|
|
|
|
|
; Clang_ast_t.ForStmt
|
|
|
|
|
|
|
|
( stmt_info
|
|
|
|
|
|
|
|
, [ idx_decl_stmt
|
|
|
|
|
|
|
|
; dummy_stmt ()
|
|
|
|
|
|
|
|
; guard
|
|
|
|
|
|
|
|
; incr
|
|
|
|
|
|
|
|
; Clang_ast_t.CompoundStmt (stmt_info, [obj_assignment; call_block; if_stop]) ] )
|
|
|
|
|
|
|
|
; free_stop ]
|
|
|
|
|
|
|
|
, op )
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
(* FIXME(t21762295) this is reachable *)
|
|
|
|
|
|
|
|
CFrontend_config.incorrect_assumption "wrong params in block enumerate translation: %a"
|
|
|
|
|
|
|
|
(Pp.seq (Pp.to_string ~f:Clang_ast_j.string_of_decl))
|
|
|
|
|
|
|
|
params
|
|
|
|
|
|
|
|
in
|
|
|
|
|
|
|
|
let open Clang_ast_t in
|
|
|
|
|
|
|
|
match stmt_list with
|
|
|
|
|
|
|
|
| [s; (BlockExpr (_, _, bei, BlockDecl (_, bdi)) as be)] ->
|
|
|
|
|
|
|
|
let block_decl, bv = make_block_decl be in
|
|
|
|
|
|
|
|
let vars_to_register = get_name_pointers bdi.bdi_parameters in
|
|
|
|
|
|
|
|
let translated_stmt, op = translate bdi.bdi_parameters s block_decl bei.ei_qual_type in
|
|
|
|
|
|
|
|
(CompoundStmt (stmt_info, translated_stmt), vars_to_register @ op @ bv)
|
|
|
|
|
|
|
|
| _ ->
|
|
|
|
|
|
|
|
(* When it is not the method we expect with only one parameter, we don't translate *)
|
|
|
|
|
|
|
|
L.(debug Capture Verbose)
|
|
|
|
|
|
|
|
"WARNING: Block Enumeration called at %s not translated."
|
|
|
|
|
|
|
|
(Clang_ast_j.string_of_stmt_info stmt_info) ;
|
|
|
|
|
|
|
|
(CompoundStmt (stmt_info, stmt_list), [])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
(* We translate an expression with a conditional*)
|
|
|
|
(* We translate an expression with a conditional*)
|
|
|
|
(* x <=> x?1:0 *)
|
|
|
|
(* x <=> x?1:0 *)
|
|
|
|
let trans_with_conditional stmt_info expr_info stmt_list =
|
|
|
|
let trans_with_conditional stmt_info expr_info stmt_list =
|
|
|
@ -652,4 +262,3 @@ let trans_with_conditional stmt_info expr_info stmt_list =
|
|
|
|
let trans_negation_with_conditional stmt_info expr_info stmt_list =
|
|
|
|
let trans_negation_with_conditional stmt_info expr_info stmt_list =
|
|
|
|
let stmt_list_cond = stmt_list @ [create_integer_literal "0"] @ [create_integer_literal "1"] in
|
|
|
|
let stmt_list_cond = stmt_list @ [create_integer_literal "0"] @ [create_integer_literal "1"] in
|
|
|
|
Clang_ast_t.ConditionalOperator (stmt_info, stmt_list_cond, expr_info)
|
|
|
|
Clang_ast_t.ConditionalOperator (stmt_info, stmt_list_cond, expr_info)
|
|
|
|
|
|
|
|
|
|
|
|