diff --git a/infer/src/clang/cContext.ml b/infer/src/clang/cContext.ml index c618df8b4..6fef8499f 100644 --- a/infer/src/clang/cContext.ml +++ b/infer/src/clang/cContext.ml @@ -19,6 +19,7 @@ type curr_class = (*class name and name of (optional) super class , and a list of protocols *) | ContextCategory of string * string (* category name and corresponding class *) | ContextProtocol of string (* category name and corresponding class *) + | ContextClsDeclPtr of Clang_ast_t.pointer | ContextNoCls type str_node_map = (string, Cfg.Node.t) Hashtbl.t @@ -83,8 +84,14 @@ let get_curr_class_name curr_class = | ContextCls (name, _, _) -> name | ContextCategory (_, cls) -> cls | ContextProtocol name -> name + | ContextClsDeclPtr _ -> assert false | ContextNoCls -> assert false +let get_curr_class_decl_ptr curr_class = + match curr_class with + | ContextClsDeclPtr ptr -> ptr + | _ -> assert false + let curr_class_to_string curr_class = match curr_class with | ContextCls (name, superclass, protocols) -> @@ -92,6 +99,7 @@ let curr_class_to_string curr_class = ", protocols: " ^ (IList.to_string (fun x -> x) protocols)) | ContextCategory (name, cls) -> ("category " ^ name ^ " of class " ^ cls) | ContextProtocol name -> ("protocol " ^ name) + | ContextClsDeclPtr ptr -> ("decl_ptr: " ^ string_of_int ptr) | ContextNoCls -> "no class" let curr_class_compare curr_class1 curr_class2 = @@ -108,18 +116,15 @@ let curr_class_compare curr_class1 curr_class2 = String.compare name1 name2 | ContextProtocol _, _ -> -1 | _, ContextProtocol _ -> 1 + | ContextClsDeclPtr ptr1, ContextClsDeclPtr ptr2 -> + ptr1 - ptr2 + | ContextClsDeclPtr _, _ -> -1 + | _, ContextClsDeclPtr _ -> 1 | ContextNoCls, ContextNoCls -> 0 let curr_class_equal curr_class1 curr_class2 = curr_class_compare curr_class1 curr_class2 == 0 -let curr_class_hash curr_class = - match curr_class with - | ContextCls (name, _, _) -> Hashtbl.hash name - | ContextCategory (name, cls) -> Hashtbl.hash (name, cls) - | ContextProtocol name -> Hashtbl.hash name - | ContextNoCls -> Hashtbl.hash "no class" - let create_curr_class tenv class_name ck = let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in match Tenv.lookup tenv class_tn_name with @@ -158,4 +163,3 @@ let rec get_outer_procname context = match context.outer_context with | Some outer_context -> get_outer_procname outer_context | None -> Cfg.Procdesc.get_proc_name context.procdesc - diff --git a/infer/src/clang/cContext.mli b/infer/src/clang/cContext.mli index ad5f221a2..0ea896e75 100644 --- a/infer/src/clang/cContext.mli +++ b/infer/src/clang/cContext.mli @@ -17,6 +17,7 @@ type curr_class = (*class name and name of (optional) super class , and a list of protocols *) | ContextCategory of string * string (* category name and corresponding class *) | ContextProtocol of string (* category name and corresponding class *) + | ContextClsDeclPtr of Clang_ast_t.pointer | ContextNoCls type str_node_map = (string, Cfg.Node.t) Hashtbl.t @@ -46,14 +47,14 @@ val get_curr_class : t -> curr_class val get_curr_class_name : curr_class -> string +val get_curr_class_decl_ptr : curr_class -> Clang_ast_t.pointer + val curr_class_to_string : curr_class -> string val curr_class_compare : curr_class -> curr_class -> int val curr_class_equal : curr_class -> curr_class -> bool -val curr_class_hash : curr_class -> int - val is_objc_method : t -> bool val get_tenv : t -> Tenv.t diff --git a/infer/src/clang/cFrontend_decl.ml b/infer/src/clang/cFrontend_decl.ml index 137c7413a..7e114933d 100644 --- a/infer/src/clang/cFrontend_decl.ml +++ b/infer/src/clang/cFrontend_decl.ml @@ -213,16 +213,12 @@ struct | CXXConversionDecl (decl_info, _, _, _, _) | CXXDestructorDecl (decl_info, _, _, _, _) -> (* di_parent_pointer has pointer to lexical context such as class.*) - let class_decl = match decl_info.Clang_ast_t.di_parent_pointer with - | Some ptr -> - Ast_utils.get_decl ptr - | None -> - assert false in + let parent_ptr = Option.get decl_info.Clang_ast_t.di_parent_pointer in + let class_decl = Ast_utils.get_decl parent_ptr in (match class_decl with - | Some (CXXRecordDecl _ as d) - | Some (ClassTemplateSpecializationDecl _ as d) -> - let class_name = CTypes_decl.get_record_name d in - let curr_class = CContext.ContextCls(class_name, None, []) in + | Some (CXXRecordDecl _) + | Some (ClassTemplateSpecializationDecl _) -> + let curr_class = CContext.ContextClsDeclPtr parent_ptr in if Config.cxx_experimental then process_methods tenv cg cfg curr_class [dec] | Some dec -> diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index b9ffb1180..07b1d6131 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -30,8 +30,8 @@ type method_call_type = type function_method_decl_info = | Func_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.type_ptr * Config.clang_lang - | Cpp_Meth_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.cxx_method_decl_info * string * Clang_ast_t.type_ptr - | ObjC_Meth_decl_info of Clang_ast_t.obj_c_method_decl_info * string + | Cpp_Meth_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.cxx_method_decl_info * Clang_ast_t.pointer * Clang_ast_t.type_ptr + | ObjC_Meth_decl_info of Clang_ast_t.obj_c_method_decl_info * Clang_ast_t.pointer | Block_decl_info of Clang_ast_t.block_decl_info * Clang_ast_t.type_ptr * CContext.t let is_instance_method function_method_decl_info = @@ -52,11 +52,11 @@ let get_original_return_type function_method_decl_info = let get_class_param function_method_decl_info = if (is_instance_method function_method_decl_info) then match function_method_decl_info with - | Cpp_Meth_decl_info (_, _, class_name, _) -> - let class_type = Ast_expressions.create_class_type (class_name, `CPP) in + | Cpp_Meth_decl_info (_, _, class_decl_ptr, _) -> + let class_type = `DeclPtr class_decl_ptr in [(Mangled.from_string CFrontend_config.this, class_type)] - | ObjC_Meth_decl_info (_, class_name) -> - let class_type = Ast_expressions.create_class_type (class_name, `OBJC) in + | ObjC_Meth_decl_info (_, class_decl_ptr) -> + let class_type = `DeclPtr class_decl_ptr in [(Mangled.from_string CFrontend_config.self, class_type)] | _ -> [] else [] @@ -181,7 +181,8 @@ let method_signature_of_decl tenv meth_decl block_data_opt = let method_name = Ast_utils.get_unqualified_name name_info in let class_name = Ast_utils.get_class_name_from_member name_info in let procname = General_utils.mk_procname_from_cpp_method class_name method_name tp in - let method_decl = Cpp_Meth_decl_info (fdi, mdi, class_name, tp) in + let parent_ptr = Option.get decl_info.di_parent_pointer in + let method_decl = Cpp_Meth_decl_info (fdi, mdi, parent_ptr, tp) in let parent_pointer = decl_info.Clang_ast_t.di_parent_pointer in let ms = build_method_signature tenv decl_info procname method_decl parent_pointer None in let non_null_instrs = get_assume_not_null_calls fdi.Clang_ast_t.fdi_parameters in @@ -190,7 +191,8 @@ let method_signature_of_decl tenv meth_decl block_data_opt = | ObjCMethodDecl (decl_info, name_info, mdi), _ -> let class_name = Ast_utils.get_class_name_from_member name_info in let procname = get_objc_method_name name_info mdi class_name in - let method_decl = ObjC_Meth_decl_info (mdi, class_name) in + let parent_ptr = Option.get decl_info.di_parent_pointer in + let method_decl = ObjC_Meth_decl_info (mdi, parent_ptr) in let parent_pointer = decl_info.Clang_ast_t.di_parent_pointer in let pointer_to_property_opt = match mdi.Clang_ast_t.omdi_property_decl with @@ -252,6 +254,7 @@ let get_superclass_curr_class_objc context = | CContext.ContextCategory (_, cls) -> retrive_super cls None | CContext.ContextNoCls + | CContext.ContextClsDeclPtr _ | CContext.ContextProtocol _ -> assert false (* Gets the class name from a method signature found by clang, if search is successful *) diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index 6a3254509..a46a32b47 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -2610,7 +2610,7 @@ struct (* an input parameter. *) and cxx_constructor_init_trans ctor_init trans_state = (*let tenv = trans_state.context.CContext.tenv in*) - let class_name = CContext.get_curr_class_name trans_state.context.CContext.curr_class in + let class_ptr = CContext.get_curr_class_decl_ptr trans_state.context.CContext.curr_class in let source_range = ctor_init.Clang_ast_t.xci_source_range in let sil_loc = CLocation.get_sil_location_from_range source_range true in (* its pointer will be used in PriorityNode *) @@ -2619,8 +2619,7 @@ struct let child_stmt_info = { (Ast_expressions.dummy_stmt_info ()) with Clang_ast_t.si_source_range = source_range } in let trans_state' = PriorityNode.try_claim_priority_node trans_state this_stmt_info in - let class_type_ptr = Ast_expressions.create_pointer_type - (Ast_expressions.create_class_type (class_name, `CPP)) in + let class_type_ptr = Ast_expressions.create_pointer_type (`DeclPtr class_ptr) in let this_res_trans = this_expr_trans trans_state' sil_loc class_type_ptr in let var_res_trans = match ctor_init.Clang_ast_t.xci_subject with | `Delegating _ | `BaseClass _ ->