* because it would compute msg_typedef at compile time when
* the flag debug_typedef is always false
*)
-let msg_typedef s n =
+let msg_typedef s ii n =
incr Stat.nTypedefInfer;
msg_gen (!Flag_parsing_c.debug_typedef)
is_known_typdef
(fun s ->
- (*pr2_cpp (Printf.sprintf "TYPEDEF: promoting(%d): %s" n s)*)
- pr2_cpp (Printf.sprintf "TYPEDEF: promoting: %s" 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
(* recurse, may have other storage attributes *)
find_macro_paren (PToken (tok1)::xs)
-
*)
(* storage attribute *)
::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
| 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 *)
LP.disable_typedef();
- msg_typedef s 1; LP.add_typedef_root s;
+ msg_typedef s i1 1; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx yy *)
->
(* && not_annot s2 BUT lead to false positive*)
- msg_typedef s 2; LP.add_typedef_root s;
+ msg_typedef s i1 2; LP.add_typedef_root s;
TypedefIdent (s, i1)
| (TIdent (s, i1)::Tinline i2::_ , _) when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s 3; 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 4; LP.add_typedef_root s;
- TypedefIdent (s, i1)
+ msg_typedef s i1 4; LP.add_typedef_root s;
+ TypedefIdent (s, i1)
(* xx* [,)] *)
(* specialcase: [,(] xx* [,)] *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s 5; LP.add_typedef_root s;
+ msg_typedef s i1 5; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s 6; LP.add_typedef_root s;
+ msg_typedef s i1 6; LP.add_typedef_root s;
TypedefIdent (s, i1)
&& ok_typedef s
->
- msg_typedef s 7; LP.add_typedef_root s;
+ msg_typedef s i1 7; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx const *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
->
- msg_typedef s 8; LP.add_typedef_root s;
+ msg_typedef s i1 8; LP.add_typedef_root s;
TypedefIdent (s, i1)
->
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
- msg_typedef s 9; 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 10; LP.add_typedef_root s;
+ msg_typedef s i1 10; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s 11; LP.add_typedef_root s;
+ msg_typedef s i1 11; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* [(,] xx [ AND parameterdeclaration *)
when (LP.current_context() =*= LP.InParameter)
&& ok_typedef s
->
- msg_typedef s 12; LP.add_typedef_root s;
+ msg_typedef s i1 12; LP.add_typedef_root s;
TypedefIdent (s, i1)
(*------------------------------------------------------------*)
(Tregister _|Tstatic _ |Tvolatile _|Tconst _|Trestrict _)::_) when
pointer ptr && ok_typedef s
->
- msg_typedef s 13; 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 *)
&& pointer ptr && ok_typedef s
->
- msg_typedef s 14; LP.add_typedef_root s;
+ msg_typedef s i1 14; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before && pointer ptr &&
(LP.is_top_or_struct (LP.current_context ()))
->
- msg_typedef s 15; LP.add_typedef_root s;
+ msg_typedef s i1 15; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy , AND in Toplevel *)
&& ok_typedef s && pointer ptr
->
- msg_typedef s 16; LP.add_typedef_root s;
+ msg_typedef s i1 16; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy ( AND in Toplevel *)
&& (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s && pointer ptr
->
- msg_typedef s 17; LP.add_typedef_root s;
+ msg_typedef s i1 17; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx * yy [ *)
(LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s && pointer ptr
->
- msg_typedef s 18; LP.add_typedef_root s;
+ msg_typedef s i1 18; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* u16: 10; in struct *)
when (LP.is_top_or_struct (LP.current_context ()))
&& ok_typedef s
->
- msg_typedef s 19; LP.add_typedef_root s;
+ msg_typedef s i1 19; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before
&& ok_typedef s && pointer ptr
->
- msg_typedef s 21; LP.add_typedef_root s;
+ msg_typedef s i1 21; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before && (LP.current_context () =*= LP.InParameter)
&& ok_typedef s && pointer ptr
->
- msg_typedef s 22; LP.add_typedef_root s;
+ msg_typedef s i1 22; LP.add_typedef_root s;
TypedefIdent (s, i1)
(TOBrace _| TPtVirg _)::_) when not_struct_enum before
&& ok_typedef s & pointer ptr
->
- msg_typedef s 23; LP.add_typedef_root s;
+ msg_typedef s i1 23; LP.add_typedef_root s;
msg_maybe_dangereous_typedef s;
TypedefIdent (s, i1)
(TOBrace _| TPtVirg _)::_) when
ok_typedef s && pointer ptr
->
- msg_typedef s 24; LP.add_typedef_root s;
+ msg_typedef s i1 24; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* struct user_info_t sometimes *)
&& ok_typedef s && pointer ptr
->
- msg_typedef s 25; LP.add_typedef_root s;
+ msg_typedef s i1 25; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx ** yy *) (* wrong ? *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s 26; LP.add_typedef_root s;
+ msg_typedef s i1 26; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx *** yy *)
&& ok_typedef s
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
->
- msg_typedef s 27; LP.add_typedef_root s;
+ msg_typedef s i1 27; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* xx ** ) *)
(* && !LP._lexer_hint = Some LP.ParameterDeclaration *)
&& ok_typedef s
->
- msg_typedef s 28; LP.add_typedef_root s;
+ msg_typedef s i1 28; LP.add_typedef_root s;
TypedefIdent (s, i1)
*)
(* (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 29; LP.add_typedef_root s;
+ msg_typedef s i1 29; LP.add_typedef_root s;
(*TOPar info*)
TypedefIdent (s, i1)
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 31; LP.add_typedef_root s;
+ msg_typedef s i1 31; LP.add_typedef_root s;
(* TOPar info *)
TypedefIdent (s, i1)
| (TIdent (s, i1)::ptr::TCPar _::TIdent (s2, i2)::_ , (TOPar info)::_)
when ok_typedef s && pointer ptr
->
- msg_typedef s 32; LP.add_typedef_root s;
+ msg_typedef s i1 32; LP.add_typedef_root s;
(*TOPar info*)
TypedefIdent (s,i1)
when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x)
&& ok_typedef s
->
- msg_typedef s 33; LP.add_typedef_root s;
+ msg_typedef s i1 33; LP.add_typedef_root s;
TypedefIdent (s, i1)
when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s 34; LP.add_typedef_root s;
+ msg_typedef s i1 34; LP.add_typedef_root s;
TypedefIdent (s, i1)
(* x* ( *y )(params), function pointer 2 *)
when not_struct_enum before
&& ok_typedef s
->
- msg_typedef s 35; LP.add_typedef_root s;
+ msg_typedef s i1 35; LP.add_typedef_root s;
TypedefIdent (s, i1)
end
else TIdent (s, i1)
-
-
(*-------------------------------------------------------------*)
| v::xs, _ -> v
| _ -> raise Impossible