(* Yoann Padioleau
- *
+ *
+ * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
* Copyright (C) 2006, 2007, 2008 Ecole des Mines de Nantes
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
* version 2 as published by the Free Software Foundation.
- *
+ *
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
(*****************************************************************************)
(* Wrappers *)
(*****************************************************************************)
-let pr2_err, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_parsing
+let pr2_err, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_parsing
(*****************************************************************************)
(* Consistency checking *)
(* todo:
* could check that an ident has always the same class, be it a typedef
- * (but sometimes do 'acpi_val acpi_val;'), an ident, a TMacroStatement,
+ * (but sometimes do 'acpi_val acpi_val;'), an ident, a TMacroStatement,
* etc.
*)
-type class_ident =
+type class_ident =
| CIdent (* can be var, func, field, tag, enum constant *)
| CTypedef
(* but take care that must still be able to use '=' *)
type context = InFunction | InEnum | InStruct | InInitializer | InParams
-type class_token =
+type class_token =
| CIdent of class_ident
- | CComment
+ | CComment
| CSpace
| CCommentCpp of cppkind
| CCommentMisc
let ident_to_typename ident : Ast_c.fullType =
Ast_c.mk_ty (Ast_c.TypeName (ident, Ast_c.noTypedefDef())) Ast_c.noii
-
+
(* parse_typedef_fix4 *)
-let consistency_checking2 xs =
+let consistency_checking2 xs =
(* first phase, gather data *)
- let stat = Hashtbl.create 101 in
+ let stat = Hashtbl.create 101 in
(* default value for hash *)
let v1 () = Hashtbl.create 101 in
let bigf = { Visitor_c.default_visitor_c with
- Visitor_c.kexpr = (fun (k,bigf) x ->
+ Visitor_c.kexpr = (fun (k,bigf) x ->
match Ast_c.unwrap_expr x with
- | Ast_c.Ident (id) ->
+ | Ast_c.Ident (id) ->
let s = Ast_c.str_of_name id in
- stat +>
- Common.hfind_default s v1 +> Common.hfind_default CIdent v2 +>
+ stat +>
+ Common.hfind_default s v1 +> Common.hfind_default CIdent v2 +>
(fun aref -> incr aref)
| _ -> k x
);
- Visitor_c.ktype = (fun (k,bigf) t ->
+ Visitor_c.ktype = (fun (k,bigf) t ->
match Ast_c.unwrap_typeC t with
- | Ast_c.TypeName (name,_typ) ->
+ | Ast_c.TypeName (name,_typ) ->
let s = Ast_c.str_of_name name in
- stat +>
- Common.hfind_default s v1 +> Common.hfind_default CTypedef v2 +>
+ stat +>
+ Common.hfind_default s v1 +> Common.hfind_default CTypedef v2 +>
(fun aref -> incr aref)
| _ -> k t
);
- }
+ }
in
xs +> List.iter (fun (p) -> Visitor_c.vk_toplevel bigf p);
let ident_to_type = ref [] in
-
+
(* second phase, analyze data *)
- stat +> Hashtbl.iter (fun k v ->
+ stat +> Hashtbl.iter (fun k v ->
let xs = Common.hash_to_list v in
if List.length xs >= 2
then begin
pr2_err ("TYPEDEF CONFLICT:" ^ k);
- let sorted = xs +> List.sort (fun (ka,va) (kb,vb) ->
+ let sorted = xs +> List.sort (fun (ka,va) (kb,vb) ->
if !va =|= !vb then
(match ka, kb with
| CTypedef, _ -> 1 (* first is smaller *)
) in
let sorted = List.rev sorted in
match sorted with
- | [CTypedef, i1;CIdent, i2] ->
+ | [CTypedef, i1;CIdent, i2] ->
pr2_err ("transforming some ident in typedef");
push2 k ident_to_type;
| [CIdent, i1;CTypedef, i2] ->
pr2_err ("TODO:typedef now used as an identifier");
- | _ ->
+ | _ ->
pr2_err ("TODO:other transforming?");
-
+
end
);
- (* third phase, update ast.
+ (* third phase, update ast.
* todo? but normally should try to handle correctly scope ? maybe sometime
- * sizeof(id) and even if id was for a long time an identifier, maybe
+ * sizeof(id) and even if id was for a long time an identifier, maybe
* a few time, because of the scope it's actually really a type.
*)
if (null !ident_to_type)
- then xs
- else
+ then xs
+ else
let bigf = { Visitor_c.default_visitor_c_s with
- Visitor_c.kdefineval_s = (fun (k,bigf) x ->
+ Visitor_c.kdefineval_s = (fun (k,bigf) x ->
match x with
- | Ast_c.DefineExpr e ->
+ | Ast_c.DefineExpr e ->
(match Ast_c.unwrap_expr e with
- | Ast_c.Ident (ident) ->
- let s = Ast_c.str_of_name ident in
+ | Ast_c.Ident (ident) ->
+ let s = Ast_c.str_of_name ident in
if List.mem s !ident_to_type
then
let t = ident_to_typename ident in
)
| _ -> k x
);
- Visitor_c.kexpr_s = (fun (k, bigf) x ->
+ Visitor_c.kexpr_s = (fun (k, bigf) x ->
match Ast_c.get_e_and_ii x with
- | (Ast_c.SizeOfExpr e, tref), isizeof ->
+ | (Ast_c.SizeOfExpr e, tref), isizeof ->
let i1 = tuple_of_list1 isizeof in
(match Ast_c.get_e_and_ii e with
- | (Ast_c.ParenExpr e, _), iiparen ->
+ | (Ast_c.ParenExpr e, _), iiparen ->
let (i2, i3) = tuple_of_list2 iiparen in
(match Ast_c.get_e_and_ii e with
- | (Ast_c.Ident (ident), _), _ii ->
+ | (Ast_c.Ident (ident), _), _ii ->
- let s = Ast_c.str_of_name ident in
+ let s = Ast_c.str_of_name ident in
if List.mem s !ident_to_type
then
let t = ident_to_typename ident in
| _ -> k x
);
} in
- xs +> List.map (fun (p) ->
+ xs +> List.map (fun (p) ->
Visitor_c.vk_toplevel_s bigf p
)
-let consistency_checking a =
+let consistency_checking a =
Common.profile_code "C consistencycheck" (fun () -> consistency_checking2 a)