aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Bitfields.ml
diff options
context:
space:
mode:
authorXavier Leroy <xavier.leroy@inria.fr>2018-04-21 18:27:46 +0300
committerXavier Leroy <xavierleroy@users.noreply.github.com>2018-04-25 14:27:31 +0200
commit7be3e73fa8a46b6b813c1be98da54a1a471378b9 (patch)
tree5607dc89579f4104745b5d9f15527c6019a892d4 /cparser/Bitfields.ml
parentf016c51503ceff5354e12b27f22ae33172b8fb0e (diff)
downloadcompcert-7be3e73fa8a46b6b813c1be98da54a1a471378b9.tar.gz
compcert-7be3e73fa8a46b6b813c1be98da54a1a471378b9.zip
Bitfields transformation: record the fields after transformation
For each struct or union that contains bitfields, we record the list of members after transformation, where bit fields were replaced by carrier fields. Right now we do not use this information but it will come handy to fix a problem with struct initialization. Also: clear the global hash tables on entry so that multiple runs of the Bitfields transformation don't interfere with each other. There probably was no interference before because identifiers are unique enough, but this is fragile.
Diffstat (limited to 'cparser/Bitfields.ml')
-rw-r--r--cparser/Bitfields.ml24
1 files changed, 20 insertions, 4 deletions
diff --git a/cparser/Bitfields.ml b/cparser/Bitfields.ml
index 9ac9b61f..71226ec6 100644
--- a/cparser/Bitfields.ml
+++ b/cparser/Bitfields.ml
@@ -44,7 +44,7 @@ let carrier_field bf =
{ fld_name = bf.bf_carrier; fld_typ = bf.bf_carrier_typ;
fld_bitfield = None; fld_anonymous = false }
-(* Mapping (struct identifier, bitfield name) -> bitfield info *)
+(* Mapping (struct/union identifier, bitfield name) -> bitfield info *)
let bitfield_table =
(Hashtbl.create 57: (ident * string, bitfield_info) Hashtbl.t)
@@ -53,6 +53,13 @@ let is_bitfield structid fieldname =
try Some (Hashtbl.find bitfield_table (structid, fieldname))
with Not_found -> None
+(* Mapping struct/union identifier -> list of members after transformation,
+ including the carrier fields, but without the bit fields.
+ structs and unions containing no bit fields are not put in this table. *)
+
+let composite_transformed_members =
+ (Hashtbl.create 57: (ident, C.field list) Hashtbl.t)
+
(* Signedness issues *)
let unsigned_ikind_for_carrier nbits =
@@ -183,9 +190,16 @@ let rec transf_union_members env id count = function
:: transf_union_members env id (count + 1) ms)
let transf_composite env su id attr ml =
- match su with
- | Struct -> (attr, transf_struct_members env id 1 ml)
- | Union -> (attr, transf_union_members env id 1 ml)
+ if List.for_all (fun f -> f.fld_bitfield = None) ml then
+ (attr, ml)
+ else begin
+ let ml' =
+ match su with
+ | Struct -> transf_struct_members env id 1 ml
+ | Union -> transf_union_members env id 1 ml in
+ Hashtbl.add composite_transformed_members id ml';
+ (attr, ml')
+ end
(* Bitfield manipulation expressions *)
@@ -537,6 +551,8 @@ let transf_fundef env f =
(* Programs *)
let program p =
+ Hashtbl.clear bitfield_table;
+ Hashtbl.clear composite_transformed_members;
Transform.program
~composite:transf_composite
~decl: transf_decl