diff options
Diffstat (limited to 'cparser/Cutil.ml')
-rw-r--r-- | cparser/Cutil.ml | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/cparser/Cutil.ml b/cparser/Cutil.ml index a3c05c34..0def347f 100644 --- a/cparser/Cutil.ml +++ b/cparser/Cutil.ml @@ -273,6 +273,42 @@ let combine_types mode env t1 t2 = in try Some(comp mode t1 t2) with Incompat -> None +let rec equal_types env t1 t2 = + match t1, t2 with + | TVoid a1, TVoid a2 -> + a1=a2 + | TInt(ik1, a1), TInt(ik2, a2) -> + ik1 = ik2 && a1 = a2 + | TFloat(fk1, a1), TFloat(fk2, a2) -> + fk1 = fk2 && a1 = a2 + | TPtr(ty1, a1), TPtr(ty2, a2) -> + a1 = a2 && equal_types env ty1 ty2 + | TArray(ty1, sz1, a1), TArray(ty2, sz2, a2) -> + let size = begin match sz1,sz2 with + | None, None -> true + | Some s1, Some s2 -> s1 = s2 + | _ -> false end in + size && a1 = a2 && equal_types env t1 t2 + | TFun(ty1, params1, vararg1, a1), TFun(ty2, params2, vararg2, a2) -> + let params = + match params1, params2 with + | None, None -> true + | None, Some _ + | Some _, None -> false + | Some l1, Some l2 -> + try + List.for_all2 (fun (_,t1) (_,t2) -> equal_types env t1 t2) l1 l2 + with _ -> false + in params && a1 = a2 && vararg1 = vararg2 && equal_types env ty1 ty2 + | TNamed _, _ -> equal_types env (unroll env t1) t2 + | _, TNamed _ -> equal_types env t1 (unroll env t2) + | TStruct(s1, a1), TStruct(s2, a2) + | TUnion(s1, a1), TUnion(s2, a2) + | TEnum(s1, a1), TEnum(s2, a2) -> + s1 = s2 && a1 = a2 + | _, _ -> + false + (** Check whether two types are compatible. *) let compatible_types mode env t1 t2 = @@ -427,7 +463,6 @@ let sizeof_union env members = We lay out fields consecutively, inserting padding to preserve their alignment. Not done here but in composite_info_decl: rounding size to alignment. *) - let sizeof_struct env members = let rec sizeof_rec ofs = function | [] -> @@ -449,6 +484,26 @@ let sizeof_struct env members = end in sizeof_rec 0 members +(* Simplified version to compute offsets on structs without bitfields *) +let struct_layout env members = + let rec struct_layout_rec mem ofs = function + | [] -> + mem + | [ { fld_typ = TArray(_, None, _) } as m ] -> + (* C99: ty[] allowed as last field *) + begin match alignof env m.fld_typ with + | Some a -> ( m.fld_name,align ofs a)::mem + | None -> [] + end + | m :: rem -> + match alignof env m.fld_typ, sizeof env m.fld_typ with + | Some a, Some s -> + let offset = align ofs a in + struct_layout_rec ((m.fld_name,offset)::mem) (offset + s) rem + | _, _ -> [] + in struct_layout_rec [] 0 members + + (* Determine whether a type is incomplete *) let incomplete_type env t = |