[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. * necessarily the same as the translation unit's source file.
*) *)
MF.monospaced_to_string 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 L.die InternalError "helper function %s is unknown" ph

@ -1468,6 +1468,16 @@ let is_init_expr_cxx11_constant an =
false 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 is_in_source_file an path_re =
let src_file = Ctl_parser_types.get_source_file an in source_file_matches (Ctl_parser_types.get_source_file an) path_re
ALVar.compare_str_with_alexp (SourceFile.to_rel_path (SourceFile.create src_file)) 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. * 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 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 * 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 CPredicates.cxx_construct_expr_has_no_parameters an
| "is_in_source_file", [path_re], an -> | "is_in_source_file", [path_re], an ->
CPredicates.is_in_source_file an path_re 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 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 match Clang_ast_proj.get_var_decl_tuple decl with
| Some (_, ndi, _, {vdi_is_global= false}) -> | Some (_, ndi, _, {vdi_is_global= false}) ->
ndi.ni_name ndi.ni_name
| _ -> ( | _ ->
match Clang_ast_proj.get_named_decl_tuple decl with Option.value_map
| Some (_, ndi) -> ~f:(fun (_, ndi) -> "::" ^ String.concat ~sep:"::" (List.rev ndi.Clang_ast_t.ni_qual_name))
"::" ^ String.concat ~sep:"::" (List.rev ndi.ni_qual_name) ~default:""
| None -> (Clang_ast_proj.get_named_decl_tuple decl)
"" )
let ast_node_cxx_fully_qualified_name an = let ast_node_cxx_fully_qualified_name an =
@ -97,22 +96,16 @@ let ast_node_cxx_fully_qualified_name an =
match an with match an with
| Decl decl -> | Decl decl ->
decl_cxx_fully_qualified_name decl decl_cxx_fully_qualified_name decl
| Stmt (DeclRefExpr (_, _, _, {drti_decl_ref= Some dr})) -> ( | Stmt (DeclRefExpr (_, _, _, {drti_decl_ref= Some dr})) ->
match CAst_utils.get_decl dr.dr_decl_pointer with Option.value_map ~f:decl_cxx_fully_qualified_name ~default:""
| Some decl -> (CAst_utils.get_decl dr.dr_decl_pointer)
decl_cxx_fully_qualified_name decl | Stmt stmt ->
| None -> Option.value_map
"" ) ~f:(fun (_, _, _, xcei) ->
| Stmt stmt -> ( Option.value_map ~f:decl_cxx_fully_qualified_name ~default:""
match Clang_ast_proj.get_cxx_construct_expr_tuple stmt with (CAst_utils.get_decl xcei.xcei_decl_ref.dr_decl_pointer) )
| Some (_, _, _, xcei) -> ( ~default:""
match CAst_utils.get_decl xcei.xcei_decl_ref.dr_decl_pointer with (Clang_ast_proj.get_cxx_construct_expr_tuple stmt)
| Some decl ->
decl_cxx_fully_qualified_name decl
| None ->
"" )
| None ->
"" )
let ast_node_kind node = let ast_node_kind node =
@ -622,11 +615,30 @@ let get_source_range an =
decl_info.di_source_range decl_info.di_source_range
let get_source_file an = let get_source_file_of_range (range : Clang_ast_t.source_range) =
match get_source_range an with match range with {sl_file= Some sf}, _ | _, {sl_file= Some sf} -> Some sf | _ -> None
| {sl_file= Some sf}, _ ->
sf
| _, {sl_file= Some sf} -> let get_source_file an = get_source_file_of_range (get_source_range an)
sf
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 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, 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_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_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_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, 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, [] 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 report_when = NOT is_decl() AND has_cxx_fully_qualified_name_in_custom_symbols("test");
SET message = "found usage of %cxx_fully_qualified_name%"; 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" #include "test_included.h"
struct Bazowey { struct Bazowey {
void frazzle(); void frazzle() { Bazoo().fibble(); }
}; };

Loading…
Cancel
Save