flitter/lang_cpp/parsing/parsing_hacks_lib.ml
Joey Yakimowich-Payne fa600b98f7 Add poc files
2018-05-26 10:55:38 +09:00

287 lines
8.9 KiB
OCaml

(* Yoann Padioleau
*
* Copyright (C) 2002-2008 Yoann Padioleau
* Copyright (C) 2011 Facebook
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License (GPL)
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* file license.txt for more details.
*)
open Common
module Flag = Flag_parsing_cpp
module Ast = Ast_cpp
module TH = Token_helpers_cpp
module Parser = Parser_cpp
module PI = Parse_info
open Parser_cpp
open Token_views_cpp
(*****************************************************************************)
(* Wrappers *)
(*****************************************************************************)
let pr2, _pr2_once = Common2.mk_pr2_wrappers Flag_parsing_cpp.verbose_parsing
(*****************************************************************************)
(* Helpers *)
(*****************************************************************************)
(*
* 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
* that we don't know yet. If we print everything, then we can easily
* get lost with too much verbose tracing information. So those
* functions "filter" some messages. So our heuristics are still good,
* there is no more (or not that much) hardcoded linux stuff.
*)
let msg_gen is_known printer s =
if not (!Flag.filter_msg)
then printer s
else
if not (is_known s)
then printer s
let pos ii = Parse_info.string_of_info ii
(*****************************************************************************)
(* Some debugging functions *)
(*****************************************************************************)
let pr2_pp s =
if !Flag.debug_pp
then Common.pr2 ("PP-" ^ s)
let pr2_cplusplus s =
if !Flag.debug_cplusplus
then Common.pr2 ("C++-" ^ s)
let pr2_typedef s =
if !Flag.debug_typedef
then Common.pr2 ("TYPEDEF-" ^ s)
let msg_change_tok tok =
match tok with
(* mostly in parsing_hacks_define.ml *)
| TIdent_Define (_s, _ii) ->
()
| TOPar_Define (_ii) ->
()
| TCommentNewline_DefineEndOfMacro _ ->
()
(* mostly in parsing_hacks.ml *)
| TIdent_Typedef (s, ii) ->
(* todo? also do LP.add_typedef_root s ??? *)
s +> msg_gen (fun s ->
match s with
| "u_char" | "u_short" | "u_int" | "u_long"
| "u8" | "u16" | "u32" | "u64"
| "s8" | "s16" | "s32" | "s64"
| "__u8" | "__u16" | "__u32" | "__u64"
-> true
| "acpi_handle" | "acpi_status" -> true
| "FILE" | "DIR" -> true
| s when s =~ ".*_t$" -> true
| _ -> false
)
(fun s -> pr2_typedef (spf "promoting %s at %s " s (pos ii)))
(* mostly in parsing_hacks_pp.ml *)
(* cppext: *)
| TComment_Pp (directive, ii) ->
let s = PI.str_of_info ii in
(match directive, s with
| Token_cpp.CppMacro, _ ->
pr2_pp (spf "MACRO: commented at %s" (pos ii))
| Token_cpp.CppDirective, _ when s =~ "#define.*" ->
pr2_pp (spf "DEFINE: commented at %s" (pos ii));
| Token_cpp.CppDirective, _ when s =~ "#include.*" ->
pr2_pp (spf "INCLUDE: commented at %s" (pos ii));
| Token_cpp.CppDirective, _ when s =~ "#if.*" ->
pr2_pp (spf "IFDEF: commented at %s" (pos ii));
| Token_cpp.CppDirective, _ when s =~ "#undef.*" ->
pr2_pp (spf "UNDEF: commented at %s" (pos ii));
| Token_cpp.CppDirective, _ ->
pr2_pp (spf "OTHER: commented directive at %s" (pos ii));
| _ ->
(* todo? *)
()
)
| TOBrace_DefineInit ii ->
pr2_pp (spf "DEFINE: initializer at %s" (pos ii))
| TIdent_MacroString ii ->
let s = PI.str_of_info ii in
s +> msg_gen (fun s ->
match s with
| "REVISION" | "UTS_RELEASE" | "SIZE_STR" | "DMA_STR"
-> true
(* s when s =~ ".*STR.*" -> true *)
| _ -> false
)
(fun s -> pr2_pp (spf "MACRO: string-macro %s at %s " s (pos ii)))
| TIdent_MacroStmt ii ->
pr2_pp (spf "MACRO: stmt-macro at %s" (pos ii));
| TIdent_MacroDecl (s, ii) ->
s +> msg_gen (fun s ->
match s with
| "DECLARE_MUTEX" | "DECLARE_COMPLETION" | "DECLARE_RWSEM"
| "DECLARE_WAITQUEUE" | "DECLARE_WAIT_QUEUE_HEAD"
| "DEFINE_SPINLOCK" | "DEFINE_TIMER"
| "DEVICE_ATTR" | "CLASS_DEVICE_ATTR" | "DRIVER_ATTR"
| "SENSOR_DEVICE_ATTR"
| "LIST_HEAD"
| "DECLARE_WORK" | "DECLARE_TASKLET"
| "PORT_ATTR_RO" | "PORT_PMA_ATTR"
| "DECLARE_BITMAP"
-> true
(*
| s when s =~ "^DECLARE_.*" -> true
| s when s =~ ".*_ATTR$" -> true
| s when s =~ "^DEFINE_.*" -> true
| s when s =~ "NS_DECL.*" -> true
*)
| _ -> false
)
(fun _s -> pr2_pp (spf "MACRO: macro-declare at %s" (pos ii)))
| Tconst_MacroDeclConst ii ->
pr2_pp (spf "MACRO: retag const at %s" (pos ii))
| TAny_Action ii ->
pr2_pp (spf "ACTION: retag at %s" (pos ii))
| TCPar_EOL ii ->
pr2_pp (spf "MISC: retagging ) %s" (pos ii))
(* mostly in parsing_hacks_cpp.ml *)
(* c++ext: *)
| TComment_Cpp (directive, ii) ->
let s = PI.str_of_info ii in
(match directive, s with
| Token_cpp.CplusplusTemplate, _ ->
pr2_cplusplus (spf "COM-TEMPLATE: commented at %s" (pos ii))
| Token_cpp.CplusplusQualifier, _ ->
pr2_cplusplus (spf "COM-QUALIFIER: commented at %s" (pos ii))
)
| TOPar_CplusplusInit ii ->
pr2_cplusplus (spf "constructor initializer at %s" (pos ii))
| TOCro_new ii | TCCro_new ii ->
pr2_cplusplus (spf "new [] at %s" (pos ii))
| TInf_Template ii | TSup_Template ii ->
pr2_cplusplus (spf "template <> at %s" (pos ii))
| Tchar_Constr ii | Tint_Constr ii | Tfloat_Constr ii | Tdouble_Constr ii
| Tshort_Constr ii | Tlong_Constr ii | Tbool_Constr ii
| Tunsigned_Constr ii | Tsigned_Constr ii
->
pr2_cplusplus(spf "constructed object builtin at %s" (pos ii));
| TIdent_TypedefConstr (s, ii) ->
pr2_cplusplus (spf "constructed object %s at %s" s (pos ii))
| TIdent_ClassnameInQualifier (s, ii) ->
pr2_cplusplus (spf "CLASSNAME: in qualifier context %s at %s " s (pos ii))
| TIdent_Constructor (s, ii) ->
pr2_cplusplus (spf "CONSTRUCTOR: found %s at %s " s (pos ii))
| TIdent_Templatename (s, ii) ->
pr2_cplusplus (spf "TEMPLATENAME: found %s at %s" s (pos ii))
| TColCol_BeforeTypedef ii ->
pr2_typedef (spf "RECLASSIF colcol to colcol2 at %s" (pos ii))
| TIdent_ClassnameInQualifier_BeforeTypedef (s, ii) ->
pr2_typedef (spf "RECLASSIF class in qualifier %s at %s" s (pos ii))
| TIdent_TemplatenameInQualifier_BeforeTypedef (s, ii) ->
pr2_typedef (spf "RECLASSIF template in qualifier %s at %s" s (pos ii))
| _ ->
raise Todo
let msg_context t ctx =
let ctx_str =
match ctx with
| InParameter -> "InParameter"
| InArgument -> "InArgument"
| _ -> raise Impossible
in
pr2_cplusplus (spf "CONTEXT: %s at %s" ctx_str (pos (TH.info_of_tok t)))
let change_tok extended_tok tok =
msg_change_tok tok;
(* otherwise parse_c will be lost if don't find a EOF token
* why? because paren detection had a pb because of
* some ifdef-exp?
*)
if TH.is_eof extended_tok.t
then pr2 "PB: wierd, I try to tag an EOF token as something else"
else extended_tok.t <- tok
let fresh_tok tok =
msg_change_tok tok;
tok
(* normally the caller have first filtered the set of tokens to have
* a clearer "view" to work on
*)
let set_as_comment cppkind x =
assert(not (TH.is_real_comment x.t));
change_tok x (TComment_Pp (cppkind, TH.info_of_tok x.t))
(*****************************************************************************)
(* The regexp and basic view definitions *)
(*****************************************************************************)
(*
val regexp_macro: Str.regexp
val regexp_annot: Str.regexp
val regexp_declare: Str.regexp
val regexp_foreach: Str.regexp
val regexp_typedef: Str.regexp
*)
(* opti: better to built then once and for all, especially regexp_foreach *)
let regexp_macro = Str.regexp
"^[A-Z_][A-Z_0-9]*$"
(* linuxext: *)
let regexp_declare = Str.regexp
".*DECLARE.*"
(* firefoxext: *)
let regexp_ns_decl_like = Str.regexp
("\\(" ^
"NS_DECL_\\|NS_DECLARE_\\|NS_IMPL_\\|" ^
"NS_IMPLEMENT_\\|NS_INTERFACE_\\|NS_FORWARD_\\|NS_HTML_\\|" ^
"NS_DISPLAY_\\|NS_IMPL_\\|" ^
"TX_DECL_\\|DOM_CLASSINFO_\\|NS_CLASSINFO_\\|IMPL_INTERNAL_\\|" ^
"ON_\\|EVT_\\|NS_UCONV_\\|NS_GENERIC_\\|NS_COM_" ^
"\\).*")