diff --git a/infer/src/IR/BuiltinDecl.ml b/infer/src/IR/BuiltinDecl.ml index 6045bebc2..146840f9e 100644 --- a/infer/src/IR/BuiltinDecl.ml +++ b/infer/src/IR/BuiltinDecl.ml @@ -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 diff --git a/infer/src/IR/Cfg.re b/infer/src/IR/Cfg.re index ecb3272ea..7bea12d62 100644 --- a/infer/src/IR/Cfg.re +++ b/infer/src/IR/Cfg.re @@ -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] diff --git a/infer/src/IR/Procname.re b/infer/src/IR/Procname.re index 3f149ec9d..6f46fc73e 100644 --- a/infer/src/IR/Procname.re +++ b/infer/src/IR/Procname.re @@ -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] | _ => [] }; diff --git a/infer/src/IR/Procname.rei b/infer/src/IR/Procname.rei index 8ce094980..b88bcb167 100644 --- a/infer/src/IR/Procname.rei +++ b/infer/src/IR/Procname.rei @@ -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 diff --git a/infer/src/backend/prover.ml b/infer/src/backend/prover.ml index be7398030..9988cb95d 100644 --- a/infer/src/backend/prover.ml +++ b/infer/src/backend/prover.ml @@ -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 diff --git a/infer/src/backend/symExec.ml b/infer/src/backend/symExec.ml index 38c9de6ad..e727c9f56 100644 --- a/infer/src/backend/symExec.ml +++ b/infer/src/backend/symExec.ml @@ -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 diff --git a/infer/src/backend/taint.ml b/infer/src/backend/taint.ml index c108876d8..fa418d6ab 100644 --- a/infer/src/backend/taint.ml +++ b/infer/src/backend/taint.ml @@ -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 = diff --git a/infer/src/checkers/patternMatch.ml b/infer/src/checkers/patternMatch.ml index a05f67d8e..9718bad51 100644 --- a/infer/src/checkers/patternMatch.ml +++ b/infer/src/checkers/patternMatch.ml @@ -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 = diff --git a/infer/src/clang/CProcname.ml b/infer/src/clang/CProcname.ml index fa956a559..a8f797571 100644 --- a/infer/src/clang/CProcname.ml +++ b/infer/src/clang/CProcname.ml @@ -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 diff --git a/infer/src/clang/CProcname.mli b/infer/src/clang/CProcname.mli index 4d170904f..eba3d7d9c 100644 --- a/infer/src/clang/CProcname.mli +++ b/infer/src/clang/CProcname.mli @@ -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 diff --git a/infer/src/clang/CType.ml b/infer/src/clang/CType.ml index ac85da433..af10efb23 100644 --- a/infer/src/clang/CType.ml +++ b/infer/src/clang/CType.ml @@ -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 diff --git a/infer/src/clang/CType.mli b/infer/src/clang/CType.mli index 4ab9d678d..9b1ed1af4 100644 --- a/infer/src/clang/CType.mli +++ b/infer/src/clang/CType.mli @@ -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 diff --git a/infer/src/clang/CType_decl.ml b/infer/src/clang/CType_decl.ml index a305095b8..6f08befd9 100644 --- a/infer/src/clang/CType_decl.ml +++ b/infer/src/clang/CType_decl.ml @@ -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))) diff --git a/infer/src/clang/CType_decl.mli b/infer/src/clang/CType_decl.mli index 1cafecae2..8f2295381 100644 --- a/infer/src/clang/CType_decl.mli +++ b/infer/src/clang/CType_decl.mli @@ -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 diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index 79b4da294..f854127c8 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -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 diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index 8fdbdaf38..045f9f1dd 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -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 diff --git a/infer/src/clang/cContext.ml b/infer/src/clang/cContext.ml index 7ab543448..6a71e1b77 100644 --- a/infer/src/clang/cContext.ml +++ b/infer/src/clang/cContext.ml @@ -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) diff --git a/infer/src/clang/cContext.mli b/infer/src/clang/cContext.mli index 4d9ae2d3b..da156989d 100644 --- a/infer/src/clang/cContext.mli +++ b/infer/src/clang/cContext.mli @@ -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 diff --git a/infer/src/clang/cFrontend_decl.ml b/infer/src/clang/cFrontend_decl.ml index f7795d8b5..9ebaf6d82 100644 --- a/infer/src/clang/cFrontend_decl.ml +++ b/infer/src/clang/cFrontend_decl.ml @@ -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, _, _, _, _) diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 48a592a05..23237e43e 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -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 diff --git a/infer/src/clang/cMethod_trans.mli b/infer/src/clang/cMethod_trans.mli index 64ac3194a..8107c6e70 100644 --- a/infer/src/clang/cMethod_trans.mli +++ b/infer/src/clang/cMethod_trans.mli @@ -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 diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 34207cf42..f210c3f86 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -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 diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index 9873ede03..8987cb98e 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -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 diff --git a/infer/src/clang/cTrans_models.mli b/infer/src/clang/cTrans_models.mli index 4acf26a0e..4994718cf 100644 --- a/infer/src/clang/cTrans_models.mli +++ b/infer/src/clang/cTrans_models.mli @@ -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 diff --git a/infer/src/clang/cTrans_utils.ml b/infer/src/clang/cTrans_utils.ml index c971e97c0..e20e76f12 100644 --- a/infer/src/clang/cTrans_utils.ml +++ b/infer/src/clang/cTrans_utils.ml @@ -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 diff --git a/infer/src/clang/cTrans_utils.mli b/infer/src/clang/cTrans_utils.mli index fb2151419..8950a4ca2 100644 --- a/infer/src/clang/cTrans_utils.mli +++ b/infer/src/clang/cTrans_utils.mli @@ -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 -> diff --git a/infer/src/clang/cType_to_sil_type.ml b/infer/src/clang/cType_to_sil_type.ml index ca792c8fb..0d85e63ea 100644 --- a/infer/src/clang/cType_to_sil_type.ml +++ b/infer/src/clang/cType_to_sil_type.ml @@ -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 diff --git a/infer/src/clang/clang_ast_types.ml b/infer/src/clang/clang_ast_types.ml index ee9aa3cc3..2805d3c69 100644 --- a/infer/src/clang/clang_ast_types.ml +++ b/infer/src/clang/clang_ast_types.ml @@ -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" diff --git a/infer/src/clang/objcCategory_decl.ml b/infer/src/clang/objcCategory_decl.ml index 9b4b74257..3059366ea 100644 --- a/infer/src/clang/objcCategory_decl.ml +++ b/infer/src/clang/objcCategory_decl.ml @@ -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 diff --git a/infer/src/clang/objcCategory_decl.mli b/infer/src/clang/objcCategory_decl.mli index 05d2ef4fe..162685397 100644 --- a/infer/src/clang/objcCategory_decl.mli +++ b/infer/src/clang/objcCategory_decl.mli @@ -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