Commit e436d980 authored by Valentin Perrelle's avatar Valentin Perrelle

[Cil] add a field forder in fieldinfo

parent 18624738
...@@ -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,47 +5504,29 @@ and makeCompType ghost (isstruct: bool) ...@@ -5493,47 +5504,29 @@ 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 in
let rec map_but_last l = fold addFieldInfo flds nl
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
match nl with
| [] -> []
| [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 = Cil_datatype.Fieldinfo.Hashtbl.create 17 in let fld_table = Cil_datatype.Fieldinfo.Hashtbl.create 17 in
let check f = let check f =
......
...@@ -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;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment