3 * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
4 * Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License (GPL)
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * file license.txt for more details.
19 (*****************************************************************************)
21 (*****************************************************************************)
22 let pr2_err, pr2_once
= Common.mk_pr2_wrappers
Flag_parsing_c.verbose_parsing
24 (*****************************************************************************)
25 (* Consistency checking *)
26 (*****************************************************************************)
29 * could check that an ident has always the same class, be it a typedef
30 * (but sometimes do 'acpi_val acpi_val;'), an ident, a TMacroStatement,
35 | CIdent
(* can be var, func, field, tag, enum constant *)
38 let str_of_class_ident = function
40 | CTypedef
-> "Typedef"
50 (* but take care that must still be able to use '=' *)
51 type context
= InFunction
| InEnum
| InStruct
| InInitializer
| InParams
53 | CIdent
of class_ident
57 | CCommentCpp
of cppkind
67 | CReservedKwd
(type | decl
| qualif
| flow
| misc
| attr
)
70 let ident_to_typename ident
: Ast_c.fullType
=
71 Ast_c.mk_ty
(Ast_c.TypeName
(ident
, Ast_c.noTypedefDef
())) Ast_c.noii
74 (* parse_typedef_fix4 *)
75 let consistency_checking2 xs
=
77 (* first phase, gather data *)
78 let stat = Hashtbl.create
101 in
80 (* default value for hash *)
81 let v1 () = Hashtbl.create
101 in
84 let bigf = { Visitor_c.default_visitor_c
with
86 Visitor_c.kexpr
= (fun (k
,bigf) x
->
87 match Ast_c.unwrap_expr x
with
89 let s = Ast_c.str_of_name id
in
91 Common.hfind_default
s v1 +> Common.hfind_default CIdent
v2 +>
92 (fun aref
-> incr aref
)
96 Visitor_c.ktype
= (fun (k
,bigf) t
->
97 match Ast_c.unwrap_typeC t
with
98 | Ast_c.TypeName
(name
,_typ
) ->
99 let s = Ast_c.str_of_name name
in
101 Common.hfind_default
s v1 +> Common.hfind_default CTypedef
v2 +>
102 (fun aref
-> incr aref
)
108 xs
+> List.iter
(fun (p
) -> Visitor_c.vk_toplevel
bigf p
);
111 let ident_to_type = ref [] in
114 (* second phase, analyze data *)
115 stat +> Hashtbl.iter
(fun k v
->
116 let xs = Common.hash_to_list v
in
117 if List.length
xs >= 2
119 pr2_err ("TYPEDEF CONFLICT:" ^ k
);
120 let sorted = xs +> List.sort
(fun (ka
,va
) (kb
,vb
) ->
123 | CTypedef
, _
-> 1 (* first is smaller *)
129 let sorted = List.rev
sorted in
131 | [CTypedef
, i1
;CIdent
, i2
] ->
132 pr2_err ("transforming some ident in typedef");
133 push2 k
ident_to_type;
134 | [CIdent
, i1
;CTypedef
, i2
] ->
135 pr2_err ("TODO:typedef now used as an identifier");
137 pr2_err ("TODO:other transforming?");
142 (* third phase, update ast.
143 * todo? but normally should try to handle correctly scope ? maybe sometime
144 * sizeof(id) and even if id was for a long time an identifier, maybe
145 * a few time, because of the scope it's actually really a type.
147 if (null
!ident_to_type)
150 let bigf = { Visitor_c.default_visitor_c_s
with
151 Visitor_c.kdefineval_s
= (fun (k
,bigf) x
->
153 | Ast_c.DefineExpr e
->
154 (match Ast_c.unwrap_expr e
with
155 | Ast_c.Ident
(ident
) ->
156 let s = Ast_c.str_of_name ident
in
157 if List.mem
s !ident_to_type
159 let t = ident_to_typename ident
in
166 Visitor_c.kexpr_s
= (fun (k
, bigf) x
->
167 match Ast_c.get_e_and_ii x
with
168 | (Ast_c.SizeOfExpr e
, tref
), isizeof
->
169 let i1 = tuple_of_list1 isizeof
in
170 (match Ast_c.get_e_and_ii e
with
171 | (Ast_c.ParenExpr e
, _
), iiparen
->
172 let (i2
, i3
) = tuple_of_list2 iiparen
in
173 (match Ast_c.get_e_and_ii e
with
174 | (Ast_c.Ident
(ident
), _
), _ii
->
176 let s = Ast_c.str_of_name ident
in
177 if List.mem
s !ident_to_type
179 let t = ident_to_typename ident
in
180 (Ast_c.SizeOfType
t, tref
),[i1;i2
;i3
]
189 xs +> List.map
(fun (p
) ->
190 Visitor_c.vk_toplevel_s
bigf p
194 let consistency_checking a
=
195 Common.profile_code
"C consistencycheck" (fun () -> consistency_checking2 a
)