CodeSonar C++ API
[For improved navigation, enable JavaScript.]
cs_ast_decl.hpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2023-2025, 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_AST_DECL_HPP
17 #define CS_AST_DECL_HPP
18 
19 #include "cs_ast.h"
20 
21 #ifndef CSFE_API
22 #include "cs_types.hpp"
23 #endif
24 
26 #include "cs_ir_boilerplate.hpp"
27 #include "cs_scratchpad.hpp"
28 #ifndef CSFE_API
30 #endif /* CSFE_API */
31 
34 namespace cs{
35 
37 
38 #ifndef CSFE_API
39 #else /* CSFE_API */
40 class ast_iterator_policy;
41 #endif /* CSFE_API */
42 
50  class ast_family{
51  CS_ENUM_BOILERPLATE(ast_family, cs_ast_family,
52  /* better to show something than nothing?
53  * ast family names are ambiguous without
54  * also knowing the language.
55  */
56  rv = inner ? "unnormalized" : "normalized",
57  (csuint64)_inner < (csuint64)5);
58 #include "cs_ast_family_decls.hpp"
59  };
60 #ifndef CSFE_API
61  CS_ENUM_BOILERPLATE_FRIENDS(ast_family,
62  friend class symbol;
63  friend class point;
64  friend class compunit;
65  friend class procedure;,
67  )
68 #else /* CSFE_API */
69  CS_ENUM_BOILERPLATE_FRIENDS(ast_family,
70  friend class csfe::symbol;
71  friend class csfe::global_init;
72  friend class csfe::point;
73  friend class csfe::compunit;
74  friend class csfe::procedure;,
76  )
77 #endif /* CSFE_API */
78 #include "cs_ast_family_defs.hpp"
79 
91  class ast_class{
92  ast_class();
93  CS_ENUM_BOILERPLATE_NONAME(ast_class, cs_ast_class,
94  cs_ast_class_name((cs_ast_class)_inner))
95  public:
102  ast_class superclass() const
103  { return ast_class(cs_ast_class_superclass(inner)); }
104 
114  bool is_subclass_of(ast_class sup)
115  { return !!cs_ast_class_is_subclass( inner, sup.unwrap() ); }
122  std::string name() const
123  { return cs_ast_class_name(inner); }
124 #include "cs_ast_class_decls.hpp"
125  };
126 #ifndef CSFE_API
127  CS_ENUM_BOILERPLATE_FRIENDS(ast_class,
128  friend class ast;
129  friend class ast_field;
130  friend class compunit;
131  friend class sfileinst;
132  friend class ir_factory;
133  friend struct ::FatTypeTraits<cs::ast_class>;,
134  cs
135  )
136 #else /* CSFE_API */
137  CS_ENUM_BOILERPLATE_FRIENDS(ast_class,
138  friend class ast;
139  friend class ast_field;
140  friend class csfe::ir_factory;
141  friend class csfe::compunit;
142  friend class csfe::point;
143  friend class csfe::symbol;,
145  )
146 #endif /* CSFE_API */
147 #include "cs_ast_class_defs.hpp"
148 
159  class ast_ordinal{
160  ast_ordinal();
161 
162  ast_ordinal(const empty_class &tag, cs_ast_ordinal _inner)
163  : inner(_inner)
164  {}
165 
166  static ast_ordinal wrap(cs_ast_ordinal _inner)
167  { return ast_ordinal(empty_class(), _inner); }
169  CS_ENUM_BOILERPLATE_NONAME_NOCTOR(ast_ordinal, cs_ast_ordinal);
170 
179  static ast_ordinal from_integer(csint64 _inner)
180  {
181  cs_ast_ordinal ct_inner = (cs_ast_ordinal)_inner;
182  if( (csint64)ct_inner != _inner )
183  check(CS_ERROR_INVALID_ARGUMENT);
184  if( _inner == 0 )
185  check(CS_ERROR_INVALID_ARGUMENT);
186  if( _inner < 0 && cs_ast_ordinal_name(ct_inner) == NULL )
187  check(CS_ERROR_INVALID_ARGUMENT);
188  return ast_ordinal(empty_class(), ct_inner);
189  }
190 
202  ast_ordinal(size_t position)
203  : inner((ctype)position)
204  {
205  if( inner <= 0 || (size_t)inner != position )
206  cs::check(CS_ERROR_INVALID_ARGUMENT);
207  }
208 
213  std::string name() const
214  {
215  if( inner > 0 )
216  {
217  std::stringstream buf;
218  buf << inner;
219  return buf.str();
220  }
221  return cs_ast_ordinal_name(inner);
222  }
223 
231  size_t as_size_t() const
232  {
233  if( inner <= 0 )
234  cs::check(CS_ERROR_INVALID_ARGUMENT);
235  return (size_t)inner;
236  }
237 
238 #include "cs_ast_ordinal_decls.hpp"
239  };
240  CS_ENUM_BOILERPLATE_FRIENDS_NO_CGLUE(ast_ordinal)
241  template<>
242  class cglue<ast_ordinal>
243  {
244  friend class ast_field;
245  friend class ast;
246 #ifndef CSFE_API
247 #else /* CSFE_API */
248  friend class csfe::ir_factory;
249 #endif /* CSFE_API */
250  cglue();
251  public:
252  typedef ast_ordinal::ctype ctype;
253  typedef ast_ordinal type;
254  CS_CXX_API_CGLUE_ACCESS_MODIFIER:
255  static type wrap(const ctype &c)
256  { return ast_ordinal::wrap(c); }
257  static ctype unwrap(const type &c)
258  { return c.unwrap(); }
259  };
260  CS_ENUM_BOILERPLATE_NONMEMBERS(ast_ordinal, cs)
261 #include "cs_ast_ordinal_defs.hpp"
262 
270  CS_ENUM_BOILERPLATE_UB(ast_field_type, cs_ast_field_type,
271  rv = cs_ast_field_type_name(inner),
272  csft_count);
274  };
275  CS_ENUM_BOILERPLATE_FRIENDS(ast_field_type,
276  friend class ast_field;,
278  )
279 #include "cs_ast_field_type_defs.hpp"
280 
281 
289  CS_FLAGS_BOILERPLATE(ast_traverse_flags, cs_ast_traverse_flags,
290  csatf_all,
291  "right_to_left",
292  "postorder");
294  static const ast_traverse_flags NONE;
295 
297  static const ast_traverse_flags RIGHT_TO_LEFT;
298 
300  static const ast_traverse_flags POSTORDER;
301  };
302  CS_FLAGS_BOILERPLATE_FRIENDS(ast_traverse_flags,
303  friend class ast_iterator_policy;
304  friend class ast;,
306  )
307 #ifdef CS_CPP_IMPL
311 #endif
325  CS_FLAGS_BOILERPLATE(ast_traverse_directives, cs_ast_traverse_directives,
326  csatd_all,
327  "skip_children");
328 
331 
335  };
336  CS_FLAGS_BOILERPLATE_FRIENDS(ast_traverse_directives,
337  friend class ast_iterator_policy;,
338  cs
339  )
340 #ifdef CS_CPP_IMPL
343 #endif
345 #ifndef CSFE_API
346  CS_IR_BOILERPLATE_FORWARD(
347  ast,
348  cs_ast,
349  friend class point;
350  friend class procedure;
351  friend class symbol;
352  friend class compunit;
353  friend class ast_field;
354  friend class ast_iterator_policy;
355  friend class ast_pattern;
356  friend class ir_factory;
357  friend class iterator_adapter<ast_iterator_policy>;
358  friend class project;
360  friend struct FatTypeTraits<ast>;
362  );
363 #else /* CSFE_API */
364  CS_IR_BOILERPLATE_FORWARD(
365  ast,
366  cs_ast,
367  friend class csfe::compunit;
368  friend class csfe::global_init;
369  friend class csfe::ir_factory;
370  friend class csfe::point;
371  friend class csfe::procedure;
372  friend class csfe::symbol;
373  friend class ast_field;
374  friend class ast_iterator_policy;
375  );
376 #endif /* CSFE_API */
377 
438  class ast{
444  CS_IR_BOILERPLATE(ast);
445  public:
446 
470  int stable_cmp(const ast& other) const
471  {
472  return cs_ast_stable_compare(inner, other.inner);
473  }
475 
482  ast_class get_class() const
483  { return cglue<ast_class>::wrap(cs_ast_get_class(inner)); }
484 
485 
494  bool is_a(ast_class c) const
495  { return !!cs_ast_is_a(inner, cglue<ast_class>::unwrap(c)); }
496 
497 
498 #if defined(SWIG) && defined(SWIGJAVA)
499 %javaexception("ast_field_not_found_error") operator[] {
500  try {
501  $action
502  }
503  catch (cs::ast_field_not_found_error &e) {
504  jclass clazz = jenv->FindClass("com/codesecure/cs/ast_field_not_found_error");
505  jobject obj = jenv->NewObject(
506  clazz,
507  jenv->GetMethodID(clazz, "<init>", "(JZ)V"),
508  (jlong)new cs::ast_field_not_found_error(e),
509  (jboolean)1 );
510  jenv->Throw(static_cast<jthrowable>(obj));
511  return $null;
512  }
513 }
514 #endif
515 
542  ast_field operator[](ast_ordinal ord) const;
544 
575  ast_field operator[](size_t ord) const;
576 #if defined(SWIG) && defined(SWIGPYTHON)
577  %rename(__contains__) has_field;
578  %rename(__len__) num_fields;
579 #endif
580 
592  bool has_field(ast_ordinal ord) const;
593 
608  bool has_field(size_t ord) const;
610 
616  size_t num_fields() const;
617 
618 #if defined(SWIG) && defined(SWIGPYTHON)
619  %pythoncode{
620  def __getitem__(self, k):
621  return self._getitem_impl(k).value()
622  def get(self, k, dflt=None):
623  try:
624  return self[k]
626  return dflt
627  def __iter__(self): return iter(self.fields())
628  def to_dict(self):
629  rv = {}
630  for f in self:
631  rv[f.ordinal()] = f.value()
632  return rv
633  };
634 #endif
635 
645  std::vector<ast_field> fields() const;
646 
647 
657  std::vector<ast_field> children() const;
658 
659 
667  std::vector<ast_field> attributes() const;
668 
686  std::string pretty_print(size_t limit=SIZE_MAX) const;
688 
698  std::string dump(size_t attribute_depth=2) const;
700 
718  void set_field(const ast_field &c);
721 #ifndef CSFE_API
722 
731 #endif
734  std::string as_string() const
735  { return pretty_print(); }
736 
738  std::string as_repr() const;
739  };
740  CS_IR_BOILERPLATE_FRIENDS(ast)
741  CS_STD_HASH(ast, cs)
742 
750  inline std::ostream &operator<<( std::ostream &out, const ast &a )
751  {
752  return out << CS_AS_REPR_PREFIX << "ast ["
753  << a.get_class().name() << "] "
754  << a.as_string() << CS_AS_REPR_SUFFIX;
755  }
757  inline std::string ast::as_repr() const
758  {
759  std::stringstream buf;
760  buf << *this;
761  return buf.str();
762  }
763 
764  inline ast cglue<ast>::wrap(const cs_ast &c)
765  { return ast(c); }
766 
767  inline cs_ast cglue<ast>::unwrap(const ast &c)
768  { return c.unwrap(); }
769 
770  class ast_iterator_policy_container{
771  ast_iterator_policy_container();
772  public:
773  ast_iterator_policy_container(
774  ast _root, ast_traverse_flags _flags)
775  : root(_root), flags(_flags){}
776  ast root;
778  };
779 
780  class ast_iterator_policy{
781  public:
782 #ifndef SWIG
783  class iterator_impl{
784  public:
785  iterator_impl(): directives(ast_traverse_directives::NONE){}
786  cs_ast_traverse_iter c_iter;
787  ast_traverse_directives directives;
788  };
789 #endif
790 
791  typedef ast key;
792  typedef ast_iterator_policy_container ctype;
793  typedef ast_traverse_directives directives;
794 
795  static cs_result iter_first(
796  ctype container,
797  cglue<key>::ctype *val,
798  iterator_impl *it)
799  {
800  it->directives = ast_traverse_directives::NONE;
801  return cs_ast_iter_first(
802  cglue<ast>::unwrap(container.root),
803  cglue<ast_traverse_flags>::unwrap(container.flags), val, &it->c_iter );
804  }
805 
806  static cs_result iter_next(
807  ctype container,
808  cglue<key>::ctype *val,
809  iterator_impl *it)
810  {
811  cs_result r = cs_ast_iter_next(
812  cglue<ast_traverse_directives>::unwrap(it->directives),
813  val, &it->c_iter );
814  it->directives = ast_traverse_directives::NONE;
815  return r;
816  }
817  static cs_result iter_close(iterator_impl *it)
818  { return cs_ast_iter_close( &it->c_iter ); }
819  static const char *name()
820  { return "ast_iterator"; }
821  };
823 #ifndef CSFE_API
824  template<>
825  class iterator_adapter_mixin<ast_iterator_policy>
826  {
827  protected:
828  iterator_adapter_mixin(){}
829  public:
855  void apply_directives(ast_traverse_directives directives)
856  { static_cast<iterator_adapter<ast_iterator_policy>*>(this)->inner->directives = directives; }
857  };
858 #endif /* CSFE_API */
859 
860 #ifndef CSFE_API
861  CS_IR_BOILERPLATE_FORWARD(ast_field, cs_ast_field,
862  friend class ast;
863  friend class ir_factory;
864  );
865 #else /* CSFE_API */
866  CS_IR_BOILERPLATE_FORWARD(ast_field, cs_ast_field,
867  friend class ast;
868  friend class ir_factory;
869  friend class csfe::ir_factory;
870  );
871 #endif /* CSFE_API */
872 
883  class ast_field{
884  CS_IR_BOILERPLATE(ast_field);
886  private:
887 #ifndef CSFE_API
889  friend class cglue<string_ast_field_pair>;
891 #endif
892 
893  public:
919  int stable_cmp(const ast_field& other) const
920  { return cs_ast_field_stable_compare(inner, other.inner); }
922 
931  int fast_cmp(const ast_field& other) const
932  { return cs_ast_field_fast_compare(inner, other.inner); }
941  ast_field(ast_ordinal ord, ast val)
942  {
943  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
944  inner.type = csft_ast;
945  inner._.ast = cglue<ast>::unwrap(val);
946  }
947 
955  {
956  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
957  inner.type = csft_ast_class;
958  inner._.ast_class = cglue<ast_class>::unwrap(val);
959  }
967  ast_field(ast_ordinal ord, bool val)
968  {
969  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
970  inner.type = csft_boolean;
971  inner._.boolean = val;
972  }
973 
974 #ifndef SWIG
981  ast_field(ast_ordinal ord, csint8 val)
982  {
983  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
984  inner.type = csft_int8;
985  inner._.int8 = val;
986  }
994  ast_field(ast_ordinal ord, csuint8 val)
995  {
996  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
997  inner.type = csft_uint8;
998  inner._.uint8 = val;
999  }
1000 
1007  ast_field(ast_ordinal ord, csint16 val)
1008  {
1009  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1010  inner.type = csft_int16;
1011  inner._.int16 = val;
1012  }
1013 
1020  ast_field(ast_ordinal ord, csuint16 val)
1021  {
1022  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1023  inner.type = csft_uint16;
1024  inner._.uint16 = val;
1025  }
1033  ast_field(ast_ordinal ord, csint32 val)
1034  {
1035  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1036  inner.type = csft_int32;
1037  inner._.int32 = val;
1038  }
1039 
1046  ast_field(ast_ordinal ord, csuint32 val)
1047  {
1048  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1049  inner.type = csft_uint32;
1050  inner._.uint32 = val;
1051  }
1052 
1059  ast_field(ast_ordinal ord, csint64 val)
1060  {
1061  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1062  inner.type = csft_int64;
1063  inner._.int64 = val;
1064  }
1072  ast_field(ast_ordinal ord, csuint64 val)
1073  {
1074  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1075  inner.type = csft_uint64;
1076  inner._.uint64 = val;
1077  }
1078 
1085  ast_field(ast_ordinal ord, float val)
1086  {
1087  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1088  inner.type = csft_flt32;
1089  inner._.flt32 = val;
1090  }
1091 
1098  ast_field(ast_ordinal ord, double val)
1099  {
1100  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1101  inner.type = csft_flt64;
1102  inner._.flt64 = val;
1103  }
1104 #endif
1105 
1111  ast_field(ast_ordinal ord, const std::string &val)
1112  {
1113  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1114  inner.type = csft_reserved;
1115  size_t len = val.size();
1116  char *s = new char[len+1];
1117  inner._.const_str = s;
1118  memcpy( s, val.c_str(), len );
1119  s[len] = '\0';
1120  }
1121 
1122 #ifndef CSFE_API
1123 
1129  ast_field(ast_ordinal ord, symbol val);
1130 #endif /* CSFE_API */
1135  ast_field(ast_ordinal ord, const ast_field &f)
1136  : inner(f.inner)
1137  {
1138  if( inner.type == csft_reserved )
1139  {
1140  const char *val = inner._.const_str;
1141  size_t len = strlen(val);
1142  char *s = new char[len+1];
1143  inner._.const_str = s;
1144  memcpy( s, val, len+1 );
1145  }
1146  inner.ordinal = cglue<ast_ordinal>::unwrap(ord);
1147  }
1148 
1153 
1156  : inner(f.inner)
1157  {
1158  if( inner.type == csft_reserved )
1159  {
1160  const char *val = inner._.const_str;
1161  size_t len = strlen(val);
1162  char *s = new char[len+1];
1163  inner._.const_str = s;
1164  memcpy( s, val, len+1 );
1165  }
1166  }
1168  ~ast_field()
1169  {
1170  if( inner.type == csft_reserved )
1171  delete[] const_cast<char*>(inner._.const_str);
1172  }
1181  ast_ordinal ordinal() const
1182  {
1183  if( inner.ordinal == csao_null )
1184  check(CS_ERROR_INVALID_ARGUMENT);
1185  return cglue<ast_ordinal>::wrap(inner.ordinal);
1186  }
1187 
1193  ast_field_type get_type() const
1194  {
1195  return cglue<ast_field_type>::wrap(
1196  inner.type == csft_reserved
1197  ? csft_const_str
1198  : inner.type);
1199  }
1209  ast as_ast() const
1210  {
1211  if( inner.type != csft_ast )
1212  check(CS_ERROR_INVALID_TYPE);
1213  return cglue<ast>::wrap(inner._.ast);
1214  }
1225  {
1226  if( inner.type != csft_ast_class )
1227  check(CS_ERROR_INVALID_TYPE);
1228  return cglue<ast_class>::wrap(inner._.ast_class);
1229  }
1239  bool as_boolean() const
1240  {
1241  if( inner.type != csft_boolean )
1242  check(CS_ERROR_INVALID_TYPE);
1243  return !!inner._.boolean;
1244  }
1255  csint32 as_enum_value_int32() const
1256  {
1257  if( inner.type != csft_enumeration )
1258  check(CS_ERROR_INVALID_TYPE);
1259  return inner._.enumeration.as_integer;
1260  }
1261 
1271  std::string as_enum_value_string() const
1272  {
1273  if( inner.type != csft_enumeration )
1274  check(CS_ERROR_INVALID_TYPE);
1275  return inner._.enumeration.as_string;
1276  }
1277 
1286  csint8 as_int8() const
1287  {
1288  if( inner.type != csft_int8 )
1289  check(CS_ERROR_INVALID_TYPE);
1290  return inner._.int8;
1291  }
1292 
1301  csuint8 as_uint8() const
1302  {
1303  if( inner.type != csft_uint8 )
1304  check(CS_ERROR_INVALID_TYPE);
1305  return inner._.uint8;
1306  }
1307 
1316  csint16 as_int16() const
1317  {
1318  if( inner.type != csft_int16 )
1319  check(CS_ERROR_INVALID_TYPE);
1320  return inner._.int16;
1321  }
1322 
1331  csuint16 as_uint16() const
1332  {
1333  if( inner.type != csft_uint16 )
1334  check(CS_ERROR_INVALID_TYPE);
1335  return inner._.uint16;
1336  }
1337 
1346  csint32 as_int32() const
1347  {
1348  if( inner.type != csft_int32 )
1349  check(CS_ERROR_INVALID_TYPE);
1350  return inner._.int32;
1351  }
1352 
1361  csuint32 as_uint32() const
1362  {
1363  if( inner.type != csft_uint32 )
1364  check(CS_ERROR_INVALID_TYPE);
1365  return inner._.uint32;
1366  }
1367 
1376  csint64 as_int64() const
1377  {
1378  if( inner.type != csft_int64 )
1379  check(CS_ERROR_INVALID_TYPE);
1380  return inner._.int64;
1381  }
1382 
1391  csuint64 as_uint64() const
1392  {
1393  if( inner.type != csft_uint64 )
1394  check(CS_ERROR_INVALID_TYPE);
1395  return inner._.uint64;
1396  }
1397 
1406  float as_flt32() const
1407  {
1408  if( inner.type != csft_flt32 )
1409  check(CS_ERROR_INVALID_TYPE);
1410  return inner._.flt32;
1411  }
1412 
1421  double as_flt64() const
1422  {
1423  if( inner.type != csft_flt64 )
1424  check(CS_ERROR_INVALID_TYPE);
1425  return inner._.flt64;
1426  }
1427 
1428 #if defined(SWIG) && defined(SWIGPYTHON)
1429  %pythonprepend as_str %{
1430  if self.get_type() == ast_field_type.BYTES:
1432 #endif
1433 
1447  std::string as_str() const
1448  {
1449  switch( inner.type )
1450  {
1451  case csft_bytes:
1452  case csft_const_str64:
1453  return cglue<std_string_wrapper>::wrap(inner._.const_str64).value;
1454  case csft_const_str:
1455  return inner._.const_str;
1456  case csft_reserved:
1457  return inner._.const_str;
1458  case csft_enumeration:
1459  return inner._.enumeration.as_string;
1460  default:
1461  check(CS_ERROR_INVALID_TYPE);
1462  return "";
1463  }
1464  }
1465 
1466 #if defined(SWIG) && defined(SWIGPYTHON)
1467  %extend {
1468  /* This is documented separately because it has no C++ equivalent. */
1469  std::string as_bytes() const
1470  {
1471  if( $self->get_type() != cs::ast_field_type::BYTES )
1472  cs::check(CS_ERROR_INVALID_TYPE);
1473  return $self->as_str();
1474  }
1475  }
1476 #endif
1477 #ifndef CSFE_API
1478 
1486  symbol as_symbol() const;
1487 #endif /* CSFE_API */
1498 
1499 #ifdef SWIG
1500  %extend{
1501  /* Some swig languages don't do so well with overloads
1502  * that differ only slightly (e.g., by integer width). So
1503  * give them an alternate way of constructing these
1504  * things.
1505  */
1506  static cs::ast_field from_int8( ast_ordinal ord, csint8 v )
1507  { return cs::ast_field(ord, v); }
1508  static cs::ast_field from_uint8( ast_ordinal ord, csuint8 v )
1509  { return cs::ast_field(ord, v); }
1510  static cs::ast_field from_int16( ast_ordinal ord, csint16 v )
1511  { return cs::ast_field(ord, v); }
1512  static cs::ast_field from_uint16( ast_ordinal ord, csuint16 v )
1513  { return cs::ast_field(ord, v); }
1514  static cs::ast_field from_int32( ast_ordinal ord, csint32 v )
1515  { return cs::ast_field(ord, v); }
1516  static cs::ast_field from_uint32( ast_ordinal ord, csuint32 v )
1517  { return cs::ast_field(ord, v); }
1518  static cs::ast_field from_int64( ast_ordinal ord, csint64 v )
1519  { return cs::ast_field(ord, v); }
1520  static cs::ast_field from_uint64( ast_ordinal ord, csuint64 v )
1521  { return cs::ast_field(ord, v); }
1522  static cs::ast_field from_float( ast_ordinal ord, float v )
1523  { return cs::ast_field(ord, v); }
1524  static cs::ast_field from_double( ast_ordinal ord, double v )
1525  { return cs::ast_field(ord, v); }
1526 
1527 #ifdef SWIGPYTHON
1528  /* This is documented separately because it has no C++ equivalent. */
1529  %pythoncode{
1530  _ast_field_type_to_accessor = {
1531  ast_field_type.AST: as_ast,
1532  ast_field_type.AST_CLASS: as_ast_class,
1547  ast_field_type.BYTES: as_bytes,
1550  ast_field_type.NULL_: lambda _: None,
1551  }
1552  def value(self):
1553  t = self.get_type()
1554  try:
1555  accessor = ast_field._ast_field_type_to_accessor[t]
1556  except KeyError:
1557  raise ValueError(self)
1558  return accessor(self)
1559  };
1560 #endif
1561  };
1562 #endif
1564  /* Since ast is by far the most common type, let's make it
1565  * pretty.
1566  */
1567 #ifndef SWIG
1568 
1577  ast operator*() const
1578  { return as_ast(); }
1579 #endif
1580 
1581 #if defined(SWIG) && defined(SWIGJAVA)
1582 %javaexception("ast_field_not_found_error") operator[] {
1583  try {
1584  $action
1585  }
1586  catch (cs::ast_field_not_found_error &e) {
1587  jclass clazz = jenv->FindClass("com/codesecure/cs/ast_field_not_found_error");
1588  jobject obj = jenv->NewObject(
1589  clazz,
1590  jenv->GetMethodID(clazz, "<init>", "(JZ)V"),
1591  (jlong)new cs::ast_field_not_found_error(e),
1592  (jboolean)1 );
1593  jenv->Throw(static_cast<jthrowable>(obj));
1594  return $null;
1595  }
1597 #endif
1598  /* Make it so things like ast[1][2][3] will work as
1599  * expected.
1600  */
1601 
1642  ast_field operator[](ast_ordinal ord) const
1643  { return (**this)[ord]; }
1644 
1645 
1690  ast_field operator[](size_t ord) const
1691  { return (**this)[ord]; }
1692 
1693 #if defined(SWIG) && defined(SWIGPYTHON)
1694  %rename(__contains__) has_field;
1695  %rename(__len__) num_fields;
1696 #endif
1697 
1730  bool has_field(ast_ordinal ord) const
1731  { return (**this).has_field(ord); }
1732 
1733 
1769  bool has_field(size_t ord) const
1770  { return (**this).has_field(ord); }
1771 
1772 
1795  size_t num_fields() const
1796  { return (**this).num_fields(); }
1797 
1798 #if defined(SWIG) && defined(SWIGPYTHON)
1799  %pythoncode{
1800  def __getitem__(self, k):
1801  return self._getitem_impl(k).value()
1802  def get(self, k, dflt=None):
1803  try:
1804  return self[k]
1805  except ast_field_not_found_error:
1806  return dflt
1807  def __iter__(self): return iter(self.as_ast().fields())
1808  };
1809 #endif
1811 #ifndef SWIG
1812  /* This should fly:
1813  * ast b = a[1][csao_nc_type][3];
1814  */
1815 
1822  operator ast() const
1823  { return **this; }
1824 #endif
1825 
1826  private:
1833  void print( std::ostream &out ) const;
1834  NOTSWIG(friend std::ostream &operator<<( std::ostream &out, const ast_field &a ));
1835 
1836  public:
1838  std::string as_string() const
1839  {
1840  std::stringstream buf;
1841  print(buf);
1842  return buf.str();
1843  }
1844 
1846  std::string as_repr() const;
1847 
1848 
1854  CS_BOILERPLATE_HASH_TYPE fast_hash() const
1855  { return cs_ast_field_fast_hash( inner ); }
1856 
1857  };
1858 
1859  CS_IR_BOILERPLATE_FRIENDS(ast_field)
1860 
1861 #if 0
1862 /* Instantiating pairs that use these things seems to work... */
1863 %traits_swigtype(signed char);
1864 %traits_swigtype(unsigned char);
1865 %traits_swigtype(short);
1866 %traits_swigtype(unsigned short);
1867 %traits_swigtype(int);
1868 %traits_swigtype(unsigned int);
1869 %traits_swigtype(long long);
1870 %traits_swigtype(unsigned long long);
1871 
1872 %typemap(out) cs::ast_field {
1873  switch(cglue<ast_field_type>::unwrap($1.get_type()))
1874  {
1875  case csft_null:
1876  abort();
1877  break;
1878  case csft_ast:
1879  $result = swig::from($1.as_ast());
1880  break;
1881  case csft_ast_class:
1882  $result = swig::from($1.as_ast_class().as_string());
1883  break;
1884  case csft_boolean:
1885  $result = swig::from(!!($1.as_boolean()));
1886  break;
1887  case csft_enumeration:
1888  $result = swig::from($1.as_enum_value_string());
1889  break;
1890  case csft_int8:
1891  $result = swig::from($1.as_int8());
1892  break;
1893  case csft_uint8:
1894  $result = swig::from($1.as_uint8());
1895  break;
1896  case csft_int16:
1897  $result = swig::from($1.as_int16());
1898  break;
1899  case csft_uint16:
1900  $result = swig::from($1.as_uint16());
1901  break;
1902  case csft_int32:
1903  $result = swig::from($1.as_int32());
1904  break;
1905  case csft_uint32:
1906  $result = swig::from($1.as_uint32());
1907  break;
1908  case csft_int64:
1909  $result = swig::from($1.as_int64());
1910  break;
1911  case csft_uint64:
1912  $result = swig::from($1.as_uint64());
1913  break;
1914  case csft_int128:
1915  abort();
1916  break;
1917  case csft_uint128:
1918  abort();
1919  break;
1920  case csft_flt32:
1921  $result = swig::from($1.as_flt32());
1922  break;
1923  case csft_flt64:
1924  $result = swig::from($1.as_flt64());
1925  break;
1926  case csft_flt96:
1927  abort();
1928  break;
1929  case csft_flt128:
1930  abort();
1931  break;
1932  case csft_const_str64:
1933  $result = swig::from($1.as_string());
1934  break;
1935  case csft_const_str:
1936  $result = swig::from($1.as_string());
1937  break;
1938  case csft_abs_loc:
1939  $result = swig::from($1.as_symbol());
1940  break;
1941  case csft_sfid:
1942  $result = swig::from($1.as_sfileinst());
1943  break;
1944  case csft_reserved:
1945  $result = swig::from($1.as_string());
1946  break;
1947  default:
1948  abort();
1949  break;
1950  }
1951  $result = swig::from($1);
1952 }
1953 #endif
1954 
1963  inline std::ostream &operator<<( std::ostream &out, const ast_field &a )
1964  {
1965  out << CS_AS_REPR_PREFIX << "ast_field ";
1966  a.print(out);
1967  out << CS_AS_REPR_SUFFIX;
1968  return out;
1969  }
1970 
1971  inline std::string ast_field::as_repr() const
1972  {
1973  std::stringstream buf;
1974  buf << *this;
1975  return buf.str();
1976  }
1977 
1978  inline ast_field cglue<ast_field>::wrap(const cs_ast_field &c)
1979  { return ast_field(c); }
1980 
1981  inline cs_ast_field cglue<ast_field>::unwrap(const ast_field &c)
1982  {
1983  if( c.inner.type == csft_reserved )
1984  {
1985  ctype rv = c.inner;
1986  rv.type = csft_const_str;
1987  return rv;
1988  }
1989  return c.inner;
1990  }
1992 #ifndef CSFE_API
1993  template<>
1994  class cglue<string_ast_field_pair>{
1995  cglue();
1996  friend class scratchpad<string_ast_field_pair>;
1997  friend class ast_pattern;
1998  public:
1999  typedef cs_ast_binding ctype;
2000  typedef string_ast_field_pair type;
2001  CS_CXX_API_CGLUE_ACCESS_MODIFIER:
2002  static type wrap(const ctype &c)
2003  { return string_ast_field_pair(c.name, ast_field(c.f)); }
2004  };
2005 
2009  class ast_bindings{
2010  friend class ast_pattern;
2011  bool valid;
2012  std::vector<string_ast_field_pair> bindings;
2013  ast_bindings(): valid(false){}
2014  ast_bindings(const std::vector<string_ast_field_pair> &_bindings)
2015  : valid(true)
2016  , bindings(_bindings)
2017  {
2018  /* remove null fields... they did not match, but are
2019  * returned from the C API none the less
2020  */
2021  for( std::vector<string_ast_field_pair>::iterator i = bindings.begin();
2022  i != bindings.end();
2023  )
2024  {
2025  if( i->second.get_type() == ast_field_type::NULL_ )
2026  i = bindings.erase(i);
2027  else
2028  ++i;
2029  }
2030  }
2031  public:
2042  ast_field operator[](const std::string &name) const
2043  {
2044  for( size_t i = 0; i < bindings.size(); i++ )
2045  {
2046  if( bindings[i].first == name )
2047  return bindings[i].second;
2048  }
2049  check(CS_ELEMENT_NOT_PRESENT);
2050  for(;;);
2051  }
2052 
2053 #if defined(SWIG)
2054  %ignore operator!;
2055 #endif
2056 
2062  bool operator!() const
2063  { return !valid; }
2064 
2065 
2072  bool matched() const
2073  { return valid; }
2074 
2075 
2084  bool contains(const std::string &name) const
2085  {
2086  for( size_t i = 0; i < bindings.size(); i++ )
2087  {
2088  if( bindings[i].first == name )
2089  return true;
2090  }
2091  return false;
2092  }
2093 
2099  size_t size() const
2100  { return bindings.size(); }
2101 
2102 
2108  std::vector<string_ast_field_pair> items() const
2109  { return bindings; }
2110 
2111  private:
2119  void print(std::ostream &out) const
2120  {
2121  out << "{";
2122  for( size_t i = 0; i < bindings.size(); i++ )
2123  {
2124  if( i )
2125  out << ", ";
2126  out << (bindings[i].first)
2127  << ": "
2128  << bindings[i].second;
2129  }
2130  out << "}";
2131  }
2132 
2133  NOTSWIG(friend std::ostream &operator<<( std::ostream &out, const ast_bindings &a ));
2134  public:
2136  std::string as_string() const
2137  {
2138  std::stringstream buf;
2139  print(buf);
2140  return buf.str();
2141  }
2142 
2144  std::string as_repr() const;
2145  };
2146 
2156  inline std::ostream &operator<<( std::ostream &out, const ast_bindings &a )
2157  {
2158  out << CS_AS_REPR_PREFIX
2159  << "ast_bindings ";
2160  a.print(out);
2161  out << CS_AS_REPR_SUFFIX;
2162  return out;
2163  }
2164  inline std::string ast_bindings::as_repr() const
2165  {
2166  std::stringstream buf;
2167  buf << *this;
2168  return buf.str();
2169  }
2170 
2171 #if defined(SWIG) && defined(SWIGJAVA)
2172 %typemap(javabase) cs::ast_pattern_compilation_error "java.lang.Exception";
2173 
2174 %typemap(javacode) cs::ast_pattern_compilation_error %{
2175  public String getMessage() {
2176  return toString();
2177  }
2178  static final long serialVersionUID = 1114691178779779371L;
2179 %}
2180 #endif
2189  friend class ast_pattern;
2190  std::string message;
2191  std::string pattern;
2192  ast_pattern_compilation_error(const std::string &m, const std::string &p)
2193  : message(m)
2194  , pattern(p){}
2195  public:
2200  std::string get_pattern() const
2201  { return pattern; }
2202 
2204  std::string as_string() const
2205  { return message; }
2206 
2208  std::string as_repr() const
2209  { return CS_AS_REPR_FROM_STRING(ast_pattern_compilation_error); }
2210 
2211 
2213  CS_BOILERPLATE_HASH_TYPE hash() const
2214  { return 1; }
2215  };
2216  CS_IR_BOILERPLATE_NONMEMBERS(ast_pattern_compilation_error, cs)
2217 
2218 
2259  class ast_pattern{
2260  cs_ast_pattern *inner;
2261  public:
2262 #if defined(SWIG) && defined(SWIGJAVA)
2263 %javaexception("ast_pattern_compilation_error") ast_pattern {
2264  try {
2265  $action
2266  }
2268  jclass clazz = jenv->FindClass("com/codesecure/cs/ast_pattern_compilation_error");
2269  jobject obj = jenv->NewObject(
2270  clazz,
2271  jenv->GetMethodID(clazz, "<init>", "(JZ)V"),
2272  (jlong)new cs::ast_pattern_compilation_error(e),
2273  (jboolean)1 );
2274  jenv->Throw(static_cast<jthrowable>(obj));
2275  return $null;
2276  }
2277 }
2278 #endif
2279  /* Not implemented: callbacks */
2280 
2293  ast_pattern(const std::string &pattern)
2294  {
2295  const char *err;
2296  const char *err_location;
2297  cs_result r = cs_ast_pattern_compile(
2298  pattern.c_str(),
2299  &inner,
2300  &err,
2301  &err_location,
2302  NULL /* This NULL will ensure that any embedded %Ps cause failure */
2303  );
2304  if( r != CS_SUCCESS )
2305  {
2306 #if CS_CPP_NO_EXCEPTIONS
2307  cs_fatal(
2308  "ast_pattern compilation error: `%s' near `%s'",
2309  err,
2310  err_location);
2311 #else
2312  throw ast_pattern_compilation_error(
2313  "ast_pattern compilation error: `"
2314  + std::string(err)
2315  + "' near `"
2316  + std::string(err_location)
2317  + "'",
2318  pattern);
2319 #endif
2320  }
2321  }
2322 
2324  { check(cs_ast_pattern_close(inner)); }
2325 
2329  ast_pattern(const ast_pattern &rhs)
2330  : inner(rhs.inner)
2331  { cs_ast_pattern_incr(inner); }
2332 
2333 #if defined(SWIG) && defined(SWIGPYTHON)
2334  %rename(_match_with_bindings) match_with_bindings;
2335  %ignore match;
2336 #endif
2337 
2350  bool match(ast node) const
2351  {
2352  size_t bn;
2353  cs_result r = cs_ast_match(
2354  cglue<ast>::unwrap(node),
2355  inner, NULL, 0, &bn );
2356  switch( r )
2357  {
2358  case CS_SUCCESS:
2359  case CS_TRUNCATED:
2360  return true;
2361  case CS_ELEMENT_NOT_PRESENT:
2362  return false;
2363  default:
2364  check(r);
2365  for(;;);
2366  }
2367  }
2368 
2369 
2379  ast_bindings match_with_bindings(ast node) const
2380  {
2381  typedef scratchpad<string_ast_field_pair> sp;
2382  sp::to_vector_functor2<ast, cs_ast_pattern*, cs_ast_match>
2383  functor(cglue<ast>::unwrap(node), inner);
2384  size_t cardinality;
2385  cs_result r = sp::execute(functor, cardinality);
2386  switch( r )
2387  {
2388  case CS_SUCCESS:
2389  {
2390  cs_ast_binding *bindings = sp::data();
2391  size_t wc = 0;
2392  for( size_t rc = 0; rc < cardinality; rc++ )
2393  if( bindings[rc].f.type != csft_null )
2394  bindings[wc++] = bindings[rc];
2395  return ast_bindings(sp::to_vector(wc));
2396  }
2397  case CS_ELEMENT_NOT_PRESENT:
2398  return ast_bindings();
2399  default:
2400  check(r);
2401  for(;;);
2402  }
2403  }
2404 #if defined(SWIG) && defined(SWIGPYTHON)
2405  %pythoncode{
2406  def match(self, ast):
2407  bindings = self._match_with_bindings(ast)
2408  if bindings.matched():
2409  rv = dict([(k, v.value()) for (k, v) in bindings.items()])
2410  if rv:
2411  return rv
2412  return True
2413  return False};
2414 #endif
2415 
2417  std::string as_string() const
2418  { return as_repr(); }
2419 
2421  std::string as_repr() const
2422  { return CS_AS_REPR(ast_pattern, std::string("...")); }
2423 
2425  CS_BOILERPLATE_HASH_TYPE hash() const
2426  { return static_cast<CS_BOILERPLATE_HASH_TYPE>(reinterpret_cast<uintptr_t>(inner)); }
2427  };
2428  CS_IR_BOILERPLATE_NONMEMBERS(ast_pattern, cs)
2429 
2430 #endif
2431 
2432 #if defined(SWIG) && defined(SWIGJAVA)
2433 %typemap(javabase) cs::ast_field_not_found_error "java.lang.Exception";
2434 
2435 %typemap(javacode) cs::ast_field_not_found_error %{
2436  public String getMessage() {
2437  return toString();
2438  }
2439  static final long serialVersionUID = -9218798017701316509L;
2440 %}
2441 #endif
2442 
2450  class ast_field_not_found_error{
2451  friend class ast;
2452  ast m_node;
2453  ast_ordinal m_ordinal;
2454  ast_field_not_found_error(const ast &node, ast_ordinal ord)
2455  : m_node(node)
2456  , m_ordinal(ord){}
2457  public:
2462  ast get_ast() const
2463  { return m_node; }
2464 
2465 
2470  ast_ordinal get_ordinal() const
2471  { return m_ordinal; }
2472 
2473 
2475  std::string as_string() const
2476  {
2477  std::stringstream buf;
2478  buf << m_ordinal << " not found in " << m_node;
2479  return buf.str();
2480  }
2481 
2483  std::string as_repr() const
2484  { return CS_AS_REPR_FROM_STRING(ast_field_not_found_error); }
2487  CS_BOILERPLATE_HASH_TYPE hash() const
2488  { return m_node.hash() + m_ordinal.hash(); }
2489  };
2490  CS_IR_BOILERPLATE_NONMEMBERS(ast_field_not_found_error, cs)
2491 }
2492 
2493 #endif /* CS_AST_DECL_HPP */
static const ast_traverse_flags NONE
No flags set.
Definition: cs_ast_decl.hpp:297
ast_field operator[](ast_ordinal ord) const
For an ast_field of type ast_field_type::AST, get the designated field of the represented ast...
Definition: cs_ast_decl.hpp:1657
cs::ast_iterator_policy
Definition: cs_ast_decl.hpp:795
Namespace for CodeSonar/CodeSurfer API.
Definition: cs_ast.hpp:33
std::vector< ast_field > children() const
Get all children of an ast.
Definition: cs_ast.hpp:165
static const ast_field_type ABS_LOC
a symbol
Definition: cs_ast_decl.hpp:179
static const result ERROR_INVALID_TYPE
Set when an invalid type is requested.
Definition: cs_result.hpp:685
csuint64 as_uint64() const
Get the value from an ast_field of type ast_field_type::UINT64.
Definition: cs_ast_decl.hpp:1406
bool has_field(ast_ordinal ord) const
For an ast_field of type ast_field_type::AST, check whether the represented ast contains the designat...
Definition: cs_ast_decl.hpp:1745
std::pair< std::string, cs::ast_field > string_ast_field_pair
A std::pair (name, field) representing a binding from one pattern variable to an ast_field.
Definition: cs_tplt_instantiations.hpp:449
ast_iterator traverse(ast_traverse_flags flags=ast_traverse_flags::NONE) const
Get an iterator over an ast.
Definition: cs_ast.hpp:203
ast_class as_ast_class() const
Get the value from an ast_field of type ast_field_type::AST_CLASS.
Definition: cs_ast_decl.hpp:1239
A CodeSonar or CodeSurfer project.
Definition: cs_project.hpp:392
std::string as_str() const
Get a string representation of an ast_field.
Definition: cs_ast_decl.hpp:1462
double as_flt64() const
Get the value from an ast_field of type ast_field_type::FLT64.
Definition: cs_ast_decl.hpp:1436
std::string as_repr() const
Get a representation of a ast_field object that includes information useful for debugging.
Definition: cs_ast_decl.hpp:1991
A function or variable.
Definition: cs_symbol_decl.hpp:243
static const ast_field_type SFID
a sfileinst
Definition: cs_ast_decl.hpp:186
static const ast_field_type NULL_
(This should never be observed.)
Definition: cs_ast_decl.hpp:25
bool has_field(ast_ordinal ord) const
Check: is the designated field present in an ast?
Definition: cs_ast.hpp:109
Describe an error where an ast_field lookup failed.
Definition: cs_ast_decl.hpp:2485
Flag class: specifies what kind of traversal an ast_iterator will carry out.
Definition: cs_ast_decl.hpp:288
The result of an ast_pattern::match() query: bindings from ast_pattern variables to AST fields (ast_f...
Definition: cs_ast_decl.hpp:2029
cs::ast_field_type::AST_CLASS
static const ast_field_type AST_CLASS
No field in a ast will have this type, but it may be used in patterns and bound by matching such patt...
Definition: cs_ast_decl.hpp:39
cs_hash_t fast_hash() const
If this is ast-typed, applies ast::fast_hash() to this.as_ast(); otherwise behaves just like hash()...
Definition: cs_ast_decl.hpp:1874
static const ast_field_type UINT32
an unsigned 32-bit integer
Definition: cs_ast_decl.hpp:95
std
Definition: cs_ast_decl.hpp:67
A single program point.
Definition: cs_point_decl.hpp:66
An Abstract Syntax Tree (AST).
Definition: cs_ast_decl.hpp:448
csint16 as_int16() const
Get the value from an ast_field of type ast_field_type::INT16.
Definition: cs_ast_decl.hpp:1331
csint8 as_int8() const
Get the value from an ast_field of type ast_field_type::INT8.
Definition: cs_ast_decl.hpp:1301
std::string as_enum_value_string() const
Get the string representation from an ast_field of type ast_field_type::ENUMERATION.
Definition: cs_ast_decl.hpp:1286
static const ast_field_type INT8
an 8-bit integer
Definition: cs_ast_decl.hpp:60
A single procedure/function/method.
Definition: cs_procedure_decl.hpp:173
std::string as_repr() const
Get a representation of a ast_bindings object that includes information useful for debugging...
Definition: cs_ast_decl.hpp:2189
std::string dump(size_t attribute_depth=2) const
Get an ASCII art tree rendering of an ast.
Definition: cs_ast.hpp:189
static const ast_field_type UINT64
an unsigned 64-bit integer
Definition: cs_ast_decl.hpp:109
Flag class: specifies behavior during traversal with an ast_iterator.
Definition: cs_ast_decl.hpp:329
std::string pretty_print(size_t limit=SIZE_MAX) const
Get a pretty-printed version of an ast.
Definition: cs_ast.hpp:181
bool as_boolean() const
Get the value from an ast_field of type ast_field_type::BOOLEAN.
Definition: cs_ast_decl.hpp:1254
cs::ast_field_type::AST
static const ast_field_type AST
a ast
Definition: cs_ast_decl.hpp:32
ast_field operator[](ast_ordinal ord) const
Get the designated field from an ast.
Definition: cs_ast.hpp:75
cs::iterator_adapter_mixin
Iterator class template.
Definition: cs_iterator_adapter.hpp:35
csint32 as_enum_value_int32() const
Get the integer value from an ast_field of type ast_field_type::ENUMERATION.
Definition: cs_ast_decl.hpp:1270
static const ast_field_type FLT32
a 32-bit float
Definition: cs_ast_decl.hpp:130
Enumeration class for AST classes.
Definition: cs_ast_decl.hpp:91
cs_hash_t hash() const
Get a hash value for a ast_field.
Definition: cs_ast_decl.hpp:899
ast_field_type get_type() const
Get the ast_field_type associated with an ast_field.
Definition: cs_ast_decl.hpp:1208
Enumeration class for AST ordinals: used to designate a field (ast_field) of an ast.
Definition: cs_ast_decl.hpp:159
sfileinst as_sfileinst() const
Get the value from an ast_field whose type is ast_field_type::SFID.
Definition: cs_ast.hpp:64
ast as_ast() const
Get the value from an ast_field of type ast_field_type::AST.
Definition: cs_ast_decl.hpp:1224
static const ast_field_type INT32
a 32-bit integer
Definition: cs_ast_decl.hpp:88
csuint8 as_uint8() const
Get the value from an ast_field of type ast_field_type::UINT8.
Definition: cs_ast_decl.hpp:1316
static const point_syntax_element NONE
All other program points.
Definition: cs_point_syntax_element_decls.hpp:21
static const ast_field_type INT16
a 16-bit integer
Definition: cs_ast_decl.hpp:74
std::string as_string() const
Get a simple string representation of a ast_field object.
Definition: cs_ast_decl.hpp:1855
static const ast_field_type BYTES
a std::string representing unencoded data
Definition: cs_ast_decl.hpp:172
csuint16 as_uint16() const
Get the value from an ast_field of type ast_field_type::UINT16.
Definition: cs_ast_decl.hpp:1346
int stable_cmp(const ast_field &other) const
Compare with another ast_field, with stable results across sufficiently-similar analyses.
Definition: cs_ast_decl.hpp:934
size_t num_fields() const
For an ast_field of type ast_field_type::AST, get the number of fields contained in the represented a...
Definition: cs_ast_decl.hpp:1810
static const ast_field_type CONST_STR64
a utf-8 encoded std::string
Definition: cs_ast_decl.hpp:158
static const ast_traverse_directives NONE
No directives set.
Definition: cs_ast_decl.hpp:337
size_t num_fields() const
Get the number of fields in an ast (that is, the number of children plus the number of attributes)...
Definition: cs_ast.hpp:141
static const ast_traverse_flags POSTORDER
Postorder traversal.
Definition: cs_ast_decl.hpp:305
static const ast_field_type ENUMERATION
an element of an AST helper enumeration, as a cs_ast_enum_value (C API only: for other languages...
Definition: cs_ast_decl.hpp:53
The result of an API operation.
Definition: cs_result.hpp:50
csint64 as_int64() const
Get the value from an ast_field of type ast_field_type::INT64.
Definition: cs_ast_decl.hpp:1391
static const ast_field_type BOOLEAN
a bool
Definition: cs_ast_decl.hpp:46
csuint32 as_uint32() const
Get the value from an ast_field of type ast_field_type::UINT32.
Definition: cs_ast_decl.hpp:1376
ast operator*() const
Get the value from an ast_field of type ast_field_type::AST.
Definition: cs_ast_decl.hpp:1592
Enumeration class for AST family.
Definition: cs_ast_decl.hpp:50
float as_flt32() const
Get the value from an ast_field of type ast_field_type::FLT32.
Definition: cs_ast_decl.hpp:1421
static const ast_field_type CONST_STR
a utf-8 encoded std::string
Definition: cs_ast_decl.hpp:165
std::string as_repr() const
Get a representation of a ast object that includes information useful for debugging.
Definition: cs_ast_decl.hpp:772
std::vector< ast_field > attributes() const
Get all attributes of an ast.
Definition: cs_ast.hpp:173
A source file instance.
Definition: cs_sfileinst_decl.hpp:302
int fast_cmp(const ast_field &other) const
If this is ast-typed, applies ast::fast_cmp() to this.as_ast(); otherwise behaves just like cmp()...
Definition: cs_ast_decl.hpp:946
static const ast_field_type INT64
a 64-bit integer
Definition: cs_ast_decl.hpp:102
std::string as_string() const
Get a simple string representation of a ast object.
Definition: cs_ast_decl.hpp:746
static const ast_field_type UINT8
an unsigned 8-bit integer
Definition: cs_ast_decl.hpp:67
cs::iterator_adapter
Iterator class template.
Definition: cs_iterator_adapter.hpp:65
An AST Pattern.
Definition: cs_ast_decl.hpp:2289
int stable_cmp(const ast &other) const
Compare with another ast, with stable results across sufficiently-similar analyses.
Definition: cs_ast_decl.hpp:480
static const ast_traverse_directives SKIP_CHILDREN
Skip the children of the current node, but continue with remainder of traversal.
Definition: cs_ast_decl.hpp:344
bool is_a(ast_class c) const
Check: is an ast an instance of the specified ast_class?
Definition: cs_ast_decl.hpp:504
A field (child or attribute) of an Abstract Syntax Tree (class ast).
Definition: cs_ast_decl.hpp:898
static const ast_field_type UINT16
an unsigned 16-bit integer
Definition: cs_ast_decl.hpp:81
A compilation unit.
Definition: cs_compunit_decl.hpp:70
ast_ordinal ordinal() const
Get the ast_ordinal associated with an ast_field.
Definition: cs_ast_decl.hpp:1196
static const ast_traverse_flags RIGHT_TO_LEFT
Right-to-left traversal.
Definition: cs_ast_decl.hpp:302
ast_class get_class() const
Get ast_class to which an ast belongs.
Definition: cs_ast_decl.hpp:492
static const ast_field_type FLT64
a 64-bit float
Definition: cs_ast_decl.hpp:137
symbol as_symbol() const
Get the value from an ast_field whose type is ast_field_type::ABS_LOC.
Definition: cs_ast.hpp:44
Enumeration class for AST field (child or attribute; ast_field) types.
Definition: cs_ast_decl.hpp:269
Iterator over the Abstract Syntax Trees (ASTs, ast) in the tree rooted at a particular ast...
Definition: cs_tplt_instantiations.hpp:585
std::vector< ast_field > fields() const
Get all fields (that is, all children and all attributes) of an ast.
Definition: cs_ast.hpp:157
Describe an error in compiling an ast_pattern.
Definition: cs_ast_decl.hpp:2213
csint32 as_int32() const
Get the value from an ast_field of type ast_field_type::INT32.
Definition: cs_ast_decl.hpp:1361