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
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot 4
parent ad325d5047
commit 97fe6275bd

@ -74,7 +74,6 @@ and contains_ck_impl decl_list =
const NSString *y; const NSString *y;
``` *) ``` *)
let mutable_local_vars_advice context decl = let mutable_local_vars_advice context decl =
let open CFrontend_utils.Ast_utils in
match decl with match decl with
| Clang_ast_t.VarDecl(decl_info, _, qual_type, _) -> | Clang_ast_t.VarDecl(decl_info, _, qual_type, _) ->
let is_const_ref = match Ast_utils.get_type qual_type.qt_type_ptr with 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 | _ -> false in
let is_const = qual_type.qt_is_const || is_const_ref in let is_const = qual_type.qt_is_const || is_const_ref in
let condition = context.CLintersContext.is_ck_translation_unit let condition = context.CLintersContext.is_ck_translation_unit
&& is_in_main_file decl && Ast_utils.is_in_main_file decl
&& (is_objc () || is_objcpp ()) && General_utils.is_objc_extention
&& (not (is_syntactically_global_var decl)) && (not (Ast_utils.is_syntactically_global_var decl))
&& (not is_const) in && (not is_const) in
if condition then if condition then
Some { Some {

@ -150,7 +150,7 @@ let unary_operation_instruction uoi e typ loc =
let id = Ident.create_fresh Ident.knormal in let id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Load (id, e, typ, loc) 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 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 e
else else
e_plus_1 in 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 id = Ident.create_fresh Ident.knormal in
let instr1 = Sil.Load (id, e, typ, loc) 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 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 e
else else
e_minus_1 in e_minus_1 in

@ -200,7 +200,7 @@ let global_var_init_with_calls_warning _ decl =
match Clang_ast_proj.get_named_decl_tuple decl with match Clang_ast_proj.get_named_decl_tuple decl with
| Some (di, ndi) -> di, ndi.ni_name | Some (di, ndi) -> di, ndi.ni_name
| None -> assert false (* we cannot be here *) in | 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 && Ast_utils.is_syntactically_global_var decl
&& (not (Ast_utils.is_const_expr_var decl)) && (not (Ast_utils.is_const_expr_var decl))
&& is_initialized_with_expensive_call decl in && is_initialized_with_expensive_call decl in

@ -344,16 +344,6 @@ struct
| Clang_ast_t.VarDecl (_, _ ,_, vdi) -> vdi.vdi_is_const_expr | Clang_ast_t.VarDecl (_, _ ,_, vdi) -> vdi.vdi_is_const_expr
| _ -> false | _ -> 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 = let is_ptr_to_objc_class typ class_name =
match typ with match typ with
| Some Clang_ast_t.ObjCObjectPointerType (_, {Clang_ast_t.qt_type_ptr}) -> | Some Clang_ast_t.ObjCObjectPointerType (_, {Clang_ast_t.qt_type_ptr}) ->
@ -596,8 +586,11 @@ struct
| None -> file) | None -> file)
| None -> "" | None -> ""
let is_cpp_translation language = let is_cpp_translation =
language = Config.CPP || language = Config.OBJCPP 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 = 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 (* For virtual methods return mangled name of the method from most base class
@ -619,7 +612,7 @@ struct
get_mangled_method_name fdi mdi get_mangled_method_name fdi mdi
| _ -> assert false) | _ -> 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 = let file =
match function_decl_info_opt with match function_decl_info_opt with
| Some (decl_info, function_decl_info) -> | Some (decl_info, function_decl_info) ->
@ -634,7 +627,7 @@ struct
| _ -> None in | _ -> None in
let mangled_name = let mangled_name =
match mangled_opt with match mangled_opt with
| Some m when is_cpp_translation language -> m | Some m when is_cpp_translation -> m
| _ -> "" in | _ -> "" in
let mangled = (string_crc_hex32 file) ^ mangled_name in let mangled = (string_crc_hex32 file) ^ mangled_name in
if String.length file == 0 && String.length mangled_name == 0 then if String.length file == 0 && String.length mangled_name == 0 then
@ -666,9 +659,8 @@ struct
match meth_decl with match meth_decl with
| FunctionDecl (decl_info, name_info, _, fdi) -> | FunctionDecl (decl_info, name_info, _, fdi) ->
let name = Ast_utils.get_qualified_name name_info in let name = Ast_utils.get_qualified_name name_info in
let language = Config.clang_lang in
let function_info = Some (decl_info, fdi) 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) | CXXMethodDecl (_, name_info, _, fdi, mdi)
| CXXConstructorDecl (_, name_info, _, fdi, mdi) | CXXConstructorDecl (_, name_info, _, fdi, mdi)
| CXXConversionDecl (_, name_info, _, fdi, mdi) | CXXConversionDecl (_, name_info, _, fdi, mdi)

@ -127,12 +127,6 @@ sig
(** true if a declaration is a constexpr variable *) (** true if a declaration is a constexpr variable *)
val is_const_expr_var : Clang_ast_t.decl -> bool 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 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 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_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) 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 -> val get_mangled_method_name : Clang_ast_t.function_decl_info ->
Clang_ast_t.cxx_method_decl_info -> string option 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 -> val mk_sil_var : Clang_ast_t.named_decl_info -> var_info option -> Procname.t -> Procname.t ->
Pvar.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 end

@ -28,7 +28,7 @@ type method_call_type =
| MCStatic | MCStatic
type function_method_decl_info = 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 | 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 | 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 | 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 = let get_original_return_type function_method_decl_info =
match function_method_decl_info with match function_method_decl_info with
| Func_decl_info (_, typ, _) | Func_decl_info (_, typ)
| Cpp_Meth_decl_info (_, _, _, typ) | Cpp_Meth_decl_info (_, _, _, typ)
| Block_decl_info (_, typ, _) -> CTypes.return_type_of_function_type 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 | 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 = let get_param_decls function_method_decl_info =
match function_method_decl_info with 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, _, _, _) -> | Cpp_Meth_decl_info (function_decl_info, _, _, _) ->
function_decl_info.Clang_ast_t.fdi_parameters function_decl_info.Clang_ast_t.fdi_parameters
| ObjC_Meth_decl_info (method_decl_info, _) -> method_decl_info.Clang_ast_t.omdi_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 = let get_language function_method_decl_info =
match function_method_decl_info with match function_method_decl_info with
| Func_decl_info (_, _, language) -> language | Func_decl_info (_, _) -> Config.clang_lang
| Cpp_Meth_decl_info _ -> Config.CPP | Cpp_Meth_decl_info _ -> Config.CPP
| ObjC_Meth_decl_info _ -> Config.OBJC | ObjC_Meth_decl_info _ -> Config.OBJC
| Block_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 _, 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 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 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 Ast_expressions.create_reference_type qt.Clang_ast_t.qt_type_ptr
| _ -> qt.Clang_ast_t.qt_type_ptr in | _ -> qt.Clang_ast_t.qt_type_ptr in
(mangled, {qt with qt_type_ptr}) (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 let open Clang_ast_t in
match meth_decl, block_data_opt with match meth_decl, block_data_opt with
| FunctionDecl (decl_info, _, qt, fdi), _ -> | 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) in
let func_decl = Func_decl_info (fdi, qt.Clang_ast_t.qt_type_ptr, language) in
let procname = General_utils.procname_of_decl meth_decl 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 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 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 -> | Some class_name ->
General_utils.mk_procname_from_cpp_method class_name name None General_utils.mk_procname_from_cpp_method class_name name None
| 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; create_external_procdesc context.cfg callee_name false None;
callee_name callee_name

@ -640,7 +640,7 @@ struct
let ast_typ = CTypes_decl.type_ptr_to_sil_type context.tenv type_ptr in let ast_typ = CTypes_decl.type_ptr_to_sil_type context.tenv type_ptr in
let typ = match ast_typ with let typ = match ast_typ with
| Tstruct _ when decl_ref.dr_kind = `ParmVar -> | 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) Typ.Tptr (ast_typ, Pk_reference)
else ast_typ else ast_typ
| _ -> ast_typ in | _ -> ast_typ in
@ -659,7 +659,7 @@ struct
| Some VarDecl (_, _, qual_type, vdi) -> | Some VarDecl (_, _, qual_type, vdi) ->
(match ast_typ with (match ast_typ with
| Tstruct _ | 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 (* Do not convert a global struct to a local because SIL
values do not include structs, they must all be heap-allocated *) values do not include structs, they must all be heap-allocated *)
false, None false, None
@ -833,7 +833,7 @@ struct
if (is_binary_assign_op binary_operator_info) if (is_binary_assign_op binary_operator_info)
(* assignment operator result is lvalue in CPP, rvalue in C, *) (* assignment operator result is lvalue in CPP, rvalue in C, *)
(* hence the difference *) (* 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 ( && ((not creating_node) || (is_return_temp trans_state.continuation)) then (
(* We are in this case when an assignment is inside *) (* We are in this case when an assignment is inside *)
(* another operator that creates a node. Eg. another *) (* another operator that creates a node. Eg. another *)

Loading…
Cancel
Save