23#include <unordered_map>
30#include "abg-internal.h"
32ABG_BEGIN_EXPORT_DECLARATIONS
43ABG_END_EXPORT_DECLARATIONS
50using std::dynamic_pointer_cast;
51using std::static_pointer_cast;
54using std::ostringstream;
58using 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());
116struct non_canonicalized_type_hash
135 return h(p->get_pretty_representation(
false,
151struct non_canonicalized_type_equal
177typedef std::unordered_set<const type_base*> type_ptr_set_type;
183typedef 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>
200struct function_tdecl_hash
203 {
return reinterpret_cast<size_t>(f.get());}
207 string, function_tdecl_hash>
208fn_tmpl_shared_ptr_map;
210struct 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;
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;
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();
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];
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;}
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();
812 m_emitted_corpora_set.insert(path);
818 const type_ptr_set_type&
819 get_emitted_types_set()
const
820 {
return m_emitted_type_set;}
825 clear_referenced_types()
827 m_referenced_types_set.clear();
828 m_referenced_fn_types_set.clear();
832 get_fun_symbol_map()
const
833 {
return m_fun_symbol_map;}
837 {
return m_fun_symbol_map;}
841static void write_location(
const location&, write_context&);
842static void write_location(
const decl_base_sptr&, write_context&);
843static bool write_visibility(
const decl_base_sptr&, ostream&);
844static bool write_binding(
const decl_base_sptr&, ostream&);
845static bool write_is_artificial(
const decl_base_sptr&, ostream&);
846static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
847static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
850static void write_size_and_alignment(
const type_base_sptr, ostream&,
851 size_t default_size = 0,
852 size_t default_alignment = 0);
856static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
860static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
861static bool write_elf_symbol_reference(write_context&,
865static bool write_elf_symbol_reference(write_context&,
869static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
871static void write_is_anonymous(
const decl_base_sptr&, ostream&);
872static void write_type_hash_and_cti(
const type_base_sptr&, ostream&);
873static void write_naming_typedef(
const decl_base_sptr&, write_context&);
874static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
875static void write_decl_in_scope(
const decl_base_sptr&,
876 write_context&,
unsigned);
877static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
879 write_context&,
unsigned);
880static bool write_qualified_type_def(
const qualified_type_def_sptr&,
881 write_context&,
unsigned);
883 write_context&,
unsigned);
885 write_context&,
unsigned);
887 write_context&,
unsigned);
889 write_context&,
unsigned);
894 write_context&,
unsigned);
896 write_context&,
unsigned);
898 write_context&,
unsigned);
899static bool write_elf_symbols_table(
const elf_symbols&,
900 write_context&,
unsigned);
902 write_context&,
bool,
unsigned);
904 write_context&,
bool,
unsigned);
906 write_context&,
unsigned);
907static bool write_member_type_opening_tag(
const type_base_sptr&,
908 write_context&,
unsigned);
909static bool write_member_type(
const type_base_sptr&,
910 write_context&,
unsigned);
911static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
912 write_context&,
unsigned,
bool);
914 write_context&,
unsigned);
915static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
916 write_context&,
unsigned,
bool);
917static bool write_union_decl(
const union_decl_sptr&,
const string&,
918 write_context&,
unsigned);
919static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
920static void write_common_type_info(
const type_base_sptr&, write_context&,
921 const string&
id=
"");
922static bool write_type(
const type_base_sptr&, write_context&,
unsigned);
923static bool write_type_tparameter
924(
const shared_ptr<type_tparameter>, write_context&,
unsigned);
925static bool write_non_type_tparameter
926(
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
927static bool write_template_tparameter
928(
const shared_ptr<template_tparameter>, write_context&,
unsigned);
929static bool write_type_composition
930(
const shared_ptr<type_composition>, write_context&,
unsigned);
931static bool write_template_parameter(
const shared_ptr<template_parameter>,
932 write_context&,
unsigned);
933static void write_template_parameters(
const shared_ptr<template_decl>,
934 write_context&,
unsigned);
935static bool write_function_tdecl
936(
const shared_ptr<function_tdecl>,
937 write_context&,
unsigned);
938static bool write_class_tdecl
939(
const shared_ptr<class_tdecl>,
940 write_context&,
unsigned);
941static void do_indent(ostream&,
unsigned);
942static void do_indent_to_level(write_context&,
unsigned,
unsigned);
943static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
947do_indent(ostream& o,
unsigned nb_whitespaces)
949 for (
unsigned i = 0; i < nb_whitespaces; ++i)
961do_indent_to_level(write_context& ctxt,
962 unsigned initial_indent,
965 do_indent(ctxt.get_ostream(),
966 get_indent_to_level(ctxt, initial_indent, level));
978get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
981 int nb_ws = initial_indent +
982 level * ctxt.get_config().get_xml_element_indent();
1002template <
typename T>
1004annotate(
const T& decl,
1005 write_context& ctxt,
1011 if (!ctxt.get_annotate())
1014 ostream& o = ctxt.get_ostream();
1016 do_indent(o, indent);
1038 write_context& ctxt,
1044 if (!ctxt.get_annotate())
1047 ostream& o = ctxt.get_ostream();
1049 do_indent(o, indent);
1069 write_context& ctxt,
1075 if (!ctxt.get_annotate())
1078 ostream& o = ctxt.get_ostream();
1080 do_indent(o, indent);
1082 o <<
"<!-- typedef "
1105 write_context& ctxt,
1111 if (!ctxt.get_annotate())
1114 ostream& o = ctxt.get_ostream();
1116 do_indent(o, indent);
1138 write_context& ctxt,
1144 if (!ctxt.get_annotate())
1147 ostream& o = ctxt.get_ostream();
1149 do_indent(o, indent);
1161 vector<function_decl::parameter_sptr>::const_iterator pi =
1162 fn->get_first_non_implicit_parm();
1164 for (; pi != fn->get_parameters().end(); ++pi)
1168 if (distance(pi, fn->get_parameters().end()) > 1)
1188 write_context& ctxt,
1194 if (!ctxt.get_annotate())
1197 ostream &o = ctxt.get_ostream();
1199 do_indent(o, indent);
1203 if (parm->get_variadic_marker())
1204 o <<
"variadic parameter";
1207 if (parm->get_is_artificial())
1209 if (parm->get_index() == 0)
1214 o <<
"parameter of type '"
1233write_location(
const location& loc, write_context& ctxt)
1238 if (!ctxt.get_show_locs())
1242 unsigned line = 0, column = 0;
1244 loc.
expand(filepath, line, column);
1246 ostream &o = ctxt.get_ostream();
1248 if (ctxt.get_short_locs())
1252 <<
" line='" << line <<
"'"
1253 <<
" column='" << column <<
"'";
1264write_location(
const decl_base_sptr& decl,
1265 write_context& ctxt)
1270 location loc = decl->get_location();
1274 write_location(loc, ctxt);
1286write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1296 case decl_base::VISIBILITY_NONE:
1298 case decl_base::VISIBILITY_DEFAULT:
1301 case decl_base::VISIBILITY_PROTECTED:
1304 case decl_base::VISIBILITY_HIDDEN:
1307 case decl_base::VISIBILITY_INTERNAL:
1315 o <<
" visibility='" << str <<
"'";
1326write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1333 shared_ptr<var_decl> var =
1334 dynamic_pointer_cast<var_decl>(decl);
1336 bind = var->get_binding();
1339 shared_ptr<function_decl> fun =
1340 dynamic_pointer_cast<function_decl>(decl);
1342 bind = fun->get_binding();
1348 case decl_base::BINDING_NONE:
1350 case decl_base::BINDING_LOCAL:
1353 case decl_base::BINDING_GLOBAL:
1356 case decl_base::BINDING_WEAK:
1362 o <<
" binding='" << str <<
"'";
1376write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1381 if (decl->get_is_artificial())
1382 o <<
" is-artificial='yes'";
1396write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1401 corpus* c = t->get_corpus();
1405 if (!c->recording_types_reachable_from_public_interface_supported()
1406 || c->type_is_reachable_from_public_interfaces(*t))
1409 o <<
" is-non-reachable='yes'";
1422write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1425 corpus_group* group = corpus->get_group();
1427 if (corpus->recording_types_reachable_from_public_interface_supported())
1429 o <<
" tracking-non-reachable-types='yes'";
1450write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1451 size_t default_size,
size_t default_alignment)
1453 size_t size_in_bits = decl->get_size_in_bits();
1454 if (size_in_bits != default_size)
1455 o <<
" size-in-bits='" << size_in_bits <<
"'";
1457 size_t alignment_in_bits = decl->get_alignment_in_bits();
1458 if (alignment_in_bits != default_alignment)
1459 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1467write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1469 if (decl->is_non_finite())
1470 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1472 size_t size_in_bits = decl->get_size_in_bits();
1474 o <<
" size-in-bits='" << size_in_bits <<
"'";
1477 size_t alignment_in_bits = decl->get_alignment_in_bits();
1478 if (alignment_in_bits)
1479 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1489 string access_str =
"private";
1493 case private_access:
1494 access_str =
"private";
1497 case protected_access:
1498 access_str =
"protected";
1502 access_str =
"public";
1509 o <<
" access='" << access_str <<
"'";
1520 o <<
" layout-offset-in-bits='"
1527write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1532 if (base->get_offset_in_bits() >= 0)
1533 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1542write_access(decl_base_sptr member, ostream& o)
1559 o <<
" vtable-offset='" << voffset <<
"'";
1576 case elf_symbol::NOTYPE_TYPE:
1579 case elf_symbol::OBJECT_TYPE:
1580 repr =
"object-type";
1582 case elf_symbol::FUNC_TYPE:
1585 case elf_symbol::SECTION_TYPE:
1586 repr =
"section-type";
1588 case elf_symbol::FILE_TYPE:
1591 case elf_symbol::COMMON_TYPE:
1592 repr =
"common-type";
1594 case elf_symbol::TLS_TYPE:
1597 case elf_symbol::GNU_IFUNC_TYPE:
1598 repr =
"gnu-ifunc-type";
1605 o <<
" type='" << repr <<
"'";
1621 case elf_symbol::LOCAL_BINDING:
1622 repr =
"local-binding";
1624 case elf_symbol::GLOBAL_BINDING:
1625 repr =
"global-binding";
1627 case elf_symbol::WEAK_BINDING:
1628 repr =
"weak-binding";
1630 case elf_symbol::GNU_UNIQUE_BINDING:
1631 repr =
"gnu-unique-binding";
1634 repr =
"no-binding";
1638 o <<
" binding='" << repr <<
"'";
1654 case elf_symbol::DEFAULT_VISIBILITY:
1655 repr =
"default-visibility";
1657 case elf_symbol::PROTECTED_VISIBILITY:
1658 repr =
"protected-visibility";
1660 case elf_symbol::HIDDEN_VISIBILITY:
1661 repr =
"hidden-visibility";
1663 case elf_symbol::INTERNAL_VISIBILITY:
1664 repr =
"internal-visibility";
1667 repr =
"default-visibility";
1671 o <<
" visibility='" << repr <<
"'";
1682write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1684 if (!sym.is_main_symbol() || !sym.has_aliases())
1688 std::vector<std::string> aliases;
1689 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1690 s = s->get_next_alias())
1692 if (!s->is_public())
1695 if (s->is_suppressed())
1698 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1701 aliases.push_back(s->get_id_string());
1704 if (!aliases.empty())
1707 std::string separator;
1708 for (
const auto& alias : aliases)
1710 out << separator << alias;
1737write_elf_symbol_reference(write_context& ctxt,
1738 const elf_symbol& sym,
1744 s = abi.lookup_variable_symbol(sym);
1750 || (!ctxt.get_write_undefined_symbols() && !s->is_defined()))
1754 const elf_symbol* main = sym.get_main_symbol().get();
1755 const elf_symbol* alias = &sym;
1756 bool found = !alias->is_suppressed();
1761 found = !alias->is_suppressed();
1766 alias = alias->get_next_alias().get();
1768 if (!alias || alias == main)
1770 found = !alias->is_suppressed();
1775 o <<
" elf-symbol-id='"
1796write_elf_symbol_reference(write_context& ctxt,
1804 return write_elf_symbol_reference(ctxt, *sym, abi, o);
1821write_cdtor_const_static(
bool is_ctor,
1828 o <<
" static='yes'";
1830 o <<
" constructor='yes'";
1832 o <<
" destructor='yes'";
1834 o <<
" const='yes'";
1844write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
1846 if (d->get_is_declaration_only())
1847 o <<
" is-declaration-only='yes'";
1859 if (klass->is_struct())
1860 o <<
" is-struct='yes'";
1870write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1872 if (decl->get_is_anonymous())
1873 o <<
" is-anonymous='yes'";
1882write_type_hash_and_cti(
const type_base_sptr& t, ostream& o)
1889 o <<
" hash='" << h;
1890 if (t->priv_->canonical_type_index)
1891 o <<
"#" << t->priv_->canonical_type_index;
1903write_naming_typedef(
const decl_base_sptr& decl, write_context& ctxt)
1908 ostream &o = ctxt.get_ostream();
1912 string id = ctxt.get_id_for_type(typedef_type);
1913 o <<
" naming-typedef-id='" <<
id <<
"'";
1914 ctxt.record_type_as_referenced(typedef_type);
1926write_common_type_info(
const type_base_sptr& t,
1927 write_context& ctxt,
1930 decl_base_sptr d =
is_decl(t);
1932 ostream& o = ctxt.get_ostream();
1934 if (!d || (d && !d->get_is_declaration_only()))
1937 write_size_and_alignment(t, o);
1939 write_array_size_and_alignment(a, o);
1944 write_is_anonymous(d, o);
1945 write_is_declaration_only(d, o);
1946 write_location(d, ctxt);
1949 write_type_hash_and_cti(t, o);
1953 i = ctxt.get_id_for_type(t);
1954 o <<
" id='" << i <<
"'";
1956 ctxt.record_type_as_emitted(t);
1969write_type(
const type_base_sptr& type, write_context& ctxt,
unsigned indent)
1971 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
1973 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1976 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
1978 || write_reference_type_def(dynamic_pointer_cast
1979 <reference_type_def>(type), ctxt, indent)
1980 || write_ptr_to_mbr_type(dynamic_pointer_cast
1981 <ptr_to_mbr_type>(type),
1983 || write_array_type_def(dynamic_pointer_cast
1984 <array_type_def>(type), ctxt, indent)
1985 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
1987 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
1991 || (write_function_tdecl
1992 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
1993 || (write_class_tdecl
1994 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
2012write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
2014 if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
2016 || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
2018 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
2021 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
2023 || write_reference_type_def(dynamic_pointer_cast
2024 <reference_type_def>(decl), ctxt, indent)
2025 || write_ptr_to_mbr_type(dynamic_pointer_cast
2026 <ptr_to_mbr_type>(decl),
2028 || write_array_type_def(dynamic_pointer_cast
2029 <array_type_def>(decl), ctxt, indent)
2030 || write_array_subrange_type(dynamic_pointer_cast
2031 <array_type_def::subrange_type>(decl),
2033 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
2035 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
2037 || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
2039 || write_function_decl(dynamic_pointer_cast<method_decl>
2042 || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
2043 ctxt,
false, indent)
2046 || (write_function_tdecl
2047 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
2048 || (write_class_tdecl
2049 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
2067write_decl_in_scope(
const decl_base_sptr& decl,
2068 write_context& ctxt,
2069 unsigned initial_indent)
2071 type_base_sptr type =
is_type(decl);
2072 if ((type && ctxt.type_is_emitted(type))
2073 || (!type && ctxt.decl_is_emitted(decl)))
2076 list<scope_decl*> scopes;
2077 for (scope_decl* s = decl->get_scope();
2080 scopes.push_front(s);
2082 ostream& o = ctxt.get_ostream();
2083 const config& c = ctxt.get_config();
2084 stack<string> closing_tags;
2085 stack<unsigned> closing_indents;
2086 unsigned indent = initial_indent;
2087 for (list<scope_decl*>::const_iterator i = scopes.begin();
2096 do_indent(o, indent);
2097 o <<
"<namespace-decl name='"
2100 closing_tags.push(
"</namespace-decl>");
2101 closing_indents.push(indent);
2108 if (!ctxt.type_is_emitted(c))
2110 write_type(class_type, ctxt, initial_indent);
2115 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2117 closing_tags.push(
"</class-decl>");
2118 closing_indents.push(indent);
2120 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2121 write_member_type_opening_tag(type, ctxt, nb_ws);
2123 closing_tags.push(
"</member-type>");
2124 closing_indents.push(nb_ws);
2130 union_decl_sptr union_type(u, noop_deleter());
2131 if (!ctxt.type_is_emitted(u))
2133 write_type(union_type, ctxt, initial_indent);
2138 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2140 closing_tags.push(
"</union-decl>");
2141 closing_indents.push(indent);
2143 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2144 write_member_type_opening_tag(type, ctxt, nb_ws);
2146 closing_tags.push(
"</member-type>");
2147 closing_indents.push(nb_ws);
2153 indent += c.get_xml_element_indent();
2156 bool do_write =
false;
2157 if (type_base_sptr type =
is_type(decl))
2159 if (!ctxt.type_is_emitted(type))
2164 if (!ctxt.decl_is_emitted(decl))
2169 write_decl(decl, ctxt, indent);
2171 while (!closing_tags.empty())
2173 do_indent(o, closing_indents.top());
2174 o << closing_tags.top() <<
"\n";
2176 closing_indents.pop();
2190 ostream& default_output_stream)
2207{ctxt.set_show_locs(flag);}
2219{ctxt.set_annotate(flag);}
2230{ctxt.set_ostream(os);}
2242{ctxt.set_write_architecture(flag);}
2254{ctxt.set_write_corpus_path(flag);}
2266{ctxt.set_write_comp_dir(flag);}
2278{ctxt.set_short_locs(flag);}
2290{ctxt.set_write_parameter_names(flag);}
2302{ctxt.set_write_elf_needed(flag);}
2314{ctxt.set_write_undefined_symbols(flag);}
2329{ctxt.set_write_default_sizes(flag);}
2340{ctxt.set_type_id_style(
style);}
2355write_canonical_types_of_scope(
const scope_decl &scope,
2356 write_context &ctxt,
2357 const unsigned indent,
2363 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2364 i != canonical_types.end();
2367 if (ctxt.type_is_emitted(*i))
2370 write_member_type(*i, ctxt, indent);
2372 write_type(*i, ctxt, indent);
2394referenced_type_should_be_emitted(
const type_base *t,
2395 const write_context& ctxt,
2396 const translation_unit& tu,
2399 if ((tu_is_last || (t->get_translation_unit()
2400 && (t->get_translation_unit()->get_absolute_path()
2401 == tu.get_absolute_path())))
2402 && !ctxt.type_is_emitted(t))
2419write_referenced_types(write_context & ctxt,
2420 const translation_unit& tu,
2421 const unsigned indent,
2424 const config& c = ctxt.get_config();
2432 type_ptr_set_type referenced_types_to_emit;
2437 for (type_ptr_set_type::const_iterator i =
2438 ctxt.get_referenced_types().begin();
2439 i != ctxt.get_referenced_types().end();
2441 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2442 referenced_types_to_emit.insert(*i);
2444 for (fn_type_ptr_set_type::const_iterator i =
2445 ctxt.get_referenced_function_types().begin();
2446 i != ctxt.get_referenced_function_types().end();
2448 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2449 referenced_types_to_emit.insert(*i);
2452 while (!referenced_types_to_emit.empty())
2457 vector<type_base*> sorted_referenced_types;
2458 ctxt.sort_types(referenced_types_to_emit,
2459 sorted_referenced_types);
2462 for (vector<type_base*>::const_iterator i =
2463 sorted_referenced_types.begin();
2464 i != sorted_referenced_types.end();
2470 if (!ctxt.type_is_emitted(t))
2474 decl_base_sptr decl(d, noop_deleter());
2475 write_decl_in_scope(decl, ctxt,
2476 indent + c.get_xml_element_indent());
2481 write_function_type(fn_type, ctxt,
2482 indent + c.get_xml_element_indent());
2491 referenced_types_to_emit.clear();
2503 for (type_ptr_set_type::const_iterator i =
2504 ctxt.get_referenced_types().begin();
2505 i != ctxt.get_referenced_types().end();
2507 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2508 referenced_types_to_emit.insert(*i);
2536 const unsigned indent,
2544 && ctxt.has_non_emitted_referenced_types())
2547 ostream& o = ctxt.get_ostream();
2548 const config& c = ctxt.get_config();
2550 do_indent(o, indent);
2557 std::string tu_path = tu.
get_path();
2558 if (ctxt.get_short_locs())
2560 if (!tu_path.empty())
2564 o <<
" comp-dir-path='"
2567 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
2581 ctxt, indent + c.get_xml_element_indent());
2584 const declarations& decls = tu.
get_global_scope()->get_sorted_member_decls();
2586 for (
const decl_base_sptr& decl : decls)
2588 if (type_base_sptr t =
is_type(decl))
2595 if (class_type->get_is_declaration_only()
2596 && !ctxt.type_is_emitted(class_type))
2597 write_type(class_type, ctxt,
2598 indent + c.get_xml_element_indent());
2601 write_type(t, ctxt, indent + c.get_xml_element_indent());
2605 if (!ctxt.decl_is_emitted(decl))
2606 write_decl_in_scope(decl, ctxt, indent + c.get_xml_element_indent());
2610 if (!ctxt.decl_is_emitted(decl))
2611 write_decl(decl, ctxt, indent + c.get_xml_element_indent());
2618 for (
auto undefined_function : abi->get_sorted_undefined_functions())
2622 if (f->get_translation_unit() != &tu || ctxt.decl_is_emitted(f))
2625 write_decl(f, ctxt, indent + c.get_xml_element_indent());
2631 for (
auto undefined_var : abi->get_sorted_undefined_variables())
2634 if (v->get_translation_unit() != &tu || ctxt.decl_is_emitted(v))
2637 write_decl(v, ctxt, indent + c.get_xml_element_indent());
2640 write_referenced_types(ctxt, tu, indent, is_last);
2645 vector<type_base_sptr> sorted_types;
2646 ctxt.sort_types(t, sorted_types);
2648 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
2649 i != sorted_types.end();
2654 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
2661 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
2666 write_referenced_types(ctxt, tu, indent, is_last);
2668 do_indent(o, indent);
2669 o <<
"</abi-instr>\n";
2687write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
2692 ostream& o = ctxt.get_ostream();
2694 annotate(d, ctxt, indent);
2696 do_indent(o, indent);
2700 write_common_type_info(d, ctxt);
2720 write_context& ctxt,
unsigned indent)
2722 if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
2725 ostream& o = ctxt.get_ostream();
2726 const config &c = ctxt.get_config();
2728 annotate(decl, ctxt, indent);
2730 do_indent(o, indent);
2732 o <<
"<namespace-decl name='"
2737 typedef declarations::const_iterator const_iterator;
2738 const declarations& d = decl->get_sorted_member_decls();
2740 write_canonical_types_of_scope(*decl, ctxt,
2741 indent + c.get_xml_element_indent());
2743 for (const_iterator i = d.begin(); i != d.end(); ++i)
2745 if (type_base_sptr t =
is_type(*i))
2746 if (ctxt.type_is_emitted(t))
2750 write_decl(*i, ctxt, indent + c.get_xml_element_indent());
2753 do_indent(o, indent);
2754 o <<
"</namespace-decl>\n";
2778write_qualified_type_def(
const qualified_type_def_sptr& decl,
2780 write_context& ctxt,
2786 ostream& o = ctxt.get_ostream();
2789 type_base_sptr underlying_type = decl->get_underlying_type();
2791 annotate(decl, ctxt, indent);
2793 do_indent(o, indent);
2794 o <<
"<qualified-type-def type-id='"
2795 << ctxt.get_id_for_type(underlying_type)
2798 ctxt.record_type_as_referenced(underlying_type);
2800 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
2801 o <<
" const='yes'";
2802 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
2803 o <<
" volatile='yes'";
2804 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
2805 o <<
" restrict='yes'";
2807 write_common_type_info(decl, ctxt,
id);
2825write_qualified_type_def(
const qualified_type_def_sptr& decl,
2826 write_context& ctxt,
2828{
return write_qualified_type_def(decl,
"", ctxt, indent);}
2850 write_context& ctxt,
2856 ostream& o = ctxt.get_ostream();
2858 annotate(decl, ctxt, indent);
2860 do_indent(o, indent);
2864 o <<
"<pointer-type-def ";
2866 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2868 i = ctxt.get_id_for_type(pointed_to_type);
2870 o <<
"type-id='" << i <<
"'";
2872 ctxt.record_type_as_referenced(pointed_to_type);
2874 write_common_type_info(decl, ctxt,
id);
2892 write_context& ctxt,
2894{
return write_pointer_type_def(decl,
"", ctxt, indent);}
2916 write_context& ctxt,
2922 annotate(decl->get_canonical_type(), ctxt, indent);
2924 ostream& o = ctxt.get_ostream();
2926 do_indent(o, indent);
2928 o <<
"<reference-type-def kind='";
2929 if (decl->is_lvalue())
2935 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2936 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
2938 ctxt.record_type_as_referenced(pointed_to_type);
2941 ctxt.record_type_as_referenced(f);
2943 write_common_type_info(decl, ctxt,
id);
2961 write_context& ctxt,
2963{
return write_reference_type_def(decl,
"", ctxt, indent);}
2979 const string&
id, write_context& ctxt,
2985 annotate(decl->get_canonical_type(), ctxt, indent);
2987 ostream& o = ctxt.get_ostream();
2989 do_indent(o, indent);
2991 o <<
"<pointer-to-member-type";
2993 type_base_sptr member_type = decl->get_member_type();
2994 string i = ctxt.get_id_for_type(member_type);
2995 o <<
" member-type-id='" << i <<
"'";
2996 ctxt.record_type_as_referenced(member_type);
2998 type_base_sptr containing_type = decl->get_containing_type();
2999 i = ctxt.get_id_for_type(containing_type);
3000 o <<
" containing-type-id='" << i <<
"'";
3001 ctxt.record_type_as_referenced(containing_type);
3003 write_common_type_info(decl, ctxt,
id);
3021 write_context& ctxt,
unsigned indent)
3022{
return write_ptr_to_mbr_type(decl,
"", ctxt, indent);}
3035 write_context& ctxt,
3041 annotate(decl, ctxt, indent);
3043 ostream& o = ctxt.get_ostream();
3045 do_indent(o, indent);
3049 if (!decl->get_name().empty())
3050 o <<
" name='" << decl->get_name() <<
"'";
3053 if (decl->is_non_finite())
3056 o << decl->get_length();
3061 || decl->get_length() == 0
3062 || (decl->get_length() ==
3063 (uint64_t) (decl->get_upper_bound()
3064 - decl->get_lower_bound() + 1)));
3065 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
3066 << decl->get_upper_bound() <<
"'";
3068 type_base_sptr underlying_type = decl->get_underlying_type();
3069 if (underlying_type)
3072 << ctxt.get_id_for_type(underlying_type)
3074 ctxt.record_type_as_referenced(underlying_type);
3077 write_common_type_info(decl, ctxt);
3104 write_context& ctxt,
3110 annotate(decl, ctxt, indent);
3112 ostream& o = ctxt.get_ostream();
3114 do_indent(o, indent);
3115 o <<
"<array-type-def";
3117 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
3119 type_base_sptr element_type = decl->get_element_type();
3120 o <<
" type-id='" << ctxt.get_id_for_type(element_type) <<
"'";
3122 ctxt.record_type_as_referenced(element_type);
3124 write_common_type_info(decl, ctxt,
id);
3126 if (!decl->get_dimension_count())
3132 vector<array_type_def::subrange_sptr>::const_iterator si;
3134 for (si = decl->get_subranges().begin();
3135 si != decl->get_subranges().end(); ++si)
3137 unsigned local_indent =
3138 indent + ctxt.get_config().get_xml_element_indent();
3139 write_array_subrange_type(*si, ctxt, local_indent);
3142 do_indent(o, indent);
3143 o <<
"</array-type-def>\n";
3160 write_context& ctxt,
3162{
return write_array_type_def(decl,
"", ctxt, indent);}
3184 write_context& ctxt,
3192 annotate(decl->get_canonical_type(), ctxt, indent);
3194 ostream& o = ctxt.get_ostream();
3196 do_indent(o, indent);
3199 write_naming_typedef(decl, ctxt);
3200 write_is_artificial(decl, o);
3201 write_is_non_reachable(
is_type(decl), o);
3203 if (!decl->get_linkage_name().empty())
3204 o <<
" linkage-name='"
3208 write_common_type_info(decl, ctxt,
id);
3212 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3213 o <<
"<underlying-type type-id='"
3214 << ctxt.get_id_for_type(decl->get_underlying_type())
3217 for (enum_type_decl::enumerators::const_iterator i =
3218 decl->get_enumerators().begin();
3219 i != decl->get_enumerators().end();
3222 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3223 o <<
"<enumerator name='"
3230 do_indent(o, indent);
3231 o <<
"</enum-decl>\n";
3247 write_context& ctxt,
3249{
return write_enum_type_decl(decl,
"", ctxt, indent);}
3263 write_context& ctxt,
3269 ostream &o = ctxt.get_ostream();
3271 annotate(sym, ctxt, indent);
3272 do_indent(o, indent);
3274 if (sym->is_variable() && sym->get_size())
3275 o <<
" size='" << sym->get_size() <<
"'";
3277 if (!sym->get_version().is_empty())
3279 o <<
" version='" << sym->get_version().str() <<
"'";
3280 o <<
" is-default-version='";
3281 if (sym->get_version().is_default())
3288 write_elf_symbol_type(sym->get_type(), o);
3290 write_elf_symbol_binding(sym->get_binding(), o);
3292 write_elf_symbol_visibility(sym->get_visibility(), o);
3294 write_elf_symbol_aliases(*sym, o);
3296 o <<
" is-defined='";
3297 if (sym->is_defined())
3303 if (sym->is_common_symbol())
3304 o <<
" is-common='yes'";
3306 if (sym->get_crc().has_value())
3308 << std::hex << std::showbase << sym->get_crc().value()
3309 << std::dec << std::noshowbase <<
"'";
3311 if (sym->get_namespace().has_value())
3312 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3331 write_context& ctxt,
3337 for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
3338 write_elf_symbol(*it, ctxt, indent);
3354write_elf_needed(
const vector<string>& needed,
3355 write_context& ctxt,
3361 ostream& o = ctxt.get_ostream();
3363 for (vector<string>::const_iterator i = needed.begin();
3367 do_indent(o, indent);
3368 o <<
"<dependency name='" << *i <<
"'/>\n";
3393 write_context& ctxt,
3399 ostream &o = ctxt.get_ostream();
3401 annotate(decl, ctxt, indent);
3403 do_indent(o, indent);
3405 o <<
"<typedef-decl name='"
3409 type_base_sptr underlying_type = decl->get_underlying_type();
3410 string type_id = ctxt.get_id_for_type(underlying_type);
3411 o <<
" type-id='" << type_id <<
"'";
3412 ctxt.record_type_as_referenced(underlying_type);
3414 write_common_type_info(decl, ctxt,
id);
3432 write_context& ctxt,
3434{
return write_typedef_decl(decl,
"", ctxt, indent);}
3449write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
3450 bool write_linkage_name,
unsigned indent)
3455 annotate(decl, ctxt, indent);
3457 ostream &o = ctxt.get_ostream();
3459 do_indent(o, indent);
3462 type_base_sptr var_type = decl->get_type();
3463 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
3464 ctxt.record_type_as_referenced(var_type);
3466 if (write_linkage_name)
3468 const string& linkage_name = decl->get_linkage_name();
3469 if (!linkage_name.empty())
3470 o <<
" mangled-name='" << linkage_name <<
"'";
3473 write_visibility(decl, o);
3475 write_binding(decl, o);
3477 write_location(decl, ctxt);
3480 if (corpus* abi = decl->get_corpus())
3481 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3485 ctxt.record_decl_as_emitted(decl);
3504 bool skip_first_parm,
3505 write_context& ctxt,
3509 fun_type->get_canonical_type()
3513 unsigned cur_indent =
3514 indent + ctxt.get_config().get_xml_element_indent();
3516 ostream &o = ctxt.get_ostream();
3518 type_base_sptr parm_type;
3519 auto pi = t->get_parameters().begin();
3520 for ((skip_first_parm && pi != t->get_parameters().end()) ? ++pi: pi;
3521 pi != t->get_parameters().end();
3524 if ((*pi)->get_variadic_marker())
3526 do_indent(o, cur_indent);
3527 o <<
"<parameter is-variadic='yes'";
3531 parm_type = (*pi)->get_type();
3533 annotate(*pi, ctxt, cur_indent);
3534 do_indent(o, cur_indent);
3536 o <<
"<parameter type-id='"
3537 << ctxt.get_id_for_type(parm_type)
3539 ctxt.record_type_as_referenced(parm_type);
3541 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3544 write_is_artificial(*pi, o);
3545 write_location((*pi)->get_location(), ctxt);
3549 if (shared_ptr<type_base> return_type = t->get_return_type())
3551 annotate(return_type , ctxt, cur_indent);
3552 do_indent(o, cur_indent);
3553 o <<
"<return type-id='"
3554 << ctxt.get_id_for_type(return_type)
3556 ctxt.record_type_as_referenced(return_type);
3574 bool skip_first_parm,
unsigned indent)
3579 annotate(decl, ctxt, indent);
3581 ostream &o = ctxt.get_ostream();
3583 do_indent(o, indent);
3585 o <<
"<function-decl name='"
3589 if (!decl->get_linkage_name().empty())
3590 o <<
" mangled-name='"
3593 write_location(decl, ctxt);
3595 if (decl->is_declared_inline())
3596 o <<
" declared-inline='yes'";
3598 write_visibility(decl, o);
3600 write_binding(decl, o);
3602 write_size_and_alignment(decl->get_type(), o,
3603 (ctxt.get_write_default_sizes()
3605 : decl->get_translation_unit()->get_address_size()),
3608 if (corpus* abi = decl->get_corpus())
3609 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3611 write_type_hash_and_cti(decl->get_type(), o);
3615 write_fn_parm_and_return_types(decl->get_type(),
3619 do_indent(o, indent);
3620 o <<
"</function-decl>\n";
3622 ctxt.record_decl_as_emitted(decl);
3638 write_context& ctxt,
unsigned indent)
3647 fun_type->get_canonical_type()
3651 ostream &o = ctxt.get_ostream();
3653 annotate(fn_type, ctxt, indent);
3655 do_indent(o, indent);
3657 o <<
"<function-type";
3662 o <<
" method-class-id='"
3663 << ctxt.get_id_for_type(method_type->get_class_type())
3666 write_cdtor_const_static(
false,
false,
3667 method_type->get_is_const(),
3671 write_common_type_info(fn_type, ctxt);
3675 write_fn_parm_and_return_types(fn_type,
false,
3678 do_indent(o, indent);
3680 o <<
"</function-type>\n";
3705 write_context& ctxt,
3707 bool prepare_to_handle_empty)
3712 ostream& o = ctxt.get_ostream();
3714 do_indent_to_level(ctxt, indent, 0);
3718 write_is_struct(decl, o);
3720 write_is_artificial(decl, o);
3722 write_is_non_reachable(
is_type(decl), o);
3724 write_naming_typedef(decl, ctxt);
3726 write_visibility(decl, o);
3728 if (decl->get_earlier_declaration())
3731 o <<
" def-of-decl-id='"
3732 << ctxt.get_id_for_type(
is_type(decl->get_earlier_declaration()))
3736 write_common_type_info(decl, ctxt,
id);
3738 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
3764write_union_decl_opening_tag(
const union_decl_sptr& decl,
3766 write_context& ctxt,
3768 bool prepare_to_handle_empty)
3773 ostream& o = ctxt.get_ostream();
3775 do_indent_to_level(ctxt, indent, 0);
3779 write_naming_typedef(decl, ctxt);
3781 write_visibility(decl, o);
3783 write_is_artificial(decl, o);
3785 write_is_non_reachable(
is_type(decl), o);
3787 write_common_type_info(decl, ctxt,
id);
3789 if (prepare_to_handle_empty && decl->has_no_member())
3815 write_context& ctxt,
3823 annotate(decl, ctxt, indent);
3825 ostream& o = ctxt.get_ostream();
3827 if (decl->get_is_declaration_only())
3831 const environment& env = ctxt.get_environment();
3849 *decl->get_corpus(),
3852 for (
auto t : result)
3854 type_base_sptr type(t);
3856 for (
auto m : c->get_member_types())
3857 if (member_types.find(m) != member_types.end())
3858 member_types.insert(m);
3862 if (!member_types.empty())
3868 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3870 member_types.empty());
3872 vector<type_base_sptr> sorted_types;
3875 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3877 for (
auto t : sorted_types)
3878 if (!ctxt.type_is_emitted(t))
3879 write_member_type(t, ctxt, nb_ws);
3881 if (!member_types.empty())
3882 o << indent <<
"</class-decl>\n";
3887 for (
auto t : result)
3888 ctxt.record_type_as_emitted(type_base_sptr(t));
3893 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3896 if (!decl->has_no_base_nor_member())
3898 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3899 type_base_sptr base_type;
3900 for (class_decl::base_specs::const_iterator base =
3901 decl->get_base_specifiers().begin();
3902 base != decl->get_base_specifiers().end();
3905 annotate((*base)->get_base_class(), ctxt, nb_ws);
3906 do_indent(o, nb_ws);
3909 write_access((*base)->get_access_specifier(), o);
3911 write_layout_offset (*base, o);
3913 if ((*base)->get_is_virtual ())
3914 o <<
" is-virtual='yes'";
3916 base_type = (*base)->get_base_class();
3918 << ctxt.get_id_for_type(base_type)
3921 ctxt.record_type_as_referenced(base_type);
3924 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
3927 for (class_decl::member_types::const_iterator ti =
3928 decl->get_sorted_member_types().begin();
3929 ti != decl->get_sorted_member_types().end();
3931 if (!(*ti)->get_naked_canonical_type())
3932 write_member_type(*ti, ctxt, nb_ws);
3935 for (
const auto& s_dm : decl->get_static_data_members())
3937 do_indent(o, nb_ws);
3938 o <<
"<data-member";
3943 write_cdtor_const_static(
false,
3948 write_layout_offset(s_dm, o);
3951 write_var_decl(s_dm, ctxt, is_static,
3952 get_indent_to_level(ctxt, indent, 2));
3954 do_indent_to_level(ctxt, indent, 1);
3955 o <<
"</data-member>\n";
3959 for (
const auto& dm : decl->get_non_static_data_members())
3961 do_indent(o, nb_ws);
3962 o <<
"<data-member";
3966 write_cdtor_const_static(
false,
3971 write_layout_offset(dm, o);
3974 write_var_decl(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";
3981 for (class_decl::member_functions::const_iterator f =
3982 decl->get_member_functions().begin();
3983 f != decl->get_member_functions().end();
3994 do_indent(o, nb_ws);
3995 o <<
"<member-function";
4004 write_function_decl(fn, ctxt,
4006 get_indent_to_level(ctxt, indent, 2));
4008 do_indent_to_level(ctxt, indent, 1);
4009 o <<
"</member-function>\n";
4012 for (class_decl::member_functions::const_iterator f =
4013 decl->get_virtual_mem_fns().begin();
4014 f != decl->get_virtual_mem_fns().end();
4021 do_indent(o, nb_ws);
4022 o <<
"<member-function";
4029 write_voffset(fn, o);
4032 write_function_decl(fn, ctxt,
4034 get_indent_to_level(ctxt, indent, 2));
4036 do_indent_to_level(ctxt, indent, 1);
4037 o <<
"</member-function>\n";
4040 for (member_function_templates::const_iterator fn =
4041 decl->get_member_function_templates().begin();
4042 fn != decl->get_member_function_templates().end();
4045 do_indent(o, nb_ws);
4046 o <<
"<member-template";
4047 write_access((*fn)->get_access_specifier(), o);
4048 write_cdtor_const_static((*fn)->is_constructor(),
4051 (*fn)->get_is_static(), o);
4053 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4054 get_indent_to_level(ctxt, indent, 2));
4055 do_indent(o, nb_ws);
4056 o <<
"</member-template>\n";
4059 for (member_class_templates::const_iterator cl =
4060 decl->get_member_class_templates().begin();
4061 cl != decl->get_member_class_templates().end();
4064 do_indent(o, nb_ws);
4065 o <<
"<member-template";
4066 write_access((*cl)->get_access_specifier(), o);
4067 write_cdtor_const_static(
false,
false,
false,
4068 (*cl)->get_is_static(), o);
4070 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4071 get_indent_to_level(ctxt, indent, 2));
4072 do_indent(o, nb_ws);
4073 o <<
"</member-template>\n";
4076 do_indent_to_level(ctxt, indent, 0);
4078 o <<
"</class-decl>\n";
4081 ctxt.record_type_as_emitted(decl);
4097 write_context& ctxt,
4099{
return write_class_decl(decl,
"", ctxt, indent);}
4111write_union_decl(
const union_decl_sptr& d,
4113 write_context& ctxt,
4121 annotate(decl, ctxt, indent);
4123 ostream& o = ctxt.get_ostream();
4125 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4127 if (!decl->has_no_member())
4129 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4130 for (class_decl::member_types::const_iterator ti =
4131 decl->get_member_types().begin();
4132 ti != decl->get_member_types().end();
4134 if (!(*ti)->get_naked_canonical_type())
4135 write_member_type(*ti, ctxt, nb_ws);
4137 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4140 for (union_decl::data_members::const_iterator data =
4141 decl->get_data_members().begin();
4142 data != decl->get_data_members().end();
4145 do_indent(o, nb_ws);
4146 o <<
"<data-member";
4150 write_cdtor_const_static(
false,
4157 write_var_decl(*data, ctxt, is_static,
4158 get_indent_to_level(ctxt, indent, 2));
4160 do_indent_to_level(ctxt, indent, 1);
4161 o <<
"</data-member>\n";
4164 for (union_decl::member_functions::const_iterator f =
4165 decl->get_member_functions().begin();
4166 f != decl->get_member_functions().end();
4177 do_indent(o, nb_ws);
4178 o <<
"<member-function";
4187 write_function_decl(fn, ctxt,
4189 get_indent_to_level(ctxt, indent, 2));
4191 do_indent_to_level(ctxt, indent, 1);
4192 o <<
"</member-function>\n";
4195 for (member_function_templates::const_iterator fn =
4196 decl->get_member_function_templates().begin();
4197 fn != decl->get_member_function_templates().end();
4200 do_indent(o, nb_ws);
4201 o <<
"<member-template";
4202 write_access((*fn)->get_access_specifier(), o);
4203 write_cdtor_const_static((*fn)->is_constructor(),
4206 (*fn)->get_is_static(), o);
4208 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4209 get_indent_to_level(ctxt, indent, 2));
4210 do_indent(o, nb_ws);
4211 o <<
"</member-template>\n";
4214 for (member_class_templates::const_iterator cl =
4215 decl->get_member_class_templates().begin();
4216 cl != decl->get_member_class_templates().end();
4219 do_indent(o, nb_ws);
4220 o <<
"<member-template";
4221 write_access((*cl)->get_access_specifier(), o);
4222 write_cdtor_const_static(
false,
false,
false,
4223 (*cl)->get_is_static(), o);
4225 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4226 get_indent_to_level(ctxt, indent, 2));
4227 do_indent(o, nb_ws);
4228 o <<
"</member-template>\n";
4231 do_indent_to_level(ctxt, indent, 0);
4233 o <<
"</union-decl>\n";
4240write_union_decl(
const union_decl_sptr& decl,
4241 write_context& ctxt,
4243{
return write_union_decl(decl,
"", ctxt, indent);}
4255write_member_type_opening_tag(
const type_base_sptr& t,
4256 write_context& ctxt,
4259 ostream& o = ctxt.get_ostream();
4261 do_indent_to_level(ctxt, indent, 0);
4266 o <<
"<member-type";
4267 write_access(decl, o);
4286write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4291 ostream& o = ctxt.get_ostream();
4293 write_member_type_opening_tag(t, ctxt, indent);
4295 string id = ctxt.get_id_for_type(t);
4297 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4298 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4300 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4302 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4304 || write_ptr_to_mbr_type(dynamic_pointer_cast<ptr_to_mbr_type>(t),
4306 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4308 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4310 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4312 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4314 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
4317 do_indent_to_level(ctxt, indent, 0);
4318 o <<
"</member-type>\n";
4334 write_context& ctxt,
4340 ostream &o = ctxt.get_ostream();
4341 do_indent_to_level(ctxt, indent, 0);
4343 string id_attr_name;
4344 if (ctxt.type_has_existing_id(decl))
4345 id_attr_name =
"type-id";
4347 id_attr_name =
"id";
4349 o <<
"<template-type-parameter "
4350 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
4354 o <<
" name='" << name <<
"'";
4356 write_location(decl, ctxt);
4360 ctxt.record_type_as_emitted(decl);
4375write_non_type_tparameter(
4376 const shared_ptr<non_type_tparameter> decl,
4377 write_context& ctxt,
unsigned indent)
4382 ostream &o = ctxt.get_ostream();
4383 do_indent_to_level(ctxt, indent, 0);
4385 o <<
"<template-non-type-parameter type-id='"
4386 << ctxt.get_id_for_type(decl->get_type())
4391 o <<
" name='" << name <<
"'";
4393 write_location(decl, ctxt);
4412 write_context& ctxt,
4418 ostream& o = ctxt.get_ostream();
4419 do_indent_to_level(ctxt, indent, 0);
4421 string id_attr_name =
"id";
4422 if (ctxt.type_has_existing_id(decl))
4423 id_attr_name =
"type-id";
4425 o <<
"<template-template-parameter " << id_attr_name <<
"='"
4426 << ctxt.get_id_for_type(decl) <<
"'";
4430 o <<
" name='" << name <<
"'";
4434 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4435 for (list<shared_ptr<template_parameter> >::const_iterator p =
4436 decl->get_template_parameters().begin();
4437 p != decl->get_template_parameters().end();
4439 write_template_parameter(decl, ctxt, nb_spaces);
4441 do_indent_to_level(ctxt, indent, 0);
4442 o <<
"</template-template-parameter>\n";
4444 ctxt.record_type_as_emitted(decl);
4459write_type_composition
4460(
const shared_ptr<type_composition> decl,
4461 write_context& ctxt,
unsigned indent)
4466 ostream& o = ctxt.get_ostream();
4468 do_indent_to_level(ctxt, indent, 0);
4470 o <<
"<template-parameter-type-composition>\n";
4472 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4473 (write_pointer_type_def
4474 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
4476 || write_reference_type_def
4477 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
4479 || write_array_type_def
4480 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
4482 || write_qualified_type_def
4483 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
4486 do_indent_to_level(ctxt, indent, 0);
4487 o <<
"</template-parameter-type-composition>\n";
4502write_template_parameter(
const shared_ptr<template_parameter> decl,
4503 write_context& ctxt,
unsigned indent)
4505 if ((!write_type_tparameter
4506 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
4507 && (!write_non_type_tparameter
4508 (dynamic_pointer_cast<non_type_tparameter>(decl),
4510 && (!write_template_tparameter
4511 (dynamic_pointer_cast<template_tparameter>(decl),
4513 && (!write_type_composition
4514 (dynamic_pointer_cast<type_composition>(decl),
4525write_template_parameters(
const shared_ptr<template_decl> tmpl,
4526 write_context& ctxt,
unsigned indent)
4531 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4532 for (list<shared_ptr<template_parameter> >::const_iterator p =
4533 tmpl->get_template_parameters().begin();
4534 p != tmpl->get_template_parameters().end();
4536 write_template_parameter(*p, ctxt, nb_spaces);
4547write_function_tdecl(
const shared_ptr<function_tdecl> decl,
4548 write_context& ctxt,
unsigned indent)
4553 ostream& o = ctxt.get_ostream();
4555 do_indent_to_level(ctxt, indent, 0);
4557 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
4559 write_location(decl, ctxt);
4561 write_visibility(decl, o);
4563 write_binding(decl, o);
4567 write_template_parameters(decl, ctxt, indent);
4569 write_function_decl(decl->get_pattern(), ctxt,
4571 get_indent_to_level(ctxt, indent, 1));
4573 do_indent_to_level(ctxt, indent, 0);
4575 o <<
"</function-template-decl>\n";
4592write_class_tdecl(
const shared_ptr<class_tdecl> decl,
4593 write_context& ctxt,
unsigned indent)
4598 ostream& o = ctxt.get_ostream();
4600 do_indent_to_level(ctxt, indent, 0);
4602 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
4604 write_location(decl, ctxt);
4606 write_visibility(decl, o);
4610 write_template_parameters(decl, ctxt, indent);
4612 write_class_decl(decl->get_pattern(), ctxt,
4613 get_indent_to_level(ctxt, indent, 1));
4615 do_indent_to_level(ctxt, indent, 0);
4617 o <<
"</class-template-decl>\n";
4626write_version_info(write_context& ctxt)
4628 ostream& o = ctxt.get_ostream();
4629 const config& c = ctxt.get_config();
4632 << c.get_format_major_version_number()
4633 <<
"." << c.get_format_minor_version_number()
4653 const corpus_sptr&
corpus,
4655 bool member_of_group)
4663 do_indent_to_level(ctxt, indent, 0);
4665 std::ostream& out = ctxt.get_ostream();
4667 out <<
"<abi-corpus ";
4669 write_version_info(ctxt);
4674 if (!ctxt.get_write_corpus_path())
4676 if (member_of_group)
4679 corpus_path.clear();
4683 if (ctxt.get_short_locs())
4686 if (!corpus_path.empty())
4690 && ctxt.get_write_architecture())
4696 write_tracking_non_reachable_types(
corpus, out);
4704 do_indent_to_level(ctxt, indent, 1);
4705 out <<
"<elf-needed>\n";
4707 get_indent_to_level(ctxt, indent, 2));
4708 do_indent_to_level(ctxt, indent, 1);
4709 out <<
"</elf-needed>\n";
4715 do_indent_to_level(ctxt, indent, 1);
4716 out <<
"<elf-function-symbols>\n";
4719 get_indent_to_level(ctxt, indent, 2));
4721 do_indent_to_level(ctxt, indent, 1);
4722 out <<
"</elf-function-symbols>\n";
4728 do_indent_to_level(ctxt, indent, 1);
4729 out <<
"<elf-variable-symbols>\n";
4732 get_indent_to_level(ctxt, indent, 2));
4734 do_indent_to_level(ctxt, indent, 1);
4735 out <<
"</elf-variable-symbols>\n";
4739 if (ctxt.get_write_undefined_symbols()
4742 do_indent_to_level(ctxt, indent, 1);
4743 out <<
"<undefined-elf-function-symbols>\n";
4746 get_indent_to_level(ctxt, indent, 2));
4748 do_indent_to_level(ctxt, indent, 1);
4749 out <<
"</undefined-elf-function-symbols>\n";
4754 if (ctxt.get_write_undefined_symbols()
4757 do_indent_to_level(ctxt, indent, 1);
4758 out <<
"<undefined-elf-variable-symbols>\n";
4761 get_indent_to_level(ctxt, indent, 2));
4763 do_indent_to_level(ctxt, indent, 1);
4764 out <<
"</undefined-elf-variable-symbols>\n";
4769 for (translation_units::const_iterator i =
4776 get_indent_to_level(ctxt, indent, 1),
4780 do_indent_to_level(ctxt, indent, 0);
4781 out <<
"</abi-corpus>\n";
4783 ctxt.clear_referenced_types();
4784 ctxt.record_corpus_as_emitted(
corpus);
4801 const corpus_group_sptr& group,
4808 do_indent_to_level(ctxt, indent, 0);
4810std::ostream& out = ctxt.get_ostream();
4812 out <<
"<abi-corpus-group ";
4813 write_version_info(ctxt);
4815 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
4818 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
4819 out <<
" architecture='" << group->get_architecture_name()<<
"'";
4821 write_tracking_non_reachable_types(group, out);
4823 if (group->is_empty())
4832 for (corpus_group::corpora_type::const_iterator c =
4833 group->get_corpora().begin();
4834 c != group->get_corpora().end();
4838 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
4841 do_indent_to_level(ctxt, indent, 0);
4842 out <<
"</abi-corpus-group>\n";
4863 xml_writer::write_context ctxt(d->get_environment(), o);
4865 write_decl(d, ctxt, 0);
4907 xml_writer::write_context ctxt(v->get_environment(), o);
4909 write_var_decl(v, ctxt,
true, 0);
4978 unsigned line = 0, col = 0;
4980 l.
expand(path, line, col);
4981 o << path <<
":" << line <<
"," << col <<
"\n";
5031#ifdef WITH_DEBUG_SELF_COMPARISON
5042write_type_record(xml_writer::write_context& ctxt,
5065 id = ctxt.get_id_for_type (
const_cast<type_base*
>(type));
5068 <<
" <id>" <<
id <<
"</id>\n"
5071 <<
reinterpret_cast<uintptr_t
>(canonical)
5087write_canonical_type_ids(xml_writer::write_context& ctxt, ostream& o)
5106 o <<
"<abixml-types-check>\n";
5108 for (
const auto &type : ctxt.get_emitted_types_set())
5109 write_type_record(ctxt, type, o);
5111 o <<
"</abixml-types-check>\n";
5124write_canonical_type_ids(xml_writer::write_context& ctxt,
5125 const string &file_path)
5127 std:: ofstream o (file_path);
5131 write_canonical_type_ids(ctxt, o);
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
This type abstracts the configuration information of the library.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
virtual const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
virtual const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
const string & get_soname()
Getter for the soname property of the corpus.
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
virtual bool is_empty() const
Tests if the corpus is empty from an ABI surface perspective. I.e. if all of these criteria are true:
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
string & get_path() const
Get the file path associated to the corpus file.
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
The base type of all declarations.
const location & get_location() const
Get the location of a given declaration.
visibility
ELF visibility.
binding
The binding of a symbol.
type
The type of a symbol.
visibility
The visibility of the symbol.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
interned_string intern(const string &) const
Do intern a string.
Abstraction for a function declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Abstraction of a function type.
The source location of a token.
bool get_is_artificial() const
Test if the location is artificial.
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
A declaration that introduces a scope.
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
char get_address_size() const
Getter of the address size in this translation unit.
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
const std::string & get_path() const
Get the path of the current translation unit.
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
const environment & get_environment() const
Getter of the environment of the current translation_unit.
language get_language() const
Getter of the language of the source code of the translation unit.
An abstraction helper for type declarations.
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
The abstraction of a typedef declaration.
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
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 ...
uint32_t fnv_hash(const std::string &str)
Compute a stable string hash.
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.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
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...
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...
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
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< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
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.
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.
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...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
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.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
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...
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
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.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
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.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
void set_write_undefined_symbols(write_context &ctxt, bool flag)
Set the 'undefined-symbols' flag.
void set_short_locs(write_context &ctxt, bool flag)
Set the 'short-locs' flag.
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.
std::unordered_set< function_type * > fn_type_ptr_set_type
A convenience typedef for a set of function type*.
void set_write_parameter_names(write_context &ctxt, bool flag)
Set the 'parameter-names' flag.
bool annotate(const function_decl::parameter_sptr &parm, write_context &ctxt, unsigned indent)
Annotate a function parameter in form of an ABIXML comment.
void set_ostream(write_context &ctxt, ostream &os)
Set the new ostream.
shared_ptr< write_context > write_context_sptr
A convenience typedef for a shared pointer to write_context.
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...
void set_annotate(write_context &ctxt, bool flag)
Set the 'annotate' flag.
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.
void set_write_default_sizes(write_context &ctxt, bool flag)
Set the 'default-sizes' flag.
void set_write_elf_needed(write_context &ctxt, bool flag)
Set the 'elf-needed' flag.
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 ...
void set_write_corpus_path(write_context &ctxt, bool flag)
Set the 'write-corpus-path' flag.
void set_write_architecture(write_context &ctxt, bool flag)
Set the 'write-architecture' flag.
type_id_style_kind
The style of type id the XML writer will output.
void set_show_locs(write_context &ctxt, bool flag)
Set the "show-locs" flag.
unordered_map< type_base *, interned_string > type_ptr_map
A convenience typedef for a map that associates a pointer to type to a string.
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.
void set_type_id_style(write_context &ctxt, type_id_style_kind style)
Set the 'type-id-style' property.
void set_write_comp_dir(write_context &ctxt, bool flag)
Set the 'write-comp-dir' flag.
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.
void escape_xml_comment(const std::string &str, std::string &escaped)
Escape the '-' character, to avoid having a '–' in a comment.
void escape_xml_string(const std::string &str, std::string &escaped)
Escape the 5 characters representing the predefined XML entities.
Toplevel namespace for libabigail.
void dump(const decl_base_sptr d, std::ostream &o, const bool annotate)
Serialize a pointer to decl_base to an output stream.
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 dump_location(const location &l, ostream &o)
Serialize a source location to an output stream.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.
Datum consolidating style preferences.