[clang] Store Typename.t in Procname.ObjC_Cpp.class

Summary:
It used to be string which:
1. Doesn't have enough information for parametric models
2. Doesn't have good type

Changing this blows up in clang frontend, but I think it's for the better

Reviewed By: jberdine

Differential Revision: D4667633

fbshipit-source-id: 9f61bf1
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent 674cfe4c83
commit 1a9b81c0f4

@ -23,7 +23,8 @@ let create_procname name =
let create_objc_class_method class_name method_name =
let method_kind = Procname.ObjCClassMethod in
let pname = (Procname.ObjC_Cpp (Procname.objc_cpp class_name method_name method_kind)) in
let tname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string class_name) in
let pname = Procname.ObjC_Cpp (Procname.objc_cpp tname method_name method_kind) in
register pname;
pname

@ -396,8 +396,7 @@ let specialize_types_proc callee_pdesc resolved_pdesc substitutions => {
let redirected_typename = Option.value_exn (redirect_typename id);
let redirected_typ = mk_ptr_typ redirected_typename;
let redirected_pname =
Procname.replace_class
(Procname.Java callee_pname_java) (Typename.name redirected_typename);
Procname.replace_class (Procname.Java callee_pname_java) redirected_typename;
let args = {
let other_args = List.map f::(fun (exp, typ) => (convert_exp exp, typ)) origin_args;
[(Exp.Var id, redirected_typ), ...other_args]

@ -55,7 +55,7 @@ type objc_cpp_method_kind =
/** Type of Objective C and C++ procedure names: method signatures. */
type objc_cpp = {method_name: string, class_name: string, kind: objc_cpp_method_kind}
type objc_cpp = {method_name: string, class_name: Typename.t, kind: objc_cpp_method_kind}
[@@deriving compare];
@ -182,9 +182,9 @@ let is_constexpr =
/** Replace the class name component of a procedure name.
In case of Java, replace package and class name. */
let replace_class t new_class =>
let replace_class t (new_class: Typename.t) =>
switch t {
| Java j => Java {...j, class_name: Typename.Java.from_string new_class}
| Java j => Java {...j, class_name: new_class}
| ObjC_Cpp osig => ObjC_Cpp {...osig, class_name: new_class}
| C _
| Block _
@ -193,7 +193,9 @@ let replace_class t new_class =>
/** Get the class name of a Objective-C/C++ procedure name. */
let objc_cpp_get_class_name objc_cpp => objc_cpp.class_name;
let objc_cpp_get_class_name objc_cpp => Typename.name objc_cpp.class_name;
let objc_cpp_get_class_type_name objc_cpp => objc_cpp.class_name;
/** Return the package.classname of a java procname. */
@ -480,7 +482,7 @@ let to_readable_string (c1, c2) verbose => {
let c_method_to_string osig detail_level =>
switch detail_level {
| Simple => osig.method_name
| Non_verbose => osig.class_name ^ "_" ^ osig.method_name
| Non_verbose => Typename.name osig.class_name ^ "_" ^ osig.method_name
| Verbose =>
let m_str =
switch osig.kind {
@ -505,7 +507,7 @@ let c_method_to_string osig detail_level =>
| ObjCInstanceMethod => "instance"
| ObjCInternalMethod => "internal"
};
osig.class_name ^ "_" ^ osig.method_name ^ m_str
Typename.name osig.class_name ^ "_" ^ osig.method_name ^ m_str
};
@ -579,6 +581,7 @@ let get_qualifiers pname =>
| C c => fst c |> QualifiedCppName.qualifiers_of_qual_name
| ObjC_Cpp objc_cpp =>
List.append
(QualifiedCppName.qualifiers_of_qual_name objc_cpp.class_name) [objc_cpp.method_name]
(QualifiedCppName.qualifiers_of_qual_name (Typename.name objc_cpp.class_name))
[objc_cpp.method_name]
| _ => []
};

@ -141,14 +141,16 @@ let mangled_objc_block: string => t;
/** Create an objc procedure name from a class_name and method_name. */
let objc_cpp: string => string => objc_cpp_method_kind => objc_cpp;
let objc_cpp: Typename.t => string => objc_cpp_method_kind => objc_cpp;
let get_default_objc_class_method: string => t;
let get_default_objc_class_method: Typename.t => t;
/** Get the class name of a Objective-C/C++ procedure name. */
let objc_cpp_get_class_name: objc_cpp => string;
let objc_cpp_get_class_type_name: objc_cpp => Typename.t;
/** Create ObjC method type from a bool is_instance. */
let objc_method_kind_of_bool: bool => objc_cpp_method_kind;
@ -253,7 +255,7 @@ let pp_set: Format.formatter => Set.t => unit;
/** Replace the class name component of a procedure name.
In case of Java, replace package and class name. */
let replace_class: t => string => t;
let replace_class: t => Typename.t => t;
/** Given a package.class_name string, look for the latest dot and split the string

@ -1650,7 +1650,7 @@ let get_overrides_of tenv supertype pname =
if not (Typ.equal typ supertype) && Subtyping_check.check_subtype tenv typ supertype then
(* only select the ones that implement [pname] as overrides *)
let resolved_pname =
Procname.replace_class pname (Typename.name tname) in
Procname.replace_class pname tname in
if typ_has_method resolved_pname typ then (typ, resolved_pname) :: overrides_acc
else overrides_acc
else overrides_acc in

@ -486,7 +486,7 @@ let resolve_method tenv class_name proc_name =
let rec resolve (class_name: Typename.t) =
visited := Typename.Set.add class_name !visited;
let right_proc_name =
Procname.replace_class proc_name (Typename.name class_name) in
Procname.replace_class proc_name class_name in
match class_name, Tenv.lookup tenv class_name with
| TN_csu (Class _, _), Some { methods; supers } ->
if method_exists right_proc_name methods then

@ -273,8 +273,9 @@ let java_method_to_procname java_method =
(* turn string specificiation of an objc method into a procname *)
let objc_method_to_procname objc_method =
let method_kind = Procname.objc_method_kind_of_bool (not objc_method.is_static) in
let typename = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string objc_method.classname) in
Procname.ObjC_Cpp
(Procname.objc_cpp objc_method.classname objc_method.method_name method_kind)
(Procname.objc_cpp typename objc_method.method_name method_kind)
let taint_spec_to_taint_info taint_spec =
let taint_source =

@ -334,7 +334,7 @@ let proc_calls resolve_attributes pdesc filter : (Procname.t * ProcAttributes.t)
let override_exists f tenv proc_name =
let rec super_type_exists tenv super_class_name =
let super_proc_name =
Procname.replace_class proc_name (Typename.name super_class_name) in
Procname.replace_class proc_name super_class_name in
match Tenv.lookup tenv super_class_name with
| Some ({ methods; supers; }) ->
let is_override pname =

@ -60,6 +60,10 @@ let mk_cpp_method class_name method_name ?meth_decl mangled =
Procname.ObjC_Cpp
(Procname.objc_cpp class_name method_name method_kind)
let mk_objc_method class_typename method_name method_kind =
Procname.ObjC_Cpp
(Procname.objc_cpp class_typename method_name method_kind)
let block_procname_with_index defining_proc i =
Config.anonymous_block_prefix ^
(Procname.to_string defining_proc) ^
@ -85,6 +89,12 @@ let mk_fresh_block_procname defining_proc =
Procname.mangled_objc_block name
let get_class_typename method_decl_info =
let class_ptr = Option.value_exn method_decl_info.Clang_ast_t.di_parent_pointer in
match CAst_utils.get_decl class_ptr with
| Some class_decl -> CType_decl.get_record_typename class_decl
| None -> assert false
module NoAstDecl = struct
let c_function_of_string translation_unit_context name =
mk_c_function translation_unit_context name None
@ -93,10 +103,10 @@ module NoAstDecl = struct
mk_cpp_method class_name method_name None
let objc_method_of_string_kind class_name method_name method_kind =
Procname.ObjC_Cpp
(Procname.objc_cpp class_name method_name method_kind)
mk_objc_method class_name method_name method_kind
end
let from_decl translation_unit_context meth_decl =
let open Clang_ast_t in
match meth_decl with
@ -104,20 +114,20 @@ let from_decl translation_unit_context meth_decl =
let name = CAst_utils.get_qualified_name name_info in
let function_info = Some (decl_info, fdi) in
mk_c_function translation_unit_context name function_info
| CXXMethodDecl (_, name_info, _, fdi, mdi)
| CXXConstructorDecl (_, name_info, _, fdi, mdi)
| CXXConversionDecl (_, name_info, _, fdi, mdi)
| CXXDestructorDecl (_, name_info, _, fdi, mdi) ->
| CXXMethodDecl (decl_info, name_info, _, fdi, mdi)
| CXXConstructorDecl (decl_info, name_info, _, fdi, mdi)
| CXXConversionDecl (decl_info, name_info, _, fdi, mdi)
| CXXDestructorDecl (decl_info, name_info, _, fdi, mdi) ->
let mangled = get_mangled_method_name fdi mdi in
let method_name = CAst_utils.get_unqualified_name name_info in
let class_name = CAst_utils.get_class_name_from_member name_info in
mk_cpp_method class_name method_name ~meth_decl mangled
| ObjCMethodDecl (_, name_info, mdi) ->
let class_name = CAst_utils.get_class_name_from_member name_info in
let class_typename = get_class_typename decl_info in
mk_cpp_method class_typename method_name ~meth_decl mangled
| ObjCMethodDecl (decl_info, name_info, mdi) ->
let class_typename = get_class_typename decl_info in
let method_name = name_info.Clang_ast_t.ni_name in
let is_instance = mdi.Clang_ast_t.omdi_is_instance_method in
let method_kind = Procname.objc_method_kind_of_bool is_instance in
NoAstDecl.objc_method_of_string_kind class_name method_name method_kind
mk_objc_method class_typename method_name method_kind
| BlockDecl _ ->
let name = Config.anonymous_block_prefix ^ Config.anonymous_block_num_sep ^
(string_of_int (get_fresh_block_index ())) in

@ -18,9 +18,10 @@ val from_decl : CFrontend_config.translation_unit_context -> Clang_ast_t.decl ->
module NoAstDecl : sig
val c_function_of_string : CFrontend_config.translation_unit_context -> string -> Procname.t
val cpp_method_of_string : string -> string -> Procname.t
val cpp_method_of_string : Typename.t -> string -> Procname.t
val objc_method_of_string_kind : string -> string -> Procname.objc_cpp_method_kind -> Procname.t
val objc_method_of_string_kind : Typename.t -> string -> Procname.objc_cpp_method_kind ->
Procname.t
end

@ -21,22 +21,22 @@ let remove_pointer_to_typ typ =
| Typ.Tptr(typ, Typ.Pk_pointer) -> typ
| _ -> typ
let classname_of_type typ =
let mk_classname n ck = Typename.TN_csu (Csu.Class ck, Mangled.from_string n)
let mk_structname n = Typename.TN_csu (Csu.Struct, Mangled.from_string n)
let objc_classname_of_type typ =
match typ with
| Typ.Tstruct name -> Typename.name name
| Typ.Tfun _ -> CFrontend_config.objc_object
| Typ.Tstruct name -> name
| Typ.Tfun _ -> mk_classname CFrontend_config.objc_object Csu.Objc
| _ ->
Logging.out_debug
"Classname of type cannot be extracted in type %s" (Typ.to_string typ);
"undefined"
let mk_classname n ck = Typename.TN_csu (Csu.Class ck, Mangled.from_string n)
let mk_structname n = Typename.TN_csu (Csu.Struct, Mangled.from_string n)
mk_classname "undefined" Csu.Objc
let is_class typ =
match typ with
| Typ.Tptr (Tstruct ((TN_csu _) as name), _) ->
| Typ.Tptr (Tstruct name, _) ->
String.equal (Typename.name name) CFrontend_config.objc_class
| _ -> false

@ -13,7 +13,7 @@ open! IStd
val add_pointer_to_typ : Typ.t -> Typ.t
val classname_of_type : Typ.t -> string
val objc_classname_of_type : Typ.t -> Typename.t
val mk_classname : string -> Csu.class_kind -> Typename.t

@ -72,12 +72,23 @@ let get_record_name_csu decl =
(* we use Csu.Class for C++ because we expect Csu.Class csu from *)
(* types that have methods. And in C++ struct/class/union can have methods *)
name_info, Csu.Class Csu.CPP
| _-> assert false in
| ObjCInterfaceDecl (_, name_info, _, _, _)
| ObjCImplementationDecl (_, name_info, _, _, _)
| ObjCProtocolDecl (_, name_info, _, _, _)
| ObjCCategoryDecl (_, name_info, _, _, _)
| ObjCCategoryImplDecl (_, name_info, _, _, _) ->
name_info, Csu.Class Csu.Objc
| _ -> assert false in
let name = CAst_utils.get_qualified_name name_info in
csu, name
let get_record_name decl = snd (get_record_name_csu decl)
let get_record_typename decl =
let csu, name = get_record_name_csu decl in
let mangled_name = Mangled.from_string name in
Typename.TN_csu (csu, mangled_name)
let get_class_template_name = function
| Clang_ast_t.ClassTemplateDecl (_, name_info, _ ) -> CAst_utils.get_qualified_name name_info
| _ -> assert false
@ -185,9 +196,8 @@ and get_record_struct_type tenv definition_decl =
| ClassTemplateSpecializationDecl (_, _, _, type_ptr, _, _, record_decl_info, _, _)
| CXXRecordDecl (_, _, _, type_ptr, _, _, record_decl_info, _)
| RecordDecl (_, _, _, type_ptr, _, _, record_decl_info) ->
let sil_typename = get_record_typename definition_decl in
let csu, name = get_record_name_csu definition_decl in
let mangled_name = Mangled.from_string name in
let sil_typename = Typename.TN_csu (csu, mangled_name) in
(match Tenv.lookup tenv sil_typename with
| Some _ -> Typ.Tstruct sil_typename (* just reuse what is already in tenv *)
| None ->
@ -237,16 +247,13 @@ and add_types_from_decl_to_tenv tenv decl =
and type_ptr_to_sil_type tenv tp =
CType_to_sil_type.type_ptr_to_sil_type add_types_from_decl_to_tenv tenv tp
let objc_class_name_to_sil_type tenv name =
type_ptr_to_sil_type tenv (Ast_expressions.create_class_type (name, `OBJC))
let get_type_from_expr_info ei tenv =
let tp = ei.Clang_ast_t.ei_type_ptr in
type_ptr_to_sil_type tenv tp
let class_from_pointer_type tenv type_ptr =
match type_ptr_to_sil_type tenv type_ptr with
| Typ.Tptr( Typ.Tstruct (Typename.TN_csu (_, name)), _) -> Mangled.to_string name
| Typ.Tptr(Typ.Tstruct typename, _) -> typename
| _ -> assert false
let get_class_type_np tenv expr_info obj_c_message_expr_info =
@ -255,7 +262,3 @@ let get_class_type_np tenv expr_info obj_c_message_expr_info =
| `Class tp -> tp
| _ -> expr_info.Clang_ast_t.ei_type_ptr in
type_ptr_to_sil_type tenv tp
let get_type_curr_class_objc curr_class =
let name = CContext.get_curr_class_name curr_class in
Typ.Tstruct (TN_csu (Class Objc, (Mangled.from_string name)))

@ -13,6 +13,8 @@ open! IStd
val get_record_name : Clang_ast_t.decl -> string
val get_record_typename : Clang_ast_t.decl -> Typename.t
val add_types_from_decl_to_tenv : Tenv.t -> Clang_ast_t.decl -> Typ.t
(* Adds the predefined types objc_class which is a struct, *)
@ -21,13 +23,9 @@ val add_predefined_types : Tenv.t -> unit
val type_ptr_to_sil_type : Tenv.t -> Clang_ast_t.type_ptr -> Typ.t
val class_from_pointer_type : Tenv.t -> Clang_ast_t.type_ptr -> string
val class_from_pointer_type : Tenv.t -> Clang_ast_t.type_ptr -> Typename.t
val get_class_type_np : Tenv.t -> Clang_ast_t.expr_info ->
Clang_ast_t.obj_c_message_expr_info -> Typ.t
val get_type_curr_class_objc : CContext.curr_class -> Typ.t
val get_type_from_expr_info : Clang_ast_t.expr_info -> Tenv.t -> Typ.t
val objc_class_name_to_sil_type : Tenv.t -> string -> Typ.t

@ -106,9 +106,12 @@ let create_void_unsigned_long_type =
let create_void_void_type =
new_constant_type_ptr ()
let create_class_type class_info = `ClassType class_info
let create_class_qual_type ?(is_const=false) class_info =
create_qual_type ~is_const @@ create_class_type class_info
let create_class_type typename = `ClassType typename
let create_class_qual_type ?(is_const=false) typename =
create_qual_type ~is_const @@ create_class_type typename
let make_objc_class_type class_name =
create_class_type (Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string class_name))
let create_struct_type struct_name = `StructType struct_name
@ -204,7 +207,7 @@ let make_obj_c_message_expr_info_instance sel = {
let make_obj_c_message_expr_info_class selector tp pointer = {
Clang_ast_t.omei_selector = selector;
omei_receiver_kind = `Class (create_class_type (tp, `OBJC));
omei_receiver_kind = `Class (create_class_type tp);
omei_is_definition_found = false;
omei_decl_pointer = pointer
}
@ -331,7 +334,7 @@ let build_OpaqueValueExpr si source_expr ei =
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)
let pseudo_object_tp () = create_class_type (CFrontend_config.pseudo_object_type, `OBJC)
let pseudo_object_tp () = make_objc_class_type CFrontend_config.pseudo_object_type
(* Create expression PseudoObjectExpr for 'o.m' *)
let build_PseudoObjectExpr tp_m o_cast_decl_ref_exp mname =
@ -515,8 +518,8 @@ let translate_block_enumerate block_name stmt_info stmt_list ei =
(* 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 tp = create_qual_type @@ create_pointer_type @@ create_class_type
(CFrontend_config.nsarray_cl, `OBJC) in
let tp = create_qual_type @@ create_pointer_type @@
make_objc_class_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

@ -44,10 +44,10 @@ val create_void_unsigned_long_type : type_ptr
val create_void_void_type : type_ptr
val create_class_type : Clang_ast_types.class_info -> type_ptr
val create_class_qual_type : ?is_const:bool -> Clang_ast_types.class_info -> qual_type
val create_class_type : Typename.t -> type_ptr
val create_class_qual_type : ?is_const:bool -> Typename.t -> qual_type
val create_struct_type : string -> type_ptr
val create_struct_type : Typename.t -> type_ptr
val create_pointer_type : type_ptr -> type_ptr
val create_pointer_qual_type : is_const:bool -> type_ptr -> qual_type
@ -79,7 +79,7 @@ val make_message_expr : type_ptr -> string -> stmt -> stmt_info -> bool -> stmt
val make_binary_stmt : stmt -> stmt -> stmt_info -> expr_info -> binary_operator_info -> stmt
val make_obj_c_message_expr_info_class : string -> string -> pointer option ->
val make_obj_c_message_expr_info_class : string -> Typename.t -> pointer option ->
obj_c_message_expr_info
val make_obj_c_message_expr_info_instance : string -> obj_c_message_expr_info

@ -81,18 +81,21 @@ let get_curr_class_decl_ptr curr_class =
| ContextClsDeclPtr ptr -> ptr
| _ -> assert false
let get_curr_class_name curr_class =
let get_curr_class_ptr curr_class =
let decl_ptr = get_curr_class_decl_ptr curr_class in
let get_ptr_from_decl_ref = function
| Some dr -> dr.Clang_ast_t.dr_decl_pointer
| None -> assert false in
(* Resolve categories to their class names *)
let class_decl_ptr = match CAst_utils.get_decl decl_ptr with
| Some ObjCCategoryDecl (_, _, _, _, ocdi) ->
get_ptr_from_decl_ref ocdi.odi_class_interface
| Some ObjCCategoryImplDecl (_, _, _, _, ocidi) ->
get_ptr_from_decl_ref ocidi.ocidi_class_interface
| _ -> decl_ptr in
match CAst_utils.get_decl decl_ptr with
| Some ObjCCategoryDecl (_, _, _, _, ocdi) ->
get_ptr_from_decl_ref ocdi.odi_class_interface
| Some ObjCCategoryImplDecl (_, _, _, _, ocidi) ->
get_ptr_from_decl_ref ocidi.ocidi_class_interface
| _ -> decl_ptr
let get_curr_class_name curr_class =
let class_decl_ptr = get_curr_class_ptr curr_class in
let _, name_info = match Option.bind
(CAst_utils.get_decl class_decl_ptr)
Clang_ast_proj.get_named_decl_tuple with
@ -100,6 +103,11 @@ let get_curr_class_name curr_class =
| None -> assert false in
CAst_utils.get_qualified_name name_info
let get_curr_class_typename curr_class =
match get_curr_class_ptr curr_class |> CAst_utils.get_decl with
| Some decl -> CType_decl.get_record_typename decl
| None -> assert false
let curr_class_to_string curr_class =
match curr_class with
| ContextClsDeclPtr ptr -> ("decl_ptr: " ^ string_of_int ptr)

@ -47,6 +47,8 @@ val get_curr_class : t -> curr_class
val get_curr_class_name : curr_class -> string
val get_curr_class_typename : curr_class -> Typename.t
val get_curr_class_decl_ptr : curr_class -> Clang_ast_t.pointer
val curr_class_to_string : curr_class -> string

@ -197,12 +197,12 @@ struct
ignore (ObjcCategory_decl.category_impl_decl CType_decl.type_ptr_to_sil_type tenv dec);
process_methods trans_unit_ctx tenv cg cfg curr_class decl_list;
| ObjCImplementationDecl(decl_info, name_info, decl_list, _, _) ->
| ObjCImplementationDecl(decl_info, _, decl_list, _, _) ->
let curr_class = CContext.ContextClsDeclPtr dec_ptr in
let class_name = CAst_utils.get_qualified_name name_info in
let class_typename = CType_decl.get_record_typename dec in
let type_ptr_to_sil_type = CType_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 trans_unit_ctx class_name decl_info;
CMethod_trans.add_default_method_for_class trans_unit_ctx class_typename decl_info;
process_methods trans_unit_ctx tenv cg cfg curr_class decl_list;
| CXXMethodDecl (decl_info, _, _, _, _)

@ -217,9 +217,9 @@ let get_method_name_from_clang tenv ms_opt =
else
(ignore (CType_decl.add_types_from_decl_to_tenv tenv decl);
match ObjcCategory_decl.get_base_class_name_from_category decl with
| Some class_name ->
| Some class_typename ->
let procname = CMethod_signature.ms_get_name ms in
let new_procname = Procname.replace_class procname class_name in
let new_procname = Procname.replace_class procname class_typename in
CMethod_signature.ms_set_name ms new_procname;
Some ms
| None -> Some ms)
@ -250,7 +250,7 @@ let get_superclass_curr_class_objc context =
super_of_decl_ref_opt ocidi.ocidi_class_interface
| _ -> assert false in
match CContext.get_curr_class context with
| CContext.ContextClsDeclPtr ptr -> retreive_super_name ptr
| CContext.ContextClsDeclPtr ptr -> CType.mk_classname (retreive_super_name ptr) Csu.Objc
| CContext.ContextNoCls -> assert false
(* Gets the class name from a method signature found by clang, if search is successful *)
@ -262,7 +262,7 @@ let get_class_name_method_call_from_clang trans_unit_ctx tenv obj_c_message_expr
begin
match CMethod_signature.ms_get_name ms with
| Procname.ObjC_Cpp objc_cpp ->
Some (Procname.objc_cpp_get_class_name objc_cpp)
Some (Procname.objc_cpp_get_class_type_name objc_cpp)
| _ ->
None
end
@ -274,11 +274,11 @@ let get_class_name_method_call_from_receiver_kind context obj_c_message_expr_inf
match obj_c_message_expr_info.Clang_ast_t.omei_receiver_kind with
| `Class tp ->
let sil_type = CType_decl.type_ptr_to_sil_type context.CContext.tenv tp in
(CType.classname_of_type sil_type)
(CType.objc_classname_of_type sil_type)
| `Instance ->
(match act_params with
| (_, Typ.Tptr(t, _)):: _
| (_, t):: _ -> CType.classname_of_type t
| (_, t):: _ -> CType.objc_classname_of_type t
| _ -> assert false)
| `SuperInstance ->get_superclass_curr_class_objc context
| `SuperClass -> get_superclass_curr_class_objc context

@ -36,10 +36,10 @@ val get_objc_method_data : Clang_ast_t.obj_c_message_expr_info ->
(string * Clang_ast_t.pointer option * method_call_type)
val get_class_name_method_call_from_receiver_kind : CContext.t ->
Clang_ast_t.obj_c_message_expr_info -> (Exp.t * Typ.t) list -> string
Clang_ast_t.obj_c_message_expr_info -> (Exp.t * Typ.t) list -> Typename.t
val get_class_name_method_call_from_clang : CFrontend_config.translation_unit_context -> Tenv.t ->
Clang_ast_t.obj_c_message_expr_info -> string option
Clang_ast_t.obj_c_message_expr_info -> Typename.t option
val method_signature_of_decl : CFrontend_config.translation_unit_context -> Tenv.t ->
Clang_ast_t.decl -> CModule_type.block_data option ->
@ -51,10 +51,10 @@ val method_signature_of_pointer : CFrontend_config.translation_unit_context -> T
val get_method_name_from_clang : Tenv.t -> CMethod_signature.method_signature option ->
CMethod_signature.method_signature option
val create_procdesc_with_pointer : CContext.t -> Clang_ast_t.pointer -> string option -> string ->
Procname.t
val create_procdesc_with_pointer : CContext.t -> Clang_ast_t.pointer -> Typename.t option ->
string -> Procname.t
val add_default_method_for_class : CFrontend_config.translation_unit_context -> string ->
val add_default_method_for_class : CFrontend_config.translation_unit_context -> Typename.t ->
Clang_ast_t.decl_info -> unit
val get_procname_from_cpp_lambda : CContext.t -> Clang_ast_t.decl -> Procname.t

@ -46,7 +46,7 @@ struct
CProcname.NoAstDecl.objc_method_of_string_kind class_name selector method_kind in
let predefined_ms_opt = match proc_name with
| Procname.ObjC_Cpp objc_cpp ->
let class_name = Procname.objc_cpp_get_class_name objc_cpp in
let class_name = Procname.objc_cpp_get_class_type_name objc_cpp in
CTrans_models.get_predefined_model_method_signature class_name selector
CProcname.NoAstDecl.objc_method_of_string_kind CFrontend_config.ObjC
| _ ->
@ -207,8 +207,7 @@ struct
try
f trans_state stmt
with Self.SelfClassException class_name ->
let typ =
CType_decl.objc_class_name_to_sil_type trans_state.context.CContext.tenv class_name in
let typ = Typ.Tstruct class_name in
{ empty_res_trans with
exps = [(Exp.Sizeof (typ, None, Subtype.exact), Tint IULong)] }
@ -527,7 +526,6 @@ struct
let decl_opt = CAst_utils.get_function_decl_with_body decl_ptr in
Option.iter ~f:(call_translation context) decl_opt;
let method_name = CAst_utils.get_unqualified_name name_info in
let class_name = CAst_utils.get_class_name_from_member name_info in
Logging.out_debug "!!!!! Dealing with method '%s' @." method_name;
let method_typ = CType_decl.type_ptr_to_sil_type context.tenv type_ptr in
let ms_opt = CMethod_trans.method_signature_of_pointer
@ -568,7 +566,9 @@ struct
type_ptr with
| Some builtin_pname -> builtin_pname
| None ->
CMethod_trans.create_procdesc_with_pointer context decl_ptr (Some class_name)
let class_typename = CType.mk_classname
(CAst_utils.get_class_name_from_member name_info) Csu.CPP in
CMethod_trans.create_procdesc_with_pointer context decl_ptr (Some class_typename)
method_name in
let method_exp = (Exp.Const (Const.Cfun pname), method_typ) in
{ pre_trans_result with
@ -657,10 +657,11 @@ struct
else empty_res_trans in
let exps = if Self.is_var_self pvar (CContext.is_objc_method context) then
let curr_class = CContext.get_curr_class context in
let class_typename = CContext.get_curr_class_typename curr_class in
if (CType.is_class typ) then
raise (Self.SelfClassException (CContext.get_curr_class_name curr_class))
raise (Self.SelfClassException class_typename)
else
let typ = CType.add_pointer_to_typ (CType_decl.get_type_curr_class_objc curr_class) in
let typ = CType.add_pointer_to_typ (Typ.Tstruct class_typename) in
[(var_exp, typ)]
else [(var_exp, typ)] in
Logging.out_debug "\n\n PVAR ='%s'\n\n" (Pvar.to_string pvar);
@ -1056,11 +1057,11 @@ struct
try
let fst_res_trans = instruction trans_state_param stmt in
obj_c_message_expr_info, fst_res_trans
with Self.SelfClassException class_name ->
with Self.SelfClassException class_typename ->
let pointer = obj_c_message_expr_info.Clang_ast_t.omei_decl_pointer in
let selector = obj_c_message_expr_info.Clang_ast_t.omei_selector in
let obj_c_message_expr_info =
Ast_expressions.make_obj_c_message_expr_info_class selector class_name pointer in
Ast_expressions.make_obj_c_message_expr_info_class selector class_typename pointer in
obj_c_message_expr_info, empty_res_trans in
let instruction' =
exec_with_self_exception (exec_with_glvalue_as_reference instruction) in

@ -11,6 +11,8 @@ open! IStd
open Objc_models
let class_equal class_typename class_name = String.equal (Typename.name class_typename) class_name
let is_cf_non_null_alloc pname =
String.equal (Procname.to_string pname) CFrontend_config.cf_non_null_alloc
@ -143,7 +145,7 @@ let get_predefined_ms_method condition class_name method_name method_kind mk_pro
let get_predefined_ms_stringWithUTF8String class_name method_name mk_procname lang =
let condition =
String.equal class_name CFrontend_config.nsstring_cl &&
class_equal class_name CFrontend_config.nsstring_cl &&
String.equal method_name CFrontend_config.string_with_utf8_m in
let id_type = Ast_expressions.create_id_type in
let args = [(Mangled.from_string "x",
@ -156,17 +158,17 @@ let get_predefined_ms_retain_release method_name mk_procname lang =
let return_type =
if is_retain_method method_name || is_autorelease_method method_name
then Ast_expressions.create_id_type else Ast_expressions.create_void_type in
let class_name = CFrontend_config.nsobject_cl in
let class_type = Ast_expressions.create_class_qual_type (class_name, `OBJC) in
let class_typename = CType.mk_classname CFrontend_config.nsobject_cl Csu.Objc in
let class_type = Ast_expressions.create_class_qual_type class_typename in
let args = [(Mangled.from_string CFrontend_config.self, class_type)] in
get_predefined_ms_method condition class_name method_name Procname.ObjCInstanceMethod
get_predefined_ms_method condition class_typename method_name Procname.ObjCInstanceMethod
mk_procname lang args return_type [] (get_builtinname method_name)
let get_predefined_ms_autoreleasepool_init class_name method_name mk_procname lang =
let condition =
String.equal method_name CFrontend_config.init &&
String.equal class_name CFrontend_config.nsautorelease_pool_cl in
let class_type = Ast_expressions.create_class_qual_type (class_name, `OBJC) in
class_equal class_name CFrontend_config.nsautorelease_pool_cl in
let class_type = Ast_expressions.create_class_qual_type class_name in
get_predefined_ms_method condition class_name method_name Procname.ObjCInstanceMethod
mk_procname lang [(Mangled.from_string CFrontend_config.self, class_type)]
Ast_expressions.create_void_type [] None
@ -176,8 +178,8 @@ let get_predefined_ms_nsautoreleasepool_release class_name method_name mk_procna
(String.equal method_name CFrontend_config.release ||
String.equal method_name CFrontend_config.drain)
&&
String.equal class_name CFrontend_config.nsautorelease_pool_cl in
let class_type = Ast_expressions.create_class_qual_type (class_name, `OBJC) in
class_equal class_name CFrontend_config.nsautorelease_pool_cl in
let class_type = Ast_expressions.create_class_qual_type class_name in
let args = [(Mangled.from_string CFrontend_config.self, class_type)] in
get_predefined_ms_method condition class_name method_name Procname.ObjCInstanceMethod
mk_procname lang args Ast_expressions.create_void_type
@ -185,7 +187,7 @@ let get_predefined_ms_nsautoreleasepool_release class_name method_name mk_procna
let get_predefined_ms_is_kind_of_class class_name method_name mk_procname lang =
let condition = String.equal method_name CFrontend_config.is_kind_of_class in
let class_type = Ast_expressions.create_class_qual_type (class_name, `OBJC) in
let class_type = Ast_expressions.create_class_qual_type class_name in
let args = [(Mangled.from_string CFrontend_config.self, class_type)] in
get_predefined_ms_method condition class_name method_name Procname.ObjCInstanceMethod
mk_procname lang args Ast_expressions.create_BOOL_type

@ -39,8 +39,8 @@ val is_toll_free_bridging : Procname.t -> bool
val is_cf_retain_release : Procname.t -> bool
val get_predefined_model_method_signature : string -> string ->
(string -> string -> Procname.objc_cpp_method_kind -> Procname.t) ->
val get_predefined_model_method_signature : Typename.t -> string ->
(Typename.t -> string -> Procname.objc_cpp_method_kind -> Procname.t) ->
CFrontend_config.clang_lang -> CMethod_signature.method_signature option
val is_dispatch_function_name : string -> (string * int) option

@ -355,7 +355,7 @@ let new_or_alloc_trans trans_state loc stmt_info type_ptr class_name_opt selecto
let class_name =
match class_name_opt with
| Some class_name -> class_name
| None -> CType.classname_of_type function_type in
| None -> CType.objc_classname_of_type function_type in
if String.equal selector CFrontend_config.alloc then
alloc_trans trans_state loc stmt_info function_type true None
else if String.equal selector CFrontend_config.new_str then
@ -579,14 +579,14 @@ let rec get_type_from_exp_stmt stmt =
module Self =
struct
exception SelfClassException of string
exception SelfClassException of Typename.t
let add_self_parameter_for_super_instance context procname loc mei =
if is_superinstance mei then
let typ, self_expr, ins =
let t' =
CType.add_pointer_to_typ
(CType_decl.get_type_curr_class_objc context.CContext.curr_class) in
(Typ.Tstruct (CContext.get_curr_class_typename context.CContext.curr_class)) in
let e = Exp.Lvar (Pvar.mk (Mangled.from_string CFrontend_config.self) procname) in
let id = Ident.create_fresh Ident.knormal in
t', Exp.Var id, [Sil.Load (id, e, t', loc)] in

@ -109,7 +109,7 @@ val alloc_trans :
Procname.t option -> trans_result
val new_or_alloc_trans : trans_state -> Location.t -> Clang_ast_t.stmt_info ->
Clang_ast_t.type_ptr -> string option -> string -> trans_result
Clang_ast_t.type_ptr -> Typename.t option -> string -> trans_result
val cpp_new_trans : Location.t -> Typ.t -> Exp.t option -> trans_result
@ -202,7 +202,7 @@ end
module Self :
sig
exception SelfClassException of string
exception SelfClassException of Typename.t
val add_self_parameter_for_super_instance :
CContext.t -> Procname.t -> Location.t -> Clang_ast_t.obj_c_message_expr_info ->

@ -178,9 +178,8 @@ and type_ptr_to_sil_type translate_decl tenv type_ptr =
| `ReferenceOf typ ->
let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in
Typ.Tptr (sil_typ, Typ.Pk_reference)
| `ClassType (name, lang) ->
let kind = match lang with `OBJC -> Csu.Objc | `CPP -> Csu.CPP in
Typ.Tstruct (CType.mk_classname name kind)
| `StructType name -> Typ.Tstruct (CType.mk_structname name)
| `ClassType typename ->
Typ.Tstruct typename
| `StructType typename -> Typ.Tstruct typename
| `DeclPtr ptr -> decl_ptr_to_sil_type translate_decl tenv ptr
| `ErrorType -> Typ.Tvoid

@ -17,15 +17,14 @@ open! IStd
(* Type pointers *)
exception Not_Clang_Pointer
type class_info = string * [`CPP | `OBJC] [@@deriving compare]
type t_ptr = [
| `TPtr of int
| `Prebuilt of int
| `PointerOf of t_ptr
| `ReferenceOf of t_ptr
| `ClassType of class_info
| `StructType of string
| `ClassType of Typename.t
| `StructType of Typename.t
| `DeclPtr of int
| `ErrorType
] [@@deriving compare]
@ -41,8 +40,8 @@ let rec type_ptr_to_string type_ptr = match type_ptr with
| `Prebuilt raw -> "prebuilt_" ^ (string_of_int raw)
| `PointerOf typ -> "pointer_of_" ^ type_ptr_to_string typ
| `ReferenceOf typ -> "reference_of_" ^ type_ptr_to_string typ
| `ClassType (name, _) -> "class_name_" ^ name
| `StructType name -> "struct_name_" ^ name
| `ClassType name -> "class_name_" ^ Typename.name name
| `StructType name -> "struct_name_" ^ Typename.name name
| `DeclPtr raw -> "decl_ptr_" ^ (string_of_int raw)
| `ErrorType -> "error_type"

@ -59,7 +59,7 @@ let get_base_class_name_from_category decl =
| Some decl_ref ->
(match CAst_utils.get_decl decl_ref.Clang_ast_t.dr_decl_pointer with
| Some ObjCInterfaceDecl (_, name_info, _, _, _) ->
Some (CAst_utils.get_qualified_name name_info)
Some (CType.mk_classname (CAst_utils.get_qualified_name name_info) Csu.Objc)
| _ -> None)
| None -> None

@ -18,4 +18,4 @@ val category_impl_decl : CAst_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_
val noname_category : string -> string
val get_base_class_name_from_category : Clang_ast_t.decl -> string option
val get_base_class_name_from_category : Clang_ast_t.decl -> Typename.t option

Loading…
Cancel
Save