diff --git a/infer/src/clang/CType_decl.ml b/infer/src/clang/CType_decl.ml index f65571f59..ac06d606b 100644 --- a/infer/src/clang/CType_decl.ml +++ b/infer/src/clang/CType_decl.ml @@ -11,6 +11,86 @@ open! IStd (** Processes types and record declarations by adding them to the tenv *) +let get_struct_decls decl = + let open Clang_ast_t in + match decl with + | CapturedDecl (_, decl_list, _) + | ClassTemplateSpecializationDecl (_, _, _, decl_list, _, _, _, _, _, _) + | ClassTemplatePartialSpecializationDecl (_, _, _, decl_list, _, _, _, _, _, _) + | CXXRecordDecl (_, _, _, decl_list, _, _, _, _) + | EnumDecl (_, _, _, decl_list, _, _, _) + | LinkageSpecDecl (_, decl_list, _) + | NamespaceDecl (_, _, decl_list, _, _) + | ObjCCategoryDecl (_, _, decl_list, _, _) + | ObjCCategoryImplDecl (_, _, decl_list, _, _) + | ObjCImplementationDecl (_, _, decl_list, _, _) + | ObjCInterfaceDecl (_, _, decl_list, _, _) + | ObjCProtocolDecl (_, _, decl_list, _, _) + | RecordDecl (_, _, _, decl_list, _, _, _) + | TranslationUnitDecl (_, decl_list, _, _) -> + decl_list + | AccessSpecDecl _ + | BlockDecl _ + | ClassScopeFunctionSpecializationDecl _ + | EmptyDecl _ + | ExportDecl _ + | ExternCContextDecl _ + | FileScopeAsmDecl _ + | FriendDecl _ + | FriendTemplateDecl _ + | ImportDecl _ + | LabelDecl _ + | NamespaceAliasDecl _ + | ObjCCompatibleAliasDecl _ + | ObjCMethodDecl _ + | ObjCPropertyDecl _ + | BuiltinTemplateDecl _ + | ClassTemplateDecl _ + | FunctionTemplateDecl _ + | TypeAliasTemplateDecl _ + | VarTemplateDecl _ + | TemplateTemplateParmDecl _ + | TemplateTypeParmDecl _ + | ObjCTypeParamDecl _ + | TypeAliasDecl _ + | TypedefDecl _ + | UnresolvedUsingTypenameDecl _ + | UsingDecl _ + | UsingDirectiveDecl _ + | UsingPackDecl _ + | UsingShadowDecl _ + | ConstructorUsingShadowDecl _ + | BindingDecl _ + | FieldDecl _ + | ObjCAtDefsFieldDecl _ + | ObjCIvarDecl _ + | FunctionDecl _ + | CXXDeductionGuideDecl _ + | CXXMethodDecl _ + | CXXConstructorDecl _ + | CXXConversionDecl _ + | CXXDestructorDecl _ + | MSPropertyDecl _ + | NonTypeTemplateParmDecl _ + | VarDecl _ + | DecompositionDecl _ + | ImplicitParamDecl _ + | OMPCapturedExprDecl _ + | ParmVarDecl _ + | VarTemplateSpecializationDecl _ + | VarTemplatePartialSpecializationDecl _ + | EnumConstantDecl _ + | IndirectFieldDecl _ + | OMPDeclareReductionDecl _ + | UnresolvedUsingValueDecl _ + | OMPThreadPrivateDecl _ + | ObjCPropertyImplDecl _ + | PragmaCommentDecl _ + | PragmaDetectMismatchDecl _ + | StaticAssertDecl _ -> + [] + + let add_predefined_objc_types tenv = ignore (Tenv.mk_struct tenv (CType_to_sil_type.get_builtin_objc_typename `ObjCClass)) ; ignore (Tenv.mk_struct tenv (CType_to_sil_type.get_builtin_objc_typename `ObjCId)) @@ -102,84 +182,52 @@ let get_record_definition decl = decl -let get_struct_decls decl = +let is_decl_info_generic_model {Clang_ast_t.di_attributes} = + let f = function + | Clang_ast_t.AnnotateAttr {ai_parameters= [_; name; _]} + when String.equal name "__infer_generic_model" -> + true + | _ -> + false + in + List.exists ~f di_attributes + + +(** Global counter for anonymous block*) +let block_counter = ref 0 + +let get_fresh_block_index () = + block_counter := !block_counter + 1 ; + !block_counter + + +let mk_objc_method class_typename method_name method_kind = + Typ.Procname.ObjC_Cpp + (Typ.Procname.ObjC_Cpp.make class_typename method_name method_kind Typ.NoTemplate + ~is_generic_model:false) + + +let rec get_mangled_method_name function_decl_info method_decl_info = + (* For virtual methods return mangled name of the method from most base class + Go recursively until there is no method in any parent class. All names + of the same method need to be the same, otherwise dynamic dispatch won't + work. *) let open Clang_ast_t in - match decl with - | CapturedDecl (_, decl_list, _) - | ClassTemplateSpecializationDecl (_, _, _, decl_list, _, _, _, _, _, _) - | ClassTemplatePartialSpecializationDecl (_, _, _, decl_list, _, _, _, _, _, _) - | CXXRecordDecl (_, _, _, decl_list, _, _, _, _) - | EnumDecl (_, _, _, decl_list, _, _, _) - | LinkageSpecDecl (_, decl_list, _) - | NamespaceDecl (_, _, decl_list, _, _) - | ObjCCategoryDecl (_, _, decl_list, _, _) - | ObjCCategoryImplDecl (_, _, decl_list, _, _) - | ObjCImplementationDecl (_, _, decl_list, _, _) - | ObjCInterfaceDecl (_, _, decl_list, _, _) - | ObjCProtocolDecl (_, _, decl_list, _, _) - | RecordDecl (_, _, _, decl_list, _, _, _) - | TranslationUnitDecl (_, decl_list, _, _) -> - decl_list - | AccessSpecDecl _ - | BlockDecl _ - | ClassScopeFunctionSpecializationDecl _ - | EmptyDecl _ - | ExportDecl _ - | ExternCContextDecl _ - | FileScopeAsmDecl _ - | FriendDecl _ - | FriendTemplateDecl _ - | ImportDecl _ - | LabelDecl _ - | NamespaceAliasDecl _ - | ObjCCompatibleAliasDecl _ - | ObjCMethodDecl _ - | ObjCPropertyDecl _ - | BuiltinTemplateDecl _ - | ClassTemplateDecl _ - | FunctionTemplateDecl _ - | TypeAliasTemplateDecl _ - | VarTemplateDecl _ - | TemplateTemplateParmDecl _ - | TemplateTypeParmDecl _ - | ObjCTypeParamDecl _ - | TypeAliasDecl _ - | TypedefDecl _ - | UnresolvedUsingTypenameDecl _ - | UsingDecl _ - | UsingDirectiveDecl _ - | UsingPackDecl _ - | UsingShadowDecl _ - | ConstructorUsingShadowDecl _ - | BindingDecl _ - | FieldDecl _ - | ObjCAtDefsFieldDecl _ - | ObjCIvarDecl _ - | FunctionDecl _ - | CXXDeductionGuideDecl _ - | CXXMethodDecl _ - | CXXConstructorDecl _ - | CXXConversionDecl _ - | CXXDestructorDecl _ - | MSPropertyDecl _ - | NonTypeTemplateParmDecl _ - | VarDecl _ - | DecompositionDecl _ - | ImplicitParamDecl _ - | OMPCapturedExprDecl _ - | ParmVarDecl _ - | VarTemplateSpecializationDecl _ - | VarTemplatePartialSpecializationDecl _ - | EnumConstantDecl _ - | IndirectFieldDecl _ - | OMPDeclareReductionDecl _ - | UnresolvedUsingValueDecl _ - | OMPThreadPrivateDecl _ - | ObjCPropertyImplDecl _ - | PragmaCommentDecl _ - | PragmaDetectMismatchDecl _ - | StaticAssertDecl _ -> - [] + match method_decl_info.xmdi_overriden_methods with + | [] -> + function_decl_info.fdi_mangled_name + | base1_dr :: _ -> + let base1 = + match CAst_utils.get_decl base1_dr.dr_decl_pointer with Some b -> b | _ -> assert false + in + match base1 with + | CXXMethodDecl (_, _, _, fdi, mdi) + | CXXConstructorDecl (_, _, _, fdi, mdi) + | CXXConversionDecl (_, _, _, fdi, mdi) + | CXXDestructorDecl (_, _, _, fdi, mdi) -> + get_mangled_method_name fdi mdi + | _ -> + assert false let rec get_struct_fields tenv decl = @@ -293,49 +341,6 @@ and get_superclass_list_cpp tenv decl = List.map ~f:get_super_field base_decls -and get_record_struct_type tenv definition_decl : Typ.desc = - let open Clang_ast_t in - match definition_decl with - | ClassTemplateSpecializationDecl (_, _, type_ptr, _, _, _, record_decl_info, _, _, _) - | CXXRecordDecl (_, _, type_ptr, _, _, _, record_decl_info, _) - | RecordDecl (_, _, type_ptr, _, _, _, record_decl_info) - -> ( - let sil_typename = get_record_typename ~tenv definition_decl in - let sil_desc = Typ.Tstruct sil_typename in - match Tenv.lookup tenv sil_typename with - | Some _ -> - sil_desc (* just reuse what is already in tenv *) - | None -> - let is_translatable_definition = - let open Clang_ast_t in - record_decl_info.rdi_is_complete_definition - && not record_decl_info.rdi_is_dependent_type - in - if is_translatable_definition then ( - CAst_utils.update_sil_types_map type_ptr sil_desc ; - let fields = get_struct_fields tenv definition_decl in - let statics = [] in - (* Note: We treat static field same as global variables *) - let methods = [] in - (* C++ methods are not put into tenv (info isn't used) *) - let supers = get_superclass_list_cpp tenv definition_decl in - let annots = - if Typ.Name.Cpp.is_class sil_typename then Annot.Class.cpp - else (* No annotations for structs *) Annot.Item.empty - in - Tenv.mk_struct tenv ~fields ~statics ~methods ~supers ~annots sil_typename |> ignore ; - CAst_utils.update_sil_types_map type_ptr sil_desc ; - sil_desc ) - else ( - (* There is no definition for that struct in whole translation unit. - Put empty struct into tenv to prevent backend problems *) - ignore (Tenv.mk_struct tenv ~fields:[] sil_typename) ; - CAst_utils.update_sil_types_map type_ptr sil_desc ; - sil_desc ) ) - | _ -> - assert false - - and add_types_from_decl_to_tenv tenv decl = let open Clang_ast_t in match decl with @@ -379,147 +384,204 @@ and qual_type_to_sil_type tenv qual_type = CType_to_sil_type.qual_type_to_sil_type add_types_from_decl_to_tenv tenv qual_type -module CProcname = struct - let rec get_mangled_method_name function_decl_info method_decl_info = - (* For virtual methods return mangled name of the method from most base class - Go recursively until there is no method in any parent class. All names - of the same method need to be the same, otherwise dynamic dispatch won't - work. *) - let open Clang_ast_t in - match method_decl_info.xmdi_overriden_methods with - | [] -> - function_decl_info.fdi_mangled_name - | base1_dr :: _ -> - let base1 = - match CAst_utils.get_decl base1_dr.dr_decl_pointer with Some b -> b | _ -> assert false - in - match base1 with - | CXXMethodDecl (_, _, _, fdi, mdi) - | CXXConstructorDecl (_, _, _, fdi, mdi) - | CXXConversionDecl (_, _, _, fdi, mdi) - | CXXDestructorDecl (_, _, _, fdi, mdi) -> - get_mangled_method_name fdi mdi - | _ -> - assert false - - - let get_template_info tenv (fdi: Clang_ast_t.function_decl_info) = - match fdi.fdi_template_specialization with - | Some spec_info -> - Typ.Template {mangled= fdi.fdi_mangled_name; args= get_template_args tenv spec_info} - | None -> - Typ.NoTemplate +and get_template_info tenv (fdi: Clang_ast_t.function_decl_info) = + match fdi.fdi_template_specialization with + | Some spec_info -> + Typ.Template {mangled= fdi.fdi_mangled_name; args= get_template_args tenv spec_info} + | None -> + Typ.NoTemplate - let is_decl_info_generic_model {Clang_ast_t.di_attributes} = - let f = function - | Clang_ast_t.AnnotateAttr {ai_parameters= [_; name; _]} - when String.equal name "__infer_generic_model" -> - true - | _ -> - false - in - List.exists ~f di_attributes - - - let mk_c_function ?tenv ~is_cpp name function_decl_info_opt = - let file = - match function_decl_info_opt with - | Some (decl_info, function_decl_info) -> ( - match function_decl_info.Clang_ast_t.fdi_storage_class with - | Some "static" - (* when we model static functions, we cannot take the file into account to +and mk_c_function ?tenv ~is_cpp name function_decl_info_opt = + let file = + match function_decl_info_opt with + | Some (decl_info, function_decl_info) -> ( + match function_decl_info.Clang_ast_t.fdi_storage_class with + | Some "static" + (* when we model static functions, we cannot take the file into account to create a mangled name because the file of the model is different to the real file, thus the model won't work *) - when not - (CTrans_models.is_modelled_static_function (QualifiedCppName.to_qual_string name)) -> - let file_opt = - (fst decl_info.Clang_ast_t.di_source_range).Clang_ast_t.sl_file - |> Option.map ~f:SourceFile.from_abs_path - in - let file_to_hex src = SourceFile.to_string src |> Utils.string_crc_hex32 in - Option.value_map ~f:file_to_hex ~default:"" file_opt - | _ -> - "" ) - | None -> - "" - in - let mangled_opt = - match function_decl_info_opt with - | Some (_, function_decl_info) -> - function_decl_info.Clang_ast_t.fdi_mangled_name - | _ -> - None - in - let mangled_name = match mangled_opt with Some m when is_cpp -> m | _ -> "" in - let template_info, is_generic_model = - match (function_decl_info_opt, tenv) with - | Some (decl_info, function_decl_info), Some t -> - (get_template_info t function_decl_info, is_decl_info_generic_model decl_info) + when not (CTrans_models.is_modelled_static_function (QualifiedCppName.to_qual_string name)) -> + let file_opt = + (fst decl_info.Clang_ast_t.di_source_range).Clang_ast_t.sl_file + |> Option.map ~f:SourceFile.from_abs_path + in + let file_to_hex src = SourceFile.to_string src |> Utils.string_crc_hex32 in + Option.value_map ~f:file_to_hex ~default:"" file_opt | _ -> - (Typ.NoTemplate, false) - in - let mangled = file ^ mangled_name in - if String.is_empty mangled then - Typ.Procname.from_string_c_fun (QualifiedCppName.to_qual_string name) - else Typ.Procname.C (Typ.Procname.c name mangled template_info ~is_generic_model) + "" ) + | None -> + "" + in + let mangled_opt = + match function_decl_info_opt with + | Some (_, function_decl_info) -> + function_decl_info.Clang_ast_t.fdi_mangled_name + | _ -> + None + in + let mangled_name = match mangled_opt with Some m when is_cpp -> m | _ -> "" in + let template_info, is_generic_model = + match (function_decl_info_opt, tenv) with + | Some (decl_info, function_decl_info), Some t -> + (get_template_info t function_decl_info, is_decl_info_generic_model decl_info) + | _ -> + (Typ.NoTemplate, false) + in + let mangled = file ^ mangled_name in + if String.is_empty mangled then + Typ.Procname.from_string_c_fun (QualifiedCppName.to_qual_string name) + else Typ.Procname.C (Typ.Procname.c name mangled template_info ~is_generic_model) - let mk_cpp_method ?tenv class_name method_name ?meth_decl mangled = - let open Clang_ast_t in - let method_kind = - match meth_decl with - | Some (Clang_ast_t.CXXConstructorDecl (_, _, _, _, {xmdi_is_constexpr})) -> - Typ.Procname.ObjC_Cpp.CPPConstructor {mangled; is_constexpr= xmdi_is_constexpr} - | Some (Clang_ast_t.CXXDestructorDecl _) -> - Typ.Procname.ObjC_Cpp.CPPDestructor {mangled} - | _ -> - Typ.Procname.ObjC_Cpp.CPPMethod {mangled} - in - let template_info, is_generic_model = - match meth_decl with - | Some (CXXMethodDecl (di, _, _, fdi, _)) - | Some (CXXConstructorDecl (di, _, _, fdi, _)) - | Some (CXXConversionDecl (di, _, _, fdi, _)) - | Some (CXXDestructorDecl (di, _, _, fdi, _)) -> - let templ_info = - match tenv with Some t -> get_template_info t fdi | None -> Typ.NoTemplate - in - let is_gen_model = - is_decl_info_generic_model di - || (* read whether parent class is annoatated as generic model *) - di.di_parent_pointer |> Option.value_map ~f:CAst_utils.get_decl ~default:None - |> Option.map ~f:Clang_ast_proj.get_decl_tuple - |> Option.value_map ~f:is_decl_info_generic_model ~default:false - in - (templ_info, is_gen_model) - | _ -> - (Typ.NoTemplate, false) - in - Typ.Procname.ObjC_Cpp - (Typ.Procname.ObjC_Cpp.make class_name method_name method_kind template_info - ~is_generic_model) +and mk_cpp_method ?tenv class_name method_name ?meth_decl mangled = + let open Clang_ast_t in + let method_kind = + match meth_decl with + | Some (Clang_ast_t.CXXConstructorDecl (_, _, _, _, {xmdi_is_constexpr})) -> + Typ.Procname.ObjC_Cpp.CPPConstructor {mangled; is_constexpr= xmdi_is_constexpr} + | Some (Clang_ast_t.CXXDestructorDecl _) -> + Typ.Procname.ObjC_Cpp.CPPDestructor {mangled} + | _ -> + Typ.Procname.ObjC_Cpp.CPPMethod {mangled} + in + let template_info, is_generic_model = + match meth_decl with + | Some (CXXMethodDecl (di, _, _, fdi, _)) + | Some (CXXConstructorDecl (di, _, _, fdi, _)) + | Some (CXXConversionDecl (di, _, _, fdi, _)) + | Some (CXXDestructorDecl (di, _, _, fdi, _)) -> + let templ_info = + match tenv with Some t -> get_template_info t fdi | None -> Typ.NoTemplate + in + let is_gen_model = + is_decl_info_generic_model di + || (* read whether parent class is annoatated as generic model *) + di.di_parent_pointer |> Option.value_map ~f:CAst_utils.get_decl ~default:None + |> Option.map ~f:Clang_ast_proj.get_decl_tuple + |> Option.value_map ~f:is_decl_info_generic_model ~default:false + in + (templ_info, is_gen_model) + | _ -> + (Typ.NoTemplate, false) + in + Typ.Procname.ObjC_Cpp + (Typ.Procname.ObjC_Cpp.make class_name method_name method_kind template_info ~is_generic_model) + +and get_class_typename ?tenv 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 -> + get_record_typename ?tenv class_decl + | None -> + CFrontend_config.incorrect_assumption __POS__ method_decl_info.Clang_ast_t.di_source_range + "Expecting class declaration when getting the class typename" - let mk_objc_method class_typename method_name method_kind = - Typ.Procname.ObjC_Cpp - (Typ.Procname.ObjC_Cpp.make class_typename method_name method_kind Typ.NoTemplate - ~is_generic_model:false) +and objc_method_procname ?tenv decl_info method_name mdi = + let class_typename = get_class_typename ?tenv decl_info in + let is_instance = mdi.Clang_ast_t.omdi_is_instance_method in + let method_kind = Typ.Procname.ObjC_Cpp.objc_method_kind_of_bool is_instance in + mk_objc_method class_typename method_name method_kind - let block_procname_with_index defining_proc i = - Config.anonymous_block_prefix ^ Typ.Procname.to_string defining_proc - ^ Config.anonymous_block_num_sep ^ string_of_int i +and from_decl ?tenv ~is_cpp meth_decl = + let open Clang_ast_t in + match meth_decl with + | FunctionDecl (decl_info, name_info, _, fdi) -> + let name = CAst_utils.get_qualified_name name_info in + let function_info = Some (decl_info, fdi) in + mk_c_function ~is_cpp ?tenv name function_info + | 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_typename = get_class_typename ?tenv decl_info in + mk_cpp_method ?tenv class_typename method_name ~meth_decl mangled + | ObjCMethodDecl (decl_info, name_info, mdi) -> + objc_method_procname ?tenv decl_info name_info.Clang_ast_t.ni_name mdi + | BlockDecl _ -> + let name = + Config.anonymous_block_prefix ^ Config.anonymous_block_num_sep + ^ string_of_int (get_fresh_block_index ()) + in + Typ.Procname.mangled_objc_block name + | _ -> + Logging.die InternalError "Expected method decl, but got %s." + (Clang_ast_proj.get_decl_kind_string meth_decl) + + +and get_struct_methods struct_decl tenv = + let open Clang_ast_t in + List.filter_map (get_struct_decls struct_decl) ~f:(fun decl -> + match decl with + | FunctionDecl _ + | CXXMethodDecl _ + | CXXConstructorDecl _ + | CXXConversionDecl _ + | CXXDestructorDecl _ + | ObjCMethodDecl _ + | BlockDecl _ -> + Some (from_decl ~is_cpp:true ~tenv decl) + | _ -> + None ) + + +and get_record_struct_type tenv definition_decl : Typ.desc = + let open Clang_ast_t in + match definition_decl with + | ClassTemplateSpecializationDecl (_, _, type_ptr, _, _, _, record_decl_info, _, _, _) + | CXXRecordDecl (_, _, type_ptr, _, _, _, record_decl_info, _) + | RecordDecl (_, _, type_ptr, _, _, _, record_decl_info) + -> ( + let sil_typename = get_record_typename ~tenv definition_decl in + let sil_desc = Typ.Tstruct sil_typename in + match Tenv.lookup tenv sil_typename with + | Some _ -> + sil_desc (* just reuse what is already in tenv *) + | None -> + let is_translatable_definition = + let open Clang_ast_t in + record_decl_info.rdi_is_complete_definition + && not record_decl_info.rdi_is_dependent_type + in + if is_translatable_definition then ( + CAst_utils.update_sil_types_map type_ptr sil_desc ; + let fields = get_struct_fields tenv definition_decl in + (* Note: We treat static field same as global variables *) + let statics = [] in + let methods = get_struct_methods definition_decl tenv in + let supers = get_superclass_list_cpp tenv definition_decl in + let annots = + if Typ.Name.Cpp.is_class sil_typename then Annot.Class.cpp + else (* No annotations for structs *) Annot.Item.empty + in + Tenv.mk_struct tenv ~fields ~statics ~methods ~supers ~annots sil_typename |> ignore ; + CAst_utils.update_sil_types_map type_ptr sil_desc ; + sil_desc ) + else ( + (* There is no definition for that struct in whole translation unit. + Put empty struct into tenv to prevent backend problems *) + ignore (Tenv.mk_struct tenv ~fields:[] sil_typename) ; + CAst_utils.update_sil_types_map type_ptr sil_desc ; + sil_desc ) ) + | _ -> + assert false + + +module CProcname = struct + let from_decl = from_decl - (** Global counter for anonymous block*) - let block_counter = ref 0 + (* silly, but required to avoid circular dependencies *) let reset_block_counter () = block_counter := 0 - let get_fresh_block_index () = - block_counter := !block_counter + 1 ; - !block_counter + let block_procname_with_index defining_proc i = + Config.anonymous_block_prefix ^ Typ.Procname.to_string defining_proc + ^ Config.anonymous_block_num_sep ^ string_of_int i let mk_fresh_block_procname defining_proc = @@ -527,16 +589,6 @@ module CProcname = struct Typ.Procname.mangled_objc_block name - let get_class_typename ?tenv 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 -> - get_record_typename ?tenv class_decl - | None -> - CFrontend_config.incorrect_assumption __POS__ method_decl_info.Clang_ast_t.di_source_range - "Expecting class declaration when getting the class typename" - - module NoAstDecl = struct let c_function_of_string ~is_cpp tenv name = let qual_name = QualifiedCppName.of_qual_string name in @@ -551,41 +603,6 @@ module CProcname = struct mk_objc_method class_name method_name method_kind end - let objc_method_procname ?tenv decl_info method_name mdi = - let class_typename = get_class_typename ?tenv decl_info in - let is_instance = mdi.Clang_ast_t.omdi_is_instance_method in - let method_kind = Typ.Procname.ObjC_Cpp.objc_method_kind_of_bool is_instance in - mk_objc_method class_typename method_name method_kind - - - let from_decl ?tenv ~is_cpp meth_decl = - let open Clang_ast_t in - match meth_decl with - | FunctionDecl (decl_info, name_info, _, fdi) -> - let name = CAst_utils.get_qualified_name name_info in - let function_info = Some (decl_info, fdi) in - mk_c_function ~is_cpp ?tenv name function_info - | 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_typename = get_class_typename ?tenv decl_info in - mk_cpp_method ?tenv class_typename method_name ~meth_decl mangled - | ObjCMethodDecl (decl_info, name_info, mdi) -> - objc_method_procname ?tenv decl_info name_info.Clang_ast_t.ni_name mdi - | BlockDecl _ -> - let name = - Config.anonymous_block_prefix ^ Config.anonymous_block_num_sep - ^ string_of_int (get_fresh_block_index ()) - in - Typ.Procname.mangled_objc_block name - | _ -> - Logging.die InternalError "Expected method decl, but got %s." - (Clang_ast_proj.get_decl_kind_string meth_decl) - - let from_decl_for_linters ~is_cpp method_decl = let open Clang_ast_t in match method_decl with