[cleanup] Move ObjC/C++-specific Procname functions to dedicated module

Summary: Continuing the cleanup started in D6740465.

Reviewed By: jeremydubreil, mbouaziz

Differential Revision: D6945967

fbshipit-source-id: 23e9d08
master
Sam Blackshear 7 years ago committed by Facebook Github Bot
parent 3d170a82c4
commit 1a75ec9cf8

@ -21,11 +21,12 @@ let create_procname name =
let create_objc_class_method class_name method_name = let create_objc_class_method class_name method_name =
let method_kind = Typ.Procname.ObjCClassMethod in let method_kind = Typ.Procname.ObjC_Cpp.ObjCClassMethod in
let tname = Typ.Name.Objc.from_string class_name in let tname = Typ.Name.Objc.from_string class_name in
let pname = let pname =
Typ.Procname.ObjC_Cpp Typ.Procname.ObjC_Cpp
(Typ.Procname.objc_cpp tname method_name method_kind Typ.NoTemplate ~is_generic_model:false) (Typ.Procname.ObjC_Cpp.make tname method_name method_kind Typ.NoTemplate
~is_generic_model:false)
in in
register pname ; pname register pname ; pname

@ -459,7 +459,7 @@ let is_specialized pdesc =
attributes.ProcAttributes.is_specialized attributes.ProcAttributes.is_specialized
(* true if pvar is a captred variable of a cpp lambda or obcj block *) (* true if pvar is a captured variable of a cpp lambda or objc block *)
let is_captured_var procdesc pvar = let is_captured_var procdesc pvar =
let procname = get_proc_name procdesc in let procname = get_proc_name procdesc in
let pvar_name = Pvar.get_name pvar in let pvar_name = Pvar.get_name pvar in
@ -468,11 +468,15 @@ let is_captured_var procdesc pvar =
in in
let pvar_matches (name, _) = Mangled.equal name pvar_name in let pvar_matches (name, _) = Mangled.equal name pvar_name in
let is_captured_var_cpp_lambda = let is_captured_var_cpp_lambda =
match procname with
| Typ.Procname.ObjC_Cpp cpp_pname ->
(* var is captured if the procedure is a lambda and the var is not in the locals or formals *) (* var is captured if the procedure is a lambda and the var is not in the locals or formals *)
Typ.Procname.is_cpp_lambda procname Typ.Procname.ObjC_Cpp.is_cpp_lambda cpp_pname
&& not && not
( List.exists ~f:pvar_local_matches (get_locals procdesc) ( List.exists ~f:pvar_local_matches (get_locals procdesc)
|| List.exists ~f:pvar_matches (get_formals procdesc) ) || List.exists ~f:pvar_matches (get_formals procdesc) )
| _ ->
false
in in
let is_captured_var_objc_block = let is_captured_var_objc_block =
(* var is captured if the procedure is a objc block and the var is in the captured *) (* var is captured if the procedure is a objc block and the var is in the captured *)

@ -23,7 +23,7 @@ type typ = Typ.t
type c = Typ.Procname.c type c = Typ.Procname.c
type objc_cpp = Typ.Procname.objc_cpp type objc_cpp = Typ.Procname.ObjC_Cpp.t
type qual_name = QualifiedCppName.t type qual_name = QualifiedCppName.t
@ -184,9 +184,9 @@ let name_cons
| _ -> | _ ->
None None
in in
let on_objc_cpp f objc_cpp = let on_objc_cpp f (objc_cpp: Typ.Procname.ObjC_Cpp.t) =
if String.equal name objc_cpp.Typ.Procname.method_name then if String.equal name objc_cpp.method_name then
on_templated_name f (templated_name_of_class_name objc_cpp.Typ.Procname.class_name) on_templated_name f (templated_name_of_class_name objc_cpp.class_name)
else None else None
in in
{on_objc_cpp; on_qual_name; get_markers} {on_objc_cpp; on_qual_name; get_markers}
@ -210,12 +210,12 @@ let all_names_cons
on_templated_name_rec f (rest, []) on_templated_name_rec f (rest, [])
in in
let on_templated_name = on_templated_name_rec in let on_templated_name = on_templated_name_rec in
let on_objc_cpp f objc_cpp = let on_objc_cpp f (objc_cpp: Typ.Procname.ObjC_Cpp.t) =
match on_objc_cpp f objc_cpp with match on_objc_cpp f objc_cpp with
| Some _ as some -> | Some _ as some ->
some some
| None -> | None ->
on_templated_name f (templated_name_of_class_name objc_cpp.Typ.Procname.class_name) on_templated_name f (templated_name_of_class_name objc_cpp.class_name)
in in
{on_templated_name; get_markers; path_extra= PathNonEmpty {on_objc_cpp}} {on_templated_name; get_markers; path_extra= PathNonEmpty {on_objc_cpp}}
@ -232,14 +232,12 @@ let templ_begin
| Some (f, captured_types) -> | Some (f, captured_types) ->
Some (f, captured_types, template_args) Some (f, captured_types, template_args)
in in
let on_objc_cpp f objc_cpp = let on_objc_cpp f (objc_cpp: Typ.Procname.ObjC_Cpp.t) =
match on_objc_cpp f objc_cpp with match on_objc_cpp f objc_cpp with
| None -> | None ->
None None
| Some (f, captured_types) -> | Some (f, captured_types) ->
let template_args = let template_args = template_args_of_template_spec_info objc_cpp.template_args in
template_args_of_template_spec_info objc_cpp.Typ.Procname.template_args
in
Some (f, captured_types, template_args) Some (f, captured_types, template_args)
in in
{on_objc_cpp; on_templated_name; get_markers} {on_objc_cpp; on_templated_name; get_markers}

@ -416,13 +416,13 @@ let pp_instr pe0 f instr =
let add_with_block_parameters_flag instr = let add_with_block_parameters_flag instr =
match instr with match instr with
| Call (ret_id, Exp.Const Const.Cfun name, arg_ts, loc, cf) -> | Call (ret_id, Exp.Const Const.Cfun pname, arg_ts, loc, cf) ->
if List.exists ~f:(fun (exp, _) -> Exp.is_objc_block_closure exp) arg_ts if List.exists ~f:(fun (exp, _) -> Exp.is_objc_block_closure exp) arg_ts
&& (Typ.Procname.is_objc_method name || Typ.Procname.is_c_function name) && Typ.Procname.is_clang pname
(* to be extended to other methods *) (* to be extended to other methods *)
then then
let cf' = {cf with cf_with_block_parameters= true} in let cf' = {cf with cf_with_block_parameters= true} in
Call (ret_id, Exp.Const (Const.Cfun name), arg_ts, loc, cf') Call (ret_id, Exp.Const (Const.Cfun pname), arg_ts, loc, cf')
else instr else instr
| _ -> | _ ->
instr instr

@ -694,28 +694,93 @@ module Procname = struct
match List.last parameters with Some (_, "java.lang.Object[]") -> true | _ -> false match List.last parameters with Some (_, "java.lang.Object[]") -> true | _ -> false
end end
(** Type of c procedure names. *) module ObjC_Cpp = struct
type c = type kind =
{ name: QualifiedCppName.t | CPPMethod of string option
; mangled: string option | CPPConstructor of (string option * bool)
; template_args: template_spec_info | CPPDestructor of string option
; is_generic_model: bool }
[@@deriving compare]
type objc_cpp_method_kind =
| CPPMethod of string option (** with mangling *)
| CPPConstructor of (string option * bool) (** with mangling + is it constexpr? *)
| CPPDestructor of string option (** with mangling *)
| ObjCClassMethod | ObjCClassMethod
| ObjCInstanceMethod | ObjCInstanceMethod
| ObjCInternalMethod | ObjCInternalMethod
[@@deriving compare] [@@deriving compare]
(** Type of Objective C and C++ procedure names: method signatures. *) type t =
type objc_cpp =
{ method_name: string { method_name: string
; class_name: Name.t ; class_name: Name.t
; kind: objc_cpp_method_kind ; kind: kind
; template_args: template_spec_info
; is_generic_model: bool }
[@@deriving compare]
let make class_name method_name kind template_args ~is_generic_model =
{class_name; method_name; kind; template_args; is_generic_model}
let get_class_name objc_cpp = Name.name objc_cpp.class_name
let get_class_type_name objc_cpp = objc_cpp.class_name
let get_class_qualifiers objc_cpp = Name.qual_name objc_cpp.class_name
let objc_method_kind_of_bool is_instance =
if is_instance then ObjCInstanceMethod else ObjCClassMethod
let is_objc_constructor method_name =
String.equal method_name "new" || String.is_prefix ~prefix:"init" method_name
let is_objc_kind = function
| ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod ->
true
| _ ->
false
let is_objc_method {kind} = is_objc_kind kind
let is_objc_dealloc method_name = String.equal method_name "dealloc"
let is_destructor = function
| {kind= CPPDestructor _} ->
true
| name ->
is_objc_dealloc name.method_name
let is_constexpr = function {kind= CPPConstructor (_, true)} -> true | _ -> false
let is_cpp_lambda {method_name} = String.is_substring ~substring:"operator()" method_name
let kind_to_verbose_string = function
| CPPMethod m | CPPDestructor m ->
"(" ^ (match m with None -> "" | Some s -> s) ^ ")"
| CPPConstructor (m, is_constexpr) ->
"{" ^ (match m with None -> "" | Some s -> s)
^ (if is_constexpr then "|constexpr" else "") ^ "}"
| ObjCClassMethod ->
"class"
| ObjCInstanceMethod ->
"instance"
| ObjCInternalMethod ->
"internal"
let to_string osig detail_level =
match detail_level with
| Simple ->
osig.method_name
| Non_verbose ->
Name.name osig.class_name ^ "_" ^ osig.method_name
| Verbose ->
let m_str = kind_to_verbose_string osig.kind in
Name.name osig.class_name ^ "_" ^ osig.method_name ^ m_str
end
(** Type of c procedure names. *)
type c =
{ name: QualifiedCppName.t
; mangled: string option
; template_args: template_spec_info ; template_args: template_spec_info
; is_generic_model: bool } ; is_generic_model: bool }
[@@deriving compare] [@@deriving compare]
@ -729,7 +794,7 @@ module Procname = struct
| C of c | C of c
| Linters_dummy_method | Linters_dummy_method
| Block of block_name | Block of block_name
| ObjC_Cpp of objc_cpp | ObjC_Cpp of ObjC_Cpp.t
| WithBlockParameters of t * block_name list | WithBlockParameters of t * block_name list
[@@deriving compare] [@@deriving compare]
@ -737,10 +802,6 @@ module Procname = struct
let hash = Hashtbl.hash let hash = Hashtbl.hash
let objc_method_kind_of_bool is_instance =
if is_instance then ObjCInstanceMethod else ObjCClassMethod
let block_name_of_procname procname = let block_name_of_procname procname =
match procname with match procname with
| Block block_name -> | Block block_name ->
@ -763,11 +824,6 @@ module Procname = struct
; is_generic_model= false } ; is_generic_model= false }
(** Create an objc procedure name from a class_name and method_name. *)
let objc_cpp class_name method_name kind template_args ~is_generic_model =
{class_name; method_name; kind; template_args; is_generic_model}
let with_block_parameters base blocks = WithBlockParameters (base, blocks) let with_block_parameters base blocks = WithBlockParameters (base, blocks)
(** Create an objc procedure name from a class_name and method_name. *) (** Create an objc procedure name from a class_name and method_name. *)
@ -775,11 +831,17 @@ module Procname = struct
let is_java = function Java _ -> true | _ -> false let is_java = function Java _ -> true | _ -> false
(* TODO: deprecate this unfortunately named function and use is_clang instead *)
let is_c_method = function ObjC_Cpp _ -> true | _ -> false let is_c_method = function ObjC_Cpp _ -> true | _ -> false
let is_c_function = function C _ -> true | _ -> false let is_c_function = function C _ -> true | _ -> false
let is_constexpr = function ObjC_Cpp {kind= CPPConstructor (_, true)} -> true | _ -> false let is_clang = function
| ObjC_Cpp name ->
ObjC_Cpp.is_objc_method name
| name ->
is_c_function name
(** Replace the class name component of a procedure name. (** Replace the class name component of a procedure name.
In case of Java, replace package and class name. *) In case of Java, replace package and class name. *)
@ -805,11 +867,6 @@ module Procname = struct
t t
(** Get the class name of a Objective-C/C++ procedure name. *)
let objc_cpp_get_class_name objc_cpp = Name.name objc_cpp.class_name
let objc_cpp_get_class_type_name objc_cpp = objc_cpp.class_name
(** Return the method/function of a procname. *) (** Return the method/function of a procname. *)
let rec get_method = function let rec get_method = function
| ObjC_Cpp name -> | ObjC_Cpp name ->
@ -829,9 +886,6 @@ module Procname = struct
(** Return whether the procname is a block procname. *) (** Return whether the procname is a block procname. *)
let is_objc_block = function Block _ -> true | _ -> false let is_objc_block = function Block _ -> true | _ -> false
(** Return whether the procname is a cpp lambda. *)
let is_cpp_lambda procname = String.is_substring ~substring:"operator()" (get_method procname)
(** Return the language of the procedure. *) (** Return the language of the procedure. *)
let get_language = function let get_language = function
| ObjC_Cpp _ -> | ObjC_Cpp _ ->
@ -848,39 +902,14 @@ module Procname = struct
Language.Java Language.Java
let is_objc_constructor method_name =
String.equal method_name "new" || String.is_prefix ~prefix:"init" method_name
let is_objc_kind = function
| ObjCClassMethod | ObjCInstanceMethod | ObjCInternalMethod ->
true
| _ ->
false
let is_objc_method = function ObjC_Cpp {kind} -> is_objc_kind kind | _ -> false
(** [is_constructor pname] returns true if [pname] is a constructor *) (** [is_constructor pname] returns true if [pname] is a constructor *)
let is_constructor = function let is_constructor = function
| Java js -> | Java js ->
String.equal js.method_name "<init>" String.equal js.method_name "<init>"
| ObjC_Cpp {kind= CPPConstructor _} -> | ObjC_Cpp {kind= CPPConstructor _} ->
true true
| ObjC_Cpp {kind; method_name} when is_objc_kind kind -> | ObjC_Cpp {kind; method_name} when ObjC_Cpp.is_objc_kind kind ->
is_objc_constructor method_name ObjC_Cpp.is_objc_constructor method_name
| _ ->
false
let is_objc_dealloc method_name = String.equal method_name "dealloc"
(** [is_dealloc pname] returns true if [pname] is the dealloc method in Objective-C *)
let is_destructor = function
| ObjC_Cpp {kind= CPPDestructor _} ->
true
| ObjC_Cpp name ->
is_objc_dealloc name.method_name
| _ -> | _ ->
false false
@ -913,32 +942,6 @@ module Procname = struct
if verbose then match c2 with None -> plain | Some s -> plain ^ "{" ^ s ^ "}" else plain if verbose then match c2 with None -> plain | Some s -> plain ^ "{" ^ s ^ "}" else plain
let c_method_kind_verbose_str kind =
match kind with
| CPPMethod m | CPPDestructor m ->
"(" ^ (match m with None -> "" | Some s -> s) ^ ")"
| CPPConstructor (m, is_constexpr) ->
"{" ^ (match m with None -> "" | Some s -> s) ^ (if is_constexpr then "|constexpr" else "")
^ "}"
| ObjCClassMethod ->
"class"
| ObjCInstanceMethod ->
"instance"
| ObjCInternalMethod ->
"internal"
let c_method_to_string osig detail_level =
match detail_level with
| Simple ->
osig.method_name
| Non_verbose ->
Name.name osig.class_name ^ "_" ^ osig.method_name
| Verbose ->
let m_str = c_method_kind_verbose_str osig.kind in
Name.name osig.class_name ^ "_" ^ osig.method_name ^ m_str
let with_blocks_parameters_to_string base blocks to_string_f = let with_blocks_parameters_to_string base blocks to_string_f =
let base_id = to_string_f base in let base_id = to_string_f base in
String.concat ~sep:"_" (base_id :: blocks) String.concat ~sep:"_" (base_id :: blocks)
@ -952,7 +955,7 @@ module Procname = struct
| C {name; mangled} -> | C {name; mangled} ->
to_readable_string (name, mangled) true to_readable_string (name, mangled) true
| ObjC_Cpp osig -> | ObjC_Cpp osig ->
c_method_to_string osig Verbose ObjC_Cpp.to_string osig Verbose
| Block name -> | Block name ->
name name
| WithBlockParameters (base, blocks) -> | WithBlockParameters (base, blocks) ->
@ -969,7 +972,7 @@ module Procname = struct
| C {name; mangled} -> | C {name; mangled} ->
to_readable_string (name, mangled) false to_readable_string (name, mangled) false
| ObjC_Cpp osig -> | ObjC_Cpp osig ->
c_method_to_string osig Non_verbose ObjC_Cpp.to_string osig Non_verbose
| Block name -> | Block name ->
name name
| WithBlockParameters (base, blocks) -> | WithBlockParameters (base, blocks) ->
@ -986,7 +989,7 @@ module Procname = struct
| C {name; mangled} -> | C {name; mangled} ->
to_readable_string (name, mangled) false ^ "()" to_readable_string (name, mangled) false ^ "()"
| ObjC_Cpp osig -> | ObjC_Cpp osig ->
c_method_to_string osig Simple ObjC_Cpp.to_string osig Simple
| Block _ -> | Block _ ->
"block" "block"
| WithBlockParameters (base, _) -> | WithBlockParameters (base, _) ->
@ -1002,7 +1005,7 @@ module Procname = struct
invariant when introducing new annonynous classes *) invariant when introducing new annonynous classes *)
Str.global_replace (Str.regexp "$[0-9]+") "$_" Str.global_replace (Str.regexp "$[0-9]+") "$_"
(Java.to_string ~withclass:true pname Simple) (Java.to_string ~withclass:true pname Simple)
| ObjC_Cpp _ when is_objc_method p -> | ObjC_Cpp m when ObjC_Cpp.is_objc_method m ->
(* In Objective C, the list of parameters is part of the method name. To prevent the bug (* In Objective C, the list of parameters is part of the method name. To prevent the bug
hash to change when a parameter is introduced or removed, only the part of the name hash to change when a parameter is introduced or removed, only the part of the name
before the first colon is used for the bug hash *) before the first colon is used for the bug hash *)
@ -1044,14 +1047,12 @@ module Procname = struct
let pp = pp let pp = pp
end) end)
let objc_cpp_get_class_qualifiers objc_cpp = Name.qual_name objc_cpp.class_name
let get_qualifiers pname = let get_qualifiers pname =
match pname with match pname with
| C {name} -> | C {name} ->
name name
| ObjC_Cpp objc_cpp -> | ObjC_Cpp objc_cpp ->
objc_cpp_get_class_qualifiers objc_cpp ObjC_Cpp.get_class_qualifiers objc_cpp
|> QualifiedCppName.append_qualifier ~qual:objc_cpp.method_name |> QualifiedCppName.append_qualifier ~qual:objc_cpp.method_name
| _ -> | _ ->
QualifiedCppName.empty QualifiedCppName.empty
@ -1068,7 +1069,7 @@ module Procname = struct
| C {mangled} -> | C {mangled} ->
get_qual_name_str pname :: Option.to_list mangled |> String.concat ~sep:"#" get_qual_name_str pname :: Option.to_list mangled |> String.concat ~sep:"#"
| ObjC_Cpp objc_cpp -> | ObjC_Cpp objc_cpp ->
get_qual_name_str pname ^ "#" ^ c_method_kind_verbose_str objc_cpp.kind get_qual_name_str pname ^ "#" ^ ObjC_Cpp.kind_to_verbose_string objc_cpp.kind
| _ -> | _ ->
to_unique_id pname to_unique_id pname
in in

@ -334,26 +334,57 @@ module Procname : sig
(** Check if this is a class initializer. *) (** Check if this is a class initializer. *)
end end
(** Type of c procedure names. *) module ObjC_Cpp : sig
type c = private type kind =
{ name: QualifiedCppName.t
; mangled: string option
; template_args: template_spec_info
; is_generic_model: bool }
type objc_cpp_method_kind =
| CPPMethod of string option (** with mangling *) | CPPMethod of string option (** with mangling *)
| CPPConstructor of (string option * bool) (** with mangling + is it constexpr? *) | CPPConstructor of (string option * bool) (** with mangling + is it constexpr? *)
| CPPDestructor of string option (** with mangling *) | CPPDestructor of string option (** with mangling *)
| ObjCClassMethod | ObjCClassMethod
| ObjCInstanceMethod | ObjCInstanceMethod
| ObjCInternalMethod | ObjCInternalMethod
[@@deriving compare]
(** Type of Objective C and C++ procedure names. *) (** Type of Objective C and C++ procedure names: method signatures. *)
type objc_cpp = private type t =
{ method_name: string { method_name: string
; class_name: Name.t ; class_name: Name.t
; kind: objc_cpp_method_kind ; kind: kind
; template_args: template_spec_info
; is_generic_model: bool }
[@@deriving compare]
val make : Name.t -> string -> kind -> template_spec_info -> is_generic_model:bool -> t
(** Create an objc procedure name from a class_name and method_name. *)
val get_class_name : t -> string
val get_class_type_name : t -> Name.t
val get_class_qualifiers : t -> QualifiedCppName.t
val objc_method_kind_of_bool : bool -> kind
(** Create ObjC method type from a bool is_instance. *)
val is_objc_constructor : string -> bool
(** Check if this is a constructor method in Objective-C. *)
val is_objc_dealloc : string -> bool
(** Check if this is a dealloc method in Objective-C. *)
val is_destructor : t -> bool
(** Check if this is a dealloc method. *)
val is_constexpr : t -> bool
(** Check if this is a constexpr function. *)
val is_cpp_lambda : t -> bool
(** Return whether the procname is a cpp lambda. *)
end
(** Type of c procedure names. *)
type c = private
{ name: QualifiedCppName.t
; mangled: string option
; template_args: template_spec_info ; template_args: template_spec_info
; is_generic_model: bool } ; is_generic_model: bool }
@ -371,7 +402,7 @@ module Procname : sig
| C of c | C of c
| Linters_dummy_method | Linters_dummy_method
| Block of block_name | Block of block_name
| ObjC_Cpp of objc_cpp | ObjC_Cpp of ObjC_Cpp.t
| WithBlockParameters of t * block_name list | WithBlockParameters of t * block_name list
[@@deriving compare] [@@deriving compare]
@ -416,61 +447,30 @@ module Procname : sig
val is_objc_block : t -> bool val is_objc_block : t -> bool
(** Return whether the procname is a block procname. *) (** Return whether the procname is a block procname. *)
val is_cpp_lambda : t -> bool
(** Return whether the procname is a cpp lambda. *)
val hash_pname : t -> int val hash_pname : t -> int
(** Hash function for procname. *) (** Hash function for procname. *)
val is_c_method : t -> bool val is_c_method : t -> bool
(** Check if this is an Objective-C/C++ method name. *) (** Return true this is an Objective-C/C++ method name. *)
val is_c_function : t -> bool
(** Check if this is a C function name. *)
val is_objc_constructor : string -> bool
(** Check if this is a constructor method in Objective-C. *)
val is_objc_method : t -> bool val is_clang : t -> bool
(** Check if this is an Objective-C method. *) (** Return true if this is a C, C++, or Objective-C procedure name *)
val is_constructor : t -> bool val is_constructor : t -> bool
(** Check if this is a constructor. *) (** Check if this is a constructor. *)
val is_constexpr : t -> bool
(** Check if this is a constexpr function. *)
val is_java : t -> bool val is_java : t -> bool
(** Check if this is a Java procedure name. *) (** Check if this is a Java procedure name. *)
val is_objc_dealloc : string -> bool
(** Check if this is a dealloc method in Objective-C. *)
val is_destructor : t -> bool
(** Check if this is a dealloc method. *)
val mangled_objc_block : string -> t val mangled_objc_block : string -> t
(** Create an objc block name. *) (** Create an objc block name. *)
val objc_cpp :
Name.t -> string -> objc_cpp_method_kind -> template_spec_info -> is_generic_model:bool
-> objc_cpp
(** Create an objc procedure name from a class_name and method_name. *)
val with_block_parameters : t -> block_name list -> t val with_block_parameters : t -> block_name list -> t
(** Create a procedure name instantiated with block parameters from a base procedure name (** Create a procedure name instantiated with block parameters from a base procedure name
and a list of block procedure names (the arguments). *) and a list of block procedure names (the arguments). *)
val objc_cpp_get_class_name : objc_cpp -> string
(** Get the class name of a Objective-C/C++ procedure name. *)
val objc_cpp_get_class_type_name : objc_cpp -> Name.t
val objc_cpp_replace_method_name : t -> string -> t val objc_cpp_replace_method_name : t -> string -> t
val objc_method_kind_of_bool : bool -> objc_cpp_method_kind
(** Create ObjC method type from a bool is_instance. *)
val is_infer_undefined : t -> bool val is_infer_undefined : t -> bool
(** Check if this is a special Infer undefined procedure. *) (** Check if this is a special Infer undefined procedure. *)
@ -502,9 +502,6 @@ module Procname : sig
val get_qualifiers : t -> QualifiedCppName.t val get_qualifiers : t -> QualifiedCppName.t
(** get qualifiers of C/objc/C++ method/function *) (** get qualifiers of C/objc/C++ method/function *)
val objc_cpp_get_class_qualifiers : objc_cpp -> QualifiedCppName.t
(** get qualifiers of a class owning objc/C++ method *)
end end
module Fieldname : sig module Fieldname : sig

@ -28,7 +28,7 @@ let is_one_of_classes = QualifiedCppName.Match.match_qualifiers
let is_method_of_objc_cpp_class pname matcher = let is_method_of_objc_cpp_class pname matcher =
match pname with match pname with
| Typ.Procname.ObjC_Cpp objc_cpp -> | Typ.Procname.ObjC_Cpp objc_cpp ->
let class_qual_opt = Typ.Procname.objc_cpp_get_class_qualifiers objc_cpp in let class_qual_opt = Typ.Procname.ObjC_Cpp.get_class_qualifiers objc_cpp in
is_one_of_classes matcher class_qual_opt is_one_of_classes matcher class_qual_opt
| _ -> | _ ->
false false

@ -115,7 +115,7 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
(Typ.Procname.Java.get_class_name java_proc) (Typ.Procname.Java.get_class_name java_proc)
| Typ.Procname.ObjC_Cpp objc_cpp_prod -> | Typ.Procname.ObjC_Cpp objc_cpp_prod ->
String.equal frame.Stacktrace.class_str String.equal frame.Stacktrace.class_str
(Typ.Procname.objc_cpp_get_class_name objc_cpp_prod) (Typ.Procname.ObjC_Cpp.get_class_name objc_cpp_prod)
| Typ.Procname.C _ -> | Typ.Procname.C _ ->
true (* Needed for test code. *) true (* Needed for test code. *)
| Typ.Procname.Block _ | Typ.Procname.Block _

@ -137,9 +137,8 @@ module TransferFunctions (CFG : ProcCfg.S) = struct
else None ) else None )
in in
Domain.join astate (NonBottom SiofTrace.empty, Domain.VarNames.of_list init) Domain.join astate (NonBottom SiofTrace.empty, Domain.VarNames.of_list init)
| Call (_, Const Cfun callee_pname, _ :: actuals_without_self, loc, _) | Call (_, Const Cfun (ObjC_Cpp cpp_pname as callee_pname), _ :: actuals_without_self, loc, _)
when Typ.Procname.is_c_method callee_pname && Typ.Procname.is_constructor callee_pname when Typ.Procname.is_constructor callee_pname && Typ.Procname.ObjC_Cpp.is_constexpr cpp_pname ->
&& Typ.Procname.is_constexpr callee_pname ->
add_actuals_globals astate pdesc loc actuals_without_self add_actuals_globals astate pdesc loc actuals_without_self
| Call (_, Const Cfun callee_pname, actuals, loc, _) -> | Call (_, Const Cfun callee_pname, actuals, loc, _) ->
let callee_astate = let callee_astate =
@ -267,7 +266,12 @@ let checker {Callbacks.proc_desc; tenv; summary; get_procs_in_file} : Specs.summ
to figure this out when analyzing the function, but we might as well use the user's to figure this out when analyzing the function, but we might as well use the user's
specification if it's given to us. This also serves as an optimization as this skips the specification if it's given to us. This also serves as an optimization as this skips the
analysis of the function. *) analysis of the function. *)
if Typ.Procname.is_constexpr pname then Summary.update_summary initial summary if match pname with
| ObjC_Cpp cpp_pname ->
Typ.Procname.ObjC_Cpp.is_constexpr cpp_pname
| _ ->
false
then Summary.update_summary initial summary
else else
match Analyzer.compute_post proc_data ~initial with match Analyzer.compute_post proc_data ~initial with
| Some post -> | Some post ->

@ -105,11 +105,11 @@ let mk_cpp_method ?tenv class_name method_name ?meth_decl mangled =
let method_kind = let method_kind =
match meth_decl with match meth_decl with
| Some Clang_ast_t.CXXConstructorDecl (_, _, _, _, {xmdi_is_constexpr}) -> | Some Clang_ast_t.CXXConstructorDecl (_, _, _, _, {xmdi_is_constexpr}) ->
Typ.Procname.CPPConstructor (mangled, xmdi_is_constexpr) Typ.Procname.ObjC_Cpp.CPPConstructor (mangled, xmdi_is_constexpr)
| Some Clang_ast_t.CXXDestructorDecl _ -> | Some Clang_ast_t.CXXDestructorDecl _ ->
Typ.Procname.CPPDestructor mangled Typ.Procname.ObjC_Cpp.CPPDestructor mangled
| _ -> | _ ->
Typ.Procname.CPPMethod mangled Typ.Procname.ObjC_Cpp.CPPMethod mangled
in in
let template_info, is_generic_model = let template_info, is_generic_model =
match meth_decl with match meth_decl with
@ -132,12 +132,12 @@ let mk_cpp_method ?tenv class_name method_name ?meth_decl mangled =
(Typ.NoTemplate, false) (Typ.NoTemplate, false)
in in
Typ.Procname.ObjC_Cpp Typ.Procname.ObjC_Cpp
(Typ.Procname.objc_cpp class_name method_name method_kind template_info ~is_generic_model) (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 = let mk_objc_method class_typename method_name method_kind =
Typ.Procname.ObjC_Cpp Typ.Procname.ObjC_Cpp
(Typ.Procname.objc_cpp class_typename method_name method_kind Typ.NoTemplate (Typ.Procname.ObjC_Cpp.make class_typename method_name method_kind Typ.NoTemplate
~is_generic_model:false) ~is_generic_model:false)
@ -188,7 +188,7 @@ end
let objc_method_procname ?tenv decl_info method_name mdi = let objc_method_procname ?tenv decl_info method_name mdi =
let class_typename = get_class_typename ?tenv decl_info in let class_typename = get_class_typename ?tenv decl_info in
let is_instance = mdi.Clang_ast_t.omdi_is_instance_method in let is_instance = mdi.Clang_ast_t.omdi_is_instance_method in
let method_kind = Typ.Procname.objc_method_kind_of_bool is_instance 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 mk_objc_method class_typename method_name method_kind

@ -29,7 +29,7 @@ module NoAstDecl : sig
val cpp_method_of_string : Tenv.t -> Typ.Name.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 : val objc_method_of_string_kind :
Typ.Name.t -> string -> Typ.Procname.objc_cpp_method_kind -> Typ.Procname.t Typ.Name.t -> string -> Typ.Procname.ObjC_Cpp.kind -> Typ.Procname.t
end end
val mk_fresh_block_procname : Typ.Procname.t -> Typ.Procname.t val mk_fresh_block_procname : Typ.Procname.t -> Typ.Procname.t

@ -296,7 +296,7 @@ let get_class_name_method_call_from_clang trans_unit_ctx tenv obj_c_message_expr
| Some ms -> ( | Some ms -> (
match CMethod_signature.ms_get_name ms with match CMethod_signature.ms_get_name ms with
| Typ.Procname.ObjC_Cpp objc_cpp -> | Typ.Procname.ObjC_Cpp objc_cpp ->
Some (Typ.Procname.objc_cpp_get_class_type_name objc_cpp) Some (Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp)
| _ -> | _ ->
None ) None )
| None -> | None ->
@ -529,7 +529,7 @@ let get_objc_property_accessor tenv ms =
let class_tname = let class_tname =
match CMethod_signature.ms_get_name ms with match CMethod_signature.ms_get_name ms with
| Typ.Procname.ObjC_Cpp objc_cpp -> | Typ.Procname.ObjC_Cpp objc_cpp ->
Typ.Procname.objc_cpp_get_class_type_name objc_cpp Typ.Procname.ObjC_Cpp.get_class_type_name objc_cpp
| _ -> | _ ->
assert false assert false
in in

@ -403,10 +403,12 @@ let get_method_name_from_context context =
let is_objc_constructor context = let is_objc_constructor context =
Typ.Procname.is_objc_constructor (get_method_name_from_context context) Typ.Procname.ObjC_Cpp.is_objc_constructor (get_method_name_from_context context)
let is_objc_dealloc context = Typ.Procname.is_objc_dealloc (get_method_name_from_context context) let is_objc_dealloc context =
Typ.Procname.ObjC_Cpp.is_objc_dealloc (get_method_name_from_context context)
let is_in_method context name = let is_in_method context name =
let current_method_name = get_method_name_from_context context in let current_method_name = get_method_name_from_context context in

@ -28,7 +28,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
CMethod_trans.get_objc_method_data obj_c_message_expr_info CMethod_trans.get_objc_method_data obj_c_message_expr_info
in in
let is_instance = mc_type <> CMethod_trans.MCStatic in let is_instance = mc_type <> CMethod_trans.MCStatic in
let objc_method_kind = Typ.Procname.objc_method_kind_of_bool is_instance in let objc_method_kind = Typ.Procname.ObjC_Cpp.objc_method_kind_of_bool is_instance in
let method_kind = let method_kind =
if is_instance then ProcAttributes.OBJC_INSTANCE else ProcAttributes.OBJC_CLASS if is_instance then ProcAttributes.OBJC_INSTANCE else ProcAttributes.OBJC_CLASS
in in
@ -55,7 +55,7 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
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 CProcname.NoAstDecl.objc_method_of_string_kind CFrontend_config.ObjC
| _ -> | _ ->
@ -2435,7 +2435,13 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
this is ensured by creating a fresh pointer in `inject_destructors` this is ensured by creating a fresh pointer in `inject_destructors`
*) *)
if destr_trans_result.root_nodes <> [] then assert false ; if destr_trans_result.root_nodes <> [] then assert false ;
let is_destructor = Typ.Procname.is_destructor procname in let is_destructor =
match procname with
| Typ.Procname.ObjC_Cpp cpp_pname ->
Typ.Procname.ObjC_Cpp.is_destructor cpp_pname
| _ ->
false
in
let destructor_res = let destructor_res =
if is_destructor then if is_destructor then
cxx_inject_field_destructors_in_destructor_body trans_state_pri stmt_info cxx_inject_field_destructors_in_destructor_body trans_state_pri stmt_info
@ -3484,7 +3490,13 @@ module CTrans_funct (F : CModule_type.CFrontend) : CModule_type.CTranslation = s
; opaque_exp= None } ; opaque_exp= None }
in in
let procname = Procdesc.get_proc_name context.CContext.procdesc in let procname = Procdesc.get_proc_name context.CContext.procdesc in
let is_destructor = Typ.Procname.is_destructor procname in let is_destructor =
match procname with
| Typ.Procname.ObjC_Cpp cpp_pname ->
Typ.Procname.ObjC_Cpp.is_destructor cpp_pname
| _ ->
false
in
let stmt_info, _ = Clang_ast_proj.get_stmt_tuple body in let stmt_info, _ = Clang_ast_proj.get_stmt_tuple body in
let destructor_res, body = let destructor_res, body =
if is_destructor_wrapper then if is_destructor_wrapper then

@ -93,7 +93,7 @@ let get_predefined_ms_stringWithUTF8String class_name method_name mk_procname la
Ast_expressions.create_char_star_type ~quals:(Typ.mk_type_quals ~is_const:true ()) () Ast_expressions.create_char_star_type ~quals:(Typ.mk_type_quals ~is_const:true ()) ()
in in
let args = [(Mangled.from_string "x", char_star_type)] in let args = [(Mangled.from_string "x", char_star_type)] in
get_predefined_ms_method condition class_name method_name Typ.Procname.ObjCClassMethod get_predefined_ms_method condition class_name method_name Typ.Procname.ObjC_Cpp.ObjCClassMethod
mk_procname lang args id_type [] None mk_procname lang args id_type [] None
@ -101,8 +101,9 @@ let get_predefined_ms_is_kind_of_class class_name method_name mk_procname lang =
let condition = String.equal method_name CFrontend_config.is_kind_of_class in let condition = String.equal method_name CFrontend_config.is_kind_of_class in
let class_type = Ast_expressions.create_class_qual_type class_name in let class_type = Ast_expressions.create_class_qual_type class_name in
let args = [(Mangled.from_string CFrontend_config.self, class_type)] in let args = [(Mangled.from_string CFrontend_config.self, class_type)] in
get_predefined_ms_method condition class_name method_name Typ.Procname.ObjCInstanceMethod get_predefined_ms_method condition class_name method_name
mk_procname lang args Ast_expressions.create_BOOL_type [] (Some BuiltinDecl.__instanceof) Typ.Procname.ObjC_Cpp.ObjCInstanceMethod mk_procname lang args Ast_expressions.create_BOOL_type
[] (Some BuiltinDecl.__instanceof)
let get_predefined_model_method_signature class_name method_name mk_procname lang = let get_predefined_model_method_signature class_name method_name mk_procname lang =

@ -28,6 +28,5 @@ val is_modeled_builtin : string -> bool
val is_modeled_attribute : string -> bool val is_modeled_attribute : string -> bool
val get_predefined_model_method_signature : val get_predefined_model_method_signature :
Typ.Name.t -> string Typ.Name.t -> string -> (Typ.Name.t -> string -> Typ.Procname.ObjC_Cpp.kind -> Typ.Procname.t)
-> (Typ.Name.t -> string -> Typ.Procname.objc_cpp_method_kind -> Typ.Procname.t)
-> CFrontend_config.clang_lang -> CMethod_signature.method_signature option -> CFrontend_config.clang_lang -> CMethod_signature.method_signature option

@ -381,7 +381,7 @@ let objc_new_trans trans_state ~alloc_builtin loc stmt_info cls_name function_ty
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 CProcname.NoAstDecl.objc_method_of_string_kind cls_name CFrontend_config.init
Typ.Procname.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 ;
let args = [(alloc_ret_exp, alloc_ret_type)] in let args = [(alloc_ret_exp, alloc_ret_type)] in

@ -1493,7 +1493,7 @@ let report_unsafe_accesses (aggregated_access_map: reported_access list AccessLi
reported_writes= Typ.Procname.Set.empty; reported_reads= Typ.Procname.Set.empty } reported_writes= Typ.Procname.Set.empty; reported_reads= Typ.Procname.Set.empty }
in in
let class_has_mutex_member objc_cpp tenv = let class_has_mutex_member objc_cpp tenv =
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
let matcher = QualifiedCppName.Match.of_fuzzy_qual_names ["std::mutex"] in let matcher = QualifiedCppName.Match.of_fuzzy_qual_names ["std::mutex"] in
Option.exists (Tenv.lookup tenv class_name) ~f:(fun class_str -> Option.exists (Tenv.lookup tenv class_name) ~f:(fun class_str ->
(* check if the class contains a member of type std::mutex *) (* check if the class contains a member of type std::mutex *)

@ -274,8 +274,8 @@ module Models = struct
; "std::vector" ]) ; "std::vector" ])
in in
function function
| (Typ.Procname.ObjC_Cpp _ | C _) as pname -> | Typ.Procname.ObjC_Cpp cpp_pname as pname ->
Typ.Procname.is_destructor pname Typ.Procname.ObjC_Cpp.is_destructor cpp_pname
|| QualifiedCppName.Match.match_qualifiers (Lazy.force matcher) || QualifiedCppName.Match.match_qualifiers (Lazy.force matcher)
(Typ.Procname.get_qualifiers pname) (Typ.Procname.get_qualifiers pname)
| _ -> | _ ->

@ -68,7 +68,7 @@ module SourceKind = struct
let qualified_pname = Typ.Procname.get_qualifiers pname in let qualified_pname = Typ.Procname.get_qualifiers pname in
match match
( QualifiedCppName.to_list ( QualifiedCppName.to_list
(Typ.Name.unqualified_name (Typ.Procname.objc_cpp_get_class_type_name cpp_name)) (Typ.Name.unqualified_name (Typ.Procname.ObjC_Cpp.get_class_type_name cpp_name))
, Typ.Procname.get_method pname ) , Typ.Procname.get_method pname )
with with
| ( ["std"; ("basic_istream" | "basic_iostream")] | ( ["std"; ("basic_istream" | "basic_iostream")]
@ -128,7 +128,7 @@ module SourceKind = struct
| _ -> | _ ->
false false
in in
let typename = Typ.Procname.objc_cpp_get_class_type_name cpp_pname in let typename = Typ.Procname.ObjC_Cpp.get_class_type_name cpp_pname in
PatternMatch.supertype_exists tenv is_thrift_service_ typename PatternMatch.supertype_exists tenv is_thrift_service_ typename
in in
(* taint all formals except for [this] *) (* taint all formals except for [this] *)
@ -149,7 +149,7 @@ module SourceKind = struct
| Typ.Procname.ObjC_Cpp cpp_pname as pname -> | Typ.Procname.ObjC_Cpp cpp_pname as pname ->
let qualified_pname = let qualified_pname =
F.sprintf "%s::%s" F.sprintf "%s::%s"
(Typ.Procname.objc_cpp_get_class_name cpp_pname) (Typ.Procname.ObjC_Cpp.get_class_name cpp_pname)
(Typ.Procname.get_method pname) (Typ.Procname.get_method pname)
in in
if String.Set.mem endpoints qualified_pname then if String.Set.mem endpoints qualified_pname then
@ -272,7 +272,7 @@ module SinkKind = struct
| Typ.Procname.ObjC_Cpp cpp_name -> ( | Typ.Procname.ObjC_Cpp cpp_name -> (
match match
( QualifiedCppName.to_list ( QualifiedCppName.to_list
(Typ.Name.unqualified_name (Typ.Procname.objc_cpp_get_class_type_name cpp_name)) (Typ.Name.unqualified_name (Typ.Procname.ObjC_Cpp.get_class_type_name cpp_name))
, Typ.Procname.get_method pname ) , Typ.Procname.get_method pname )
with with
| ( ["std"; ("basic_fstream" | "basic_ifstream" | "basic_ofstream")] | ( ["std"; ("basic_fstream" | "basic_ifstream" | "basic_ofstream")]

Loading…
Cancel
Save