permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_c / parsing_hacks.ml
index c2ba571..0e96e67 100644 (file)
@@ -45,7 +45,6 @@ let msg_gen cond is_known printer s =
       if not (is_known s)
       then printer s
 
-
 (* In the following, there are some harcoded names of types or macros
  * but they are not used by our heuristics! They are just here to
  * enable to detect false positive by printing only the typedef/macros
@@ -62,7 +61,7 @@ let is_known_typdef =
       | "u8" | "u16" | "u32" | "u64"
       | "s8"  | "s16" | "s32" | "s64"
       | "__u8" | "__u16" | "__u32"  | "__u64"
-          -> true
+        -> true
 
       | "acpi_handle"
       | "acpi_status"
@@ -81,12 +80,16 @@ let is_known_typdef =
  * because it would compute msg_typedef at compile time when
  * the flag debug_typedef is always false
  *)
-let msg_typedef s =
+let msg_typedef s ii n =
   incr Stat.nTypedefInfer;
   msg_gen (!Flag_parsing_c.debug_typedef)
     is_known_typdef
     (fun s ->
-      pr2_cpp ("TYPEDEF: promoting: " ^ s)
+      pr2_cpp
+       (Printf.sprintf "TYPEDEF: promoting:(%d) %s on line %d" n s
+          (Ast_c.line_of_info ii))
+       (*(Printf.sprintf "TYPEDEF: promoting: %s on line %d" s
+          (Ast_c.line_of_info ii))*)
     )
     s
 
@@ -178,7 +181,7 @@ let msg_stringification s =
       | "UTS_RELEASE"
       | "SIZE_STR"
       | "DMA_STR"
-          -> true
+        -> true
       (* s when s =~ ".*STR.*" -> true  *)
       | _ -> false
       )
@@ -235,15 +238,15 @@ let msg_attribute s =
 
 (* opti: better to built then once and for all, especially regexp_foreach *)
 
-let regexp_macro =  Str.regexp
+let regexp_macro = Str.regexp
   "^[A-Z_][A-Z_0-9]*$"
 
 (* linuxext: *)
-let regexp_annot =  Str.regexp
+let regexp_annot = Str.regexp
   "^__.*$"
 
 (* linuxext: *)
-let regexp_declare =  Str.regexp
+let regexp_declare = Str.regexp
   ".*DECLARE.*"
 
 (* linuxext: *)
@@ -262,6 +265,10 @@ let ok_typedef s = not (List.mem s false_typedef)
 
 let not_annot s =
   not (s ==~ regexp_annot)
+let is_macro s =
+  s ==~ regexp_macro
+let not_macro s =
+  not (is_macro s)
 
 
 
@@ -309,7 +316,7 @@ let rec is_really_foreach xs =
         single statement in the body of the loop.  undoubtedly more
         cases are needed.
          todo: premier(statement) - suivant(funcall)
-      *)
+       *)
     | TCPar _::TIdent _::xs -> true, xs
     | TCPar _::Tif _::xs -> true, xs
     | TCPar _::Twhile _::xs -> true, xs
@@ -337,11 +344,10 @@ let set_ifdef_token_parenthize_info cnt x =
 
     | TIfdefBool (_, tag, _)
     | TIfdefMisc (_, tag, _)
-    | TIfdefVersion (_, tag, _)
-        ->
-        tag := Some cnt;
+    | TIfdefVersion (_, tag, _) ->
+       tag := Some cnt;
 
-    | _ -> raise Impossible
+    | _ -> raise (Impossible 89)
 
 
 
@@ -406,6 +412,7 @@ let mark_end_define ii =
         Common.charpos = Ast_c.pos_of_info ii + 1
       };
       cocci_tag = ref Ast_c.emptyAnnot;
+      annots_tag = Token_annot.empty;
       comments_tag = ref Ast_c.emptyComments;
     }
   in
@@ -418,7 +425,11 @@ let rec define_line_1 acc xs =
   | TDefine ii::xs ->
       let line = Ast_c.line_of_info ii in
       let acc = (TDefine ii) :: acc in
-      define_line_2 acc line ii xs
+      define_line_2 acc ((=|=) line) ii xs
+  | TUndef ii::xs ->
+      let line = Ast_c.line_of_info ii in
+      let acc = (TUndef ii) :: acc in
+      define_line_2 acc ((=|=) line) ii xs
   | TCppEscapedNewline ii::xs ->
       pr2 ("SUSPICIOUS: a \\ character appears outside of a #define at");
       pr2 (Ast_c.strloc_of_info ii);
@@ -426,14 +437,14 @@ let rec define_line_1 acc xs =
       define_line_1 acc xs
   | x::xs -> define_line_1 (x::acc) xs
 
-and define_line_2 acc line lastinfo xs =
+and define_line_2 acc lineOk lastinfo xs =
   match xs with
   | [] ->
       (* should not happened, should meet EOF before *)
       pr2 "PB: WEIRD";
       List.rev (mark_end_define lastinfo::acc)
   | x::xs ->
-      let line' = TH.line_of_tok x in
+      let line = TH.line_of_tok x in
       let info = TH.info_of_tok x in
 
       (match x with
@@ -442,12 +453,16 @@ and define_line_2 acc line lastinfo xs =
          let acc = (EOF ii) :: acc in
           define_line_1 acc xs
       | TCppEscapedNewline ii ->
-          if (line' <> line) then pr2 "PB: WEIRD: not same line number";
+          if not (lineOk line) then pr2 "PB: WEIRD: not same line number";
          let acc = (TCommentSpace ii) :: acc in
-          define_line_2 acc (line+1) info xs
+          define_line_2 acc ((=|=) (line + 1)) info xs
+      | TComment _ when lineOk line ->
+          define_line_2 (x::acc) (function x -> true) info xs
+      | TString _ when lineOk line ->
+          define_line_2 (x::acc) (function x -> true) info xs
       | x ->
-          if line' =|= line
-          then define_line_2 (x::acc) line info xs
+          if lineOk line
+          then define_line_2 (x::acc) ((=|=) line) info xs
           else
            (* Put end of line token before the newline.  A newline at least
               must be there because the line changed and because we saw a
@@ -460,6 +475,17 @@ and define_line_2 acc line lastinfo xs =
 let rec define_ident acc xs =
   match xs with
   | [] -> List.rev acc
+  | TUndef ii::xs ->
+      let acc = TUndef ii :: acc in
+      (match xs with
+       TCommentSpace i1::TIdent (s,i2)::xs ->
+         let acc = (TCommentSpace i1) :: acc in
+         let acc = (TIdentDefine (s,i2)) :: acc in
+          define_ident acc xs
+      | _ ->
+          pr2 "WEIRD: weird #define body";
+          define_ident acc xs
+      )
   | TDefine ii::xs ->
       let acc = TDefine ii :: acc in
       (match xs with
@@ -490,23 +516,18 @@ let rec define_ident acc xs =
        * body (it would be a recursive macro, which is forbidden).
        *)
 
-      | TCommentSpace i1::t::xs ->
-
+      | TCommentSpace i1::t::xs
+       when TH.str_of_tok t ==~ Common.regexp_alpha
+       ->
           let s = TH.str_of_tok t in
           let ii = TH.info_of_tok t in
-          if s ==~ Common.regexp_alpha
-          then begin
-            pr2 (spf "remapping: %s to an ident in macro name" s);
-           let acc = (TCommentSpace i1) :: acc in
-           let acc = (TIdentDefine (s,ii)) :: acc in
-            define_ident acc xs
-          end
-          else begin
-            pr2 "WEIRD: weird #define body";
-            define_ident acc xs
-          end
-
-      | _ ->
+         pr2 (spf "remapping: %s to an ident in macro name" s);
+          let acc = (TCommentSpace i1) :: acc in
+         let acc = (TIdentDefine (s,ii)) :: acc in
+          define_ident acc xs
+          
+      | TCommentSpace _::_::xs
+      | xs ->
           pr2 "WEIRD: weird #define body";
           define_ident acc xs
       )
@@ -556,6 +577,7 @@ let new_info posadd str ii =
       };
     (* must generate a new ref each time, otherwise share *)
     cocci_tag = ref Ast_c.emptyAnnot;
+    annots_tag = Token_annot.empty;
     comments_tag = ref Ast_c.emptyComments;
    }
 
@@ -625,7 +647,7 @@ let rec commentize_skip_start_to_end xs =
             in
             let topass = x::x2::before in
             topass +> List.iter (fun tok ->
-              set_as_comment Token_c.CppPassingExplicit tok
+              TV.set_as_comment Token_c.CppPassingExplicit tok
             );
             commentize_skip_start_to_end after
           with Not_found ->
@@ -653,20 +675,22 @@ let rec find_ifdef_bool xs =
       msg_ifdef_bool_passing is_ifdef_positif;
 
       (match xxs with
-      | [] -> raise Impossible
+      | [] -> raise (Impossible 90)
       | firstclause::xxs ->
-          info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
+          info_ifdef_stmt +>
+         List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
 
           if is_ifdef_positif
           then xxs +> List.iter
-            (iter_token_ifdef (set_as_comment Token_c.CppPassingNormal))
+            (iter_token_ifdef (TV.set_as_comment Token_c.CppPassingNormal))
           else begin
-            firstclause +> iter_token_ifdef (set_as_comment Token_c.CppPassingNormal);
+            firstclause +>
+           iter_token_ifdef (TV.set_as_comment Token_c.CppPassingNormal);
             (match List.rev xxs with
             (* keep only last *)
             | last::startxs ->
                 startxs +> List.iter
-                  (iter_token_ifdef (set_as_comment Token_c.CppPassingNormal))
+                  (iter_token_ifdef (TV.set_as_comment Token_c.CppPassingNormal))
             | [] -> (* not #else *) ()
             );
           end
@@ -685,7 +709,7 @@ let rec find_ifdef_mid xs =
   | NotIfdefLine _ -> ()
   | Ifdef (xxs, info_ifdef_stmt) ->
       (match xxs with
-      | [] -> raise Impossible
+      | [] -> raise (Impossible 91)
       | [first] -> ()
       | first::second::rest ->
           (* don't analyse big ifdef *)
@@ -711,9 +735,11 @@ let rec find_ifdef_mid xs =
               msg_ifdef_mid_something();
 
               (* keep only first, treat the rest as comment *)
-              info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
+              info_ifdef_stmt +>
+             List.iter
+               (TV.save_as_comment (function x -> Token_c.CppIfDirective x));
               (second::rest) +> List.iter
-                (iter_token_ifdef (set_as_comment Token_c.CppPassingCosWouldGetError));
+                (iter_token_ifdef (TV.set_as_comment Token_c.CppPassingCosWouldGetError));
             end
 
       );
@@ -748,10 +774,11 @@ let rec find_ifdef_funheaders = function
       find_ifdef_funheaders xs;
 
       msg_ifdef_funheaders ();
-      info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
+      info_ifdef_stmt +>
+      List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
       let all_toks = [xline2] @ line2 in
-      all_toks +> List.iter (set_as_comment Token_c.CppPassingCosWouldGetError) ;
-      ifdefblock2 +> iter_token_ifdef (set_as_comment Token_c.CppPassingCosWouldGetError);
+      all_toks +> List.iter (TV.set_as_comment Token_c.CppPassingCosWouldGetError) ;
+      ifdefblock2 +> iter_token_ifdef (TV.set_as_comment Token_c.CppPassingCosWouldGetError);
 
   (* ifdef with nested ifdef *)
   | Ifdef
@@ -770,10 +797,12 @@ let rec find_ifdef_funheaders = function
       find_ifdef_funheaders xs;
 
       msg_ifdef_funheaders ();
-      info_ifdef_stmt  +> List.iter (set_as_comment Token_c.CppDirective);
-      info_ifdef_stmt2 +> List.iter (set_as_comment Token_c.CppDirective);
+      info_ifdef_stmt  +>
+      List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
+      info_ifdef_stmt2 +>
+      List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
       let all_toks = [xline2;xline3] @ line2 @ line3 in
-      all_toks +> List.iter (set_as_comment Token_c.CppPassingCosWouldGetError);
+      all_toks +> List.iter (TV.set_as_comment Token_c.CppPassingCosWouldGetError);
 
  (* ifdef with elseif *)
   | Ifdef
@@ -788,9 +817,10 @@ let rec find_ifdef_funheaders = function
       find_ifdef_funheaders xs;
 
       msg_ifdef_funheaders ();
-      info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
+      info_ifdef_stmt +>
+      List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
       let all_toks = [xline2;xline3] @ line2 @ line3 in
-      all_toks +> List.iter (set_as_comment Token_c.CppPassingCosWouldGetError)
+      all_toks +> List.iter (TV.set_as_comment Token_c.CppPassingCosWouldGetError)
 
   (* recurse *)
   | Ifdef (xxs,info_ifdef_stmt)::xs
@@ -825,7 +855,7 @@ let rec find_ifdef_cparen_else xs =
   | NotIfdefLine _ -> ()
   | Ifdef (xxs, info_ifdef_stmt) ->
       (match xxs with
-      | [] -> raise Impossible
+      | [] -> raise (Impossible 92)
       | [first] -> ()
       | first::second::rest ->
 
@@ -850,9 +880,10 @@ let rec find_ifdef_cparen_else xs =
             msg_ifdef_cparen_else();
 
             (* keep only first, treat the rest as comment *)
-            info_ifdef_stmt +> List.iter (set_as_comment Token_c.CppDirective);
+            info_ifdef_stmt +>
+           List.iter (TV.save_as_comment (fun x -> Token_c.CppIfDirective x));
             (second::rest) +> List.iter
-              (iter_token_ifdef (set_as_comment Token_c.CppPassingCosWouldGetError));
+              (iter_token_ifdef (TV.set_as_comment Token_c.CppPassingCosWouldGetError));
           end
 
       );
@@ -889,6 +920,7 @@ let rec find_string_macro_paren xs =
           xs +> List.iter (fun tok ->
             match tok with
             | PToken({tok = TIdent (s,_)} as id) ->
+
                 msg_stringification s;
                 id.tok <- TMacroString (s, TH.info_of_tok id.tok);
             | _ -> ()
@@ -917,15 +949,15 @@ let rec find_macro_paren xs =
      ->
       pr2_cpp ("MACRO: __attribute detected ");
       [Parenthised (xxs, info_parens)] +>
-        iter_token_paren (set_as_comment Token_c.CppAttr);
-      set_as_comment Token_c.CppAttr id;
+        iter_token_paren (TV.set_as_comment Token_c.CppAttr);
+      TV.set_as_comment Token_c.CppAttr id;
       find_macro_paren xs
 
   | PToken ({tok = TattributeNoarg _} as id)
     ::xs
      ->
       pr2_cpp ("MACRO: __attributenoarg detected ");
-      set_as_comment Token_c.CppAttr id;
+      TV.set_as_comment Token_c.CppAttr id;
       find_macro_paren xs
 
 (*
@@ -956,7 +988,6 @@ let rec find_macro_paren xs =
       (* recurse, may have other storage attributes *)
       find_macro_paren (PToken (tok1)::xs)
 
-
 *)
 
   (* storage attribute *)
@@ -983,7 +1014,7 @@ let rec find_macro_paren xs =
       msg_stringification_params s;
       id.tok <- TMacroString (s, TH.info_of_tok id.tok);
       [Parenthised (xxs, info_parens)] +>
-        iter_token_paren (set_as_comment Token_c.CppMacro);
+        iter_token_paren (TV.set_as_comment Token_c.CppMacro);
       find_macro_paren xs
 
   (* after case *)
@@ -995,7 +1026,7 @@ let rec find_macro_paren xs =
       msg_stringification_params s;
       id.tok <- TMacroString (s, TH.info_of_tok id.tok);
       [Parenthised (xxs, info_parens)] +>
-        iter_token_paren (set_as_comment Token_c.CppMacro);
+        iter_token_paren (TV.set_as_comment Token_c.CppMacro);
       find_macro_paren xs
 
 
@@ -1005,7 +1036,7 @@ let rec find_macro_paren xs =
 
   (* string macro variable, before case *)
   | PToken ({tok = (TString _ | TMacroString _)})::PToken ({tok = TIdent (s,_)} as id)
-      ::xs ->
+      ::xs when not !Flag.c_plus_plus ->
 
       msg_stringification s;
       id.tok <- TMacroString (s, TH.info_of_tok id.tok);
@@ -1108,8 +1139,6 @@ let rec find_macro_lineparen xs =
       find_macro_lineparen (xs)
 
 
-
-
   (* on multiple lines *)
   | (Line
         (
@@ -1133,6 +1162,46 @@ let rec find_macro_lineparen xs =
       find_macro_lineparen (xs)
 
 
+  | (Line (* initializer case *)
+        (
+          PToken ({tok = Tstatic _}) ::
+           PToken ({tok = TIdent (s,_)} as macro) ::
+           Parenthised (xxs,info_parens) ::
+           PToken ({tok = TEq _}) :: rest
+        ))
+    ::xs
+    when (s ==~ regexp_macro) ->
+
+      msg_declare_macro s;
+      let info = TH.info_of_tok macro.tok in
+      macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
+
+      (* continue with the rest of the line *)
+      find_macro_lineparen ((Line(rest))::xs)
+
+
+  | (Line (* multi-line initializer case *)
+        (
+          (PToken ({tok = Tstatic _})::[]
+          )))
+    ::(Line
+        (
+          PToken ({tok = Tstatic _}) ::
+           PToken ({tok = TIdent (s,_)} as macro) ::
+           Parenthised (xxs,info_parens) ::
+           PToken ({tok = TEq _}) :: rest
+        ))
+    ::xs
+    when (s ==~ regexp_macro) ->
+
+      msg_declare_macro s;
+      let info = TH.info_of_tok macro.tok in
+      macro.tok <- TMacroDecl (Ast_c.str_of_info info, info);
+
+      (* continue with the rest of the line *)
+      find_macro_lineparen ((Line(rest))::xs)
+
+
   (* linuxext: ex: DECLARE_BITMAP();
    *
    * Here I use regexp_declare and not regexp_macro because
@@ -1185,6 +1254,7 @@ let rec find_macro_lineparen xs =
              | TCBrace _ when ctx <> InFunction -> false
              | TPtVirg _
              | TDotDot _
+             | TWhy _
                -> false
              | tok when TH.is_binary_operator tok -> false
 
@@ -1225,6 +1295,8 @@ let rec find_macro_lineparen xs =
     ::xs
     (* when s ==~ regexp_macro *)
     ->
+      (* This can give a false positive for K&R functions if the function
+         name is in the same column as the first parameter declaration. *)
       let condition =
         (col1 =|= col2 &&
             (match other.tok with
@@ -1232,6 +1304,7 @@ let rec find_macro_lineparen xs =
             | TCBrace _ when ctx <> InFunction -> false
             | TPtVirg _
             | TDotDot _
+            | TWhy _
                 -> false
             | tok when TH.is_binary_operator tok -> false
 
@@ -1264,7 +1337,7 @@ let rec find_macro_lineparen xs =
           msg_macro_noptvirg s;
           macro.tok <- TMacroStmt (s, TH.info_of_tok macro.tok);
           [Parenthised (xxs, info_parens)] +>
-            iter_token_paren (set_as_comment Token_c.CppMacro);
+            iter_token_paren (TV.set_as_comment Token_c.CppMacro);
         end;
 
       find_macro_lineparen (line2::xs)
@@ -1293,6 +1366,7 @@ let rec find_macro_lineparen xs =
             | TPtVirg _ -> false
             | TOr _ -> false
             | TCBrace _ when ctx <> InFunction -> false
+            | TWhy _ -> false
             | tok when TH.is_binary_operator tok -> false
 
             | _ -> true
@@ -1427,7 +1501,7 @@ and find_actions_params xxs =
         then
           (* certainly because paren detection had a pb because of
            * some ifdef-exp. Do similar additional checking than
-           * what is done in set_as_comment.
+           * what is done in TV.set_as_comment.
            *)
           pr2 "PB: weird, I try to tag an EOF token as an action"
         else
@@ -1496,8 +1570,8 @@ let insert_virtual_positions l =
        | _ -> x::skip_fake xs in
   skip_fake l
 
-
 (* ------------------------------------------------------------------------- *)
+
 let fix_tokens_cpp2 ~macro_defs tokens =
   let tokens2 = ref (tokens +> Common.acc_map TV.mk_token_extended) in
 
@@ -1585,6 +1659,20 @@ let fix_tokens_cpp ~macro_defs a =
 
 
 
+let can_be_on_top_level tl =
+  match tl with
+  | Tstruct _
+  | Ttypedef _
+  | TDefine _ 
+  | TIfdef _
+  | TIfdefelse _
+  | TIfdefelif _
+  | TIfdefBool _
+  | TIfdefMisc _
+  | TIfdefVersion _
+  | TEndif _ -> true
+  | _ -> false
+
 
 (*****************************************************************************)
 (* Lexing with lookahead *)
@@ -1619,10 +1707,96 @@ let not_struct_enum = function
   | (Parser_c.Tstruct _ | Parser_c.Tunion _ | Parser_c.Tenum _)::_ -> false
   | _ -> true
 
+let pointer ?(followed_by=fun _ -> true) 
+    ?(followed_by_more=fun _ -> true) ts = 
+  let rec loop ts = 
+    match ts with
+    | TMul _ :: rest -> loop rest
+    | TAnd _ :: rest when !Flag.c_plus_plus -> loop rest
+    | t :: ts' -> followed_by t && followed_by_more ts' 
+    | [] -> failwith "unexpected end of token stream" in
+  match ts with
+  | TMul _ :: rest -> loop rest
+  | TAnd _ :: rest when !Flag.c_plus_plus -> loop rest
+  | _ -> false
+
+let ident = function
+    TIdent _ -> true
+  | _ -> false
+
+let is_type = function
+  | TypedefIdent _ 
+  | Tvoid _
+  | Tchar _
+  | Tfloat _
+  | Tdouble _
+
+  | Tsize_t _
+  | Tssize_t _
+  | Tptrdiff_t _
+      
+  | Tint _
+  | Tlong _
+  | Tshort _ -> true
+  | _ -> false
+
+let is_cparen = function (TCPar _) -> true | _ -> false
+let is_oparen = function (TOPar _) -> true | _ -> false
+
+let rec not_has_type_before f xs =
+  match xs with
+  | [] -> raise (Impossible 666)
+  | x :: xs ->
+      if f x then
+       true
+      else if is_type x then
+       false
+      else
+       not_has_type_before f xs
+
+(* This function is inefficient, because it will look over a K&R header,
+or function prototype multiple times.  At least when we see a , and are in a
+parameter list, we know we will eventually see a close paren, and it
+should come fairly soon. *)
+let k_and_r l =
+  let l1 = drop_until is_cparen l in
+  match l1 with
+    (TCPar _) :: (TOCro _) :: _ -> false
+  | (TCPar _) :: _ -> true
+  | _ -> false
+
+(* (a)(b) is ambiguous, because (a) could be a function name or a cast.
+At this point, we just see an ident for a; we don't know if it is eg a local
+variable.  This function sees at least if b is the only argument, ie there
+are no commas at top level *)
+let paren_before_comma l =
+  let rec loop level = function
+      [] -> false
+    | (TComma _)::_ when level = 1 -> false
+    | (TCPar _)::_ when level = 1 -> true
+    | (TCPar _)::rest -> loop (level-1) rest
+    | (TOPar _)::rest -> loop (level+1) rest
+    | x::rest -> loop level rest in
+  loop 0 l
 
 let lookahead2 ~pass next before =
-
   match (next, before) with
+      
+  (* c++ hacks *)
+  (* yy xx(   and in function *)
+  | TOPar i1::_,              TIdent(s,i2)::TypedefIdent _::_
+      when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+        pr2_cpp("constructed_object: "  ^s);
+        TOParCplusplusInit i1
+  | TOPar i1::_,              TIdent(s,i2)::ptr
+      when !Flag.c_plus_plus 
+         && pointer ~followed_by:(function TypedefIdent _ -> true | _ -> false) ptr
+         && (LP.current_context () = (LP.InFunction)) ->
+        pr2_cpp("constructed_object: "  ^s);
+        TOParCplusplusInit i1
+  | TypedefIdent(s,i)::TOPar i1::_,_
+      when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+       TIdent(s,i)
 
   (*-------------------------------------------------------------*)
   (* typedef inference, parse_typedef_fix3 *)
@@ -1642,18 +1816,126 @@ let lookahead2 ~pass next before =
       if !Flag_parsing_c.debug_typedef
       then pr2 ("TYPEDEF: disable typedef cos special case: " ^ s);
 
+
       LP.disable_typedef();
+      msg_typedef s i1 1; LP.add_typedef_root s;
+      TypedefIdent (s, i1)
+
+       (* christia *)
+
+       (* delete[] *)
+  | (TOCro i1 :: _, Tdelete _ :: _) 
+    when !Flag.c_plus_plus ->
+      TCommentCpp (Token_c.CppDirective, i1)
+       (* delete[] *)
+  | (TCCro i1 :: _, Tdelete _ :: _) 
+    when !Flag.c_plus_plus ->
+      TCommentCpp (Token_c.CppDirective, i1)
+
+       (* extern "_" tt *)
+  | ((TString ((s, _), i1) | TMacroString (s, i1)) :: _ , Textern _ :: _) 
+    when !Flag.c_plus_plus ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* ) const { *)
+  | (Tconst i1 :: TOBrace _ :: _ , TCPar _ :: _) 
+    when !Flag.c_plus_plus ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* xx const tt *)
+  | (TIdent (s, i1)::(Tconst _|Tvolatile _|Trestrict _)::type_::_  , _) 
+    when not_struct_enum before
+       && is_type type_ ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* xx struct *)
+  | (TIdent (s, i1)::Tstruct _::_  , _) 
+    when not_struct_enum before ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* xx tt *)
+  | (TIdent (s, i1)::type_::_  , _) 
+    when not_struct_enum before
+       && is_type type_ ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* tt xx yy *)
+  | (TIdent (s, i1)::TIdent (s2, i2)::_  , seen::_) 
+    when not_struct_enum before
+       && is_type seen ->
+         if is_macro s2 then
+           TIdent (s, i1)
+         else
+           TCommentCpp (Token_c.CppDirective, i1)
+
+        (* exception to next rule *)
+  | (TIdent (s2, i2)::TOPar _::_ , TIdent (s1, i1)::seen::_)
+    when not_struct_enum before
+        && is_macro s2 && is_type seen ->
+          TIdent (s2, i2)
+
+  | (TIdent (s2, i2)::_  , TIdent (s, i1)::seen::_) 
+    when not_struct_enum before
+       && is_macro s2 && is_type seen ->
+         TCommentCpp (Token_c.CppDirective, i2)
+
+       (* tt xx * *)
+  | (TIdent (s, i1)::ptr  , seen::_) 
+    when not_struct_enum before
+       && pointer ptr && is_type seen ->
+         TCommentCpp (Token_c.CppDirective, i1)
+
+       (* tt * xx yy *)
+  | (TIdent (s, i1)::TIdent(s2, i2)::_  , ptr) 
+    when not_struct_enum before
+       && pointer ptr ->
+         if is_macro s2 then
+           TIdent (s, i1)
+         else
+           TCommentCpp (Token_c.CppDirective, i1)
+
+  (* exception to next rule *)
+  | (TIdent (s2, i2)::TOPar _::_ , TIdent (s1, i1)::ptr)
+      when not_struct_enum before
+        && is_macro s2 && pointer ptr ->
+    TIdent (s2, i2)
+       (* tt * xx yy *)
+  | (TIdent(s2, i2)::_  , TIdent (s, i1)::ptr) 
+    when not_struct_enum before
+       && is_macro s2 && pointer ptr ->
+         TCommentCpp (Token_c.CppDirective, i2)
 
-      msg_typedef s; LP.add_typedef_root s;
+        (* exception to next rule *)
+  | (TIdent(s2, i2)::TOPar _ :: _ , TIdent(s, i1)::seen::_) 
+    when not_struct_enum before
+       && is_macro s2 && is_type seen ->
+         TIdent(s2, i2)
+       (* tt xx yy *)
+  | (TIdent(s2, i2)::_  , TIdent(s, i1)::seen::_) 
+    when not_struct_enum before
+       && is_macro s2 && is_type seen ->
+         TCommentCpp (Token_c.CppDirective, i2)
+
+  (*  xx * yy      AND  in paramdecl *)
+  | (TIdent (s, i1)::ptr , _)
+    when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false) ptr
+       && ok_typedef s ->
+      msg_typedef s i1 14; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
+  (* xx MM ( *)
+  (* exception to next rule *)
+  | (TIdent (s, i1)::TIdent (s2, i2)::TOPar _::_  , _) when not_struct_enum before
+      && ok_typedef s && is_macro s2
+        ->
+         TIdent (s, i1)
   (* xx yy *)
   | (TIdent (s, i1)::TIdent (s2, i2)::_  , _) when not_struct_enum before
       && ok_typedef s
         ->
          (* && not_annot s2 BUT lead to false positive*)
-
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 2; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1661,26 +1943,40 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::Tinline i2::_  , _) when not_struct_enum before
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 3; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (* [,(] xx [,)] AND param decl *)
-  | (TIdent (s, i1)::(TComma _|TCPar _)::_ , (TComma _ |TOPar _)::_ )
+  | (TIdent (s, i1)::(((TComma _|TCPar _)::_) as rest) ,
+     ((TComma _ |TOPar _)::_ as bef))
+    when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
+      && k_and_r rest 
+      && not_has_type_before is_cparen rest 
+      && not_has_type_before is_oparen bef
+      ->
+
+       TKRParam(s,i1)
+
+  | (TIdent (s, i1)::((TComma _|TCPar _)::_) , (TComma _ |TOPar _)::_ )
     when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
-      TypedefIdent (s, i1)
+
+       msg_typedef s i1 4; LP.add_typedef_root s;
+       TypedefIdent (s, i1)
 
   (* xx* [,)] *)
   (* specialcase:  [,(] xx* [,)] *)
-  | (TIdent (s, i1)::TMul _::(TComma _|TCPar _)::_ , (*(TComma _|TOPar _)::*)_ )
-    when not_struct_enum before
+  | (TIdent (s, i1)::ptr , (*(TComma _|TOPar _)::*)_ )
+    when pointer ~followed_by:(function TComma _ |TCPar _ -> true | _ -> false) ptr
+       && not_struct_enum before
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
     ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 5; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1691,7 +1987,8 @@ let lookahead2 ~pass next before =
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
     ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 6; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1703,7 +2000,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 7; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx const *)
@@ -1713,25 +2010,28 @@ let lookahead2 ~pass next before =
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 8; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (* xx * const *)
-  | (TIdent (s, i1)::TMul _::(Tconst _ | Tvolatile _|Trestrict _)::_ , _ )
-      when not_struct_enum before
-      && ok_typedef s
+  | (TIdent (s, i1)::ptr , _ )
+      when pointer ~followed_by:(function Tconst _ | Tvolatile _ | Trestrict _ -> true | _ -> false) ptr
+         && not_struct_enum before
+         && ok_typedef s
       ->
+
       (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 9; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (* ( const xx)  *)
   | (TIdent (s, i1)::TCPar _::_,  (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when
       ok_typedef s ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 10; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1741,7 +2041,8 @@ let lookahead2 ~pass next before =
     when not_struct_enum before
       && ok_typedef s
     ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 11; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* [(,] xx [   AND parameterdeclaration *)
@@ -1749,7 +2050,8 @@ let lookahead2 ~pass next before =
       when (LP.current_context() =*= LP.InParameter)
       && ok_typedef s
      ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 12; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*------------------------------------------------------------*)
@@ -1758,61 +2060,77 @@ let lookahead2 ~pass next before =
   (*------------------------------------------------------------*)
 
   (* static xx * yy  *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::_ ,
+  | (TIdent (s, i1)::ptr ,
      (Tregister _|Tstatic _  |Tvolatile _|Tconst _|Trestrict _)::_) when
-      ok_typedef s
+      pointer ~followed_by:(function TIdent _ -> true | _ -> false) ptr
+        && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 13; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  TODO  xx * yy ; AND in start of compound element  *)
 
 
   (*  xx * yy,      AND  in paramdecl *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ , _)
+  | (TIdent (s, i1)::ptr , _)
     when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
-      && ok_typedef s
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TComma _ :: _ -> true | _ -> false) ptr
+       && ok_typedef s
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 14; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (*  xx * yy ;     AND in Toplevel, except when have = before  *)
   | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ , TEq _::_) ->
       TIdent (s, i1)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ , _)
-    when not_struct_enum before && (LP.is_top_or_struct (LP.current_context ()))
+  | (TIdent (s, i1)::ptr , _)
+    when not_struct_enum before 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TPtVirg _ :: _ -> true | _ -> false) ptr
+       && (LP.is_top_or_struct (LP.current_context ()))
       ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 15; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx * yy ,     AND in Toplevel  *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ , _)
+  | (TIdent (s, i1)::ptr , _)
     when not_struct_enum before && (LP.current_context () =*= LP.InTopLevel)
-      && ok_typedef s
+       && ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TComma _ :: _ -> true | _ -> false) ptr
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 16; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx * yy (     AND in Toplevel  *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TOPar _::_ , _)
+  | (TIdent (s, i1)::ptr , _)
     when not_struct_enum before
-      && (LP.is_top_or_struct (LP.current_context ()))
-      && ok_typedef s
+       && (LP.is_top_or_struct (LP.current_context ()))
+       && ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TOPar _ :: _ -> true | _ -> false) ptr
       ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 17; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx * yy [ *)
   (* todo? enough ? cos in struct def we can have some expression ! *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TOCro _::_ , _)
-    when not_struct_enum before &&
-      (LP.is_top_or_struct (LP.current_context ()))
-      && ok_typedef s
+  | (TIdent (s, i1)::ptr , _)
+    when not_struct_enum before 
+       && (LP.is_top_or_struct (LP.current_context ()))
+       && ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TOCro _ :: _ -> true | _ -> false) ptr
       ->
-      msg_typedef s;  LP.add_typedef_root s;
+
+      msg_typedef s i1 18;  LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* u16: 10; in struct *)
@@ -1820,7 +2138,8 @@ let lookahead2 ~pass next before =
     when       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s
       ->
-      msg_typedef s;  LP.add_typedef_root s;
+
+      msg_typedef s i1 19;  LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1833,63 +2152,90 @@ let lookahead2 ~pass next before =
       (take_safe 1 !passed_tok <> [Tenum]))
       &&
       !LP._lexer_hint = Some LP.Toplevel ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 20; LP.add_typedef_root s;
       TypedefIdent s
      *)
 
   (*  xx * yy =  *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TEq _::_ , _)
+  | (TIdent (s, i1)::ptr , _)
     when not_struct_enum before
-      && ok_typedef s
+       && ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TEq _ :: _ -> true | _ -> false) ptr
       ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 21; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (*  xx * yy)      AND in paramdecl *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TCPar _::_ , _)
-      when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
-      && ok_typedef s
+  | (TIdent (s, i1)::ptr , _)
+    when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
+       && ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TCPar _ :: _ -> true | _ -> false) ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 22; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (*  xx * yy; *) (* wrong ? *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TPtVirg _::_ ,
-     (TOBrace _| TPtVirg _)::_)  when not_struct_enum before
-      && ok_typedef s
+  | (TIdent (s, i1)::ptr ,
+     (TOBrace _| TPtVirg _)::_) when not_struct_enum before
+       && ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TPtVirg _ :: _ -> true | _ -> false) ptr
         ->
-      msg_typedef s;  LP.add_typedef_root s;
+
+      msg_typedef s i1 23;  LP.add_typedef_root s;
       msg_maybe_dangereous_typedef s;
       TypedefIdent (s, i1)
 
 
   (*  xx * yy,  and ';' before xx *) (* wrong ? *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::TComma _::_ ,
+  | (TIdent (s, i1)::ptr ,
      (TOBrace _| TPtVirg _)::_) when
-      ok_typedef s
+      ok_typedef s 
+       && pointer ~followed_by:(function TIdent _ -> true | _ -> false)
+              ~followed_by_more:(function TComma _ :: _ -> true | _ -> false) ptr
     ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 24; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
   (* xx_t * yy *)
-  | (TIdent (s, i1)::TMul _::TIdent (s2, i2)::_ , _)
+  | (TIdent (s, i1)::ptr , _)
       when s ==~ regexp_typedef && not_struct_enum before
         (* struct user_info_t sometimes *)
-      && ok_typedef s
+       && ok_typedef s 
+        && pointer ~followed_by:(function TIdent _ -> true | _ -> false) ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 25; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx ** yy *)  (* wrong ? *)
   | (TIdent (s, i1)::TMul _::TMul _::TIdent (s2, i2)::_ , _)
+    when not_struct_enum before
+       && (LP.current_context() =*= LP.InParameter)
+       && ok_typedef s
+    ->
+
+      msg_typedef s i1 26; LP.add_typedef_root s;
+      TypedefIdent (s, i1)
+
+  (*  xx ** yy *)  (* wrong ? *)
+  | (TIdent (s, i1)::TMul _::TMul _::TIdent (s2, i2)::_ , (TOBrace _ | TPtVirg _)::_)
     when not_struct_enum before
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
-      && ok_typedef s
-      ->
-      msg_typedef s; LP.add_typedef_root s;
+       && ok_typedef s
+       (* christia : this code catches 'a * *b' which is wrong 
+        *)
+    ->
+
+      msg_typedef s i1 26; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx *** yy *)
@@ -1898,7 +2244,8 @@ let lookahead2 ~pass next before =
       && ok_typedef s
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 27; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (*  xx ** ) *)
@@ -1907,7 +2254,8 @@ let lookahead2 ~pass next before =
         (* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
       && ok_typedef s
       ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 28; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1922,12 +2270,14 @@ let lookahead2 ~pass next before =
   (*  (xx) yy *)
   | (TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::_ ,
     (TOPar info)::x::_)
-    when not (TH.is_stuff_taking_parenthized x) &&
-      Ast_c.line_of_info i2 =|= Ast_c.line_of_info i3
+    when not (TH.is_stuff_taking_parenthized x) (* &&
+      Ast_c.line_of_info i2 =|= Ast_c.line_of_info i3 - why useful?
+      *)
       && ok_typedef s
+      && not (ident x) (* possible K&R declaration *)
       ->
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 29; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s, i1)
 
@@ -1940,25 +2290,29 @@ let lookahead2 ~pass next before =
     when not (TH.is_stuff_taking_parenthized x)
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s 30; LP.add_typedef_root s;
       (* TOPar info *)
       TypedefIdent (s, i1)
   *)
   (* special case:  = (xx) (    yy) *)
-  | (TIdent (s, i1)::TCPar _::TOPar _::_ ,
+  | (TIdent (s, i1)::TCPar _::((TOPar _::_) as rest) ,
     (TOPar info)::(TEq _ |TEqEq _)::_)
-    when ok_typedef s
+    when ok_typedef s && paren_before_comma rest
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 31; LP.add_typedef_root s;
       (* TOPar info *)
       TypedefIdent (s, i1)
 
 
   (*  (xx * ) yy *)
-  | (TIdent (s, i1)::TMul _::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_) when
-      ok_typedef s
+  | (TIdent (s, i1)::ptr, (TOPar info)::_)
+    when ok_typedef s 
+       && pointer ~followed_by:(function TCPar _ -> true | _ -> false)
+              ~followed_by_more:(function TIdent _ :: _ -> true | _ -> false) ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 32; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s,i1)
 
@@ -1968,7 +2322,8 @@ let lookahead2 ~pass next before =
       when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x)
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 33; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1985,7 +2340,8 @@ let lookahead2 ~pass next before =
       when not_struct_enum before
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 34; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* x* ( *y )(params),  function pointer 2 *)
@@ -1993,7 +2349,8 @@ let lookahead2 ~pass next before =
       when not_struct_enum before
       && ok_typedef s
         ->
-      msg_typedef s; LP.add_typedef_root s;
+
+      msg_typedef s i1 35; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -2005,9 +2362,10 @@ let lookahead2 ~pass next before =
         as x)
     ::_, _
       ->
+
       (*
       if not !Flag_parsing_c.ifdef_to_if
-      then TCommentCpp (Ast_c.CppDirective, ii)
+      then TCommentCpp (Ast_c.CppIfDirective, ii)
       else
       *)
       (* not !LP._lexer_hint.toplevel *)
@@ -2023,11 +2381,18 @@ let lookahead2 ~pass next before =
           pr2_cpp("IFDEF: or related inside function. I treat it as comment");
           incr Stat.nIfdefPassing;
         end;
-        TCommentCpp (Token_c.CppDirective, ii)
+       let x =
+         match x with
+           TIfdef _ | TIfdefMisc _ | TIfdefVersion _ -> Token_c.IfDef
+         | TIfdefBool _ -> Token_c.IfDef0
+         | TIfdefelse _ | TIfdefelif _ -> Token_c.Else
+         | TEndif _ -> Token_c.Endif
+         | _ -> Token_c.Other in (* not possible here *)
+        TCommentCpp (Token_c.CppIfDirective x, ii)
       end
       else x
 
-  | (TUndef (id, ii) as x)::_, _
+  | (TUndef (ii) as x)::_, _
       ->
         if (pass >= 2)
         then begin
@@ -2066,11 +2431,16 @@ let lookahead2 ~pass next before =
       end
       else TIdent (s, i1)
 
-
-
- (*-------------------------------------------------------------*)
+(*  (* christia: here insert support for macros on top level *)
+  | TIdent (s, ii) :: tl :: _, _ when
+    can_be_on_top_level tl && LP.current_context () = InTopLevel ->
+      pr2_cpp ("'" ^ s ^ "' looks like a macro, I treat it as comment");
+      TCommentCpp (Token_c.CppDirective, ii)
+*)      
+    
+(*-------------------------------------------------------------*)
  | v::xs, _ -> v
- | _ -> raise Impossible
+ | _ -> raise (Impossible 93)
 
 let lookahead ~pass a b =
   Common.profile_code "C parsing.lookahead" (fun () -> lookahead2 ~pass a b)