From 97fe6275bd2d5d38f2b8e65605c4cc2defc59fe3 Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Thu, 1 Sep 2016 08:50:40 -0700 Subject: [PATCH] Simplify language detection in frontend Summary: There were overly complex and different ways of identifying C++/objC languages. Simplify and unify them. How I came up with naming - there are two languages C and C++. You can apply "Objective-" extention to both of them. We usually need to differentiate C and C++ (different AST) and whether it's extended (checks specific to ObjC) Reviewed By: dulmarod Differential Revision: D3804457 fbshipit-source-id: 685e40a --- infer/src/clang/ComponentKit.ml | 7 +++---- infer/src/clang/cArithmetic_trans.ml | 4 ++-- infer/src/clang/cFrontend_checkers.ml | 2 +- infer/src/clang/cFrontend_utils.ml | 24 ++++++++---------------- infer/src/clang/cFrontend_utils.mli | 14 ++++++-------- infer/src/clang/cMethod_trans.ml | 15 +++++++-------- infer/src/clang/cTrans.ml | 6 +++--- 7 files changed, 30 insertions(+), 42 deletions(-) diff --git a/infer/src/clang/ComponentKit.ml b/infer/src/clang/ComponentKit.ml index 70863aaf5..81266f98c 100644 --- a/infer/src/clang/ComponentKit.ml +++ b/infer/src/clang/ComponentKit.ml @@ -74,7 +74,6 @@ and contains_ck_impl decl_list = const NSString *y; ``` *) let mutable_local_vars_advice context decl = - let open CFrontend_utils.Ast_utils in match decl with | Clang_ast_t.VarDecl(decl_info, _, qual_type, _) -> let is_const_ref = match Ast_utils.get_type qual_type.qt_type_ptr with @@ -83,9 +82,9 @@ let mutable_local_vars_advice context decl = | _ -> false in let is_const = qual_type.qt_is_const || is_const_ref in let condition = context.CLintersContext.is_ck_translation_unit - && is_in_main_file decl - && (is_objc () || is_objcpp ()) - && (not (is_syntactically_global_var decl)) + && Ast_utils.is_in_main_file decl + && General_utils.is_objc_extention + && (not (Ast_utils.is_syntactically_global_var decl)) && (not is_const) in if condition then Some { diff --git a/infer/src/clang/cArithmetic_trans.ml b/infer/src/clang/cArithmetic_trans.ml index 3bf10bc14..31ecaebdf 100644 --- a/infer/src/clang/cArithmetic_trans.ml +++ b/infer/src/clang/cArithmetic_trans.ml @@ -150,7 +150,7 @@ let unary_operation_instruction uoi e typ loc = let id = Ident.create_fresh Ident.knormal in let instr1 = Sil.Load (id, e, typ, loc) in let e_plus_1 = Exp.BinOp(Binop.PlusA, Exp.Var id, Exp.Const(Const.Cint (IntLit.one))) in - let exp = if General_utils.is_cpp_translation Config.clang_lang then + let exp = if General_utils.is_cpp_translation then e else e_plus_1 in @@ -164,7 +164,7 @@ let unary_operation_instruction uoi e typ loc = let id = Ident.create_fresh Ident.knormal in let instr1 = Sil.Load (id, e, typ, loc) in let e_minus_1 = Exp.BinOp(Binop.MinusA, Exp.Var id, Exp.Const(Const.Cint (IntLit.one))) in - let exp = if General_utils.is_cpp_translation Config.clang_lang then + let exp = if General_utils.is_cpp_translation then e else e_minus_1 in diff --git a/infer/src/clang/cFrontend_checkers.ml b/infer/src/clang/cFrontend_checkers.ml index 9a64755d9..fcdc571ac 100644 --- a/infer/src/clang/cFrontend_checkers.ml +++ b/infer/src/clang/cFrontend_checkers.ml @@ -200,7 +200,7 @@ let global_var_init_with_calls_warning _ decl = match Clang_ast_proj.get_named_decl_tuple decl with | Some (di, ndi) -> di, ndi.ni_name | None -> assert false (* we cannot be here *) in - let condition = (Ast_utils.is_objc () || Ast_utils.is_objcpp ()) + let condition = General_utils.is_objc_extention && Ast_utils.is_syntactically_global_var decl && (not (Ast_utils.is_const_expr_var decl)) && is_initialized_with_expensive_call decl in diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index aac4dab97..6d92a6db5 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -344,16 +344,6 @@ struct | Clang_ast_t.VarDecl (_, _ ,_, vdi) -> vdi.vdi_is_const_expr | _ -> false - let is_objc () = - match Config.clang_lang with - | Config.OBJC -> true - | _ -> false - - let is_objcpp () = - match Config.clang_lang with - | Config.OBJCPP -> true - | _ -> false - let is_ptr_to_objc_class typ class_name = match typ with | Some Clang_ast_t.ObjCObjectPointerType (_, {Clang_ast_t.qt_type_ptr}) -> @@ -596,8 +586,11 @@ struct | None -> file) | None -> "" - let is_cpp_translation language = - language = Config.CPP || language = Config.OBJCPP + let is_cpp_translation = + Config.clang_lang = Config.CPP || Config.clang_lang = Config.OBJCPP + + let is_objc_extention = + Config.clang_lang = Config.OBJC || Config.clang_lang = Config.OBJCPP let rec get_mangled_method_name function_decl_info method_decl_info = (* For virtual methods return mangled name of the method from most base class @@ -619,7 +612,7 @@ struct get_mangled_method_name fdi mdi | _ -> assert false) - let mk_procname_from_function name function_decl_info_opt language = + let mk_procname_from_function name function_decl_info_opt = let file = match function_decl_info_opt with | Some (decl_info, function_decl_info) -> @@ -634,7 +627,7 @@ struct | _ -> None in let mangled_name = match mangled_opt with - | Some m when is_cpp_translation language -> m + | Some m when is_cpp_translation -> m | _ -> "" in let mangled = (string_crc_hex32 file) ^ mangled_name in if String.length file == 0 && String.length mangled_name == 0 then @@ -666,9 +659,8 @@ struct match meth_decl with | FunctionDecl (decl_info, name_info, _, fdi) -> let name = Ast_utils.get_qualified_name name_info in - let language = Config.clang_lang in let function_info = Some (decl_info, fdi) in - mk_procname_from_function name function_info language + mk_procname_from_function name function_info | CXXMethodDecl (_, name_info, _, fdi, mdi) | CXXConstructorDecl (_, name_info, _, fdi, mdi) | CXXConversionDecl (_, name_info, _, fdi, mdi) diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index 29c4c79cf..b3494edf3 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -127,12 +127,6 @@ sig (** true if a declaration is a constexpr variable *) val is_const_expr_var : Clang_ast_t.decl -> bool - (** true if CFrontend_config.language is set ot ObjC *) - val is_objc : unit -> bool - - (** true if CFrontend_config.language is set ot ObjC *) - val is_objcpp : unit -> bool - val is_ptr_to_objc_class : Clang_ast_t.c_type option -> string -> bool val full_name_of_decl_opt : Clang_ast_t.decl option -> string @@ -213,7 +207,7 @@ sig val mk_procname_from_objc_method : string -> string -> Procname.objc_cpp_method_kind -> Procname.t val mk_procname_from_function : string -> (Clang_ast_t.decl_info * Clang_ast_t.function_decl_info) - option -> Config.clang_lang -> Procname.t + option -> Procname.t val get_mangled_method_name : Clang_ast_t.function_decl_info -> Clang_ast_t.cxx_method_decl_info -> string option @@ -233,6 +227,10 @@ sig val mk_sil_var : Clang_ast_t.named_decl_info -> var_info option -> Procname.t -> Procname.t -> Pvar.t - val is_cpp_translation : Config.clang_lang -> bool + (** true if Config.clang_lang is C++ or ObjC++ *) + val is_cpp_translation : bool + + (** true if Config.clang_lang is ObjC or ObjC++ *) + val is_objc_extention : bool end diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index a725152da..f600d84c7 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -28,7 +28,7 @@ type method_call_type = | MCStatic 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 | 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 * Clang_ast_t.pointer | Block_decl_info of Clang_ast_t.block_decl_info * Clang_ast_t.type_ptr * CContext.t @@ -43,7 +43,7 @@ let is_instance_method function_method_decl_info = let get_original_return_type function_method_decl_info = match function_method_decl_info with - | Func_decl_info (_, typ, _) + | Func_decl_info (_, typ) | Cpp_Meth_decl_info (_, _, _, typ) | Block_decl_info (_, typ, _) -> CTypes.return_type_of_function_type typ | ObjC_Meth_decl_info (method_decl_info, _) -> method_decl_info.Clang_ast_t.omdi_result_type @@ -83,7 +83,7 @@ let get_return_param tenv function_method_decl_info = let get_param_decls function_method_decl_info = match function_method_decl_info with - | Func_decl_info (function_decl_info, _, _) + | Func_decl_info (function_decl_info, _) | Cpp_Meth_decl_info (function_decl_info, _, _, _) -> function_decl_info.Clang_ast_t.fdi_parameters | ObjC_Meth_decl_info (method_decl_info, _) -> method_decl_info.Clang_ast_t.omdi_parameters @@ -91,7 +91,7 @@ let get_param_decls function_method_decl_info = let get_language function_method_decl_info = match function_method_decl_info with - | Func_decl_info (_, _, language) -> language + | Func_decl_info (_, _) -> Config.clang_lang | Cpp_Meth_decl_info _ -> Config.CPP | ObjC_Meth_decl_info _ -> Config.OBJC | Block_decl_info _ -> Config.OBJC @@ -112,7 +112,7 @@ let get_parameters tenv function_method_decl_info = let _, mangled = General_utils.get_var_name_mangled name_info var_decl_info in let param_typ = CTypes_decl.type_ptr_to_sil_type tenv qt.Clang_ast_t.qt_type_ptr in let qt_type_ptr = match param_typ with - | Typ.Tstruct _ when General_utils.is_cpp_translation Config.clang_lang -> + | Typ.Tstruct _ when General_utils.is_cpp_translation -> Ast_expressions.create_reference_type qt.Clang_ast_t.qt_type_ptr | _ -> qt.Clang_ast_t.qt_type_ptr in (mangled, {qt with qt_type_ptr}) @@ -160,8 +160,7 @@ let method_signature_of_decl tenv meth_decl block_data_opt = let open Clang_ast_t in match meth_decl, block_data_opt with | FunctionDecl (decl_info, _, qt, fdi), _ -> - let language = Config.clang_lang in - let func_decl = Func_decl_info (fdi, qt.Clang_ast_t.qt_type_ptr, language) in + let func_decl = Func_decl_info (fdi, qt.Clang_ast_t.qt_type_ptr) in let procname = General_utils.procname_of_decl meth_decl in let ms = build_method_signature tenv decl_info procname func_decl None None in let extra_instrs = get_assume_not_null_calls fdi.Clang_ast_t.fdi_parameters in @@ -462,7 +461,7 @@ let create_procdesc_with_pointer context pointer class_name_opt name = | Some class_name -> General_utils.mk_procname_from_cpp_method class_name name None | None -> - General_utils.mk_procname_from_function name None Config.clang_lang in + General_utils.mk_procname_from_function name None 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 feb0f5085..0f73cdee0 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -640,7 +640,7 @@ struct let ast_typ = CTypes_decl.type_ptr_to_sil_type context.tenv type_ptr in let typ = match ast_typ with | Tstruct _ when decl_ref.dr_kind = `ParmVar -> - if General_utils.is_cpp_translation Config.clang_lang then + if General_utils.is_cpp_translation then Typ.Tptr (ast_typ, Pk_reference) else ast_typ | _ -> ast_typ in @@ -659,7 +659,7 @@ struct | Some VarDecl (_, _, qual_type, vdi) -> (match ast_typ with | Tstruct _ - when not (General_utils.is_cpp_translation Config.clang_lang) -> + when not General_utils.is_cpp_translation -> (* Do not convert a global struct to a local because SIL values do not include structs, they must all be heap-allocated *) false, None @@ -833,7 +833,7 @@ struct if (is_binary_assign_op binary_operator_info) (* assignment operator result is lvalue in CPP, rvalue in C, *) (* hence the difference *) - && (not (General_utils.is_cpp_translation Config.clang_lang)) + && (not General_utils.is_cpp_translation) && ((not creating_node) || (is_return_temp trans_state.continuation)) then ( (* We are in this case when an assignment is inside *) (* another operator that creates a node. Eg. another *)