diff --git a/infer/src/backend/config.ml b/infer/src/backend/config.ml index a5f6994c7..e60e2e73f 100644 --- a/infer/src/backend/config.ml +++ b/infer/src/backend/config.ml @@ -26,6 +26,11 @@ let string_to_analyzer = ("tracing", Tracing); ("crashcontext", Crashcontext); ("linters", Linters); ("quandary", Quandary);] +let clang_frontend_action_symbols = [ + ("lint", `Lint); + ("capture", `Capture); + ("lint_and_capture", `Lint_and_capture); +] type clang_lang = C | CPP | OBJC | OBJCPP @@ -624,6 +629,12 @@ and check_duplicate_symbols = ~exes:CLOpt.[Analyze] "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 = 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 \ @@ -1366,6 +1377,16 @@ and checkers = !checkers (** should the checkers be run? *) 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_lang = !clang_lang and cluster_cmdline = !cluster @@ -1464,6 +1485,17 @@ and xcode_developer_dir = !xcode_developer_dir and xml_specs = !xml_specs 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 = IList.assoc (=) analyzer analysis_path_regex_whitelist_options diff --git a/infer/src/backend/config.mli b/infer/src/backend/config.mli index 939850e91..684f65af0 100644 --- a/infer/src/backend/config.mli +++ b/infer/src/backend/config.mli @@ -167,6 +167,10 @@ val calls_csv : outfile option val check_duplicate_symbols : bool val checkers : 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_lang : clang_lang val cluster_cmdline : string option diff --git a/infer/src/clang/cFrontend.ml b/infer/src/clang/cFrontend.ml index 542bbbd15..5bd548e0c 100644 --- a/infer/src/clang/cFrontend.ml +++ b/infer/src/clang/cFrontend.ml @@ -27,7 +27,7 @@ let compute_icfg tenv ast = Printing.log_out "\n Start creating icfg\n"; let cg = Cg.create () 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) decl_list; 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" (DB.source_file_to_string source_file); (* 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; (* This part below is a boilerplate in every frontends. *) (* This could be moved in the cfg_infer module *) diff --git a/infer/src/clang/cFrontend_checkers_main.ml b/infer/src/clang/cFrontend_checkers_main.ml index b9fb542b0..8a9ec260b 100644 --- a/infer/src/clang/cFrontend_checkers_main.ml +++ b/infer/src/clang/cFrontend_checkers_main.ml @@ -74,6 +74,7 @@ let store_issues source_file = LintIssues.store_issues lint_issues_file !LintIssues.errLogMap 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 | Clang_ast_t.TranslationUnitDecl(_, decl_list, _, _) -> 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 IList.iter (do_frontend_checks_decl context cfg cg) allowed_decls; (* TODO (t12740727): Remove condition once the transition to linters mode is finished *) - if Config.analyzer = Some Config.Linters && (LintIssues.exists_issues ()) then - store_issues source_file + if Config.clang_frontend_action = `Lint && (LintIssues.exists_issues ()) then + 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 *) diff --git a/infer/src/clang/cFrontend_errors.ml b/infer/src/clang/cFrontend_errors.ml index 44d00e7d1..b87f24064 100644 --- a/infer/src/clang/cFrontend_errors.ml +++ b/infer/src/clang/cFrontend_errors.ml @@ -80,7 +80,7 @@ let get_err_log cfg cg method_decl_opt loc = let procname = match method_decl_opt with | Some method_decl -> General_utils.procname_of_decl method_decl | 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 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 diff --git a/infer/src/clang/cMain.ml b/infer/src/clang/cMain.ml index 4d9217e58..ec5798ae2 100644 --- a/infer/src/clang/cMain.ml +++ b/infer/src/clang/cMain.ml @@ -56,7 +56,9 @@ let do_run source_path ast_path = CFrontend_config.json := ast_filename; CLocation.check_source_file source_path; 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; Printf.printf "End translation AST file %s... OK!\n" !CFrontend_config.json; print_elapsed ();