@ -52,6 +52,37 @@ let get_protocols protocols =
) protocols in
) protocols in
protocol_names
protocol_names
let get_curr_class class_name ocdi =
let super = get_super_interface_decl ocdi . Clang_ast_t . otdi_super in
let protocols = get_protocols ocdi . Clang_ast_t . otdi_protocols in
CContext . ContextCls ( class_name , super , protocols )
let get_curr_class_impl oi =
let open Clang_ast_t in
match oi . Clang_ast_t . oidi_class_interface with
| Some decl_ref ->
( match Ast_utils . get_decl decl_ref . Clang_ast_t . dr_decl_pointer with
| Some ObjCInterfaceDecl ( _ , name_info , _ , _ , obj_c_interface_decl_info ) ->
let class_name = name_info . Clang_ast_t . ni_name in
get_curr_class class_name obj_c_interface_decl_info
| _ -> assert false )
| _ -> assert false
let add_class_decl type_ptr_to_sil_type tenv idi =
let decl_ref_opt = idi . Clang_ast_t . oidi_class_interface in
Ast_utils . add_type_from_decl_ref type_ptr_to_sil_type tenv decl_ref_opt true
let add_super_class_decl type_ptr_to_sil_type tenv ocdi =
let decl_ref_opt = ocdi . Clang_ast_t . otdi_super in
Ast_utils . add_type_from_decl_ref type_ptr_to_sil_type tenv decl_ref_opt false
let add_protocols_decl type_ptr_to_sil_type tenv protocols =
Ast_utils . add_type_from_decl_ref_list type_ptr_to_sil_type tenv protocols
let add_class_implementation type_ptr_to_sil_type tenv idi =
let decl_ref_opt = idi . Clang_ast_t . otdi_implementation in
Ast_utils . add_type_from_decl_ref type_ptr_to_sil_type tenv decl_ref_opt false
(* The superclass is the first element in the list of super classes of structs in the tenv, *)
(* The superclass is the first element in the list of super classes of structs in the tenv, *)
(* then come the protocols and categories. *)
(* then come the protocols and categories. *)
let get_interface_superclasses super_opt protocols =
let get_interface_superclasses super_opt protocols =
@ -65,40 +96,26 @@ let get_interface_superclasses super_opt protocols =
let super_classes = super_class @ protocol_names in
let super_classes = super_class @ protocol_names in
super_classes
super_classes
let create_curr_class_and_superclasses_fields tenv decl_list class_name otdi_super otdi_protocols =
let create_superclasses_fields type_ptr_to_sil_type tenv curr_class decl_list class_name
otdi_super otdi_protocols =
let super = get_super_interface_decl otdi_super in
let super = get_super_interface_decl otdi_super in
let protocols = get_protocols otdi_protocols in
let protocols = get_protocols otdi_protocols in
let curr_class = CContext . ContextCls ( class_name , super , protocols ) in
let superclasses = get_interface_superclasses super protocols in
let superclasses = get_interface_superclasses super protocols in
let fields = CField_decl . get_fields tenv curr_class decl_list in
let fields = CField_decl . get_fields type_ptr_to_sil_type tenv curr_class decl_list in
curr_class , superclasses , fields
superclasses , fields
let update_curr_class curr_class superclasses =
let get_protocols protocols = IList . fold_right (
fun protocol converted_protocols ->
match protocol with
| ( Sil . Protocol , name ) -> ( Mangled . to_string name ) :: converted_protocols
| _ -> converted_protocols
) protocols [] in
match curr_class with
| CContext . ContextCls ( class_name , _ , _ ) ->
let super , protocols =
match superclasses with
| ( Sil . Class , name ) :: rest -> Some ( Mangled . to_string name ) , get_protocols rest
| _ -> None , get_protocols superclasses in
CContext . ContextCls ( class_name , super , protocols )
| _ -> assert false
(* Adds pairs ( interface name, interface_type_info ) to the global environment. *)
(* Adds pairs ( interface name, interface_type_info ) to the global environment. *)
let add_class_to_tenv t env decl_info class_name decl_list o bj_ c_ interface_ decl_ info =
let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name decl_list ocidi =
Printing . log_out " ADDING: ObjCInterfaceDecl for '%s' \n " class_name ;
Printing . log_out " ADDING: ObjCInterfaceDecl for '%s' \n " class_name ;
let interface_name = CTypes . mk_classname class_name in
let interface_name = CTypes . mk_classname class_name in
let curr_class , superclasses , fields =
let decl_key = ` DeclPtr decl_info . Clang_ast_t . di_pointer in
create_curr_class_and_superclasses_fields tenv decl_list class_name
Ast_utils . update_sil_types_map decl_key ( Sil . Tvar interface_name ) ;
obj_c_interface_decl_info . Clang_ast_t . otdi_super
let superclasses , fields =
obj_c_interface_decl_info . Clang_ast_t . otdi_protocols in
create_superclasses_fields type_ptr_to_sil_type tenv curr_class decl_list class_name
ocidi . Clang_ast_t . otdi_super
ocidi . Clang_ast_t . otdi_protocols in
let methods = ObjcProperty_decl . get_methods curr_class decl_list in
let methods = ObjcProperty_decl . get_methods curr_class decl_list in
let fields_sc = CField_decl . fields_superclass tenv obj_c_interface_decl_info in
let fields_sc = CField_decl . fields_superclass tenv ocidi in
IList . iter ( fun ( fn , ft , _ ) ->
IList . iter ( fun ( fn , ft , _ ) ->
Printing . log_out " ----->SuperClass field: '%s' " ( Ident . fieldname_to_string fn ) ;
Printing . log_out " ----->SuperClass field: '%s' " ( Ident . fieldname_to_string fn ) ;
Printing . log_out " type: '%s' \n " ( Sil . typ_to_string ft ) ) fields_sc ;
Printing . log_out " type: '%s' \n " ( Sil . typ_to_string ft ) ) fields_sc ;
@ -121,34 +138,52 @@ let add_class_to_tenv tenv decl_info class_name decl_list obj_c_interface_decl_i
Sil . Tstruct ( fields , [] , Sil . Class , Some ( Mangled . from_string class_name ) ,
Sil . Tstruct ( fields , [] , Sil . Class , Some ( Mangled . from_string class_name ) ,
superclasses , methods , objc_class_annotation ) in
superclasses , methods , objc_class_annotation ) in
Sil . tenv_add tenv interface_name interface_type_info ;
Sil . tenv_add tenv interface_name interface_type_info ;
let decl_key = ` DeclPtr decl_info . Clang_ast_t . di_pointer in
Ast_utils . update_sil_types_map decl_key ( Sil . Tvar interface_name ) ;
Printing . log_out
Printing . log_out
" >>>Verifying that Typename '%s' is in tenv \n " ( Sil . typename_to_string interface_name ) ;
" >>>Verifying that Typename '%s' is in tenv \n " ( Sil . typename_to_string interface_name ) ;
( match Sil . tenv_lookup tenv interface_name with
( match Sil . tenv_lookup tenv interface_name with
| Some t -> Printing . log_out " >>>OK. Found typ='%s' \n " ( Sil . typ_to_string t )
| Some t -> Printing . log_out " >>>OK. Found typ='%s' \n " ( Sil . typ_to_string t )
| None -> Printing . log_out " >>>NOT Found!! \n " ) ;
| None -> Printing . log_out " >>>NOT Found!! \n " ) ;
curr_class
Sil . Tvar interface_name
let add_missing_methods tenv class_name decl_ list curr_class =
let add_missing_methods tenv class_name decl_ info decl_ list curr_class =
let methods = ObjcProperty_decl . get_methods curr_class decl_list in
let methods = ObjcProperty_decl . get_methods curr_class decl_list in
let class_tn_name = Sil . TN_csu ( Sil . Class , ( Mangled . from_string class_name ) ) in
let class_tn_name = Sil . TN_csu ( Sil . Class , ( Mangled . from_string class_name ) ) in
match Sil . tenv_lookup tenv class_tn_name with
let decl_key = ` DeclPtr decl_info . Clang_ast_t . di_pointer in
| Some Sil . Tstruct ( fields , [] , Sil . Class , Some name , superclass , existing_methods , annotation ) ->
Ast_utils . update_sil_types_map decl_key ( Sil . Tvar class_tn_name ) ;
let methods = General_utils . append_no_duplicates_methods existing_methods methods in
( match Sil . tenv_lookup tenv class_tn_name with
let typ = Sil . Tstruct ( fields , [] , Sil . Class , Some name , superclass , methods , annotation ) in
| Some Sil . Tstruct ( fields , [] , Sil . Class , Some name , superclass , existing_methods , annotation ) ->
Sil . tenv_add tenv class_tn_name typ
let methods = General_utils . append_no_duplicates_methods existing_methods methods in
| _ -> ()
let typ = Sil . Tstruct ( fields , [] , Sil . Class , Some name , superclass , methods , annotation ) in
Sil . tenv_add tenv class_tn_name typ
| _ -> () ) ;
Sil . Tvar class_tn_name
(* Interface_type_info has the name of instance variables and the name of methods. *)
(* Interface_type_info has the name of instance variables and the name of methods. *)
let interface_declaration tenv decl_info class_name decl_list obj_c_interface_decl_info =
let interface_declaration type_ptr_to_sil_type tenv decl =
add_class_to_tenv tenv decl_info class_name decl_list obj_c_interface_decl_info
let open Clang_ast_t in
match decl with
| ObjCInterfaceDecl ( decl_info , name_info , decl_list , _ , ocidi ) ->
let name = name_info . Clang_ast_t . ni_name in
let curr_class = get_curr_class name ocidi in
let typ =
add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info name decl_list ocidi in
let _ = add_class_implementation type_ptr_to_sil_type tenv ocidi in
let _ = add_super_class_decl type_ptr_to_sil_type tenv ocidi in
let _ = add_protocols_decl type_ptr_to_sil_type tenv ocidi . Clang_ast_t . otdi_protocols in
typ
| _ -> assert false
(* Translate the methods defined in the implementation. *)
(* Translate the methods defined in the implementation. *)
let interface_impl_declaration tenv class_name decl_list idi =
let interface_impl_declaration type_ptr_to_sil_type tenv decl =
Printing . log_out " ADDING: ObjCImplementationDecl for class '%s' \n " class_name ;
let open Clang_ast_t in
let curr_class = CContext . create_curr_class tenv class_name in
match decl with
let fields = CField_decl . get_fields tenv curr_class decl_list in
| ObjCImplementationDecl ( decl_info , name_info , decl_list , decl_context_info , idi ) ->
CField_decl . add_missing_fields tenv class_name fields ;
let class_name = name_info . Clang_ast_t . ni_name in
add_missing_methods tenv class_name decl_list curr_class ;
Printing . log_out " ADDING: ObjCImplementationDecl for class '%s' \n " class_name ;
curr_class
let _ = add_class_decl type_ptr_to_sil_type tenv idi in
let curr_class = get_curr_class_impl idi in
let fields = CField_decl . get_fields type_ptr_to_sil_type tenv curr_class decl_list in
CField_decl . add_missing_fields tenv class_name fields ;
let typ = add_missing_methods tenv class_name decl_info decl_list curr_class in
typ
| _ -> assert false