[clang] combine CProcname and CType_decl

Summary:
Needed to prevent a circular dependency between `CProcname` and `CType_decl`.
An upcoming diff will introduce a function for getting all the methods from a struct that requires both modules.

Reviewed By: dulmarod

Differential Revision: D7813367

fbshipit-source-id: b049d36
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent ff23aca725
commit 8a57575188

@ -1,230 +0,0 @@
(*
* Copyright (c) 2017 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! IStd
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= CType_decl.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
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)
| _ ->
(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)
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 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
(** Global counter for anonymous block*)
let block_counter = ref 0
let reset_block_counter () = block_counter := 0
let get_fresh_block_index () =
block_counter := !block_counter + 1 ;
!block_counter
let mk_fresh_block_procname defining_proc =
let name = block_procname_with_index defining_proc (get_fresh_block_index ()) in
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 ->
CType_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
mk_c_function ~is_cpp ~tenv qual_name None
let cpp_method_of_string tenv class_name method_name =
mk_cpp_method ~tenv class_name method_name None
let objc_method_of_string_kind class_name method_name method_kind =
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
| ObjCMethodDecl (decl_info, name_info, mdi) ->
let method_name =
match String.split ~on:':' name_info.Clang_ast_t.ni_name with
| hd :: _ ->
hd
| _ ->
name_info.Clang_ast_t.ni_name
in
objc_method_procname decl_info method_name mdi
| _ ->
from_decl ~is_cpp method_decl

@ -1,36 +0,0 @@
(*
* Copyright (c) 2017 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! IStd
val from_decl : ?tenv:Tenv.t -> is_cpp:bool -> Clang_ast_t.decl -> Typ.Procname.t
(** Given decl, return its procname. This function should be used for all procedures
present in original AST *)
val from_decl_for_linters : is_cpp:bool -> Clang_ast_t.decl -> Typ.Procname.t
(** This is used for bug hashing for linters. In ObjC the method names contain the parameter names,
thus if people add new parameters, any bug about the method will be considered different which means
reporting on unchanged code. So, in the ObjC method case, we create the method name only based on the
first part of the name without the parameters *)
(** WARNING: functions from this module should not be used if full decl is available in AST *)
module NoAstDecl : sig
val c_function_of_string : is_cpp:bool -> Tenv.t -> string -> Typ.Procname.t
val cpp_method_of_string : Tenv.t -> Typ.Name.t -> string -> Typ.Procname.t
val objc_method_of_string_kind :
Typ.Name.t -> string -> Typ.Procname.ObjC_Cpp.kind -> Typ.Procname.t
end
val mk_fresh_block_procname : Typ.Procname.t -> Typ.Procname.t
(** Makes a fresh name for a block defined inside the defining procedure.
It updates the global block_counter *)
val reset_block_counter : unit -> unit

@ -379,6 +379,229 @@ 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 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
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
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)
| _ ->
(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)
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 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
(** Global counter for anonymous block*)
let block_counter = ref 0
let reset_block_counter () = block_counter := 0
let get_fresh_block_index () =
block_counter := !block_counter + 1 ;
!block_counter
let mk_fresh_block_procname defining_proc =
let name = block_procname_with_index defining_proc (get_fresh_block_index ()) in
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
mk_c_function ~is_cpp ~tenv qual_name None
let cpp_method_of_string tenv class_name method_name =
mk_cpp_method ~tenv class_name method_name None
let objc_method_of_string_kind class_name method_name method_kind =
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
| ObjCMethodDecl (decl_info, name_info, mdi) ->
let method_name =
match String.split ~on:':' name_info.Clang_ast_t.ni_name with
| hd :: _ ->
hd
| _ ->
name_info.Clang_ast_t.ni_name
in
objc_method_procname decl_info method_name mdi
| _ ->
from_decl ~is_cpp method_decl
end
let get_type_from_expr_info ei tenv = let get_type_from_expr_info ei tenv =
let qt = ei.Clang_ast_t.ei_qual_type in let qt = ei.Clang_ast_t.ei_qual_type in
qual_type_to_sil_type tenv qt qual_type_to_sil_type tenv qt

@ -9,6 +9,34 @@
open! IStd open! IStd
module CProcname : sig
val from_decl : ?tenv:Tenv.t -> is_cpp:bool -> Clang_ast_t.decl -> Typ.Procname.t
(** Given decl, return its procname. This function should be used for all procedures
present in original AST *)
val from_decl_for_linters : is_cpp:bool -> Clang_ast_t.decl -> Typ.Procname.t
(** This is used for bug hashing for linters. In ObjC the method names contain the parameter names,
thus if people add new parameters, any bug about the method will be considered different which means
reporting on unchanged code. So, in the ObjC method case, we create the method name only based on the
first part of the name without the parameters *)
(** WARNING: functions from this module should not be used if full decl is available in AST *)
module NoAstDecl : sig
val c_function_of_string : is_cpp:bool -> Tenv.t -> string -> Typ.Procname.t
val cpp_method_of_string : Tenv.t -> Typ.Name.t -> string -> Typ.Procname.t
val objc_method_of_string_kind :
Typ.Name.t -> string -> Typ.Procname.ObjC_Cpp.kind -> Typ.Procname.t
end
val mk_fresh_block_procname : Typ.Procname.t -> Typ.Procname.t
(** Makes a fresh name for a block defined inside the defining procedure.
It updates the global block_counter *)
val reset_block_counter : unit -> unit
end
(** Processes types and record declarations by adding them to the tenv *) (** Processes types and record declarations by adding them to the tenv *)
val get_record_typename : ?tenv:Tenv.t -> Clang_ast_t.decl -> Typ.Name.t val get_record_typename : ?tenv:Tenv.t -> Clang_ast_t.decl -> Typ.Name.t
@ -24,5 +52,3 @@ val qual_type_to_sil_type : Tenv.t -> Clang_ast_t.qual_type -> Typ.t
val class_from_pointer_type : Tenv.t -> Clang_ast_t.qual_type -> Typ.Name.t val class_from_pointer_type : Tenv.t -> Clang_ast_t.qual_type -> Typ.Name.t
val get_type_from_expr_info : Clang_ast_t.expr_info -> Tenv.t -> Typ.t val get_type_from_expr_info : Clang_ast_t.expr_info -> Tenv.t -> Typ.t
val get_template_args : Tenv.t -> Clang_ast_t.template_specialization_info -> Typ.template_arg list

@ -41,7 +41,7 @@ let compute_icfg trans_unit_ctx tenv ast =
let init_global_state_capture () = let init_global_state_capture () =
Ident.NameGenerator.reset () ; Ident.NameGenerator.reset () ;
CFrontend_config.global_translation_unit_decls := [] ; CFrontend_config.global_translation_unit_decls := [] ;
CProcname.reset_block_counter () CType_decl.CProcname.reset_block_counter ()
let do_source_file (translation_unit_context: CFrontend_config.translation_unit_context) ast = let do_source_file (translation_unit_context: CFrontend_config.translation_unit_context) ast =

@ -441,7 +441,7 @@ let log_frontend_issue ~is_cpp method_decl_opt (node: Ctl_parser_types.ast_node)
let procname = let procname =
match method_decl_opt with match method_decl_opt with
| Some method_decl -> | Some method_decl ->
CProcname.from_decl_for_linters ~is_cpp method_decl CType_decl.CProcname.from_decl_for_linters ~is_cpp method_decl
| None -> | None ->
Typ.Procname.Linters_dummy_method Typ.Procname.Linters_dummy_method
in in

@ -190,14 +190,14 @@ let method_signature_of_decl trans_unit_ctx tenv meth_decl block_data_opt =
match (meth_decl, block_data_opt) with match (meth_decl, block_data_opt) with
| FunctionDecl (decl_info, _, qt, fdi), _ -> | FunctionDecl (decl_info, _, qt, fdi), _ ->
let func_decl = Func_decl_info (fdi, qt) in let func_decl = Func_decl_info (fdi, qt) in
let procname = CProcname.from_decl ~is_cpp ~tenv meth_decl in let procname = CType_decl.CProcname.from_decl ~is_cpp ~tenv meth_decl in
let ms = build_method_signature trans_unit_ctx tenv decl_info procname func_decl None None in let ms = build_method_signature trans_unit_ctx tenv decl_info procname func_decl None None in
(ms, fdi.Clang_ast_t.fdi_body, []) (ms, fdi.Clang_ast_t.fdi_body, [])
| CXXMethodDecl (decl_info, _, qt, fdi, mdi), _ | CXXMethodDecl (decl_info, _, qt, fdi, mdi), _
| CXXConstructorDecl (decl_info, _, qt, fdi, mdi), _ | CXXConstructorDecl (decl_info, _, qt, fdi, mdi), _
| CXXConversionDecl (decl_info, _, qt, fdi, mdi), _ | CXXConversionDecl (decl_info, _, qt, fdi, mdi), _
| CXXDestructorDecl (decl_info, _, qt, fdi, mdi), _ -> | CXXDestructorDecl (decl_info, _, qt, fdi, mdi), _ ->
let procname = CProcname.from_decl ~is_cpp ~tenv meth_decl in let procname = CType_decl.CProcname.from_decl ~is_cpp ~tenv meth_decl in
let parent_ptr = Option.value_exn decl_info.di_parent_pointer in let parent_ptr = Option.value_exn decl_info.di_parent_pointer in
let method_decl = Cpp_Meth_decl_info (fdi, mdi, parent_ptr, qt) in let method_decl = Cpp_Meth_decl_info (fdi, mdi, parent_ptr, qt) in
let parent_pointer = decl_info.Clang_ast_t.di_parent_pointer in let parent_pointer = decl_info.Clang_ast_t.di_parent_pointer in
@ -209,7 +209,7 @@ let method_signature_of_decl trans_unit_ctx tenv meth_decl block_data_opt =
(* it will be empty for methods *) (* it will be empty for methods *)
(ms, fdi.Clang_ast_t.fdi_body, init_list_instrs) (ms, fdi.Clang_ast_t.fdi_body, init_list_instrs)
| ObjCMethodDecl (decl_info, _, mdi), _ -> | ObjCMethodDecl (decl_info, _, mdi), _ ->
let procname = CProcname.from_decl ~is_cpp ~tenv meth_decl in let procname = CType_decl.CProcname.from_decl ~is_cpp ~tenv meth_decl in
let parent_ptr = Option.value_exn decl_info.di_parent_pointer in let parent_ptr = Option.value_exn decl_info.di_parent_pointer in
let method_decl = ObjC_Meth_decl_info (mdi, parent_ptr) 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 parent_pointer = decl_info.Clang_ast_t.di_parent_pointer in
@ -656,11 +656,11 @@ let create_procdesc_with_pointer context pointer class_name_opt name =
let callee_name, method_kind = let callee_name, method_kind =
match class_name_opt with match class_name_opt with
| Some class_name -> | Some class_name ->
( CProcname.NoAstDecl.cpp_method_of_string context.tenv class_name name ( CType_decl.CProcname.NoAstDecl.cpp_method_of_string context.tenv class_name name
, ProcAttributes.CPP_INSTANCE ) , ProcAttributes.CPP_INSTANCE )
| None -> | None ->
let is_cpp = CGeneral_utils.is_cpp_translation context.translation_unit_context in let is_cpp = CGeneral_utils.is_cpp_translation context.translation_unit_context in
( CProcname.NoAstDecl.c_function_of_string ~is_cpp context.tenv name ( CType_decl.CProcname.NoAstDecl.c_function_of_string ~is_cpp context.tenv name
, ProcAttributes.C_FUNCTION ) , ProcAttributes.C_FUNCTION )
in in
create_external_procdesc context.cfg callee_name method_kind None ; create_external_procdesc context.cfg callee_name method_kind None ;

@ -50,14 +50,15 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
CMethod_trans.get_class_name_method_call_from_receiver_kind context CMethod_trans.get_class_name_method_call_from_receiver_kind context
obj_c_message_expr_info act_params obj_c_message_expr_info act_params
in in
CProcname.NoAstDecl.objc_method_of_string_kind class_name selector objc_method_kind CType_decl.CProcname.NoAstDecl.objc_method_of_string_kind class_name selector
objc_method_kind
in in
let predefined_ms_opt = let predefined_ms_opt =
match proc_name with match proc_name with
| Typ.Procname.ObjC_Cpp objc_cpp -> | Typ.Procname.ObjC_Cpp objc_cpp ->
let class_name = Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp in let class_name = Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp in
CTrans_models.get_predefined_model_method_signature class_name selector CTrans_models.get_predefined_model_method_signature class_name selector
CProcname.NoAstDecl.objc_method_of_string_kind CFrontend_config.ObjC CType_decl.CProcname.NoAstDecl.objc_method_of_string_kind CFrontend_config.ObjC
| _ -> | _ ->
None None
in in
@ -2629,7 +2630,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
match decl with match decl with
| Clang_ast_t.BlockDecl (_, block_decl_info) -> | Clang_ast_t.BlockDecl (_, block_decl_info) ->
let open CContext in let open CContext in
let block_pname = CProcname.mk_fresh_block_procname procname in let block_pname = CType_decl.CProcname.mk_fresh_block_procname procname in
let captured_pvars = let captured_pvars =
CVar_decl.captured_vars_from_block_info context stmt_info.Clang_ast_t.si_source_range CVar_decl.captured_vars_from_block_info context stmt_info.Clang_ast_t.si_source_range
block_decl_info.Clang_ast_t.bdi_captured_variables block_decl_info.Clang_ast_t.bdi_captured_variables

@ -380,7 +380,7 @@ let objc_new_trans trans_state ~alloc_builtin loc stmt_info cls_name function_ty
let call_flags = {CallFlags.default with CallFlags.cf_virtual= is_instance} in let call_flags = {CallFlags.default with CallFlags.cf_virtual= is_instance} in
let method_kind = ProcAttributes.OBJC_INSTANCE in let method_kind = ProcAttributes.OBJC_INSTANCE in
let pname = let pname =
CProcname.NoAstDecl.objc_method_of_string_kind cls_name CFrontend_config.init CType_decl.CProcname.NoAstDecl.objc_method_of_string_kind cls_name CFrontend_config.init
Typ.Procname.ObjC_Cpp.ObjCInstanceMethod Typ.Procname.ObjC_Cpp.ObjCInstanceMethod
in in
CMethod_trans.create_external_procdesc trans_state.context.CContext.cfg pname method_kind None ; CMethod_trans.create_external_procdesc trans_state.context.CContext.cfg pname method_kind None ;

Loading…
Cancel
Save