@ -17,53 +17,64 @@ let get_load_self_instr location (self, self_typ) fieldname =
( field_exp , load_self_instr )
( field_exp , load_self_instr )
let objc_getter proc_desc location self_with_typ ( fieldname , field_typ , _ ) =
let objc_getter tenv proc_desc location self_with_typ ( fieldname , field_typ , _ ) =
let field_exp , load_self_instr = get_load_self_instr location self_with_typ fieldname in
let field_exp , load_self_instr = get_load_self_instr location self_with_typ fieldname in
let id_field = Ident . create_fresh Ident . knormal in
let store_instrs =
let store_instrs =
let id_field = Ident . create_fresh Ident . knormal in
match field_typ with
let load_field_instr =
| { Typ . desc = Tstruct ( CStruct _ as struct_name ) } ->
Sil . Load { id = id_field ; e = field_exp ; root_typ = field_typ ; typ = field_typ ; loc = location }
let ret_param = Exp . Lvar ( Pvar . get_ret_param_pvar ( Procdesc . get_proc_name proc_desc ) ) in
in
Sil . Load { id = id_field ; e = ret_param ; root_typ = field_typ ; typ = field_typ ; loc = location }
let exp_var = Exp . Lvar ( Procdesc . get_ret_var proc_desc ) in
:: CStructCopy . struct_copy tenv location ( Exp . Var id_field ) field_exp ~ typ : field_typ
let return_exp =
~ struct_name
Sil . Store
| _ ->
{ e1 = exp_var ; root_typ = field_typ ; typ = field_typ ; e2 = Exp . Var id_field ; loc = location }
let load_field_instr =
in
Sil . Load { id = id_field ; e = field_exp ; root_typ = field_typ ; typ = field_typ ; loc = location }
[ load_field_instr ; return_exp ]
in
let exp_var = Exp . Lvar ( Procdesc . get_ret_var proc_desc ) in
let return_exp =
Sil . Store
{ e1 = exp_var ; root_typ = field_typ ; typ = field_typ ; e2 = Exp . Var id_field ; loc = location }
in
[ load_field_instr ; return_exp ]
in
in
load_self_instr :: store_instrs
load_self_instr :: store_instrs
let objc_setter location self_with_typ ( var , var_typ ) ( fieldname , field_typ , _ ) =
let objc_setter tenv location self_with_typ ( var , var_typ ) ( fieldname , field_typ , _ ) =
let field_exp , load_self_instr = get_load_self_instr location self_with_typ fieldname in
let field_exp , load_self_instr = get_load_self_instr location self_with_typ fieldname in
let store_instrs =
let store_instrs =
let id_field = Ident . create_fresh Ident . knormal in
match field_typ with
let load_var_instr =
| { Typ . desc = Tstruct ( CStruct _ as struct_name ) } ->
Sil . Load { id = id_field ; e = Lvar var ; root_typ = var_typ ; typ = var_typ ; loc = location }
CStructCopy . struct_copy tenv location field_exp ( Exp . Lvar var ) ~ typ : field_typ ~ struct_name
in
| _ ->
let store_exp =
let id_field = Ident . create_fresh Ident . knormal in
Sil . Store
let load_var_instr =
{ e1 = field_exp ; root_typ = field_typ ; typ = field_typ ; e2 = Exp . Var id_field ; loc = location }
Sil . Load { id = id_field ; e = Lvar var ; root_typ = var_typ ; typ = var_typ ; loc = location }
in
in
[ load_var_instr ; store_exp ]
let store_exp =
Sil . Store
{ e1 = field_exp ; root_typ = field_typ ; typ = field_typ ; e2 = Exp . Var id_field ; loc = location }
in
[ load_var_instr ; store_exp ]
in
in
load_self_instr :: store_instrs
load_self_instr :: store_instrs
let process_getter_setter proc_name proc_desc =
let process_getter_setter tenv proc_name proc_desc =
let location = Procdesc . get_loc proc_desc in
let location = Procdesc . get_loc proc_desc in
let formals = Procdesc . get_formals proc_desc in
let formals = Procdesc . get_formals proc_desc in
let attributes = Procdesc . get_attributes proc_desc in
let attributes = Procdesc . get_attributes proc_desc in
Ident . NameGenerator . reset () ;
Ident . NameGenerator . reset () ;
let getter_setter_instrs =
let getter_setter_instrs =
match ( attributes . ProcAttributes . objc_accessor , formals ) with
match ( attributes . ProcAttributes . objc_accessor , formals ) with
| Some ( Objc_getter field ) , [ (self , self_typ ) ] ->
| Some ( Objc_getter field ) , (self , self_typ ) :: _ ->
let self_var = Pvar . mk self proc_name in
let self_var = Pvar . mk self proc_name in
objc_getter proc_desc location ( self_var , self_typ ) field
objc_getter tenv proc_desc location ( self_var , self_typ ) field
| Some ( Objc_setter field ) , [ ( self , self_typ ) ; ( var_name , var_typ ) ] ->
| Some ( Objc_setter field ) , [ ( self , self_typ ) ; ( var_name , var_typ ) ] ->
let self_var = Pvar . mk self proc_name in
let self_var = Pvar . mk self proc_name in
let var = Pvar . mk var_name proc_name in
let var = Pvar . mk var_name proc_name in
objc_setter location ( self_var , self_typ ) ( var , var_typ ) field
objc_setter tenv location ( self_var , self_typ ) ( var , var_typ ) field
| _ ->
| _ ->
[]
[]
in
in
@ -83,4 +94,4 @@ let process_getter_setter proc_name proc_desc =
Procdesc . node_set_succs proc_desc getter_setter_node ~ normal : [ exit_node ] ~ exn : [] )
Procdesc . node_set_succs proc_desc getter_setter_node ~ normal : [ exit_node ] ~ exn : [] )
let process cfg = Procname . Hash . iter process_getter_setter cfg
let process cfg tenv = Procname . Hash . iter ( process_getter_setter tenv ) cfg