From e26f9b4dd4da5a6ab0ca3f7fdee2b565455d6dd6 Mon Sep 17 00:00:00 2001 From: Dulma Rodriguez Date: Mon, 28 Sep 2015 12:59:33 -0100 Subject: [PATCH] [clang] Removing the use of raw types Summary: This diff aims at removing the occurrences of the types in string form so that we can remove them from the ast which will save space. There is one occurrence left regarding attributes that will be handled later by Andrzej. We build a function to create a string out of a function type used for name mangling. --- infer/src/clang/ast_expressions.ml | 9 +--- infer/src/clang/ast_expressions.mli | 2 - infer/src/clang/cFrontend_utils.ml | 14 +++-- infer/src/clang/cFrontend_utils.mli | 8 +-- infer/src/clang/cMethod_trans.ml | 11 ++-- infer/src/clang/cTrans.ml | 8 +-- infer/src/clang/cTrans_models.ml | 4 +- infer/src/clang/cTypes.ml | 80 +++-------------------------- infer/src/clang/cTypes.mli | 8 +-- infer/src/clang/cTypes_decl.ml | 15 +++--- infer/src/clang/cTypes_decl.mli | 2 - 11 files changed, 38 insertions(+), 123 deletions(-) diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index 2f3c5350f..af9a7dad2 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -76,13 +76,6 @@ let stmt_info_with_fresh_pointer stmt_info = { si_source_range = stmt_info.Clang_ast_t.si_source_range; } -let create_qual_type s = { - Clang_ast_t.qt_raw = s; - qt_desugared = Some s; - (* pointer needs to be set when we start using these, non trivial to do though *) - qt_type_ptr = Ast_utils.get_invalid_pointer (); -} - let create_qual_type_with_just_pointer pointer = { Clang_ast_t.qt_raw = ""; @@ -93,7 +86,7 @@ let create_qual_type_with_just_pointer pointer = let get_constant_qual_type s = let pointer = CFrontend_config.type_pointer_prefix ^ s in { - Clang_ast_t.qt_raw = s; + Clang_ast_t.qt_raw = ""; qt_desugared = None; qt_type_ptr = pointer } diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index 752b95089..e2b473d2a 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -21,8 +21,6 @@ val dummy_source_range : unit -> source_range val dummy_stmt_info : unit -> stmt_info -val create_qual_type : string -> qual_type - val create_char_star_type : qual_type val create_id_type : qual_type diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index bce272ba9..37ebb2953 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -302,7 +302,12 @@ struct | Some AttributedType (_, attr_info) -> attr_info.ati_attr_kind = `Nonnull | _ -> false -end + let string_of_qual_type qt = + match get_desugared_type qt.Clang_ast_t.qt_type_ptr with + | Some typ -> (Clang_ast_proj.get_type_tuple typ).Clang_ast_t.ti_raw + | None -> "" + +end (* Global counter for anonymous block*) let block_counter = ref 0 @@ -423,7 +428,7 @@ struct let mk_class_field_name class_name field_name = Ident.create_fieldname (Mangled.mangled field_name (class_name^"_"^field_name)) 0 - let mk_procname_from_function name function_decl_info_opt type_name = + let mk_procname_from_function name function_decl_info_opt qt = let file = match function_decl_info_opt with | Some (decl_info, function_decl_info) -> @@ -437,7 +442,7 @@ struct let type_string = match !CFrontend_config.language with | CFrontend_config.CPP - | CFrontend_config.OBJCPP -> type_name + | CFrontend_config.OBJCPP -> Ast_utils.string_of_qual_type qt | _ -> "" in let mangled = file ^ type_string in if String.length mangled == 0 then @@ -450,7 +455,8 @@ struct let mangled = Procname.mangled_of_objc_method_kind method_kind in Procname.mangled_c_method class_name method_name mangled - let mk_procname_from_cpp_method class_name method_name type_name = + let mk_procname_from_cpp_method class_name method_name qt = + let type_name = Ast_utils.string_of_qual_type qt in let type_name_crc = Some (CRC.crc16 type_name) in Procname.mangled_c_method class_name method_name type_name_crc diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index 8e870ea17..e61a41967 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -90,6 +90,8 @@ sig NOTE: this function needs extending to handle objC types *) val get_decl_from_typ_ptr : Clang_ast_t.type_ptr -> Clang_ast_t.decl + val string_of_qual_type : Clang_ast_t.qual_type -> string + end module General_utils : @@ -132,10 +134,10 @@ sig val mk_procname_from_objc_method : string -> string -> Procname.objc_method_kind -> Procname.t - val mk_procname_from_function : string -> - (Clang_ast_t.decl_info * Clang_ast_t.function_decl_info) option -> string -> Procname.t + val mk_procname_from_function : string -> (Clang_ast_t.decl_info * Clang_ast_t.function_decl_info) + option -> Clang_ast_t.qual_type -> Procname.t - val mk_procname_from_cpp_method : string -> string -> string -> Procname.t + val mk_procname_from_cpp_method : string -> string -> Clang_ast_t.qual_type -> Procname.t val mk_class_field_name : string -> string -> Ident.fieldname diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index c116af0a3..6d767cfd6 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -93,15 +93,13 @@ let method_signature_of_decl class_name_opt meth_decl block_data_opt = | FunctionDecl (decl_info, name_info, qt, fdi), _, _ -> let name = name_info.ni_name in let func_decl = Func_decl_info (fdi, qt) in - let type_string = CTypes.get_type qt in let function_info = Some (decl_info, fdi) in - let procname = General_utils.mk_procname_from_function name function_info type_string in + let procname = General_utils.mk_procname_from_function name function_info qt in let ms = build_method_signature decl_info procname func_decl false false false in ms, fdi.Clang_ast_t.fdi_body, fdi.Clang_ast_t.fdi_parameters | CXXMethodDecl (decl_info, name_info, qt, fdi), _, Some class_name -> let method_name = name_info.Clang_ast_t.ni_name in - let typ = CTypes.get_type qt in - let procname = General_utils.mk_procname_from_cpp_method class_name method_name typ in + let procname = General_utils.mk_procname_from_cpp_method class_name method_name qt in let method_decl = Cpp_Meth_decl_info (fdi, class_name, qt) in let ms = build_method_signature decl_info procname method_decl false false false in ms, fdi.Clang_ast_t.fdi_body, fdi.Clang_ast_t.fdi_parameters @@ -321,13 +319,12 @@ let create_procdesc_with_pointer context pointer class_name_opt name qt = ignore (create_local_procdesc context.cfg context.tenv callee_ms [] [] false); CMethod_signature.ms_get_name callee_ms | None -> - let type_name = qt.Clang_ast_t.qt_raw in let callee_name = match class_name_opt with | Some class_name -> - General_utils.mk_procname_from_cpp_method class_name name type_name + General_utils.mk_procname_from_cpp_method class_name name qt | None -> - General_utils.mk_procname_from_function name None type_name in + General_utils.mk_procname_from_function name None qt in create_external_procdesc context.cfg callee_name false None; callee_name diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index d23af9bf4..553ea4cbb 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -82,13 +82,9 @@ struct | _ -> false let objc_exp_of_type_block fun_exp_stmt = - let is_block_qt qt = - match Str.split (Str.regexp_string "(^)") qt.Clang_ast_t.qt_raw with - | [_; _] -> true - | _ -> false in match fun_exp_stmt with | Clang_ast_t.ImplicitCastExpr(_, _, ei, _) - when is_block_qt ei.Clang_ast_t.ei_qual_type -> true + when CTypes.is_block_type ei.Clang_ast_t.ei_qual_type -> true | _ -> false (* This function add in tenv a class representing an objc block. *) @@ -228,7 +224,7 @@ struct stringLiteral_trans trans_state stmt_info expr_info selector let objCEncodeExpr_trans trans_state stmt_info expr_info qual_type = - stringLiteral_trans trans_state stmt_info expr_info (CTypes.get_type qual_type) + stringLiteral_trans trans_state stmt_info expr_info (Ast_utils.string_of_qual_type qual_type) let objCProtocolExpr_trans trans_state stmt_info expr_info decl_ref = let name = (match decl_ref.Clang_ast_t.dr_name with diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index 2f37ee057..0fa970ab9 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -99,8 +99,8 @@ let is_toll_free_bridging pn_opt = (** If the function is a builtin model, return the model, otherwise return the function *) let builtin_predefined_model fun_stmt sil_fe = match get_func_type_from_stmt fun_stmt with - | Some exp -> - let typ = CTypes.get_type exp in + | Some typ -> + let typ = Ast_utils.string_of_qual_type typ in (match sil_fe with | Sil.Const (Sil.Cfun pn) when Specs.summary_exists pn -> sil_fe, false | Sil.Const (Sil.Cfun pn) when is_retain_predefined_model typ (Procname.to_string pn) -> diff --git a/infer/src/clang/cTypes.ml b/infer/src/clang/cTypes.ml index 1249cc3f7..f2f7103ca 100644 --- a/infer/src/clang/cTypes.ml +++ b/infer/src/clang/cTypes.ml @@ -13,11 +13,6 @@ open Utils open CFrontend_utils module L = Logging -let get_type qt = - match qt.Clang_ast_t.qt_desugared with - | Some t -> t - | _ -> qt.Clang_ast_t.qt_raw - let get_type_from_expr_info ei = ei.Clang_ast_t.ei_qual_type @@ -47,67 +42,6 @@ let lookup_var_type context pvar = (Sil.pvar_to_string pvar); Sil.Tvoid -(* Extract the type out of a statement. This is useful when the statement *) -(* denotes actually an expression *) -let extract_type_from_stmt s = - let open Clang_ast_t in - match s with - | BinaryConditionalOperator (_, _, expr_info) | ConditionalOperator (_, _, expr_info) - | AddrLabelExpr (_, _, expr_info, _) | ArraySubscriptExpr (_, _, expr_info) - | ArrayTypeTraitExpr (_, _, expr_info) | AsTypeExpr (_, _, expr_info) - | AtomicExpr (_, _, expr_info) | BinaryOperator (_, _, expr_info, _) - | CompoundAssignOperator (_, _, expr_info, _, _) - | BlockExpr (_, _, expr_info, _) | CXXBindTemporaryExpr (_, _ , expr_info, _) - | CXXBoolLiteralExpr (_, _, expr_info, _) | CXXConstructExpr (_, _, expr_info, _) - | CXXTemporaryObjectExpr (_, _, expr_info, _) | CXXDefaultArgExpr (_, _, expr_info) - | CXXDefaultInitExpr (_, _, expr_info) | CXXDeleteExpr (_, _, expr_info, _) - | CXXDependentScopeMemberExpr (_, _, expr_info) | CXXNewExpr (_, _, expr_info, _) - | CXXNoexceptExpr (_, _, expr_info) | CXXNullPtrLiteralExpr (_, _, expr_info) - | CXXPseudoDestructorExpr (_, _, expr_info) | CXXScalarValueInitExpr (_, _, expr_info) - | CXXStdInitializerListExpr (_, _, expr_info) | CXXThisExpr (_, _, expr_info) - | CXXThrowExpr (_, _, expr_info) | CXXTypeidExpr (_, _, expr_info) - | CXXUnresolvedConstructExpr (_, _, expr_info) | CXXUuidofExpr (_, _, expr_info) - | CallExpr (_, _, expr_info) | CUDAKernelCallExpr (_, _, expr_info) - | CXXMemberCallExpr (_, _, expr_info) | CXXOperatorCallExpr (_, _, expr_info) - | UserDefinedLiteral (_, _, expr_info) | CStyleCastExpr (_, _, expr_info, _, _) - | CXXFunctionalCastExpr (_, _, expr_info, _, _) | CXXConstCastExpr (_, _, expr_info, _, _, _) - | CXXDynamicCastExpr (_, _, expr_info, _, _, _) | CXXReinterpretCastExpr(_, _, expr_info, _, _, _) - | CXXStaticCastExpr (_, _, expr_info, _, _, _) | ObjCBridgedCastExpr (_, _, expr_info, _, _) - | ImplicitCastExpr (_, _, expr_info, _) | CharacterLiteral (_, _, expr_info, _ ) - | ChooseExpr (_, _, expr_info) | CompoundLiteralExpr (_, _, expr_info) - | ConvertVectorExpr (_, _, expr_info) | DeclRefExpr (_, _, expr_info, _) - | DependentScopeDeclRefExpr (_, _, expr_info) | DesignatedInitExpr (_, _, expr_info) - | ExprWithCleanups (_, _, expr_info, _) | ExpressionTraitExpr (_, _, expr_info) - | ExtVectorElementExpr (_, _, expr_info) | FloatingLiteral (_, _, expr_info, _) - | FunctionParmPackExpr (_, _, expr_info) | GNUNullExpr (_, _, expr_info) - | GenericSelectionExpr (_, _, expr_info) | ImaginaryLiteral (_, _, expr_info) - | ImplicitValueInitExpr (_, _, expr_info) - | InitListExpr (_, _, expr_info) | IntegerLiteral(_, _, expr_info, _) - | LambdaExpr (_, _, expr_info, _) | MSPropertyRefExpr (_, _, expr_info) - | MaterializeTemporaryExpr (_, _, expr_info, _) - | MemberExpr (_, _, expr_info, _) | ObjCArrayLiteral (_, _, expr_info) - | ObjCBoolLiteralExpr (_, _, expr_info , _) | ObjCBoxedExpr (_, _, expr_info, _) - | ObjCDictionaryLiteral (_, _, expr_info) | ObjCEncodeExpr (_, _, expr_info, _) - | ObjCIndirectCopyRestoreExpr (_, _, expr_info) | ObjCIsaExpr (_, _, expr_info) - | ObjCIvarRefExpr(_, _, expr_info, _) | ObjCMessageExpr(_, _, expr_info, _) - | ObjCPropertyRefExpr(_, _, expr_info, _) | ObjCProtocolExpr (_, _, expr_info, _) - | ObjCSelectorExpr (_, _, expr_info, _) | ObjCStringLiteral (_, _, expr_info) - | ObjCSubscriptRefExpr(_, _, expr_info, _) | OffsetOfExpr (_, _, expr_info) - | OpaqueValueExpr(_, _, expr_info, _) | UnresolvedLookupExpr (_, _, expr_info, _, _) - | UnresolvedMemberExpr (_, _, expr_info, _) | PackExpansionExpr (_, _, expr_info) - | ParenExpr (_, _, expr_info) | ParenListExpr (_, _, expr_info) - | PredefinedExpr (_, _, expr_info, _) | PseudoObjectExpr (_, _, expr_info) - | ShuffleVectorExpr (_, _, expr_info) | SizeOfPackExpr (_, _, expr_info) - | StmtExpr (_, _, expr_info) | StringLiteral (_, _, expr_info, _) - | SubstNonTypeTemplateParmExpr (_, _, expr_info) - | SubstNonTypeTemplateParmPackExpr (_, _, expr_info) - | TypeTraitExpr (_, _, expr_info) | UnaryExprOrTypeTraitExpr (_, _, expr_info, _) - | UnaryOperator(_, _, expr_info, _) - | VAArgExpr (_, _, expr_info) -> expr_info.Clang_ast_t.ei_qual_type - | _ -> (* For the other case we cannot get the type info *) - Printing.log_err "WARNING: Could not get type of statement '%s'\n%!" (Clang_ast_j.string_of_stmt s); - assert false - let get_desugared_type t = match t.Clang_ast_t.qt_desugared with | Some t' -> t' @@ -146,14 +80,6 @@ let classname_of_type typ = "Classname of type cannot be extracted in type %s" (Sil.typ_to_string typ); "undefined" -let get_raw_qual_type_decl_ref_exp_info decl_ref_expr_info = - match decl_ref_expr_info.Clang_ast_t.drti_decl_ref with - | Some d -> - (match d.Clang_ast_t.dr_qual_type with - | Some qt -> Some qt.Clang_ast_t.qt_raw - | None -> None) - | None -> None - (* Iterates over the tenv to find the value of the enumeration constant *) (* using its name Here we assume that the enumeration constant have *) (* different names. Note: this assumption may not be true all the time. So *) @@ -203,6 +129,12 @@ let rec return_type_of_function_type_ptr type_ptr = let return_type_of_function_type qt = return_type_of_function_type_ptr qt.Clang_ast_t.qt_type_ptr +let is_block_type qt = + let open Clang_ast_t in + match Ast_utils.get_desugared_type qt.Clang_ast_t.qt_type_ptr with + | Some BlockPointerType _ -> true + | _ -> false + (* Expand a named type Tvar if it has a definition in tenv. This is used for Tenum, Tstruct, etc. *) let rec expand_structured_type tenv typ = match typ with diff --git a/infer/src/clang/cTypes.mli b/infer/src/clang/cTypes.mli index d2d8e92fc..41375da1b 100644 --- a/infer/src/clang/cTypes.mli +++ b/infer/src/clang/cTypes.mli @@ -13,12 +13,6 @@ val lookup_var_type : CContext.t -> Sil.pvar -> Sil.typ val add_pointer_to_typ : Sil.typ -> Sil.typ -val get_raw_qual_type_decl_ref_exp_info : Clang_ast_t.decl_ref_expr_info -> string option - -val extract_type_from_stmt : Clang_ast_t.stmt -> Clang_ast_t.qual_type - -val get_type : Clang_ast_t.qual_type -> string - val search_enum_type_by_name : Sil.tenv -> string -> Sil.const option val classname_of_type : Sil.typ -> string @@ -37,6 +31,8 @@ val is_class : Sil.typ -> bool val return_type_of_function_type : Clang_ast_t.qual_type -> Clang_ast_t.pointer +val is_block_type : Clang_ast_t.qual_type -> bool + val expand_structured_type : Sil.tenv -> Sil.typ -> Sil.typ val get_name_from_type_pointer : string -> string * string diff --git a/infer/src/clang/cTypes_decl.ml b/infer/src/clang/cTypes_decl.ml index acaa36840..ee004b846 100644 --- a/infer/src/clang/cTypes_decl.ml +++ b/infer/src/clang/cTypes_decl.ml @@ -109,11 +109,10 @@ let get_method_decls parent decl_list = let get_class_methods tenv class_name namespace decl_list = let process_method_decl = function - | Clang_ast_t.CXXMethodDecl (decl_info, name_info, qual_type, function_decl_info) -> + | Clang_ast_t.CXXMethodDecl (decl_info, name_info, qt, function_decl_info) -> let method_name = name_info.Clang_ast_t.ni_name in Printing.log_out " ...Declaring method '%s'.\n" method_name; - let typ = CTypes.get_type qual_type in - let method_proc = General_utils.mk_procname_from_cpp_method class_name method_name typ in + let method_proc = General_utils.mk_procname_from_cpp_method class_name method_name qt in Some method_proc | _ -> None in (* poor mans list_filter_map *) @@ -147,9 +146,11 @@ let rec get_struct_fields tenv record_name namespace decl_list = 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 _ -> + | CXXRecordDecl (decl_info, _, _, _, _, _, _, _) + | RecordDecl (decl_info, _, _, _, _, _, _) -> (* C++/C Records treated in the same way*) - ignore (add_types_from_decl_to_tenv tenv namespace decl); [] + if not decl_info.Clang_ast_t.di_is_implicit then + ignore (add_types_from_decl_to_tenv tenv namespace decl); [] | _ -> [] in list_flatten (list_map do_one_decl decl_list) @@ -211,10 +212,6 @@ let get_class_type_np tenv expr_info obj_c_message_expr_info = | _ -> expr_info.Clang_ast_t.ei_qual_type in qual_type_to_sil_type tenv qt -let extract_sil_type_from_stmt tenv s = - let qt = CTypes.extract_type_from_stmt s in - qual_type_to_sil_type tenv qt - let get_type_curr_class tenv curr_class_opt = let name = CContext.get_curr_class_name curr_class_opt in let typ = Sil.Tvar (Sil.TN_csu (Sil.Class, (Mangled.from_string name))) in diff --git a/infer/src/clang/cTypes_decl.mli b/infer/src/clang/cTypes_decl.mli index 82d7d341b..071b2998e 100644 --- a/infer/src/clang/cTypes_decl.mli +++ b/infer/src/clang/cTypes_decl.mli @@ -30,8 +30,6 @@ val class_from_pointer_type : Sil.tenv -> Clang_ast_t.qual_type -> string val get_class_type_np : Sil.tenv -> Clang_ast_t.expr_info -> Clang_ast_t.obj_c_message_expr_info -> Sil.typ -val extract_sil_type_from_stmt : Sil.tenv -> Clang_ast_t.stmt -> Sil.typ - val get_type_curr_class : Sil.tenv -> CContext.curr_class -> Sil.typ val get_type_from_expr_info : Clang_ast_t.expr_info -> Sil.tenv -> Sil.typ