CodeSonar C++ API
[For improved navigation, enable JavaScript.]
cs_procedure_decl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023, an unpublished work by CodeSecure, Inc.
3  * ALL RIGHTS RESERVED
4  *
5  * Copyright (c) 2013-2023, an unpublished work by GrammaTech, Inc.
6  * ALL RIGHTS RESERVED
7  *
8  * This software is furnished under a license and may be used and
9  * copied only in accordance with the terms of such license and the
10  * inclusion of the above copyright notice. This software or any
11  * other copies thereof may not be provided or otherwise made
12  * available to any other person. Title to and ownership of the
13  * software is retained by CodeSecure, Inc.
14  */
15 
16 #ifndef CS_PROCEDURE_DECL_HPP
17 #define CS_PROCEDURE_DECL_HPP
18 
19 #include "cs_procedure_fwd.hpp"
20 #include "cs_point_decl.hpp"
21 #include "cs_basic_block_set_decl.hpp"
22 #include "cs_ast_decl.hpp"
23 #include "cs_sfileinst_decl.hpp"
24 #include "cs_compunit_decl.hpp"
25 
28 namespace cs{
29  class procedure_locals_iterator_policy{
30  public:
31  typedef cs_pdg_locals_iter iterator_impl;
32  typedef symbol key;
33  typedef cs_pdg ctype;
34 
35  static cs_result iter_first(
36  const ctype &container,
37  cglue<key>::ctype *val,
38  iterator_impl *it)
39  { return cs_pdg_locals_iter_first( container, val, it ); }
40  static cs_result iter_next(
41  const ctype &container,
42  cglue<key>::ctype *val,
43  iterator_impl *it)
44  { return cs_pdg_locals_iter_next( val, it ); }
45  static cs_result iter_close(iterator_impl *it)
46  { return cs_pdg_locals_iter_close( it ); }
47  static const char *name()
48  { return "procedure_locals_iterator"; }
49  };
50 
60  CS_FLAGS_BOILERPLATE(procedure_call_sites_flags,
61  cs_pdg_call_sites_flags,
62  cs_pcsf_all,
63  "direct",
64  "indirect");
67 
72 
78 
79  };
80  CS_FLAGS_BOILERPLATE_FRIENDS(procedure_call_sites_flags,
81  friend class procedure;,
83  )
84 #ifdef CS_CPP_IMPL
88 #endif
89 
90  class procedure_call_sites_iterator_policy{
91  public:
92  typedef cs_pdg_call_sites_iter iterator_impl;
93  typedef point key;
94 #ifndef SWIG
95  struct ctype
96  {
97  cs_pdg pdg;
98  cs_pdg_call_sites_flags flags;
99  ctype(cs_pdg _pdg, cs_pdg_call_sites_flags _flags)
100  : pdg(_pdg), flags(_flags){}
101  };
102 #endif
103 
104  static cs_result iter_first(
105  ctype container,
106  cglue<key>::ctype *val,
107  iterator_impl *it)
108  { return cs_pdg_call_sites_iter_first( container.pdg, container.flags, val, it ); }
109  static cs_result iter_next(
110  ctype container,
111  cglue<key>::ctype *val,
112  iterator_impl *it)
113  { return cs_pdg_call_sites_iter_next( val, it ); }
114  static cs_result iter_close(iterator_impl *it)
115  { return cs_pdg_call_sites_iter_close( it ); }
116  static const char *name()
117  { return "procedure_call_sites_iterator"; }
118  };
119 
120  class procedure_callers_iterator_policy{
121  public:
122  typedef cs_pdg_callers_iter iterator_impl;
123  typedef point key;
124  typedef cs_pdg ctype;
125 
126  static cs_result iter_first(
127  ctype container,
128  cglue<key>::ctype *val,
129  iterator_impl *it)
130  { return cs_pdg_callers_iter_first( container, val, it ); }
131  static cs_result iter_next(
132  ctype container,
133  cglue<key>::ctype *val,
134  iterator_impl *it)
135  { return cs_pdg_callers_iter_next( val, it ); }
136  static cs_result iter_close(iterator_impl *it)
137  { return cs_pdg_callers_iter_close( it ); }
138  static const char *name()
139  { return "procedure_callers_iterator"; }
140  };
141 
142  class procedure_adjusted_callers_iterator_policy;
143 
144 
168  class procedure{
174  CS_IR_BOILERPLATE(procedure);
175 
194  csuint64 stable_hash() const
195  {
196  return cs_pdg_stable_hash(inner);
197  }
198 
221  int stable_cmp(const procedure& other) const
222  {
223  return cs_pdg_stable_compare(inner, other.inner);
224  }
225 
232  procedure_kind get_kind() const
233  { return cglue<procedure_kind>::wrap(cs_pdg_get_kind(inner)); }
234 
235 
236 #if 0
237  /* This is redundant; use get_compunit().normalized_name() */
238  std::string normalized_compilation_unit() const
239  {
240  string_scratchpad::
241  to_string_functor1_limit<procedure, cs_pdg_normalized_compilation_unit>
242  functor(inner, -1);
243  return string_scratchpad::to_string(functor);
244  }
245 
246  /* This is redundant; use get_compunit().name() */
247  std::string compilation_unit() const
248  {
249  string_scratchpad::
250  to_string_functor1_limit<
251  procedure, cs_pdg_compilation_unit>
252  functor(inner, -1);
253  return string_scratchpad::to_string(functor);
254  }
255 
256 #endif
257 
273  ast get_ast(ast_family family = ast_family::DEFAULT) const
274  {
275  cs_ast rv;
276  check(cs_pdg_ast(inner, cglue<ast_family>::unwrap(family), &rv));
277  return ast::;
278  }
279 
292  void set_ast(ast_family family, ast val)
293  {
294  check(cs_pdg_set_ast(inner, cglue<ast_family>::unwrap(family),
295  cglue<ast>::unwrap(val)));
296  }
313  {
314  cs_sfid rvs;
315  cs_line rvl;
316  check(cs_pdg_file_line(inner, &rvs, &rvl));
317  return sfileinst_line_pair(sfileinst::, rvl);
318  }
319 
320 
326  symbol get_symbol() const;
327 
328 
334  compunit get_compunit() const
335  {
336  cs_uid rv;
337  check(cs_pdg_compilation_uid(inner, &rv));
338  return compunit::;
339  }
340 
351  point entry_point() const
352  {
353  cs_pdg_vertex rv;
354  check(cs_pdg_entry_vertex(inner, &rv));
355  return point::;
356  }
357 
372  point preexit_point() const
373  {
374  cs_pdg_vertex rv;
375  check(cs_pdg_preexit_vertex(inner, &rv));
376  return point::;
377  }
378 
393  point exit_point() const
394  {
395  cs_pdg_vertex rv;
396  check(cs_pdg_exit_vertex(inner, &rv));
397  return point::;
398  }
399 
400 
419  csint64 id() const
420  { return cs_pdg_procedure_id(inner); }
421 
422 
450  std::string verbose_name() const
451  { return cs_pdg_string(inner); }
452 
453 
474  std::string name() const
475  {
476  string_scratchpad::
477  to_string_functor1_limit<procedure, cs_pdg_friendly_name>
478  functor(inner, -1);
479  return string_scratchpad::to_string(functor);
480  }
481 
507  std::string basename() const
508  {
509  string_scratchpad::
510  to_string_functor1_limit<procedure, cs_pdg_basename>
511  functor(inner, -1);
512  return string_scratchpad::to_string(functor);
513  }
514 
529  std::string demangled_name() const
530  {
531  string_scratchpad::
532  to_string_functor1_limit<procedure, cs_pdg_demangled_name>
533  functor(inner, -1);
534  return string_scratchpad::to_string(functor);
535  }
536 
546  point_set points() const
547  {
548  cs_const_pdg_vertex_set rv;
549  check(cs_pdg_vertices(inner, &rv));
550  return cglue<point_set>::wrap(rv, true);
551  }
552 
569  { return procedure_locals_iterator(inner); }
570 
571 
593  std::vector<symbol> declared_symbols() const
594  {
595  typedef scratchpad<symbol> sp;
596  sp::to_vector_functor1<procedure, cs_pdg_declarations>
597  functor(inner);
598  return sp::to_vector(functor);
599  }
620  symbol find_symbol_by_offset(csint32 off) const
621  {
622  cs_abs_loc rv;
623  check(cs_pdg_off_to_abs_loc(inner, off, &rv));
624  return symbol::;
625  }
626 
627 
645  symbol find_containing_symbol_by_offset(csint32 off) const
646  {
647  cs_abs_loc rv;
648  check(cs_pdg_off_to_containing_abs_loc(inner, off, &rv));
649  return symbol::;
650  }
651 
672  point add_declaration(symbol al);
702  std::vector<point> call_sites_vector(
704  {
705  typedef scratchpad<point> sp;
706  sp::to_vector_functor2<procedure, cs_pdg_call_sites_flags, cs_pdg_call_sites>
707  functor(inner, cglue<procedure_call_sites_flags>::unwrap(flags));
708  return sp::to_vector(functor);
709  }
710 
711 
736  size_t call_sites_count(
738  { return cs_pdg_call_sites_count(inner, cglue<procedure_call_sites_flags>::unwrap(flags)); }
739 
740 
762  procedure_call_sites_iterator call_sites(
763  procedure_call_sites_flags flags = procedure_call_sites_flags::DIRECT) const
764  {
765  return procedure_call_sites_iterator(
766  procedure_call_sites_iterator_policy::ctype(
767  inner, cglue<procedure_call_sites_flags>::unwrap(flags)));
768  }
769 
770 
780  size_t callers_count() const
781  { return cs_pdg_callers_count(inner); }
782 
783 
795  procedure_callers_iterator callers() const
796  { return procedure_callers_iterator(inner); }
797 
798 
817  point_set formal_ins() const
818  {
819  cs_pdg_vertex_set rv;
820  check(cs_pdg_formals_in(inner, &rv));
821  return cglue<point_set>::wrap(rv, false);
822  }
823 
824 
843  std::vector<point> formal_ins_vector() const
844  {
845  typedef scratchpad<point> sp;
846  sp::to_vector_functor1<procedure, cs_pdg_formals_in_as_list>
847  functor(inner);
848  return sp::to_vector(functor);
849  }
850 
851 
874  point formal_in(size_t rank)
875  {
876  cs_pdg_vertex rv;
877  check(cs_pdg_formal_in(inner, rank, &rv));
878  return point::;
879  }
880 
899  void set_formal_ins(const std::vector<symbol> &v)
900  {
901  size_t count = v.size();
902  cs_abs_loc *locs = new cs_abs_loc[count];
903  for( size_t i = 0; i < count; i++ )
904  locs[i] = cglue<symbol>::unwrap(v[i]);
905  cs_result r = cs_pdg_set_formals_in(
906  inner, locs, count);
907  delete[] locs;
908  check(r);
909  }
931  point_set formal_outs() const
932  {
933  cs_pdg_vertex_set rv;
934  check(cs_pdg_formals_out(inner, &rv));
935  return cglue<point_set>::wrap(rv, false);
936  }
937 
938 
957  std::vector<point> formal_outs_vector() const
958  {
959  typedef scratchpad<point> sp;
960  sp::to_vector_functor1<procedure, cs_pdg_formals_out_as_list>
961  functor(inner);
962  return sp::to_vector(functor);
963  }
964 
965 
983  void set_formal_outs(const std::vector<symbol> &v)
984  {
985  size_t count = v.size();
986  cs_abs_loc *locs = new cs_abs_loc[count];
987  for( size_t i = 0; i < count; i++ )
988  locs[i] = cglue<symbol>::unwrap(v[i]);
989  cs_result r = cs_pdg_set_formals_out(
990  inner, locs, count);
991  delete[] locs;
992  check(r);
993  }
1014  point retrieve_point(csint64 _id) const
1015  {
1016  cs_pdg_vertex rv;
1017  check(cs_pdg_retrieve_vertex(inner, _id, &rv));
1018  return point::;
1019  }
1020 
1038  point_set used_points(symbol al) const;
1061  point_set used_points_from_set(const symbol_set &s) const
1062  {
1063  cs_pdg_vertex_set rv;
1064  check(cs_pdg_abs_loc_set_used_vertices(
1065  inner, cglue<symbol_set>::unwrap(s), &rv));
1066  return cglue<point_set>::wrap(rv, false);
1067  }
1088  point_set killed_points(symbol al) const;
1111  point_set killed_points_from_set(const symbol_set &s) const
1112  {
1113  cs_pdg_vertex_set rv;
1114  check(cs_pdg_abs_loc_set_killed_vertices(
1115  inner, cglue<symbol_set>::unwrap(s), &rv));
1116  return cglue<point_set>::wrap(rv, false);
1117  }
1140  point_set cond_killed_points(symbol al) const;
1163  point_set cond_killed_points_from_set(const symbol_set &s) const
1164  {
1165  cs_pdg_vertex_set rv;
1166  check(cs_pdg_abs_loc_set_cond_killed_vertices(
1167  inner, cglue<symbol_set>::unwrap(s), &rv));
1168  return cglue<point_set>::wrap(rv, false);
1169  }
1192  point_set may_killed_points(symbol al) const;
1215  point_set may_killed_points_from_set(const symbol_set &s) const
1216  {
1217  cs_pdg_vertex_set rv;
1218  check(cs_pdg_abs_loc_set_may_killed_vertices(
1219  inner, cglue<symbol_set>::unwrap(s), &rv));
1220  return cglue<point_set>::wrap(rv, false);
1221  }
1244  symbol_set gref() const
1245  {
1246  cs_const_abs_loc_set rv;
1247  check(cs_pdg_gref_abs_loc_set(inner, &rv));
1248  return cglue<symbol_set>::wrap(rv, true);
1249  }
1272  symbol_set gmod() const
1273  {
1274  cs_const_abs_loc_set rv;
1275  check(cs_pdg_gmod_abs_loc_set(inner, &rv));
1276  return cglue<symbol_set>::wrap(rv, true);
1277  }
1286  bool has_vararg() const
1287  { return !!cs_pdg_has_vararg(inner); }
1288 
1289 
1300  bool has_incomplete_summary() const
1301  { return !!cs_pdg_has_incomplete_summary(inner); }
1321  size_t scc_id() const
1322  {
1323  size_t rv;
1324  check(cs_pdg_scc_id(inner, &rv));
1325  return rv;
1326  }
1355  basic_block retrieve_basic_block(csint64 id) const;
1356 
1357 
1376  basic_block entry_basic_block() const;
1377 
1378 
1400  basic_block exit_basic_block() const;
1401 
1402 
1421  basic_block_set basic_blocks() const
1422  {
1423  cs_basic_block_set rv;
1424  check(cs_pdg_get_basic_blocks(inner, &rv));
1425  return cglue<basic_block_set>::wrap(rv, false);
1426  }
1449  point normal_exit() const
1450  {
1451  cs_pdg_vertex rv;
1452  check(cs_pdg_normal_exit(inner, &rv));
1453  return point::;
1454  }
1474  std::vector<exceptional_exit> exceptional_exits() const
1475  {
1476  typedef scratchpad<exceptional_exit> sp;
1477  sp::to_vector_functor1_card<procedure, cs_pdg_exceptional_exits>
1478  functor(inner);
1479  return sp::to_vector(functor);
1480  }
1486  std::string as_string() const
1487  { return name(); }
1488 
1489 
1492  std::string as_repr() const
1493  { return CS_AS_REPR_FROM_STRING(procedure); }
1494 
1495 #if defined(CSONAR_API_SWIG_HPP) || !defined(SWIG)
1496 
1497  /* documented in csonar_visitor.hpp */
1498  iterator_adapter<procedure_adjusted_callers_iterator_policy>
1499  adjusted_callers() const;
1500 
1501  bool
1502  reachable() const;
1504 #endif
1505 
1520  std::string decompilation()
1521  {
1522  string_scratchpad::
1523  to_string_functor1_limit<procedure, cs_decompilation_for_pdg>
1524  functor(inner, -1);
1525  return string_scratchpad::to_string(functor);
1526  }
1551  {
1552  effective_address addr;
1553  check(cs_pdg_ea(inner, &addr));
1554  return addr;
1555  }
1556 
1573  std::string handle() const
1574  {
1575  string_scratchpad::
1576  to_string_functor1_limit<procedure, cs_pdg_get_handle>
1577  functor(inner, -1);
1578  return string_scratchpad::to_string(functor);
1579  }
1580 
1581  };
1582  CS_IR_BOILERPLATE_FRIENDS_PLUS_OSTREAM(procedure, cs)
1584 
1585 #endif /* CS_PROCEDURE_DECL_HPP */
Enumeration class: the "kind" of a procedure.
Definition: cs_procedure_kind.hpp:30
Namespace for CodeSonar/CodeSurfer API.
Definition: cs_ast.hpp:33
std::string basename() const
Get the basename of a procedure.
Definition: cs_procedure_decl.hpp:512
static const procedure_call_sites_flags DIRECT
Singleton set containing the "direct call sites" flag: points of kind point_kind::CALL_SITE are of in...
Definition: cs_procedure_decl.hpp:76
std::pair< cs::sfileinst, cs::line_number > sfileinst_line_pair
A std::pair (sfi, line) where:
Definition: cs_tplt_instantiations.hpp:107
std::vector< point > call_sites_vector(procedure_call_sites_flags flags=procedure_call_sites_flags::DIRECT) const
Get a std::vector of the call sites in a procedure.
Definition: cs_procedure_decl.hpp:707
point entry_point() const
Get the entry point of a procedure.
Definition: cs_procedure_decl.hpp:356
cs::procedure_call_sites_iterator_policy
Definition: cs_procedure_decl.hpp:95
A function or variable.
Definition: cs_symbol_decl.hpp:243
symbol find_containing_symbol_by_offset(csint32 off) const
[Binary analyses only] Get the procedure local containing the given stack offset. ...
Definition: cs_procedure_decl.hpp:650
cs::procedure_call_sites_iterator_policy::ctype
Definition: cs_procedure_decl.hpp:100
ast get_ast(ast_family family=ast_family::DEFAULT) const
Retrieve the AST for a procedure.
Definition: cs_procedure_decl.hpp:278
size_t callers_count() const
Get the number of direct callers of a procedure.
Definition: cs_procedure_decl.hpp:785
point retrieve_point(csint64 _id) const
Get a point from a procedure by ID.
Definition: cs_procedure_decl.hpp:1019
std::string as_string() const
Get a simple string representation of a procedure object.
Definition: cs_procedure_decl.hpp:1493
A single program point.
Definition: cs_point_decl.hpp:66
std::vector< point > formal_outs_vector() const
Get the formal-out points of a procedure.
Definition: cs_procedure_decl.hpp:962
bool has_vararg() const
Check: does a procedure have a formal vararg parameter?
Definition: cs_procedure_decl.hpp:1291
An Abstract Syntax Tree (AST).
Definition: cs_ast_decl.hpp:448
std::string handle() const
Get a handle for this procedure.
Definition: cs_procedure_decl.hpp:1583
A single procedure/function/method.
Definition: cs_procedure_decl.hpp:173
csuint64 stable_hash() const
Get a hash value for a procedure, with stable results across sufficiently-similar analyses...
Definition: cs_procedure_decl.hpp:199
cs::procedure_locals_iterator_policy
Definition: cs_procedure_decl.hpp:29
symbol find_symbol_by_offset(csint32 off) const
[Binary analyses only] Get the procedure local with the given stack offset.
Definition: cs_procedure_decl.hpp:625
point formal_in(size_t rank)
Get the point corresponding to the formal-in with the specified rank.
Definition: cs_procedure_decl.hpp:879
point preexit_point() const
Get the preexit point of a procedure.
Definition: cs_procedure_decl.hpp:377
std::string verbose_name() const
Get the name of a procedure.
Definition: cs_procedure_decl.hpp:455
static const ast_family DEFAULT
Represents the first AST family, whatever it might be.
Definition: cs_ast_decl.hpp:25
A set of points (point).
Definition: cs_tplt_instantiations.hpp:214
std::string as_repr() const
Get a representation of a procedure object that includes information useful for debugging.
Definition: cs_procedure_decl.hpp:1502
symbol get_symbol() const
Get the symbol for a procedure.
Definition: cs_procedure.hpp:25
procedure_call_sites_iterator call_sites(procedure_call_sites_flags flags=procedure_call_sites_flags::DIRECT) const
Get an iterator over the call sites in a procedure.
Definition: cs_procedure_decl.hpp:767
iterator_adapter< procedure_adjusted_callers_iterator_policy > adjusted_callers() const
Get an iterator over the call sites (point of kind point_kind::CALL_SITE or point_kind::INDIRECT_CALL...
Definition: csonar_visitor.hpp:6042
A set of symbols (symbol).
Definition: cs_tplt_instantiations.hpp:231
csint64 id() const
Get the unique identifier of a procedure.
Definition: cs_procedure_decl.hpp:424
point_set formal_ins() const
Get the formal-in and global-formal-in points of a procedure.
Definition: cs_procedure_decl.hpp:822
point_set points() const
Get all the points in a procedure.
Definition: cs_procedure_decl.hpp:551
Enumeration class for AST family.
Definition: cs_ast_decl.hpp:50
std::string demangled_name() const
[Binary analyses only] Get the demangled user-friendly name of a procedure.
Definition: cs_procedure_decl.hpp:534
sfileinst_line_pair file_line() const
Get the file instance and (smallest offset) line of the entry point for a procedure.
Definition: cs_procedure_decl.hpp:317
Iterator over the local variables (symbol) that are declared in a procedure.
Definition: cs_tplt_instantiations.hpp:830
effective_address get_address() const
[Binary analyses only] Get the effective address of a procedure, if there is one. ...
Definition: cs_procedure_decl.hpp:1560
point exit_point() const
Get the exit point of a procedure.
Definition: cs_procedure_decl.hpp:398
procedure_locals_iterator local_symbols() const
Get an iterator over the local variables (symbol) that are declared in a procedure.
Definition: cs_procedure_decl.hpp:573
compunit get_compunit() const
Get the compilation unit containing a procedure.
Definition: cs_procedure_decl.hpp:339
cs::iterator_adapter< procedure_adjusted_callers_iterator_policy >
size_t call_sites_count(procedure_call_sites_flags flags=procedure_call_sites_flags::DIRECT) const
Get the number of call sites in a procedure.
Definition: cs_procedure_decl.hpp:741
point_set formal_outs() const
Get the formal-out and global-formal-out points of a procedure.
Definition: cs_procedure_decl.hpp:936
A compilation unit.
Definition: cs_compunit_decl.hpp:70
static const procedure_call_sites_flags NONE
Empty set: contains no flags.
Definition: cs_procedure_decl.hpp:69
procedure_kind get_kind() const
Retrieve the procedure_kind of a procedure.
Definition: cs_procedure_decl.hpp:237
int stable_cmp(const procedure &other) const
Compare with another procedure, with stable results across sufficiently-similar analyses.
Definition: cs_procedure_decl.hpp:226
bool reachable() const
Check: is a procedure reachable from the reachability roots specified with configuration file paramet...
Definition: csonar_visitor.hpp:5775
std::string name() const
Get the user-friendly name of a procedure.
Definition: cs_procedure_decl.hpp:479
std::vector< point > formal_ins_vector() const
Get a std::vector containing the formal-in points of a procedure.
Definition: cs_procedure_decl.hpp:848
Flag class: specifies call site types.
Definition: cs_procedure_decl.hpp:59
cs_ea effective_address
An effective address: used for binary analyses to hold the address of an entity such as a point or sy...
Definition: cs_types.hpp:392
procedure_callers_iterator callers() const
Get an iterator over the direct call sites (point of kind point_kind::CALL_SITE) whose target is this...
Definition: cs_procedure_decl.hpp:800
static const procedure_call_sites_flags INDIRECT
Singleton set containing the "indirect call sites" flag: points of kind point_kind::INDIRECT_CALL are...
Definition: cs_procedure_decl.hpp:82