Summary: Refactor Sil.struct_typ and associated operations into a separate StructTyp module. This is possible now that Typ.Tstruct only carries a type name instead of the definition directly, and is helpful to simplify module dependencies. Reviewed By: cristianoc Differential Revision: D3919357 fbshipit-source-id: a37a656master
parent
44e2c32524
commit
ae632e281a
@ -0,0 +1,143 @@
|
||||
/*
|
||||
* vim: set ft=rust:
|
||||
* vim: set ft=reason:
|
||||
*
|
||||
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
||||
* Copyright (c) 2013 - 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.
|
||||
*/
|
||||
|
||||
open! Utils;
|
||||
|
||||
|
||||
/** The Smallfoot Intermediate Language: Struct Types */
|
||||
let module L = Logging;
|
||||
|
||||
let module F = Format;
|
||||
|
||||
type fields = list (Ident.fieldname, Typ.t, Annot.Item.t);
|
||||
|
||||
|
||||
/** Type for a structured value. */
|
||||
type t = {
|
||||
fields: fields, /** non-static fields */
|
||||
statics: fields, /** static fields */
|
||||
supers: list Typename.t, /** superclasses */
|
||||
methods: list Procname.t, /** methods defined */
|
||||
annots: Annot.Item.t /** annotations */
|
||||
};
|
||||
|
||||
type lookup = Typename.t => option t;
|
||||
|
||||
let fld_typ_ann_compare fta1 fta2 =>
|
||||
triple_compare Ident.fieldname_compare Typ.compare Annot.Item.compare fta1 fta2;
|
||||
|
||||
let pp pe pp_base name f {fields} =>
|
||||
if false {
|
||||
/* change false to true to print the details of struct */
|
||||
F.fprintf
|
||||
f
|
||||
"%a {%a} %a"
|
||||
Typename.pp
|
||||
name
|
||||
(pp_seq (fun f (fld, t, _) => F.fprintf f "%a %a" (Typ.pp_full pe) t Ident.pp_fieldname fld))
|
||||
fields
|
||||
pp_base
|
||||
()
|
||||
} else {
|
||||
F.fprintf f "%a %a" Typename.pp name pp_base ()
|
||||
};
|
||||
|
||||
let internal_mk_struct
|
||||
default::default=?
|
||||
fields::fields=?
|
||||
statics::statics=?
|
||||
methods::methods=?
|
||||
supers::supers=?
|
||||
annots::annots=?
|
||||
() => {
|
||||
let mk_struct_
|
||||
default::default={fields: [], statics: [], methods: [], supers: [], annots: Annot.Item.empty}
|
||||
fields::fields=default.fields
|
||||
statics::statics=default.statics
|
||||
methods::methods=default.methods
|
||||
supers::supers=default.supers
|
||||
annots::annots=default.annots
|
||||
() => {
|
||||
fields,
|
||||
statics,
|
||||
methods,
|
||||
supers,
|
||||
annots
|
||||
};
|
||||
mk_struct_
|
||||
default::?default
|
||||
fields::?fields
|
||||
statics::?statics
|
||||
methods::?methods
|
||||
supers::?supers
|
||||
annots::?annots
|
||||
()
|
||||
};
|
||||
|
||||
|
||||
/** the element typ of the final extensible array in the given typ, if any */
|
||||
let rec get_extensible_array_element_typ lookup::lookup (typ: Typ.t) =>
|
||||
switch typ {
|
||||
| Tarray typ _ => Some typ
|
||||
| Tstruct name =>
|
||||
switch (lookup name) {
|
||||
| Some {fields} =>
|
||||
switch (IList.last fields) {
|
||||
| Some (_, fld_typ, _) => get_extensible_array_element_typ lookup::lookup fld_typ
|
||||
| None => None
|
||||
}
|
||||
| None => None
|
||||
}
|
||||
| _ => None
|
||||
};
|
||||
|
||||
|
||||
/** If a struct type with field f, return the type of f. If not, return the default */
|
||||
let fld_typ lookup::lookup default::default fn (typ: Typ.t) =>
|
||||
switch typ {
|
||||
| Tstruct name =>
|
||||
switch (lookup name) {
|
||||
| Some {fields} =>
|
||||
try (snd3 (IList.find (fun (f, _, _) => Ident.fieldname_equal f fn) fields)) {
|
||||
| Not_found => default
|
||||
}
|
||||
| None => default
|
||||
}
|
||||
| _ => default
|
||||
};
|
||||
|
||||
let get_field_type_and_annotation lookup::lookup fn (typ: Typ.t) =>
|
||||
switch typ {
|
||||
| Tstruct name
|
||||
| Tptr (Tstruct name) _ =>
|
||||
switch (lookup name) {
|
||||
| Some {fields, statics} =>
|
||||
try {
|
||||
let (_, t, a) = IList.find (fun (f, _, _) => Ident.fieldname_equal f fn) (fields @ statics);
|
||||
Some (t, a)
|
||||
} {
|
||||
| Not_found => None
|
||||
}
|
||||
| None => None
|
||||
}
|
||||
| _ => None
|
||||
};
|
||||
|
||||
let objc_ref_counter_annot = [({Annot.class_name: "ref_counter", parameters: []}, false)];
|
||||
|
||||
|
||||
/** Field used for objective-c reference counting */
|
||||
let objc_ref_counter_field = (Ident.fieldname_hidden, Typ.Tint IInt, objc_ref_counter_annot);
|
||||
|
||||
let is_objc_ref_counter_field (fld, _, a) =>
|
||||
Ident.fieldname_is_hidden fld && Annot.Item.compare a objc_ref_counter_annot == 0;
|
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* vim: set ft=rust:
|
||||
* vim: set ft=reason:
|
||||
*
|
||||
* Copyright (c) 2009 - 2013 Monoidics ltd.
|
||||
* Copyright (c) 2013 - 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.
|
||||
*/
|
||||
|
||||
open! Utils;
|
||||
|
||||
|
||||
/** The Smallfoot Intermediate Language: Struct Types */
|
||||
let module F = Format;
|
||||
|
||||
type fields = list (Ident.fieldname, Typ.t, Annot.Item.t);
|
||||
|
||||
|
||||
/** Type for a structured value. */
|
||||
type t = private {
|
||||
fields: fields, /** non-static fields */
|
||||
statics: fields, /** static fields */
|
||||
supers: list Typename.t, /** supers */
|
||||
methods: list Procname.t, /** methods defined */
|
||||
annots: Annot.Item.t /** annotations */
|
||||
};
|
||||
|
||||
type lookup = Typename.t => option t;
|
||||
|
||||
|
||||
/** Comparision for fieldnames * types * item annotations. */
|
||||
let fld_typ_ann_compare:
|
||||
(Ident.fieldname, Typ.t, Annot.Item.t) => (Ident.fieldname, Typ.t, Annot.Item.t) => int;
|
||||
|
||||
|
||||
/** Pretty print a struct type. */
|
||||
let pp: printenv => (F.formatter => unit => unit) => Typename.t => F.formatter => t => unit;
|
||||
|
||||
|
||||
/** Construct a struct_typ, normalizing field types */
|
||||
let internal_mk_struct:
|
||||
default::t? =>
|
||||
fields::fields? =>
|
||||
statics::fields? =>
|
||||
methods::list Procname.t? =>
|
||||
supers::list Typename.t? =>
|
||||
annots::Annot.Item.t? =>
|
||||
unit =>
|
||||
t;
|
||||
|
||||
|
||||
/** the element typ of the final extensible array in the given typ, if any */
|
||||
let get_extensible_array_element_typ: lookup::lookup => Typ.t => option Typ.t;
|
||||
|
||||
|
||||
/** If a struct type with field f, return the type of f.
|
||||
If not, return the default type if given, otherwise raise an exception */
|
||||
let fld_typ: lookup::lookup => default::Typ.t => Ident.fieldname => Typ.t => Typ.t;
|
||||
|
||||
|
||||
/** Return the type of the field [fn] and its annotation, None if [typ] has no field named [fn] */
|
||||
let get_field_type_and_annotation:
|
||||
lookup::lookup => Ident.fieldname => Typ.t => option (Typ.t, Annot.Item.t);
|
||||
|
||||
|
||||
/** Field used for objective-c reference counting */
|
||||
let objc_ref_counter_field: (Ident.fieldname, Typ.t, Annot.Item.t);
|
||||
|
||||
let is_objc_ref_counter_field: (Ident.fieldname, Typ.t, Annot.Item.t) => bool;
|
Loading…
Reference in new issue