Add structured type_ptr

Summary: @​public
Get newest goodness from facebook-clang-plugins
that allows us to change type of type_ptr during deserialization

We are modifying clang_ast_types.ml that fcp/clang-ocaml expects to
exist - we provide our own implementations of:
t_ptr, pointer_to_type_ptr, type_ptr_to_pointer

Reviewed By: @dulmarod

Differential Revision: D2498623
master
Andrzej Kotulski 9 years ago committed by facebook-github-bot-7
parent 7d95e284d2
commit 2a425b8218

@ -1 +1 @@
Subproject commit 657a463bfb6cd9e194684f5953c66f196a078ff9
Subproject commit ae44c0bb0f2f76110535401c0d3b2966e4c630f4

@ -76,11 +76,9 @@ let stmt_info_with_fresh_pointer stmt_info = {
si_source_range = stmt_info.Clang_ast_t.si_source_range;
}
let create_type_ptr_with_just_pointer pointer = pointer
let get_constant_type_ptr s =
let pointer = CFrontend_config.type_pointer_prefix ^ s in
pointer
`Prebuilt pointer
(* Whenever new type are added manually to the translation here, *)
(* they should be added to the map in cTypes_decl too!! *)
@ -114,11 +112,11 @@ let create_void_unsigned_long_type =
let create_void_void_type =
get_constant_type_ptr "void (void *)"
let create_class_type class_name = "custom_class_name*" ^ class_name
let create_class_type class_name = `ClassType class_name
let create_struct_type struct_name = "custom_struct_name*" ^ struct_name
let create_struct_type struct_name = `StructType struct_name
let create_pointer_type class_type = "custom_pointer_" ^ class_type
let create_pointer_type typ = `PointerOf typ
let create_integer_literal stmt_info n =
let stmt_info = dummy_stmt_info () in

@ -47,8 +47,6 @@ val create_struct_type : string -> type_ptr
val create_pointer_type : type_ptr -> type_ptr
val create_type_ptr_with_just_pointer : Clang_ast_t.pointer -> type_ptr
val make_objc_ivar_decl : decl_info -> type_ptr -> obj_c_property_impl_decl_info ->
named_decl_info -> decl

@ -47,7 +47,7 @@ let rec get_enum_constants context decl_list v =
(Mangled.from_string name, const) :: get_enum_constants context decl_list' v)
| _ -> assert false
let enum_decl name tenv cfg cg namespace pointer decl_list opt_type =
let enum_decl name tenv cfg cg namespace type_ptr decl_list opt_type =
Printing.log_out "ADDING: EnumDecl '%s'\n" name;
let context' =
CContext.create_context tenv cg cfg !global_procdesc namespace CContext.ContextNoCls
@ -59,6 +59,6 @@ let enum_decl name tenv cfg cg namespace pointer decl_list opt_type =
(* Here we could give "enum "^name but I want to check that this the type is always defined *)
let typename = CTypes.mk_enumname name in
let typ = Sil.Tenum enum_constants in
Ast_utils.update_sil_types_map pointer typ;
Ast_utils.update_sil_types_map type_ptr typ;
Printing.log_out " TN_typename('%s')\n" (Sil.typename_to_string typename);
Sil.tenv_add tenv typename typ

@ -10,5 +10,5 @@
(** Translate an enumeration declaration by adding it to the tenv and *)
(** translating the code and adding it to a fake procdesc *)
val enum_decl : string -> Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.pointer ->
val enum_decl : string -> Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.type_ptr ->
Clang_ast_t.decl list -> Clang_ast_t.opt_type -> unit

@ -156,7 +156,7 @@ let generated_suffix = "*generated"
let pointer_type_index = ref Clang_ast_main.PointerMap.empty
(* Map from type pointers or declaration pointers to sil types *)
let sil_types_map = ref Clang_ast_main.PointerMap.empty
let sil_types_map = ref Clang_ast_types.TypePointerMap.empty
let type_pointer_prefix = "internal_type"

@ -145,10 +145,13 @@ val enumerateObjectsUsingBlock : string
val generated_suffix : string
(** Map from clang pointers to types produced by ast exporter.
Populated once on InferClang startup *)
val pointer_type_index : Clang_ast_t.c_type Clang_ast_main.PointerMap.t ref
(* Map from type pointers or declaration pointers to sil types *)
val sil_types_map : (Sil.typ Clang_ast_main.PointerMap.t) ref
(** Map from type pointers (clang pointers and types created later by frontend) to sil types
Populated during frontend execution when new type is found *)
val sil_types_map : (Sil.typ Clang_ast_types.TypePointerMap.t) ref
val type_pointer_prefix : string

@ -283,12 +283,20 @@ struct
let update_sil_types_map type_ptr sil_type =
CFrontend_config.sil_types_map :=
Clang_ast_main.PointerMap.add type_ptr sil_type !CFrontend_config.sil_types_map
Clang_ast_types.TypePointerMap.add type_ptr sil_type !CFrontend_config.sil_types_map
let get_type type_ptr =
try
Some (Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.pointer_type_index)
with Not_found -> Printing.log_stats "type with pointer %s not found\n" type_ptr; None
(* There is chance for success only if type_ptr is in fact clang pointer *)
(let raw_ptr = Clang_ast_types.type_ptr_to_clang_pointer type_ptr in
try
Some (Clang_ast_main.PointerMap.find raw_ptr !CFrontend_config.pointer_type_index)
with Not_found -> Printing.log_stats "type with pointer %s not found\n" raw_ptr; None)
with Clang_ast_types.Not_Clang_Pointer ->
(* otherwise, function fails *)
let type_str = Clang_ast_types.type_ptr_to_string type_ptr in
Printing.log_stats "type %s is not clang pointer\n" type_str;
None
let get_desugared_type type_ptr =
let typ_opt = get_type type_ptr in

@ -79,14 +79,17 @@ sig
val get_decl : Clang_ast_t.pointer -> Clang_ast_t.decl option
val update_sil_types_map : Clang_ast_t.pointer -> Sil.typ -> unit
val update_sil_types_map : Clang_ast_t.type_ptr -> Sil.typ -> unit
(** creates a string to append to a name from a list of qualifiers to a name *)
val get_qualifier_string : Clang_ast_t.named_decl_info -> string
val get_type : Clang_ast_t.pointer -> Clang_ast_t.c_type option
(** looks up clang pointer to type and returns c_type. It requires type_ptr to be `TPtr. *)
val get_type : Clang_ast_t.type_ptr -> Clang_ast_t.c_type option
val get_desugared_type : Clang_ast_t.pointer -> Clang_ast_t.c_type option
(** looks up clang pointer to type and resolves any sugar around it.
See get_type for more info and restrictions *)
val get_desugared_type : Clang_ast_t.type_ptr -> Clang_ast_t.c_type option
(** returns declaration of the type for certain types and crashes for others
NOTE: this function needs extending to handle objC types *)

@ -82,8 +82,7 @@ let get_return_type function_method_decl_info =
match function_method_decl_info with
| Func_decl_info (_, typ, _)
| Cpp_Meth_decl_info (_, _, typ)
| Block_decl_info (_, typ) ->
Ast_expressions.create_type_ptr_with_just_pointer (CTypes.return_type_of_function_type typ)
| Block_decl_info (_, typ) -> CTypes.return_type_of_function_type typ
| ObjC_Meth_decl_info (method_decl_info, _) -> method_decl_info.Clang_ast_t.omdi_result_type
let build_method_signature decl_info procname function_method_decl_info is_instance is_anonym_block is_generated =

@ -145,7 +145,8 @@ let get_predefined_ms_retain_release class_name method_name mk_procname lang =
if is_retain_method method_name || is_autorelease_method method_name
then Ast_expressions.create_id_type else Ast_expressions.create_void_type in
let class_name = CFrontend_config.nsobject_cl in
let args = [(CFrontend_config.self, class_name, None)] in
let class_type = Ast_expressions.create_class_type class_name in
let args = [(CFrontend_config.self, class_type, None)] in
get_predefined_ms_method condition class_name method_name Procname.Instance_objc_method
mk_procname lang args return_type [] (get_builtinname method_name)

@ -9,20 +9,6 @@
open CFrontend_utils
let custom_type_ptr_to_sil_type type_pointer =
if Utils.string_is_prefix "custom" type_pointer then
let typ =
(match CTypes.get_name_from_type_pointer type_pointer with
| "custom_class_name", class_name -> Sil.Tvar (CTypes.mk_classname class_name)
| "custom_pointer_custom_class_name", class_name ->
Sil.Tptr (Sil.Tvar (CTypes.mk_classname class_name), Sil.Pk_pointer)
| "custom_struct_name", struct_name -> Sil.Tvar (CTypes.mk_structname struct_name)
| "custom_pointer_custom_struct_name", struct_name ->
Sil.Tptr (Sil.Tvar (CTypes.mk_structname struct_name), Sil.Pk_pointer)
| _ -> assert false) in
Some typ
else None
let get_builtin_objc_typename builtin_type =
match builtin_type with
| `ObjCId -> Sil.TN_csu (Sil.Struct, (Mangled.from_string CFrontend_config.objc_object))
@ -74,7 +60,7 @@ let pointer_attribute_of_objc_attribute attr_info =
| `OCL_Autoreleasing -> Sil.Pk_objc_autoreleasing
let rec build_array_type translate_decl tenv type_ptr n =
let array_type = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in
let array_type = type_ptr_to_sil_type translate_decl tenv type_ptr in
let exp = Sil.exp_int (Sil.Int.of_int64 (Int64.of_int n)) in
Sil.Tarray (array_type, exp)
@ -83,9 +69,9 @@ and sil_type_of_attr_type translate_decl tenv type_info attr_info =
| Some type_ptr ->
(match Ast_utils.get_type type_ptr with
| Some Clang_ast_t.ObjCObjectPointerType (type_info', type_ptr') ->
let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr' in
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr' in
Sil.Tptr (typ, pointer_attribute_of_objc_attribute attr_info)
| _ -> type_ptr_ptr_to_sil_type translate_decl tenv type_ptr)
| _ -> type_ptr_to_sil_type translate_decl tenv type_ptr)
| None -> Sil.Tvoid
and sil_type_of_c_type translate_decl tenv c_type =
@ -96,14 +82,14 @@ and sil_type_of_c_type translate_decl tenv c_type =
sil_type_of_builtin_type_kind builtin_type_kind
| PointerType (type_info, type_ptr)
| ObjCObjectPointerType (type_info, type_ptr) ->
let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in
if Sil.typ_equal typ (get_builtin_objc_type `ObjCClass) then
typ
else Sil.Tptr (typ, Sil.Pk_pointer)
| ObjCObjectType (type_info, objc_object_type_info) ->
type_ptr_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type
type_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type
| BlockPointerType (type_info, type_ptr) ->
let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in
Sil.Tptr (typ, Sil.Pk_pointer)
| IncompleteArrayType (type_info, type_ptr)
| DependentSizedArrayType (type_info, type_ptr)
@ -115,32 +101,33 @@ and sil_type_of_c_type translate_decl tenv c_type =
| FunctionNoProtoType (type_info, function_type_info) ->
Sil.Tfun false
| ParenType (type_info, type_ptr) ->
type_ptr_ptr_to_sil_type translate_decl tenv type_ptr
type_ptr_to_sil_type translate_decl tenv type_ptr
| DecayedType (type_info, type_ptr) ->
type_ptr_ptr_to_sil_type translate_decl tenv type_ptr
type_ptr_to_sil_type translate_decl tenv type_ptr
| RecordType (type_info, pointer)
| EnumType (type_info, pointer) ->
decl_ptr_to_sil_type translate_decl tenv pointer
| ElaboratedType (type_info) ->
(match type_info.Clang_ast_t.ti_desugared_type with
Some type_ptr -> type_ptr_ptr_to_sil_type translate_decl tenv type_ptr
Some type_ptr -> type_ptr_to_sil_type translate_decl tenv type_ptr
| None -> Sil.Tvoid)
| ObjCInterfaceType (type_info, pointer) ->
decl_ptr_to_sil_type translate_decl tenv pointer
| LValueReferenceType (type_info, type_ptr) ->
let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in
let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in
Sil.Tptr (typ, Sil.Pk_reference)
| AttributedType (type_info, attr_info) ->
sil_type_of_attr_type translate_decl tenv type_info attr_info
| _ -> (* TypedefType, etc *)
let type_info = Clang_ast_proj.get_type_tuple c_type in
match type_info.Clang_ast_t.ti_desugared_type with
| Some typ -> type_ptr_ptr_to_sil_type translate_decl tenv typ
| Some typ -> type_ptr_to_sil_type translate_decl tenv typ
| None -> Sil.Tvoid
and decl_ptr_to_sil_type translate_decl tenv decl_ptr =
let open Clang_ast_t in
try Clang_ast_main.PointerMap.find decl_ptr !CFrontend_config.sil_types_map
let typ = `DeclPtr decl_ptr in
try Clang_ast_types.TypePointerMap.find typ !CFrontend_config.sil_types_map
with Not_found ->
match Ast_utils.get_decl decl_ptr with
| Some (ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, oidi)) ->
@ -158,19 +145,33 @@ and decl_ptr_to_sil_type translate_decl tenv decl_ptr =
(Clang_ast_j.string_of_pointer decl_ptr);
Sil.Tvoid
and type_ptr_ptr_to_sil_type translate_decl tenv type_ptr =
and clang_type_ptr_to_sil_type translate_decl tenv type_ptr =
try
Clang_ast_types.TypePointerMap.find type_ptr !CFrontend_config.sil_types_map
with Not_found ->
(match Ast_utils.get_type type_ptr with
| Some c_type ->
let sil_type = sil_type_of_c_type translate_decl tenv c_type in
Ast_utils.update_sil_types_map type_ptr sil_type;
sil_type
| _ -> Sil.Tvoid)
and prebuilt_type_to_sil_type type_ptr =
try
Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.sil_types_map
Clang_ast_types.TypePointerMap.find type_ptr !CFrontend_config.sil_types_map
with Not_found ->
match Ast_utils.get_type type_ptr with
| Some c_type ->
let sil_type = sil_type_of_c_type translate_decl tenv c_type in
Ast_utils.update_sil_types_map type_ptr sil_type;
sil_type
| _ -> Sil.Tvoid
Printing.log_stats "Prebuilt type %s not found\n"
(Clang_ast_types.type_ptr_to_string type_ptr);
assert false
and type_ptr_to_sil_type translate_decl tenv tp =
let type_ptr = tp in
match custom_type_ptr_to_sil_type type_ptr with
| Some typ -> typ
| None -> type_ptr_ptr_to_sil_type translate_decl tenv type_ptr
and type_ptr_to_sil_type translate_decl tenv type_ptr =
match type_ptr with
| `TPtr _ -> clang_type_ptr_to_sil_type translate_decl tenv type_ptr
| `Prebuilt _ -> prebuilt_type_to_sil_type type_ptr
| `PointerOf typ ->
let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in
Sil.Tptr (sil_typ, Sil.Pk_pointer)
| `ClassType name -> Sil.Tvar (CTypes.mk_classname name)
| `StructType name -> Sil.Tvar (CTypes.mk_structname name)
| `DeclPtr ptr -> decl_ptr_to_sil_type translate_decl tenv ptr
| `ErrorType -> Sil.Tvoid

@ -114,12 +114,12 @@ let rec return_type_of_function_type_ptr type_ptr =
return_type_of_function_type_ptr in_type_ptr
| Some _ ->
Printing.log_err "Warning: Type pointer %s is not a function type."
(Clang_ast_j.string_of_pointer type_ptr);
""
(Clang_ast_types.type_ptr_to_string type_ptr);
`ErrorType
| None ->
Printing.log_err "Warning: Type pointer %s not found."
(Clang_ast_j.string_of_pointer type_ptr);
""
(Clang_ast_types.type_ptr_to_string type_ptr);
`ErrorType
let return_type_of_function_type tp =
return_type_of_function_type_ptr tp

@ -29,7 +29,7 @@ val remove_pointer_to_typ : Sil.typ -> Sil.typ
val is_class : Sil.typ -> bool
val return_type_of_function_type : Clang_ast_t.type_ptr -> Clang_ast_t.pointer
val return_type_of_function_type : Clang_ast_t.type_ptr -> Clang_ast_t.type_ptr
val is_block_type : Clang_ast_t.type_ptr -> bool

@ -0,0 +1,52 @@
(*
* Copyright (c) 2015 - 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.
*)
(* This module adds more structure to some fields in AST *)
(* The implementation is replacement of default one from *)
(* facebook-clang-plugins repository *)
(* Type pointers *)
exception Not_Clang_Pointer
type t_ptr = [
| `TPtr of string
| `Prebuilt of string
| `PointerOf of t_ptr
| `ClassType of string
| `StructType of string
| `DeclPtr of string
| `ErrorType]
module TypePointerOrd = struct
type t = t_ptr
let compare = Pervasives.compare
end
module TypePointerMap = Map.Make(TypePointerOrd)
let rec type_ptr_to_string type_ptr = match type_ptr with
| `TPtr raw -> "clang_ptr_" ^ raw
| `Prebuilt raw -> "prebuilt_" ^ raw
| `PointerOf typ -> "pointer_of_" ^ type_ptr_to_string typ
| `ClassType name -> "class_name_" ^ name
| `StructType name -> "struct_name_" ^ name
| `DeclPtr raw -> "decl_ptr_" ^ raw
| `ErrorType -> "error_type"
let type_ptr_to_clang_pointer type_ptr = match type_ptr with
| `TPtr raw -> raw
| _ -> raise Not_Clang_Pointer
let pointer_to_type_ptr raw = `TPtr raw
let type_ptr_to_pointer type_ptr = match type_ptr with
| `TPtr raw -> raw
| _ -> "custom_type_" ^ (type_ptr_to_string type_ptr)

@ -121,7 +121,8 @@ let add_class_to_tenv tenv decl_info class_name decl_list obj_c_interface_decl_i
Sil.Tstruct(fields, [], Sil.Class, Some (Mangled.from_string class_name),
superclasses, methods, objc_class_annotation) in
Sil.tenv_add tenv interface_name interface_type_info;
Ast_utils.update_sil_types_map decl_info.Clang_ast_t.di_pointer (Sil.Tvar interface_name);
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
Ast_utils.update_sil_types_map decl_key (Sil.Tvar interface_name);
Printing.log_out
" >>>Verifying that Typename '%s' is in tenv\n" (Sil.typename_to_string interface_name);
(match Sil.tenv_lookup tenv interface_name with

Loading…
Cancel
Save