Add an option clang-frontend-action to drive the frontend into capture or linters when the -a capture option is used

Reviewed By: jberdine

Differential Revision: D3828294

fbshipit-source-id: 6b471e5
master
Dulma Churchill 8 years ago committed by Facebook Github Bot 5
parent 27cfb141da
commit f99d3a7c8e

@ -26,6 +26,11 @@ let string_to_analyzer =
("tracing", Tracing); ("crashcontext", Crashcontext); ("linters", Linters); ("tracing", Tracing); ("crashcontext", Crashcontext); ("linters", Linters);
("quandary", Quandary);] ("quandary", Quandary);]
let clang_frontend_action_symbols = [
("lint", `Lint);
("capture", `Capture);
("lint_and_capture", `Lint_and_capture);
]
type clang_lang = C | CPP | OBJC | OBJCPP type clang_lang = C | CPP | OBJC | OBJCPP
@ -624,6 +629,12 @@ and check_duplicate_symbols =
~exes:CLOpt.[Analyze] ~exes:CLOpt.[Analyze]
"Check if a symbol with the same name is defined in more than one file." "Check if a symbol with the same name is defined in more than one file."
and clang_frontend_action =
CLOpt.mk_symbol_opt ~long:"clang-frontend-action"
~exes:CLOpt.[Clang]
"Specify whether the clang frontend should capture or lint or both."
~symbols:clang_frontend_action_symbols
and clang_include_to_override = and clang_include_to_override =
CLOpt.mk_string_opt ~long:"clang-include-to-override" ~meta:"dir" CLOpt.mk_string_opt ~long:"clang-include-to-override" ~meta:"dir"
"Use this option in the uncommon case where the normal compilation process overrides the \ "Use this option in the uncommon case where the normal compilation process overrides the \
@ -1366,6 +1377,16 @@ and checkers = !checkers
(** should the checkers be run? *) (** should the checkers be run? *)
and checkers_enabled = not (!eradicate || !crashcontext || !quandary) and checkers_enabled = not (!eradicate || !crashcontext || !quandary)
(* TODO (t12740727): Remove this variable once the transition to linters mode is finished *)
and clang_frontend_action =
match !clang_frontend_action with
| Some clang_frontend_action ->
clang_frontend_action
| None ->
match !analyzer with
| Some Linters -> `Lint
| Some Infer -> `Capture
| _ -> `Lint_and_capture
and clang_include_to_override = !clang_include_to_override and clang_include_to_override = !clang_include_to_override
and clang_lang = !clang_lang and clang_lang = !clang_lang
and cluster_cmdline = !cluster and cluster_cmdline = !cluster
@ -1464,6 +1485,17 @@ and xcode_developer_dir = !xcode_developer_dir
and xml_specs = !xml_specs and xml_specs = !xml_specs
and zip_libraries = !zip_libraries and zip_libraries = !zip_libraries
let clang_frontend_do_capture, clang_frontend_do_lint =
match clang_frontend_action with
| `Lint -> false, true
| `Capture -> true, false
| `Lint_and_capture -> true, true
let clang_frontend_action_string =
String.concat " and "
((if clang_frontend_do_capture then ["translating"] else [])
@ (if clang_frontend_do_lint then ["linting"] else []))
let analysis_path_regex_whitelist analyzer = let analysis_path_regex_whitelist analyzer =
IList.assoc (=) analyzer analysis_path_regex_whitelist_options IList.assoc (=) analyzer analysis_path_regex_whitelist_options

@ -167,6 +167,10 @@ val calls_csv : outfile option
val check_duplicate_symbols : bool val check_duplicate_symbols : bool
val checkers : bool val checkers : bool
val checkers_enabled : bool val checkers_enabled : bool
val clang_frontend_action : [`Lint | `Capture | `Lint_and_capture ]
val clang_frontend_action_string : string
val clang_frontend_do_capture : bool
val clang_frontend_do_lint : bool
val clang_include_to_override : string option val clang_include_to_override : string option
val clang_lang : clang_lang val clang_lang : clang_lang
val cluster_cmdline : string option val cluster_cmdline : string option

@ -27,7 +27,7 @@ let compute_icfg tenv ast =
Printing.log_out "\n Start creating icfg\n"; Printing.log_out "\n Start creating icfg\n";
let cg = Cg.create () in let cg = Cg.create () in
let cfg = Cfg.Node.create_cfg () in let cfg = Cfg.Node.create_cfg () in
if Config.analyzer <> Some Config.Linters then if Config.clang_frontend_do_capture then
IList.iter (CFrontend_declImpl.translate_one_declaration tenv cg cfg `DeclTraversal) IList.iter (CFrontend_declImpl.translate_one_declaration tenv cg cfg `DeclTraversal)
decl_list; decl_list;
Printing.log_out "\n Finished creating icfg\n"; Printing.log_out "\n Finished creating icfg\n";
@ -62,7 +62,7 @@ let do_source_file source_file ast =
Printing.log_out "\n End building call/cfg graph for '%s'.\n" Printing.log_out "\n End building call/cfg graph for '%s'.\n"
(DB.source_file_to_string source_file); (DB.source_file_to_string source_file);
(* TODO (t12740727): Move this call to cMain once the transition to linters mode is finished *) (* TODO (t12740727): Move this call to cMain once the transition to linters mode is finished *)
if Config.analyzer <> Some Config.Infer then if Config.clang_frontend_do_lint then
CFrontend_checkers_main.do_frontend_checks cfg call_graph source_file ast; CFrontend_checkers_main.do_frontend_checks cfg call_graph source_file ast;
(* This part below is a boilerplate in every frontends. *) (* This part below is a boilerplate in every frontends. *)
(* This could be moved in the cfg_infer module *) (* This could be moved in the cfg_infer module *)

@ -74,6 +74,7 @@ let store_issues source_file =
LintIssues.store_issues lint_issues_file !LintIssues.errLogMap LintIssues.store_issues lint_issues_file !LintIssues.errLogMap
let do_frontend_checks cfg cg source_file ast = let do_frontend_checks cfg cg source_file ast =
Printing.log_stats "Start linting file %s\n" (DB.source_file_to_string source_file);
match ast with match ast with
| Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) -> | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) ->
let context = context_with_ck_set CLintersContext.empty decl_list in let context = context_with_ck_set CLintersContext.empty decl_list in
@ -83,6 +84,7 @@ let do_frontend_checks cfg cg source_file ast =
let allowed_decls = IList.filter is_decl_allowed decl_list in let allowed_decls = IList.filter is_decl_allowed decl_list in
IList.iter (do_frontend_checks_decl context cfg cg) allowed_decls; IList.iter (do_frontend_checks_decl context cfg cg) allowed_decls;
(* TODO (t12740727): Remove condition once the transition to linters mode is finished *) (* TODO (t12740727): Remove condition once the transition to linters mode is finished *)
if Config.analyzer = Some Config.Linters && (LintIssues.exists_issues ()) then if Config.clang_frontend_action = `Lint && (LintIssues.exists_issues ()) then
store_issues source_file store_issues source_file;
Printing.log_stats "End linting file %s\n" (DB.source_file_to_string source_file)
| _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *) | _ -> assert false (* NOTE: Assumes that an AST alsways starts with a TranslationUnitDecl *)

@ -80,7 +80,7 @@ let get_err_log cfg cg method_decl_opt loc =
let procname = match method_decl_opt with let procname = match method_decl_opt with
| Some method_decl -> General_utils.procname_of_decl method_decl | Some method_decl -> General_utils.procname_of_decl method_decl
| None -> General_utils.get_procname_for_frontend_checks loc in | None -> General_utils.get_procname_for_frontend_checks loc in
if Config.analyzer = Some Config.Linters then if Config.clang_frontend_action = `Lint then
LintIssues.get_err_log procname LintIssues.get_err_log procname
else (* TODO (t12740727): Remove this branch once the transition to linters mode is finished *) else (* TODO (t12740727): Remove this branch once the transition to linters mode is finished *)
let pdesc = CMethod_trans.get_method_for_frontend_checks cfg cg loc in let pdesc = CMethod_trans.get_method_for_frontend_checks cfg cg loc in

@ -56,7 +56,9 @@ let do_run source_path ast_path =
CFrontend_config.json := ast_filename; CFrontend_config.json := ast_filename;
CLocation.check_source_file source_path; CLocation.check_source_file source_path;
let source_file = CLocation.source_file_from_path source_path in let source_file = CLocation.source_file_from_path source_path in
Printf.printf "Start translation of AST from %s\n" !CFrontend_config.json; Printing.log_stats "Clang frontend action is %s\n" Config.clang_frontend_action_string;
Printf.printf "Start %s of AST from %s\n" Config.clang_frontend_action_string
!CFrontend_config.json;
CFrontend.do_source_file source_file ast_decl; CFrontend.do_source_file source_file ast_decl;
Printf.printf "End translation AST file %s... OK!\n" !CFrontend_config.json; Printf.printf "End translation AST file %s... OK!\n" !CFrontend_config.json;
print_elapsed (); print_elapsed ();

Loading…
Cancel
Save