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
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
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. *)
*)
!Config.std_h;
*)
- ]
- in
+ ] in
let need_no_changed_variables =
(* could add some of the flags of flag_parsing_c.ml *)
- []
- in
- Common.cache_computation_robust
- file ".ast_raw"
+ [] in
+ 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 () ->
+ (* check whether to clear the cache *)
+ (match (!Flag_parsing_c.cache_limit,!Flag_parsing_c.cache_prefix) with
+ (None,_) | (_,None) -> ()
+ | (Some limit,Some prefix) ->
+ let count =
+ Common.cmd_to_list
+ (Printf.sprintf
+ "test -e %s && ls %s/*.ast_raw %s/*.depend_raw | wc -l"
+ prefix prefix prefix) in
+ match count with
+ [c] ->
+ if int_of_string c >= limit
+ then
+ let _ =
+ Sys.command
+ (Printf.sprintf "/bin/rm -r %s/*.ast_raw %s/*.depend_raw"
+ prefix prefix) in
+ ()
+ | _ -> ());
+ (* recompute *)
+ parse_print_error_heuristic None None file)