|
|
|
(*
|
|
|
|
* Copyright (c) 2013 - 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
|
|
|
|
module L = Logging
|
|
|
|
|
|
|
|
let add_protocol_super qual_type_to_sil_type tenv obj_c_protocol_decl_info =
|
|
|
|
let protocols = obj_c_protocol_decl_info.Clang_ast_t.opcdi_protocols in
|
|
|
|
CAst_utils.add_type_from_decl_ref_list qual_type_to_sil_type tenv protocols
|
|
|
|
|
|
|
|
let protocol_decl qual_type_to_sil_type tenv decl =
|
|
|
|
let open Clang_ast_t in
|
|
|
|
match decl with
|
|
|
|
| ObjCProtocolDecl (decl_info, name_info, _, _, obj_c_protocol_decl_info)
|
|
|
|
-> let name = CAst_utils.get_qualified_name name_info in
|
|
|
|
(* Adds pairs (protocol name, protocol_type_info) to the global environment. *)
|
|
|
|
(* Protocol_type_info contains the methods composing the protocol. *)
|
|
|
|
(* Here we are giving a similar treatment as interfaces (see above)*)
|
|
|
|
(* It may turn out that we need a more specific treatment for protocols*)
|
|
|
|
L.(debug Capture Verbose) "ADDING: ObjCProtocolDecl for '%a'@\n" QualifiedCppName.pp name ;
|
|
|
|
let protocol_name = Typ.Name.Objc.protocol_from_qual_name name in
|
|
|
|
let protocol_desc = Typ.Tstruct protocol_name in
|
|
|
|
let decl_key = Clang_ast_extend.DeclPtr decl_info.Clang_ast_t.di_pointer in
|
|
|
|
CAst_utils.update_sil_types_map decl_key protocol_desc ;
|
|
|
|
ignore (Tenv.mk_struct tenv ~methods:[] protocol_name) ;
|
|
|
|
add_protocol_super qual_type_to_sil_type tenv obj_c_protocol_decl_info ;
|
|
|
|
protocol_desc
|
|
|
|
| _
|
|
|
|
-> assert false
|
Using clang's method resolution if possible
Summary: public
Using clang's method resolution. This means that, in method calls, clang gives you a pointer to the declaration of the method.
In some cases though, clang doesn't find the right method. For example, when it finds a method in a category, we
need to make it into a method in the corresponding class, because that's how we treat categories in Infer. Moreover,
when it finds a method in a protocol, that is not useful for us, since the implementation will be in some class. Finally,
sometimes the call is on an object of type id, in which case clang doesn't know what is the correct declaration. In
those cases, we fall back to what we were doing before of approximating the method resolution. We also refactor
some of the code.
Reviewed By: akotulski
Differential Revision: D2679766
fb-gh-sync-id: b79bb85
9 years ago
|
|
|
|
|
|
|
let is_protocol decl = Clang_ast_t.(match decl with ObjCProtocolDecl _ -> true | _ -> false)
|