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
| "u8" | "u16" | "u32" | "u64"
| "s8" | "s16" | "s32" | "s64"
| "__u8" | "__u16" | "__u32" | "__u64"
- -> true
+ -> true
| "acpi_handle"
| "acpi_status"
* 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
| "UTS_RELEASE"
| "SIZE_STR"
| "DMA_STR"
- -> true
+ -> true
(* s when s =~ ".*STR.*" -> true *)
| _ -> false
)
(* 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: *)
let not_annot s =
not (s ==~ regexp_annot)
+let is_macro s =
+ s ==~ regexp_macro
+let not_macro s =
+ not (is_macro s)
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
| TIfdefBool (_, tag, _)
| TIfdefMisc (_, tag, _)
- | TIfdefVersion (_, tag, _)
- ->
- tag := Some cnt;
+ | TIfdefVersion (_, tag, _) ->
+ tag := Some cnt;
- | _ -> raise Impossible
+ | _ -> raise (Impossible 89)
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
| 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);
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
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
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
* 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
)
};
(* 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;
}
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 ->
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
| NotIfdefLine _ -> ()
| Ifdef (xxs, info_ifdef_stmt) ->
(match xxs with
- | [] -> raise Impossible
+ | [] -> raise (Impossible 91)
| [first] -> ()
| first::second::rest ->
(* don't analyse big ifdef *)
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
);
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
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
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
| NotIfdefLine _ -> ()
| Ifdef (xxs, info_ifdef_stmt) ->
(match xxs with
- | [] -> raise Impossible
+ | [] -> raise (Impossible 92)
| [first] -> ()
| first::second::rest ->
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
);
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);
| _ -> ()
->
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
(*
(* recurse, may have other storage attributes *)
find_macro_paren (PToken (tok1)::xs)
-
*)
(* storage attribute *)
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 *)
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
(* 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);
find_macro_lineparen (xs)
-
-
(* on multiple lines *)
| (Line
(
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
| TCBrace _ when ctx <> InFunction -> false
| TPtVirg _
| TDotDot _
+ | TWhy _
-> false
| tok when TH.is_binary_operator tok -> false
::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
| TCBrace _ when ctx <> InFunction -> false
| TPtVirg _
| TDotDot _
+ | TWhy _
-> false
| tok when TH.is_binary_operator tok -> false
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)
| TPtVirg _ -> false
| TOr _ -> false
| TCBrace _ when ctx <> InFunction -> false
+ | TWhy _ -> false
| tok when TH.is_binary_operator tok -> false
| _ -> true
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
| _ -> 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
+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 *)
| (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 *)
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)
| (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)
(* && !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)
&& 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 *)
(* && !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)
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 *)
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)
(*------------------------------------------------------------*)
(*------------------------------------------------------------*)
(* 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 *)
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)
(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 *)
&& 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 ** ) *)
(* && !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)
(* (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)
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)
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)
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 *)
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)
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 *)
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
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)