Use pointers to decls instead of class names when creating a type

Summary:
Class names fragile, easy to break and they introduce another level of indirection.
Since C++ translation doesn't need names, pass decl pointers everywhere.
Doing otherwise will most likely result in assert false.

Handling of class names in objc translation is more involving and it's left
for now. Later, objc can use same mechanism as C++.

Reviewed By: dulmarod

Differential Revision: D3570176

fbshipit-source-id: b957aba
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot 3
parent b9a5a3b5ad
commit e61b6fe719

@ -19,6 +19,7 @@ type curr_class =
(*class name and name of (optional) super class , and a list of protocols *) (*class name and name of (optional) super class , and a list of protocols *)
| ContextCategory of string * string (* category name and corresponding class *) | ContextCategory of string * string (* category name and corresponding class *)
| ContextProtocol of string (* category name and corresponding class *) | ContextProtocol of string (* category name and corresponding class *)
| ContextClsDeclPtr of Clang_ast_t.pointer
| ContextNoCls | ContextNoCls
type str_node_map = (string, Cfg.Node.t) Hashtbl.t type str_node_map = (string, Cfg.Node.t) Hashtbl.t
@ -83,8 +84,14 @@ let get_curr_class_name curr_class =
| ContextCls (name, _, _) -> name | ContextCls (name, _, _) -> name
| ContextCategory (_, cls) -> cls | ContextCategory (_, cls) -> cls
| ContextProtocol name -> name | ContextProtocol name -> name
| ContextClsDeclPtr _ -> assert false
| ContextNoCls -> assert false | ContextNoCls -> assert false
let get_curr_class_decl_ptr curr_class =
match curr_class with
| ContextClsDeclPtr ptr -> ptr
| _ -> assert false
let curr_class_to_string curr_class = let curr_class_to_string curr_class =
match curr_class with match curr_class with
| ContextCls (name, superclass, protocols) -> | ContextCls (name, superclass, protocols) ->
@ -92,6 +99,7 @@ let curr_class_to_string curr_class =
", protocols: " ^ (IList.to_string (fun x -> x) protocols)) ", protocols: " ^ (IList.to_string (fun x -> x) protocols))
| ContextCategory (name, cls) -> ("category " ^ name ^ " of class " ^ cls) | ContextCategory (name, cls) -> ("category " ^ name ^ " of class " ^ cls)
| ContextProtocol name -> ("protocol " ^ name) | ContextProtocol name -> ("protocol " ^ name)
| ContextClsDeclPtr ptr -> ("decl_ptr: " ^ string_of_int ptr)
| ContextNoCls -> "no class" | ContextNoCls -> "no class"
let curr_class_compare curr_class1 curr_class2 = let curr_class_compare curr_class1 curr_class2 =
@ -108,18 +116,15 @@ let curr_class_compare curr_class1 curr_class2 =
String.compare name1 name2 String.compare name1 name2
| ContextProtocol _, _ -> -1 | ContextProtocol _, _ -> -1
| _, ContextProtocol _ -> 1 | _, ContextProtocol _ -> 1
| ContextClsDeclPtr ptr1, ContextClsDeclPtr ptr2 ->
ptr1 - ptr2
| ContextClsDeclPtr _, _ -> -1
| _, ContextClsDeclPtr _ -> 1
| ContextNoCls, ContextNoCls -> 0 | ContextNoCls, ContextNoCls -> 0
let curr_class_equal curr_class1 curr_class2 = let curr_class_equal curr_class1 curr_class2 =
curr_class_compare curr_class1 curr_class2 == 0 curr_class_compare curr_class1 curr_class2 == 0
let curr_class_hash curr_class =
match curr_class with
| ContextCls (name, _, _) -> Hashtbl.hash name
| ContextCategory (name, cls) -> Hashtbl.hash (name, cls)
| ContextProtocol name -> Hashtbl.hash name
| ContextNoCls -> Hashtbl.hash "no class"
let create_curr_class tenv class_name ck = let create_curr_class tenv class_name ck =
let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in let class_tn_name = Typename.TN_csu (Csu.Class ck, (Mangled.from_string class_name)) in
match Tenv.lookup tenv class_tn_name with match Tenv.lookup tenv class_tn_name with
@ -158,4 +163,3 @@ let rec get_outer_procname context =
match context.outer_context with match context.outer_context with
| Some outer_context -> get_outer_procname outer_context | Some outer_context -> get_outer_procname outer_context
| None -> Cfg.Procdesc.get_proc_name context.procdesc | None -> Cfg.Procdesc.get_proc_name context.procdesc

@ -17,6 +17,7 @@ type curr_class =
(*class name and name of (optional) super class , and a list of protocols *) (*class name and name of (optional) super class , and a list of protocols *)
| ContextCategory of string * string (* category name and corresponding class *) | ContextCategory of string * string (* category name and corresponding class *)
| ContextProtocol of string (* category name and corresponding class *) | ContextProtocol of string (* category name and corresponding class *)
| ContextClsDeclPtr of Clang_ast_t.pointer
| ContextNoCls | ContextNoCls
type str_node_map = (string, Cfg.Node.t) Hashtbl.t type str_node_map = (string, Cfg.Node.t) Hashtbl.t
@ -46,14 +47,14 @@ val get_curr_class : t -> curr_class
val get_curr_class_name : curr_class -> string val get_curr_class_name : curr_class -> string
val get_curr_class_decl_ptr : curr_class -> Clang_ast_t.pointer
val curr_class_to_string : curr_class -> string val curr_class_to_string : curr_class -> string
val curr_class_compare : curr_class -> curr_class -> int val curr_class_compare : curr_class -> curr_class -> int
val curr_class_equal : curr_class -> curr_class -> bool val curr_class_equal : curr_class -> curr_class -> bool
val curr_class_hash : curr_class -> int
val is_objc_method : t -> bool val is_objc_method : t -> bool
val get_tenv : t -> Tenv.t val get_tenv : t -> Tenv.t

@ -213,16 +213,12 @@ struct
| CXXConversionDecl (decl_info, _, _, _, _) | CXXConversionDecl (decl_info, _, _, _, _)
| CXXDestructorDecl (decl_info, _, _, _, _) -> | CXXDestructorDecl (decl_info, _, _, _, _) ->
(* di_parent_pointer has pointer to lexical context such as class.*) (* di_parent_pointer has pointer to lexical context such as class.*)
let class_decl = match decl_info.Clang_ast_t.di_parent_pointer with let parent_ptr = Option.get decl_info.Clang_ast_t.di_parent_pointer in
| Some ptr -> let class_decl = Ast_utils.get_decl parent_ptr in
Ast_utils.get_decl ptr
| None ->
assert false in
(match class_decl with (match class_decl with
| Some (CXXRecordDecl _ as d) | Some (CXXRecordDecl _)
| Some (ClassTemplateSpecializationDecl _ as d) -> | Some (ClassTemplateSpecializationDecl _) ->
let class_name = CTypes_decl.get_record_name d in let curr_class = CContext.ContextClsDeclPtr parent_ptr in
let curr_class = CContext.ContextCls(class_name, None, []) in
if Config.cxx_experimental then if Config.cxx_experimental then
process_methods tenv cg cfg curr_class [dec] process_methods tenv cg cfg curr_class [dec]
| Some dec -> | Some dec ->

@ -30,8 +30,8 @@ type method_call_type =
type function_method_decl_info = type function_method_decl_info =
| Func_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.type_ptr * Config.clang_lang | Func_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.type_ptr * Config.clang_lang
| Cpp_Meth_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.cxx_method_decl_info * string * Clang_ast_t.type_ptr | Cpp_Meth_decl_info of Clang_ast_t.function_decl_info * Clang_ast_t.cxx_method_decl_info * Clang_ast_t.pointer * Clang_ast_t.type_ptr
| ObjC_Meth_decl_info of Clang_ast_t.obj_c_method_decl_info * string | ObjC_Meth_decl_info of Clang_ast_t.obj_c_method_decl_info * Clang_ast_t.pointer
| Block_decl_info of Clang_ast_t.block_decl_info * Clang_ast_t.type_ptr * CContext.t | Block_decl_info of Clang_ast_t.block_decl_info * Clang_ast_t.type_ptr * CContext.t
let is_instance_method function_method_decl_info = let is_instance_method function_method_decl_info =
@ -52,11 +52,11 @@ let get_original_return_type function_method_decl_info =
let get_class_param function_method_decl_info = let get_class_param function_method_decl_info =
if (is_instance_method function_method_decl_info) then if (is_instance_method function_method_decl_info) then
match function_method_decl_info with match function_method_decl_info with
| Cpp_Meth_decl_info (_, _, class_name, _) -> | Cpp_Meth_decl_info (_, _, class_decl_ptr, _) ->
let class_type = Ast_expressions.create_class_type (class_name, `CPP) in let class_type = `DeclPtr class_decl_ptr in
[(Mangled.from_string CFrontend_config.this, class_type)] [(Mangled.from_string CFrontend_config.this, class_type)]
| ObjC_Meth_decl_info (_, class_name) -> | ObjC_Meth_decl_info (_, class_decl_ptr) ->
let class_type = Ast_expressions.create_class_type (class_name, `OBJC) in let class_type = `DeclPtr class_decl_ptr in
[(Mangled.from_string CFrontend_config.self, class_type)] [(Mangled.from_string CFrontend_config.self, class_type)]
| _ -> [] | _ -> []
else [] else []
@ -181,7 +181,8 @@ let method_signature_of_decl tenv meth_decl block_data_opt =
let method_name = Ast_utils.get_unqualified_name name_info in let method_name = Ast_utils.get_unqualified_name name_info in
let class_name = Ast_utils.get_class_name_from_member name_info in let class_name = Ast_utils.get_class_name_from_member name_info in
let procname = General_utils.mk_procname_from_cpp_method class_name method_name tp in let procname = General_utils.mk_procname_from_cpp_method class_name method_name tp in
let method_decl = Cpp_Meth_decl_info (fdi, mdi, class_name, tp) in let parent_ptr = Option.get decl_info.di_parent_pointer in
let method_decl = Cpp_Meth_decl_info (fdi, mdi, parent_ptr, tp) 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
let ms = build_method_signature tenv decl_info procname method_decl parent_pointer None in let ms = build_method_signature tenv decl_info procname method_decl parent_pointer None in
let non_null_instrs = get_assume_not_null_calls fdi.Clang_ast_t.fdi_parameters in let non_null_instrs = get_assume_not_null_calls fdi.Clang_ast_t.fdi_parameters in
@ -190,7 +191,8 @@ let method_signature_of_decl tenv meth_decl block_data_opt =
| ObjCMethodDecl (decl_info, name_info, mdi), _ -> | ObjCMethodDecl (decl_info, name_info, mdi), _ ->
let class_name = Ast_utils.get_class_name_from_member name_info in let class_name = Ast_utils.get_class_name_from_member name_info in
let procname = get_objc_method_name name_info mdi class_name in let procname = get_objc_method_name name_info mdi class_name in
let method_decl = ObjC_Meth_decl_info (mdi, class_name) in let parent_ptr = Option.get decl_info.di_parent_pointer 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
let pointer_to_property_opt = let pointer_to_property_opt =
match mdi.Clang_ast_t.omdi_property_decl with match mdi.Clang_ast_t.omdi_property_decl with
@ -252,6 +254,7 @@ let get_superclass_curr_class_objc context =
| CContext.ContextCategory (_, cls) -> | CContext.ContextCategory (_, cls) ->
retrive_super cls None retrive_super cls None
| CContext.ContextNoCls | CContext.ContextNoCls
| CContext.ContextClsDeclPtr _
| CContext.ContextProtocol _ -> assert false | CContext.ContextProtocol _ -> assert false
(* Gets the class name from a method signature found by clang, if search is successful *) (* Gets the class name from a method signature found by clang, if search is successful *)

@ -2610,7 +2610,7 @@ struct
(* an input parameter. *) (* an input parameter. *)
and cxx_constructor_init_trans ctor_init trans_state = and cxx_constructor_init_trans ctor_init trans_state =
(*let tenv = trans_state.context.CContext.tenv in*) (*let tenv = trans_state.context.CContext.tenv in*)
let class_name = CContext.get_curr_class_name trans_state.context.CContext.curr_class in let class_ptr = CContext.get_curr_class_decl_ptr trans_state.context.CContext.curr_class in
let source_range = ctor_init.Clang_ast_t.xci_source_range in let source_range = ctor_init.Clang_ast_t.xci_source_range in
let sil_loc = CLocation.get_sil_location_from_range source_range true in let sil_loc = CLocation.get_sil_location_from_range source_range true in
(* its pointer will be used in PriorityNode *) (* its pointer will be used in PriorityNode *)
@ -2619,8 +2619,7 @@ struct
let child_stmt_info = let child_stmt_info =
{ (Ast_expressions.dummy_stmt_info ()) with Clang_ast_t.si_source_range = source_range } in { (Ast_expressions.dummy_stmt_info ()) with Clang_ast_t.si_source_range = source_range } in
let trans_state' = PriorityNode.try_claim_priority_node trans_state this_stmt_info in let trans_state' = PriorityNode.try_claim_priority_node trans_state this_stmt_info in
let class_type_ptr = Ast_expressions.create_pointer_type let class_type_ptr = Ast_expressions.create_pointer_type (`DeclPtr class_ptr) in
(Ast_expressions.create_class_type (class_name, `CPP)) in
let this_res_trans = this_expr_trans trans_state' sil_loc class_type_ptr in let this_res_trans = this_expr_trans trans_state' sil_loc class_type_ptr in
let var_res_trans = match ctor_init.Clang_ast_t.xci_subject with let var_res_trans = match ctor_init.Clang_ast_t.xci_subject with
| `Delegating _ | `BaseClass _ -> | `Delegating _ | `BaseClass _ ->

Loading…
Cancel
Save