You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

93 lines
4.0 KiB

(*
* Copyright (c) 2013 - present Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*)
open! Utils
(** Module for function to retrieve the location (file, line, etc) of instructions *)
let clang_to_sil_location trans_unit_ctx clang_loc =
let line = Option.default (-1) clang_loc.Clang_ast_t.sl_line in
let col = Option.default (-1) clang_loc.Clang_ast_t.sl_column in
let file = Option.map_default DB.source_file_from_abs_path
trans_unit_ctx.CFrontend_config.source_file clang_loc.Clang_ast_t.sl_file in
Location.{line; col; file}
let file_in_project file =
(* IMPORTANT: results of realpath are cached to not ruin performance *)
let real_root = realpath Config.project_root in
let real_file = realpath file in
let file_in_project = string_is_prefix real_root real_file in
let paths = Config.skip_translation_headers in
let file_should_be_skipped =
IList.exists
(fun path -> string_is_prefix (Filename.concat real_root path) real_file)
paths in
file_in_project && not (file_should_be_skipped)
let should_do_frontend_check trans_unit_ctx (loc_start, _) =
match loc_start.Clang_ast_t.sl_file with
| Some file ->
let equal_current_source file =
DB.source_file_equal (DB.source_file_from_abs_path file)
trans_unit_ctx.CFrontend_config.source_file in
equal_current_source file ||
(file_in_project file && not Config.testing_mode)
| None -> false
(** We translate by default the instructions in the current file. In C++ development, we also
translate the headers that are part of the project. However, in testing mode, we don't want to
translate the headers because the dot files in the frontend tests should contain nothing else
than the source file to avoid conflicts between different versions of the libraries. *)
let should_translate trans_unit_ctx (loc_start, loc_end) decl_trans_context ~translate_when_used =
let map_path_of pred loc =
match loc.Clang_ast_t.sl_file with
| Some f -> pred f
| None -> false
in
let map_file_of pred loc =
let path_pred path = pred (DB.source_file_from_abs_path path) in
map_path_of path_pred loc
in
(* it's not necessary to compare inodes here because both files come from
the same context - they are produced by the same invocation of ASTExporter
which uses same logic to produce both files *)
let equal_current_source = DB.source_file_equal trans_unit_ctx.CFrontend_config.source_file
in
let file_in_project = map_path_of file_in_project loc_end
|| map_path_of file_in_project loc_start in
let translate_on_demand = translate_when_used || file_in_project || Config.models_mode in
let file_in_models = map_file_of DB.source_file_is_cpp_model loc_end
|| map_file_of DB.source_file_is_cpp_model loc_start in
map_file_of equal_current_source loc_end
|| map_file_of equal_current_source loc_start
|| file_in_models
|| (Config.cxx_experimental && decl_trans_context = `Translation && translate_on_demand
&& not Config.testing_mode)
let should_translate_lib trans_unit_ctx source_range decl_trans_context ~translate_when_used =
not Config.no_translate_libs
|| should_translate trans_unit_ctx source_range decl_trans_context ~translate_when_used
let is_file_blacklisted file =
let paths = Config.skip_clang_analysis_in_path in
let is_file_blacklisted =
IList.exists
(fun path -> Str.string_match (Str.regexp ("^.*/" ^ path)) file 0)
paths in
is_file_blacklisted
let get_sil_location_from_range trans_unit_ctx source_range prefer_first =
let sloc1, sloc2 = source_range in
let sloc = if not prefer_first then sloc2 else sloc1 in
clang_to_sil_location trans_unit_ctx sloc
let get_sil_location stmt_info context =
let sloc1, _ = stmt_info.Clang_ast_t.si_source_range in
clang_to_sil_location context.CContext.translation_unit_context sloc1