23 #include <unordered_map>
30 #include "abg-internal.h"
32 ABG_BEGIN_EXPORT_DECLARATIONS
49 using std::shared_ptr;
50 using std::dynamic_pointer_cast;
51 using std::static_pointer_cast;
54 using std::ostringstream;
58 using std::unordered_map;
71 mutable unsigned long long m_cur_id;
75 {
return ++m_cur_id; }
83 get_environment()
const
93 return env.
intern(o.str());
101 get_id_with_prefix(
const string& prefix)
const
104 o << prefix << get_new_id();
106 return env.
intern(o.str());
116 struct non_canonicalized_type_hash
135 return h(p->get_pretty_representation(
false,
151 struct non_canonicalized_type_equal
177 typedef std::unordered_set<const type_base*> type_ptr_set_type;
183 typedef std::unordered_set<
const type_base*,
184 non_canonicalized_type_hash,
185 non_canonicalized_type_equal>
193 non_canonicalized_type_hash,
194 non_canonicalized_type_equal>
200 struct function_tdecl_hash
203 {
return reinterpret_cast<size_t>(f.get());}
207 string, function_tdecl_hash>
208 fn_tmpl_shared_ptr_map;
210 struct class_tdecl_hash
213 {
return reinterpret_cast<size_t>(c.get());}
218 class_tdecl_hash> class_tmpl_shared_ptr_map;
222 const environment& m_env;
223 id_manager m_id_manager;
227 bool m_write_architecture;
228 bool m_write_corpus_path;
229 bool m_write_comp_dir;
230 bool m_write_elf_needed;
231 bool m_write_undefined_symbols;
232 bool m_write_parameter_names;
234 bool m_write_default_sizes;
236 mutable type_ptr_map m_type_id_map;
238 mutable unordered_set<uint32_t> m_used_type_id_hashes;
239 mutable type_ptr_set_type m_emitted_type_set;
242 type_ptr_set_type m_referenced_types_set;
243 fn_type_ptr_set_type m_referenced_fn_types_set;
244 fn_tmpl_shared_ptr_map m_fn_tmpl_id_map;
245 class_tmpl_shared_ptr_map m_class_tmpl_id_map;
248 unordered_set<interned_string, hash_interned_string> m_emitted_decls_set;
249 unordered_set<string> m_emitted_corpora_set;
260 write_context(
const environment& env, ostream& os)
266 m_write_architecture(true),
267 m_write_corpus_path(true),
268 m_write_comp_dir(true),
269 m_write_elf_needed(true),
270 m_write_undefined_symbols(true),
271 m_write_parameter_names(true),
273 m_write_default_sizes(true),
274 m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
281 get_environment()
const
286 {
return get_environment().get_config();}
320 get_write_architecture()
321 {
return m_write_architecture;}
328 {m_write_architecture = f;}
334 get_write_elf_needed()
335 {
return m_write_elf_needed;}
342 {m_write_elf_needed = f;}
348 get_write_undefined_symbols()
const
349 {
return m_write_undefined_symbols;}
356 {m_write_undefined_symbols = f;}
362 get_write_default_sizes()
363 {
return m_write_default_sizes;}
370 {m_write_default_sizes = f;}
376 get_write_corpus_path()
377 {
return m_write_corpus_path;}
384 {m_write_corpus_path = f;}
391 {
return m_write_comp_dir;}
398 {m_write_comp_dir = f;}
405 {
return m_short_locs;}
418 get_write_parameter_names()
const
419 {
return m_write_parameter_names;}
426 {m_write_parameter_names = f;}
435 get_show_locs()
const
436 {
return m_show_locs;}
454 get_type_id_style()
const
455 {
return m_type_id_style;}
464 {m_type_id_style = style;}
471 get_id_manager()
const
472 {
return m_id_manager;}
476 {
return m_id_manager;}
480 type_has_existing_id(type_base_sptr type)
const
481 {
return type_has_existing_id(type.get());}
485 type_has_existing_id(type_base* type)
const
488 return m_type_id_map.find(type) != m_type_id_map.end();
496 get_id_for_type(
const type_base_sptr& t)
497 {
return get_id_for_type(t.get());}
504 get_id_for_type(
const type_base* type)
const
508 auto it = m_type_id_map.find(c);
509 if (it != m_type_id_map.end())
512 switch (m_type_id_style)
514 case SEQUENCE_TYPE_ID_STYLE:
516 interned_string
id = get_id_manager().get_id_with_prefix(
"type-id-");
517 return m_type_id_map[c] = id;
519 case HASH_TYPE_ID_STYLE:
521 interned_string pretty = c->get_cached_pretty_representation(
true);
523 while (!m_used_type_id_hashes.insert(hash).second)
525 std::ostringstream os;
526 os << std::hex << std::setfill(
'0') << std::setw(8) <<
hash;
527 return m_type_id_map[c] = c->get_environment().intern(os.str());
531 return interned_string();
535 get_id_for_fn_tmpl(
const function_tdecl_sptr& f)
537 fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
538 if (it == m_fn_tmpl_id_map.end())
540 string id = get_id_manager().get_id_with_prefix(
"fn-tmpl-id-");
541 m_fn_tmpl_id_map[f] = id;
544 return m_fn_tmpl_id_map[f];
548 get_id_for_class_tmpl(
const class_tdecl_sptr& c)
550 class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
551 if (it == m_class_tmpl_id_map.end())
553 string id = get_id_manager().get_id_with_prefix(
"class-tmpl-id-");
554 m_class_tmpl_id_map[c] = id;
557 return m_class_tmpl_id_map[c];
563 m_type_id_map.clear();
574 const type_ptr_set_type&
575 get_referenced_types()
const
576 {
return m_referenced_types_set;}
582 const fn_type_ptr_set_type&
583 get_referenced_function_types()
const
584 {
return m_referenced_fn_types_set;}
590 has_non_emitted_referenced_types()
const
592 for (
const auto t : get_referenced_types())
593 if (!type_is_emitted(t))
605 record_type_as_referenced(
const type_base_sptr& type)
611 m_referenced_fn_types_set.insert(f);
613 m_referenced_types_set.insert(t);
624 type_is_referenced(
const type_base_sptr& type)
628 return (m_referenced_fn_types_set.find(f)
629 != m_referenced_fn_types_set.end());
631 return m_referenced_types_set.find(t) != m_referenced_types_set.end();
645 vector<type_base*>& sorted)
648 for (type_ptr_set_type::const_iterator i = types.begin();
651 sorted.push_back(const_cast<type_base*>(*i));
653 sort(sorted.begin(), sorted.end(), comp);
667 vector<type_base_sptr> &sorted)
669 for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
672 sorted.push_back(type_base_sptr(i->second));
674 sort(sorted.begin(), sorted.end(), comp);
688 sort_types(
const vector<function_type_sptr>& types,
689 vector<type_base_sptr> &sorted)
691 for (vector<function_type_sptr>::const_iterator i = types.begin();
694 sorted.push_back(*i);
696 sort(sorted.begin(), sorted.end(), comp);
703 record_type_as_emitted(
const type_base_sptr &t)
704 {record_type_as_emitted(t.get());}
710 record_type_as_emitted(
const type_base* t)
713 m_emitted_type_set.insert(c);
723 type_is_emitted(
const type_base* t)
const
726 return (m_emitted_type_set.find(c) != m_emitted_type_set.end());
736 type_is_emitted(
const type_base_sptr& t)
const
737 {
return type_is_emitted(t.get());}
746 decl_is_emitted(
const decl_base& decl)
const
748 string repr = decl.get_pretty_representation(
true);
749 interned_string irepr = decl.get_environment().intern(repr);
750 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
760 decl_is_emitted(
const decl_base_sptr& decl)
const
764 interned_string irepr = decl->get_environment().intern(repr);
765 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
772 record_decl_as_emitted(
const decl_base_sptr& decl)
775 interned_string irepr = decl->get_environment().intern(repr);
776 m_emitted_decls_set.insert(irepr);
788 corpus_is_emitted(
const corpus_sptr& corp)
793 if (m_emitted_corpora_set.find(corp->get_path())
794 == m_emitted_corpora_set.end())
804 record_corpus_as_emitted(
const corpus_sptr& corp)
809 const string& path = corp->get_path();
811 m_emitted_corpora_set.insert(path);
817 const type_ptr_set_type&
818 get_emitted_types_set()
const
819 {
return m_emitted_type_set;}
824 clear_referenced_types()
826 m_referenced_types_set.clear();
827 m_referenced_fn_types_set.clear();
831 get_fun_symbol_map()
const
832 {
return m_fun_symbol_map;}
836 {
return m_fun_symbol_map;}
840 static void write_location(
const location&, write_context&);
841 static void write_location(
const decl_base_sptr&, write_context&);
842 static bool write_visibility(
const decl_base_sptr&, ostream&);
843 static bool write_binding(
const decl_base_sptr&, ostream&);
844 static bool write_is_artificial(
const decl_base_sptr&, ostream&);
845 static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
846 static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
849 static void write_size_and_alignment(
const type_base_sptr, ostream&,
850 size_t default_size = 0,
851 size_t default_alignment = 0);
855 static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
859 static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
860 static bool write_elf_symbol_reference(write_context&,
864 static bool write_elf_symbol_reference(write_context&,
868 static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
870 static void write_is_anonymous(
const decl_base_sptr&, ostream&);
871 static void write_type_hash_and_cti(
const type_base_sptr&, ostream&);
872 static void write_naming_typedef(
const decl_base_sptr&, write_context&);
873 static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
874 static void write_decl_in_scope(
const decl_base_sptr&,
875 write_context&,
unsigned);
876 static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
878 write_context&,
unsigned);
879 static bool write_qualified_type_def(
const qualified_type_def_sptr&,
880 write_context&,
unsigned);
882 write_context&,
unsigned);
884 write_context&,
unsigned);
886 write_context&,
unsigned);
888 write_context&,
unsigned);
893 write_context&,
unsigned);
895 write_context&,
unsigned);
897 write_context&,
unsigned);
898 static bool write_elf_symbols_table(
const elf_symbols&,
899 write_context&,
unsigned);
901 write_context&,
bool,
unsigned);
903 write_context&,
bool,
unsigned);
905 write_context&,
unsigned);
906 static bool write_member_type_opening_tag(
const type_base_sptr&,
907 write_context&,
unsigned);
908 static bool write_member_type(
const type_base_sptr&,
909 write_context&,
unsigned);
910 static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
911 write_context&,
unsigned,
bool);
913 write_context&,
unsigned);
914 static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
915 write_context&,
unsigned,
bool);
916 static bool write_union_decl(
const union_decl_sptr&,
const string&,
917 write_context&,
unsigned);
918 static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
919 static void write_common_type_info(
const type_base_sptr&, write_context&,
920 const string&
id=
"");
921 static bool write_type(
const type_base_sptr&, write_context&,
unsigned);
922 static bool write_type_tparameter
923 (
const shared_ptr<type_tparameter>, write_context&,
unsigned);
924 static bool write_non_type_tparameter
925 (
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
926 static bool write_template_tparameter
927 (
const shared_ptr<template_tparameter>, write_context&,
unsigned);
928 static bool write_type_composition
929 (
const shared_ptr<type_composition>, write_context&,
unsigned);
930 static bool write_template_parameter(
const shared_ptr<template_parameter>,
931 write_context&,
unsigned);
932 static void write_template_parameters(
const shared_ptr<template_decl>,
933 write_context&,
unsigned);
934 static bool write_function_tdecl
935 (
const shared_ptr<function_tdecl>,
936 write_context&,
unsigned);
937 static bool write_class_tdecl
938 (
const shared_ptr<class_tdecl>,
939 write_context&,
unsigned);
940 static void do_indent(ostream&,
unsigned);
941 static void do_indent_to_level(write_context&,
unsigned,
unsigned);
942 static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
946 do_indent(ostream& o,
unsigned nb_whitespaces)
948 for (
unsigned i = 0; i < nb_whitespaces; ++i)
960 do_indent_to_level(write_context& ctxt,
961 unsigned initial_indent,
964 do_indent(ctxt.get_ostream(),
965 get_indent_to_level(ctxt, initial_indent, level));
977 get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
980 int nb_ws = initial_indent +
981 level * ctxt.get_config().get_xml_element_indent();
1001 template <
typename T>
1003 annotate(
const T& decl,
1004 write_context& ctxt,
1010 if (!ctxt.get_annotate())
1013 ostream& o = ctxt.get_ostream();
1015 do_indent(o, indent);
1037 write_context& ctxt,
1043 if (!ctxt.get_annotate())
1046 ostream& o = ctxt.get_ostream();
1048 do_indent(o, indent);
1068 write_context& ctxt,
1074 if (!ctxt.get_annotate())
1077 ostream& o = ctxt.get_ostream();
1079 do_indent(o, indent);
1081 o <<
"<!-- typedef "
1104 write_context& ctxt,
1110 if (!ctxt.get_annotate())
1113 ostream& o = ctxt.get_ostream();
1115 do_indent(o, indent);
1137 write_context& ctxt,
1143 if (!ctxt.get_annotate())
1146 ostream& o = ctxt.get_ostream();
1148 do_indent(o, indent);
1160 vector<function_decl::parameter_sptr>::const_iterator pi =
1161 fn->get_first_non_implicit_parm();
1163 for (; pi != fn->get_parameters().end(); ++pi)
1167 if (distance(pi, fn->get_parameters().end()) > 1)
1187 write_context& ctxt,
1193 if (!ctxt.get_annotate())
1196 ostream &o = ctxt.get_ostream();
1198 do_indent(o, indent);
1202 if (parm->get_variadic_marker())
1203 o <<
"variadic parameter";
1206 if (parm->get_is_artificial())
1208 if (parm->get_index() == 0)
1213 o <<
"parameter of type '"
1232 write_location(
const location& loc, write_context& ctxt)
1237 if (!ctxt.get_show_locs())
1241 unsigned line = 0, column = 0;
1243 loc.
expand(filepath, line, column);
1245 ostream &o = ctxt.get_ostream();
1247 if (ctxt.get_short_locs())
1251 <<
" line='" << line <<
"'"
1252 <<
" column='" << column <<
"'";
1263 write_location(
const decl_base_sptr& decl,
1264 write_context& ctxt)
1269 location loc = decl->get_location();
1273 write_location(loc, ctxt);
1285 write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1295 case decl_base::VISIBILITY_NONE:
1297 case decl_base::VISIBILITY_DEFAULT:
1300 case decl_base::VISIBILITY_PROTECTED:
1303 case decl_base::VISIBILITY_HIDDEN:
1306 case decl_base::VISIBILITY_INTERNAL:
1314 o <<
" visibility='" << str <<
"'";
1325 write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1332 shared_ptr<var_decl> var =
1333 dynamic_pointer_cast<var_decl>(decl);
1335 bind = var->get_binding();
1338 shared_ptr<function_decl> fun =
1339 dynamic_pointer_cast<function_decl>(decl);
1341 bind = fun->get_binding();
1347 case decl_base::BINDING_NONE:
1349 case decl_base::BINDING_LOCAL:
1352 case decl_base::BINDING_GLOBAL:
1355 case decl_base::BINDING_WEAK:
1361 o <<
" binding='" << str <<
"'";
1375 write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1380 if (decl->get_is_artificial())
1381 o <<
" is-artificial='yes'";
1395 write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1400 corpus* c = t->get_corpus();
1404 if (!c->recording_types_reachable_from_public_interface_supported()
1405 || c->type_is_reachable_from_public_interfaces(*t))
1408 o <<
" is-non-reachable='yes'";
1421 write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1424 corpus_group* group = corpus->get_group();
1426 if (corpus->recording_types_reachable_from_public_interface_supported())
1428 o <<
" tracking-non-reachable-types='yes'";
1449 write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1450 size_t default_size,
size_t default_alignment)
1452 size_t size_in_bits = decl->get_size_in_bits();
1453 if (size_in_bits != default_size)
1454 o <<
" size-in-bits='" << size_in_bits <<
"'";
1456 size_t alignment_in_bits = decl->get_alignment_in_bits();
1457 if (alignment_in_bits != default_alignment)
1458 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1466 write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1468 if (decl->is_non_finite())
1469 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1471 size_t size_in_bits = decl->get_size_in_bits();
1473 o <<
" size-in-bits='" << size_in_bits <<
"'";
1476 size_t alignment_in_bits = decl->get_alignment_in_bits();
1477 if (alignment_in_bits)
1478 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1488 string access_str =
"private";
1492 case private_access:
1493 access_str =
"private";
1496 case protected_access:
1497 access_str =
"protected";
1501 access_str =
"public";
1508 o <<
" access='" << access_str <<
"'";
1519 o <<
" layout-offset-in-bits='"
1526 write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1531 if (base->get_offset_in_bits() >= 0)
1532 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1541 write_access(decl_base_sptr member, ostream& o)
1558 o <<
" vtable-offset='" << voffset <<
"'";
1575 case elf_symbol::NOTYPE_TYPE:
1578 case elf_symbol::OBJECT_TYPE:
1579 repr =
"object-type";
1581 case elf_symbol::FUNC_TYPE:
1584 case elf_symbol::SECTION_TYPE:
1585 repr =
"section-type";
1587 case elf_symbol::FILE_TYPE:
1590 case elf_symbol::COMMON_TYPE:
1591 repr =
"common-type";
1593 case elf_symbol::TLS_TYPE:
1596 case elf_symbol::GNU_IFUNC_TYPE:
1597 repr =
"gnu-ifunc-type";
1604 o <<
" type='" << repr <<
"'";
1620 case elf_symbol::LOCAL_BINDING:
1621 repr =
"local-binding";
1623 case elf_symbol::GLOBAL_BINDING:
1624 repr =
"global-binding";
1626 case elf_symbol::WEAK_BINDING:
1627 repr =
"weak-binding";
1629 case elf_symbol::GNU_UNIQUE_BINDING:
1630 repr =
"gnu-unique-binding";
1633 repr =
"no-binding";
1637 o <<
" binding='" << repr <<
"'";
1653 case elf_symbol::DEFAULT_VISIBILITY:
1654 repr =
"default-visibility";
1656 case elf_symbol::PROTECTED_VISIBILITY:
1657 repr =
"protected-visibility";
1659 case elf_symbol::HIDDEN_VISIBILITY:
1660 repr =
"hidden-visibility";
1662 case elf_symbol::INTERNAL_VISIBILITY:
1663 repr =
"internal-visibility";
1666 repr =
"default-visibility";
1670 o <<
" visibility='" << repr <<
"'";
1681 write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1683 if (!sym.is_main_symbol() || !sym.has_aliases())
1687 std::vector<std::string> aliases;
1688 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1689 s = s->get_next_alias())
1691 if (!s->is_public())
1694 if (s->is_suppressed())
1697 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1700 aliases.push_back(s->get_id_string());
1703 if (!aliases.empty())
1706 std::string separator;
1707 for (
const auto& alias : aliases)
1709 out << separator << alias;
1736 write_elf_symbol_reference(write_context& ctxt,
1737 const elf_symbol& sym,
1743 s = abi.lookup_variable_symbol(sym);
1749 || (!ctxt.get_write_undefined_symbols() && !s->is_defined()))
1753 const elf_symbol* main = sym.get_main_symbol().get();
1754 const elf_symbol* alias = &sym;
1755 bool found = !alias->is_suppressed();
1760 found = !alias->is_suppressed();
1765 alias = alias->get_next_alias().get();
1767 if (!alias || alias == main)
1769 found = !alias->is_suppressed();
1774 o <<
" elf-symbol-id='"
1795 write_elf_symbol_reference(write_context& ctxt,
1803 return write_elf_symbol_reference(ctxt, *sym, abi, o);
1820 write_cdtor_const_static(
bool is_ctor,
1827 o <<
" static='yes'";
1829 o <<
" constructor='yes'";
1831 o <<
" destructor='yes'";
1833 o <<
" const='yes'";
1843 write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
1845 if (d->get_is_declaration_only())
1846 o <<
" is-declaration-only='yes'";
1858 if (klass->is_struct())
1859 o <<
" is-struct='yes'";
1869 write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1871 if (decl->get_is_anonymous())
1872 o <<
" is-anonymous='yes'";
1881 write_type_hash_and_cti(
const type_base_sptr& t, ostream& o)
1883 hash_t hash = t->hash_value();
1888 o <<
" hash='" << h;
1889 if (t->priv_->canonical_type_index)
1890 o <<
"#" << t->priv_->canonical_type_index;
1902 write_naming_typedef(
const decl_base_sptr& decl, write_context& ctxt)
1907 ostream &o = ctxt.get_ostream();
1911 string id = ctxt.get_id_for_type(typedef_type);
1912 o <<
" naming-typedef-id='" <<
id <<
"'";
1913 ctxt.record_type_as_referenced(typedef_type);
1925 write_common_type_info(
const type_base_sptr& t,
1926 write_context& ctxt,
1929 decl_base_sptr d =
is_decl(t);
1931 ostream& o = ctxt.get_ostream();
1933 if (!d || (d && !d->get_is_declaration_only()))
1936 write_size_and_alignment(t, o);
1938 write_array_size_and_alignment(a, o);
1943 write_is_anonymous(d, o);
1944 write_is_declaration_only(d, o);
1945 write_location(d, ctxt);
1948 write_type_hash_and_cti(t, o);
1952 i = ctxt.get_id_for_type(t);
1953 o <<
" id='" << i <<
"'";
1955 ctxt.record_type_as_emitted(t);
1968 write_type(
const type_base_sptr& type, write_context& ctxt,
unsigned indent)
1970 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
1972 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1975 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
1977 || write_reference_type_def(dynamic_pointer_cast
1978 <reference_type_def>(type), ctxt, indent)
1979 || write_ptr_to_mbr_type(dynamic_pointer_cast
1980 <ptr_to_mbr_type>(type),
1982 || write_array_type_def(dynamic_pointer_cast
1983 <array_type_def>(type), ctxt, indent)
1984 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
1986 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
1990 || (write_function_tdecl
1991 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
1992 || (write_class_tdecl
1993 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
2011 write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
2013 if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
2015 || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
2017 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
2020 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
2022 || write_reference_type_def(dynamic_pointer_cast
2023 <reference_type_def>(decl), ctxt, indent)
2024 || write_ptr_to_mbr_type(dynamic_pointer_cast
2025 <ptr_to_mbr_type>(decl),
2027 || write_array_type_def(dynamic_pointer_cast
2028 <array_type_def>(decl), ctxt, indent)
2029 || write_array_subrange_type(dynamic_pointer_cast
2030 <array_type_def::subrange_type>(decl),
2032 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
2034 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
2036 || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
2038 || write_function_decl(dynamic_pointer_cast<method_decl>
2041 || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
2042 ctxt,
false, indent)
2045 || (write_function_tdecl
2046 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
2047 || (write_class_tdecl
2048 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
2066 write_decl_in_scope(
const decl_base_sptr& decl,
2067 write_context& ctxt,
2068 unsigned initial_indent)
2070 type_base_sptr type =
is_type(decl);
2071 if ((type && ctxt.type_is_emitted(type))
2072 || (!type && ctxt.decl_is_emitted(decl)))
2075 list<scope_decl*> scopes;
2076 for (scope_decl* s = decl->get_scope();
2079 scopes.push_front(s);
2081 ostream& o = ctxt.get_ostream();
2082 const config& c = ctxt.get_config();
2083 stack<string> closing_tags;
2084 stack<unsigned> closing_indents;
2085 unsigned indent = initial_indent;
2086 for (list<scope_decl*>::const_iterator i = scopes.begin();
2095 do_indent(o, indent);
2096 o <<
"<namespace-decl name='"
2099 closing_tags.push(
"</namespace-decl>");
2100 closing_indents.push(indent);
2107 bool do_break =
false;
2108 if (!ctxt.type_is_emitted(c))
2110 write_type(class_type, ctxt, initial_indent);
2132 || (type && !ctxt.type_is_emitted(type))
2133 || (!type && !ctxt.decl_is_emitted(decl)))
2135 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2137 closing_tags.push(
"</class-decl>");
2138 closing_indents.push(indent);
2140 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2141 write_member_type_opening_tag(type, ctxt, nb_ws);
2143 closing_tags.push(
"</member-type>");
2144 closing_indents.push(nb_ws);
2153 union_decl_sptr union_type(u, noop_deleter());
2154 if (!ctxt.type_is_emitted(u))
2156 write_type(union_type, ctxt, initial_indent);
2161 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2163 closing_tags.push(
"</union-decl>");
2164 closing_indents.push(indent);
2166 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2167 write_member_type_opening_tag(type, ctxt, nb_ws);
2169 closing_tags.push(
"</member-type>");
2170 closing_indents.push(nb_ws);
2176 indent += c.get_xml_element_indent();
2179 bool do_write =
false;
2180 if (type_base_sptr type =
is_type(decl))
2182 if (!ctxt.type_is_emitted(type))
2187 if (!ctxt.decl_is_emitted(decl))
2192 write_decl(decl, ctxt, indent);
2194 while (!closing_tags.empty())
2196 do_indent(o, closing_indents.top());
2197 o << closing_tags.top() <<
"\n";
2199 closing_indents.pop();
2213 ostream& default_output_stream)
2230 {ctxt.set_show_locs(flag);}
2242 {ctxt.set_annotate(flag);}
2253 {ctxt.set_ostream(os);}
2265 {ctxt.set_write_architecture(flag);}
2277 {ctxt.set_write_corpus_path(flag);}
2289 {ctxt.set_write_comp_dir(flag);}
2301 {ctxt.set_short_locs(flag);}
2313 {ctxt.set_write_parameter_names(flag);}
2325 {ctxt.set_write_elf_needed(flag);}
2337 {ctxt.set_write_undefined_symbols(flag);}
2352 {ctxt.set_write_default_sizes(flag);}
2363 {ctxt.set_type_id_style(style);}
2378 write_canonical_types_of_scope(
const scope_decl &scope,
2379 write_context &ctxt,
2380 const unsigned indent,
2386 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2387 i != canonical_types.end();
2390 if (ctxt.type_is_emitted(*i))
2393 write_member_type(*i, ctxt, indent);
2395 write_type(*i, ctxt, indent);
2417 referenced_type_should_be_emitted(
const type_base *t,
2418 const write_context& ctxt,
2419 const translation_unit& tu,
2422 if ((tu_is_last || (t->get_translation_unit()
2423 && (t->get_translation_unit()->get_absolute_path()
2424 == tu.get_absolute_path())))
2425 && !ctxt.type_is_emitted(t))
2442 write_referenced_types(write_context & ctxt,
2443 const translation_unit& tu,
2444 const unsigned indent,
2447 const config& c = ctxt.get_config();
2455 type_ptr_set_type referenced_types_to_emit;
2460 for (type_ptr_set_type::const_iterator i =
2461 ctxt.get_referenced_types().begin();
2462 i != ctxt.get_referenced_types().end();
2464 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2465 referenced_types_to_emit.insert(*i);
2467 for (fn_type_ptr_set_type::const_iterator i =
2468 ctxt.get_referenced_function_types().begin();
2469 i != ctxt.get_referenced_function_types().end();
2471 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2472 referenced_types_to_emit.insert(*i);
2475 while (!referenced_types_to_emit.empty())
2480 vector<type_base*> sorted_referenced_types;
2481 ctxt.sort_types(referenced_types_to_emit,
2482 sorted_referenced_types);
2485 for (vector<type_base*>::const_iterator i =
2486 sorted_referenced_types.begin();
2487 i != sorted_referenced_types.end();
2493 if (!ctxt.type_is_emitted(t))
2497 decl_base_sptr decl(d, noop_deleter());
2498 write_decl_in_scope(decl, ctxt,
2499 indent + c.get_xml_element_indent());
2504 write_function_type(fn_type, ctxt,
2505 indent + c.get_xml_element_indent());
2514 referenced_types_to_emit.clear();
2526 for (type_ptr_set_type::const_iterator i =
2527 ctxt.get_referenced_types().begin();
2528 i != ctxt.get_referenced_types().end();
2530 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2531 referenced_types_to_emit.insert(*i);
2559 const unsigned indent,
2567 && ctxt.has_non_emitted_referenced_types())
2570 ostream& o = ctxt.get_ostream();
2571 const config& c = ctxt.get_config();
2573 do_indent(o, indent);
2580 std::string tu_path = tu.
get_path();
2581 if (ctxt.get_short_locs())
2583 if (!tu_path.empty())
2587 o <<
" comp-dir-path='"
2590 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
2604 ctxt, indent + c.get_xml_element_indent());
2607 const declarations& decls = tu.
get_global_scope()->get_sorted_member_decls();
2609 for (
const decl_base_sptr& decl : decls)
2611 if (type_base_sptr t =
is_type(decl))
2618 if (class_type->get_is_declaration_only()
2619 && !ctxt.type_is_emitted(class_type))
2620 write_type(class_type, ctxt,
2621 indent + c.get_xml_element_indent());
2624 write_type(t, ctxt, indent + c.get_xml_element_indent());
2628 if (!ctxt.decl_is_emitted(decl))
2629 write_decl_in_scope(decl, ctxt, indent + c.get_xml_element_indent());
2633 if (!ctxt.decl_is_emitted(decl))
2634 write_decl(decl, ctxt, indent + c.get_xml_element_indent());
2641 for (
auto undefined_function : abi->get_sorted_undefined_functions())
2645 if (f->get_translation_unit() != &tu || ctxt.decl_is_emitted(f))
2648 write_decl(f, ctxt, indent + c.get_xml_element_indent());
2654 for (
auto undefined_var : abi->get_sorted_undefined_variables())
2657 if (v->get_translation_unit() != &tu || ctxt.decl_is_emitted(v))
2660 write_decl(v, ctxt, indent + c.get_xml_element_indent());
2663 write_referenced_types(ctxt, tu, indent, is_last);
2668 vector<type_base_sptr> sorted_types;
2669 ctxt.sort_types(t, sorted_types);
2671 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
2672 i != sorted_types.end();
2677 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
2684 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
2689 write_referenced_types(ctxt, tu, indent, is_last);
2691 do_indent(o, indent);
2692 o <<
"</abi-instr>\n";
2710 write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
2715 ostream& o = ctxt.get_ostream();
2717 annotate(d, ctxt, indent);
2719 do_indent(o, indent);
2723 write_common_type_info(d, ctxt);
2743 write_context& ctxt,
unsigned indent)
2745 if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
2748 ostream& o = ctxt.get_ostream();
2749 const config &c = ctxt.get_config();
2751 annotate(decl, ctxt, indent);
2753 do_indent(o, indent);
2755 o <<
"<namespace-decl name='"
2760 typedef declarations::const_iterator const_iterator;
2761 const declarations& d = decl->get_sorted_member_decls();
2763 write_canonical_types_of_scope(*decl, ctxt,
2764 indent + c.get_xml_element_indent());
2766 for (const_iterator i = d.begin(); i != d.end(); ++i)
2768 if (type_base_sptr t =
is_type(*i))
2769 if (ctxt.type_is_emitted(t))
2773 write_decl(*i, ctxt, indent + c.get_xml_element_indent());
2776 do_indent(o, indent);
2777 o <<
"</namespace-decl>\n";
2801 write_qualified_type_def(
const qualified_type_def_sptr& decl,
2803 write_context& ctxt,
2809 ostream& o = ctxt.get_ostream();
2812 type_base_sptr underlying_type = decl->get_underlying_type();
2814 annotate(decl, ctxt, indent);
2816 do_indent(o, indent);
2817 o <<
"<qualified-type-def type-id='"
2818 << ctxt.get_id_for_type(underlying_type)
2821 ctxt.record_type_as_referenced(underlying_type);
2823 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
2824 o <<
" const='yes'";
2825 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
2826 o <<
" volatile='yes'";
2827 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
2828 o <<
" restrict='yes'";
2830 write_common_type_info(decl, ctxt,
id);
2848 write_qualified_type_def(
const qualified_type_def_sptr& decl,
2849 write_context& ctxt,
2851 {
return write_qualified_type_def(decl,
"", ctxt, indent);}
2873 write_context& ctxt,
2879 ostream& o = ctxt.get_ostream();
2881 annotate(decl, ctxt, indent);
2883 do_indent(o, indent);
2887 o <<
"<pointer-type-def ";
2889 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2891 i = ctxt.get_id_for_type(pointed_to_type);
2893 o <<
"type-id='" << i <<
"'";
2895 ctxt.record_type_as_referenced(pointed_to_type);
2897 write_common_type_info(decl, ctxt,
id);
2915 write_context& ctxt,
2917 {
return write_pointer_type_def(decl,
"", ctxt, indent);}
2939 write_context& ctxt,
2945 annotate(decl->get_canonical_type(), ctxt, indent);
2947 ostream& o = ctxt.get_ostream();
2949 do_indent(o, indent);
2951 o <<
"<reference-type-def kind='";
2952 if (decl->is_lvalue())
2958 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2959 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
2961 ctxt.record_type_as_referenced(pointed_to_type);
2964 ctxt.record_type_as_referenced(f);
2966 write_common_type_info(decl, ctxt,
id);
2984 write_context& ctxt,
2986 {
return write_reference_type_def(decl,
"", ctxt, indent);}
3002 const string&
id, write_context& ctxt,
3008 annotate(decl->get_canonical_type(), ctxt, indent);
3010 ostream& o = ctxt.get_ostream();
3012 do_indent(o, indent);
3014 o <<
"<pointer-to-member-type";
3016 type_base_sptr member_type = decl->get_member_type();
3017 string i = ctxt.get_id_for_type(member_type);
3018 o <<
" member-type-id='" << i <<
"'";
3019 ctxt.record_type_as_referenced(member_type);
3021 type_base_sptr containing_type = decl->get_containing_type();
3022 i = ctxt.get_id_for_type(containing_type);
3023 o <<
" containing-type-id='" << i <<
"'";
3024 ctxt.record_type_as_referenced(containing_type);
3026 write_common_type_info(decl, ctxt,
id);
3044 write_context& ctxt,
unsigned indent)
3045 {
return write_ptr_to_mbr_type(decl,
"", ctxt, indent);}
3058 write_context& ctxt,
3064 annotate(decl, ctxt, indent);
3066 ostream& o = ctxt.get_ostream();
3068 do_indent(o, indent);
3072 if (!decl->get_name().empty())
3073 o <<
" name='" << decl->get_name() <<
"'";
3076 if (decl->is_non_finite())
3079 o << decl->get_length();
3084 || decl->get_length() == 0
3085 || (decl->get_length() ==
3086 (uint64_t) (decl->get_upper_bound()
3087 - decl->get_lower_bound() + 1)));
3088 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
3089 << decl->get_upper_bound() <<
"'";
3091 type_base_sptr underlying_type = decl->get_underlying_type();
3092 if (underlying_type)
3095 << ctxt.get_id_for_type(underlying_type)
3097 ctxt.record_type_as_referenced(underlying_type);
3100 write_common_type_info(decl, ctxt);
3127 write_context& ctxt,
3133 annotate(decl, ctxt, indent);
3135 ostream& o = ctxt.get_ostream();
3137 do_indent(o, indent);
3138 o <<
"<array-type-def";
3140 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
3142 type_base_sptr element_type = decl->get_element_type();
3143 o <<
" type-id='" << ctxt.get_id_for_type(element_type) <<
"'";
3145 ctxt.record_type_as_referenced(element_type);
3147 write_common_type_info(decl, ctxt,
id);
3149 if (!decl->get_dimension_count())
3155 vector<array_type_def::subrange_sptr>::const_iterator si;
3157 for (si = decl->get_subranges().begin();
3158 si != decl->get_subranges().end(); ++si)
3160 unsigned local_indent =
3161 indent + ctxt.get_config().get_xml_element_indent();
3162 write_array_subrange_type(*si, ctxt, local_indent);
3165 do_indent(o, indent);
3166 o <<
"</array-type-def>\n";
3183 write_context& ctxt,
3185 {
return write_array_type_def(decl,
"", ctxt, indent);}
3207 write_context& ctxt,
3215 annotate(decl->get_canonical_type(), ctxt, indent);
3217 ostream& o = ctxt.get_ostream();
3219 do_indent(o, indent);
3222 write_naming_typedef(decl, ctxt);
3223 write_is_artificial(decl, o);
3224 write_is_non_reachable(
is_type(decl), o);
3226 if (!decl->get_linkage_name().empty())
3227 o <<
" linkage-name='"
3231 write_common_type_info(decl, ctxt,
id);
3235 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3236 o <<
"<underlying-type type-id='"
3237 << ctxt.get_id_for_type(decl->get_underlying_type())
3240 for (enum_type_decl::enumerators::const_iterator i =
3241 decl->get_enumerators().begin();
3242 i != decl->get_enumerators().end();
3245 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3246 o <<
"<enumerator name='"
3253 do_indent(o, indent);
3254 o <<
"</enum-decl>\n";
3270 write_context& ctxt,
3272 {
return write_enum_type_decl(decl,
"", ctxt, indent);}
3286 write_context& ctxt,
3292 ostream &o = ctxt.get_ostream();
3294 annotate(sym, ctxt, indent);
3295 do_indent(o, indent);
3297 if (sym->is_variable() && sym->get_size())
3298 o <<
" size='" << sym->get_size() <<
"'";
3300 if (!sym->get_version().is_empty())
3302 o <<
" version='" << sym->get_version().str() <<
"'";
3303 o <<
" is-default-version='";
3304 if (sym->get_version().is_default())
3311 write_elf_symbol_type(sym->get_type(), o);
3313 write_elf_symbol_binding(sym->get_binding(), o);
3315 write_elf_symbol_visibility(sym->get_visibility(), o);
3317 write_elf_symbol_aliases(*sym, o);
3319 o <<
" is-defined='";
3320 if (sym->is_defined())
3326 if (sym->is_common_symbol())
3327 o <<
" is-common='yes'";
3329 if (sym->get_crc().has_value())
3331 << std::hex << std::showbase << sym->get_crc().value()
3332 << std::dec << std::noshowbase <<
"'";
3334 if (sym->get_namespace().has_value())
3335 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3354 write_context& ctxt,
3360 for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
3361 write_elf_symbol(*it, ctxt, indent);
3377 write_elf_needed(
const vector<string>& needed,
3378 write_context& ctxt,
3384 ostream& o = ctxt.get_ostream();
3386 for (vector<string>::const_iterator i = needed.begin();
3390 do_indent(o, indent);
3391 o <<
"<dependency name='" << *i <<
"'/>\n";
3416 write_context& ctxt,
3422 ostream &o = ctxt.get_ostream();
3424 annotate(decl, ctxt, indent);
3426 do_indent(o, indent);
3428 o <<
"<typedef-decl name='"
3432 type_base_sptr underlying_type = decl->get_underlying_type();
3433 string type_id = ctxt.get_id_for_type(underlying_type);
3434 o <<
" type-id='" << type_id <<
"'";
3435 ctxt.record_type_as_referenced(underlying_type);
3437 write_common_type_info(decl, ctxt,
id);
3455 write_context& ctxt,
3457 {
return write_typedef_decl(decl,
"", ctxt, indent);}
3472 write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
3473 bool write_linkage_name,
unsigned indent)
3478 annotate(decl, ctxt, indent);
3480 ostream &o = ctxt.get_ostream();
3482 do_indent(o, indent);
3485 type_base_sptr var_type = decl->get_type();
3486 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
3487 ctxt.record_type_as_referenced(var_type);
3489 if (write_linkage_name)
3491 const string& linkage_name = decl->get_linkage_name();
3492 if (!linkage_name.empty())
3493 o <<
" mangled-name='" << linkage_name <<
"'";
3496 write_visibility(decl, o);
3498 write_binding(decl, o);
3500 write_location(decl, ctxt);
3503 if (corpus* abi = decl->get_corpus())
3504 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3508 ctxt.record_decl_as_emitted(decl);
3527 bool skip_first_parm,
3528 write_context& ctxt,
3532 fun_type->get_canonical_type()
3536 unsigned cur_indent =
3537 indent + ctxt.get_config().get_xml_element_indent();
3539 ostream &o = ctxt.get_ostream();
3541 type_base_sptr parm_type;
3542 auto pi = t->get_parameters().begin();
3543 for ((skip_first_parm && pi != t->get_parameters().end()) ? ++pi: pi;
3544 pi != t->get_parameters().end();
3547 if ((*pi)->get_variadic_marker())
3549 do_indent(o, cur_indent);
3550 o <<
"<parameter is-variadic='yes'";
3554 parm_type = (*pi)->get_type();
3556 annotate(*pi, ctxt, cur_indent);
3557 do_indent(o, cur_indent);
3559 o <<
"<parameter type-id='"
3560 << ctxt.get_id_for_type(parm_type)
3562 ctxt.record_type_as_referenced(parm_type);
3564 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3567 write_is_artificial(*pi, o);
3568 write_location((*pi)->get_location(), ctxt);
3572 if (shared_ptr<type_base> return_type = t->get_return_type())
3574 annotate(return_type , ctxt, cur_indent);
3575 do_indent(o, cur_indent);
3576 o <<
"<return type-id='"
3577 << ctxt.get_id_for_type(return_type)
3579 ctxt.record_type_as_referenced(return_type);
3597 bool skip_first_parm,
unsigned indent)
3602 annotate(decl, ctxt, indent);
3604 ostream &o = ctxt.get_ostream();
3606 do_indent(o, indent);
3608 o <<
"<function-decl name='"
3612 if (!decl->get_linkage_name().empty())
3613 o <<
" mangled-name='"
3616 write_location(decl, ctxt);
3618 if (decl->is_declared_inline())
3619 o <<
" declared-inline='yes'";
3621 write_visibility(decl, o);
3623 write_binding(decl, o);
3625 write_size_and_alignment(decl->get_type(), o,
3626 (ctxt.get_write_default_sizes()
3628 : decl->get_translation_unit()->get_address_size()),
3631 if (corpus* abi = decl->get_corpus())
3632 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3634 write_type_hash_and_cti(decl->get_type(), o);
3638 write_fn_parm_and_return_types(decl->get_type(),
3642 do_indent(o, indent);
3643 o <<
"</function-decl>\n";
3645 ctxt.record_decl_as_emitted(decl);
3661 write_context& ctxt,
unsigned indent)
3670 fun_type->get_canonical_type()
3674 ostream &o = ctxt.get_ostream();
3676 annotate(fn_type, ctxt, indent);
3678 do_indent(o, indent);
3680 o <<
"<function-type";
3685 o <<
" method-class-id='"
3686 << ctxt.get_id_for_type(method_type->get_class_type())
3689 write_cdtor_const_static(
false,
false,
3690 method_type->get_is_const(),
3694 write_common_type_info(fn_type, ctxt);
3698 write_fn_parm_and_return_types(fn_type,
false,
3701 do_indent(o, indent);
3703 o <<
"</function-type>\n";
3728 write_context& ctxt,
3730 bool prepare_to_handle_empty)
3735 ostream& o = ctxt.get_ostream();
3737 do_indent_to_level(ctxt, indent, 0);
3741 write_is_struct(decl, o);
3743 write_is_artificial(decl, o);
3745 write_is_non_reachable(
is_type(decl), o);
3747 write_naming_typedef(decl, ctxt);
3749 write_visibility(decl, o);
3751 if (decl->get_earlier_declaration())
3754 o <<
" def-of-decl-id='"
3755 << ctxt.get_id_for_type(
is_type(decl->get_earlier_declaration()))
3759 write_common_type_info(decl, ctxt,
id);
3761 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
3787 write_union_decl_opening_tag(
const union_decl_sptr& decl,
3789 write_context& ctxt,
3791 bool prepare_to_handle_empty)
3796 ostream& o = ctxt.get_ostream();
3798 do_indent_to_level(ctxt, indent, 0);
3802 write_naming_typedef(decl, ctxt);
3804 write_visibility(decl, o);
3806 write_is_artificial(decl, o);
3808 write_is_non_reachable(
is_type(decl), o);
3810 write_common_type_info(decl, ctxt,
id);
3812 if (prepare_to_handle_empty && decl->has_no_member())
3838 write_context& ctxt,
3846 annotate(decl, ctxt, indent);
3848 ostream& o = ctxt.get_ostream();
3850 if (decl->get_is_declaration_only())
3854 const environment& env = ctxt.get_environment();
3872 *decl->get_corpus(),
3875 for (
auto t : result)
3877 type_base_sptr type(t);
3879 for (
auto m : c->get_member_types())
3880 if (member_types.find(m) != member_types.end())
3881 member_types.insert(m);
3885 if (!member_types.empty())
3891 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3893 member_types.empty());
3895 vector<type_base_sptr> sorted_types;
3898 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3900 for (
auto t : sorted_types)
3901 if (!ctxt.type_is_emitted(t))
3902 write_member_type(t, ctxt, nb_ws);
3904 if (!member_types.empty())
3905 o << indent <<
"</class-decl>\n";
3910 for (
auto t : result)
3911 ctxt.record_type_as_emitted(type_base_sptr(t));
3916 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3919 if (!decl->has_no_base_nor_member())
3921 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3922 type_base_sptr base_type;
3923 for (class_decl::base_specs::const_iterator base =
3924 decl->get_base_specifiers().begin();
3925 base != decl->get_base_specifiers().end();
3928 annotate((*base)->get_base_class(), ctxt, nb_ws);
3929 do_indent(o, nb_ws);
3932 write_access((*base)->get_access_specifier(), o);
3934 write_layout_offset (*base, o);
3936 if ((*base)->get_is_virtual ())
3937 o <<
" is-virtual='yes'";
3939 base_type = (*base)->get_base_class();
3941 << ctxt.get_id_for_type(base_type)
3944 ctxt.record_type_as_referenced(base_type);
3947 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
3950 for (class_decl::member_types::const_iterator ti =
3951 decl->get_sorted_member_types().begin();
3952 ti != decl->get_sorted_member_types().end();
3954 if (!(*ti)->get_naked_canonical_type())
3955 write_member_type(*ti, ctxt, nb_ws);
3958 for (
const auto& s_dm : decl->get_static_data_members())
3960 do_indent(o, nb_ws);
3961 o <<
"<data-member";
3966 write_cdtor_const_static(
false,
3971 write_layout_offset(s_dm, o);
3974 write_var_decl(s_dm, ctxt, is_static,
3975 get_indent_to_level(ctxt, indent, 2));
3977 do_indent_to_level(ctxt, indent, 1);
3978 o <<
"</data-member>\n";
3982 for (
const auto& dm : decl->get_non_static_data_members())
3984 do_indent(o, nb_ws);
3985 o <<
"<data-member";
3989 write_cdtor_const_static(
false,
3994 write_layout_offset(dm, o);
3997 write_var_decl(dm, ctxt, is_static,
3998 get_indent_to_level(ctxt, indent, 2));
4000 do_indent_to_level(ctxt, indent, 1);
4001 o <<
"</data-member>\n";
4004 for (class_decl::member_functions::const_iterator f =
4005 decl->get_member_functions().begin();
4006 f != decl->get_member_functions().end();
4017 do_indent(o, nb_ws);
4018 o <<
"<member-function";
4027 write_function_decl(fn, ctxt,
4029 get_indent_to_level(ctxt, indent, 2));
4031 do_indent_to_level(ctxt, indent, 1);
4032 o <<
"</member-function>\n";
4035 for (class_decl::member_functions::const_iterator f =
4036 decl->get_virtual_mem_fns().begin();
4037 f != decl->get_virtual_mem_fns().end();
4044 do_indent(o, nb_ws);
4045 o <<
"<member-function";
4052 write_voffset(fn, o);
4055 write_function_decl(fn, ctxt,
4057 get_indent_to_level(ctxt, indent, 2));
4059 do_indent_to_level(ctxt, indent, 1);
4060 o <<
"</member-function>\n";
4063 for (member_function_templates::const_iterator fn =
4064 decl->get_member_function_templates().begin();
4065 fn != decl->get_member_function_templates().end();
4068 do_indent(o, nb_ws);
4069 o <<
"<member-template";
4070 write_access((*fn)->get_access_specifier(), o);
4071 write_cdtor_const_static((*fn)->is_constructor(),
4074 (*fn)->get_is_static(), o);
4076 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4077 get_indent_to_level(ctxt, indent, 2));
4078 do_indent(o, nb_ws);
4079 o <<
"</member-template>\n";
4082 for (member_class_templates::const_iterator cl =
4083 decl->get_member_class_templates().begin();
4084 cl != decl->get_member_class_templates().end();
4087 do_indent(o, nb_ws);
4088 o <<
"<member-template";
4089 write_access((*cl)->get_access_specifier(), o);
4090 write_cdtor_const_static(
false,
false,
false,
4091 (*cl)->get_is_static(), o);
4093 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4094 get_indent_to_level(ctxt, indent, 2));
4095 do_indent(o, nb_ws);
4096 o <<
"</member-template>\n";
4099 do_indent_to_level(ctxt, indent, 0);
4101 o <<
"</class-decl>\n";
4104 ctxt.record_type_as_emitted(decl);
4120 write_context& ctxt,
4122 {
return write_class_decl(decl,
"", ctxt, indent);}
4134 write_union_decl(
const union_decl_sptr& d,
4136 write_context& ctxt,
4144 annotate(decl, ctxt, indent);
4146 ostream& o = ctxt.get_ostream();
4148 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4150 if (!decl->has_no_member())
4152 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4153 for (class_decl::member_types::const_iterator ti =
4154 decl->get_member_types().begin();
4155 ti != decl->get_member_types().end();
4157 if (!(*ti)->get_naked_canonical_type())
4158 write_member_type(*ti, ctxt, nb_ws);
4160 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4163 for (union_decl::data_members::const_iterator data =
4164 decl->get_data_members().begin();
4165 data != decl->get_data_members().end();
4168 do_indent(o, nb_ws);
4169 o <<
"<data-member";
4173 write_cdtor_const_static(
false,
4180 write_var_decl(*data, ctxt, is_static,
4181 get_indent_to_level(ctxt, indent, 2));
4183 do_indent_to_level(ctxt, indent, 1);
4184 o <<
"</data-member>\n";
4187 for (union_decl::member_functions::const_iterator f =
4188 decl->get_member_functions().begin();
4189 f != decl->get_member_functions().end();
4200 do_indent(o, nb_ws);
4201 o <<
"<member-function";
4210 write_function_decl(fn, ctxt,
4212 get_indent_to_level(ctxt, indent, 2));
4214 do_indent_to_level(ctxt, indent, 1);
4215 o <<
"</member-function>\n";
4218 for (member_function_templates::const_iterator fn =
4219 decl->get_member_function_templates().begin();
4220 fn != decl->get_member_function_templates().end();
4223 do_indent(o, nb_ws);
4224 o <<
"<member-template";
4225 write_access((*fn)->get_access_specifier(), o);
4226 write_cdtor_const_static((*fn)->is_constructor(),
4229 (*fn)->get_is_static(), o);
4231 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4232 get_indent_to_level(ctxt, indent, 2));
4233 do_indent(o, nb_ws);
4234 o <<
"</member-template>\n";
4237 for (member_class_templates::const_iterator cl =
4238 decl->get_member_class_templates().begin();
4239 cl != decl->get_member_class_templates().end();
4242 do_indent(o, nb_ws);
4243 o <<
"<member-template";
4244 write_access((*cl)->get_access_specifier(), o);
4245 write_cdtor_const_static(
false,
false,
false,
4246 (*cl)->get_is_static(), o);
4248 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4249 get_indent_to_level(ctxt, indent, 2));
4250 do_indent(o, nb_ws);
4251 o <<
"</member-template>\n";
4254 do_indent_to_level(ctxt, indent, 0);
4256 o <<
"</union-decl>\n";
4263 write_union_decl(
const union_decl_sptr& decl,
4264 write_context& ctxt,
4266 {
return write_union_decl(decl,
"", ctxt, indent);}
4278 write_member_type_opening_tag(
const type_base_sptr& t,
4279 write_context& ctxt,
4282 ostream& o = ctxt.get_ostream();
4284 do_indent_to_level(ctxt, indent, 0);
4289 o <<
"<member-type";
4290 write_access(decl, o);
4309 write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4314 ostream& o = ctxt.get_ostream();
4316 write_member_type_opening_tag(t, ctxt, indent);
4318 string id = ctxt.get_id_for_type(t);
4320 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4321 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4323 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4325 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4327 || write_ptr_to_mbr_type(dynamic_pointer_cast<ptr_to_mbr_type>(t),
4329 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4331 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4333 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4335 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4337 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
4340 do_indent_to_level(ctxt, indent, 0);
4341 o <<
"</member-type>\n";
4357 write_context& ctxt,
4363 ostream &o = ctxt.get_ostream();
4364 do_indent_to_level(ctxt, indent, 0);
4366 string id_attr_name;
4367 if (ctxt.type_has_existing_id(decl))
4368 id_attr_name =
"type-id";
4370 id_attr_name =
"id";
4372 o <<
"<template-type-parameter "
4373 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
4377 o <<
" name='" << name <<
"'";
4379 write_location(decl, ctxt);
4383 ctxt.record_type_as_emitted(decl);
4398 write_non_type_tparameter(
4399 const shared_ptr<non_type_tparameter> decl,
4400 write_context& ctxt,
unsigned indent)
4405 ostream &o = ctxt.get_ostream();
4406 do_indent_to_level(ctxt, indent, 0);
4408 o <<
"<template-non-type-parameter type-id='"
4409 << ctxt.get_id_for_type(decl->get_type())
4414 o <<
" name='" << name <<
"'";
4416 write_location(decl, ctxt);
4435 write_context& ctxt,
4441 ostream& o = ctxt.get_ostream();
4442 do_indent_to_level(ctxt, indent, 0);
4444 string id_attr_name =
"id";
4445 if (ctxt.type_has_existing_id(decl))
4446 id_attr_name =
"type-id";
4448 o <<
"<template-template-parameter " << id_attr_name <<
"='"
4449 << ctxt.get_id_for_type(decl) <<
"'";
4453 o <<
" name='" << name <<
"'";
4457 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4458 for (list<shared_ptr<template_parameter> >::const_iterator p =
4459 decl->get_template_parameters().begin();
4460 p != decl->get_template_parameters().end();
4462 write_template_parameter(decl, ctxt, nb_spaces);
4464 do_indent_to_level(ctxt, indent, 0);
4465 o <<
"</template-template-parameter>\n";
4467 ctxt.record_type_as_emitted(decl);
4482 write_type_composition
4483 (
const shared_ptr<type_composition> decl,
4484 write_context& ctxt,
unsigned indent)
4489 ostream& o = ctxt.get_ostream();
4491 do_indent_to_level(ctxt, indent, 0);
4493 o <<
"<template-parameter-type-composition>\n";
4495 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4496 (write_pointer_type_def
4497 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
4499 || write_reference_type_def
4500 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
4502 || write_array_type_def
4503 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
4505 || write_qualified_type_def
4506 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
4509 do_indent_to_level(ctxt, indent, 0);
4510 o <<
"</template-parameter-type-composition>\n";
4525 write_template_parameter(
const shared_ptr<template_parameter> decl,
4526 write_context& ctxt,
unsigned indent)
4528 if ((!write_type_tparameter
4529 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
4530 && (!write_non_type_tparameter
4531 (dynamic_pointer_cast<non_type_tparameter>(decl),
4533 && (!write_template_tparameter
4534 (dynamic_pointer_cast<template_tparameter>(decl),
4536 && (!write_type_composition
4537 (dynamic_pointer_cast<type_composition>(decl),
4548 write_template_parameters(
const shared_ptr<template_decl> tmpl,
4549 write_context& ctxt,
unsigned indent)
4554 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4555 for (list<shared_ptr<template_parameter> >::const_iterator p =
4556 tmpl->get_template_parameters().begin();
4557 p != tmpl->get_template_parameters().end();
4559 write_template_parameter(*p, ctxt, nb_spaces);
4570 write_function_tdecl(
const shared_ptr<function_tdecl> decl,
4571 write_context& ctxt,
unsigned indent)
4576 ostream& o = ctxt.get_ostream();
4578 do_indent_to_level(ctxt, indent, 0);
4580 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
4582 write_location(decl, ctxt);
4584 write_visibility(decl, o);
4586 write_binding(decl, o);
4590 write_template_parameters(decl, ctxt, indent);
4592 write_function_decl(decl->get_pattern(), ctxt,
4594 get_indent_to_level(ctxt, indent, 1));
4596 do_indent_to_level(ctxt, indent, 0);
4598 o <<
"</function-template-decl>\n";
4615 write_class_tdecl(
const shared_ptr<class_tdecl> decl,
4616 write_context& ctxt,
unsigned indent)
4621 ostream& o = ctxt.get_ostream();
4623 do_indent_to_level(ctxt, indent, 0);
4625 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
4627 write_location(decl, ctxt);
4629 write_visibility(decl, o);
4633 write_template_parameters(decl, ctxt, indent);
4635 write_class_decl(decl->get_pattern(), ctxt,
4636 get_indent_to_level(ctxt, indent, 1));
4638 do_indent_to_level(ctxt, indent, 0);
4640 o <<
"</class-template-decl>\n";
4649 write_version_info(write_context& ctxt)
4651 ostream& o = ctxt.get_ostream();
4652 const config& c = ctxt.get_config();
4655 << c.get_format_major_version_number()
4656 <<
"." << c.get_format_minor_version_number()
4676 const corpus_sptr& corpus,
4678 bool member_of_group)
4683 if (corpus->is_empty())
4686 do_indent_to_level(ctxt, indent, 0);
4688 std::ostream& out = ctxt.get_ostream();
4690 out <<
"<abi-corpus ";
4692 write_version_info(ctxt);
4696 std::string corpus_path = corpus->get_path();
4697 if (!ctxt.get_write_corpus_path())
4699 if (member_of_group)
4702 corpus_path.clear();
4706 if (ctxt.get_short_locs())
4709 if (!corpus_path.empty())
4712 if (!corpus->get_architecture_name().empty()
4713 && ctxt.get_write_architecture())
4714 out <<
" architecture='" << corpus->get_architecture_name()<<
"'";
4716 if (!corpus->get_soname().empty())
4717 out <<
" soname='" << corpus->get_soname()<<
"'";
4719 write_tracking_non_reachable_types(corpus, out);
4725 if (ctxt.get_write_elf_needed () && !corpus->get_needed().empty())
4727 do_indent_to_level(ctxt, indent, 1);
4728 out <<
"<elf-needed>\n";
4729 write_elf_needed(corpus->get_needed(), ctxt,
4730 get_indent_to_level(ctxt, indent, 2));
4731 do_indent_to_level(ctxt, indent, 1);
4732 out <<
"</elf-needed>\n";
4736 if (!corpus->get_fun_symbol_map().empty())
4738 do_indent_to_level(ctxt, indent, 1);
4739 out <<
"<elf-function-symbols>\n";
4741 write_elf_symbols_table(corpus->get_sorted_fun_symbols(), ctxt,
4742 get_indent_to_level(ctxt, indent, 2));
4744 do_indent_to_level(ctxt, indent, 1);
4745 out <<
"</elf-function-symbols>\n";
4749 if (!corpus->get_var_symbol_map().empty())
4751 do_indent_to_level(ctxt, indent, 1);
4752 out <<
"<elf-variable-symbols>\n";
4754 write_elf_symbols_table(corpus->get_sorted_var_symbols(), ctxt,
4755 get_indent_to_level(ctxt, indent, 2));
4757 do_indent_to_level(ctxt, indent, 1);
4758 out <<
"</elf-variable-symbols>\n";
4762 if (ctxt.get_write_undefined_symbols()
4763 && !corpus->get_sorted_undefined_fun_symbols().empty())
4765 do_indent_to_level(ctxt, indent, 1);
4766 out <<
"<undefined-elf-function-symbols>\n";
4768 write_elf_symbols_table(corpus->get_sorted_undefined_fun_symbols(), ctxt,
4769 get_indent_to_level(ctxt, indent, 2));
4771 do_indent_to_level(ctxt, indent, 1);
4772 out <<
"</undefined-elf-function-symbols>\n";
4777 if (ctxt.get_write_undefined_symbols()
4778 && !corpus->get_sorted_undefined_var_symbols().empty())
4780 do_indent_to_level(ctxt, indent, 1);
4781 out <<
"<undefined-elf-variable-symbols>\n";
4783 write_elf_symbols_table(corpus->get_sorted_undefined_var_symbols(), ctxt,
4784 get_indent_to_level(ctxt, indent, 2));
4786 do_indent_to_level(ctxt, indent, 1);
4787 out <<
"</undefined-elf-variable-symbols>\n";
4791 unsigned nb_tus = corpus->get_translation_units().size(), n = 0;
4792 for (translation_units::const_iterator i =
4793 corpus->get_translation_units().begin();
4794 i != corpus->get_translation_units().end();
4799 get_indent_to_level(ctxt, indent, 1),
4803 do_indent_to_level(ctxt, indent, 0);
4804 out <<
"</abi-corpus>\n";
4806 ctxt.clear_referenced_types();
4807 ctxt.record_corpus_as_emitted(corpus);
4824 const corpus_group_sptr& group,
4831 do_indent_to_level(ctxt, indent, 0);
4833 std::ostream& out = ctxt.get_ostream();
4835 out <<
"<abi-corpus-group ";
4836 write_version_info(ctxt);
4838 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
4841 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
4842 out <<
" architecture='" << group->get_architecture_name()<<
"'";
4844 write_tracking_non_reachable_types(group, out);
4846 if (group->is_empty())
4855 for (corpus_group::corpora_type::const_iterator c =
4856 group->get_corpora().begin();
4857 c != group->get_corpora().end();
4861 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
4864 do_indent_to_level(ctxt, indent, 0);
4865 out <<
"</abi-corpus-group>\n";
4886 xml_writer::write_context ctxt(d->get_environment(), o);
4888 write_decl(d, ctxt, 0);
4898 {
dump(d, cerr, annotate);}
4918 {
dump(t, cerr, annotate);}
4930 xml_writer::write_context ctxt(v->get_environment(), o);
4932 write_var_decl(v, ctxt,
true, 0);
4942 {
dump(v, cerr, annotate);}
4964 {
dump(t, cerr, annotate);}
4977 dump(*t, o, annotate);
5001 unsigned line = 0, col = 0;
5003 l.
expand(path, line, col);
5004 o << path <<
":" << line <<
"," << col <<
"\n";
5054 #ifdef WITH_DEBUG_SELF_COMPARISON
5065 write_type_record(xml_writer::write_context& ctxt,
5066 const type_base* type,
5084 type_base* canonical = type->get_naked_canonical_type();
5088 id = ctxt.get_id_for_type (const_cast<type_base*>(type));
5091 <<
" <id>" <<
id <<
"</id>\n"
5094 <<
reinterpret_cast<uintptr_t
>(canonical)
5110 write_canonical_type_ids(xml_writer::write_context& ctxt, ostream& o)
5129 o <<
"<abixml-types-check>\n";
5131 for (
const auto &type : ctxt.get_emitted_types_set())
5132 write_type_record(ctxt, type, o);
5134 o <<
"</abixml-types-check>\n";
5147 write_canonical_type_ids(xml_writer::write_context& ctxt,
5148 const string &file_path)
5150 std:: ofstream o (file_path);
5154 write_canonical_type_ids(ctxt, o);
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
void set_write_comp_dir(write_context &ctxt, bool flag)
Set the 'write-comp-dir' flag.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
The base type of all declarations.
visibility
The visibility of the symbol.
void set_show_locs(write_context &ctxt, bool flag)
Set the "show-locs" flag.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
void dump(const decl_base_sptr d, std::ostream &o, const bool annotate)
Serialize a pointer to decl_base to an output stream.
void set_annotate(write_context &ctxt, bool flag)
Set the 'annotate' flag.
void set_write_elf_needed(write_context &ctxt, bool flag)
Set the 'elf-needed' flag.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
Utilities to ease the wrapping of C types into std::shared_ptr.
type_id_style_kind
The style of type id the XML writer will output.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
An abstraction helper for type declarations.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
const location & get_location() const
Get the location of a given declaration.
A declaration that introduces a scope.
const environment & get_environment() const
Getter of the environment of the current translation_unit.
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
bool get_is_artificial() const
Test if the location is artificial.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_ostream(write_context &ctxt, ostream &os)
Set the new ostream.
This is the abstraction of the set of relevant artefacts (types, variable declarations, functions, templates, etc) bundled together into a translation unit.
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
Datum consolidating style preferences.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
void set_write_architecture(write_context &ctxt, bool flag)
Set the 'write-architecture' flag.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
std::unordered_map< string, elf_symbol_sptr > string_elf_symbol_sptr_map_type
Convenience typedef for a map which key is a string and which value if the elf symbol of the same nam...
shared_ptr< write_context > write_context_sptr
A convenience typedef for a shared pointer to write_context.
void dump_location(const location &l, ostream &o)
Serialize a source location to an output stream.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
language get_language() const
Getter of the language of the source code of the translation unit.
bool annotate(const function_decl::parameter_sptr &parm, write_context &ctxt, unsigned indent)
Annotate a function parameter in form of an ABIXML comment.
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
Toplevel namespace for libabigail.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
uint32_t fnv_hash(const std::string &str)
Compute a stable string hash.
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This contains the private implementation of the suppression engine of libabigail. ...
unordered_map< interned_string, type_base_wptr, hash_interned_string > istring_type_base_wptr_map_type
A convenience typedef for a map which key is an interned_string and which value is a type_base_wptr...
type
The type of a symbol.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
The source location of a token.
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
unordered_map< type_base *, interned_string > type_ptr_map
A convenience typedef for a map that associates a pointer to type to a string.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
void escape_xml_comment(const std::string &str, std::string &escaped)
Escape the '-' character, to avoid having a '–' in a comment.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
void set_write_corpus_path(write_context &ctxt, bool flag)
Set the 'write-corpus-path' flag.
interned_string intern(const string &) const
Do intern a string.
bool serialize_hash(uint64_t hash, string &output)
Serialiaze a hash value computed using the XH64 algorithm (from the xxhash project) into a string of ...
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
void set_type_id_style(write_context &ctxt, type_id_style_kind style)
Set the 'type-id-style' property.
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
binding
The binding of a symbol.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
write_context_sptr create_write_context(const environment &env, ostream &default_output_stream)
Create a write_context object that can be used to emit abixml files.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
std::unordered_set< const type_base *, non_canonicalized_type_hash, non_canonicalized_type_equal > nc_type_ptr_set_type
A set meant to carry non canonicalized types.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void dump_decl_location(const decl_base &d, ostream &o)
Serialize the source location of a decl to an output stream for debugging purposes.
void set_short_locs(write_context &ctxt, bool flag)
Set the 'short-locs' flag.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer...
void escape_xml_string(const std::string &str, std::string &escaped)
Escape the 5 characters representing the predefined XML entities.
bool write_corpus_group(write_context &ctxt, const corpus_group_sptr &group, unsigned indent)
Serialize an ABI corpus group to a single native xml document. The root note of the resulting XML doc...
std::unordered_map< const type_base *, interned_string, non_canonicalized_type_hash, non_canonicalized_type_equal > nc_type_ptr_istr_map_type
A map meant to carry non canonicalized types as key.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
The abstraction of an interned string.
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
const std::string & get_path() const
Get the path of the current translation unit.
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
This type abstracts the configuration information of the library.
access_specifier
Access specifier for class members.
void set_write_parameter_names(write_context &ctxt, bool flag)
Set the 'parameter-names' flag.
void set_write_default_sizes(write_context &ctxt, bool flag)
Set the 'default-sizes' flag.
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
The abstraction of a typedef declaration.
bool lookup_decl_only_class_types(const interned_string &qualified_name, const corpus &corp, type_base_wptrs_type &result)
Look into a given corpus to find the class type*s* that have a given qualified name and that are decl...
void set_write_undefined_symbols(write_context &ctxt, bool flag)
Set the 'undefined-symbols' flag.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
The namespace of the internal representation of ABI artifacts like types and decls.
shared_ptr< type_tparameter > type_tparameter_sptr
Convenience typedef for a shared pointer to type_tparameter.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
char get_address_size() const
Getter of the address size in this translation unit.
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
Abstraction of a function type.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
bool write_corpus(write_context &ctxt, const corpus_sptr &corpus, unsigned indent, bool member_of_group)
Serialize an ABI corpus to a single native xml document. The root note of the resulting XML document ...
bool write_translation_unit(write_context &ctxt, const translation_unit &tu, const unsigned indent, bool is_last)
Serialize a translation unit to an output stream.
std::unordered_set< function_type * > fn_type_ptr_set_type
A convenience typedef for a set of function type*.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
visibility
ELF visibility.