Coccinelle release-1.0.0-rc11
[bpt/coccinelle.git] / parsing_c / parsing_hacks.ml
index 835fa8c..374b496 100644 (file)
@@ -81,12 +81,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
 
@@ -971,7 +975,6 @@ let rec find_macro_paren xs =
       (* recurse, may have other storage attributes *)
       find_macro_paren (PToken (tok1)::xs)
 
-
 *)
 
   (* storage attribute *)
@@ -1240,6 +1243,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
@@ -1639,10 +1644,48 @@ let pointer = function
   | TAnd _ when !Flag.c_plus_plus -> true
   | _ -> false
 
-let lookahead2 ~pass next before =
+let ident_or_star = function
+    TIdent _ -> true
+  | x -> pointer x
+
+(* 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 (function (TCPar _) -> true | _ -> false) 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
+  | TypedefIdent(s,i)::TOPar i1::_,_
+      when !Flag.c_plus_plus && (LP.current_context () = (LP.InFunction)) ->
+       TIdent(s,i)
+
   (*-------------------------------------------------------------*)
   (* typedef inference, parse_typedef_fix3 *)
   (*-------------------------------------------------------------*)
@@ -1663,7 +1706,7 @@ let lookahead2 ~pass next before =
 
       LP.disable_typedef();
 
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 1; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx yy *)
@@ -1672,7 +1715,7 @@ let lookahead2 ~pass next before =
         ->
          (* && 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)
 
 
@@ -1680,17 +1723,24 @@ 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 _)::_ )
+    when not_struct_enum before && (LP.current_context() =*= LP.InParameter)
+      && k_and_r rest
+      ->
+       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* [,)] *)
@@ -1699,7 +1749,7 @@ 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 5; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1710,7 +1760,7 @@ 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)
 
 
@@ -1722,7 +1772,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 *)
@@ -1732,7 +1782,7 @@ 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)
 
 
@@ -1743,14 +1793,14 @@ let lookahead2 ~pass next before =
       ->
       (* && !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)
 
 
@@ -1760,7 +1810,7 @@ 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 *)
@@ -1768,7 +1818,7 @@ 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)
 
   (*------------------------------------------------------------*)
@@ -1781,7 +1831,7 @@ let lookahead2 ~pass next before =
      (Tregister _|Tstatic _  |Tvolatile _|Tconst _|Trestrict _)::_) when
       pointer 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  *)
@@ -1793,7 +1843,7 @@ let lookahead2 ~pass next before =
       && pointer 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)
 
 
@@ -1804,7 +1854,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before && pointer 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  *)
@@ -1813,7 +1863,7 @@ let lookahead2 ~pass next before =
       && ok_typedef s && pointer 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  *)
@@ -1822,7 +1872,7 @@ let lookahead2 ~pass next before =
       && (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s && pointer ptr
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 17; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx * yy [ *)
@@ -1832,7 +1882,7 @@ let lookahead2 ~pass next before =
       (LP.is_top_or_struct (LP.current_context ()))
       && ok_typedef s && pointer 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 *)
@@ -1840,7 +1890,7 @@ 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)
 
 
@@ -1853,7 +1903,7 @@ 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
      *)
 
@@ -1862,7 +1912,7 @@ let lookahead2 ~pass next before =
     when not_struct_enum before
       && ok_typedef s && pointer ptr
       ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 21; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1871,7 +1921,7 @@ let lookahead2 ~pass next before =
       when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
       && ok_typedef s && pointer ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 22; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1880,7 +1930,7 @@ let lookahead2 ~pass next before =
      (TOBrace _| TPtVirg _)::_)  when not_struct_enum before
       && ok_typedef s & pointer 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)
 
@@ -1890,7 +1940,7 @@ let lookahead2 ~pass next before =
      (TOBrace _| TPtVirg _)::_) when
       ok_typedef s && pointer ptr
     ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 24; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
 
@@ -1900,7 +1950,7 @@ let lookahead2 ~pass next before =
         (* struct user_info_t sometimes *)
       && ok_typedef s && pointer 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 ? *)
@@ -1909,7 +1959,7 @@ 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 26; LP.add_typedef_root s;
       TypedefIdent (s, i1)
 
   (* xx *** yy *)
@@ -1918,7 +1968,7 @@ 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 ** ) *)
@@ -1927,7 +1977,7 @@ 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)
 
 
@@ -1940,14 +1990,15 @@ let lookahead2 ~pass next before =
    *)
 
   (*  (xx) yy *)
-  | (TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::_ ,
+  | (TIdent (s, i1)::TCPar i2::(TIdent (_,i3)|TInt (_,i3))::after::_ ,
     (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_or_star after) (* 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)
 
@@ -1960,16 +2011,16 @@ 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)
 
@@ -1978,7 +2029,7 @@ let lookahead2 ~pass next before =
   | (TIdent (s, i1)::ptr::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_)
     when ok_typedef s && pointer ptr
         ->
-      msg_typedef s; LP.add_typedef_root s;
+      msg_typedef s i1 32; LP.add_typedef_root s;
       (*TOPar info*)
       TypedefIdent (s,i1)
 
@@ -1988,7 +2039,7 @@ 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)
 
 
@@ -2005,7 +2056,7 @@ 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 *)
@@ -2013,7 +2064,7 @@ 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)
 
 
@@ -2086,8 +2137,6 @@ let lookahead2 ~pass next before =
       end
       else TIdent (s, i1)
 
-
-
  (*-------------------------------------------------------------*)
  | v::xs, _ -> v
  | _ -> raise Impossible