You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

143 lines
3.6 KiB

/*
* 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 compare_fld_typ_ann = [%compare : (Ident.fieldname, Typ.t, Annot.Item.t)];
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.equal_fieldname 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.equal_fieldname 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;