-(* Copyright (C) 2002-2008 Yoann Padioleau
+(* Yoann Padioleau
+ *
+ * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
+ * Copyright (C) 2002, 2006 Yoann Padioleau
*
* 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
(* Tricks used to handle the ambiguity in the grammar with the typedef
* which impose a cooperation between the lexer and the parser.
- *
+ *
* An example by hughes casse: "in the symbol table, local
* definition must replace type definition in order to correctly parse
* local variable in functions body. This is the only way to correctly
* handle this kind of exception, that is,
- *
+ *
* typedef ... ID; int f(int *p) {int ID; return (ID) * *p;} If ID
* isn't overload, last expression is parsed as a type cast, if it
* isn't, this a multiplication."
- *
+ *
* Why parse_typedef_fix2 ? Cos when introduce new variable, for
* instance when declare parameters for a function such as int var_t,
* then the var_t must not be lexed as a typedef, so we must disable
(* parse_typedef_fix *)
let _handle_typedef = ref true
+let _always_look_typedef = ref false
+
(* parse_typedef_fix2 *)
let enable_typedef () = _handle_typedef := true
let disable_typedef () = _handle_typedef := false
type identkind = TypeDefI | IdentI
(* Ca marche ce code ? on peut avoir un typedef puis un ident puis
- * un typedef nested ? oui car Hashtbl (dans scoped_h_env) gere l'historique.
- *
- * oldsimple: but slow, take 2 secondes on some C files
+ * un typedef nested ? oui car Hashtbl (dans scoped_h_env) gere l'historique.
+ *
+ * oldsimple: but slow, take 2 secondes on some C files
* let (typedef: typedef list list ref) = ref [[]]
*)
-let (_typedef : (string, identkind) Common.scoped_h_env ref) =
+let (_typedef : (string, identkind) Common.scoped_h_env ref) =
ref (Common.empty_scoped_h_env ())
-
-let is_typedef s = if !_handle_typedef then
+
+let is_typedef s =
+ if !_handle_typedef || !_always_look_typedef then
(match (Common.optionise (fun () -> Common.lookup_h_env s !_typedef)) with
| Some TypeDefI -> true
| Some IdentI -> false
let add_typedef s = Common.add_in_scope_h _typedef (s, TypeDefI)
let add_ident s = Common.add_in_scope_h _typedef (s, IdentI)
-let add_typedef_root s =
+let add_typedef_root s =
if !Flag_parsing_c.add_typedef_root
- then
+ then
Hashtbl.add !_typedef.scoped_h s TypeDefI
else add_typedef s (* have far more .failed without this *)
*)
let _old_state = ref (Common.clone_scoped_h_env !_typedef)
-let save_typedef_state () =
+let save_typedef_state () =
_old_state := Common.clone_scoped_h_env !_typedef
-let restore_typedef_state () =
+let restore_typedef_state () =
_typedef := !_old_state
-
-type context =
+
+type context =
| InTopLevel
| InFunction
| InStruct
| InParameter
| InInitializer
| InEnum
+(* InExpr ? but then orthogonal to InFunction. Could assign InExpr for
+ * instance after a '=' as in 'a = (irq_t) b;'
+ *)
let is_top_or_struct = function
| InTopLevel
- | InStruct
+ | InStruct
-> true
| _ -> false
-type lexer_hint = {
+type lexer_hint = {
mutable context_stack: context Common.stack;
}
-let default_hint () = {
+let default_hint () = {
context_stack = [InTopLevel];
}
let _lexer_hint = ref (default_hint())
-let current_context () = List.hd !_lexer_hint.context_stack
-let push_context ctx =
+let current_context () = List.hd !_lexer_hint.context_stack
+let push_context ctx =
!_lexer_hint.context_stack <- ctx::!_lexer_hint.context_stack
-let pop_context () =
+let pop_context () =
!_lexer_hint.context_stack <- List.tl !_lexer_hint.context_stack
-let lexer_reset_typedef () =
+let lexer_reset_typedef saved_typedefs =
begin
- _handle_typedef := true;
- _typedef := Common.empty_scoped_h_env ();
- _lexer_hint := (default_hint ());
+ _handle_typedef := true;
+ (match saved_typedefs with
+ None -> _typedef := Common.empty_scoped_h_env ()
+ | Some t -> _typedef := t);
+ _lexer_hint := (default_hint ());
end
-