X-Git-Url: https://git.hcoop.net/bpt/coccinelle.git/blobdiff_plain/d6ce1786f27a05efa53cabeca92fc8e744a4b239..abad11c5570b7b9bbae5ff92b3050cf68fe3fd14:/parsing_c/parsing_hacks.ml diff --git a/parsing_c/parsing_hacks.ml b/parsing_c/parsing_hacks.ml index 9d05efe..c3ac6b7 100644 --- a/parsing_c/parsing_hacks.ml +++ b/parsing_c/parsing_hacks.ml @@ -62,7 +62,7 @@ let is_known_typdef = | "u8" | "u16" | "u32" | "u64" | "s8" | "s16" | "s32" | "s64" | "__u8" | "__u16" | "__u32" | "__u64" - -> true + -> true | "acpi_handle" | "acpi_status" @@ -182,7 +182,7 @@ let msg_stringification s = | "UTS_RELEASE" | "SIZE_STR" | "DMA_STR" - -> true + -> true (* s when s =~ ".*STR.*" -> true *) | _ -> false ) @@ -239,15 +239,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: *) @@ -266,6 +266,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) @@ -313,7 +317,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 @@ -341,11 +345,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) @@ -410,6 +413,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 @@ -509,23 +513,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 ) @@ -575,6 +574,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; } @@ -672,7 +672,7 @@ 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 (TV.save_as_comment (fun x -> Token_c.CppIfDirective x)); @@ -706,7 +706,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 *) @@ -852,7 +852,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 -> @@ -1652,6 +1652,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 *) @@ -1695,12 +1709,42 @@ let ident = function TIdent _ -> true | _ -> false +let is_type = function + | TypedefIdent _ + | Tvoid _ + | Tchar _ + | Tfloat _ + | Tdouble _ + (* christia: not sure what these are? *) + | 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 (function (TCPar _) -> true | _ -> false) l in + let l1 = drop_until is_cparen l in match l1 with (TCPar _) :: (TOCro _) :: _ -> false | (TCPar _) :: _ -> true @@ -1722,7 +1766,7 @@ let paren_before_comma l = let lookahead2 ~pass next before = match (next, before) with - + (* c++ hacks *) (* yy xx( and in function *) | TOPar i1::_, TIdent(s,i2)::TypedefIdent _::_ @@ -1751,17 +1795,95 @@ let lookahead2 ~pass next before = if !Flag_parsing_c.debug_typedef then pr2 ("TYPEDEF: disable typedef cos special case: " ^ s); - LP.disable_typedef(); + LP.disable_typedef(); msg_typedef s i1 1; LP.add_typedef_root s; TypedefIdent (s, i1) + (* christia *) + (* 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) + + | (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) + + (* 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) + + (* 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::TIdent (s2, i2)::_ , _) + when not_struct_enum before && (LP.current_context() =*= LP.InParameter) + && pointer ptr && ok_typedef s + -> + + msg_typedef s i1 14; LP.add_typedef_root s; + TypedefIdent (s, i1) + + (* xx yy ( *) + | (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 i1 2; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1770,22 +1892,27 @@ let lookahead2 ~pass next before = | (TIdent (s, i1)::Tinline i2::_ , _) when not_struct_enum before && ok_typedef s -> + msg_typedef s i1 3; LP.add_typedef_root s; TypedefIdent (s, i1) (* [,(] xx [,)] AND param decl *) | (TIdent (s, i1)::(((TComma _|TCPar _)::_) as rest) , - (TComma _ |TOPar _)::_ ) + ((TComma _ |TOPar _)::_ as bef)) when not_struct_enum before && (LP.current_context() =*= LP.InParameter) - && k_and_r rest + && 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 i1 4; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1796,6 +1923,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> + msg_typedef s i1 5; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1807,6 +1935,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> + msg_typedef s i1 6; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1838,6 +1967,7 @@ let lookahead2 ~pass next before = when pointer ptr && not_struct_enum before && ok_typedef s -> + (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) msg_typedef s i1 9; LP.add_typedef_root s; @@ -1847,6 +1977,7 @@ let lookahead2 ~pass next before = (* ( const xx) *) | (TIdent (s, i1)::TCPar _::_, (Tconst _ | Tvolatile _|Trestrict _)::TOPar _::_) when ok_typedef s -> + msg_typedef s i1 10; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1857,6 +1988,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s -> + msg_typedef s i1 11; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1865,6 +1997,7 @@ let lookahead2 ~pass next before = when (LP.current_context() =*= LP.InParameter) && ok_typedef s -> + msg_typedef s i1 12; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1878,6 +2011,7 @@ let lookahead2 ~pass next before = (Tregister _|Tstatic _ |Tvolatile _|Tconst _|Trestrict _)::_) when pointer ptr && ok_typedef s -> + msg_typedef s i1 13; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1901,6 +2035,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && pointer ptr && (LP.is_top_or_struct (LP.current_context ())) -> + msg_typedef s i1 15; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1919,6 +2054,7 @@ let lookahead2 ~pass next before = && (LP.is_top_or_struct (LP.current_context ())) && ok_typedef s && pointer ptr -> + msg_typedef s i1 17; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1929,6 +2065,7 @@ let lookahead2 ~pass next before = (LP.is_top_or_struct (LP.current_context ())) && ok_typedef s && pointer ptr -> + msg_typedef s i1 18; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1937,6 +2074,7 @@ let lookahead2 ~pass next before = when (LP.is_top_or_struct (LP.current_context ())) && ok_typedef s -> + msg_typedef s i1 19; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1959,6 +2097,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s && pointer ptr -> + msg_typedef s i1 21; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1968,6 +2107,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && (LP.current_context () =*= LP.InParameter) && ok_typedef s && pointer ptr -> + msg_typedef s i1 22; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1977,6 +2117,7 @@ let lookahead2 ~pass next before = (TOBrace _| TPtVirg _)::_) when not_struct_enum before && ok_typedef s & pointer ptr -> + msg_typedef s i1 23; LP.add_typedef_root s; msg_maybe_dangereous_typedef s; TypedefIdent (s, i1) @@ -1987,6 +2128,7 @@ let lookahead2 ~pass next before = (TOBrace _| TPtVirg _)::_) when ok_typedef s && pointer ptr -> + msg_typedef s i1 24; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -1997,6 +2139,7 @@ let lookahead2 ~pass next before = (* struct user_info_t sometimes *) && ok_typedef s && pointer ptr -> + msg_typedef s i1 25; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2004,8 +2147,12 @@ let lookahead2 ~pass next before = | (TIdent (s, i1)::TMul _::TMul _::TIdent (s2, i2)::_ , _) when not_struct_enum before (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) - && ok_typedef s - -> + && ok_typedef s + (* christia : this code catches 'a * *b' which is wrong + *) + && true + -> + msg_typedef s i1 26; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2015,6 +2162,7 @@ let lookahead2 ~pass next before = && ok_typedef s (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) -> + msg_typedef s i1 27; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2024,6 +2172,7 @@ let lookahead2 ~pass next before = (* && !LP._lexer_hint = Some LP.ParameterDeclaration *) && ok_typedef s -> + msg_typedef s i1 28; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2045,6 +2194,7 @@ let lookahead2 ~pass next before = && ok_typedef s && not (ident x) (* possible K&R declaration *) -> + msg_typedef s i1 29; LP.add_typedef_root s; (*TOPar info*) TypedefIdent (s, i1) @@ -2067,6 +2217,7 @@ let lookahead2 ~pass next before = (TOPar info)::(TEq _ |TEqEq _)::_) when ok_typedef s && paren_before_comma rest -> + msg_typedef s i1 31; LP.add_typedef_root s; (* TOPar info *) TypedefIdent (s, i1) @@ -2076,6 +2227,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 i1 32; LP.add_typedef_root s; (*TOPar info*) TypedefIdent (s,i1) @@ -2086,6 +2238,7 @@ let lookahead2 ~pass next before = when (*s ==~ regexp_typedef && *) not (TH.is_stuff_taking_parenthized x) && ok_typedef s -> + msg_typedef s i1 33; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2103,6 +2256,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s -> + msg_typedef s i1 34; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2111,6 +2265,7 @@ let lookahead2 ~pass next before = when not_struct_enum before && ok_typedef s -> + msg_typedef s i1 35; LP.add_typedef_root s; TypedefIdent (s, i1) @@ -2123,6 +2278,7 @@ let lookahead2 ~pass next before = as x) ::_, _ -> + (* if not !Flag_parsing_c.ifdef_to_if then TCommentCpp (Ast_c.CppIfDirective, ii) @@ -2191,9 +2347,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)