Translate categories on demand

Summary: public Categories are now also only translated on demand.
For this we needed links from the class to the categories which we have
now.

Reviewed By: akotulski

Differential Revision: D2647072

fb-gh-sync-id: 4afdf5f
master
Dulma Rodriguez 9 years ago committed by facebook-github-bot-7
parent b2b2322db7
commit 7d5e129ac0

@ -21,6 +21,7 @@ open CGen_trans
(* Translate one global declaration *) (* Translate one global declaration *)
let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = let rec translate_one_declaration tenv cg cfg namespace parent_dec dec =
let open Clang_ast_t in
(* each procedure has different scope: start names from id 0 *) (* each procedure has different scope: start names from id 0 *)
Ident.NameGenerator.reset (); Ident.NameGenerator.reset ();
@ -29,85 +30,76 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec =
CLocation.update_curr_file info; CLocation.update_curr_file info;
let source_range = info.Clang_ast_t.di_source_range in let source_range = info.Clang_ast_t.di_source_range in
let should_translate_decl = CLocation.should_translate_lib source_range in let should_translate_decl = CLocation.should_translate_lib source_range in
let open Clang_ast_t in (if should_translate_decl then
match dec with
| FunctionDecl(di, name_info, tp, fdecl_info) ->
CMethod_declImpl.function_decl tenv cfg cg namespace dec None
(* Currently C/C++ record decl treated in the same way *)
| CXXRecordDecl (_, _, _, _, decl_list, _, _, _) | RecordDecl (_, _, _, _, decl_list, _, _) ->
ignore (CTypes_decl.add_types_from_decl_to_tenv tenv namespace dec);
let method_decls = CTypes_decl.get_method_decls dec decl_list in
let tranlate_method (parent, decl) =
translate_one_declaration tenv cg cfg namespace parent decl in
IList.iter tranlate_method method_decls
| ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, oi_decl_info) ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = ObjcInterface_decl.get_curr_class name oi_decl_info in
ignore
(ObjcInterface_decl.interface_declaration CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCProtocolDecl(decl_info, name_info, decl_list, decl_context_info, _) ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = CContext.ContextProtocol name in
ignore (ObjcProtocol_decl.protocol_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCCategoryDecl(decl_info, name_info, decl_list, decl_context_info, ocdi) ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = ObjcCategory_decl.get_curr_class_from_category_decl name ocdi in
ignore (ObjcCategory_decl.category_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCCategoryImplDecl(decl_info, name_info, decl_list, decl_context_info, ocidi) ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = ObjcCategory_decl.get_curr_class_from_category_impl name ocidi in
ignore (ObjcCategory_decl.category_impl_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCImplementationDecl(decl_info, name_info, decl_list, decl_context_info, idi) ->
let curr_class = ObjcInterface_decl.get_curr_class_impl idi in
let type_ptr_to_sil_type = CTypes_decl.type_ptr_to_sil_type in
ignore (ObjcInterface_decl.interface_impl_declaration type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list;
CFrontend_errors.check_for_property_errors cfg curr_class
| CXXMethodDecl (decl_info, name_info, type_ptr, function_decl_info, _)
| CXXConstructorDecl (decl_info, name_info, type_ptr, function_decl_info, _) ->
(* di_parent_pointer has pointer to lexical context such as class.*)
(* If it's not defined, then it's the same as parent in AST *)
let class_decl = match decl_info.Clang_ast_t.di_parent_pointer with
| Some ptr -> Ast_utils.get_decl ptr
| None -> Some parent_dec in
(match class_decl with
| Some (CXXRecordDecl _ as d) ->
let class_name = CTypes_decl.get_record_name d in
let curr_class = CContext.ContextCls(class_name, None, []) in
if !CFrontend_config.testing_mode then
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace [dec]
| Some dec -> Printing.log_stats "Methods of %s skipped\n" (Ast_utils.string_of_decl dec)
| None -> ())
| dec -> ());
match dec with match dec with
| FunctionDecl(di, name_info, tp, fdecl_info) when should_translate_decl ->
CMethod_declImpl.function_decl tenv cfg cg namespace dec None
| TypedefDecl (decl_info, name_info, opt_type, _, typedef_decl_info) ->
Printing.log_out "%s" "Skipping typedef declaration. Will expand the type in its occurrences."
(* Currently C/C++ record decl treated in the same way *)
| CXXRecordDecl (_, _, _, _, decl_list, _, _, _)
| RecordDecl (_, _, _, _, decl_list, _, _) when should_translate_decl ->
ignore (CTypes_decl.add_types_from_decl_to_tenv tenv namespace dec);
let method_decls = CTypes_decl.get_method_decls dec decl_list in
let tranlate_method (parent, decl) =
translate_one_declaration tenv cg cfg namespace parent decl in
IList.iter tranlate_method method_decls
| VarDecl(decl_info, name_info, t, _) ->
Printing.log_out "Nothing to do for global variable %s " name_info.Clang_ast_t.ni_name
| ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, oi_decl_info)
when should_translate_decl ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = ObjcInterface_decl.get_curr_class name oi_decl_info in
ignore (ObjcInterface_decl.interface_declaration CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCProtocolDecl(decl_info, name_info, decl_list, decl_context_info, obj_c_protocol_decl_info)
when should_translate_decl ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = CContext.ContextProtocol name in
ignore (ObjcProtocol_decl.protocol_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCCategoryDecl(decl_info, name_info, decl_list, decl_context_info, ocdi) ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = ObjcCategory_decl.get_curr_class_from_category_decl name ocdi in
ignore (ObjcCategory_decl.category_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCCategoryImplDecl(decl_info, name_info, decl_list, decl_context_info, ocidi) ->
let name = name_info.Clang_ast_t.ni_name in
let curr_class = ObjcCategory_decl.get_curr_class_from_category_impl name ocidi in
ignore (ObjcCategory_decl.category_impl_decl CTypes_decl.type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list
| ObjCImplementationDecl(decl_info, name_info, decl_list, decl_context_info, idi)
when should_translate_decl ->
let curr_class = ObjcInterface_decl.get_curr_class_impl idi in
let type_ptr_to_sil_type = CTypes_decl.type_ptr_to_sil_type in
ignore (ObjcInterface_decl.interface_impl_declaration type_ptr_to_sil_type tenv dec);
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace decl_list;
CFrontend_errors.check_for_property_errors cfg curr_class
| CXXMethodDecl (decl_info, name_info, type_ptr, function_decl_info, _)
| CXXConstructorDecl (decl_info, name_info, type_ptr, function_decl_info, _)
when should_translate_decl ->
(* di_parent_pointer has pointer to lexical context such as class.*)
(* If it's not defined, then it's the same as parent in AST *)
let class_decl = match decl_info.Clang_ast_t.di_parent_pointer with
| Some ptr -> Ast_utils.get_decl ptr
| None -> Some parent_dec in
(match class_decl with
| Some (CXXRecordDecl _ as d) ->
let class_name = CTypes_decl.get_record_name d in
let curr_class = CContext.ContextCls(class_name, None, []) in
if !CFrontend_config.testing_mode then
CMethod_declImpl.process_methods tenv cg cfg curr_class namespace [dec]
| Some dec -> Printing.log_stats "Methods of %s skipped\n" (Ast_utils.string_of_decl dec)
| None -> ())
| EnumDecl _ -> ignore (CEnum_decl.enum_decl dec) | EnumDecl _ -> ignore (CEnum_decl.enum_decl dec)
| LinkageSpecDecl(decl_info, decl_list, decl_context_info) -> | LinkageSpecDecl (decl_info, decl_list, decl_context_info) ->
Printing.log_out "ADDING: LinkageSpecDecl decl list\n"; Printing.log_out "ADDING: LinkageSpecDecl decl list\n";
IList.iter (translate_one_declaration tenv cg cfg namespace dec) decl_list IList.iter (translate_one_declaration tenv cg cfg namespace dec) decl_list
| NamespaceDecl(decl_info, name_info, decl_list, decl_context_info, _) -> | NamespaceDecl (decl_info, name_info, decl_list, decl_context_info, _) ->
let name = ns_suffix^name_info.Clang_ast_t.ni_name in let name = ns_suffix^name_info.Clang_ast_t.ni_name in
IList.iter (translate_one_declaration tenv cg cfg (Some name) dec) decl_list IList.iter (translate_one_declaration tenv cg cfg (Some name) dec) decl_list
| EmptyDecl _ ->
Printing.log_out "Passing from EmptyDecl. Treated as skip\n";
| dec -> () | dec -> ()
(* Translates a file by translating the ast into a cfg. *) (* Translates a file by translating the ast into a cfg. *)

@ -79,6 +79,9 @@ let add_super_class_decl type_ptr_to_sil_type tenv ocdi =
let add_protocols_decl type_ptr_to_sil_type tenv protocols = let add_protocols_decl type_ptr_to_sil_type tenv protocols =
Ast_utils.add_type_from_decl_ref_list type_ptr_to_sil_type tenv protocols Ast_utils.add_type_from_decl_ref_list type_ptr_to_sil_type tenv protocols
let add_categories_decl type_ptr_to_sil_type tenv categories =
Ast_utils.add_type_from_decl_ref_list type_ptr_to_sil_type tenv categories
let add_class_implementation type_ptr_to_sil_type tenv idi = let add_class_implementation type_ptr_to_sil_type tenv idi =
let decl_ref_opt = idi.Clang_ast_t.otdi_implementation in let decl_ref_opt = idi.Clang_ast_t.otdi_implementation in
Ast_utils.add_type_from_decl_ref type_ptr_to_sil_type tenv decl_ref_opt false Ast_utils.add_type_from_decl_ref type_ptr_to_sil_type tenv decl_ref_opt false
@ -170,6 +173,8 @@ let interface_declaration type_ptr_to_sil_type tenv decl =
let _ = add_class_implementation type_ptr_to_sil_type tenv ocidi in let _ = add_class_implementation type_ptr_to_sil_type tenv ocidi in
let _ = add_super_class_decl type_ptr_to_sil_type tenv ocidi in let _ = add_super_class_decl type_ptr_to_sil_type tenv ocidi in
let _ = add_protocols_decl type_ptr_to_sil_type tenv ocidi.Clang_ast_t.otdi_protocols in let _ = add_protocols_decl type_ptr_to_sil_type tenv ocidi.Clang_ast_t.otdi_protocols in
let known_categories = ocidi.Clang_ast_t.otdi_known_categories in
let _ = add_categories_decl type_ptr_to_sil_type tenv known_categories in
typ typ
| _ -> assert false | _ -> assert false

Loading…
Cancel
Save