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();
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;}
840static void write_location(
const location&, write_context&);
841static void write_location(
const decl_base_sptr&, write_context&);
842static bool write_visibility(
const decl_base_sptr&, ostream&);
843static bool write_binding(
const decl_base_sptr&, ostream&);
844static bool write_is_artificial(
const decl_base_sptr&, ostream&);
845static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
846static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
849static void write_size_and_alignment(
const type_base_sptr, ostream&,
850 size_t default_size = 0,
851 size_t default_alignment = 0);
855static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
859static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
860static bool write_elf_symbol_reference(write_context&,
864static bool write_elf_symbol_reference(write_context&,
868static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
870static void write_is_anonymous(
const decl_base_sptr&, ostream&);
871static void write_type_hash_and_cti(
const type_base_sptr&, ostream&);
872static void write_naming_typedef(
const decl_base_sptr&, write_context&);
873static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
874static void write_decl_in_scope(
const decl_base_sptr&,
875 write_context&,
unsigned);
876static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
878 write_context&,
unsigned);
879static 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);
898static 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);
906static bool write_member_type_opening_tag(
const type_base_sptr&,
907 write_context&,
unsigned);
908static bool write_member_type(
const type_base_sptr&,
909 write_context&,
unsigned);
910static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
911 write_context&,
unsigned,
bool);
913 write_context&,
unsigned);
914static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
915 write_context&,
unsigned,
bool);
916static bool write_union_decl(
const union_decl_sptr&,
const string&,
917 write_context&,
unsigned);
918static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
919static void write_common_type_info(
const type_base_sptr&, write_context&,
920 const string&
id=
"");
921static bool write_type(
const type_base_sptr&, write_context&,
unsigned);
922static bool write_type_tparameter
923(
const shared_ptr<type_tparameter>, write_context&,
unsigned);
924static bool write_non_type_tparameter
925(
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
926static bool write_template_tparameter
927(
const shared_ptr<template_tparameter>, write_context&,
unsigned);
928static bool write_type_composition
929(
const shared_ptr<type_composition>, write_context&,
unsigned);
930static bool write_template_parameter(
const shared_ptr<template_parameter>,
931 write_context&,
unsigned);
932static void write_template_parameters(
const shared_ptr<template_decl>,
933 write_context&,
unsigned);
934static bool write_function_tdecl
935(
const shared_ptr<function_tdecl>,
936 write_context&,
unsigned);
937static bool write_class_tdecl
938(
const shared_ptr<class_tdecl>,
939 write_context&,
unsigned);
940static void do_indent(ostream&,
unsigned);
941static void do_indent_to_level(write_context&,
unsigned,
unsigned);
942static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
946do_indent(ostream& o,
unsigned nb_whitespaces)
948 for (
unsigned i = 0; i < nb_whitespaces; ++i)
960do_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));
977get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
980 int nb_ws = initial_indent +
981 level * ctxt.get_config().get_xml_element_indent();
1001template <
typename T>
1003annotate(
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 '"
1232write_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 <<
"'";
1263write_location(
const decl_base_sptr& decl,
1264 write_context& ctxt)
1269 location loc = decl->get_location();
1273 write_location(loc, ctxt);
1285write_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 <<
"'";
1325write_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 <<
"'";
1375write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1380 if (decl->get_is_artificial())
1381 o <<
" is-artificial='yes'";
1395write_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'";
1421write_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'";
1449write_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 <<
"'";
1466write_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='"
1526write_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() <<
"'";
1541write_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 <<
"'";
1681write_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;
1736write_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='"
1795write_elf_symbol_reference(write_context& ctxt,
1803 return write_elf_symbol_reference(ctxt, *sym, abi, o);
1820write_cdtor_const_static(
bool is_ctor,
1827 o <<
" static='yes'";
1829 o <<
" constructor='yes'";
1831 o <<
" destructor='yes'";
1833 o <<
" const='yes'";
1843write_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'";
1869write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1871 if (decl->get_is_anonymous())
1872 o <<
" is-anonymous='yes'";
1881write_type_hash_and_cti(
const type_base_sptr& t, ostream& o)
1888 o <<
" hash='" << h;
1889 if (t->priv_->canonical_type_index)
1890 o <<
"#" << t->priv_->canonical_type_index;
1902write_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);
1925write_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);
1968write_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)))
2011write_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)))
2066write_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);}
2378write_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);
2417referenced_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))
2442write_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";
2710write_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";
2801write_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);
2848write_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);
3377write_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);}
3472write_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())
3787write_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);}
4134write_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";
4263write_union_decl(
const union_decl_sptr& decl,
4264 write_context& ctxt,
4266{
return write_union_decl(decl,
"", ctxt, indent);}
4278write_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);
4309write_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);
4398write_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);
4482write_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";
4525write_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),
4548write_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);
4570write_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";
4615write_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";
4649write_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)
4686 do_indent_to_level(ctxt, indent, 0);
4688 std::ostream& out = ctxt.get_ostream();
4690 out <<
"<abi-corpus ";
4692 write_version_info(ctxt);
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())
4713 && ctxt.get_write_architecture())
4719 write_tracking_non_reachable_types(
corpus, out);
4727 do_indent_to_level(ctxt, indent, 1);
4728 out <<
"<elf-needed>\n";
4730 get_indent_to_level(ctxt, indent, 2));
4731 do_indent_to_level(ctxt, indent, 1);
4732 out <<
"</elf-needed>\n";
4738 do_indent_to_level(ctxt, indent, 1);
4739 out <<
"<elf-function-symbols>\n";
4742 get_indent_to_level(ctxt, indent, 2));
4744 do_indent_to_level(ctxt, indent, 1);
4745 out <<
"</elf-function-symbols>\n";
4751 do_indent_to_level(ctxt, indent, 1);
4752 out <<
"<elf-variable-symbols>\n";
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()
4765 do_indent_to_level(ctxt, indent, 1);
4766 out <<
"<undefined-elf-function-symbols>\n";
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()
4780 do_indent_to_level(ctxt, indent, 1);
4781 out <<
"<undefined-elf-variable-symbols>\n";
4784 get_indent_to_level(ctxt, indent, 2));
4786 do_indent_to_level(ctxt, indent, 1);
4787 out <<
"</undefined-elf-variable-symbols>\n";
4792 for (translation_units::const_iterator i =
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);
4833std::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);
4930 xml_writer::write_context ctxt(v->get_environment(), o);
4932 write_var_decl(v, ctxt,
true, 0);
5001 unsigned line = 0, col = 0;
5003 l.
expand(path, line, col);
5004 o << path <<
":" << line <<
"," << col <<
"\n";
5054#ifdef WITH_DEBUG_SELF_COMPARISON
5065write_type_record(xml_writer::write_context& ctxt,
5088 id = ctxt.get_id_for_type (
const_cast<type_base*
>(type));
5091 <<
" <id>" <<
id <<
"</id>\n"
5094 <<
reinterpret_cast<uintptr_t
>(canonical)
5110write_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";
5147write_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);
#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.