[Typ] Add instantiation types to StructTyp.t

Summary: Make backend aware of some template instantiation arguments for template classes.

Reviewed By: jberdine

Differential Revision: D4421338

fbshipit-source-id: f7d72b4
master
Andrzej Kotulski 8 years ago committed by Facebook Github Bot
parent d64480cf72
commit bc852ec0d1

@ -48,6 +48,7 @@ let mk_struct
methods::methods=? methods::methods=?
supers::supers=? supers::supers=?
annots::annots=? annots::annots=?
specialization::specialization=?
name => { name => {
let struct_typ = let struct_typ =
Typ.Struct.internal_mk_struct Typ.Struct.internal_mk_struct
@ -57,6 +58,7 @@ let mk_struct
methods::?methods methods::?methods
supers::?supers supers::?supers
annots::?annots annots::?annots
specialization::?specialization
(); ();
TypenameHash.replace tenv name struct_typ; TypenameHash.replace tenv name struct_typ;
struct_typ struct_typ

@ -46,6 +46,7 @@ let mk_struct:
methods::list Procname.t? => methods::list Procname.t? =>
supers::list Typename.t? => supers::list Typename.t? =>
annots::Annot.Item.t? => annots::Annot.Item.t? =>
specialization::Typ.template_spec_info? =>
Typename.t => Typename.t =>
Typ.Struct.t; Typ.Struct.t;

@ -296,7 +296,13 @@ let java_proc_return_typ pname_java =>
| typ => typ | typ => typ
}; };
type typ = t; type typ = t [@@deriving compare];
/* template instantiation arguments */
type template_spec_info =
| NoTemplate
| Template (string, list (option t))
[@@deriving compare];
let module Struct = { let module Struct = {
type field = (Ident.fieldname, T.t, Annot.Item.t) [@@deriving compare]; type field = (Ident.fieldname, T.t, Annot.Item.t) [@@deriving compare];
@ -308,7 +314,8 @@ let module Struct = {
statics: fields, /** static fields */ statics: fields, /** static fields */
supers: list Typename.t, /** superclasses */ supers: list Typename.t, /** superclasses */
methods: list Procname.t, /** methods defined */ methods: list Procname.t, /** methods defined */
annots: Annot.Item.t /** annotations */ annots: Annot.Item.t, /** annotations */
specialization: template_spec_info /** template specialization */
}; };
type lookup = Typename.t => option t; type lookup = Typename.t => option t;
let pp pe name f {fields, supers, methods, annots} => let pp pe name f {fields, supers, methods, annots} =>
@ -342,21 +349,31 @@ let module Struct = {
methods::methods=? methods::methods=?
supers::supers=? supers::supers=?
annots::annots=? annots::annots=?
specialization::specialization=?
() => { () => {
let mk_struct_ let mk_struct_
default:: default::
default={fields: [], statics: [], methods: [], supers: [], annots: Annot.Item.empty} default={
fields: [],
statics: [],
methods: [],
supers: [],
annots: Annot.Item.empty,
specialization: NoTemplate
}
fields::fields=default.fields fields::fields=default.fields
statics::statics=default.statics statics::statics=default.statics
methods::methods=default.methods methods::methods=default.methods
supers::supers=default.supers supers::supers=default.supers
annots::annots=default.annots annots::annots=default.annots
specialization::specialization=default.specialization
() => { () => {
fields, fields,
statics, statics,
methods, methods,
supers, supers,
annots annots,
specialization
}; };
mk_struct_ mk_struct_
default::?default default::?default
@ -365,6 +382,7 @@ let module Struct = {
methods::?methods methods::?methods
supers::?supers supers::?supers
annots::?annots annots::?annots
specialization::?specialization
() ()
}; };

@ -154,6 +154,12 @@ let java_proc_return_typ: Procname.java => t;
type typ = t; type typ = t;
/* template instantiation arguments */
type template_spec_info =
| NoTemplate
| Template (string, list (option t))
[@@deriving compare];
let module Struct: { let module Struct: {
type field = (Ident.fieldname, typ, Annot.Item.t) [@@deriving compare]; type field = (Ident.fieldname, typ, Annot.Item.t) [@@deriving compare];
type fields = list field; type fields = list field;
@ -164,7 +170,8 @@ let module Struct: {
statics: fields, /** static fields */ statics: fields, /** static fields */
supers: list Typename.t, /** supers */ supers: list Typename.t, /** supers */
methods: list Procname.t, /** methods defined */ methods: list Procname.t, /** methods defined */
annots: Annot.Item.t /** annotations */ annots: Annot.Item.t, /** annotations */
specialization: template_spec_info /** template specialization */
}; };
type lookup = Typename.t => option t; type lookup = Typename.t => option t;
@ -179,6 +186,7 @@ let module Struct: {
methods::list Procname.t? => methods::list Procname.t? =>
supers::list Typename.t? => supers::list Typename.t? =>
annots::Annot.Item.t? => annots::Annot.Item.t? =>
specialization::template_spec_info? =>
unit => unit =>
t; t;

@ -78,6 +78,10 @@ let get_record_name_csu decl =
let get_record_name decl = snd (get_record_name_csu decl) let get_record_name decl = snd (get_record_name_csu decl)
let get_class_template_name = function
| Clang_ast_t.ClassTemplateDecl (_, name_info, _ ) -> CAst_utils.get_qualified_name name_info
| _ -> assert false
let get_superclass_decls decl = let get_superclass_decls decl =
let open Clang_ast_t in let open Clang_ast_t in
match decl with match decl with
@ -164,6 +168,17 @@ and get_record_custom_type tenv definition_decl =
Option.map ~f:(type_ptr_to_sil_type tenv) (get_translate_as_friend_decl decl_list) Option.map ~f:(type_ptr_to_sil_type tenv) (get_translate_as_friend_decl decl_list)
| _ -> None | _ -> None
and get_template_specialization tenv = function
| Clang_ast_t.ClassTemplateSpecializationDecl (_, _, _, _, _, _, _, _, spec_info) ->
let tname = match CAst_utils.get_decl spec_info.tsi_template_decl with
| Some decl -> get_class_template_name decl
| None -> assert false in
let args_in_sil = List.map spec_info.tsi_specialization_args ~f:(function
| `Type t_ptr -> Some (type_ptr_to_sil_type tenv t_ptr)
| _ -> None) in
Typ.Template (tname, args_in_sil)
| _ -> Typ.NoTemplate
and get_record_struct_type tenv definition_decl = and get_record_struct_type tenv definition_decl =
let open Clang_ast_t in let open Clang_ast_t in
match definition_decl with match definition_decl with
@ -190,7 +205,9 @@ and get_record_struct_type tenv definition_decl =
let statics = [] in (* Note: We treat static field same as global variables *) let statics = [] in (* Note: We treat static field same as global variables *)
let methods = [] in (* C++ methods are not put into tenv (info isn't used) *) let methods = [] in (* C++ methods are not put into tenv (info isn't used) *)
let supers = get_superclass_list_cpp definition_decl in let supers = get_superclass_list_cpp definition_decl in
ignore (Tenv.mk_struct tenv ~fields ~statics ~methods ~supers ~annots sil_typename); let specialization = get_template_specialization tenv definition_decl in
Tenv.mk_struct tenv ~fields ~statics ~methods ~supers ~annots ~specialization
sil_typename |> ignore;
let sil_type = Typ.Tstruct sil_typename in let sil_type = Typ.Tstruct sil_typename in
CAst_utils.update_sil_types_map type_ptr sil_type; CAst_utils.update_sil_types_map type_ptr sil_type;
sil_type sil_type

Loading…
Cancel
Save