Commit 460e1534 authored by Virgile Prevosto's avatar Virgile Prevosto

Merge branch 'feature/cil/field-order' into 'master'

[Cil] add a field forder in fieldinfo

See merge request frama-c/frama-c!2923
parents cd9f960d 56a347e3
...@@ -5385,8 +5385,14 @@ and makeCompType ghost (isstruct: bool) ...@@ -5385,8 +5385,14 @@ and makeCompType ghost (isstruct: bool)
(* Create the self cell for use in fields and forward references. Or maybe (* Create the self cell for use in fields and forward references. Or maybe
* one exists already from a forward reference *) * one exists already from a forward reference *)
let comp, _ = createCompInfo isstruct n' norig in let comp, _ = createCompInfo isstruct n' norig in
let doFieldGroup ~is_first_group ~is_last_group ((s: A.spec_elem list), let rec fold f acc = function
(nl: (A.name * A.expression option) list)) = | [] -> acc
| [x] -> f ~last:true acc x
| x :: l -> fold f (f ~last:false acc x) l
in
let addFieldGroup ~last:last_group (flds : fieldinfo list)
((s: A.spec_elem list), (nl: (A.name * A.expression option) list)) =
(* Do the specifiers exactly once *) (* Do the specifiers exactly once *)
let sugg = match nl with let sugg = match nl with
| [] -> "" | [] -> ""
...@@ -5394,13 +5400,13 @@ and makeCompType ghost (isstruct: bool) ...@@ -5394,13 +5400,13 @@ and makeCompType ghost (isstruct: bool)
in in
let bt, sto, inl, attrs = doSpecList ghost sugg s in let bt, sto, inl, attrs = doSpecList ghost sugg s in
(* Do the fields *) (* Do the fields *)
let makeFieldInfo ~is_first_field ~is_last_field let addFieldInfo ~last:last_field (flds : fieldinfo list)
(((n,ndt,a,cloc) : A.name), (widtho : A.expression option)) (((n,ndt,a,cloc) : A.name), (widtho : A.expression option))
: fieldinfo = : fieldinfo list =
if sto <> NoStorage || inl then if sto <> NoStorage || inl then
Kernel.error ~once:true ~current:true "Storage or inline not allowed for fields"; Kernel.error ~once:true ~current:true "Storage or inline not allowed for fields";
let allowZeroSizeArrays = true in let allowZeroSizeArrays = true in
let ftype, nattr = let ftype, fattr =
doType doType
~allowZeroSizeArrays ghost false (AttrName false) bt ~allowZeroSizeArrays ghost false (AttrName false) bt
(A.PARENTYPE(attrs, ndt, a)) (A.PARENTYPE(attrs, ndt, a))
...@@ -5420,11 +5426,11 @@ and makeCompType ghost (isstruct: bool) ...@@ -5420,11 +5426,11 @@ and makeCompType ghost (isstruct: bool)
else if not (Cil.isCompleteType ~allowZeroSizeArrays ftype) else if not (Cil.isCompleteType ~allowZeroSizeArrays ftype)
then begin then begin
match Cil.unrollType ftype with match Cil.unrollType ftype with
| TArray(_,None,_,_) when is_last_field -> | TArray(_,None,_,_) when last_group && last_field ->
begin begin
(* possible flexible array member; check if struct contains at least (* possible flexible array member; check if struct contains at least
one other field *) one other field *)
if is_first_field then (* struct is empty *) if flds = [] then (* struct is empty *)
Kernel.error ~current:true Kernel.error ~current:true
"flexible array member '%s' (type %a) \ "flexible array member '%s' (type %a) \
not allowed in otherwise empty struct" not allowed in otherwise empty struct"
...@@ -5436,7 +5442,7 @@ and makeCompType ghost (isstruct: bool) ...@@ -5436,7 +5442,7 @@ and makeCompType ghost (isstruct: bool)
"field `%s' is declared with incomplete type %a" "field `%s' is declared with incomplete type %a"
n Cil_printer.pp_typ ftype n Cil_printer.pp_typ ftype
end; end;
let width, ftype = let fbitfield, ftype =
match widtho with match widtho with
| None -> None, ftype | None -> None, ftype
| Some w -> begin | Some w -> begin
...@@ -5459,9 +5465,14 @@ and makeCompType ghost (isstruct: bool) ...@@ -5459,9 +5465,14 @@ and makeCompType ghost (isstruct: bool)
w, ftype w, ftype
end end
in in
(* Compute the order of the field in the structure *)
let forder = match flds with
| [] -> 0
| { forder=previous_order } :: _ -> previous_order + 1
in
(* If the field is unnamed and its type is a structure of union type (* If the field is unnamed and its type is a structure of union type
* then give it a distinguished name *) * then give it a distinguished name *)
let n' = let fname =
if n = missingFieldName then begin if n = missingFieldName then begin
match unrollType ftype with match unrollType ftype with
| TComp _ -> begin | TComp _ -> begin
...@@ -5493,52 +5504,34 @@ and makeCompType ghost (isstruct: bool) ...@@ -5493,52 +5504,34 @@ and makeCompType ghost (isstruct: bool)
| _ -> () | _ -> ()
in in
is_circular ftype; is_circular ftype;
{ fcomp = comp; { fcomp = comp;
forder;
forig_name = n; forig_name = n;
fname = n'; fname;
ftype = ftype; ftype;
fbitfield = width; fbitfield;
fattr = nattr; fattr;
floc = convLoc cloc; floc = convLoc cloc;
faddrof = false; faddrof = false;
fsize_in_bits = None; fsize_in_bits = None;
foffset_in_bits = None; foffset_in_bits = None;
fpadding_in_bits = None; fpadding_in_bits = None;
} } :: flds
in
let rec map_but_last l =
match l with
| [] -> []
| [f] ->
[makeFieldInfo ~is_first_field:false ~is_last_field:is_last_group f]
| f::l ->
let fi = makeFieldInfo ~is_first_field:false ~is_last_field:false f in
[fi] @ map_but_last l
in in
match nl with fold addFieldInfo flds nl
| [] -> []
| [f] ->
[makeFieldInfo ~is_first_field:is_first_group ~is_last_field:is_last_group f]
| f::l ->
let fi =
makeFieldInfo ~is_first_field:is_first_group ~is_last_field:false f
in
[fi] @ map_but_last l
in in
(* Do regular fields first. *) (* Do regular fields first. *)
let flds = let to_field = function
List.filter (function FIELD _ -> true | TYPE_ANNOT _ -> false) nglist in | TYPE_ANNOT _ -> None
let flds = | FIELD (f,g) -> Some (f,g) in
List.map (function FIELD (f,g) -> (f,g) | _ -> assert false) flds in let flds = Extlib.filter_map_opt to_field nglist in
let last = List.length flds - 1 in let flds = List.rev (fold addFieldGroup [] flds) in
let doField i = doFieldGroup ~is_first_group:(i=0) ~is_last_group:(i=last) in
let flds = List.concat (List.mapi doField flds) in let fld_table = Hashtbl.create 17 in
let fld_table = Cil_datatype.Fieldinfo.Hashtbl.create 17 in
let check f = let check f =
try try
let oldf = Cil_datatype.Fieldinfo.Hashtbl.find fld_table f in let oldf = Hashtbl.find fld_table f.fname in
let source = fst f.floc in let source = fst f.floc in
Kernel.error ~source Kernel.error ~source
"field %s occurs multiple times in aggregate %a. \ "field %s occurs multiple times in aggregate %a. \
...@@ -5547,7 +5540,7 @@ and makeCompType ghost (isstruct: bool) ...@@ -5547,7 +5540,7 @@ and makeCompType ghost (isstruct: bool)
(fst oldf.floc).Filepath.pos_lnum (fst oldf.floc).Filepath.pos_lnum
with Not_found -> with Not_found ->
(* Do not add unnamed bitfields: they can share the empty name. *) (* Do not add unnamed bitfields: they can share the empty name. *)
if f.fname <> "" then Cil_datatype.Fieldinfo.Hashtbl.add fld_table f f if f.fname <> "" then Hashtbl.add fld_table f.fname f
in in
List.iter check flds; List.iter check flds;
if comp.cfields <> [] then begin if comp.cfields <> [] then begin
......
...@@ -400,6 +400,9 @@ and fieldinfo = { ...@@ -400,6 +400,9 @@ and fieldinfo = {
(** The host structure that contains this field. There can be only one (** The host structure that contains this field. There can be only one
[compinfo] that contains the field. *) [compinfo] that contains the field. *)
mutable forder: int;
(** The position in the host structure. *)
forig_name: string; forig_name: string;
(** original name as found in C file. *) (** original name as found in C file. *)
......
...@@ -117,8 +117,9 @@ let mkCompInfo ...@@ -117,8 +117,9 @@ let mkCompInfo
cdefined = false; } cdefined = false; }
in in
let flds = let flds =
List.map (fun (fn, ft, fb, fa, fl) -> List.mapi (fun forder (fn, ft, fb, fa, fl) ->
{ fcomp = comp; { fcomp = comp;
forder;
ftype = ft; ftype = ft;
forig_name = fn; forig_name = fn;
fname = fn; fname = fn;
......
...@@ -804,6 +804,7 @@ module Fieldinfo = struct ...@@ -804,6 +804,7 @@ module Fieldinfo = struct
List.fold_left List.fold_left
(fun acc loc -> (fun acc loc ->
{ fcomp = ci; { fcomp = ci;
forder = 0;
forig_name = ""; forig_name = "";
fname = ""; fname = "";
ftype = typ; ftype = typ;
...@@ -821,7 +822,7 @@ module Fieldinfo = struct ...@@ -821,7 +822,7 @@ module Fieldinfo = struct
Typ.reprs) Typ.reprs)
[] []
Compinfo.reprs Compinfo.reprs
let fid fi = fi.fcomp.ckey, fi.fname let fid fi = fi.fcomp.ckey, fi.forder
let compare f1 f2 = Extlib.compare_basic (fid f1) (fid f2) let compare f1 f2 = Extlib.compare_basic (fid f1) (fid f2)
let hash f1 = Hashtbl.hash (fid f1) let hash f1 = Hashtbl.hash (fid f1)
let equal f1 f2 = (fid f1) = (fid f2) let equal f1 f2 = (fid f1) = (fid f2)
......
...@@ -516,8 +516,8 @@ ...@@ -516,8 +516,8 @@
"startLine": 168, "startLine": 168,
"startColumn": 4, "startColumn": 4,
"endLine": 170, "endLine": 170,
"endColumn": 82, "endColumn": 75,
"byteLength": 146 "byteLength": 132
} }
} }
} }
...@@ -587,8 +587,8 @@ ...@@ -587,8 +587,8 @@
"startLine": 240, "startLine": 240,
"startColumn": 4, "startColumn": 4,
"endLine": 244, "endLine": 244,
"endColumn": 70, "endColumn": 63,
"byteLength": 180 "byteLength": 173
} }
} }
} }
...@@ -1151,7 +1151,7 @@ ...@@ -1151,7 +1151,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 121, "endLine": 121,
"endColumn": 77, "endColumn": 77,
"byteLength": 155 "byteLength": 148
} }
} }
} }
...@@ -1266,7 +1266,7 @@ ...@@ -1266,7 +1266,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 125, "endLine": 125,
"endColumn": 77, "endColumn": 77,
"byteLength": 156 "byteLength": 149
} }
} }
} }
...@@ -1455,7 +1455,7 @@ ...@@ -1455,7 +1455,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 109, "endLine": 109,
"endColumn": 59, "endColumn": 59,
"byteLength": 125 "byteLength": 118
} }
} }
} }
...@@ -1992,8 +1992,8 @@ ...@@ -1992,8 +1992,8 @@
"startLine": 89, "startLine": 89,
"startColumn": 4, "startColumn": 4,
"endLine": 90, "endLine": 90,
"endColumn": 79, "endColumn": 72,
"byteLength": 108 "byteLength": 101
} }
} }
} }
...@@ -2202,8 +2202,8 @@ ...@@ -2202,8 +2202,8 @@
"startLine": 143, "startLine": 143,
"startColumn": 4, "startColumn": 4,
"endLine": 147, "endLine": 147,
"endColumn": 70, "endColumn": 63,
"byteLength": 177 "byteLength": 170
} }
} }
} }
...@@ -2439,7 +2439,7 @@ ...@@ -2439,7 +2439,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 59, "endLine": 59,
"endColumn": 62, "endColumn": 62,
"byteLength": 148 "byteLength": 134
} }
} }
} }
...@@ -2788,7 +2788,7 @@ ...@@ -2788,7 +2788,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 185, "endLine": 185,
"endColumn": 63, "endColumn": 63,
"byteLength": 150 "byteLength": 143
} }
} }
} }
...@@ -3563,7 +3563,7 @@ ...@@ -3563,7 +3563,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 202, "endLine": 202,
"endColumn": 22, "endColumn": 22,
"byteLength": 120 "byteLength": 113
} }
} }
} }
...@@ -3655,7 +3655,7 @@ ...@@ -3655,7 +3655,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 269, "endLine": 269,
"endColumn": 29, "endColumn": 29,
"byteLength": 167 "byteLength": 153
} }
} }
} }
...@@ -3958,7 +3958,7 @@ ...@@ -3958,7 +3958,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 97, "endLine": 97,
"endColumn": 58, "endColumn": 58,
"byteLength": 127 "byteLength": 120
} }
} }
} }
...@@ -4431,7 +4431,7 @@ ...@@ -4431,7 +4431,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 59, "endLine": 59,
"endColumn": 62, "endColumn": 62,
"byteLength": 148 "byteLength": 134
} }
} }
} }
...@@ -4826,7 +4826,7 @@ ...@@ -4826,7 +4826,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 105, "endLine": 105,
"endColumn": 51, "endColumn": 51,
"byteLength": 115 "byteLength": 108
} }
} }
} }
...@@ -4849,7 +4849,7 @@ ...@@ -4849,7 +4849,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 135, "endLine": 135,
"endColumn": 38, "endColumn": 38,
"byteLength": 192 "byteLength": 185
} }
} }
} }
...@@ -5078,8 +5078,8 @@ ...@@ -5078,8 +5078,8 @@
"startLine": 68, "startLine": 68,
"startColumn": 4, "startColumn": 4,
"endLine": 70, "endLine": 70,
"endColumn": 70, "endColumn": 63,
"byteLength": 156 "byteLength": 135
} }
} }
} }
...@@ -5269,8 +5269,8 @@ ...@@ -5269,8 +5269,8 @@
"startLine": 252, "startLine": 252,
"startColumn": 4, "startColumn": 4,
"endLine": 256, "endLine": 256,
"endColumn": 60, "endColumn": 53,
"byteLength": 208 "byteLength": 194
} }
} }
} }
...@@ -5364,7 +5364,7 @@ ...@@ -5364,7 +5364,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 269, "endLine": 269,
"endColumn": 29, "endColumn": 29,
"byteLength": 167 "byteLength": 153
} }
} }
} }
...@@ -5573,7 +5573,7 @@ ...@@ -5573,7 +5573,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 101, "endLine": 101,
"endColumn": 59, "endColumn": 59,
"byteLength": 124 "byteLength": 117
} }
} }
} }
...@@ -5739,7 +5739,7 @@ ...@@ -5739,7 +5739,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 113, "endLine": 113,
"endColumn": 51, "endColumn": 51,
"byteLength": 118 "byteLength": 111
} }
} }
} }
...@@ -5948,7 +5948,7 @@ ...@@ -5948,7 +5948,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 117, "endLine": 117,
"endColumn": 62, "endColumn": 62,
"byteLength": 157 "byteLength": 143
} }
} }
} }
...@@ -6636,7 +6636,7 @@ ...@@ -6636,7 +6636,7 @@
"startColumn": 4, "startColumn": 4,
"endLine": 130, "endLine": 130,
"endColumn": 38, "endColumn": 38,
"byteLength": 191 "byteLength": 184
} }
} }
} }
...@@ -6731,8 +6731,8 @@ ...@@ -6731,8 +6731,8 @@
"startLine": 39, "startLine": 39,
"startColumn": 4, "startColumn": 4,
"endLine": 42, "endLine": 42,
"endColumn": 77, "endColumn": 70,
"byteLength": 184 "byteLength": 170
} }
} }
} }
...@@ -6800,8 +6800,8 @@ ...@@ -6800,8 +6800,8 @@
"startLine": 155, "startLine": 155,
"startColumn": 4, "startColumn": 4,
"endLine": 159, "endLine": 159,
"endColumn": 60, "endColumn": 53,
"byteLength": 205 "byteLength": 191
} }
} }
} }
...@@ -7177,8 +7177,8 @@ ...@@ -7177,8 +7177,8 @@
"startLine": 143, "startLine": 143,
"startColumn": 4, "startColumn": 4,
"endLine": 147, "endLine": 147,
"endColumn": 70, "endColumn": 63,
"byteLength": 177 "byteLength": 170
} }
} }
} }
...@@ -7246,8 +7246,8 @@ ...@@ -7246,8 +7246,8 @@
"startLine": 240, "startLine": 240,
"startColumn": 4, "startColumn": 4,
"endLine": 244, "endLine": 244,
"endColumn": 70, "endColumn": 63,
"byteLength": 180 "byteLength": 173
} }