(* Stats on what was passed/commentized *)
(*****************************************************************************)
-let commentized xs = xs +> Common.map_filter (function
+let commentized xs = xs +> Common.tail_map_filter (function
| Parser_c.TCommentCpp (cppkind, ii) ->
let s = Ast_c.str_of_info ii in
let legal_passing =
then begin
incr Stat.nDefinePassing;
pr2_once ("CPP-DEFINE: inside function, I treat it as comment");
- let v' = Parser_c.TCommentCpp (Token_c.CppDirective,TH.info_of_tok v)
+ let v' =
+ Parser_c.TCommentCpp (Token_c.CppDirective,TH.info_of_tok v)
+ in
+ tr.passed <- v'::tr.passed;
+ tr.rest <- Parsing_hacks.comment_until_defeol tr.rest;
+ tr.rest_clean <- Parsing_hacks.drop_until_defeol tr.rest_clean;
+ lexer_function ~pass tr lexbuf
+ end
+ else begin
+ tr.passed <- v::tr.passed;
+ tr.passed_clean <- v::tr.passed_clean;
+ v
+ end
+
+ | Parser_c.TUndef (tok) ->
+ if not (LP.current_context () =*= LP.InTopLevel) &&
+ (!Flag_parsing_c.cpp_directive_passing || (pass >= 2))
+ then begin
+ incr Stat.nUndefPassing;
+ pr2_once ("CPP-UNDEF: inside function, I treat it as comment");
+ let v' =
+ Parser_c.TCommentCpp (Token_c.CppDirective,TH.info_of_tok v)
in
tr.passed <- v'::tr.passed;
tr.rest <- Parsing_hacks.comment_until_defeol tr.rest;
end
else begin
let (v,new_tokens) =
- Parsing_hacks.tokens_include (info, includes, filename, inifdef) in
+ Parsing_hacks.tokens_include(info, includes, filename, inifdef) in
let new_tokens_clean =
new_tokens +> List.filter TH.is_not_comment in
(* Call parser *)
(* -------------------------------------------------- *)
Common.profile_code_exclusif "YACC" (fun () ->
- Left (Parser_c.celem (lexer_function ~pass tr) lexbuf_fake)
+ Left (Parser_c.celem (lexer_function ~pass tr) lexbuf_fake)
)
with e ->
LP.restore_typedef_state();
let passed_before_error = tr.passed in
let current = tr.current in
-
(* error recovery, go to next synchro point *)
let (passed', rest') =
Parsing_recovery_c.find_next_synchro tr.rest tr.passed in
let defs = Common.hash_of_list defs in
- let toks = toks +> Common.map (function
+ let toks = toks +> Common.tail_map (function
(* special cases to undo *)
| Parser_c.TMacroIterator (s, ii) ->
type info_item = string * Parser_c.token list
type program2 = toplevel2 list
- and toplevel2 = Ast_c.toplevel * info_item
+ and extended_program2 = toplevel2 list *
+ (string, Lexer_parser.identkind) Common.scoped_h_env (* type defs *) *
+ (string, Cpp_token_c.define_def) Hashtbl.t (* macro defs *)
+ and toplevel2 = Ast_c.toplevel * info_item
let program_of_program2 xs =
xs +> List.map fst
* tokens_stat record and parsing_stat record.
*)
-let parse_print_error_heuristic2 file =
+let parse_print_error_heuristic2 saved_typedefs saved_macros file =
let filelines = Common.cat_array file in
let stat = Parsing_stat.default_stat file in
(* -------------------------------------------------- *)
(* call lexer and get all the tokens *)
(* -------------------------------------------------- *)
- LP.lexer_reset_typedef();
+ LP.lexer_reset_typedef saved_typedefs;
Parsing_hacks.ifdef_paren_cnt := 0;
let toks_orig = tokens file in
(* expand macros on demand trick, preparation phase *)
let macros =
Common.profile_code "MACRO mgmt prep 1" (fun () ->
- let macros = Hashtbl.copy !_defs in
+ let macros =
+ match saved_macros with None -> Hashtbl.copy !_defs | Some h -> h in
(* include also builtins as some macros may generate some builtins too
* like __decl_spec or __stdcall
*)
in
let v = loop tr in
let v = with_program2 Parsing_consistency_c.consistency_checking v in
+ let v =
+ let new_td = ref (Common.clone_scoped_h_env !LP._typedef) in
+ Common.clean_scope_h new_td;
+ (v, !new_td, macros) in
(v, stat)
-let time_total_parsing a =
- Common.profile_code "TOTAL" (fun () -> parse_print_error_heuristic2 a)
+let time_total_parsing a b =
+ Common.profile_code "TOTAL" (fun () -> parse_print_error_heuristic2 a b)
-let parse_print_error_heuristic a =
- Common.profile_code "C parsing" (fun () -> time_total_parsing a)
+let parse_print_error_heuristic a b =
+ Common.profile_code "C parsing" (fun () -> time_total_parsing a b)
(* alias *)
-let parse_c_and_cpp a = parse_print_error_heuristic a
+let parse_c_and_cpp a =
+ let ((c,_,_),stat) = parse_print_error_heuristic None None a in (c,stat)
+let parse_c_and_cpp_keep_typedefs td macs a =
+ parse_print_error_heuristic td macs a
(*****************************************************************************)
(* Same but faster cos memoize stuff *)
(*****************************************************************************)
let parse_cache file =
- if not !Flag_parsing_c.use_cache then parse_print_error_heuristic file
+ if not !Flag_parsing_c.use_cache
+ then parse_print_error_heuristic None None file
else
- let _ = pr2 "TOFIX" in
+ let _ = pr2 "TOFIX: use_cache is not sensitive to changes in the considered macros, include files, etc" in
let need_no_changed_files =
(* should use Sys.argv.(0), would be safer. *)
(* could add some of the flags of flag_parsing_c.ml *)
[]
in
- Common.cache_computation_robust
+ Common.cache_computation_robust_in_dir
+ !Flag_parsing_c.cache_prefix
file ".ast_raw"
(need_no_changed_files, need_no_changed_variables) ".depend_raw"
- (fun () -> parse_print_error_heuristic file)
+ (fun () -> parse_print_error_heuristic None None file)