diff --git a/infer/src/backend/sil.ml b/infer/src/backend/sil.ml index 491699c30..9ee39ce5b 100644 --- a/infer/src/backend/sil.ml +++ b/infer/src/backend/sil.ml @@ -75,6 +75,10 @@ let pp_item_annotation fmt item_annotation = let pp fmt (a, v) = pp_annotation fmt a in F.fprintf fmt "<%a>" (pp_seq pp) item_annotation +let item_annotation_to_string ann = + let pp fmt () = pp_item_annotation fmt ann in + Utils.pp_to_string pp () + (** Pretty print a method annotation. *) let pp_method_annotation s fmt (ia, ial) = F.fprintf fmt "%a %s(%a)" pp_item_annotation ia s (pp_seq pp_item_annotation) ial @@ -828,6 +832,34 @@ let has_objc_ref_counter hpred = IList.exists is_objc_ref_counter_field fl | _ -> false +let objc_class_str = "ObjC-Class" + +let cpp_class_str = "Cpp-Class" + +let class_annotation class_string = + [({ class_name = class_string; parameters =[]}, true)] + +let objc_class_annotation = + class_annotation objc_class_str + +let cpp_class_annotation = + class_annotation cpp_class_str + +let is_class_of_language typ class_string = + match typ with + | Tstruct(_, _, Csu.Class, _, _, _, a) -> + (match a with + | [({ class_name = n; parameters = []}, true)] + when n = class_string -> true + | _ -> false) + | _ -> false + +let is_objc_class typ = + is_class_of_language typ objc_class_str + +let is_cpp_class typ = + is_class_of_language typ cpp_class_str + (** turn a *T into a T. fails if [typ] is not a pointer type *) let typ_strip_ptr = function | Tptr (t, _) -> t diff --git a/infer/src/backend/sil.mli b/infer/src/backend/sil.mli index c482ea642..c2161de48 100644 --- a/infer/src/backend/sil.mli +++ b/infer/src/backend/sil.mli @@ -547,6 +547,14 @@ val is_objc_ref_counter_field : (Ident.fieldname * typ * item_annotation) -> boo val has_objc_ref_counter : hpred -> bool +val objc_class_annotation : (annotation * bool) list + +val cpp_class_annotation : (annotation * bool) list + +val is_objc_class : typ -> bool + +val is_cpp_class : typ -> bool + val exp_is_zero : exp -> bool val exp_is_null_literal : exp -> bool @@ -784,6 +792,8 @@ val pp_const: printenv -> Format.formatter -> const -> unit (** Pretty print an item annotation. *) val pp_item_annotation : Format.formatter -> item_annotation -> unit +val item_annotation_to_string : item_annotation -> string + (** Pretty print a method annotation. *) val pp_method_annotation : string -> Format.formatter -> method_annotation -> unit diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index 0f791f802..756c63797 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -47,7 +47,7 @@ struct (match typ with | Sil.Tstruct (fields, _, _, cls, super_classes, methods, iann) -> print_endline ( - (Typename.to_string typname) ^ "\n"^ + (Typename.to_string typname) ^ " " ^ (Sil.item_annotation_to_string iann) ^ "\n" ^ "---> superclass and protocols " ^ (IList.to_string (fun tn -> "\t" ^ (Typename.to_string tn) ^ "\n") super_classes) ^ "---> methods " ^ diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index bf8b7d25d..5843334be 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -181,7 +181,9 @@ and get_struct_cpp_class_declaration_type tenv decl = let static_fields = [] in (* Warning for the moment we do not treat static field. *) let methods = get_class_methods tenv name decl_list in (* C++ methods only *) let superclasses = get_superclass_list decl in - let item_annotation = Sil.item_annotation_empty in (* No annotations for struts *) + let item_annotation = + if csu = Csu.Class then Sil.cpp_class_annotation + else Sil.item_annotation_empty in (* No annotations for structs *) let sil_type = Sil.Tstruct (sorted_non_static_fields, static_fields, csu, Some mangled_name, superclasses, methods, item_annotation) in Ast_utils.update_sil_types_map type_ptr sil_type; diff --git a/infer/src/clang/objcInterface_decl.ml b/infer/src/clang/objcInterface_decl.ml index 59dacf001..44d717ae2 100644 --- a/infer/src/clang/objcInterface_decl.ml +++ b/infer/src/clang/objcInterface_decl.ml @@ -19,24 +19,13 @@ open CFrontend_utils module L = Logging -let objc_class_str = "ObjC-Class" - -let objc_class_annotation = - [({ Sil.class_name = objc_class_str; Sil.parameters =[]}, true)] - -let is_objc_class_annotation a = - match a with - | [({ Sil.class_name = n; Sil.parameters =[]}, true)] when n = objc_class_str -> true - | _ -> false - let is_pointer_to_objc_class tenv typ = match typ with | Sil.Tptr (Sil.Tvar (Typename.TN_csu (Csu.Class, cname)), _) -> (match Sil.tenv_lookup tenv (Typename.TN_csu (Csu.Class, cname)) with - | Some Sil.Tstruct(_, _, Csu.Class, _, _, _, a) when is_objc_class_annotation a -> true + | Some typ when Sil.is_objc_class typ -> true | _ -> false) - | Sil.Tptr (Sil.Tstruct(_, _, Csu.Class, _, _, _, a), _) when - is_objc_class_annotation a -> true + | Sil.Tptr (typ, _) when Sil.is_objc_class typ -> true | _ -> false let get_super_interface_decl otdi_super = @@ -139,7 +128,7 @@ let add_class_to_tenv type_ptr_to_sil_type tenv curr_class decl_info class_name Printing.log_out "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields; let interface_type_info = Sil.Tstruct(fields, [], Csu.Class, Some (Mangled.from_string class_name), - superclasses, methods, objc_class_annotation) in + superclasses, methods, Sil.objc_class_annotation) in Sil.tenv_add tenv interface_name interface_type_info; Printing.log_out " >>>Verifying that Typename '%s' is in tenv\n" (Typename.to_string interface_name);