diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index 53a3cd0bf..87ded84f0 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -35,11 +35,9 @@ let rec translate_one_declaration tenv cg cfg namespace parent_dec dec = CTypes_decl.do_typedef_declaration tenv namespace decl_info name opt_type typedef_decl_info (* Currently C/C++ record decl treated in the same way *) - | CXXRecordDecl (decl_info, name_info, opt_type, _, decl_list, decl_context_info, record_decl_info, _) - | RecordDecl (decl_info, name_info, opt_type, _, decl_list, decl_context_info, record_decl_info) -> - let record_name = name_info.Clang_ast_t.ni_name in - CTypes_decl.do_record_declaration tenv namespace - decl_info record_name opt_type decl_list decl_context_info record_decl_info; + | CXXRecordDecl (_, _, _, _, decl_list, _, _, _) + | RecordDecl (_, _, _, _, decl_list, _, _) -> + 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 diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index f25b05224..593c33809 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -195,23 +195,19 @@ and do_typedef_declaration tenv namespace decl_info name opt_type typedef_decl_i and get_struct_fields tenv record_name namespace decl_list = let open Clang_ast_t in - match decl_list with - | [] -> [] - | FieldDecl(decl_info, name_info, qual_type, field_decl_info):: decl_list' -> - let field_name = name_info.Clang_ast_t.ni_name in - Printing.log_out " ...Defining field '%s'.\n" field_name; - let id = General_utils.mk_class_field_name record_name field_name in - let typ = qual_type_to_sil_type tenv qual_type in - let annotation_items = [] in (* For the moment we don't use them*) - (id, typ, annotation_items):: get_struct_fields tenv record_name namespace decl_list' - | CXXRecordDecl (decl_info, name, opt_type, _, decl_list, decl_context_info, record_decl_info, _) - :: decl_list' - (* C++/C Records treated in the same way*) - | RecordDecl (decl_info, name, opt_type, _, decl_list, decl_context_info, record_decl_info) - :: decl_list'-> - do_record_declaration tenv namespace decl_info name.Clang_ast_t.ni_name opt_type decl_list decl_context_info record_decl_info; - get_struct_fields tenv record_name namespace decl_list' - | _ :: decl_list' -> get_struct_fields tenv record_name namespace decl_list' + let do_one_decl decl = match decl with + | FieldDecl (_, name_info, qual_type, _) -> + let field_name = name_info.Clang_ast_t.ni_name in + Printing.log_out " ...Defining field '%s'.\n" field_name; + let id = General_utils.mk_class_field_name record_name field_name in + let typ = qual_type_to_sil_type tenv qual_type in + let annotation_items = [] in (* For the moment we don't use them*) + [(id, typ, annotation_items)] + | CXXRecordDecl _ | RecordDecl _ -> + (* C++/C Records treated in the same way*) + add_types_from_decl_to_tenv tenv namespace decl; [] + | _ -> [] in + list_flatten (list_map do_one_decl decl_list) and get_class_methods tenv class_name namespace decl_list = let process_method_decl = function @@ -224,17 +220,26 @@ and get_class_methods tenv class_name namespace decl_list = (* poor mans list_filter_map *) list_flatten_options (list_map process_method_decl decl_list) -and do_record_declaration tenv namespace decl_info name opt_type decl_list decl_context_info record_decl_info = - Printing.log_out "ADDING: RecordDecl for '%s'" name; - Printing.log_out " pointer= '%s'\n" decl_info.Clang_ast_t.di_pointer; - if not record_decl_info.Clang_ast_t.rdi_is_complete_definition then - Printing.log_err " ...Warning, definition incomplete. The full definition will probably be later \n@."; - let typ = get_declaration_type tenv namespace decl_info name opt_type decl_list decl_context_info record_decl_info in +and add_types_from_decl_to_tenv tenv namespace decl = + let typ = get_declaration_type tenv namespace decl in let typ = expand_structured_type tenv typ in add_struct_to_tenv tenv typ (* For a record declaration it returns/constructs the type *) -and get_declaration_type tenv namespace decl_info n opt_type decl_list decl_context_info record_decl_info = +and get_declaration_type tenv namespace decl = + let open Clang_ast_t in + let n, opt_type, decl_list = match decl with + | CXXRecordDecl (decl_info, name_info, opt_type, _, decl_list, _, record_decl_info, _) + | RecordDecl (decl_info, name_info, opt_type, _, decl_list, _, record_decl_info) -> + let ptr = decl_info.Clang_ast_t.di_pointer in + let name = name_info.Clang_ast_t.ni_name in + Printing.log_out "ADDING: RecordDecl for '%s'" name; + Printing.log_out " pointer= '%s'\n" ptr; + if not record_decl_info.Clang_ast_t.rdi_is_complete_definition then + Printing.log_err " ...Warning, definition incomplete. The full definition will probably be later \n@."; + name, opt_type, decl_list + | _ -> assert false in + let ns_suffix = Ast_utils.namespace_to_string namespace in let n = ns_suffix^n in let name_str = get_record_name opt_type in @@ -253,7 +258,7 @@ and get_declaration_type tenv namespace decl_info n opt_type decl_list decl_cont | _ -> Sil.Struct) in let name = Some (Mangled.from_string name_str) in let methods_list = get_class_methods tenv name_str namespace decl_list in (* C++ methods only *) - let superclass_list = [] in (* No super class for structs *) + let superclass_list = [] in let item_annotation = Sil.item_annotation_empty in (* No annotations for struts *) Sil.Tstruct (non_static_fields, static_fields, csu, name, superclass_list, methods_list, item_annotation) @@ -268,12 +273,8 @@ and add_late_defined_record tenv namespace typename = let rec scan decls = match decls with | [] -> false - | CXXRecordDecl - (decl_info, record_name, opt_type, _, decl_list, decl_context_info, record_decl_info, _) - :: decls' - | RecordDecl - (decl_info, record_name, opt_type, _, decl_list, decl_context_info, record_decl_info) - :: decls' -> + | (CXXRecordDecl (_, _, opt_type, _, _, _, record_decl_info, _) as d) :: decls' + | (RecordDecl (_, _, opt_type, _, _, _, record_decl_info) as d) :: decls' -> (match opt_type with | `Type t -> (* the string t contains the name of the type preceded by the word struct. *) @@ -284,8 +285,7 @@ and add_late_defined_record tenv namespace typename = Sil.typename_equal typename pot_union_type) && record_decl_info.Clang_ast_t.rdi_is_complete_definition then ( Printing.log_out "!!!! Adding late-defined record '%s'\n" t; - do_record_declaration tenv namespace decl_info record_name.Clang_ast_t.ni_name opt_type decl_list - decl_context_info record_decl_info; + add_types_from_decl_to_tenv tenv namespace d; true) else scan decls' | _ -> scan decls') diff --git a/infer/src/clang/cTypes_decl.mli b/infer/src/clang/cTypes_decl.mli index 955c6216f..17ae05cd1 100644 --- a/infer/src/clang/cTypes_decl.mli +++ b/infer/src/clang/cTypes_decl.mli @@ -9,9 +9,7 @@ (** Processes types and record declarations by adding them to the tenv *) -val get_declaration_type : Sil.tenv -> string option -> Clang_ast_t.decl_info -> string -> - Clang_ast_t.opt_type -> Clang_ast_t.decl list -> Clang_ast_t.decl_context_info -> - Clang_ast_t.record_decl_info -> Sil.typ +val get_declaration_type : Sil.tenv -> string option -> Clang_ast_t.decl -> Sil.typ val add_struct_to_tenv : Sil.tenv -> Sil.typ -> unit @@ -22,9 +20,7 @@ val get_method_decls : Clang_ast_t.decl -> Clang_ast_t.decl list -> (Clang_ast_t val do_typedef_declaration : Sil.tenv -> string option -> Clang_ast_t.decl_info -> string -> Clang_ast_t.opt_type -> Clang_ast_t.typedef_decl_info -> unit -val do_record_declaration : Sil.tenv -> string option -> Clang_ast_t.decl_info -> string -> - Clang_ast_t.opt_type -> Clang_ast_t.decl list -> Clang_ast_t.decl_context_info -> - Clang_ast_t.record_decl_info -> unit +val add_types_from_decl_to_tenv : Sil.tenv -> string option -> Clang_ast_t.decl -> unit val parse_func_type : string -> string -> (Sil.typ * Sil.typ list) option diff --git a/infer/src/clang/cVar_decl.ml b/infer/src/clang/cVar_decl.ml index 0a2f92847..cfa4fa10e 100644 --- a/infer/src/clang/cVar_decl.ml +++ b/infer/src/clang/cVar_decl.ml @@ -158,10 +158,8 @@ and get_variables_decls context (decl_list : Clang_ast_t.decl list) : unit = | _ -> CContext.LocalVars.add_local_var context name typ decl_info.Clang_ast_t.di_pointer (CFrontend_utils.General_utils.is_static_var var_decl_info)) - | CXXRecordDecl (di, n_info, ot, _, dl, dci, rdi, _) - | RecordDecl (di, n_info, ot, _, dl, dci, rdi) -> - let typ = CTypes_decl.get_declaration_type context.CContext.tenv context.CContext.namespace - di n_info.Clang_ast_t.ni_name ot dl dci rdi in + | CXXRecordDecl _ | RecordDecl _ -> + let typ = CTypes_decl.get_declaration_type context.CContext.tenv context.CContext.namespace decl in CTypes_decl.add_struct_to_tenv context.CContext.tenv typ | TypedefDecl (decl_info, name_info, opt_type, _, typedef_decl_info) -> CTypes_decl.do_typedef_declaration context.CContext.tenv context.CContext.namespace