23#include <unordered_map>
28#include "abg-internal.h"
30ABG_BEGIN_EXPORT_DECLARATIONS
41ABG_END_EXPORT_DECLARATIONS
48using std::dynamic_pointer_cast;
49using std::static_pointer_cast;
52using std::ostringstream;
56using std::unordered_map;
69 mutable unsigned long long m_cur_id;
73 {
return ++m_cur_id; }
81 get_environment()
const
91 return env.
intern(o.str());
99 get_id_with_prefix(
const string& prefix)
const
102 o << prefix << get_new_id();
104 return env.
intern(o.str());
114struct non_canonicalized_type_hash
133 return h(p->get_pretty_representation(
false,
149struct non_canonicalized_type_equal
175typedef std::unordered_set<const type_base*> type_ptr_set_type;
181typedef std::unordered_set<
const type_base*,
182 non_canonicalized_type_hash,
183 non_canonicalized_type_equal>
191 non_canonicalized_type_hash,
192 non_canonicalized_type_equal>
198typedef unordered_map<shared_ptr<function_tdecl>,
202typedef unordered_map<shared_ptr<class_tdecl>,
209 id_manager m_id_manager;
213 bool m_write_architecture;
214 bool m_write_corpus_path;
215 bool m_write_comp_dir;
216 bool m_write_elf_needed;
217 bool m_write_parameter_names;
219 bool m_write_default_sizes;
223 mutable unordered_set<uint32_t> m_used_type_id_hashes;
224 mutable type_ptr_set_type m_emitted_type_set;
227 type_ptr_set_type m_referenced_types_set;
229 fn_tmpl_shared_ptr_map m_fn_tmpl_id_map;
230 class_tmpl_shared_ptr_map m_class_tmpl_id_map;
233 unordered_set<interned_string, hash_interned_string> m_emitted_decls_set;
234 unordered_set<string> m_emitted_corpora_set;
251 m_write_architecture(
true),
252 m_write_corpus_path(
true),
253 m_write_comp_dir(
true),
254 m_write_elf_needed(
true),
255 m_write_parameter_names(
true),
257 m_write_default_sizes(
true),
258 m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
265 get_environment()
const
270 {
return get_environment().get_config();}
304 get_write_architecture()
305 {
return m_write_architecture;}
312 {m_write_architecture = f;}
318 get_write_elf_needed()
319 {
return m_write_elf_needed;}
326 {m_write_elf_needed = f;}
332 get_write_default_sizes()
333 {
return m_write_default_sizes;}
340 {m_write_default_sizes = f;}
346 get_write_corpus_path()
347 {
return m_write_corpus_path;}
354 {m_write_corpus_path = f;}
361 {
return m_write_comp_dir;}
368 {m_write_comp_dir = f;}
375 {
return m_short_locs;}
388 get_write_parameter_names()
const
389 {
return m_write_parameter_names;}
396 {m_write_parameter_names = f;}
405 get_show_locs()
const
406 {
return m_show_locs;}
424 get_type_id_style()
const
425 {
return m_type_id_style;}
434 {m_type_id_style =
style;}
441 get_id_manager()
const
442 {
return m_id_manager;}
446 {
return m_id_manager;}
450 type_has_existing_id(type_base_sptr type)
const
451 {
return type_has_existing_id(type.get());}
455 type_has_existing_id(
type_base* type)
const
458 return m_type_id_map.find(type) != m_type_id_map.end();
466 get_id_for_type(
const type_base_sptr& t)
467 {
return get_id_for_type(t.get());}
478 auto it = m_type_id_map.find(c);
479 if (it != m_type_id_map.end())
482 switch (m_type_id_style)
484 case SEQUENCE_TYPE_ID_STYLE:
487 return m_type_id_map[c] = id;
489 case HASH_TYPE_ID_STYLE:
493 while (!m_used_type_id_hashes.insert(hash).second)
495 std::ostringstream os;
496 os << std::hex << std::setfill(
'0') << std::setw(8) << hash;
507 fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
508 if (it == m_fn_tmpl_id_map.end())
510 string id = get_id_manager().get_id_with_prefix(
"fn-tmpl-id-");
511 m_fn_tmpl_id_map[f] = id;
514 return m_fn_tmpl_id_map[f];
520 class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
521 if (it == m_class_tmpl_id_map.end())
523 string id = get_id_manager().get_id_with_prefix(
"class-tmpl-id-");
524 m_class_tmpl_id_map[c] = id;
527 return m_class_tmpl_id_map[c];
533 m_type_id_map.clear();
544 const type_ptr_set_type&
545 get_referenced_types()
const
546 {
return m_referenced_types_set;}
553 get_referenced_function_types()
const
554 {
return m_referenced_fn_types_set;}
560 has_non_emitted_referenced_types()
const
562 for (
const auto t : get_referenced_types())
563 if (!type_is_emitted(t))
575 record_type_as_referenced(
const type_base_sptr& type)
581 m_referenced_fn_types_set.insert(f);
583 m_referenced_types_set.insert(t);
594 type_is_referenced(
const type_base_sptr& type)
598 return (m_referenced_fn_types_set.find(f)
599 != m_referenced_fn_types_set.end());
601 return m_referenced_types_set.find(t) != m_referenced_types_set.end();
660 type_ptr_map::const_iterator i =
664 i = map->find(
const_cast<type_base*
>(r));
687 operator()(
const type_base_sptr& l,
const type_base_sptr& r)
const
688 {
return operator()(l.get(), r.get());}
702 vector<type_base*>& sorted)
705 for (type_ptr_set_type::const_iterator i = types.begin();
708 sorted.push_back(
const_cast<type_base*
>(*i));
709 type_ptr_cmp comp(&m_type_id_map);
710 sort(sorted.begin(), sorted.end(), comp);
724 vector<type_base_sptr> &sorted)
726 for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
729 sorted.push_back(type_base_sptr(i->second));
730 type_ptr_cmp comp(&m_type_id_map);
731 sort(sorted.begin(), sorted.end(), comp);
745 sort_types(
const vector<function_type_sptr>& types,
746 vector<type_base_sptr> &sorted)
748 for (vector<function_type_sptr>::const_iterator i = types.begin();
751 sorted.push_back(*i);
752 type_ptr_cmp comp(&m_type_id_map);
753 sort(sorted.begin(), sorted.end(), comp);
760 record_type_as_emitted(
const type_base_sptr &t)
761 {record_type_as_emitted(t.get());}
767 record_type_as_emitted(
const type_base* t)
770 m_emitted_type_set.insert(c);
780 type_is_emitted(
const type_base* t)
const
783 return (m_emitted_type_set.find(c) != m_emitted_type_set.end());
793 type_is_emitted(
const type_base_sptr& t)
const
794 {
return type_is_emitted(t.get());}
803 decl_is_emitted(
const decl_base_sptr& decl)
const
808 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
815 record_decl_as_emitted(
const decl_base_sptr& decl)
819 m_emitted_decls_set.insert(irepr);
831 corpus_is_emitted(
const corpus_sptr& corp)
836 if (m_emitted_corpora_set.find(corp->get_path())
837 == m_emitted_corpora_set.end())
847 record_corpus_as_emitted(
const corpus_sptr& corp)
852 const string& path = corp->get_path();
855 m_emitted_corpora_set.insert(path);
861 const type_ptr_set_type&
862 get_emitted_types_set()
const
863 {
return m_emitted_type_set;}
868 clear_referenced_types()
870 m_referenced_types_set.clear();
871 m_referenced_fn_types_set.clear();
875 get_fun_symbol_map()
const
876 {
return m_fun_symbol_map;}
880 {
return m_fun_symbol_map;}
884static void write_location(
const location&, write_context&);
885static void write_location(
const decl_base_sptr&, write_context&);
886static bool write_visibility(
const decl_base_sptr&, ostream&);
887static bool write_binding(
const decl_base_sptr&, ostream&);
888static bool write_is_artificial(
const decl_base_sptr&, ostream&);
889static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
890static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
893static void write_size_and_alignment(
const type_base_sptr, ostream&,
894 size_t default_size = 0,
895 size_t default_alignment = 0);
899static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
903static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
904static bool write_elf_symbol_reference(
const elf_symbol&, ostream&);
905static bool write_elf_symbol_reference(
const elf_symbol_sptr, ostream&);
906static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
908static void write_is_anonymous(
const decl_base_sptr&, ostream&);
909static void write_naming_typedef(
const decl_base_sptr&, write_context&);
910static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
911static void write_decl_in_scope(
const decl_base_sptr&,
912 write_context&,
unsigned);
913static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
915 write_context&,
unsigned);
916static bool write_qualified_type_def(
const qualified_type_def_sptr&,
917 write_context&,
unsigned);
919 write_context&,
unsigned);
921 write_context&,
unsigned);
923 write_context&,
unsigned);
925 write_context&,
unsigned);
930 write_context&,
unsigned);
932 write_context&,
unsigned);
934 write_context&,
unsigned);
935static bool write_elf_symbols_table(
const elf_symbols&,
936 write_context&,
unsigned);
938 write_context&,
bool,
unsigned);
940 write_context&,
bool,
unsigned);
942 write_context&,
unsigned);
943static bool write_member_type_opening_tag(
const type_base_sptr&,
944 write_context&,
unsigned);
945static bool write_member_type(
const type_base_sptr&,
946 write_context&,
unsigned);
947static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
948 write_context&,
unsigned,
bool);
950 write_context&,
unsigned);
951static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
952 write_context&,
unsigned,
bool);
953static bool write_union_decl(
const union_decl_sptr&,
const string&,
954 write_context&,
unsigned);
955static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
956static bool write_type_tparameter
957(
const shared_ptr<type_tparameter>, write_context&,
unsigned);
958static bool write_non_type_tparameter
959(
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
960static bool write_template_tparameter
961(
const shared_ptr<template_tparameter>, write_context&,
unsigned);
962static bool write_type_composition
963(
const shared_ptr<type_composition>, write_context&,
unsigned);
964static bool write_template_parameter(
const shared_ptr<template_parameter>,
965 write_context&,
unsigned);
966static void write_template_parameters(
const shared_ptr<template_decl>,
967 write_context&,
unsigned);
968static bool write_function_tdecl
969(
const shared_ptr<function_tdecl>,
970 write_context&,
unsigned);
971static bool write_class_tdecl
972(
const shared_ptr<class_tdecl>,
973 write_context&,
unsigned);
974static void do_indent(ostream&,
unsigned);
975static void do_indent_to_level(write_context&,
unsigned,
unsigned);
976static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
980do_indent(ostream& o,
unsigned nb_whitespaces)
982 for (
unsigned i = 0; i < nb_whitespaces; ++i)
994do_indent_to_level(write_context& ctxt,
995 unsigned initial_indent,
998 do_indent(ctxt.get_ostream(),
999 get_indent_to_level(ctxt, initial_indent, level));
1011get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
1014 int nb_ws = initial_indent +
1015 level * ctxt.get_config().get_xml_element_indent();
1035template <
typename T>
1037annotate(
const T& decl,
1038 write_context& ctxt,
1044 if (!ctxt.get_annotate())
1047 ostream& o = ctxt.get_ostream();
1049 do_indent(o, indent);
1071 write_context& ctxt,
1077 if (!ctxt.get_annotate())
1080 ostream& o = ctxt.get_ostream();
1082 do_indent(o, indent);
1102 write_context& ctxt,
1108 if (!ctxt.get_annotate())
1111 ostream& o = ctxt.get_ostream();
1113 do_indent(o, indent);
1115 o <<
"<!-- typedef "
1138 write_context& ctxt,
1144 if (!ctxt.get_annotate())
1147 ostream& o = ctxt.get_ostream();
1149 do_indent(o, indent);
1154 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
1183 write_context& ctxt,
1189 if (!ctxt.get_annotate())
1192 ostream& o = ctxt.get_ostream();
1194 do_indent(o, indent);
1206 vector<function_decl::parameter_sptr>::const_iterator pi =
1207 fn->get_first_non_implicit_parm();
1209 for (; pi != fn->get_parameters().end(); ++pi)
1213 if (distance(pi, fn->get_parameters().end()) > 1)
1233 write_context& ctxt,
1239 if (!ctxt.get_annotate())
1242 ostream &o = ctxt.get_ostream();
1244 do_indent(o, indent);
1248 if (parm->get_variadic_marker())
1249 o <<
"variadic parameter";
1252 if (parm->get_is_artificial())
1254 if (parm->get_index() == 0)
1259 o <<
"parameter of type '"
1278write_location(
const location& loc, write_context& ctxt)
1283 if (!ctxt.get_show_locs())
1287 unsigned line = 0, column = 0;
1289 loc.
expand(filepath, line, column);
1291 ostream &o = ctxt.get_ostream();
1293 if (ctxt.get_short_locs())
1297 <<
" line='" << line <<
"'"
1298 <<
" column='" << column <<
"'";
1309write_location(
const decl_base_sptr& decl,
1310 write_context& ctxt)
1315 location loc = decl->get_location();
1319 write_location(loc, ctxt);
1331write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1341 case decl_base::VISIBILITY_NONE:
1343 case decl_base::VISIBILITY_DEFAULT:
1346 case decl_base::VISIBILITY_PROTECTED:
1349 case decl_base::VISIBILITY_HIDDEN:
1352 case decl_base::VISIBILITY_INTERNAL:
1360 o <<
" visibility='" << str <<
"'";
1371write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1378 shared_ptr<var_decl> var =
1379 dynamic_pointer_cast<var_decl>(decl);
1381 bind = var->get_binding();
1384 shared_ptr<function_decl> fun =
1385 dynamic_pointer_cast<function_decl>(decl);
1387 bind = fun->get_binding();
1393 case decl_base::BINDING_NONE:
1395 case decl_base::BINDING_LOCAL:
1398 case decl_base::BINDING_GLOBAL:
1401 case decl_base::BINDING_WEAK:
1407 o <<
" binding='" << str <<
"'";
1421write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1426 if (decl->get_is_artificial())
1427 o <<
" is-artificial='yes'";
1441write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1446 corpus* c = t->get_corpus();
1450 if (!c->recording_types_reachable_from_public_interface_supported()
1451 || c->type_is_reachable_from_public_interfaces(*t))
1454 o <<
" is-non-reachable='yes'";
1467write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1470 corpus_group* group = corpus->get_group();
1472 if (corpus->recording_types_reachable_from_public_interface_supported())
1474 o <<
" tracking-non-reachable-types='yes'";
1495write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1496 size_t default_size,
size_t default_alignment)
1498 size_t size_in_bits = decl->get_size_in_bits();
1499 if (size_in_bits != default_size)
1500 o <<
" size-in-bits='" << size_in_bits <<
"'";
1502 size_t alignment_in_bits = decl->get_alignment_in_bits();
1503 if (alignment_in_bits != default_alignment)
1504 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1512write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1514 if (decl->is_non_finite())
1515 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1517 size_t size_in_bits = decl->get_size_in_bits();
1519 o <<
" size-in-bits='" << size_in_bits <<
"'";
1522 size_t alignment_in_bits = decl->get_alignment_in_bits();
1523 if (alignment_in_bits)
1524 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1534 string access_str =
"private";
1538 case private_access:
1539 access_str =
"private";
1542 case protected_access:
1543 access_str =
"protected";
1547 access_str =
"public";
1554 o <<
" access='" << access_str <<
"'";
1565 o <<
" layout-offset-in-bits='"
1572write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1577 if (base->get_offset_in_bits() >= 0)
1578 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1587write_access(decl_base_sptr member, ostream& o)
1604 o <<
" vtable-offset='" << voffset <<
"'";
1621 case elf_symbol::NOTYPE_TYPE:
1624 case elf_symbol::OBJECT_TYPE:
1625 repr =
"object-type";
1627 case elf_symbol::FUNC_TYPE:
1630 case elf_symbol::SECTION_TYPE:
1631 repr =
"section-type";
1633 case elf_symbol::FILE_TYPE:
1636 case elf_symbol::COMMON_TYPE:
1637 repr =
"common-type";
1639 case elf_symbol::TLS_TYPE:
1642 case elf_symbol::GNU_IFUNC_TYPE:
1643 repr =
"gnu-ifunc-type";
1650 o <<
" type='" << repr <<
"'";
1666 case elf_symbol::LOCAL_BINDING:
1667 repr =
"local-binding";
1669 case elf_symbol::GLOBAL_BINDING:
1670 repr =
"global-binding";
1672 case elf_symbol::WEAK_BINDING:
1673 repr =
"weak-binding";
1675 case elf_symbol::GNU_UNIQUE_BINDING:
1676 repr =
"gnu-unique-binding";
1679 repr =
"no-binding";
1683 o <<
" binding='" << repr <<
"'";
1699 case elf_symbol::DEFAULT_VISIBILITY:
1700 repr =
"default-visibility";
1702 case elf_symbol::PROTECTED_VISIBILITY:
1703 repr =
"protected-visibility";
1705 case elf_symbol::HIDDEN_VISIBILITY:
1706 repr =
"hidden-visibility";
1708 case elf_symbol::INTERNAL_VISIBILITY:
1709 repr =
"internal-visibility";
1712 repr =
"default-visibility";
1716 o <<
" visibility='" << repr <<
"'";
1727write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1729 if (!sym.is_main_symbol() || !sym.has_aliases())
1733 std::vector<std::string> aliases;
1734 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1735 s = s->get_next_alias())
1737 if (!s->is_public())
1740 if (s->is_suppressed())
1743 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1746 aliases.push_back(s->get_id_string());
1749 if (!aliases.empty())
1752 std::string separator;
1753 for (
const auto& alias : aliases)
1755 out << separator << alias;
1775write_elf_symbol_reference(
const elf_symbol& sym, ostream& o)
1777 const elf_symbol* main = sym.get_main_symbol().get();
1778 const elf_symbol* alias = &sym;
1779 bool found = !alias->is_suppressed();
1784 found = !alias->is_suppressed();
1789 alias = alias->get_next_alias().get();
1791 if (!alias || alias == main)
1793 found = !alias->is_suppressed();
1798 o <<
" elf-symbol-id='"
1818 return write_elf_symbol_reference(*sym, o);
1835write_cdtor_const_static(
bool is_ctor,
1842 o <<
" static='yes'";
1844 o <<
" constructor='yes'";
1846 o <<
" destructor='yes'";
1848 o <<
" const='yes'";
1858write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
1860 if (d->get_is_declaration_only())
1861 o <<
" is-declaration-only='yes'";
1873 if (klass->is_struct())
1874 o <<
" is-struct='yes'";
1884write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1886 if (decl->get_is_anonymous())
1887 o <<
" is-anonymous='yes'";
1897write_naming_typedef(
const decl_base_sptr& decl, write_context& ctxt)
1902 ostream &o = ctxt.get_ostream();
1906 string id = ctxt.get_id_for_type(typedef_type);
1907 o <<
" naming-typedef-id='" <<
id <<
"'";
1908 ctxt.record_type_as_referenced(typedef_type);
1922write_type(
const type_base_sptr& type, write_context& ctxt,
unsigned indent)
1924 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
1926 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1929 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
1931 || write_reference_type_def(dynamic_pointer_cast
1932 <reference_type_def>(type), ctxt, indent)
1933 || write_ptr_to_mbr_type(dynamic_pointer_cast
1934 <ptr_to_mbr_type>(type),
1936 || write_array_type_def(dynamic_pointer_cast
1937 <array_type_def>(type), ctxt, indent)
1938 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
1940 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
1944 || (write_function_tdecl
1945 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
1946 || (write_class_tdecl
1947 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
1965write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
1967 if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
1969 || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
1971 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1974 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
1976 || write_reference_type_def(dynamic_pointer_cast
1977 <reference_type_def>(decl), ctxt, indent)
1978 || write_ptr_to_mbr_type(dynamic_pointer_cast
1979 <ptr_to_mbr_type>(decl),
1981 || write_array_type_def(dynamic_pointer_cast
1982 <array_type_def>(decl), ctxt, indent)
1983 || write_array_subrange_type(dynamic_pointer_cast
1984 <array_type_def::subrange_type>(decl),
1986 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
1988 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
1990 || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
1992 || write_function_decl(dynamic_pointer_cast<method_decl>
1995 || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
1996 ctxt,
false, indent)
1999 || (write_function_tdecl
2000 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
2001 || (write_class_tdecl
2002 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
2020write_decl_in_scope(
const decl_base_sptr& decl,
2021 write_context& ctxt,
2022 unsigned initial_indent)
2024 type_base_sptr type =
is_type(decl);
2027 if (ctxt.type_is_emitted(type))
2030 list<scope_decl*> scopes;
2031 for (scope_decl* s = decl->get_scope();
2034 scopes.push_front(s);
2036 ostream& o = ctxt.get_ostream();
2037 const config& c = ctxt.get_config();
2038 stack<string> closing_tags;
2039 stack<unsigned> closing_indents;
2040 unsigned indent = initial_indent;
2041 for (list<scope_decl*>::const_iterator i = scopes.begin();
2050 do_indent(o, indent);
2051 o <<
"<namespace-decl name='"
2054 closing_tags.push(
"</namespace-decl>");
2055 closing_indents.push(indent);
2062 if (!ctxt.type_is_emitted(c))
2064 write_type(class_type, ctxt, initial_indent);
2069 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2071 closing_tags.push(
"</class-decl>");
2072 closing_indents.push(indent);
2074 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2075 write_member_type_opening_tag(type, ctxt, nb_ws);
2077 closing_tags.push(
"</member-type>");
2078 closing_indents.push(nb_ws);
2084 union_decl_sptr union_type(u, noop_deleter());
2085 if (!ctxt.type_is_emitted(u))
2087 write_type(union_type, ctxt, initial_indent);
2092 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2094 closing_tags.push(
"</union-decl>");
2095 closing_indents.push(indent);
2097 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2098 write_member_type_opening_tag(type, ctxt, nb_ws);
2100 closing_tags.push(
"</member-type>");
2101 closing_indents.push(nb_ws);
2107 indent += c.get_xml_element_indent();
2110 bool do_write =
false;
2111 if (type_base_sptr type =
is_type(decl))
2113 if (!ctxt.type_is_emitted(type))
2118 if (!ctxt.decl_is_emitted(decl))
2123 write_decl(decl, ctxt, indent);
2125 while (!closing_tags.empty())
2127 do_indent(o, closing_indents.top());
2128 o << closing_tags.top() <<
"\n";
2130 closing_indents.pop();
2144 ostream& default_output_stream)
2161{ctxt.set_show_locs(flag);}
2173{ctxt.set_annotate(flag);}
2184{ctxt.set_ostream(os);}
2196{ctxt.set_write_architecture(flag);}
2208{ctxt.set_write_corpus_path(flag);}
2220{ctxt.set_write_comp_dir(flag);}
2232{ctxt.set_short_locs(flag);}
2244{ctxt.set_write_parameter_names(flag);}
2256{ctxt.set_write_elf_needed(flag);}
2271{ctxt.set_write_default_sizes(flag);}
2282{ctxt.set_type_id_style(
style);}
2297write_canonical_types_of_scope(
const scope_decl &scope,
2298 write_context &ctxt,
2299 const unsigned indent,
2305 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2306 i != canonical_types.end();
2309 if (ctxt.type_is_emitted(*i))
2312 write_member_type(*i, ctxt, indent);
2314 write_type(*i, ctxt, indent);
2336referenced_type_should_be_emitted(
const type_base *t,
2337 const write_context& ctxt,
2338 const translation_unit& tu,
2341 if ((tu_is_last || (t->get_translation_unit()
2342 && (t->get_translation_unit()->get_absolute_path()
2343 == tu.get_absolute_path())))
2344 && !ctxt.type_is_emitted(t))
2361write_referenced_types(write_context & ctxt,
2362 const translation_unit& tu,
2363 const unsigned indent,
2366 const config& c = ctxt.get_config();
2374 type_ptr_set_type referenced_types_to_emit;
2379 for (type_ptr_set_type::const_iterator i =
2380 ctxt.get_referenced_types().begin();
2381 i != ctxt.get_referenced_types().end();
2383 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2384 referenced_types_to_emit.insert(*i);
2386 for (fn_type_ptr_set_type::const_iterator i =
2387 ctxt.get_referenced_function_types().begin();
2388 i != ctxt.get_referenced_function_types().end();
2390 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2391 referenced_types_to_emit.insert(*i);
2394 while (!referenced_types_to_emit.empty())
2399 vector<type_base*> sorted_referenced_types;
2400 ctxt.sort_types(referenced_types_to_emit,
2401 sorted_referenced_types);
2404 for (vector<type_base*>::const_iterator i =
2405 sorted_referenced_types.begin();
2406 i != sorted_referenced_types.end();
2412 if (!ctxt.type_is_emitted(t))
2416 decl_base_sptr decl(d, noop_deleter());
2417 write_decl_in_scope(decl, ctxt,
2418 indent + c.get_xml_element_indent());
2423 write_function_type(fn_type, ctxt,
2424 indent + c.get_xml_element_indent());
2433 referenced_types_to_emit.clear();
2445 for (type_ptr_set_type::const_iterator i =
2446 ctxt.get_referenced_types().begin();
2447 i != ctxt.get_referenced_types().end();
2449 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2450 referenced_types_to_emit.insert(*i);
2478 const unsigned indent,
2486 && ctxt.has_non_emitted_referenced_types())
2489 ostream& o = ctxt.get_ostream();
2490 const config& c = ctxt.get_config();
2492 do_indent(o, indent);
2499 std::string tu_path = tu.
get_path();
2500 if (ctxt.get_short_locs())
2502 if (!tu_path.empty())
2506 o <<
" comp-dir-path='"
2509 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
2523 ctxt, indent + c.get_xml_element_indent());
2526 const declarations& decls = tu.
get_global_scope()->get_sorted_member_decls();
2528 for (
const decl_base_sptr& decl : decls)
2530 if (type_base_sptr t =
is_type(decl))
2537 if (class_type->get_is_declaration_only()
2538 && !ctxt.type_is_emitted(class_type))
2539 write_type(class_type, ctxt,
2540 indent + c.get_xml_element_indent());
2543 write_type(t, ctxt, indent + c.get_xml_element_indent());
2547 if (!ctxt.decl_is_emitted(decl))
2548 write_decl(decl, ctxt, indent + c.get_xml_element_indent());
2552 write_referenced_types(ctxt, tu, indent, is_last);
2557 vector<type_base_sptr> sorted_types;
2558 ctxt.sort_types(t, sorted_types);
2560 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
2561 i != sorted_types.end();
2566 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
2573 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
2578 write_referenced_types(ctxt, tu, indent, is_last);
2580 do_indent(o, indent);
2581 o <<
"</abi-instr>\n";
2599write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
2604 ostream& o = ctxt.get_ostream();
2606 annotate(d, ctxt, indent);
2608 do_indent(o, indent);
2612 write_is_anonymous(d, o);
2614 write_size_and_alignment(d, o);
2616 write_is_declaration_only(d, o);
2618 write_location(d, ctxt);
2620 o <<
" id='" << ctxt.get_id_for_type(d) <<
"'" <<
"/>\n";
2622 ctxt.record_type_as_emitted(d);
2640 write_context& ctxt,
unsigned indent)
2642 if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
2645 ostream& o = ctxt.get_ostream();
2646 const config &c = ctxt.get_config();
2648 annotate(decl, ctxt, indent);
2650 do_indent(o, indent);
2652 o <<
"<namespace-decl name='"
2657 typedef declarations::const_iterator const_iterator;
2658 const declarations& d = decl->get_sorted_member_decls();
2660 write_canonical_types_of_scope(*decl, ctxt,
2661 indent + c.get_xml_element_indent());
2663 for (const_iterator i = d.begin(); i != d.end(); ++i)
2665 if (type_base_sptr t =
is_type(*i))
2666 if (ctxt.type_is_emitted(t))
2670 write_decl(*i, ctxt, indent + c.get_xml_element_indent());
2673 do_indent(o, indent);
2674 o <<
"</namespace-decl>\n";
2698write_qualified_type_def(
const qualified_type_def_sptr& decl,
2700 write_context& ctxt,
2706 ostream& o = ctxt.get_ostream();
2709 type_base_sptr underlying_type = decl->get_underlying_type();
2711 annotate(decl, ctxt, indent);
2713 do_indent(o, indent);
2714 o <<
"<qualified-type-def type-id='"
2715 << ctxt.get_id_for_type(underlying_type)
2718 ctxt.record_type_as_referenced(underlying_type);
2720 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
2721 o <<
" const='yes'";
2722 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
2723 o <<
" volatile='yes'";
2724 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
2725 o <<
" restrict='yes'";
2727 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2731 i = ctxt.get_id_for_type(decl);
2733 o <<
" id='" << i <<
"'/>\n";
2735 ctxt.record_type_as_emitted(decl);
2751write_qualified_type_def(
const qualified_type_def_sptr& decl,
2752 write_context& ctxt,
2754{
return write_qualified_type_def(decl,
"", ctxt, indent);}
2776 write_context& ctxt,
2782 ostream& o = ctxt.get_ostream();
2784 annotate(decl, ctxt, indent);
2786 do_indent(o, indent);
2790 o <<
"<pointer-type-def ";
2792 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2794 i = ctxt.get_id_for_type(pointed_to_type);
2796 o <<
"type-id='" << i <<
"'";
2798 ctxt.record_type_as_referenced(pointed_to_type);
2800 write_size_and_alignment(decl, o,
2801 (ctxt.get_write_default_sizes()
2803 : decl->get_translation_unit()->get_address_size()),
2808 i = ctxt.get_id_for_type(decl);
2810 o <<
" id='" << i <<
"'";
2812 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2815 ctxt.record_type_as_emitted(decl);
2831 write_context& ctxt,
2833{
return write_pointer_type_def(decl,
"", ctxt, indent);}
2855 write_context& ctxt,
2861 annotate(decl->get_canonical_type(), ctxt, indent);
2863 ostream& o = ctxt.get_ostream();
2865 do_indent(o, indent);
2867 o <<
"<reference-type-def kind='";
2868 if (decl->is_lvalue())
2874 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2875 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
2877 ctxt.record_type_as_referenced(pointed_to_type);
2880 ctxt.record_type_as_referenced(f);
2882 write_size_and_alignment(decl, o,
2883 (ctxt.get_write_default_sizes()
2885 : decl->get_translation_unit()->get_address_size()),
2890 i = ctxt.get_id_for_type(decl);
2891 o <<
" id='" << i <<
"'";
2893 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2897 ctxt.record_type_as_emitted(decl);
2913 write_context& ctxt,
2915{
return write_reference_type_def(decl,
"", ctxt, indent);}
2931 const string&
id, write_context& ctxt,
2937 annotate(decl->get_canonical_type(), ctxt, indent);
2939 ostream& o = ctxt.get_ostream();
2941 do_indent(o, indent);
2943 o <<
"<pointer-to-member-type";
2945 write_size_and_alignment(decl, o,
2946 (ctxt.get_write_default_sizes()
2948 : decl->get_translation_unit()->get_address_size()),
2951 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2953 type_base_sptr member_type = decl->get_member_type();
2954 string i = ctxt.get_id_for_type(member_type);
2955 o <<
" member-type-id='" << i <<
"'";
2956 ctxt.record_type_as_referenced(member_type);
2958 type_base_sptr containing_type = decl->get_containing_type();
2959 i = ctxt.get_id_for_type(containing_type);
2960 o <<
" containing-type-id='" << i <<
"'";
2961 ctxt.record_type_as_referenced(containing_type);
2965 i = ctxt.get_id_for_type(decl);
2966 o <<
" id ='" << i <<
"'";
2970 ctxt.record_type_as_emitted(decl);
2986 write_context& ctxt,
unsigned indent)
2987{
return write_ptr_to_mbr_type(decl,
"", ctxt, indent);}
3000 write_context& ctxt,
3006 annotate(decl, ctxt, indent);
3008 ostream& o = ctxt.get_ostream();
3010 do_indent(o, indent);
3014 if (!decl->get_name().empty())
3015 o <<
" name='" << decl->get_name() <<
"'";
3018 if (decl->is_non_finite())
3021 o << decl->get_length();
3026 || decl->get_length() == 0
3027 || (decl->get_length() ==
3028 (uint64_t) (decl->get_upper_bound()
3029 - decl->get_lower_bound() + 1)));
3030 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
3031 << decl->get_upper_bound() <<
"'";
3033 type_base_sptr underlying_type = decl->get_underlying_type();
3034 if (underlying_type)
3037 << ctxt.get_id_for_type(underlying_type)
3039 ctxt.record_type_as_referenced(underlying_type);
3042 o <<
" id='" << ctxt.get_id_for_type(decl) <<
"'";
3044 write_location(decl->get_location(), ctxt);
3048 ctxt.record_type_as_emitted(decl);
3073 write_context& ctxt,
3079 annotate(decl, ctxt, indent);
3081 ostream& o = ctxt.get_ostream();
3083 do_indent(o, indent);
3084 o <<
"<array-type-def";
3086 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
3088 type_base_sptr element_type = decl->get_element_type();
3089 o <<
" type-id='" << ctxt.get_id_for_type(element_type) <<
"'";
3091 ctxt.record_type_as_referenced(element_type);
3093 write_array_size_and_alignment(decl, o);
3097 i = ctxt.get_id_for_type(decl);
3098 o <<
" id='" << i <<
"'";
3100 write_location(static_pointer_cast<decl_base>(decl), ctxt);
3102 if (!decl->get_dimension_count())
3108 vector<array_type_def::subrange_sptr>::const_iterator si;
3110 for (si = decl->get_subranges().begin();
3111 si != decl->get_subranges().end(); ++si)
3113 unsigned local_indent =
3114 indent + ctxt.get_config().get_xml_element_indent();
3115 write_array_subrange_type(*si, ctxt, local_indent);
3118 do_indent(o, indent);
3119 o <<
"</array-type-def>\n";
3122 ctxt.record_type_as_emitted(decl);
3138 write_context& ctxt,
3140{
return write_array_type_def(decl,
"", ctxt, indent);}
3162 write_context& ctxt,
3170 annotate(decl->get_canonical_type(), ctxt, indent);
3172 ostream& o = ctxt.get_ostream();
3174 do_indent(o, indent);
3177 write_is_anonymous(decl, o);
3178 write_naming_typedef(decl, ctxt);
3179 write_is_artificial(decl, o);
3180 write_is_non_reachable(
is_type(decl), o);
3182 if (!decl->get_linkage_name().empty())
3183 o <<
" linkage-name='"
3187 write_location(decl, ctxt);
3188 write_is_declaration_only(decl, o);
3192 i = ctxt.get_id_for_type(decl);
3193 o <<
" id='" << i <<
"'>\n";
3195 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3196 o <<
"<underlying-type type-id='"
3197 << ctxt.get_id_for_type(decl->get_underlying_type())
3200 for (enum_type_decl::enumerators::const_iterator i =
3201 decl->get_enumerators().begin();
3202 i != decl->get_enumerators().end();
3205 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3206 o <<
"<enumerator name='"
3213 do_indent(o, indent);
3214 o <<
"</enum-decl>\n";
3216 ctxt.record_type_as_emitted(decl);
3232 write_context& ctxt,
3234{
return write_enum_type_decl(decl,
"", ctxt, indent);}
3248 write_context& ctxt,
3254 ostream &o = ctxt.get_ostream();
3256 annotate(sym, ctxt, indent);
3257 do_indent(o, indent);
3259 if (sym->is_variable() && sym->get_size())
3260 o <<
" size='" << sym->get_size() <<
"'";
3262 if (!sym->get_version().is_empty())
3264 o <<
" version='" << sym->get_version().str() <<
"'";
3265 o <<
" is-default-version='";
3266 if (sym->get_version().is_default())
3273 write_elf_symbol_type(sym->get_type(), o);
3275 write_elf_symbol_binding(sym->get_binding(), o);
3277 write_elf_symbol_visibility(sym->get_visibility(), o);
3279 write_elf_symbol_aliases(*sym, o);
3281 o <<
" is-defined='";
3282 if (sym->is_defined())
3288 if (sym->is_common_symbol())
3289 o <<
" is-common='yes'";
3291 if (sym->get_crc().has_value())
3293 << std::hex << std::showbase << sym->get_crc().value()
3294 << std::dec << std::noshowbase <<
"'";
3296 if (sym->get_namespace().has_value())
3297 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3316 write_context& ctxt,
3322 for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
3323 write_elf_symbol(*it, ctxt, indent);
3339write_elf_needed(
const vector<string>& needed,
3340 write_context& ctxt,
3346 ostream& o = ctxt.get_ostream();
3348 for (vector<string>::const_iterator i = needed.begin();
3352 do_indent(o, indent);
3353 o <<
"<dependency name='" << *i <<
"'/>\n";
3378 write_context& ctxt,
3384 ostream &o = ctxt.get_ostream();
3386 annotate(decl, ctxt, indent);
3388 do_indent(o, indent);
3390 o <<
"<typedef-decl name='"
3394 type_base_sptr underlying_type = decl->get_underlying_type();
3395 string type_id = ctxt.get_id_for_type(underlying_type);
3396 o <<
" type-id='" << type_id <<
"'";
3397 ctxt.record_type_as_referenced(underlying_type);
3399 write_location(decl, ctxt);
3403 i = ctxt.get_id_for_type(decl);
3405 o <<
" id='" << i <<
"'/>\n";
3407 ctxt.record_type_as_emitted(decl);
3423 write_context& ctxt,
3425{
return write_typedef_decl(decl,
"", ctxt, indent);}
3440write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
3441 bool write_linkage_name,
unsigned indent)
3446 annotate(decl, ctxt, indent);
3448 ostream &o = ctxt.get_ostream();
3450 do_indent(o, indent);
3453 type_base_sptr var_type = decl->get_type();
3454 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
3455 ctxt.record_type_as_referenced(var_type);
3457 if (write_linkage_name)
3459 const string& linkage_name = decl->get_linkage_name();
3460 if (!linkage_name.empty())
3461 o <<
" mangled-name='" << linkage_name <<
"'";
3464 write_visibility(decl, o);
3466 write_binding(decl, o);
3468 write_location(decl, ctxt);
3470 write_elf_symbol_reference(decl->get_symbol(), o);
3474 ctxt.record_decl_as_emitted(decl);
3493 bool skip_first_parm,
unsigned indent)
3498 annotate(decl, ctxt, indent);
3500 ostream &o = ctxt.get_ostream();
3502 do_indent(o, indent);
3504 o <<
"<function-decl name='"
3508 if (!decl->get_linkage_name().empty())
3509 o <<
" mangled-name='"
3512 write_location(decl, ctxt);
3514 if (decl->is_declared_inline())
3515 o <<
" declared-inline='yes'";
3517 write_visibility(decl, o);
3519 write_binding(decl, o);
3521 write_size_and_alignment(decl->get_type(), o,
3522 (ctxt.get_write_default_sizes()
3524 : decl->get_translation_unit()->get_address_size()),
3526 write_elf_symbol_reference(decl->get_symbol(), o);
3530 type_base_sptr parm_type;
3531 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
3532 decl->get_parameters().begin();
3533 for ((skip_first_parm && pi != decl->get_parameters().end()) ? ++pi: pi;
3534 pi != decl->get_parameters().end();
3537 if ((*pi)->get_variadic_marker())
3539 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3540 o <<
"<parameter is-variadic='yes'";
3544 parm_type = (*pi)->get_type();
3547 indent + ctxt.get_config().get_xml_element_indent());
3549 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3551 o <<
"<parameter type-id='"
3552 << ctxt.get_id_for_type(parm_type)
3554 ctxt.record_type_as_referenced(parm_type);
3556 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3559 write_is_artificial(*pi, o);
3560 write_location((*pi)->get_location(), ctxt);
3564 if (shared_ptr<type_base> return_type = decl->get_return_type())
3566 annotate(return_type , ctxt,
3567 indent + ctxt.get_config().get_xml_element_indent());
3568 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3569 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3570 ctxt.record_type_as_referenced(return_type);
3573 do_indent(o, indent);
3574 o <<
"</function-decl>\n";
3576 ctxt.record_decl_as_emitted(decl);
3592 write_context& ctxt,
unsigned indent)
3597 ostream &o = ctxt.get_ostream();
3599 annotate(fn_type, ctxt, indent);
3601 do_indent(o, indent);
3603 o <<
"<function-type";
3605 write_size_and_alignment(fn_type, o,
3606 (ctxt.get_write_default_sizes()
3608 : fn_type->get_translation_unit()->get_address_size()),
3613 o <<
" method-class-id='"
3614 << ctxt.get_id_for_type(method_type->get_class_type())
3617 write_cdtor_const_static(
false,
false,
3618 method_type->get_is_const(),
3622 interned_string
id = ctxt.get_id_for_type(fn_type);
3628 type_base_sptr parm_type;
3629 for (vector<function_decl::parameter_sptr>::const_iterator pi =
3630 fn_type->get_parameters().begin();
3631 pi != fn_type->get_parameters().end();
3635 if ((*pi)->get_variadic_marker())
3637 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3638 o <<
"<parameter is-variadic='yes'";
3642 parm_type = (*pi)->get_type();
3644 annotate(*pi, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3646 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3647 o <<
"<parameter type-id='"
3648 << ctxt.get_id_for_type(parm_type)
3650 ctxt.record_type_as_referenced(parm_type);
3652 if (!(*pi)->get_name().empty())
3655 o <<
" name='" << name <<
"'";
3658 write_is_artificial(*pi, o);
3662 if (type_base_sptr return_type = fn_type->get_return_type())
3664 annotate(return_type, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3665 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3666 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3667 ctxt.record_type_as_referenced(return_type);
3670 do_indent(o, indent);
3671 o <<
"</function-type>\n";
3673 ctxt.record_type_as_emitted(fn_type);
3697 write_context& ctxt,
3699 bool prepare_to_handle_empty)
3704 ostream& o = ctxt.get_ostream();
3706 do_indent_to_level(ctxt, indent, 0);
3710 write_size_and_alignment(decl, o);
3712 write_is_struct(decl, o);
3714 write_is_anonymous(decl, o);
3716 write_is_artificial(decl, o);
3718 write_is_non_reachable(
is_type(decl), o);
3720 write_naming_typedef(decl, ctxt);
3722 write_visibility(decl, o);
3724 write_location(decl, ctxt);
3726 write_is_declaration_only(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()))
3738 i = ctxt.get_id_for_type(decl);
3739 o <<
" id='" << i <<
"'";
3741 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
3767write_union_decl_opening_tag(
const union_decl_sptr& decl,
3769 write_context& ctxt,
3771 bool prepare_to_handle_empty)
3776 ostream& o = ctxt.get_ostream();
3778 do_indent_to_level(ctxt, indent, 0);
3782 if (!decl->get_is_declaration_only())
3783 write_size_and_alignment(decl, o);
3785 write_is_anonymous(decl, o);
3787 write_naming_typedef(decl, ctxt);
3789 write_visibility(decl, o);
3791 write_is_artificial(decl, o);
3793 write_is_non_reachable(
is_type(decl), o);
3795 write_location(decl, ctxt);
3797 write_is_declaration_only(decl, o);
3801 i = ctxt.get_id_for_type(decl);
3802 o <<
" id='" << i <<
"'";
3804 if (prepare_to_handle_empty && decl->has_no_member())
3830 write_context& ctxt,
3838 annotate(decl, ctxt, indent);
3840 ostream& o = ctxt.get_ostream();
3842 if (decl->get_is_declaration_only())
3846 const environment& env = ctxt.get_environment();
3864 *decl->get_corpus(),
3867 for (
auto t : result)
3869 type_base_sptr type(t);
3871 for (
auto m : c->get_member_types())
3872 if (member_types.find(m) != member_types.end())
3873 member_types.insert(m);
3877 if (!member_types.empty())
3883 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3885 member_types.empty());
3887 vector<type_base_sptr> sorted_types;
3890 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3892 for (
auto t : sorted_types)
3893 if (!ctxt.type_is_emitted(t))
3894 write_member_type(t, ctxt, nb_ws);
3896 if (!member_types.empty())
3897 o << indent <<
"</class-decl>\n";
3902 for (
auto t : result)
3903 ctxt.record_type_as_emitted(type_base_sptr(t));
3908 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3911 if (!decl->has_no_base_nor_member())
3913 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3914 type_base_sptr base_type;
3915 for (class_decl::base_specs::const_iterator base =
3916 decl->get_base_specifiers().begin();
3917 base != decl->get_base_specifiers().end();
3920 annotate((*base)->get_base_class(), ctxt, nb_ws);
3921 do_indent(o, nb_ws);
3924 write_access((*base)->get_access_specifier(), o);
3926 write_layout_offset (*base, o);
3928 if ((*base)->get_is_virtual ())
3929 o <<
" is-virtual='yes'";
3931 base_type = (*base)->get_base_class();
3933 << ctxt.get_id_for_type(base_type)
3936 ctxt.record_type_as_referenced(base_type);
3939 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
3942 for (class_decl::member_types::const_iterator ti =
3943 decl->get_sorted_member_types().begin();
3944 ti != decl->get_sorted_member_types().end();
3946 if (!(*ti)->get_naked_canonical_type())
3947 write_member_type(*ti, ctxt, nb_ws);
3949 for (class_decl::data_members::const_iterator data =
3950 decl->get_data_members().begin();
3951 data != decl->get_data_members().end();
3954 do_indent(o, nb_ws);
3955 o <<
"<data-member";
3959 write_cdtor_const_static(
false,
3964 write_layout_offset(*data, o);
3967 write_var_decl(*data, ctxt, is_static,
3968 get_indent_to_level(ctxt, indent, 2));
3970 do_indent_to_level(ctxt, indent, 1);
3971 o <<
"</data-member>\n";
3974 for (class_decl::member_functions::const_iterator f =
3975 decl->get_member_functions().begin();
3976 f != decl->get_member_functions().end();
3987 do_indent(o, nb_ws);
3988 o <<
"<member-function";
3997 write_function_decl(fn, ctxt,
3999 get_indent_to_level(ctxt, indent, 2));
4001 do_indent_to_level(ctxt, indent, 1);
4002 o <<
"</member-function>\n";
4005 for (class_decl::member_functions::const_iterator f =
4006 decl->get_virtual_mem_fns().begin();
4007 f != decl->get_virtual_mem_fns().end();
4014 do_indent(o, nb_ws);
4015 o <<
"<member-function";
4022 write_voffset(fn, o);
4025 write_function_decl(fn, ctxt,
4027 get_indent_to_level(ctxt, indent, 2));
4029 do_indent_to_level(ctxt, indent, 1);
4030 o <<
"</member-function>\n";
4033 for (member_function_templates::const_iterator fn =
4034 decl->get_member_function_templates().begin();
4035 fn != decl->get_member_function_templates().end();
4038 do_indent(o, nb_ws);
4039 o <<
"<member-template";
4040 write_access((*fn)->get_access_specifier(), o);
4041 write_cdtor_const_static((*fn)->is_constructor(),
4044 (*fn)->get_is_static(), o);
4046 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4047 get_indent_to_level(ctxt, indent, 2));
4048 do_indent(o, nb_ws);
4049 o <<
"</member-template>\n";
4052 for (member_class_templates::const_iterator cl =
4053 decl->get_member_class_templates().begin();
4054 cl != decl->get_member_class_templates().end();
4057 do_indent(o, nb_ws);
4058 o <<
"<member-template";
4059 write_access((*cl)->get_access_specifier(), o);
4060 write_cdtor_const_static(
false,
false,
false,
4061 (*cl)->get_is_static(), o);
4063 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4064 get_indent_to_level(ctxt, indent, 2));
4065 do_indent(o, nb_ws);
4066 o <<
"</member-template>\n";
4069 do_indent_to_level(ctxt, indent, 0);
4071 o <<
"</class-decl>\n";
4074 ctxt.record_type_as_emitted(decl);
4090 write_context& ctxt,
4092{
return write_class_decl(decl,
"", ctxt, indent);}
4104write_union_decl(
const union_decl_sptr& d,
4106 write_context& ctxt,
4114 annotate(decl, ctxt, indent);
4116 ostream& o = ctxt.get_ostream();
4118 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4120 if (!decl->has_no_member())
4122 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4123 for (class_decl::member_types::const_iterator ti =
4124 decl->get_member_types().begin();
4125 ti != decl->get_member_types().end();
4127 if (!(*ti)->get_naked_canonical_type())
4128 write_member_type(*ti, ctxt, nb_ws);
4130 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4133 for (union_decl::data_members::const_iterator data =
4134 decl->get_data_members().begin();
4135 data != decl->get_data_members().end();
4138 do_indent(o, nb_ws);
4139 o <<
"<data-member";
4143 write_cdtor_const_static(
false,
4150 write_var_decl(*data, ctxt, is_static,
4151 get_indent_to_level(ctxt, indent, 2));
4153 do_indent_to_level(ctxt, indent, 1);
4154 o <<
"</data-member>\n";
4157 for (union_decl::member_functions::const_iterator f =
4158 decl->get_member_functions().begin();
4159 f != decl->get_member_functions().end();
4170 do_indent(o, nb_ws);
4171 o <<
"<member-function";
4180 write_function_decl(fn, ctxt,
4182 get_indent_to_level(ctxt, indent, 2));
4184 do_indent_to_level(ctxt, indent, 1);
4185 o <<
"</member-function>\n";
4188 for (member_function_templates::const_iterator fn =
4189 decl->get_member_function_templates().begin();
4190 fn != decl->get_member_function_templates().end();
4193 do_indent(o, nb_ws);
4194 o <<
"<member-template";
4195 write_access((*fn)->get_access_specifier(), o);
4196 write_cdtor_const_static((*fn)->is_constructor(),
4199 (*fn)->get_is_static(), o);
4201 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4202 get_indent_to_level(ctxt, indent, 2));
4203 do_indent(o, nb_ws);
4204 o <<
"</member-template>\n";
4207 for (member_class_templates::const_iterator cl =
4208 decl->get_member_class_templates().begin();
4209 cl != decl->get_member_class_templates().end();
4212 do_indent(o, nb_ws);
4213 o <<
"<member-template";
4214 write_access((*cl)->get_access_specifier(), o);
4215 write_cdtor_const_static(
false,
false,
false,
4216 (*cl)->get_is_static(), o);
4218 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4219 get_indent_to_level(ctxt, indent, 2));
4220 do_indent(o, nb_ws);
4221 o <<
"</member-template>\n";
4224 do_indent_to_level(ctxt, indent, 0);
4226 o <<
"</union-decl>\n";
4229 ctxt.record_type_as_emitted(decl);
4235write_union_decl(
const union_decl_sptr& decl,
4236 write_context& ctxt,
4238{
return write_union_decl(decl,
"", ctxt, indent);}
4250write_member_type_opening_tag(
const type_base_sptr& t,
4251 write_context& ctxt,
4254 ostream& o = ctxt.get_ostream();
4256 do_indent_to_level(ctxt, indent, 0);
4261 o <<
"<member-type";
4262 write_access(decl, o);
4281write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4286 ostream& o = ctxt.get_ostream();
4288 write_member_type_opening_tag(t, ctxt, indent);
4290 string id = ctxt.get_id_for_type(t);
4292 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4293 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4295 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4297 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4299 || write_ptr_to_mbr_type(dynamic_pointer_cast<ptr_to_mbr_type>(t),
4301 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4303 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4305 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4307 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4309 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
4312 do_indent_to_level(ctxt, indent, 0);
4313 o <<
"</member-type>\n";
4329 write_context& ctxt,
4335 ostream &o = ctxt.get_ostream();
4336 do_indent_to_level(ctxt, indent, 0);
4338 string id_attr_name;
4339 if (ctxt.type_has_existing_id(decl))
4340 id_attr_name =
"type-id";
4342 id_attr_name =
"id";
4344 o <<
"<template-type-parameter "
4345 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
4349 o <<
" name='" << name <<
"'";
4351 write_location(decl, ctxt);
4355 ctxt.record_type_as_emitted(decl);
4370write_non_type_tparameter(
4371 const shared_ptr<non_type_tparameter> decl,
4372 write_context& ctxt,
unsigned indent)
4377 ostream &o = ctxt.get_ostream();
4378 do_indent_to_level(ctxt, indent, 0);
4380 o <<
"<template-non-type-parameter type-id='"
4381 << ctxt.get_id_for_type(decl->get_type())
4386 o <<
" name='" << name <<
"'";
4388 write_location(decl, ctxt);
4407 write_context& ctxt,
4413 ostream& o = ctxt.get_ostream();
4414 do_indent_to_level(ctxt, indent, 0);
4416 string id_attr_name =
"id";
4417 if (ctxt.type_has_existing_id(decl))
4418 id_attr_name =
"type-id";
4420 o <<
"<template-template-parameter " << id_attr_name <<
"='"
4421 << ctxt.get_id_for_type(decl) <<
"'";
4425 o <<
" name='" << name <<
"'";
4429 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4430 for (list<shared_ptr<template_parameter> >::const_iterator p =
4431 decl->get_template_parameters().begin();
4432 p != decl->get_template_parameters().end();
4434 write_template_parameter(decl, ctxt, nb_spaces);
4436 do_indent_to_level(ctxt, indent, 0);
4437 o <<
"</template-template-parameter>\n";
4439 ctxt.record_type_as_emitted(decl);
4454write_type_composition
4455(
const shared_ptr<type_composition> decl,
4456 write_context& ctxt,
unsigned indent)
4461 ostream& o = ctxt.get_ostream();
4463 do_indent_to_level(ctxt, indent, 0);
4465 o <<
"<template-parameter-type-composition>\n";
4467 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4468 (write_pointer_type_def
4469 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
4471 || write_reference_type_def
4472 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
4474 || write_array_type_def
4475 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
4477 || write_qualified_type_def
4478 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
4481 do_indent_to_level(ctxt, indent, 0);
4482 o <<
"</template-parameter-type-composition>\n";
4497write_template_parameter(
const shared_ptr<template_parameter> decl,
4498 write_context& ctxt,
unsigned indent)
4500 if ((!write_type_tparameter
4501 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
4502 && (!write_non_type_tparameter
4503 (dynamic_pointer_cast<non_type_tparameter>(decl),
4505 && (!write_template_tparameter
4506 (dynamic_pointer_cast<template_tparameter>(decl),
4508 && (!write_type_composition
4509 (dynamic_pointer_cast<type_composition>(decl),
4520write_template_parameters(
const shared_ptr<template_decl> tmpl,
4521 write_context& ctxt,
unsigned indent)
4526 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4527 for (list<shared_ptr<template_parameter> >::const_iterator p =
4528 tmpl->get_template_parameters().begin();
4529 p != tmpl->get_template_parameters().end();
4531 write_template_parameter(*p, ctxt, nb_spaces);
4542write_function_tdecl(
const shared_ptr<function_tdecl> decl,
4543 write_context& ctxt,
unsigned indent)
4548 ostream& o = ctxt.get_ostream();
4550 do_indent_to_level(ctxt, indent, 0);
4552 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
4554 write_location(decl, ctxt);
4556 write_visibility(decl, o);
4558 write_binding(decl, o);
4562 write_template_parameters(decl, ctxt, indent);
4564 write_function_decl(decl->get_pattern(), ctxt,
4566 get_indent_to_level(ctxt, indent, 1));
4568 do_indent_to_level(ctxt, indent, 0);
4570 o <<
"</function-template-decl>\n";
4587write_class_tdecl(
const shared_ptr<class_tdecl> decl,
4588 write_context& ctxt,
unsigned indent)
4593 ostream& o = ctxt.get_ostream();
4595 do_indent_to_level(ctxt, indent, 0);
4597 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
4599 write_location(decl, ctxt);
4601 write_visibility(decl, o);
4605 write_template_parameters(decl, ctxt, indent);
4607 write_class_decl(decl->get_pattern(), ctxt,
4608 get_indent_to_level(ctxt, indent, 1));
4610 do_indent_to_level(ctxt, indent, 0);
4612 o <<
"</class-template-decl>\n";
4621write_version_info(write_context& ctxt)
4623 ostream& o = ctxt.get_ostream();
4624 const config& c = ctxt.get_config();
4627 << c.get_format_major_version_number()
4628 <<
"." << c.get_format_minor_version_number()
4648 const corpus_sptr&
corpus,
4650 bool member_of_group)
4658 do_indent_to_level(ctxt, indent, 0);
4660 std::ostream& out = ctxt.get_ostream();
4662 out <<
"<abi-corpus ";
4664 write_version_info(ctxt);
4669 if (!ctxt.get_write_corpus_path())
4671 if (member_of_group)
4674 corpus_path.clear();
4678 if (ctxt.get_short_locs())
4681 if (!corpus_path.empty())
4685 && ctxt.get_write_architecture())
4691 write_tracking_non_reachable_types(
corpus, out);
4699 do_indent_to_level(ctxt, indent, 1);
4700 out <<
"<elf-needed>\n";
4702 get_indent_to_level(ctxt, indent, 2));
4703 do_indent_to_level(ctxt, indent, 1);
4704 out <<
"</elf-needed>\n";
4710 do_indent_to_level(ctxt, indent, 1);
4711 out <<
"<elf-function-symbols>\n";
4714 get_indent_to_level(ctxt, indent, 2));
4716 do_indent_to_level(ctxt, indent, 1);
4717 out <<
"</elf-function-symbols>\n";
4723 do_indent_to_level(ctxt, indent, 1);
4724 out <<
"<elf-variable-symbols>\n";
4727 get_indent_to_level(ctxt, indent, 2));
4729 do_indent_to_level(ctxt, indent, 1);
4730 out <<
"</elf-variable-symbols>\n";
4735 for (translation_units::const_iterator i =
4742 get_indent_to_level(ctxt, indent, 1),
4746 do_indent_to_level(ctxt, indent, 0);
4747 out <<
"</abi-corpus>\n";
4749 ctxt.clear_referenced_types();
4750 ctxt.record_corpus_as_emitted(
corpus);
4767 const corpus_group_sptr& group,
4774 do_indent_to_level(ctxt, indent, 0);
4776std::ostream& out = ctxt.get_ostream();
4778 out <<
"<abi-corpus-group ";
4779 write_version_info(ctxt);
4781 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
4784 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
4785 out <<
" architecture='" << group->get_architecture_name()<<
"'";
4787 write_tracking_non_reachable_types(group, out);
4789 if (group->is_empty())
4798 for (corpus_group::corpora_type::const_iterator c =
4799 group->get_corpora().begin();
4800 c != group->get_corpora().end();
4804 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
4807 do_indent_to_level(ctxt, indent, 0);
4808 out <<
"</abi-corpus-group>\n";
4829 xml_writer::write_context ctxt(d->get_environment(), o);
4831 write_decl(d, ctxt, 0);
4873 xml_writer::write_context ctxt(v->get_environment(), o);
4875 write_var_decl(v, ctxt,
true, 0);
4944 unsigned line = 0, col = 0;
4946 l.
expand(path, line, col);
4947 o << path <<
":" << line <<
"," << col <<
"\n";
4997#ifdef WITH_DEBUG_SELF_COMPARISON
5008write_type_record(xml_writer::write_context& ctxt,
5031 id = ctxt.get_id_for_type (
const_cast<type_base*
>(type));
5034 <<
" <id>" <<
id <<
"</id>\n"
5037 <<
reinterpret_cast<uintptr_t
>(canonical)
5053write_canonical_type_ids(xml_writer::write_context& ctxt, ostream& o)
5072 o <<
"<abixml-types-check>\n";
5074 for (
const auto &type : ctxt.get_emitted_types_set())
5075 write_type_record(ctxt, type, o);
5077 o <<
"</abixml-types-check>\n";
5090write_canonical_type_ids(xml_writer::write_context& ctxt,
5091 const string &file_path)
5093 std:: ofstream o (file_path);
5097 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,...
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:
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 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.
Abstraction of an elf symbol.
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.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Abstraction of a function type.
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of 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,...
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.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
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.
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.
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
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.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
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.
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.
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.
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
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.
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.
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_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.