[Sil] Create Typename.Obj/Cpp modules with constructors

Summary:
Provide proper constructor functions for all Typenames following `Typename.Java` module.
Always use those constructor functions.

Reviewed By: jeremydubreil

Differential Revision: D4673943

fbshipit-source-id: 81625c2
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent cb57578c74
commit 104acee99d

@ -23,7 +23,7 @@ let create_procname name =
let create_objc_class_method class_name method_name =
let method_kind = Procname.ObjCClassMethod in
let tname = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string class_name) in
let tname = Typename.Objc.from_string class_name in
let pname = Procname.ObjC_Cpp (Procname.objc_cpp tname method_name method_kind) in
register pname;
pname

@ -49,15 +49,6 @@ let get_mangled pn =>
};
/** Create a mangled type name from a package name and a class name */
let from_package_class package_name class_name =>
if (String.equal package_name "") {
from_string class_name
} else {
from_string (package_name ^ "." ^ class_name)
};
/** Pretty print a mangled name */
let pp f pn => F.fprintf f "%s" (to_string pn);

@ -24,10 +24,6 @@ let equal: t => t => bool;
let from_string: string => t;
/** Create a mangled type name from a package name and a class name */
let from_package_class: string => string => t;
/** Create a mangled name from a plain and mangled string */
let mangled: string => string => t;

@ -28,18 +28,44 @@ let name =
fun
| TN_csu _ name => Mangled.to_string name;
let from_string_kind class_kind class_name_str =>
TN_csu (Csu.Class class_kind) (Mangled.from_string class_name_str);
let is_class_kind class_kind =>
fun
| TN_csu (Class kind) _ when Csu.equal_class_kind class_kind kind => true
| _ => false;
let module C = {
let from_string name_str => TN_csu Csu.Struct (Mangled.from_string name_str);
let union_from_string name_str => TN_csu Csu.Union (Mangled.from_string name_str);
};
let module Java = {
let from_string class_name_str =>
TN_csu (Csu.Class Csu.Java) (Mangled.from_string class_name_str);
let is_class =
fun
| TN_csu (Class Java) _ => true
| _ => false;
let from_string = from_string_kind Csu.Java;
let from_package_class package_name class_name =>
if (String.equal package_name "") {
from_string class_name
} else {
from_string (package_name ^ "." ^ class_name)
};
let is_class = is_class_kind Csu.Java;
let java_lang_object = from_string "java.lang.Object";
let java_io_serializable = from_string "java.io.Serializable";
let java_lang_cloneable = from_string "java.lang.Cloneable";
};
let module Cpp = {
let from_string = from_string_kind Csu.CPP;
let is_class = is_class_kind Csu.CPP;
};
let module Objc = {
let from_string = from_string_kind Csu.Objc;
let protocol_from_string name_str => TN_csu Csu.Protocol (Mangled.from_string name_str);
let is_class = is_class_kind Csu.Objc;
};
let module Set = Caml.Set.Make {
type nonrec t = t;
let compare = compare;

@ -28,11 +28,16 @@ let pp: Format.formatter => t => unit;
/** name of the typename without qualifier */
let name: t => string;
let module C: {let from_string: string => t; let union_from_string: string => t;};
let module Java: {
/** Create a typename from a Java classname in the form "package.class" */
let from_string: string => t;
/** Create a typename from a package name and a class name */
let from_package_class: string => string => t;
/** [is_class name] holds if [name] names a Java class */
let is_class: t => bool;
let java_lang_object: t;
@ -40,4 +45,23 @@ let module Java: {
let java_lang_cloneable: t;
};
let module Cpp: {
/** Create a typename from a C++ classname */
let from_string: string => t;
/** [is_class name] holds if [name] names a C++ class */
let is_class: t => bool;
};
let module Objc: {
/** Create a typename from a Objc classname */
let from_string: string => t;
let protocol_from_string: string => t;
/** [is_class name] holds if [name] names a Objc class */
let is_class: t => bool;
};
let module Set: Caml.Set.S with type elt = t;

@ -1506,8 +1506,7 @@ let expand_hpred_pointer =
| Sizeof (cnt_typ, len, st) ->
(* type of struct at adr_base is unknown (typically Tvoid), but
type of contents is known, so construct struct type for single fld:cnt_typ *)
let mangled = Mangled.from_string ("counterfeit" ^ string_of_int !count) in
let name = Typename.TN_csu (Struct, mangled) in
let name = Typename.C.from_string ("counterfeit" ^ string_of_int !count) in
incr count ;
let fields = [(fld, cnt_typ, Annot.Item.empty)] in
ignore (Tenv.mk_struct tenv ~fields name) ;

@ -273,7 +273,7 @@ let java_method_to_procname java_method =
(* turn string specificiation of an objc method into a procname *)
let objc_method_to_procname objc_method =
let method_kind = Procname.objc_method_kind_of_bool (not objc_method.is_static) in
let typename = Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string objc_method.classname) in
let typename = Typename.Objc.from_string objc_method.classname in
Procname.ObjC_Cpp
(Procname.objc_cpp typename objc_method.method_name method_kind)

@ -194,8 +194,7 @@ let callback_check_write_to_parcel_java
String.equal (Procname.java_get_method pname_java) "writeToParcel" in
let expr_match () = Exp.is_this this_expr in
let type_match () =
let class_name =
Typename.TN_csu (Csu.Class Csu.Java, Mangled.from_string "android.os.Parcelable") in
let class_name = Typename.Java.from_string "android.os.Parcelable" in
match this_type with
| Typ.Tptr (Tstruct name, _) | Tstruct name ->
PatternMatch.is_immediate_subtype tenv name class_name

@ -252,8 +252,7 @@ let type_is_class typ =
| _ -> false
let initializer_classes =
List.map
~f:(fun name -> Typename.TN_csu (Csu.Class Csu.Java, Mangled.from_string name))
List.map ~f:Typename.Java.from_string
[
"android.app.Activity";
"android.app.Application";

@ -21,18 +21,14 @@ let remove_pointer_to_typ typ =
| Typ.Tptr(typ, Typ.Pk_pointer) -> typ
| _ -> typ
let mk_classname n ck = Typename.TN_csu (Csu.Class ck, Mangled.from_string n)
let mk_structname n = Typename.TN_csu (Csu.Struct, Mangled.from_string n)
let objc_classname_of_type typ =
match typ with
| Typ.Tstruct name -> name
| Typ.Tfun _ -> mk_classname CFrontend_config.objc_object Csu.Objc
| Typ.Tfun _ -> Typename.Objc.from_string CFrontend_config.objc_object
| _ ->
Logging.out_debug
"Classname of type cannot be extracted in type %s" (Typ.to_string typ);
mk_classname "undefined" Csu.Objc
Typename.Objc.from_string "undefined"
let is_class typ =
match typ with

@ -15,10 +15,6 @@ val add_pointer_to_typ : Typ.t -> Typ.t
val objc_classname_of_type : Typ.t -> Typename.t
val mk_classname : string -> Csu.class_kind -> Typename.t
val mk_structname : string -> Typename.t
val remove_pointer_to_typ : Typ.t -> Typ.t
val is_class : Typ.t -> bool

@ -32,7 +32,7 @@ let add_predefined_basic_types () =
CAst_utils.update_sil_types_map tp return_type in
let sil_void_type = CType_to_sil_type.sil_type_of_builtin_type_kind `Void in
let sil_char_type = CType_to_sil_type.sil_type_of_builtin_type_kind `Char_S in
let sil_nsarray_type = Typ.Tstruct (CType.mk_classname CFrontend_config.nsarray_cl Csu.Objc) in
let sil_nsarray_type = Typ.Tstruct (Typename.Objc.from_string CFrontend_config.nsarray_cl) in
let sil_id_type = CType_to_sil_type.get_builtin_objc_type `ObjCId in
add_basic_type create_int_type `Int;
add_basic_type create_void_type `Void;
@ -50,44 +50,37 @@ let add_predefined_types tenv =
add_predefined_objc_types tenv;
add_predefined_basic_types ()
let create_csu opt_type =
let create_c_record_typename opt_type =
match opt_type with
| `Type s ->
(let buf = Str.split (Str.regexp "[ \t]+") s in
match buf with
| "struct":: _ ->Csu.Struct
| "class":: _ -> Csu.Class Csu.CPP
| "union":: _ -> Csu.Union
| _ -> Csu.Struct)
| "struct":: _ -> Typename.C.from_string
| "class":: _ -> Typename.Cpp.from_string
| "union":: _ -> Typename.C.union_from_string
| _ -> Typename.C.from_string)
| _ -> assert false
(* We need to take the name out of the type as the struct can be anonymous*)
let get_record_name_csu decl =
let get_record_typename decl =
let open Clang_ast_t in
let name_info, csu = match decl with
| RecordDecl (_, name_info, opt_type, _, _, _, _) ->
name_info, create_csu opt_type
| CXXRecordDecl (_, name_info, _, _, _, _, _, _)
| ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _) ->
(* we use Csu.Class for C++ because we expect Csu.Class csu from *)
(* types that have methods. And in C++ struct/class/union can have methods *)
name_info, Csu.Class Csu.CPP
| ObjCInterfaceDecl (_, name_info, _, _, _)
| ObjCImplementationDecl (_, name_info, _, _, _)
| ObjCProtocolDecl (_, name_info, _, _, _)
| ObjCCategoryDecl (_, name_info, _, _, _)
| ObjCCategoryImplDecl (_, name_info, _, _, _) ->
name_info, Csu.Class Csu.Objc
| _ -> assert false in
let name = CAst_utils.get_qualified_name name_info in
csu, name
let get_record_name decl = snd (get_record_name_csu decl)
match decl with
| RecordDecl (_, name_info, opt_type, _, _, _, _) ->
CAst_utils.get_qualified_name name_info |> create_c_record_typename opt_type
| CXXRecordDecl (_, name_info, _, _, _, _, _, _)
| ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _) ->
(* we use Csu.Class for C++ because we expect Csu.Class csu from *)
(* types that have methods. And in C++ struct/class/union can have methods *)
CAst_utils.get_qualified_name name_info |> Typename.Cpp.from_string
| ObjCInterfaceDecl (_, name_info, _, _, _)
| ObjCImplementationDecl (_, name_info, _, _, _)
| ObjCProtocolDecl (_, name_info, _, _, _)
| ObjCCategoryDecl (_, name_info, _, _, _)
| ObjCCategoryImplDecl (_, name_info, _, _, _) ->
CAst_utils.get_qualified_name name_info |> Typename.Objc.from_string
| _ -> assert false
let get_record_typename decl =
let csu, name = get_record_name_csu decl in
let mangled_name = Mangled.from_string name in
Typename.TN_csu (csu, mangled_name)
let get_record_name decl = get_record_typename decl |> Typename.name
let get_class_template_name = function
| Clang_ast_t.ClassTemplateDecl (_, name_info, _ ) -> CAst_utils.get_qualified_name name_info
@ -109,9 +102,7 @@ let get_superclass_decls decl =
(** fetches list of superclasses for C++ classes *)
let get_superclass_list_cpp decl =
let base_decls = get_superclass_decls decl in
let decl_to_mangled_name decl = Mangled.from_string (get_record_name decl) in
let get_super_field super_decl =
Typename.TN_csu (Csu.Class Csu.CPP, decl_to_mangled_name super_decl) in
let get_super_field super_decl = Typename.Cpp.from_string (get_record_name super_decl) in
List.map ~f:get_super_field base_decls
let get_translate_as_friend_decl decl_list =
@ -197,16 +188,16 @@ and get_record_struct_type tenv definition_decl =
| CXXRecordDecl (_, _, _, type_ptr, _, _, record_decl_info, _)
| RecordDecl (_, _, _, type_ptr, _, _, record_decl_info) ->
let sil_typename = get_record_typename definition_decl in
let csu, name = get_record_name_csu definition_decl in
(match Tenv.lookup tenv sil_typename with
| Some _ -> Typ.Tstruct sil_typename (* just reuse what is already in tenv *)
| None ->
let is_complete_definition = record_decl_info.Clang_ast_t.rdi_is_complete_definition in
let extra_fields = if CTrans_models.is_objc_memory_model_controlled name then
let extra_fields =
if CTrans_models.is_objc_memory_model_controlled (Typename.name sil_typename) then
[Typ.Struct.objc_ref_counter_field]
else [] in
let annots =
if Csu.equal csu (Csu.Class Csu.CPP) then Annot.Class.cpp
if Typename.Cpp.is_class sil_typename then Annot.Class.cpp
else Annot.Item.empty (* No annotations for structs *) in
if is_complete_definition then (
CAst_utils.update_sil_types_map type_ptr (Typ.Tstruct sil_typename);

@ -111,7 +111,7 @@ let create_class_qual_type ?(is_const=false) typename =
create_qual_type ~is_const @@ create_class_type typename
let make_objc_class_type class_name =
create_class_type (Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string class_name))
create_class_type (Typename.Objc.from_string class_name)
let create_struct_type struct_name = `StructType struct_name

@ -24,12 +24,12 @@ let rec get_fields_super_classes tenv super_class =
CGeneral_utils.append_no_duplicates_fields fields sc_fields
| Some { fields } -> fields
let fields_superclass tenv interface_decl_info ck =
let fields_superclass tenv interface_decl_info =
match interface_decl_info.Clang_ast_t.otdi_super with
| Some dr ->
(match dr.Clang_ast_t.dr_name with
| Some sc ->
let classname = CType.mk_classname (CAst_utils.get_qualified_name sc) ck in
let classname = Typename.Objc.from_string (CAst_utils.get_qualified_name sc) in
get_fields_super_classes tenv classname
| _ -> [])
| _ -> []
@ -77,9 +77,8 @@ let rec get_fields type_ptr_to_sil_type tenv decl_list =
(* Add potential extra fields defined only in the implementation of the class *)
(* to the info given in the interface. Update the tenv accordingly. *)
let add_missing_fields tenv class_name ck missing_fields =
let mang_name = Mangled.from_string class_name in
let class_tn_name = Typename.TN_csu (Csu.Class ck, mang_name) in
let add_missing_fields tenv class_name missing_fields =
let class_tn_name = Typename.Objc.from_string class_name in
match Tenv.lookup tenv class_tn_name with
| Some ({ fields } as struct_typ) ->
let new_fields = CGeneral_utils.append_no_duplicates_fields fields missing_fields in

@ -16,12 +16,11 @@ type field_type = Ident.fieldname * Typ.t * (Annot.t * bool) list
val get_fields : CAst_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.decl list ->
field_type list
val fields_superclass :
Tenv.t -> Clang_ast_t.obj_c_interface_decl_info -> Csu.class_kind -> field_type list
val fields_superclass : Tenv.t -> Clang_ast_t.obj_c_interface_decl_info -> field_type list
val build_sil_field : CAst_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.named_decl_info ->
Clang_ast_t.type_ptr -> Clang_ast_t.property_attribute list -> field_type
val add_missing_fields : Tenv.t -> string -> Csu.class_kind -> field_type list -> unit
val add_missing_fields : Tenv.t -> string -> field_type list -> unit
val modelled_field : Clang_ast_t.named_decl_info -> field_type list

@ -250,7 +250,7 @@ let get_superclass_curr_class_objc context =
super_of_decl_ref_opt ocidi.ocidi_class_interface
| _ -> assert false in
match CContext.get_curr_class context with
| CContext.ContextClsDeclPtr ptr -> CType.mk_classname (retreive_super_name ptr) Csu.Objc
| CContext.ContextClsDeclPtr ptr -> Typename.Objc.from_string (retreive_super_name ptr)
| CContext.ContextNoCls -> assert false
(* Gets the class name from a method signature found by clang, if search is successful *)

@ -116,16 +116,16 @@ struct
Logging.out_debug "Block %s field:\n" block_name;
List.iter ~f:(fun (fn, _, _) ->
Logging.out_debug "-----> field: '%s'\n" (Ident.fieldname_to_string fn)) fields;
let mblock = Mangled.from_string block_name in
let block_name = Typename.TN_csu (Csu.Class Csu.Objc, mblock) in
ignore (Tenv.mk_struct tenv ~fields block_name);
let block_type = Typ.Tstruct block_name in
let block_typename = Typename.Objc.from_string block_name in
ignore (Tenv.mk_struct tenv ~fields block_typename);
let block_type = Typ.Tstruct block_typename in
let trans_res =
CTrans_utils.alloc_trans
trans_state loc (Ast_expressions.dummy_stmt_info ()) block_type true None in
let id_block = match trans_res.exps with
| [(Exp.Var id, _)] -> id
| _ -> assert false in
let mblock = Mangled.from_string block_name in
let block_var = Pvar.mk mblock procname in
let declare_block_local =
Sil.Declare_locals ([(block_var, Typ.Tptr (block_type, Typ.Pk_pointer))], loc) in
@ -566,8 +566,8 @@ struct
type_ptr with
| Some builtin_pname -> builtin_pname
| None ->
let class_typename = CType.mk_classname
(CAst_utils.get_class_name_from_member name_info) Csu.CPP in
let class_typename = Typename.Cpp.from_string
(CAst_utils.get_class_name_from_member name_info) in
CMethod_trans.create_procdesc_with_pointer context decl_ptr (Some class_typename)
method_name in
let method_exp = (Exp.Const (Const.Cfun pname), method_typ) in

@ -158,7 +158,7 @@ let get_predefined_ms_retain_release method_name mk_procname lang =
let return_type =
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_typename = CType.mk_classname CFrontend_config.nsobject_cl Csu.Objc in
let class_typename = Typename.Objc.from_string CFrontend_config.nsobject_cl in
let class_type = Ast_expressions.create_class_qual_type class_typename in
let args = [(Mangled.from_string CFrontend_config.self, class_type)] in
get_predefined_ms_method condition class_typename method_name Procname.ObjCInstanceMethod

@ -11,8 +11,8 @@ open! IStd
let get_builtin_objc_typename builtin_type =
match builtin_type with
| `ObjCId -> Typename.TN_csu (Csu.Struct, (Mangled.from_string CFrontend_config.objc_object))
| `ObjCClass -> Typename.TN_csu (Csu.Struct, (Mangled.from_string CFrontend_config.objc_class))
| `ObjCId -> Typename.C.from_string CFrontend_config.objc_object
| `ObjCClass -> Typename.C.from_string CFrontend_config.objc_class
let get_builtin_objc_type builtin_type =
let typ = Typ.Tstruct (get_builtin_objc_typename builtin_type) in

@ -59,7 +59,7 @@ let get_base_class_name_from_category decl =
| Some decl_ref ->
(match CAst_utils.get_decl decl_ref.Clang_ast_t.dr_decl_pointer with
| Some ObjCInterfaceDecl (_, name_info, _, _, _) ->
Some (CType.mk_classname (CAst_utils.get_qualified_name name_info) Csu.Objc)
Some (Typename.Objc.from_string (CAst_utils.get_qualified_name name_info))
| _ -> None)
| None -> None
@ -67,8 +67,7 @@ let get_base_class_name_from_category decl =
(* to the corresponding class. Update the tenv accordingly.*)
let process_category type_ptr_to_sil_type tenv class_name decl_info decl_list =
let decl_fields = CField_decl.get_fields type_ptr_to_sil_type tenv decl_list in
let mang_name = Mangled.from_string class_name in
let class_tn_name = Typename.TN_csu (Csu.Class Csu.Objc, mang_name) in
let class_tn_name = Typename.Objc.from_string class_name in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
CAst_utils.update_sil_types_map decl_key (Typ.Tstruct class_tn_name);
(match Tenv.lookup tenv class_tn_name with

@ -60,10 +60,8 @@ let get_interface_supers super_opt protocols =
let super_class =
match super_opt with
| None -> []
| Some super -> [Typename.TN_csu (Csu.Class Csu.Objc, Mangled.from_string super)] in
let protocol_names = List.map ~f:(
fun name -> Typename.TN_csu (Csu.Protocol, Mangled.from_string name)
) protocols in
| Some super -> [Typename.Objc.from_string super] in
let protocol_names = List.map ~f:Typename.Objc.protocol_from_string protocols in
let super_classes = super_class@protocol_names in
super_classes
@ -79,14 +77,14 @@ let create_supers_fields type_ptr_to_sil_type tenv decl_list
let add_class_to_tenv type_ptr_to_sil_type tenv decl_info name_info decl_list ocidi =
let class_name = CAst_utils.get_qualified_name name_info in
Logging.out_debug "ADDING: ObjCInterfaceDecl for '%s'\n" class_name;
let interface_name = CType.mk_classname class_name Csu.Objc in
let interface_name = Typename.Objc.from_string class_name in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
CAst_utils.update_sil_types_map decl_key (Typ.Tstruct interface_name);
let decl_supers, decl_fields =
create_supers_fields type_ptr_to_sil_type tenv decl_list
ocidi.Clang_ast_t.otdi_super
ocidi.Clang_ast_t.otdi_protocols in
let fields_sc = CField_decl.fields_superclass tenv ocidi Csu.Objc in
let fields_sc = CField_decl.fields_superclass tenv ocidi in
List.iter ~f:(fun (fn, ft, _) ->
Logging.out_debug "----->SuperClass field: '%s' " (Ident.fieldname_to_string fn);
Logging.out_debug "type: '%s'\n" (Typ.to_string ft)) fields_sc;
@ -141,8 +139,8 @@ let interface_impl_declaration type_ptr_to_sil_type tenv decl =
Logging.out_debug "ADDING: ObjCImplementationDecl for class '%s'\n" class_name;
let _ = add_class_decl type_ptr_to_sil_type tenv idi in
let fields = CField_decl.get_fields type_ptr_to_sil_type tenv decl_list in
CField_decl.add_missing_fields tenv class_name Csu.Objc fields;
let class_tn_name = Typename.TN_csu (Csu.Class Csu.Objc, (Mangled.from_string class_name)) in
CField_decl.add_missing_fields tenv class_name fields;
let class_tn_name = Typename.Objc.from_string class_name in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
let class_typ = Typ.Tstruct class_tn_name in
CAst_utils.update_sil_types_map decl_key class_typ;

@ -25,8 +25,7 @@ let protocol_decl type_ptr_to_sil_type tenv decl =
(* Here we are giving a similar treatment as interfaces (see above)*)
(* It may turn out that we need a more specific treatment for protocols*)
Logging.out_debug "ADDING: ObjCProtocolDecl for '%s'\n" name;
let mang_name = Mangled.from_string name in
let protocol_name = Typename.TN_csu (Csu.Protocol, mang_name) in
let protocol_name = Typename.Objc.protocol_from_string name in
let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in
CAst_utils.update_sil_types_map decl_key (Typ.Tstruct protocol_name);
ignore( Tenv.mk_struct tenv ~methods:[] protocol_name );

@ -58,7 +58,7 @@ let android_lifecycles =
let is_subtype_package_class tenv tname package classname =
PatternMatch.is_subtype tenv
tname (Typename.TN_csu (Class Java, Mangled.from_package_class package classname))
tname (Typename.Java.from_package_class package classname)
let is_context tenv tname =
is_subtype_package_class tenv tname "android.content" "Context"

@ -37,7 +37,7 @@ let try_create_lifecycle_trace name lifecycle_name lifecycle_procs tenv =
(** generate a harness for a lifecycle type in an Android application *)
let create_harness cfg cg tenv =
List.iter ~f:(fun (pkg, clazz, lifecycle_methods) ->
let typname = Typename.TN_csu (Class Java, Mangled.from_package_class pkg clazz) in
let typname = Typename.Java.from_package_class pkg clazz in
let framework_procs =
AndroidFramework.get_lifecycle_for_framework_typ_opt tenv typname lifecycle_methods in
(* iterate through the type environment and generate a lifecycle harness for each

Loading…
Cancel
Save