From 9b32ce59c7566dc30b86aa982925d9b435d980d1 Mon Sep 17 00:00:00 2001 From: Dulma Churchill Date: Fri, 1 Jun 2018 02:37:24 -0700 Subject: [PATCH] [clang] Use the procname_from_decl method when computing objc method names to add to the tenv Reviewed By: mbouaziz Differential Revision: D8206246 fbshipit-source-id: 9327eb0 --- infer/src/clang/CType_decl.ml | 15 ++++++++------- infer/src/clang/cAst_utils.ml | 3 +++ infer/src/clang/cAst_utils.mli | 3 +++ infer/src/clang/cFrontend_decl.ml | 15 +++++++++++---- infer/src/clang/objcCategory_decl.ml | 18 ++++++++++++------ infer/src/clang/objcCategory_decl.mli | 8 ++++++-- infer/src/clang/objcInterface_decl.ml | 17 ++++++++++------- infer/src/clang/objcInterface_decl.mli | 6 ++++-- infer/src/clang/objcMethod_decl.ml | 13 +++---------- infer/src/clang/objcMethod_decl.mli | 3 ++- 10 files changed, 62 insertions(+), 39 deletions(-) diff --git a/infer/src/clang/CType_decl.ml b/infer/src/clang/CType_decl.ml index 2b9847261..938e10e2c 100644 --- a/infer/src/clang/CType_decl.ml +++ b/infer/src/clang/CType_decl.ml @@ -460,15 +460,16 @@ and add_types_from_decl_to_tenv tenv decl = | ClassTemplateSpecializationDecl _ | CXXRecordDecl _ | RecordDecl _ -> get_record_declaration_type tenv decl | ObjCInterfaceDecl _ -> - ObjcInterface_decl.interface_declaration qual_type_to_sil_type tenv decl + ObjcInterface_decl.interface_declaration qual_type_to_sil_type procname_from_decl tenv decl | ObjCImplementationDecl _ -> - ObjcInterface_decl.interface_impl_declaration qual_type_to_sil_type tenv decl + ObjcInterface_decl.interface_impl_declaration qual_type_to_sil_type procname_from_decl tenv + decl | ObjCProtocolDecl _ -> ObjcProtocol_decl.protocol_decl qual_type_to_sil_type tenv decl | ObjCCategoryDecl _ -> - ObjcCategory_decl.category_decl qual_type_to_sil_type tenv decl + ObjcCategory_decl.category_decl qual_type_to_sil_type procname_from_decl tenv decl | ObjCCategoryImplDecl _ -> - ObjcCategory_decl.category_impl_decl qual_type_to_sil_type tenv decl + ObjcCategory_decl.category_impl_decl qual_type_to_sil_type procname_from_decl tenv decl | EnumDecl _ -> CEnum_decl.enum_decl decl | _ -> @@ -601,7 +602,7 @@ and objc_block_procname outer_proc_opt = (* TODO: get the parameters from BuildMethodSignature.get_parameters and pass it to the method names *) -and from_decl ?tenv ?outer_proc meth_decl = +and procname_from_decl ?tenv ?outer_proc meth_decl = let open Clang_ast_t in match meth_decl with | FunctionDecl (decl_info, name_info, _, fdi) -> @@ -635,7 +636,7 @@ and get_struct_methods struct_decl tenv = | CXXDestructorDecl _ | ObjCMethodDecl _ | BlockDecl _ -> - Some (from_decl ~tenv decl) + Some (procname_from_decl ~tenv decl) | _ -> None ) @@ -691,7 +692,7 @@ let method_signature_of_decl = BuildMethodSignature.method_signature_of_decl qua let should_add_return_param = BuildMethodSignature.should_add_return_param module CProcname = struct - let from_decl = from_decl + let from_decl = procname_from_decl module NoAstDecl = struct let c_function_of_string tenv name = diff --git a/infer/src/clang/cAst_utils.ml b/infer/src/clang/cAst_utils.ml index 2dc2ea488..038410f5e 100644 --- a/infer/src/clang/cAst_utils.ml +++ b/infer/src/clang/cAst_utils.ml @@ -14,6 +14,9 @@ module L = Logging type qual_type_to_sil_type = Tenv.t -> Clang_ast_t.qual_type -> Typ.t +type procname_from_decl = + ?tenv:Tenv.t -> ?outer_proc:Typ.Procname.t -> Clang_ast_t.decl -> Typ.Procname.t + let sanitize_name s = Str.global_replace (Str.regexp "[/ ]") "_" s let get_qual_name qual_name_list = diff --git a/infer/src/clang/cAst_utils.mli b/infer/src/clang/cAst_utils.mli index 8e1e02f58..f5db8c425 100644 --- a/infer/src/clang/cAst_utils.mli +++ b/infer/src/clang/cAst_utils.mli @@ -64,6 +64,9 @@ val name_opt_of_typedef_qual_type : Clang_ast_t.qual_type -> QualifiedCppName.t type qual_type_to_sil_type = Tenv.t -> Clang_ast_t.qual_type -> Typ.t +type procname_from_decl = + ?tenv:Tenv.t -> ?outer_proc:Typ.Procname.t -> Clang_ast_t.decl -> Typ.Procname.t + val qual_type_of_decl_ptr : Clang_ast_t.pointer -> Clang_ast_t.qual_type val add_type_from_decl_ref_opt : diff --git a/infer/src/clang/cFrontend_decl.ml b/infer/src/clang/cFrontend_decl.ml index 02fc4cf0a..75b42dfed 100644 --- a/infer/src/clang/cFrontend_decl.ml +++ b/infer/src/clang/cFrontend_decl.ml @@ -360,7 +360,8 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron | ObjCInterfaceDecl (_, _, decl_list, _, _) -> let curr_class = CContext.ContextClsDeclPtr dec_ptr in ignore - (ObjcInterface_decl.interface_declaration CType_decl.qual_type_to_sil_type tenv dec) ; + (ObjcInterface_decl.interface_declaration CType_decl.qual_type_to_sil_type + CType_decl.CProcname.from_decl tenv dec) ; process_methods trans_unit_ctx tenv cfg curr_class decl_list | ObjCProtocolDecl (_, _, decl_list, _, _) -> let curr_class = CContext.ContextClsDeclPtr dec_ptr in @@ -368,16 +369,22 @@ module CFrontend_decl_funct (T : CModule_type.CTranslation) : CModule_type.CFron process_methods trans_unit_ctx tenv cfg curr_class decl_list | ObjCCategoryDecl (_, _, decl_list, _, _) -> let curr_class = CContext.ContextClsDeclPtr dec_ptr in - ignore (ObjcCategory_decl.category_decl CType_decl.qual_type_to_sil_type tenv dec) ; + ignore + (ObjcCategory_decl.category_decl CType_decl.qual_type_to_sil_type + CType_decl.CProcname.from_decl tenv dec) ; process_methods trans_unit_ctx tenv cfg curr_class decl_list | ObjCCategoryImplDecl (_, _, decl_list, _, _) -> let curr_class = CContext.ContextClsDeclPtr dec_ptr in - ignore (ObjcCategory_decl.category_impl_decl CType_decl.qual_type_to_sil_type tenv dec) ; + ignore + (ObjcCategory_decl.category_impl_decl CType_decl.qual_type_to_sil_type + CType_decl.CProcname.from_decl tenv dec) ; process_methods trans_unit_ctx tenv cfg curr_class decl_list | ObjCImplementationDecl (_, _, decl_list, _, _) -> let curr_class = CContext.ContextClsDeclPtr dec_ptr in let qual_type_to_sil_type = CType_decl.qual_type_to_sil_type in - ignore (ObjcInterface_decl.interface_impl_declaration qual_type_to_sil_type tenv dec) ; + ignore + (ObjcInterface_decl.interface_impl_declaration qual_type_to_sil_type + CType_decl.CProcname.from_decl tenv dec) ; process_methods trans_unit_ctx tenv cfg curr_class decl_list | CXXMethodDecl (decl_info, _, _, _, _) | CXXConstructorDecl (decl_info, _, _, _, _) diff --git a/infer/src/clang/objcCategory_decl.ml b/infer/src/clang/objcCategory_decl.ml index 6a75c954c..a30a468ea 100644 --- a/infer/src/clang/objcCategory_decl.ml +++ b/infer/src/clang/objcCategory_decl.ml @@ -63,10 +63,10 @@ let get_base_class_name_from_category decl = (* Add potential extra fields and methods defined only in the category *) (* to the corresponding class. Update the tenv accordingly.*) -let process_category qual_type_to_sil_type tenv class_name decl_info decl_list = +let process_category qual_type_to_sil_type procname_from_decl tenv class_name decl_info decl_list = let class_tn_name = Typ.Name.Objc.from_qual_name class_name in let decl_fields = CField_decl.get_fields qual_type_to_sil_type tenv class_tn_name decl_list in - let decl_methods = ObjcMethod_decl.get_methods class_tn_name decl_list in + let decl_methods = ObjcMethod_decl.get_methods procname_from_decl tenv decl_list in let class_tn_desc = Typ.Tstruct class_tn_name in let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in CAst_utils.update_sil_types_map decl_key class_tn_desc ; @@ -84,7 +84,7 @@ let process_category qual_type_to_sil_type tenv class_name decl_info decl_list = class_tn_desc -let category_decl qual_type_to_sil_type tenv decl = +let category_decl qual_type_to_sil_type procname_from_decl tenv decl = let open Clang_ast_t in match decl with | ObjCCategoryDecl (decl_info, name_info, decl_list, _, cdi) -> @@ -92,14 +92,17 @@ let category_decl qual_type_to_sil_type tenv decl = let class_name = get_classname_from_category_decl cdi in L.(debug Capture Verbose) "ADDING: ObjCCategoryDecl for '%a'@\n" QualifiedCppName.pp name ; let _ = add_class_decl qual_type_to_sil_type tenv cdi in - let typ = process_category qual_type_to_sil_type tenv class_name decl_info decl_list in + let typ = + process_category qual_type_to_sil_type procname_from_decl tenv class_name decl_info + decl_list + in let _ = add_category_implementation qual_type_to_sil_type tenv cdi in typ | _ -> assert false -let category_impl_decl qual_type_to_sil_type tenv decl = +let category_impl_decl qual_type_to_sil_type procname_from_decl tenv decl = let open Clang_ast_t in match decl with | ObjCCategoryImplDecl (decl_info, name_info, decl_list, _, cii) -> @@ -107,7 +110,10 @@ let category_impl_decl qual_type_to_sil_type tenv decl = let class_name = get_classname_from_category_impl cii in L.(debug Capture Verbose) "ADDING: ObjCCategoryImplDecl for '%a'@\n" QualifiedCppName.pp name ; let _ = add_category_decl qual_type_to_sil_type tenv cii in - let typ = process_category qual_type_to_sil_type tenv class_name decl_info decl_list in + let typ = + process_category qual_type_to_sil_type procname_from_decl tenv class_name decl_info + decl_list + in typ | _ -> assert false diff --git a/infer/src/clang/objcCategory_decl.mli b/infer/src/clang/objcCategory_decl.mli index 62287fc85..637ceabcd 100644 --- a/infer/src/clang/objcCategory_decl.mli +++ b/infer/src/clang/objcCategory_decl.mli @@ -11,8 +11,12 @@ open! IStd (** is saved in the tenv as a struct with the corresponding fields and methods , and the class it belongs to *) -val category_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc +val category_decl : + CAst_utils.qual_type_to_sil_type -> CAst_utils.procname_from_decl -> Tenv.t -> Clang_ast_t.decl + -> Typ.desc -val category_impl_decl : CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc +val category_impl_decl : + CAst_utils.qual_type_to_sil_type -> CAst_utils.procname_from_decl -> Tenv.t -> Clang_ast_t.decl + -> Typ.desc val get_base_class_name_from_category : Clang_ast_t.decl -> Typ.Name.t option diff --git a/infer/src/clang/objcInterface_decl.ml b/infer/src/clang/objcInterface_decl.ml index 3bccb8a57..179d651c3 100644 --- a/infer/src/clang/objcInterface_decl.ml +++ b/infer/src/clang/objcInterface_decl.ml @@ -87,7 +87,8 @@ let append_no_duplicates_typ_name = (* Adds pairs (interface name, interface_type_info) to the global environment. *) -let add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list ocidi = +let add_class_to_tenv qual_type_to_sil_type procname_from_decl tenv decl_info name_info decl_list + ocidi = let class_name = CAst_utils.get_qualified_name name_info in let interface_name = Typ.Name.Objc.from_qual_name class_name in let interface_desc = Typ.Tstruct interface_name in @@ -114,7 +115,7 @@ let add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list o let all_fields = CGeneral_utils.append_no_duplicates_fields modelled_fields fields in let methods = CGeneral_utils.append_no_duplicates_methods - (ObjcMethod_decl.get_methods interface_name decl_list) + (ObjcMethod_decl.get_methods procname_from_decl tenv decl_list) methods in ignore @@ -124,11 +125,14 @@ let add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list o (* Interface_type_info has the name of instance variables and the name of methods. *) -let interface_declaration qual_type_to_sil_type tenv decl = +let interface_declaration qual_type_to_sil_type procname_from_decl tenv decl = let open Clang_ast_t in match decl with | ObjCInterfaceDecl (decl_info, name_info, decl_list, _, ocidi) -> - let typ = add_class_to_tenv qual_type_to_sil_type tenv decl_info name_info decl_list ocidi in + let typ = + add_class_to_tenv qual_type_to_sil_type procname_from_decl tenv decl_info name_info + decl_list ocidi + in let _ = add_class_implementation qual_type_to_sil_type tenv ocidi in let _ = add_super_class_decl qual_type_to_sil_type tenv ocidi in let _ = add_protocols_decl qual_type_to_sil_type tenv ocidi.Clang_ast_t.otdi_protocols in @@ -140,19 +144,18 @@ let interface_declaration qual_type_to_sil_type tenv decl = (* Translate the methods defined in the implementation.*) -let interface_impl_declaration qual_type_to_sil_type tenv decl = +let interface_impl_declaration qual_type_to_sil_type procname_from_decl tenv decl = let open Clang_ast_t in match decl with | ObjCImplementationDecl (decl_info, name_info, decl_list, _, idi) -> let class_name = CAst_utils.get_qualified_name name_info in - let interface_name = Typ.Name.Objc.from_qual_name class_name in L.(debug Capture Verbose) "ADDING: ObjCImplementationDecl for class '%a'@\n" QualifiedCppName.pp class_name ; let _ = add_class_decl qual_type_to_sil_type tenv idi in let class_tn_name = Typ.Name.Objc.from_qual_name class_name in let fields = CField_decl.get_fields qual_type_to_sil_type tenv class_tn_name decl_list in CField_decl.add_missing_fields tenv class_name fields ; - let methods = ObjcMethod_decl.get_methods interface_name decl_list in + let methods = ObjcMethod_decl.get_methods procname_from_decl tenv decl_list in ObjcMethod_decl.add_missing_methods tenv class_tn_name methods ; let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in let class_desc = Typ.Tstruct class_tn_name in diff --git a/infer/src/clang/objcInterface_decl.mli b/infer/src/clang/objcInterface_decl.mli index 48f7f1a4d..eb4e93c1c 100644 --- a/infer/src/clang/objcInterface_decl.mli +++ b/infer/src/clang/objcInterface_decl.mli @@ -11,7 +11,9 @@ open! IStd struct with the corresponding fields, potential superclass and list of defined methods *) val interface_declaration : - CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc + CAst_utils.qual_type_to_sil_type -> CAst_utils.procname_from_decl -> Tenv.t -> Clang_ast_t.decl + -> Typ.desc val interface_impl_declaration : - CAst_utils.qual_type_to_sil_type -> Tenv.t -> Clang_ast_t.decl -> Typ.desc + CAst_utils.qual_type_to_sil_type -> CAst_utils.procname_from_decl -> Tenv.t -> Clang_ast_t.decl + -> Typ.desc diff --git a/infer/src/clang/objcMethod_decl.ml b/infer/src/clang/objcMethod_decl.ml index d58e4fc66..1d99aa10b 100644 --- a/infer/src/clang/objcMethod_decl.ml +++ b/infer/src/clang/objcMethod_decl.ml @@ -8,18 +8,11 @@ open! IStd -let get_methods class_typename decl_list = - let open Clang_ast_t in +let get_methods (from_decl: CAst_utils.procname_from_decl) tenv decl_list = let get_method list_methods decl = match decl with - | Clang_ast_t.ObjCMethodDecl (_, ndi, mdi) -> - let method_kind = - Typ.Procname.ObjC_Cpp.objc_method_kind_of_bool mdi.omdi_is_instance_method - in - let method_name = - Typ.Procname.ObjC_Cpp - (Typ.Procname.ObjC_Cpp.make class_typename ndi.ni_name method_kind Typ.NoTemplate) - in + | Clang_ast_t.ObjCMethodDecl _ -> + let method_name = from_decl ~tenv decl in method_name :: list_methods | _ -> list_methods diff --git a/infer/src/clang/objcMethod_decl.mli b/infer/src/clang/objcMethod_decl.mli index 92e374365..697913a27 100644 --- a/infer/src/clang/objcMethod_decl.mli +++ b/infer/src/clang/objcMethod_decl.mli @@ -5,6 +5,7 @@ * LICENSE file in the root directory of this source tree. *) -val get_methods : Typ.name -> Clang_ast_t.decl list -> Typ.Procname.t list +val get_methods : + CAst_utils.procname_from_decl -> Tenv.t -> Clang_ast_t.decl list -> Typ.Procname.t list val add_missing_methods : Tenv.t -> Typ.name -> Typ.Procname.t list -> unit