From 2a425b82188dc7c370649e08e796884c823cf21a Mon Sep 17 00:00:00 2001 From: Andrzej Kotulski Date: Mon, 5 Oct 2015 07:26:06 -0700 Subject: [PATCH] Add structured type_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Summary: @​public Get newest goodness from facebook-clang-plugins that allows us to change type of type_ptr during deserialization We are modifying clang_ast_types.ml that fcp/clang-ocaml expects to exist - we provide our own implementations of: t_ptr, pointer_to_type_ptr, type_ptr_to_pointer Reviewed By: @dulmarod Differential Revision: D2498623 --- facebook-clang-plugins | 2 +- infer/src/clang/ast_expressions.ml | 10 ++-- infer/src/clang/ast_expressions.mli | 2 - infer/src/clang/cEnum_decl.ml | 4 +- infer/src/clang/cEnum_decl.mli | 2 +- infer/src/clang/cFrontend_config.ml | 2 +- infer/src/clang/cFrontend_config.mli | 7 ++- infer/src/clang/cFrontend_utils.ml | 14 ++++- infer/src/clang/cFrontend_utils.mli | 9 ++- infer/src/clang/cMethod_trans.ml | 3 +- infer/src/clang/cTrans_models.ml | 3 +- infer/src/clang/cType_to_sil_type.ml | 79 ++++++++++++++------------- infer/src/clang/cTypes.ml | 8 +-- infer/src/clang/cTypes.mli | 2 +- infer/src/clang/clang_ast_types.ml | 52 ++++++++++++++++++ infer/src/clang/objcInterface_decl.ml | 3 +- 16 files changed, 133 insertions(+), 69 deletions(-) create mode 100644 infer/src/clang/clang_ast_types.ml diff --git a/facebook-clang-plugins b/facebook-clang-plugins index 657a463bf..ae44c0bb0 160000 --- a/facebook-clang-plugins +++ b/facebook-clang-plugins @@ -1 +1 @@ -Subproject commit 657a463bfb6cd9e194684f5953c66f196a078ff9 +Subproject commit ae44c0bb0f2f76110535401c0d3b2966e4c630f4 diff --git a/infer/src/clang/ast_expressions.ml b/infer/src/clang/ast_expressions.ml index 8eee8e483..82637d5e4 100644 --- a/infer/src/clang/ast_expressions.ml +++ b/infer/src/clang/ast_expressions.ml @@ -76,11 +76,9 @@ let stmt_info_with_fresh_pointer stmt_info = { si_source_range = stmt_info.Clang_ast_t.si_source_range; } -let create_type_ptr_with_just_pointer pointer = pointer - let get_constant_type_ptr s = let pointer = CFrontend_config.type_pointer_prefix ^ s in - pointer + `Prebuilt pointer (* Whenever new type are added manually to the translation here, *) (* they should be added to the map in cTypes_decl too!! *) @@ -114,11 +112,11 @@ let create_void_unsigned_long_type = let create_void_void_type = get_constant_type_ptr "void (void *)" -let create_class_type class_name = "custom_class_name*" ^ class_name +let create_class_type class_name = `ClassType class_name -let create_struct_type struct_name = "custom_struct_name*" ^ struct_name +let create_struct_type struct_name = `StructType struct_name -let create_pointer_type class_type = "custom_pointer_" ^ class_type +let create_pointer_type typ = `PointerOf typ let create_integer_literal stmt_info n = let stmt_info = dummy_stmt_info () in diff --git a/infer/src/clang/ast_expressions.mli b/infer/src/clang/ast_expressions.mli index aa9246815..6638d2b55 100644 --- a/infer/src/clang/ast_expressions.mli +++ b/infer/src/clang/ast_expressions.mli @@ -47,8 +47,6 @@ val create_struct_type : string -> type_ptr val create_pointer_type : type_ptr -> type_ptr -val create_type_ptr_with_just_pointer : Clang_ast_t.pointer -> type_ptr - val make_objc_ivar_decl : decl_info -> type_ptr -> obj_c_property_impl_decl_info -> named_decl_info -> decl diff --git a/infer/src/clang/cEnum_decl.ml b/infer/src/clang/cEnum_decl.ml index 918df0f99..263bd0b1f 100644 --- a/infer/src/clang/cEnum_decl.ml +++ b/infer/src/clang/cEnum_decl.ml @@ -47,7 +47,7 @@ let rec get_enum_constants context decl_list v = (Mangled.from_string name, const) :: get_enum_constants context decl_list' v) | _ -> assert false -let enum_decl name tenv cfg cg namespace pointer decl_list opt_type = +let enum_decl name tenv cfg cg namespace type_ptr decl_list opt_type = Printing.log_out "ADDING: EnumDecl '%s'\n" name; let context' = CContext.create_context tenv cg cfg !global_procdesc namespace CContext.ContextNoCls @@ -59,6 +59,6 @@ let enum_decl name tenv cfg cg namespace pointer decl_list opt_type = (* Here we could give "enum "^name but I want to check that this the type is always defined *) let typename = CTypes.mk_enumname name in let typ = Sil.Tenum enum_constants in - Ast_utils.update_sil_types_map pointer typ; + Ast_utils.update_sil_types_map type_ptr typ; Printing.log_out " TN_typename('%s')\n" (Sil.typename_to_string typename); Sil.tenv_add tenv typename typ diff --git a/infer/src/clang/cEnum_decl.mli b/infer/src/clang/cEnum_decl.mli index f744fe347..9cf37ec43 100644 --- a/infer/src/clang/cEnum_decl.mli +++ b/infer/src/clang/cEnum_decl.mli @@ -10,5 +10,5 @@ (** Translate an enumeration declaration by adding it to the tenv and *) (** translating the code and adding it to a fake procdesc *) -val enum_decl : string -> Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.pointer -> +val enum_decl : string -> Sil.tenv -> Cfg.cfg -> Cg.t -> string option -> Clang_ast_t.type_ptr -> Clang_ast_t.decl list -> Clang_ast_t.opt_type -> unit diff --git a/infer/src/clang/cFrontend_config.ml b/infer/src/clang/cFrontend_config.ml index c35f03555..df5c37431 100644 --- a/infer/src/clang/cFrontend_config.ml +++ b/infer/src/clang/cFrontend_config.ml @@ -156,7 +156,7 @@ let generated_suffix = "*generated" let pointer_type_index = ref Clang_ast_main.PointerMap.empty (* Map from type pointers or declaration pointers to sil types *) -let sil_types_map = ref Clang_ast_main.PointerMap.empty +let sil_types_map = ref Clang_ast_types.TypePointerMap.empty let type_pointer_prefix = "internal_type" diff --git a/infer/src/clang/cFrontend_config.mli b/infer/src/clang/cFrontend_config.mli index 9cf56fb99..e8dc89686 100644 --- a/infer/src/clang/cFrontend_config.mli +++ b/infer/src/clang/cFrontend_config.mli @@ -145,10 +145,13 @@ val enumerateObjectsUsingBlock : string val generated_suffix : string +(** Map from clang pointers to types produced by ast exporter. + Populated once on InferClang startup *) val pointer_type_index : Clang_ast_t.c_type Clang_ast_main.PointerMap.t ref -(* Map from type pointers or declaration pointers to sil types *) -val sil_types_map : (Sil.typ Clang_ast_main.PointerMap.t) ref +(** Map from type pointers (clang pointers and types created later by frontend) to sil types + Populated during frontend execution when new type is found *) +val sil_types_map : (Sil.typ Clang_ast_types.TypePointerMap.t) ref val type_pointer_prefix : string diff --git a/infer/src/clang/cFrontend_utils.ml b/infer/src/clang/cFrontend_utils.ml index e596c5aac..4354b9db6 100644 --- a/infer/src/clang/cFrontend_utils.ml +++ b/infer/src/clang/cFrontend_utils.ml @@ -283,12 +283,20 @@ struct let update_sil_types_map type_ptr sil_type = CFrontend_config.sil_types_map := - Clang_ast_main.PointerMap.add type_ptr sil_type !CFrontend_config.sil_types_map + Clang_ast_types.TypePointerMap.add type_ptr sil_type !CFrontend_config.sil_types_map let get_type type_ptr = try - Some (Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.pointer_type_index) - with Not_found -> Printing.log_stats "type with pointer %s not found\n" type_ptr; None + (* There is chance for success only if type_ptr is in fact clang pointer *) + (let raw_ptr = Clang_ast_types.type_ptr_to_clang_pointer type_ptr in + try + Some (Clang_ast_main.PointerMap.find raw_ptr !CFrontend_config.pointer_type_index) + with Not_found -> Printing.log_stats "type with pointer %s not found\n" raw_ptr; None) + with Clang_ast_types.Not_Clang_Pointer -> + (* otherwise, function fails *) + let type_str = Clang_ast_types.type_ptr_to_string type_ptr in + Printing.log_stats "type %s is not clang pointer\n" type_str; + None let get_desugared_type type_ptr = let typ_opt = get_type type_ptr in diff --git a/infer/src/clang/cFrontend_utils.mli b/infer/src/clang/cFrontend_utils.mli index 416320b02..a4f2910ab 100644 --- a/infer/src/clang/cFrontend_utils.mli +++ b/infer/src/clang/cFrontend_utils.mli @@ -79,14 +79,17 @@ sig val get_decl : Clang_ast_t.pointer -> Clang_ast_t.decl option - val update_sil_types_map : Clang_ast_t.pointer -> Sil.typ -> unit + val update_sil_types_map : Clang_ast_t.type_ptr -> Sil.typ -> unit (** creates a string to append to a name from a list of qualifiers to a name *) val get_qualifier_string : Clang_ast_t.named_decl_info -> string - val get_type : Clang_ast_t.pointer -> Clang_ast_t.c_type option + (** 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 - val get_desugared_type : Clang_ast_t.pointer -> Clang_ast_t.c_type option + (** looks up clang pointer to type and resolves any sugar around it. + See get_type for more info and restrictions *) + val get_desugared_type : Clang_ast_t.type_ptr -> Clang_ast_t.c_type option (** returns declaration of the type for certain types and crashes for others NOTE: this function needs extending to handle objC types *) diff --git a/infer/src/clang/cMethod_trans.ml b/infer/src/clang/cMethod_trans.ml index 80a3a2595..1f226b890 100644 --- a/infer/src/clang/cMethod_trans.ml +++ b/infer/src/clang/cMethod_trans.ml @@ -82,8 +82,7 @@ let get_return_type function_method_decl_info = match function_method_decl_info with | Func_decl_info (_, typ, _) | Cpp_Meth_decl_info (_, _, typ) - | Block_decl_info (_, typ) -> - Ast_expressions.create_type_ptr_with_just_pointer (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 let build_method_signature decl_info procname function_method_decl_info is_instance is_anonym_block is_generated = diff --git a/infer/src/clang/cTrans_models.ml b/infer/src/clang/cTrans_models.ml index 8cf5282b3..192a4c59d 100644 --- a/infer/src/clang/cTrans_models.ml +++ b/infer/src/clang/cTrans_models.ml @@ -145,7 +145,8 @@ let get_predefined_ms_retain_release class_name method_name mk_procname lang = if is_retain_method method_name || is_autorelease_method method_name then Ast_expressions.create_id_type else Ast_expressions.create_void_type in let class_name = CFrontend_config.nsobject_cl in - let args = [(CFrontend_config.self, class_name, None)] in + let class_type = Ast_expressions.create_class_type class_name in + let args = [(CFrontend_config.self, class_type, None)] in get_predefined_ms_method condition class_name method_name Procname.Instance_objc_method mk_procname lang args return_type [] (get_builtinname method_name) diff --git a/infer/src/clang/cType_to_sil_type.ml b/infer/src/clang/cType_to_sil_type.ml index 7df855727..1fb506fd2 100644 --- a/infer/src/clang/cType_to_sil_type.ml +++ b/infer/src/clang/cType_to_sil_type.ml @@ -9,20 +9,6 @@ open CFrontend_utils -let custom_type_ptr_to_sil_type type_pointer = - if Utils.string_is_prefix "custom" type_pointer then - let typ = - (match CTypes.get_name_from_type_pointer type_pointer with - | "custom_class_name", class_name -> Sil.Tvar (CTypes.mk_classname class_name) - | "custom_pointer_custom_class_name", class_name -> - Sil.Tptr (Sil.Tvar (CTypes.mk_classname class_name), Sil.Pk_pointer) - | "custom_struct_name", struct_name -> Sil.Tvar (CTypes.mk_structname struct_name) - | "custom_pointer_custom_struct_name", struct_name -> - Sil.Tptr (Sil.Tvar (CTypes.mk_structname struct_name), Sil.Pk_pointer) - | _ -> assert false) in - Some typ - else None - let get_builtin_objc_typename builtin_type = match builtin_type with | `ObjCId -> Sil.TN_csu (Sil.Struct, (Mangled.from_string CFrontend_config.objc_object)) @@ -74,7 +60,7 @@ let pointer_attribute_of_objc_attribute attr_info = | `OCL_Autoreleasing -> Sil.Pk_objc_autoreleasing let rec build_array_type translate_decl tenv type_ptr n = - let array_type = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in + let array_type = type_ptr_to_sil_type translate_decl tenv type_ptr in let exp = Sil.exp_int (Sil.Int.of_int64 (Int64.of_int n)) in Sil.Tarray (array_type, exp) @@ -83,9 +69,9 @@ and sil_type_of_attr_type translate_decl tenv type_info attr_info = | Some type_ptr -> (match Ast_utils.get_type type_ptr with | Some Clang_ast_t.ObjCObjectPointerType (type_info', type_ptr') -> - let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr' in + let typ = type_ptr_to_sil_type translate_decl tenv type_ptr' in Sil.Tptr (typ, pointer_attribute_of_objc_attribute attr_info) - | _ -> type_ptr_ptr_to_sil_type translate_decl tenv type_ptr) + | _ -> type_ptr_to_sil_type translate_decl tenv type_ptr) | None -> Sil.Tvoid and sil_type_of_c_type translate_decl tenv c_type = @@ -96,14 +82,14 @@ and sil_type_of_c_type translate_decl tenv c_type = sil_type_of_builtin_type_kind builtin_type_kind | PointerType (type_info, type_ptr) | ObjCObjectPointerType (type_info, type_ptr) -> - let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in + let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in if Sil.typ_equal typ (get_builtin_objc_type `ObjCClass) then typ else Sil.Tptr (typ, Sil.Pk_pointer) | ObjCObjectType (type_info, objc_object_type_info) -> - type_ptr_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type + type_ptr_to_sil_type translate_decl tenv objc_object_type_info.Clang_ast_t.base_type | BlockPointerType (type_info, type_ptr) -> - let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in + let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in Sil.Tptr (typ, Sil.Pk_pointer) | IncompleteArrayType (type_info, type_ptr) | DependentSizedArrayType (type_info, type_ptr) @@ -115,32 +101,33 @@ and sil_type_of_c_type translate_decl tenv c_type = | FunctionNoProtoType (type_info, function_type_info) -> Sil.Tfun false | ParenType (type_info, type_ptr) -> - type_ptr_ptr_to_sil_type translate_decl tenv type_ptr + type_ptr_to_sil_type translate_decl tenv type_ptr | DecayedType (type_info, type_ptr) -> - type_ptr_ptr_to_sil_type translate_decl tenv type_ptr + type_ptr_to_sil_type translate_decl tenv type_ptr | RecordType (type_info, pointer) | EnumType (type_info, pointer) -> decl_ptr_to_sil_type translate_decl tenv pointer | ElaboratedType (type_info) -> (match type_info.Clang_ast_t.ti_desugared_type with - Some type_ptr -> type_ptr_ptr_to_sil_type translate_decl tenv type_ptr + Some type_ptr -> type_ptr_to_sil_type translate_decl tenv type_ptr | None -> Sil.Tvoid) | ObjCInterfaceType (type_info, pointer) -> decl_ptr_to_sil_type translate_decl tenv pointer | LValueReferenceType (type_info, type_ptr) -> - let typ = type_ptr_ptr_to_sil_type translate_decl tenv type_ptr in + let typ = type_ptr_to_sil_type translate_decl tenv type_ptr in Sil.Tptr (typ, Sil.Pk_reference) | AttributedType (type_info, attr_info) -> sil_type_of_attr_type translate_decl tenv type_info attr_info | _ -> (* TypedefType, etc *) let type_info = Clang_ast_proj.get_type_tuple c_type in match type_info.Clang_ast_t.ti_desugared_type with - | Some typ -> type_ptr_ptr_to_sil_type translate_decl tenv typ + | Some typ -> type_ptr_to_sil_type translate_decl tenv typ | None -> Sil.Tvoid and decl_ptr_to_sil_type translate_decl tenv decl_ptr = let open Clang_ast_t in - try Clang_ast_main.PointerMap.find decl_ptr !CFrontend_config.sil_types_map + let typ = `DeclPtr decl_ptr in + try Clang_ast_types.TypePointerMap.find typ !CFrontend_config.sil_types_map with Not_found -> match Ast_utils.get_decl decl_ptr with | Some (ObjCInterfaceDecl(decl_info, name_info, decl_list, decl_context_info, oidi)) -> @@ -158,19 +145,33 @@ and decl_ptr_to_sil_type translate_decl tenv decl_ptr = (Clang_ast_j.string_of_pointer decl_ptr); Sil.Tvoid -and type_ptr_ptr_to_sil_type translate_decl tenv type_ptr = +and clang_type_ptr_to_sil_type translate_decl tenv type_ptr = + try + Clang_ast_types.TypePointerMap.find type_ptr !CFrontend_config.sil_types_map + with Not_found -> + (match Ast_utils.get_type type_ptr with + | Some c_type -> + let sil_type = sil_type_of_c_type translate_decl tenv c_type in + Ast_utils.update_sil_types_map type_ptr sil_type; + sil_type + | _ -> Sil.Tvoid) + +and prebuilt_type_to_sil_type type_ptr = try - Clang_ast_main.PointerMap.find type_ptr !CFrontend_config.sil_types_map + Clang_ast_types.TypePointerMap.find type_ptr !CFrontend_config.sil_types_map with Not_found -> - match Ast_utils.get_type type_ptr with - | Some c_type -> - let sil_type = sil_type_of_c_type translate_decl tenv c_type in - Ast_utils.update_sil_types_map type_ptr sil_type; - sil_type - | _ -> Sil.Tvoid + Printing.log_stats "Prebuilt type %s not found\n" + (Clang_ast_types.type_ptr_to_string type_ptr); + assert false -and type_ptr_to_sil_type translate_decl tenv tp = - let type_ptr = tp in - match custom_type_ptr_to_sil_type type_ptr with - | Some typ -> typ - | None -> type_ptr_ptr_to_sil_type translate_decl tenv type_ptr +and type_ptr_to_sil_type translate_decl tenv type_ptr = + match type_ptr with + | `TPtr _ -> clang_type_ptr_to_sil_type translate_decl tenv type_ptr + | `Prebuilt _ -> prebuilt_type_to_sil_type type_ptr + | `PointerOf typ -> + let sil_typ = type_ptr_to_sil_type translate_decl tenv typ in + Sil.Tptr (sil_typ, Sil.Pk_pointer) + | `ClassType name -> Sil.Tvar (CTypes.mk_classname name) + | `StructType name -> Sil.Tvar (CTypes.mk_structname name) + | `DeclPtr ptr -> decl_ptr_to_sil_type translate_decl tenv ptr + | `ErrorType -> Sil.Tvoid diff --git a/infer/src/clang/cTypes.ml b/infer/src/clang/cTypes.ml index ab649a01e..b2fc1be02 100644 --- a/infer/src/clang/cTypes.ml +++ b/infer/src/clang/cTypes.ml @@ -114,12 +114,12 @@ let rec return_type_of_function_type_ptr type_ptr = return_type_of_function_type_ptr in_type_ptr | Some _ -> Printing.log_err "Warning: Type pointer %s is not a function type." - (Clang_ast_j.string_of_pointer type_ptr); - "" + (Clang_ast_types.type_ptr_to_string type_ptr); + `ErrorType | None -> Printing.log_err "Warning: Type pointer %s not found." - (Clang_ast_j.string_of_pointer type_ptr); - "" + (Clang_ast_types.type_ptr_to_string type_ptr); + `ErrorType let return_type_of_function_type tp = return_type_of_function_type_ptr tp diff --git a/infer/src/clang/cTypes.mli b/infer/src/clang/cTypes.mli index 908b18718..f2db931dc 100644 --- a/infer/src/clang/cTypes.mli +++ b/infer/src/clang/cTypes.mli @@ -29,7 +29,7 @@ val remove_pointer_to_typ : Sil.typ -> Sil.typ val is_class : Sil.typ -> bool -val return_type_of_function_type : Clang_ast_t.type_ptr -> Clang_ast_t.pointer +val return_type_of_function_type : Clang_ast_t.type_ptr -> Clang_ast_t.type_ptr val is_block_type : Clang_ast_t.type_ptr -> bool diff --git a/infer/src/clang/clang_ast_types.ml b/infer/src/clang/clang_ast_types.ml new file mode 100644 index 000000000..a456b0e8b --- /dev/null +++ b/infer/src/clang/clang_ast_types.ml @@ -0,0 +1,52 @@ +(* + * Copyright (c) 2015 - present Facebook, Inc. + * All rights reserved. + * + * This source code is licensed under the BSD style license found in the + * LICENSE file in the root directory of this source tree. An additional grant + * of patent rights can be found in the PATENTS file in the same directory. + *) + +(* This module adds more structure to some fields in AST *) +(* The implementation is replacement of default one from *) +(* facebook-clang-plugins repository *) + + +(* Type pointers *) + +exception Not_Clang_Pointer + +type t_ptr = [ + | `TPtr of string + | `Prebuilt of string + | `PointerOf of t_ptr + | `ClassType of string + | `StructType of string + | `DeclPtr of string + | `ErrorType] + +module TypePointerOrd = struct + type t = t_ptr + let compare = Pervasives.compare +end + +module TypePointerMap = Map.Make(TypePointerOrd) + +let rec type_ptr_to_string type_ptr = match type_ptr with + | `TPtr raw -> "clang_ptr_" ^ raw + | `Prebuilt raw -> "prebuilt_" ^ raw + | `PointerOf typ -> "pointer_of_" ^ type_ptr_to_string typ + | `ClassType name -> "class_name_" ^ name + | `StructType name -> "struct_name_" ^ name + | `DeclPtr raw -> "decl_ptr_" ^ raw + | `ErrorType -> "error_type" + +let type_ptr_to_clang_pointer type_ptr = match type_ptr with + | `TPtr raw -> raw + | _ -> raise Not_Clang_Pointer + +let pointer_to_type_ptr raw = `TPtr raw + +let type_ptr_to_pointer type_ptr = match type_ptr with + | `TPtr raw -> raw + | _ -> "custom_type_" ^ (type_ptr_to_string type_ptr) diff --git a/infer/src/clang/objcInterface_decl.ml b/infer/src/clang/objcInterface_decl.ml index 0001e5b2f..427497c25 100644 --- a/infer/src/clang/objcInterface_decl.ml +++ b/infer/src/clang/objcInterface_decl.ml @@ -121,7 +121,8 @@ let add_class_to_tenv tenv decl_info class_name decl_list obj_c_interface_decl_i Sil.Tstruct(fields, [], Sil.Class, Some (Mangled.from_string class_name), superclasses, methods, objc_class_annotation) in Sil.tenv_add tenv interface_name interface_type_info; - Ast_utils.update_sil_types_map decl_info.Clang_ast_t.di_pointer (Sil.Tvar interface_name); + let decl_key = `DeclPtr decl_info.Clang_ast_t.di_pointer in + Ast_utils.update_sil_types_map decl_key (Sil.Tvar interface_name); Printing.log_out " >>>Verifying that Typename '%s' is in tenv\n" (Sil.typename_to_string interface_name); (match Sil.tenv_lookup tenv interface_name with