diff --git a/infer/src/IR/QualifiedCppName.re b/infer/src/IR/QualifiedCppName.re index f9257511e..c2bc454b7 100644 --- a/infer/src/IR/QualifiedCppName.re +++ b/infer/src/IR/QualifiedCppName.re @@ -32,6 +32,8 @@ let of_qual_string = { let to_qual_string = String.concat sep::"::"; +let pp fmt quals => Format.fprintf fmt "%s" (to_qual_string quals); + let module Match = { type quals_matcher = Str.regexp; let regexp_string_of_qualifiers quals => Str.quote (String.concat sep::"::" quals) ^ "$"; diff --git a/infer/src/IR/QualifiedCppName.rei b/infer/src/IR/QualifiedCppName.rei index e21f53979..a2160bc71 100644 --- a/infer/src/IR/QualifiedCppName.rei +++ b/infer/src/IR/QualifiedCppName.rei @@ -16,6 +16,7 @@ let empty: t; let equal: t => t => bool; + /** attempts to parse the argument into a list::of::possibly::templated::qualifiers */ let of_qual_string: string => t; @@ -27,6 +28,7 @@ let to_qual_string: t => string; /** append qualifier to the end (innermost scope) of the qualified name */ let append_qualifier: t => qual::string => t; + /** returns list of qualifers */ let to_list: t => list string; @@ -34,6 +36,8 @@ let to_list: t => list string; /** given list of qualifiers in normal order produce qualified name ["std", "move"] */ let of_list: list string => t; +let pp: Format.formatter => t => unit; + /* Module to match qualified C++ procnames "fuzzily", that is up to namescapes and templating. In particular, this deals with the following issues: diff --git a/infer/src/IR/Typ.re b/infer/src/IR/Typ.re index d343d7351..548e5ccee 100644 --- a/infer/src/IR/Typ.re +++ b/infer/src/IR/Typ.re @@ -135,16 +135,16 @@ let module T = { | Tarray t static_length /** array type with statically fixed length */ [@@deriving compare] and name = - | CStruct Mangled.t - | CUnion Mangled.t - | CppClass Mangled.t template_spec_info + | CStruct QualifiedCppName.t + | CUnion QualifiedCppName.t + | CppClass QualifiedCppName.t template_spec_info | JavaClass Mangled.t - | ObjcClass Mangled.t - | ObjcProtocol Mangled.t + | ObjcClass QualifiedCppName.t + | ObjcProtocol QualifiedCppName.t [@@deriving compare] and template_spec_info = | NoTemplate - | Template (string, list (option t)) + | Template (QualifiedCppName.t, list (option t)) [@@deriving compare]; let equal = [%compare.equal : t]; let hash = Hashtbl.hash; @@ -160,9 +160,17 @@ let module Name = { | CStruct name | CUnion name | CppClass name _ - | JavaClass name | ObjcClass name - | ObjcProtocol name => Mangled.to_string name; + | ObjcProtocol name => QualifiedCppName.to_qual_string name + | JavaClass name => Mangled.to_string name; + let qual_name = + fun + | CStruct name + | CUnion name + | CppClass name _ + | ObjcClass name + | ObjcProtocol name => name + | JavaClass _ => QualifiedCppName.empty; let to_string tname => { let prefix = fun @@ -192,8 +200,9 @@ let module Name = { | _ => false }; let module C = { - let from_string name_str => CStruct (Mangled.from_string name_str); - let union_from_string name_str => CUnion (Mangled.from_string name_str); + let from_qual_name qual_name => CStruct qual_name; + let from_string name_str => QualifiedCppName.of_qual_string name_str |> from_qual_name; + let union_from_qual_name qual_name => CUnion qual_name; }; let module Java = { let from_string name_str => JavaClass (Mangled.from_string name_str); @@ -212,17 +221,16 @@ let module Name = { let java_lang_cloneable = from_string "java.lang.Cloneable"; }; let module Cpp = { - let from_string name_str => CppClass (Mangled.from_string name_str) NoTemplate; - let from_template_string template_spec_info name => - CppClass (Mangled.from_string name) template_spec_info; + let from_qual_name template_spec_info qual_name => CppClass qual_name template_spec_info; let is_class = fun | CppClass _ => true | _ => false; }; let module Objc = { - let from_string name_str => ObjcClass (Mangled.from_string name_str); - let protocol_from_string name_str => ObjcProtocol (Mangled.from_string name_str); + let from_qual_name qual_name => ObjcClass qual_name; + let from_string name_str => QualifiedCppName.of_qual_string name_str |> from_qual_name; + let protocol_from_qual_name qual_name => ObjcProtocol qual_name; let is_class = fun | ObjcClass _ => true @@ -407,7 +415,7 @@ let module Procname = { [@@deriving compare]; /** Type of c procedure names. */ - type c = {name: string, mangled: option string, template_args: template_spec_info} + type c = {name: QualifiedCppName.t, mangled: option string, template_args: template_spec_info} [@@deriving compare]; type objc_cpp_method_kind = | CPPMethod (option string) /** with mangling */ @@ -492,12 +500,13 @@ let module Procname = { | None => (None, package_classname) }; let split_typename typename => split_classname (Name.name typename); - let c (name: string) (mangled: string) (template_args: template_spec_info) => { + let c (name: QualifiedCppName.t) (mangled: string) (template_args: template_spec_info) => { name, mangled: Some mangled, template_args }; - let from_string_c_fun (name: string) => C {name, mangled: None, template_args: NoTemplate}; + let from_string_c_fun (name: string) => + C {name: QualifiedCppName.of_qual_string name, mangled: None, template_args: NoTemplate}; let java class_name return_type method_name parameters kind => { class_name, return_type, @@ -576,7 +585,7 @@ let module Procname = { let get_method = fun | ObjC_Cpp name => name.method_name - | C {name} => name + | C {name} => QualifiedCppName.to_qual_string name | Block name => name | Java j => j.method_name | Linters_dummy_method => "Linters_dummy_method"; @@ -783,15 +792,19 @@ let module Procname = { }; let get_global_name_of_initializer = fun - | C {name} when String.is_prefix prefix::Config.clang_initializer_prefix name => { + | C {name} + when + String.is_prefix + prefix::Config.clang_initializer_prefix (QualifiedCppName.to_qual_string name) => { + let name_str = QualifiedCppName.to_qual_string name; let prefix_len = String.length Config.clang_initializer_prefix; - Some (String.sub name pos::prefix_len len::(String.length name - prefix_len)) + Some (String.sub name_str pos::prefix_len len::(String.length name_str - prefix_len)) } | _ => None; /** to_string for C_function type */ let to_readable_string (c1, c2) verbose => { - let plain = c1; + let plain = QualifiedCppName.to_qual_string c1; if verbose { switch c2 { | None => plain @@ -884,12 +897,10 @@ let module Procname = { /** Pretty print a set of proc names */ let pp_set fmt set => Set.iter (fun pname => F.fprintf fmt "%a " pp pname) set; - let objc_cpp_get_class_qualifiers objc_cpp => QualifiedCppName.of_qual_string ( - Name.name objc_cpp.class_name - ); + let objc_cpp_get_class_qualifiers objc_cpp => Name.qual_name objc_cpp.class_name; let get_qualifiers pname => switch pname { - | C {name} => QualifiedCppName.of_qual_string name + | C {name} => name | ObjC_Cpp objc_cpp => objc_cpp_get_class_qualifiers objc_cpp |> QualifiedCppName.append_qualifier qual::objc_cpp.method_name diff --git a/infer/src/IR/Typ.rei b/infer/src/IR/Typ.rei index 87e23f331..63a0f4ad1 100644 --- a/infer/src/IR/Typ.rei +++ b/infer/src/IR/Typ.rei @@ -81,16 +81,16 @@ type t = | Tarray t static_length /** array type with statically fixed length */ [@@deriving compare] and name = - | CStruct Mangled.t - | CUnion Mangled.t - | CppClass Mangled.t template_spec_info + | CStruct QualifiedCppName.t + | CUnion QualifiedCppName.t + | CppClass QualifiedCppName.t template_spec_info | JavaClass Mangled.t - | ObjcClass Mangled.t - | ObjcProtocol Mangled.t + | ObjcClass QualifiedCppName.t + | ObjcProtocol QualifiedCppName.t [@@deriving compare] and template_spec_info = | NoTemplate - | Template (string, list (option t)) + | Template (QualifiedCppName.t, list (option t)) [@@deriving compare]; let module Name: { @@ -113,7 +113,14 @@ let module Name: { /** name of the typename without qualifier */ let name: t => string; - let module C: {let from_string: string => t; let union_from_string: string => t;}; + + /** qualified name of the type, may return nonsense for Java classes */ + let qual_name: t => QualifiedCppName.t; + let module C: { + let from_string: string => t; + let from_qual_name: QualifiedCppName.t => t; + let union_from_qual_name: QualifiedCppName.t => t; + }; let module Java: { /** Create a typename from a Java classname in the form "package.class" */ @@ -131,8 +138,7 @@ let module Name: { let module Cpp: { /** Create a typename from a C++ classname */ - let from_string: string => t; - let from_template_string: template_spec_info => string => t; + let from_qual_name: template_spec_info => QualifiedCppName.t => t; /** [is_class name] holds if [name] names a C++ class */ let is_class: t => bool; @@ -141,7 +147,8 @@ let module Name: { /** Create a typename from a Objc classname */ let from_string: string => t; - let protocol_from_string: string => t; + let from_qual_name: QualifiedCppName.t => t; + let protocol_from_qual_name: QualifiedCppName.t => t; /** [is_class name] holds if [name] names a Objc class */ let is_class: t => bool; @@ -266,7 +273,7 @@ let module Procname: { let module Set: Caml.Set.S with type elt = t; /** Create a C procedure name from plain and mangled name. */ - let c: string => string => template_spec_info => c; + let c: QualifiedCppName.t => string => template_spec_info => c; /** Empty block name. */ let empty_block: t; diff --git a/infer/src/clang/CProcname.ml b/infer/src/clang/CProcname.ml index 74a8ea88c..f03cb20dc 100644 --- a/infer/src/clang/CProcname.ml +++ b/infer/src/clang/CProcname.ml @@ -32,7 +32,7 @@ let rec get_mangled_method_name function_decl_info method_decl_info = let get_template_info tenv (fdi : Clang_ast_t.function_decl_info) : Typ.template_spec_info = match fdi.fdi_template_specialization with | Some spec_info -> Typ.Template ( - "", + QualifiedCppName.empty, List.map spec_info.tsi_specialization_args ~f:(function | `Type type_ptr -> Some (CType_decl.type_ptr_to_sil_type tenv type_ptr) | _ -> None)) @@ -60,7 +60,7 @@ let mk_c_function translation_unit_context ?tenv name function_decl_info_opt = | _ -> Typ.NoTemplate in let mangled = file ^ mangled_name in if String.is_empty mangled then - Typ.Procname.from_string_c_fun name + Typ.Procname.from_string_c_fun (QualifiedCppName.to_qual_string name) else Typ.Procname.C (Typ.Procname.c name mangled template_info) @@ -121,7 +121,8 @@ let get_class_typename ?tenv method_decl_info = module NoAstDecl = struct let c_function_of_string translation_unit_context tenv name = - mk_c_function translation_unit_context ~tenv name None + let qual_name = QualifiedCppName.of_qual_string name in + mk_c_function translation_unit_context ~tenv qual_name None let cpp_method_of_string tenv class_name method_name = mk_cpp_method ~tenv class_name method_name None diff --git a/infer/src/clang/CType_decl.ml b/infer/src/clang/CType_decl.ml index fb65ebd71..07eb4286f 100644 --- a/infer/src/clang/CType_decl.ml +++ b/infer/src/clang/CType_decl.ml @@ -55,10 +55,10 @@ let create_c_record_typename opt_type = | `Type s -> (let buf = Str.split (Str.regexp "[ \t]+") s in match buf with - | "struct":: _ -> Typ.Name.C.from_string - | "class":: _ -> Typ.Name.Cpp.from_string - | "union":: _ -> Typ.Name.C.union_from_string - | _ -> Typ.Name.C.from_string) + | "struct":: _ -> Typ.Name.C.from_qual_name + | "class":: _ -> Typ.Name.Cpp.from_qual_name Typ.NoTemplate + | "union":: _ -> Typ.Name.C.union_from_qual_name + | _ -> Typ.Name.C.from_qual_name) | _ -> assert false let get_class_template_name = function @@ -83,7 +83,7 @@ let translate_as_type_ptr_matcher = let get_translate_as_friend_decl decl_list = let is_translate_as_friend_name (_, name_info) = - let qual_name = QualifiedCppName.of_qual_string (CAst_utils.get_qualified_name name_info) in + let qual_name = CAst_utils.get_qualified_name name_info in QualifiedCppName.Match.match_qualifiers translate_as_type_ptr_matcher qual_name in let get_friend_decl_opt (decl : Clang_ast_t.decl) = match decl with | FriendDecl (_, `Type type_ptr) -> CAst_utils.get_decl_from_typ_ptr type_ptr @@ -169,17 +169,17 @@ and get_record_typename ?tenv decl = | ClassTemplateSpecializationDecl (_, name_info, _, _, _, _, _, _, _) -> (* we use Typ.CppClass for C++ because we expect Typ.CppClass from *) (* types that have methods. And in C++ struct/class/union can have methods *) - let name_str = CAst_utils.get_qualified_name name_info in + let qual_name = CAst_utils.get_qualified_name name_info in let templ_info = match tenv with | Some t -> get_template_specialization t decl | None -> Typ.NoTemplate in - Typ.Name.Cpp.from_template_string templ_info name_str + Typ.Name.Cpp.from_qual_name templ_info qual_name | ObjCInterfaceDecl (_, name_info, _, _, _) | ObjCImplementationDecl (_, name_info, _, _, _) | ObjCProtocolDecl (_, name_info, _, _, _) | ObjCCategoryDecl (_, name_info, _, _, _) | ObjCCategoryImplDecl (_, name_info, _, _, _) -> - CAst_utils.get_qualified_name name_info |> Typ.Name.Objc.from_string + CAst_utils.get_qualified_name name_info |> Typ.Name.Objc.from_qual_name | _ -> assert false (** fetches list of superclasses for C++ classes *) diff --git a/infer/src/clang/cAst_utils.ml b/infer/src/clang/cAst_utils.ml index 2da7ce4ac..c0056bacc 100644 --- a/infer/src/clang/cAst_utils.ml +++ b/infer/src/clang/cAst_utils.ml @@ -17,26 +17,22 @@ module F = Format type type_ptr_to_sil_type = Tenv.t -> Clang_ast_t.type_ptr -> Typ.t -let fold_qual_name qual_name_list = - match qual_name_list with - | [] -> "" - | name :: quals -> - let s = (List.fold_right ~f:(fun el res -> res ^ el ^ "::") quals ~init:"") ^ name in - let no_slash_space = Str.global_replace (Str.regexp "[/ ]") "_" s in - no_slash_space +let sanitize_name = Str.global_replace (Str.regexp "[/ ]") "_" +let get_qual_name qual_name_list = + List.rev_map ~f:sanitize_name qual_name_list |> QualifiedCppName.of_list let get_qualified_name name_info = - fold_qual_name name_info.Clang_ast_t.ni_qual_name + get_qual_name name_info.Clang_ast_t.ni_qual_name let get_unqualified_name name_info = let name = match name_info.Clang_ast_t.ni_qual_name with | name :: _ -> name | [] -> name_info.Clang_ast_t.ni_name in - fold_qual_name [name] + sanitize_name name let get_class_name_from_member member_name_info = match member_name_info.Clang_ast_t.ni_qual_name with - | _ :: class_qual_list -> fold_qual_name class_qual_list + | _ :: class_qual_list -> get_qual_name class_qual_list | [] -> assert false let make_name_decl name = { @@ -178,7 +174,7 @@ let name_of_typedef_type_info {Clang_ast_t.tti_decl_ptr} = match get_decl tti_decl_ptr with | Some TypedefDecl (_, name_decl_info, _, _, _) -> get_qualified_name name_decl_info - | _ -> "" + | _ -> QualifiedCppName.empty let name_opt_of_typedef_type_ptr type_ptr = match get_type type_ptr with @@ -255,8 +251,8 @@ let full_name_of_decl_opt decl_opt = | Some decl -> (match Clang_ast_proj.get_named_decl_tuple decl with | Some (_, name_info) -> get_qualified_name name_info - | None -> "") - | None -> "" + | None -> QualifiedCppName.empty) + | None -> QualifiedCppName.empty (* Generates a unique number for each variant of a type. *) let get_tag ast_item = @@ -280,7 +276,7 @@ let generate_key_decl decl = let buffer = Buffer.create 16 in let name = full_name_of_decl_opt (Some decl) in Buffer.add_string buffer (string_of_int (get_tag decl)); - Buffer.add_string buffer name; + Buffer.add_string buffer (QualifiedCppName.to_qual_string name); Buffer.contents buffer let rec get_super_if decl = @@ -386,7 +382,7 @@ let if_decl_to_di_pointer_opt if_decl = let is_instance_type type_ptr = match name_opt_of_typedef_type_ptr type_ptr with - | Some name -> String.equal name "instancetype" + | Some name -> String.equal (QualifiedCppName.to_qual_string name) "instancetype" | None -> false let return_type_matches_class_type rtp type_decl_pointer = diff --git a/infer/src/clang/cAst_utils.mli b/infer/src/clang/cAst_utils.mli index 18b7587ab..266c211ad 100644 --- a/infer/src/clang/cAst_utils.mli +++ b/infer/src/clang/cAst_utils.mli @@ -41,13 +41,13 @@ val add_enum_constant : Clang_ast_t.pointer -> Clang_ast_t.pointer option -> uni val get_enum_constant_exp : Clang_ast_t.pointer -> Clang_ast_t.pointer option * Exp.t option (** returns sanitized, fully qualified name given name info *) -val get_qualified_name : Clang_ast_t.named_decl_info -> string +val get_qualified_name : Clang_ast_t.named_decl_info -> QualifiedCppName.t (** returns sanitized unqualified name given name info *) val get_unqualified_name : Clang_ast_t.named_decl_info -> string (** returns qualified class name given member name info *) -val get_class_name_from_member : Clang_ast_t.named_decl_info -> string +val get_class_name_from_member : Clang_ast_t.named_decl_info -> QualifiedCppName.t (** looks up clang pointer to type and returns c_type. It requires type_ptr to be `TPtr. *) val get_type : Clang_ast_t.type_ptr -> Clang_ast_t.c_type option @@ -64,10 +64,10 @@ val get_decl_from_typ_ptr : Clang_ast_t.type_ptr -> Clang_ast_t.decl option NOTE: this doesn't expand type, it only converts type_ptr to string *) val string_of_type_ptr : Clang_ast_t.type_ptr -> string -val name_of_typedef_type_info : Clang_ast_t.typedef_type_info -> string +val name_of_typedef_type_info : Clang_ast_t.typedef_type_info -> QualifiedCppName.t (** returns name of typedef if type_ptr points to Typedef, None otherwise *) -val name_opt_of_typedef_type_ptr : Clang_ast_t.type_ptr -> string option +val name_opt_of_typedef_type_ptr : Clang_ast_t.type_ptr -> QualifiedCppName.t option val string_of_qual_type : Clang_ast_t.qual_type -> string @@ -98,7 +98,7 @@ val is_const_expr_var : Clang_ast_t.decl -> 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 -> QualifiedCppName.t (** Generates a key for a statement based on its sub-statements and the statement tag. *) val generate_key_stmt : Clang_ast_t.stmt -> string diff --git a/infer/src/clang/cContext.ml b/infer/src/clang/cContext.ml index 3cc3e35ec..84e3744ad 100644 --- a/infer/src/clang/cContext.ml +++ b/infer/src/clang/cContext.ml @@ -94,15 +94,6 @@ let get_curr_class_ptr curr_class = get_ptr_from_decl_ref ocidi.ocidi_class_interface | _ -> decl_ptr -let get_curr_class_name curr_class = - let class_decl_ptr = get_curr_class_ptr curr_class in - let _, name_info = match Option.bind - (CAst_utils.get_decl class_decl_ptr) - Clang_ast_proj.get_named_decl_tuple with - | Some result -> result - | None -> assert false in - CAst_utils.get_qualified_name name_info - let get_curr_class_typename context = let tenv = context.tenv in let curr_class = get_curr_class context in diff --git a/infer/src/clang/cContext.mli b/infer/src/clang/cContext.mli index d85aa445c..e2ce51751 100644 --- a/infer/src/clang/cContext.mli +++ b/infer/src/clang/cContext.mli @@ -45,8 +45,6 @@ val get_cg : t -> Cg.t val get_curr_class : t -> curr_class -val get_curr_class_name : curr_class -> string - val get_curr_class_typename : t -> Typ.Name.t val get_curr_class_decl_ptr : curr_class -> Clang_ast_t.pointer diff --git a/infer/src/clang/cField_decl.ml b/infer/src/clang/cField_decl.ml index 5c3919df2..1b7658b29 100644 --- a/infer/src/clang/cField_decl.ml +++ b/infer/src/clang/cField_decl.ml @@ -29,7 +29,7 @@ let fields_superclass tenv interface_decl_info = | Some dr -> (match dr.Clang_ast_t.dr_name with | Some sc -> - let classname = Typ.Name.Objc.from_string (CAst_utils.get_qualified_name sc) in + let classname = Typ.Name.Objc.from_qual_name (CAst_utils.get_qualified_name sc) in get_fields_super_classes tenv classname | _ -> []) | _ -> [] @@ -78,12 +78,12 @@ let rec get_fields type_ptr_to_sil_type tenv decl_list = (* Add potential extra fields defined only in the implementation of the class *) (* to the info given in the interface. Update the tenv accordingly. *) let add_missing_fields tenv class_name missing_fields = - let class_tn_name = Typ.Name.Objc.from_string class_name in + let class_tn_name = Typ.Name.Objc.from_qual_name class_name in match Tenv.lookup tenv class_tn_name with | Some ({ fields } as struct_typ) -> let new_fields = CGeneral_utils.append_no_duplicates_fields fields missing_fields in ignore (Tenv.mk_struct tenv ~default:struct_typ ~fields:new_fields ~statics:[] class_tn_name); - Logging.out_debug " Updating info for class '%s' in tenv\n" class_name + Logging.out_debug " Updating info for class '%a' in tenv\n" QualifiedCppName.pp class_name | _ -> () let modelled_fields_in_classes = diff --git a/infer/src/clang/cField_decl.mli b/infer/src/clang/cField_decl.mli index e6267c001..32ddcf638 100644 --- a/infer/src/clang/cField_decl.mli +++ b/infer/src/clang/cField_decl.mli @@ -21,6 +21,6 @@ val fields_superclass : Tenv.t -> Clang_ast_t.obj_c_interface_decl_info -> field val build_sil_field : CAst_utils.type_ptr_to_sil_type -> Tenv.t -> Clang_ast_t.named_decl_info -> Clang_ast_t.type_ptr -> Clang_ast_t.property_attribute list -> field_type -val add_missing_fields : Tenv.t -> string -> field_type list -> unit +val add_missing_fields : Tenv.t -> QualifiedCppName.t -> field_type list -> unit val modelled_field : Clang_ast_t.named_decl_info -> field_type list diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index 3100f6253..607659afb 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -201,7 +201,8 @@ let log_frontend_issue translation_unit_context method_decl_opt key issue_desc l let exn = Exceptions.Frontend_warning (name, err_desc, __POS__) in let trace = [ Errlog.make_trace_element 0 issue_desc.CIssue.loc "" [] ] in let err_kind = issue_desc.CIssue.severity in - let method_name = CAst_utils.full_name_of_decl_opt method_decl_opt in + let method_name = CAst_utils.full_name_of_decl_opt method_decl_opt + |> QualifiedCppName.to_qual_string in let key = Hashtbl.hash (key ^ method_name) in Reporting.log_issue_from_errlog err_kind errlog exn ~loc ~ltr:trace ~node_id:(0, key) ?linters_def_file diff --git a/infer/src/clang/cGeneral_utils.ml b/infer/src/clang/cGeneral_utils.ml index 1e2cbe415..7ed4450a3 100644 --- a/infer/src/clang/cGeneral_utils.ml +++ b/infer/src/clang/cGeneral_utils.ml @@ -102,8 +102,7 @@ let replicate n el = List.map ~f:(fun _ -> el) (list_range 0 (n -1)) let mk_class_field_name field_qual_name = let field_name = field_qual_name.Clang_ast_t.ni_name in let class_name = CAst_utils.get_class_name_from_member field_qual_name in - let qual_class_name = QualifiedCppName.of_qual_string class_name in - Fieldname.Clang.from_qualified qual_class_name field_name + Fieldname.Clang.from_qualified class_name field_name let is_cpp_translation translation_unit_context = let lang = translation_unit_context.CFrontend_config.lang in @@ -116,7 +115,7 @@ let is_objc_extension translation_unit_context = CFrontend_config.equal_clang_lang lang CFrontend_config.ObjCPP let get_var_name_mangled name_info var_decl_info = - let clang_name = CAst_utils.get_qualified_name name_info in + let clang_name = CAst_utils.get_qualified_name name_info |> QualifiedCppName.to_qual_string in let param_idx_opt = var_decl_info.Clang_ast_t.vdi_parm_index_in_function in let name_string = match clang_name, param_idx_opt with @@ -175,5 +174,6 @@ let mk_sil_var trans_unit_ctx named_decl_info decl_info_type_ptr_opt procname ou let mangled_name = Mangled.mangled name_string mangled in Pvar.mk mangled_name procname | None -> - let name_string = CAst_utils.get_qualified_name named_decl_info in + let name_string = CAst_utils.get_qualified_name named_decl_info + |> QualifiedCppName.to_qual_string in Pvar.mk (Mangled.from_string name_string) procname diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 000725e31..4d4221dba 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -236,7 +236,7 @@ let get_superclass_curr_class_objc context = super_of_decl_ref_opt ocidi.ocidi_class_interface | _ -> assert false in match CContext.get_curr_class context with - | CContext.ContextClsDeclPtr ptr -> Typ.Name.Objc.from_string (retreive_super_name ptr) + | CContext.ContextClsDeclPtr ptr -> Typ.Name.Objc.from_qual_name (retreive_super_name ptr) | CContext.ContextNoCls -> assert false (* Gets the class name from a method signature found by clang, if search is successful *) diff --git a/infer/src/clang/cPredicates.ml b/infer/src/clang/cPredicates.ml index 01bbb0e85..42645586e 100644 --- a/infer/src/clang/cPredicates.ml +++ b/infer/src/clang/cPredicates.ml @@ -198,7 +198,9 @@ let is_property_pointer_type an = | Some ObjCObjectPointerType _ | Some BlockPointerType _ -> true | Some TypedefType (_, tti) -> - String.equal (CAst_utils.name_of_typedef_type_info tti) CFrontend_config.id_cl + let typedef_str = CAst_utils.name_of_typedef_type_info tti + |> QualifiedCppName.to_qual_string in + String.equal typedef_str CFrontend_config.id_cl | exception Not_found -> false | _ -> false) | _ -> false diff --git a/infer/src/clang/cTrans.ml b/infer/src/clang/cTrans.ml index bf7357cc3..ff0e9d13d 100644 --- a/infer/src/clang/cTrans.ml +++ b/infer/src/clang/cTrans.ml @@ -437,7 +437,7 @@ struct let root_node' = GotoLabel.find_goto_label trans_state.context label_name sil_loc in { empty_res_trans with root_nodes = [root_node']; leaf_nodes = trans_state.succ_nodes } - let get_builtin_pname_opt trans_unit_ctx name decl_opt type_ptr = + let get_builtin_pname_opt trans_unit_ctx qual_name decl_opt type_ptr = let get_deprecated_attr_arg decl = let open Clang_ast_t in let decl_info = Clang_ast_proj.get_decl_tuple decl in @@ -451,6 +451,7 @@ struct coming from ASTExporter.h in facebook-clang-plugins *) assert false) | None -> None in + let name = QualifiedCppName.to_qual_string qual_name in let function_attr_opt = Option.bind decl_opt get_deprecated_attr_arg in match function_attr_opt with | Some attr when CTrans_models.is_modeled_attribute attr -> @@ -473,12 +474,14 @@ struct let name_info, decl_ptr, type_ptr = CAst_utils.get_info_from_decl_ref decl_ref in let decl_opt = CAst_utils.get_function_decl_with_body decl_ptr in Option.iter ~f:(call_translation context) decl_opt; - let name = CAst_utils.get_qualified_name name_info in + let qual_name = CAst_utils.get_qualified_name name_info in let typ = CType_decl.type_ptr_to_sil_type context.tenv type_ptr in let pname = - match get_builtin_pname_opt context.translation_unit_context name decl_opt type_ptr with + match get_builtin_pname_opt context.translation_unit_context qual_name decl_opt type_ptr with | Some builtin_pname -> builtin_pname - | None -> CMethod_trans.create_procdesc_with_pointer context decl_ptr None name in + | None -> + let name = QualifiedCppName.to_qual_string qual_name in + CMethod_trans.create_procdesc_with_pointer context decl_ptr None name in { empty_res_trans with exps = [(Exp.Const (Const.Cfun pname), typ)] } let field_deref_trans trans_state stmt_info pre_trans_result decl_ref ~is_constructor_init = @@ -566,7 +569,7 @@ struct type_ptr with | Some builtin_pname -> builtin_pname | None -> - let class_typename = Typ.Name.Cpp.from_string + let class_typename = Typ.Name.Cpp.from_qual_name Typ.NoTemplate (CAst_utils.get_class_name_from_member name_info) in CMethod_trans.create_procdesc_with_pointer context decl_ptr (Some class_typename) method_name in diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index 2a787a000..bec3e587e 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -74,6 +74,7 @@ let get_first_param_typedef_string_opt type_ptr = match CAst_utils.get_desugared_type type_ptr with | Some Clang_ast_t.FunctionProtoType (_, _, {pti_params_type = [param_ptr]}) -> CAst_utils.name_opt_of_typedef_type_ptr param_ptr + |> Option.map ~f:QualifiedCppName.to_qual_string | _ -> None let is_release_builtin funct fun_type = diff --git a/infer/src/clang/objcCategory_decl.ml b/infer/src/clang/objcCategory_decl.ml index 2604e687b..d0c705d70 100644 --- a/infer/src/clang/objcCategory_decl.ml +++ b/infer/src/clang/objcCategory_decl.ml @@ -59,7 +59,7 @@ let get_base_class_name_from_category decl = | Some decl_ref -> (match CAst_utils.get_decl decl_ref.Clang_ast_t.dr_decl_pointer with | Some ObjCInterfaceDecl (_, name_info, _, _, _) -> - Some (Typ.Name.Objc.from_string (CAst_utils.get_qualified_name name_info)) + Some (Typ.Name.Objc.from_qual_name (CAst_utils.get_qualified_name name_info)) | _ -> None) | None -> None @@ -67,7 +67,7 @@ let get_base_class_name_from_category decl = (* to the corresponding class. Update the tenv accordingly.*) let process_category type_ptr_to_sil_type tenv class_name decl_info decl_list = let decl_fields = CField_decl.get_fields type_ptr_to_sil_type tenv decl_list in - let class_tn_name = Typ.Name.Objc.from_string class_name in + let class_tn_name = Typ.Name.Objc.from_qual_name class_name in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in CAst_utils.update_sil_types_map decl_key (Typ.Tstruct class_tn_name); (match Tenv.lookup tenv class_tn_name with @@ -76,7 +76,7 @@ let process_category type_ptr_to_sil_type tenv class_name decl_info decl_list = ignore( Tenv.mk_struct tenv ~default:struct_typ ~fields:new_fields ~statics:[] ~methods:[] class_tn_name ); - Logging.out_debug " Updating info for class '%s' in tenv\n" class_name + Logging.out_debug " Updating info for class '%a' in tenv\n" QualifiedCppName.pp class_name | _ -> ()); Typ.Tstruct class_tn_name @@ -86,7 +86,7 @@ let category_decl type_ptr_to_sil_type tenv decl = | ObjCCategoryDecl (decl_info, name_info, decl_list, _, cdi) -> let name = CAst_utils.get_qualified_name name_info in let class_name = get_classname_from_category_decl cdi in - Logging.out_debug "ADDING: ObjCCategoryDecl for '%s'\n" name; + Logging.out_debug "ADDING: ObjCCategoryDecl for '%a'\n" QualifiedCppName.pp name; let _ = add_class_decl type_ptr_to_sil_type tenv cdi in let typ = process_category type_ptr_to_sil_type tenv class_name decl_info decl_list in let _ = add_category_implementation type_ptr_to_sil_type tenv cdi in @@ -99,7 +99,7 @@ let category_impl_decl type_ptr_to_sil_type tenv decl = | ObjCCategoryImplDecl (decl_info, name_info, decl_list, _, cii) -> let name = CAst_utils.get_qualified_name name_info in let class_name = get_classname_from_category_impl cii in - Logging.out_debug "ADDING: ObjCCategoryImplDecl for '%s'\n" name; + Logging.out_debug "ADDING: ObjCCategoryImplDecl for '%a'\n" QualifiedCppName.pp name; let _ = add_category_decl type_ptr_to_sil_type tenv cii in let typ = process_category type_ptr_to_sil_type tenv class_name decl_info decl_list in typ diff --git a/infer/src/clang/objcInterface_decl.ml b/infer/src/clang/objcInterface_decl.ml index 45caf8ec2..f1f6e0c86 100644 --- a/infer/src/clang/objcInterface_decl.ml +++ b/infer/src/clang/objcInterface_decl.ml @@ -60,8 +60,8 @@ let get_interface_supers super_opt protocols = let super_class = match super_opt with | None -> [] - | Some super -> [Typ.Name.Objc.from_string super] in - let protocol_names = List.map ~f:Typ.Name.Objc.protocol_from_string protocols in + | Some super -> [Typ.Name.Objc.from_qual_name super] in + let protocol_names = List.map ~f:Typ.Name.Objc.protocol_from_qual_name protocols in let super_classes = super_class@protocol_names in super_classes @@ -76,8 +76,8 @@ let create_supers_fields type_ptr_to_sil_type tenv decl_list (* Adds pairs (interface name, interface_type_info) to the global environment. *) let add_class_to_tenv type_ptr_to_sil_type tenv decl_info name_info decl_list ocidi = let class_name = CAst_utils.get_qualified_name name_info in - Logging.out_debug "ADDING: ObjCInterfaceDecl for '%s'\n" class_name; - let interface_name = Typ.Name.Objc.from_string class_name in + Logging.out_debug "ADDING: ObjCInterfaceDecl for '%a'\n" QualifiedCppName.pp class_name; + let interface_name = Typ.Name.Objc.from_qual_name class_name in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in CAst_utils.update_sil_types_map decl_key (Typ.Tstruct interface_name); let decl_supers, decl_fields = @@ -100,7 +100,7 @@ let add_class_to_tenv type_ptr_to_sil_type tenv decl_info name_info decl_list oc (* We add the special hidden counter_field for implementing reference counting *) let modelled_fields = Typ.Struct.objc_ref_counter_field :: CField_decl.modelled_field name_info in let all_fields = CGeneral_utils.append_no_duplicates_fields modelled_fields fields in - Logging.out_debug "Class %s field:\n" class_name; + Logging.out_debug "Class %a field:\n" QualifiedCppName.pp class_name; List.iter ~f:(fun (fn, _, _) -> Logging.out_debug "-----> field: '%s'\n" (Fieldname.to_string fn)) all_fields; ignore( @@ -136,11 +136,12 @@ let interface_impl_declaration type_ptr_to_sil_type tenv decl = match decl with | ObjCImplementationDecl (decl_info, name_info, decl_list, _, idi) -> let class_name = CAst_utils.get_qualified_name name_info in - Logging.out_debug "ADDING: ObjCImplementationDecl for class '%s'\n" class_name; + Logging.out_debug + "ADDING: ObjCImplementationDecl for class '%a'\n" QualifiedCppName.pp class_name; let _ = add_class_decl type_ptr_to_sil_type tenv idi in let fields = CField_decl.get_fields type_ptr_to_sil_type tenv decl_list in CField_decl.add_missing_fields tenv class_name fields; - let class_tn_name = Typ.Name.Objc.from_string class_name in + let class_tn_name = Typ.Name.Objc.from_qual_name class_name in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in let class_typ = Typ.Tstruct class_tn_name in CAst_utils.update_sil_types_map decl_key class_typ; diff --git a/infer/src/clang/objcProtocol_decl.ml b/infer/src/clang/objcProtocol_decl.ml index 108087bea..59f24cc68 100644 --- a/infer/src/clang/objcProtocol_decl.ml +++ b/infer/src/clang/objcProtocol_decl.ml @@ -24,8 +24,8 @@ let protocol_decl type_ptr_to_sil_type tenv decl = (* Protocol_type_info contains the methods composing the protocol. *) (* Here we are giving a similar treatment as interfaces (see above)*) (* It may turn out that we need a more specific treatment for protocols*) - Logging.out_debug "ADDING: ObjCProtocolDecl for '%s'\n" name; - let protocol_name = Typ.Name.Objc.protocol_from_string name in + Logging.out_debug "ADDING: ObjCProtocolDecl for '%a'\n" QualifiedCppName.pp name; + let protocol_name = Typ.Name.Objc.protocol_from_qual_name name in let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in CAst_utils.update_sil_types_map decl_key (Typ.Tstruct protocol_name); ignore( Tenv.mk_struct tenv ~methods:[] protocol_name );