aboutsummaryrefslogtreecommitdiffstats
path: root/cparser/Env.ml
diff options
context:
space:
mode:
authorBernhard Schommer <bschommer@users.noreply.github.com>2016-12-27 19:50:01 +0100
committerGitHub <noreply@github.com>2016-12-27 19:50:01 +0100
commit9b022d749dc5b1fdb091ff8a74647c03fc1f84bb (patch)
tree24218347dd375ebdf36789659a5fd092cc8aa575 /cparser/Env.ml
parent647cc8dc9699277cb1e77ae3b07c007186720d59 (diff)
parent860f28734063628f5582be91c7429b14f0922917 (diff)
downloadcompcert-9b022d749dc5b1fdb091ff8a74647c03fc1f84bb.tar.gz
compcert-9b022d749dc5b1fdb091ff8a74647c03fc1f84bb.zip
Merge pull request #153 from AbsInt/anonymous_struct2
Next try for support of anonymous structs.
Diffstat (limited to 'cparser/Env.ml')
-rw-r--r--cparser/Env.ml30
1 files changed, 26 insertions, 4 deletions
diff --git a/cparser/Env.ml b/cparser/Env.ml
index b2a4e21c..5fa4571a 100644
--- a/cparser/Env.ml
+++ b/cparser/Env.ml
@@ -181,20 +181,42 @@ let find_union env id =
with Not_found ->
raise(Error(Unbound_tag(id.name, "union")))
-let find_member ci m =
- List.find (fun f -> f.fld_name = m) ci
+
+let tag_id = function
+ | TStruct (id,_)
+ | TUnion (id,_) -> id
+ | _ -> assert false (* should be checked before *)
+
+let find_member env ci m =
+ let rec member acc = function
+ | [] -> raise Not_found
+ | f::rest -> if f.fld_name = m then
+ f::acc
+ else if f.fld_anonymous then
+ try
+ tag acc f
+ with Not_found ->
+ member acc rest
+ else
+ member acc rest
+ and tag acc fld =
+ let id = tag_id fld.fld_typ in
+ let ci = IdentMap.find id env.env_tag in
+ member (fld::acc) ci.ci_members
+ in
+ member [] ci
let find_struct_member env (id, m) =
try
let ci = find_struct env id in
- find_member ci.ci_members m
+ find_member env ci.ci_members m
with Not_found ->
raise(Error(No_member(id.name, "struct", m)))
let find_union_member env (id, m) =
try
let ci = find_union env id in
- find_member ci.ci_members m
+ find_member env ci.ci_members m
with Not_found ->
raise(Error(No_member(id.name, "union", m)))