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.
94 lines
3.4 KiB
94 lines
3.4 KiB
(*
|
|
* Copyright (c) Facebook, Inc. and its affiliates.
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*)
|
|
open! IStd
|
|
|
|
(* Builds a clang procedure, following the format required to match with profiler samples:
|
|
C Functions: name, mangled name optional
|
|
ObjC Methods: mangled_name
|
|
ObjC Blocks: mangled_name
|
|
C++ methods: mangled_name (For us mangled name is optional, but if it is not there then we can't match the method) *)
|
|
let clang_proc_of_decl decl =
|
|
let open Clang_ast_t in
|
|
match decl with
|
|
| ObjCMethodDecl (_, _, omdi) ->
|
|
Some (ClangProc.ObjcMethod {mangled_name= omdi.Clang_ast_t.omdi_mangled_name})
|
|
| BlockDecl (_, bdi) ->
|
|
Some (ClangProc.ObjcBlock {mangled_name= bdi.Clang_ast_t.bdi_mangled_name})
|
|
| FunctionDecl (_, named_decl_info, _, fdi) ->
|
|
Some
|
|
(ClangProc.CFunction
|
|
{ name= named_decl_info.Clang_ast_t.ni_name
|
|
; mangled_name= fdi.Clang_ast_t.fdi_mangled_name })
|
|
| CXXConversionDecl (_, _, _, fdi, _)
|
|
| CXXMethodDecl (_, _, _, fdi, _)
|
|
| CXXConstructorDecl (_, _, _, fdi, _)
|
|
| CXXDestructorDecl (_, _, _, fdi, _) -> (
|
|
match fdi.Clang_ast_t.fdi_mangled_name with
|
|
| Some mangled_name ->
|
|
Some (ClangProc.CppMethod {mangled_name})
|
|
| None ->
|
|
None )
|
|
| _ ->
|
|
None
|
|
|
|
|
|
let rec process_block_decls_in_stmts default_source_file ast_range stmts =
|
|
let open Clang_ast_t in
|
|
let process_decls_in_stmt ast_range stmt =
|
|
let _, stmts = Clang_ast_proj.get_stmt_tuple stmt in
|
|
let ast_range' = process_block_decls_in_stmts default_source_file ast_range stmts in
|
|
match stmt with
|
|
| BlockExpr (_, _, _, decl) ->
|
|
process_proc_decl default_source_file ast_range' decl
|
|
| _ ->
|
|
ast_range'
|
|
in
|
|
List.fold ~f:process_decls_in_stmt ~init:ast_range stmts
|
|
|
|
|
|
and process_proc_decl default_source_file ast_range decl =
|
|
let open Clang_ast_t in
|
|
match decl with
|
|
| ObjCMethodDecl (di, _, _)
|
|
| CXXConversionDecl (di, _, _, _, _)
|
|
| FunctionDecl (di, _, _, _)
|
|
| CXXMethodDecl (di, _, _, _, _)
|
|
| CXXConstructorDecl (di, _, _, _, _)
|
|
| CXXDestructorDecl (di, _, _, _, _)
|
|
| BlockDecl (di, _) -> (
|
|
let range = CLocation.location_of_decl_info default_source_file di in
|
|
let procname = CType_decl.CProcname.from_decl decl in
|
|
let clang_proc = clang_proc_of_decl decl in
|
|
let ast_range' = Procname.Map.add procname (range, clang_proc) ast_range in
|
|
match CAst_utils.get_method_body_opt decl with
|
|
| Some stmt ->
|
|
process_block_decls_in_stmts default_source_file ast_range' [stmt]
|
|
| None ->
|
|
ast_range' )
|
|
| _ -> (
|
|
match Clang_ast_proj.get_decl_context_tuple decl with
|
|
| Some (decls, _) ->
|
|
List.fold ~f:(process_proc_decl default_source_file) ~init:ast_range decls
|
|
| None ->
|
|
ast_range )
|
|
|
|
|
|
let process_ast ast default_source_file =
|
|
let open Clang_ast_t in
|
|
match ast with
|
|
| TranslationUnitDecl (_, decl_list, _, _) ->
|
|
List.fold decl_list ~init:Procname.Map.empty ~f:(fun map decl ->
|
|
let info = Clang_ast_proj.get_decl_tuple decl in
|
|
let source_range = info.di_source_range in
|
|
if
|
|
CLocation.should_translate_lib default_source_file source_range `DeclTraversal
|
|
~translate_when_used:true
|
|
then process_proc_decl default_source_file map decl
|
|
else map )
|
|
| _ ->
|
|
assert false
|