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