[AL] expose source loc of decl referenced by decl_ref

Reviewed By: ddino

Differential Revision: D14404449

fbshipit-source-id: e546600bd
master
David Lively 6 years ago committed by Facebook Github Bot
parent ead4c44f9d
commit 5aedc7e71c

@ -136,7 +136,16 @@ let evaluate_place_holder context ph an =
* necessarily the same as the translation unit's source file.
*)
MF.monospaced_to_string
(SourceFile.to_rel_path (SourceFile.create (Ctl_parser_types.get_source_file an)))
(Option.value_map
~f:(fun sf -> SourceFile.to_rel_path (SourceFile.create sf))
~default:""
(Ctl_parser_types.get_source_file an))
| "%ref_source_file%" ->
MF.monospaced_to_string
(Option.value_map
~f:(fun sf -> SourceFile.to_rel_path (SourceFile.create sf))
~default:""
(Ctl_parser_types.get_referenced_decl_source_file an))
| _ ->
L.die InternalError "helper function %s is unknown" ph

@ -1468,6 +1468,16 @@ let is_init_expr_cxx11_constant an =
false
let source_file_matches src_file path_re =
Option.value_map
~f:(fun sf ->
ALVar.compare_str_with_alexp (SourceFile.to_rel_path (SourceFile.create sf)) path_re )
~default:false src_file
let is_in_source_file an path_re =
let src_file = Ctl_parser_types.get_source_file an in
ALVar.compare_str_with_alexp (SourceFile.to_rel_path (SourceFile.create src_file)) path_re
source_file_matches (Ctl_parser_types.get_source_file an) path_re
let is_referencing_decl_from_source_file an path_re =
source_file_matches (Ctl_parser_types.get_referenced_decl_source_file an) path_re

@ -502,6 +502,11 @@ val is_in_source_file : Ctl_parser_types.ast_node -> ALVar.alexp -> bool
* True iff the source file path of the given node matches the given regexp or string.
*)
val is_referencing_decl_from_source_file : Ctl_parser_types.ast_node -> ALVar.alexp -> bool
(**
* True iff the given node is a DeclRefExpr referencing a decl whose source file path matches the given regexp or string.
*)
val is_cxx_method_overriding : Ctl_parser_types.ast_node -> ALVar.alexp option -> bool
(**
* True iff the current node is a CXXMethodDecl node and is overriding a

@ -1171,6 +1171,8 @@ let rec eval_Atomic pred_name_ args an lcxt =
CPredicates.cxx_construct_expr_has_no_parameters an
| "is_in_source_file", [path_re], an ->
CPredicates.is_in_source_file an path_re
| "is_referencing_decl_from_source_file", [path_re], an ->
CPredicates.is_referencing_decl_from_source_file an path_re
| _ ->
L.(die ExternalError) "Undefined Predicate or wrong set of arguments: '%s'" pred_name

@ -84,12 +84,11 @@ let decl_cxx_fully_qualified_name (decl : Clang_ast_t.decl) =
match Clang_ast_proj.get_var_decl_tuple decl with
| Some (_, ndi, _, {vdi_is_global= false}) ->
ndi.ni_name
| _ -> (
match Clang_ast_proj.get_named_decl_tuple decl with
| Some (_, ndi) ->
"::" ^ String.concat ~sep:"::" (List.rev ndi.ni_qual_name)
| None ->
"" )
| _ ->
Option.value_map
~f:(fun (_, ndi) -> "::" ^ String.concat ~sep:"::" (List.rev ndi.Clang_ast_t.ni_qual_name))
~default:""
(Clang_ast_proj.get_named_decl_tuple decl)
let ast_node_cxx_fully_qualified_name an =
@ -97,22 +96,16 @@ let ast_node_cxx_fully_qualified_name an =
match an with
| Decl decl ->
decl_cxx_fully_qualified_name decl
| Stmt (DeclRefExpr (_, _, _, {drti_decl_ref= Some dr})) -> (
match CAst_utils.get_decl dr.dr_decl_pointer with
| Some decl ->
decl_cxx_fully_qualified_name decl
| None ->
"" )
| Stmt stmt -> (
match Clang_ast_proj.get_cxx_construct_expr_tuple stmt with
| Some (_, _, _, xcei) -> (
match CAst_utils.get_decl xcei.xcei_decl_ref.dr_decl_pointer with
| Some decl ->
decl_cxx_fully_qualified_name decl
| None ->
"" )
| None ->
"" )
| Stmt (DeclRefExpr (_, _, _, {drti_decl_ref= Some dr})) ->
Option.value_map ~f:decl_cxx_fully_qualified_name ~default:""
(CAst_utils.get_decl dr.dr_decl_pointer)
| Stmt stmt ->
Option.value_map
~f:(fun (_, _, _, xcei) ->
Option.value_map ~f:decl_cxx_fully_qualified_name ~default:""
(CAst_utils.get_decl xcei.xcei_decl_ref.dr_decl_pointer) )
~default:""
(Clang_ast_proj.get_cxx_construct_expr_tuple stmt)
let ast_node_kind node =
@ -622,11 +615,30 @@ let get_source_range an =
decl_info.di_source_range
let get_source_file an =
match get_source_range an with
| {sl_file= Some sf}, _ ->
sf
| _, {sl_file= Some sf} ->
sf
let get_source_file_of_range (range : Clang_ast_t.source_range) =
match range with {sl_file= Some sf}, _ | _, {sl_file= Some sf} -> Some sf | _ -> None
let get_source_file an = get_source_file_of_range (get_source_range an)
let get_decl_source_file an =
let di = Clang_ast_proj.get_decl_tuple an in
Option.value_map ~f:(fun x -> Some x) ~default:None (get_source_file_of_range di.di_source_range)
let get_decl_ref_source_file (dr : Clang_ast_t.decl_ref) =
Option.value_map ~f:get_decl_source_file ~default:None (CAst_utils.get_decl dr.dr_decl_pointer)
let get_referenced_decl_source_file an =
let open Clang_ast_t in
match an with
| Stmt (DeclRefExpr (_, _, _, {drti_decl_ref= Some dr})) ->
get_decl_ref_source_file dr
| Stmt stmt ->
Option.value_map
~f:(fun (_, _, _, xcei) -> get_decl_ref_source_file xcei.xcei_decl_ref)
~default:None
(Clang_ast_proj.get_cxx_construct_expr_tuple stmt)
| _ ->
assert false
None

@ -84,4 +84,6 @@ val c_type_equal : Clang_ast_t.c_type -> abs_ctype -> bool
val abs_ctype_to_string : abs_ctype -> string
val get_source_file : ast_node -> Clang_ast_t.source_file
val get_source_file : ast_node -> Clang_ast_t.source_file option
val get_referenced_decl_source_file : ast_node -> Clang_ast_t.source_file option

@ -11,6 +11,7 @@ codetoanalyze/cpp/linters-for-test-only/test_fully_qualified_names.cpp, Linters_
codetoanalyze/cpp/linters-for-test-only/test_fully_qualified_names.cpp, Linters_dummy_method, 28, FIND_NODES_WITH_CXX_FULL_NAME, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_fully_qualified_names.cpp, Linters_dummy_method, 39, FIND_NODES_WITH_CXX_FULL_NAME, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_included.h, Bazoo_fibble, 11, FIND_CXX_METHODS_FROM_HEADER_FILE, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_includer.cpp, Bazowey_frazzle, 11, FIND_REF_FROM_SRC_FILE, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, B_bar, 16, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, B_foo, 14, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []
codetoanalyze/cpp/linters-for-test-only/test_overrides.cpp, Foo::Bar::SvIf_async_tm_poke, 36, FIND_CXX_METHOD_OVERRIDES, no_bucket, WARNING, []

@ -53,3 +53,8 @@ DEFINE-CHECKER FIND_LISTED_SYMBOLS = {
SET report_when = NOT is_decl() AND has_cxx_fully_qualified_name_in_custom_symbols("test");
SET message = "found usage of %cxx_fully_qualified_name%";
};
DEFINE-CHECKER FIND_REF_FROM_SRC_FILE = {
SET report_when = is_referencing_decl_from_source_file(REGEXP("/test_included.h$"));
SET message = "found ref from %ref_source_file%";
};

@ -8,5 +8,5 @@
#include "test_included.h"
struct Bazowey {
void frazzle();
void frazzle() { Bazoo().fibble(); }
};

Loading…
Cancel
Save