Getting a more precise type when creating ObjC objects

Reviewed By: ddino

Differential Revision: D3282402

fbshipit-source-id: 4a57c9c
master
Dulma Churchill 9 years ago committed by Facebook Github Bot 5
parent c92bbf362b
commit d73d4ea177

@ -49,3 +49,25 @@ let store_attributes proc_attributes =
let load_attributes proc_name =
let attributes_file = res_dir_attr_filename proc_name in
Serialization.from_file serializer attributes_file
(** Given a procdesure name, find the file where it is defined and *)
(** its corresponding type environment *)
let find_tenv_from_class_of_proc procname =
match load_attributes procname with
| None -> None
| Some attrs ->
let source_file = attrs.ProcAttributes.loc.Location.file in
let source_dir = DB.source_dir_from_source_file source_file in
let tenv_fname = DB.source_dir_get_internal_file source_dir ".tenv" in
Tenv.load_from_file tenv_fname
(** Given an ObjC class c, extract the type from the tenv where the class was *)
(** defined. We do this by adding a method that is unique to each class, and then *)
(** finding the tenv that corresponds to the class definition. *)
let get_correct_type_from_objc_class_name c =
let class_method = Procname.get_default_objc_class_method (Mangled.to_string c) in
match find_tenv_from_class_of_proc class_method with
| None -> None
| Some tenv ->
let type_name = Typename.TN_csu (Csu.Class Csu.Objc, c) in
Option.map (fun st -> Sil.Tstruct st) (Tenv.lookup tenv type_name)

@ -17,3 +17,12 @@ val store_attributes : ProcAttributes.t -> unit
(** Load the attributes for the procedure from the attributes database. *)
val load_attributes : Procname.t -> ProcAttributes.t option
(** Given a procdesure name, find the file where it is defined and *)
(** its corresponding type environment *)
val find_tenv_from_class_of_proc : Procname.t -> Tenv.t option
(** Given an ObjC class c, extract the type from the tenv where the class was *)
(** defined. We do this by adding a method that is unique to each class, and then *)
(** finding the tenv that corresponds to the class definition. *)
val get_correct_type_from_objc_class_name : Mangled.t -> Sil.typ option

@ -182,6 +182,10 @@ let objc_cpp class_name method_name mangled =
mangled = mangled;
}
let get_default_objc_class_method objc_class =
let objc_cpp = objc_cpp objc_class "__find_class_" (Some "internal") in
ObjC_Cpp objc_cpp
(** Create an objc procedure name from a class_name and method_name. *)
let mangled_objc_block name =
Block name

@ -108,6 +108,8 @@ val mangled_of_objc_method_kind : objc_method_kind -> string option
(** Create an objc procedure name from a class_name and method_name. *)
val objc_cpp : string -> string -> string option -> objc_cpp
val get_default_objc_class_method : string -> t
(** Get the class name of a Objective-C/C++ procedure name. *)
val objc_cpp_get_class_name : objc_cpp -> string

@ -770,6 +770,13 @@ let execute_alloc mk can_return_null
let handle_sizeof_exp size_exp =
Sil.Sizeof (Sil.Tarray (Sil.Tint Sil.IChar, size_exp), Sil.Subtype.exact) in
let size_exp, procname = match args with
| [(Sil.Sizeof (Sil.Tstruct
{ Sil.csu = Csu.Class Csu.Objc; struct_name = Some c } as s, subt), _)] ->
let struct_type =
match AttributesTable.get_correct_type_from_objc_class_name c with
| Some struct_type -> struct_type
| None -> s in
Sil.Sizeof (struct_type, subt), pname
| [(size_exp, _)] -> (* for malloc and __new *)
size_exp, Sil.mem_alloc_pname mk
| [(size_exp, _); (Sil.Const (Sil.Cfun pname), _)] ->

@ -166,10 +166,12 @@ struct
ignore (ObjcCategory_decl.category_impl_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
process_methods tenv cg cfg curr_class decl_list;
| ObjCImplementationDecl(_, _, decl_list, _, idi) ->
| ObjCImplementationDecl(decl_info, _, decl_list, _, idi) ->
let curr_class = ObjcInterface_decl.get_curr_class_impl idi in
let class_name = CContext.get_curr_class_name curr_class in
let type_ptr_to_sil_type = CTypes_decl.type_ptr_to_sil_type in
ignore (ObjcInterface_decl.interface_impl_declaration type_ptr_to_sil_type tenv dec);
CMethod_trans.add_default_method_for_class class_name decl_info;
process_methods tenv cg cfg curr_class decl_list;
| CXXMethodDecl (decl_info, _, _, _, _)

@ -462,6 +462,12 @@ let get_method_for_frontend_checks cfg cg loc =
Cg.add_defined_node cg proc_name;
pdesc
let add_default_method_for_class class_name decl_info =
let loc = CLocation.get_sil_location_from_range decl_info.Clang_ast_t.di_source_range true in
let proc_name = Procname.get_default_objc_class_method class_name in
let attrs = { (ProcAttributes.default proc_name Config.C_CPP) with loc = loc; } in
AttributesTable.store_attributes attrs
let get_procname_from_cpp_lambda context dec =
match dec with
| Clang_ast_t.CXXRecordDecl (_, _, _, _, _, _, _, cxx_rdi) ->

@ -52,4 +52,6 @@ val create_procdesc_with_pointer : CContext.t -> Clang_ast_t.pointer -> string o
val get_method_for_frontend_checks : Cfg.cfg -> Cg.t -> Location.t -> Cfg.Procdesc.t
val add_default_method_for_class : string -> Clang_ast_t.decl_info -> unit
val get_procname_from_cpp_lambda : CContext.t -> Clang_ast_t.decl -> Procname.t

Loading…
Cancel
Save