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());
112struct non_canonicalized_type_hash
131 return h(p->get_pretty_representation(
false,
147struct non_canonicalized_type_equal
173struct canonicalized_type_equal
200 if (ld->get_is_anonymous() && rd->get_is_anonymous())
201 if (ld->get_qualified_name(
true) != rd->get_qualified_name(
true))
221 operator()(type_base_sptr l, type_base_sptr r)
const
222 {
return operator()(l.get(), r.get());}
226struct canonicalized_type_hash
233 return reinterpret_cast<size_t>(t);
236 string repr = t->get_pretty_representation(
false,
238 size_t result = h(repr);
244typedef std::unordered_set<
const type_base*,
245 canonicalized_type_hash,
246 canonicalized_type_equal> type_ptr_set_type;
251 canonicalized_type_hash,
257typedef std::unordered_set<
const type_base*,
258 non_canonicalized_type_hash,
259 non_canonicalized_type_equal>
267 non_canonicalized_type_hash,
268 non_canonicalized_type_equal>
274struct function_tdecl_hash
277 {
return reinterpret_cast<size_t>(f.get());}
281 string, function_tdecl_hash>
282fn_tmpl_shared_ptr_map;
284struct class_tdecl_hash
287 {
return reinterpret_cast<size_t>(c.get());}
292 class_tdecl_hash> class_tmpl_shared_ptr_map;
296 const environment& m_env;
297 id_manager m_id_manager;
300 bool m_write_member_hashes;
302 bool m_write_architecture;
303 bool m_write_corpus_path;
304 bool m_write_comp_dir;
305 bool m_write_elf_needed;
306 bool m_write_undefined_symbols;
307 bool m_write_parameter_names;
309 bool m_write_default_sizes;
310 bool m_write_native_offsets;
311 bool m_write_non_reachable_types;
315 mutable unordered_set<uint32_t> m_used_type_id_hashes;
316 mutable type_ptr_set_type m_emitted_type_set;
319 type_ptr_set_type m_referenced_types_set;
321 fn_tmpl_shared_ptr_map m_fn_tmpl_id_map;
322 class_tmpl_shared_ptr_map m_class_tmpl_id_map;
327 unordered_set<string> m_emitted_corpora_set;
338 write_context(
const environment& env, ostream& os)
343 m_write_member_hashes(false),
345 m_write_architecture(true),
346 m_write_corpus_path(true),
347 m_write_comp_dir(true),
348 m_write_elf_needed(true),
349 m_write_undefined_symbols(true),
350 m_write_parameter_names(true),
352 m_write_default_sizes(true),
353 m_write_native_offsets(false),
354 m_write_non_reachable_types(false),
355 m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
362 get_environment()
const
367 {
return get_environment().get_config();}
401 get_write_member_hashes()
402 {
return m_write_member_hashes;}
409 {m_write_member_hashes = f;}
415 get_write_architecture()
416 {
return m_write_architecture;}
423 {m_write_architecture = f;}
429 get_write_elf_needed()
430 {
return m_write_elf_needed;}
437 {m_write_elf_needed = f;}
443 get_write_undefined_symbols()
const
444 {
return m_write_undefined_symbols;}
451 {m_write_undefined_symbols = f;}
457 get_write_default_sizes()
458 {
return m_write_default_sizes;}
465 {m_write_default_sizes = f;}
471 get_write_corpus_path()
472 {
return m_write_corpus_path;}
479 {m_write_corpus_path = f;}
486 {
return m_write_comp_dir;}
493 {m_write_comp_dir = f;}
500 {
return m_short_locs;}
513 get_write_parameter_names()
const
514 {
return m_write_parameter_names;}
521 {m_write_parameter_names = f;}
528 {m_write_native_offsets = flag;}
534 get_write_native_offsets()
535 {
return m_write_native_offsets;}
541 get_write_non_reachable_types()
const
542 {
return m_write_non_reachable_types;}
549 {m_write_non_reachable_types = flag;}
558 get_show_locs()
const
559 {
return m_show_locs;}
577 get_type_id_style()
const
578 {
return m_type_id_style;}
587 {m_type_id_style = style;}
594 get_id_manager()
const
595 {
return m_id_manager;}
599 {
return m_id_manager;}
603 type_has_existing_id(type_base_sptr type)
const
604 {
return type_has_existing_id(type.get());}
608 type_has_existing_id(type_base* type)
const
611 return m_type_id_map.find(type) != m_type_id_map.end();
619 get_id_for_type(
const type_base_sptr& t)
620 {
return get_id_for_type(t.get());}
627 get_id_for_type(
const type_base* type)
const
631 auto it = m_type_id_map.find(c);
632 if (it != m_type_id_map.end())
635 switch (m_type_id_style)
637 case SEQUENCE_TYPE_ID_STYLE:
639 interned_string
id = get_id_manager().get_id_with_prefix(
"type-id-");
640 return m_type_id_map[c] = id;
642 case HASH_TYPE_ID_STYLE:
644 interned_string pretty = c->get_cached_pretty_representation(
true);
646 while (!m_used_type_id_hashes.insert(hash).second)
648 std::ostringstream os;
649 os << std::hex << std::setfill(
'0') << std::setw(8) <<
hash;
650 return m_type_id_map[c] = c->get_environment().intern(os.str());
654 return interned_string();
660 fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
661 if (it == m_fn_tmpl_id_map.end())
663 string id = get_id_manager().get_id_with_prefix(
"fn-tmpl-id-");
664 m_fn_tmpl_id_map[f] = id;
667 return m_fn_tmpl_id_map[f];
673 class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
674 if (it == m_class_tmpl_id_map.end())
676 string id = get_id_manager().get_id_with_prefix(
"class-tmpl-id-");
677 m_class_tmpl_id_map[c] = id;
680 return m_class_tmpl_id_map[c];
686 m_type_id_map.clear();
697 const type_ptr_set_type&
698 get_referenced_types()
const
699 {
return m_referenced_types_set;}
706 get_referenced_function_types()
const
707 {
return m_referenced_fn_types_set;}
713 has_non_emitted_referenced_types()
const
715 for (
const auto t : get_referenced_types())
716 if (!type_is_emitted(t))
719 for (
const auto t : get_referenced_function_types())
720 if (!type_is_emitted(t))
732 record_type_as_referenced(
const type_base_sptr& type)
735 if (t && !m_write_non_reachable_types)
741 m_referenced_fn_types_set.insert(f);
743 m_referenced_types_set.insert(t);
754 type_is_referenced(
const type_base_sptr& type)
758 return (m_referenced_fn_types_set.find(f)
759 != m_referenced_fn_types_set.end());
761 return m_referenced_types_set.find(t) != m_referenced_types_set.end();
774 sort_types(type_ptr_set_type& types, vector<type_base*>& sorted)
777 for (type_ptr_set_type::const_iterator i = types.begin();
780 sorted.push_back(
const_cast<type_base*
>(*i));
798 for (
auto& type : types)
799 sorted.push_back(type);
815 vector<type_base_sptr> &sorted)
817 for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
820 sorted.push_back(type_base_sptr(i->second));
836 sort_types(
const vector<function_type_sptr>& types,
837 vector<type_base_sptr> &sorted)
839 for (vector<function_type_sptr>::const_iterator i = types.begin();
842 sorted.push_back(*i);
851 record_type_as_emitted(
const type_base_sptr &t)
852 {record_type_as_emitted(t.get());}
858 record_type_as_emitted(
const type_base* t)
861 m_emitted_type_set.insert(c);
871 type_is_emitted(
const type_base* t)
const
874 return (m_emitted_type_set.find(c) != m_emitted_type_set.end());
884 type_is_emitted(
const type_base_sptr& t)
const
885 {
return type_is_emitted(t.get());}
893 type_to_be_emitted(
const type_base* t)
const
895 if (!t || type_is_emitted(t))
898 const corpus* abi = t->get_corpus();
900 if (!get_write_non_reachable_types()
913 type_to_be_emitted(
const type_base_sptr t)
const
914 {
return type_to_be_emitted(t.get());}
923 decl_is_emitted(
const decl_base& decl)
const
925 return decl_is_emitted(&decl);
935 decl_is_emitted(
const decl_base* decl)
const
939 result = (m_emitted_var_decls_set.find(var)
940 != m_emitted_var_decls_set.end());
942 result = (m_emitted_function_decls_set.find(fn)
943 != m_emitted_function_decls_set.end());
954 decl_is_emitted(
const decl_base_sptr& decl)
const
956 return decl_is_emitted(decl.get());
963 record_decl_as_emitted(
const decl_base_sptr& decl)
966 m_emitted_var_decls_set.insert(var.get());
968 m_emitted_function_decls_set.insert(fn.get());
982 corpus_is_emitted(
const corpus_sptr& corp)
987 if (m_emitted_corpora_set.find(corp->get_path())
988 == m_emitted_corpora_set.end())
998 record_corpus_as_emitted(
const corpus_sptr& corp)
1003 const string& path = corp->get_path();
1005 m_emitted_corpora_set.insert(path);
1011 const type_ptr_set_type&
1012 get_emitted_types_set()
const
1013 {
return m_emitted_type_set;}
1018 clear_referenced_types()
1020 m_referenced_types_set.clear();
1021 m_referenced_fn_types_set.clear();
1025 get_fun_symbol_map()
const
1026 {
return m_fun_symbol_map;}
1029 get_fun_symbol_map()
1030 {
return m_fun_symbol_map;}
1034static void write_location(
const location&, write_context&);
1035static void write_location(
const decl_base_sptr&, write_context&);
1036static bool write_visibility(
const decl_base_sptr&, ostream&);
1037static bool write_binding(
const decl_base_sptr&, ostream&);
1038static bool write_is_artificial(
const decl_base_sptr&, ostream&);
1039static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
1040static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
1043static void write_size_and_alignment(
const type_base_sptr, ostream&,
1044 size_t default_size = 0,
1045 size_t default_alignment = 0);
1049static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
1053static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
1054static bool write_elf_symbol_reference(write_context&,
1058static bool write_elf_symbol_reference(write_context&,
1062static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
1064static void write_is_anonymous(
const decl_base_sptr&, ostream&);
1065static void write_type_hash_and_cti(
const type_base_sptr&, ostream&);
1066static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
1068 write_context&,
unsigned);
1069static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
1070static void write_decls_from_scope(write_context&,
1074 write_context&,
unsigned);
1075static bool write_qualified_type_def(
const qualified_type_def_sptr&,
1076 write_context&,
unsigned);
1078 write_context&,
unsigned);
1080 write_context&,
unsigned);
1082 write_context&,
unsigned);
1084 write_context&,
unsigned);
1089 write_context&,
unsigned);
1091 write_context&,
unsigned);
1093 write_context&,
unsigned);
1094static bool write_elf_symbols_table(
const elf_symbols&,
1095 write_context&,
unsigned);
1097 write_context&,
bool,
unsigned);
1105 bool skip_first_parm,
1106 write_context& ctxt,
1109 write_context& ctxt,
unsigned indent);
1112 write_context&,
unsigned);
1113static bool write_member_type_opening_tag(
const type_base_sptr&,
1114 write_context&,
unsigned);
1116 write_context&,
unsigned);
1118 write_context& ctxt,
unsigned indent);
1119static bool write_member_type(
const type_base_sptr&,
1120 write_context&,
unsigned);
1122 write_context&,
unsigned);
1123static string maybe_emit_type_hash(write_context&, type_base_sptr);
1124static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
1125 write_context&,
unsigned,
bool);
1127 write_context&,
unsigned);
1128static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
1129 write_context&,
unsigned,
bool);
1130static bool write_union_decl(
const union_decl_sptr&,
const string&,
1131 write_context&,
unsigned);
1132static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
1133static void write_common_type_info(
const type_base_sptr&, write_context&,
1134 const string&
id=
"");
1135static bool write_type(
const type_base_sptr& t,
1136 write_context& ctxt,
1138static bool write_type_tparameter
1139(
const shared_ptr<type_tparameter>, write_context&,
unsigned);
1140static bool write_non_type_tparameter
1141(
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
1142static bool write_template_tparameter
1143(
const shared_ptr<template_tparameter>, write_context&,
unsigned);
1144static bool write_type_composition
1145(
const shared_ptr<type_composition>, write_context&,
unsigned);
1146static bool write_template_parameter(
const shared_ptr<template_parameter>,
1147 write_context&,
unsigned);
1148static void write_template_parameters(
const shared_ptr<template_decl>,
1149 write_context&,
unsigned);
1150static bool write_function_tdecl
1151(
const shared_ptr<function_tdecl>,
1152 write_context&,
unsigned);
1153static bool write_class_tdecl
1154(
const shared_ptr<class_tdecl>,
1155 write_context&,
unsigned);
1156static void do_indent(ostream&,
unsigned);
1157static void do_indent_to_level(write_context&,
unsigned,
unsigned);
1158static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
1159static decl_base* get_variant_of_decl_from_abi(
const write_context&,
1160 const decl_base_sptr);
1161static bool scope_is_essentially_empty(
const scope_decl *scope,
1162 const write_context& ctxt);
1164 const write_context& ctxt);
1167do_indent(ostream& o,
unsigned nb_whitespaces)
1169 for (
unsigned i = 0; i < nb_whitespaces; ++i)
1181do_indent_to_level(write_context& ctxt,
1182 unsigned initial_indent,
1185 do_indent(ctxt.get_ostream(),
1186 get_indent_to_level(ctxt, initial_indent, level));
1198get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
1201 int nb_ws = initial_indent +
1202 level * ctxt.get_config().get_xml_element_indent();
1224template <
typename T>
1226annotate(
const T& decl,
1227 write_context& ctxt,
1229 const string& addendum =
"")
1234 if (!ctxt.get_annotate())
1237 ostream& o = ctxt.get_ostream();
1239 do_indent(o, indent);
1241 string decl_repr = decl->get_pretty_representation(
false);
1242 if (!addendum.empty())
1243 decl_repr += addendum;
1267 write_context& ctxt,
1269 const string& addendum)
1274 if (!ctxt.get_annotate())
1277 ostream& o = ctxt.get_ostream();
1279 string elf_symbol_repr =
1282 if (!addendum.empty())
1283 elf_symbol_repr += addendum;
1285 do_indent(o, indent);
1307 write_context& ctxt,
1309 const string& addendum)
1314 if (!ctxt.get_annotate())
1317 ostream& o = ctxt.get_ostream();
1319 do_indent(o, indent);
1321 o <<
"<!-- typedef "
1347 write_context& ctxt,
1349 const string& addendum =
"")
1354 if (!ctxt.get_annotate())
1357 ostream& o = ctxt.get_ostream();
1359 do_indent(o, indent);
1382 write_context& ctxt,
1384 const string& addendum =
"")
1389 if (!ctxt.get_annotate())
1392 ostream& o = ctxt.get_ostream();
1394 do_indent(o, indent);
1406 vector<function_decl::parameter_sptr>::const_iterator pi =
1407 fn->get_first_non_implicit_parm();
1409 for (; pi != fn->get_parameters().end(); ++pi)
1413 if (distance(pi, fn->get_parameters().end()) > 1)
1438 write_context& ctxt,
1440 const string& addendum)
1445 if (!ctxt.get_annotate())
1448 ostream &o = ctxt.get_ostream();
1450 do_indent(o, indent);
1454 if (parm->get_variadic_marker())
1455 o <<
"variadic parameter";
1458 if (parm->get_is_artificial())
1460 if (parm->get_index() == 0)
1465 o <<
"parameter of type '"
1486write_location(
const location& loc, write_context& ctxt)
1491 if (!ctxt.get_show_locs())
1495 unsigned line = 0, column = 0;
1497 loc.
expand(filepath, line, column);
1499 ostream &o = ctxt.get_ostream();
1501 if (ctxt.get_short_locs())
1505 <<
" line='" << line <<
"'"
1506 <<
" column='" << column <<
"'";
1517write_location(
const decl_base_sptr& decl,
1518 write_context& ctxt)
1523 location loc = decl->get_location();
1527 write_location(loc, ctxt);
1539write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1549 case decl_base::VISIBILITY_NONE:
1551 case decl_base::VISIBILITY_DEFAULT:
1554 case decl_base::VISIBILITY_PROTECTED:
1557 case decl_base::VISIBILITY_HIDDEN:
1560 case decl_base::VISIBILITY_INTERNAL:
1568 o <<
" visibility='" << str <<
"'";
1579write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1586 shared_ptr<var_decl> var =
1587 dynamic_pointer_cast<var_decl>(decl);
1589 bind = var->get_binding();
1592 shared_ptr<function_decl> fun =
1593 dynamic_pointer_cast<function_decl>(decl);
1595 bind = fun->get_binding();
1601 case decl_base::BINDING_NONE:
1603 case decl_base::BINDING_LOCAL:
1606 case decl_base::BINDING_GLOBAL:
1609 case decl_base::BINDING_WEAK:
1615 o <<
" binding='" << str <<
"'";
1629write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1634 if (decl->get_is_artificial())
1635 o <<
" is-artificial='yes'";
1649write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1654 corpus* c = t->get_corpus();
1655 if (!c || !c->recording_types_reachable_from_public_interface_supported())
1659 o <<
" is-non-reachable='yes'";
1672write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1675 corpus_group* group = corpus->get_group();
1677 if (corpus->recording_types_reachable_from_public_interface_supported())
1679 o <<
" tracking-non-reachable-types='yes'";
1700write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1701 size_t default_size,
size_t default_alignment)
1703 size_t size_in_bits = decl->get_size_in_bits();
1704 if (size_in_bits != default_size)
1705 o <<
" size-in-bits='" << size_in_bits <<
"'";
1707 size_t alignment_in_bits = decl->get_alignment_in_bits();
1708 if (alignment_in_bits != default_alignment)
1709 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1717write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1719 if (decl->is_non_finite())
1720 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1722 size_t size_in_bits = decl->get_size_in_bits();
1724 o <<
" size-in-bits='" << size_in_bits <<
"'";
1727 size_t alignment_in_bits = decl->get_alignment_in_bits();
1728 if (alignment_in_bits)
1729 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1739 string access_str =
"private";
1743 case private_access:
1744 access_str =
"private";
1747 case protected_access:
1748 access_str =
"protected";
1752 access_str =
"public";
1759 o <<
" access='" << access_str <<
"'";
1770 o <<
" layout-offset-in-bits='"
1777write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1782 if (base->get_offset_in_bits() >= 0)
1783 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1792write_access(decl_base_sptr member, ostream& o)
1809 o <<
" vtable-offset='" << voffset <<
"'";
1826 case elf_symbol::NOTYPE_TYPE:
1829 case elf_symbol::OBJECT_TYPE:
1830 repr =
"object-type";
1832 case elf_symbol::FUNC_TYPE:
1835 case elf_symbol::SECTION_TYPE:
1836 repr =
"section-type";
1838 case elf_symbol::FILE_TYPE:
1841 case elf_symbol::COMMON_TYPE:
1842 repr =
"common-type";
1844 case elf_symbol::TLS_TYPE:
1847 case elf_symbol::GNU_IFUNC_TYPE:
1848 repr =
"gnu-ifunc-type";
1855 o <<
" type='" << repr <<
"'";
1871 case elf_symbol::LOCAL_BINDING:
1872 repr =
"local-binding";
1874 case elf_symbol::GLOBAL_BINDING:
1875 repr =
"global-binding";
1877 case elf_symbol::WEAK_BINDING:
1878 repr =
"weak-binding";
1880 case elf_symbol::GNU_UNIQUE_BINDING:
1881 repr =
"gnu-unique-binding";
1884 repr =
"no-binding";
1888 o <<
" binding='" << repr <<
"'";
1904 case elf_symbol::DEFAULT_VISIBILITY:
1905 repr =
"default-visibility";
1907 case elf_symbol::PROTECTED_VISIBILITY:
1908 repr =
"protected-visibility";
1910 case elf_symbol::HIDDEN_VISIBILITY:
1911 repr =
"hidden-visibility";
1913 case elf_symbol::INTERNAL_VISIBILITY:
1914 repr =
"internal-visibility";
1917 repr =
"default-visibility";
1921 o <<
" visibility='" << repr <<
"'";
1932write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1934 if (!sym.is_main_symbol() || !sym.has_aliases())
1938 std::vector<std::string> aliases;
1939 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1940 s = s->get_next_alias())
1942 if (!s->is_public())
1945 if (s->is_suppressed())
1948 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1951 aliases.push_back(s->get_id_string());
1954 if (!aliases.empty())
1957 std::string separator;
1958 for (
const auto& alias : aliases)
1960 out << separator << alias;
1987write_elf_symbol_reference(write_context& ctxt,
1988 const elf_symbol& sym,
1994 s = abi.lookup_variable_symbol(sym);
2000 || (!ctxt.get_write_undefined_symbols() && !s->is_defined()))
2004 const elf_symbol* main = sym.get_main_symbol().get();
2005 const elf_symbol* alias = &sym;
2006 bool found = !alias->is_suppressed();
2011 found = !alias->is_suppressed();
2016 alias = alias->get_next_alias().get();
2018 if (!alias || alias == main)
2020 found = !alias->is_suppressed();
2025 o <<
" elf-symbol-id='"
2046write_elf_symbol_reference(write_context& ctxt,
2054 return write_elf_symbol_reference(ctxt, *sym, abi, o);
2071write_cdtor_const_static(
bool is_ctor,
2078 o <<
" static='yes'";
2080 o <<
" constructor='yes'";
2082 o <<
" destructor='yes'";
2084 o <<
" const='yes'";
2094write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
2096 if (d->get_is_declaration_only())
2097 o <<
" is-declaration-only='yes'";
2109 if (klass->is_struct())
2110 o <<
" is-struct='yes'";
2120write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
2122 if (decl->get_is_anonymous())
2123 o <<
" is-anonymous='yes'";
2132write_type_hash_and_cti(
const type_base_sptr& t, ostream& o)
2140 o <<
" hash='" << h;
2141 if (t->priv_->canonical_type_index)
2142 o <<
"#" << t->priv_->canonical_type_index;
2155write_artifact_native_offset(write_context& ctxt,
2159 if (!ctxt.get_write_native_offsets() || !t)
2162 if (
offset_t offset = t->get_native_offset())
2164 std::ostringstream os;
2165 os << std::hex << *offset;
2166 o <<
" native-offset='" << os.str() <<
"'";
2178write_common_type_info(
const type_base_sptr& t,
2179 write_context& ctxt,
2182 decl_base_sptr d =
is_decl(t);
2184 ostream& o = ctxt.get_ostream();
2186 write_is_non_reachable(t, o);
2188 if (!d || (d && !d->get_is_declaration_only()))
2191 write_size_and_alignment(t, o);
2193 write_array_size_and_alignment(a, o);
2198 write_is_anonymous(d, o);
2199 write_is_declaration_only(d, o);
2200 write_location(d, ctxt);
2203 write_artifact_native_offset(ctxt, t, o);
2204 write_type_hash_and_cti(t, o);
2208 i = ctxt.get_id_for_type(t);
2209 o <<
" id='" << i <<
"'";
2211 ctxt.record_type_as_emitted(t);
2228write_type(
const type_base_sptr& t,
2229 write_context& ctxt,
2234 if (!ctxt.type_to_be_emitted(type))
2237 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
2239 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
2242 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
2244 || write_reference_type_def(dynamic_pointer_cast
2245 <reference_type_def>(type), ctxt, indent)
2246 || write_ptr_to_mbr_type(dynamic_pointer_cast
2247 <ptr_to_mbr_type>(type),
2249 || write_array_type_def(dynamic_pointer_cast
2250 <array_type_def>(type), ctxt, indent)
2251 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
2253 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
2258 || (write_function_tdecl
2259 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
2260 || (write_class_tdecl
2261 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
2279write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
2283 if (type && !ctxt.type_to_be_emitted(type))
2287 || write_namespace_decl(
is_namespace(decl), ctxt, indent)
2294 || write_enum_type_decl(
is_enum_type(type), ctxt, indent)
2295 || write_typedef_decl(
is_typedef(type), ctxt, indent)
2296 || write_var_decl(
is_var_decl(decl), ctxt,
true, indent)
2301 || (write_function_tdecl
2302 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
2303 || (write_class_tdecl
2304 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
2323 write_context& ctxt,
2324 unsigned initial_indent)
2326 type_base_sptr type =
is_type(artf);
2327 decl_base_sptr decl =
is_decl(artf);
2328 if ((type && ctxt.type_is_emitted(type))
2329 || (!type && ctxt.decl_is_emitted(decl)))
2332 list<scope_decl_sptr> scopes;
2334 for (
auto s = decl->get_scope();
2337 scopes.push_front(s);
2339 ostream& o = ctxt.get_ostream();
2340 const config& c = ctxt.get_config();
2341 stack<string> closing_tags;
2342 stack<unsigned> closing_indents;
2343 unsigned indent = initial_indent;
2344 for (
auto i = scopes.begin();
2353 do_indent(o, indent);
2354 o <<
"<namespace-decl name='"
2357 closing_tags.push(
"</namespace-decl>");
2358 closing_indents.push(indent);
2366 bool do_break =
false;
2367 if (!ctxt.type_is_emitted(c) && ctxt.type_to_be_emitted(c))
2369 write_type(class_type, ctxt, initial_indent);
2393 || (type && !ctxt.type_is_emitted(type))
2394 || (!type && !ctxt.decl_is_emitted(decl)))
2396 annotate(class_type, ctxt, indent);
2397 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2399 closing_tags.push(
"</class-decl>");
2400 closing_indents.push(indent);
2401 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2403 auto type_to_emit = type;
2404 auto decl_to_emit = decl;
2405 auto next_scope_index = i;
2407 if (next_scope_index != scopes.end())
2409 type_to_emit =
is_type(*next_scope_index);
2410 decl_to_emit =
is_decl(*next_scope_index);
2414 write_member_type_opening_tag(type_to_emit, ctxt, nb_ws);
2415 closing_tags.push(
"</member-type>");
2416 closing_indents.push(indent);
2420 write_member_function_opening_tag(fn_decl, ctxt, nb_ws);
2421 closing_tags.push(
"</member-function>");
2422 closing_indents.push(indent);
2424 closing_indents.push(nb_ws);
2432 union_decl_sptr union_type = u;
2433 bool do_break =
false;
2434 if (!ctxt.type_is_emitted(u))
2436 write_type(union_type, ctxt, initial_indent);
2444 || !ctxt.type_is_emitted(type))
2446 annotate(union_type, ctxt, indent);
2447 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2449 closing_tags.push(
"</union-decl>");
2450 closing_indents.push(indent);
2452 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2453 write_member_type_opening_tag(type, ctxt, nb_ws);
2455 closing_tags.push(
"</member-type>");
2456 closing_indents.push(nb_ws);
2465 write_member_function_opening_tag(fn, ctxt, indent);
2466 write_function_decl_opening_tag(fn, ctxt, get_indent_to_level(ctxt, indent, 1));
2469 write_function_member_decls(fn, ctxt,
2470 get_indent_to_level(ctxt, indent, 2));
2475 write_fn_parm_and_return_types(fn->get_type(),
2478 write_function_decl_closing_tag(fn, ctxt, indent);
2479 write_member_function_closing_tag(fn, ctxt, indent);
2480 ctxt.record_decl_as_emitted(fn);
2495 indent += c.get_xml_element_indent();
2498 bool do_write =
false;
2499 if (type_base_sptr type =
is_type(decl))
2501 if (ctxt.type_to_be_emitted(type))
2506 if (!ctxt.decl_is_emitted(decl))
2511 write_decl(decl, ctxt, indent);
2513 while (!closing_tags.empty())
2515 do_indent(o, closing_indents.top());
2516 o << closing_tags.top() <<
"\n";
2518 closing_indents.pop();
2532 ostream& default_output_stream)
2549{ctxt.set_show_locs(flag);}
2561{ctxt.set_annotate(flag);}
2570{ctxt.set_write_member_hashes(flag);}
2579{ctxt.set_write_non_reachable_types(flag);}
2590{ctxt.set_ostream(os);}
2602{ctxt.set_write_architecture(flag);}
2614{ctxt.set_write_corpus_path(flag);}
2626{ctxt.set_write_comp_dir(flag);}
2638{ctxt.set_short_locs(flag);}
2650{ctxt.set_write_parameter_names(flag);}
2662{ctxt.set_write_elf_needed(flag);}
2674{ctxt.set_write_undefined_symbols(flag);}
2689{ctxt.set_write_default_sizes(flag);}
2700{ctxt.set_type_id_style(
style);}
2713{ctxt.set_write_native_offsets(flag);}
2728write_canonical_types_of_scope(
const scope_decl &scope,
2729 write_context &ctxt,
2730 const unsigned indent,
2736 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2737 i != canonical_types.end();
2740 if (!ctxt.type_to_be_emitted(*i))
2743 write_member_type(*i, ctxt, indent);
2745 write_type(*i, ctxt, indent);
2762write_referenced_types(write_context & ctxt,
2763 const unsigned indent)
2765 const config& c = ctxt.get_config();
2773 type_ptr_set_type referenced_types_to_emit;
2778 for (type_ptr_set_type::const_iterator i =
2779 ctxt.get_referenced_types().begin();
2780 i != ctxt.get_referenced_types().end();
2782 if (ctxt.type_to_be_emitted(*i))
2783 referenced_types_to_emit.insert(*i);
2785 for (fn_type_ptr_set_type::const_iterator i =
2786 ctxt.get_referenced_function_types().begin();
2787 i != ctxt.get_referenced_function_types().end();
2789 if (ctxt.type_to_be_emitted(*i))
2790 referenced_types_to_emit.insert(*i);
2793 while (!referenced_types_to_emit.empty())
2798 vector<type_base*> sorted_referenced_types;
2799 ctxt.sort_types(referenced_types_to_emit,
2800 sorted_referenced_types);
2803 for (vector<type_base*>::const_iterator i =
2804 sorted_referenced_types.begin();
2805 i != sorted_referenced_types.end();
2811 if (ctxt.type_to_be_emitted(t))
2815 decl_base_sptr decl(d, noop_deleter());
2816 write_artifact_in_scope(decl, ctxt,
2817 indent + c.get_xml_element_indent());
2822 write_function_type(fn_type, ctxt,
2823 indent + c.get_xml_element_indent());
2832 referenced_types_to_emit.clear();
2844 for (type_ptr_set_type::const_iterator i =
2845 ctxt.get_referenced_types().begin();
2846 i != ctxt.get_referenced_types().end();
2848 if (ctxt.type_to_be_emitted(*i))
2849 referenced_types_to_emit.insert(*i);
2864get_variant_of_decl_from_abi(
const write_context& ctxt,
2865 const decl_base_sptr decl)
2876 interned_string
id = function->get_id();
2877 if (
const std::unordered_set<const function_decl*>* fns =
2878 abi->lookup_functions(
id))
2881 if (ctxt.get_write_undefined_symbols() || sym->is_defined())
2882 return const_cast<function_decl*>(f);
2884 if (ctxt.get_write_undefined_symbols())
2885 if (abi->get_undefined_functions().find(function.get())
2886 != abi->get_undefined_functions().end())
2887 return function.get();
2891 interned_string
id = variable->get_id();
2892 if (
const std::unordered_set<var_decl_sptr>* vars =
2893 abi->lookup_variables(
id))
2894 for (
auto v : *vars)
2896 if (ctxt.get_write_undefined_symbols() || sym->is_defined())
2913translation_unit_is_essentially_empty(
const write_context& ctxt,
2914 const translation_unit& tu)
2920 if (scope_is_essentially_empty(scope, ctxt))
2934write_decls_from_scope(write_context& ctxt,
2935 const scope_decl& scope,
2936 const unsigned indent)
2939 const declarations& decls = scope.get_sorted_member_decls();
2940 const config& c = ctxt.get_config();
2942 for (
const decl_base_sptr& decl : decls)
2944 if (type_base_sptr t =
is_type(decl))
2946 if (!ctxt.type_to_be_emitted(t))
2958 if (!ctxt.decl_is_emitted(v))
2959 write_artifact_in_scope(v, ctxt, indent);
2968 if (!ctxt.decl_is_emitted(fn))
2969 write_decl(fn, ctxt, indent + c.get_xml_element_indent());
2973 write_decl(decl, ctxt, indent);
2991 const unsigned indent)
2993 if (tu.
is_empty() || translation_unit_is_essentially_empty(ctxt, tu))
2996 ostream& o = ctxt.get_ostream();
2997 const config& c = ctxt.get_config();
2999 do_indent(o, indent);
3006 std::string tu_path = tu.
get_path();
3007 if (ctxt.get_short_locs())
3009 if (!tu_path.empty())
3013 o <<
" comp-dir-path='"
3016 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
3034 ctxt, indent + c.get_xml_element_indent());
3037 indent + c.get_xml_element_indent());
3049 if ((fn && fn->get_translation_unit() != &tu)
3050 || ctxt.decl_is_emitted(fn))
3054 write_decl(fn, ctxt, indent + c.get_xml_element_indent());
3065 if ((var && var->get_translation_unit() != &tu)
3066 || ctxt.decl_is_emitted(v))
3070 write_decl(var, ctxt, indent + c.get_xml_element_indent());
3078 vector<type_base_sptr> sorted_types;
3079 ctxt.sort_types(t, sorted_types);
3081 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
3082 i != sorted_types.end();
3087 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
3094 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
3099 write_referenced_types(ctxt, indent);
3102 do_indent(o, indent);
3103 o <<
"</abi-instr>\n";
3120 const corpus& abi_corpus,
3121 const unsigned indent)
3123 std::ostream& o = ctxt.get_ostream();
3124 const config &conf = ctxt.get_config();
3126 do_indent(o, indent);
3128 const vector<type_base_wptr>& types =
3133 o <<
"<abi-types/>\n";
3137 o <<
"<abi-types>\n";
3139 for (
auto& type_wptr : types)
3141 type_base_sptr t(type_wptr);
3143 if (!ctxt.type_to_be_emitted(t))
3147 write_type(fn_type, ctxt, indent + conf.get_xml_element_indent());
3149 write_artifact_in_scope(
type_decl, ctxt,
3150 indent + conf.get_xml_element_indent());
3155 write_referenced_types(ctxt, indent + conf.get_xml_element_indent());
3157 do_indent(o, indent);
3158 o <<
"</abi-types>\n";
3176write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
3181 ostream& o = ctxt.get_ostream();
3183 annotate(d, ctxt, indent);
3185 do_indent(o, indent);
3189 write_common_type_info(d, ctxt);
3207scope_is_essentially_empty(
const scope_decl *scope,
const write_context& ctxt)
3210 for (
auto& type : scope->get_canonical_types())
3211 if (ctxt.type_to_be_emitted(type))
3214 for (
auto& decl : scope->get_member_decls())
3216 if (type_base_sptr type =
is_type(decl))
3218 if (ctxt.type_to_be_emitted(type))
3228 if (!ctxt.decl_is_emitted(v))
3238 if (!ctxt.decl_is_emitted(fn))
3243 if (!scope_is_essentially_empty(s, ctxt))
3265 const write_context& ctxt)
3266{
return scope_is_essentially_empty(decl.get(), ctxt);}
3281 write_context& ctxt,
unsigned indent)
3286 if (scope_is_essentially_empty(decl, ctxt))
3289 ostream& o = ctxt.get_ostream();
3290 const config &c = ctxt.get_config();
3292 annotate(decl, ctxt, indent);
3294 do_indent(o, indent);
3296 o <<
"<namespace-decl name='"
3300 write_canonical_types_of_scope(*decl, ctxt,
3301 indent + c.get_xml_element_indent());
3303 write_decls_from_scope(ctxt, *decl, indent + c.get_xml_element_indent());
3305 do_indent(o, indent);
3306 o <<
"</namespace-decl>\n";
3330write_qualified_type_def(
const qualified_type_def_sptr& decl,
3332 write_context& ctxt,
3338 ostream& o = ctxt.get_ostream();
3341 type_base_sptr underlying_type = decl->get_underlying_type();
3343 annotate(decl, ctxt, indent);
3345 do_indent(o, indent);
3346 o <<
"<qualified-type-def type-id='"
3347 << ctxt.get_id_for_type(underlying_type)
3350 ctxt.record_type_as_referenced(underlying_type);
3352 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
3353 o <<
" const='yes'";
3354 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
3355 o <<
" volatile='yes'";
3356 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
3357 o <<
" restrict='yes'";
3359 write_common_type_info(decl, ctxt,
id);
3377write_qualified_type_def(
const qualified_type_def_sptr& decl,
3378 write_context& ctxt,
3380{
return write_qualified_type_def(decl,
"", ctxt, indent);}
3402 write_context& ctxt,
3408 ostream& o = ctxt.get_ostream();
3410 annotate(decl, ctxt, indent);
3412 do_indent(o, indent);
3416 o <<
"<pointer-type-def ";
3418 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
3420 i = ctxt.get_id_for_type(pointed_to_type);
3422 o <<
"type-id='" << i <<
"'";
3424 ctxt.record_type_as_referenced(pointed_to_type);
3426 write_common_type_info(decl, ctxt,
id);
3444 write_context& ctxt,
3446{
return write_pointer_type_def(decl,
"", ctxt, indent);}
3468 write_context& ctxt,
3474 annotate(decl->get_canonical_type(), ctxt, indent);
3476 ostream& o = ctxt.get_ostream();
3478 do_indent(o, indent);
3480 o <<
"<reference-type-def kind='";
3481 if (decl->is_lvalue())
3487 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
3488 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
3490 ctxt.record_type_as_referenced(pointed_to_type);
3493 ctxt.record_type_as_referenced(f);
3495 write_common_type_info(decl, ctxt,
id);
3513 write_context& ctxt,
3515{
return write_reference_type_def(decl,
"", ctxt, indent);}
3531 const string&
id, write_context& ctxt,
3537 annotate(decl->get_canonical_type(), ctxt, indent);
3539 ostream& o = ctxt.get_ostream();
3541 do_indent(o, indent);
3543 o <<
"<pointer-to-member-type";
3545 type_base_sptr member_type = decl->get_member_type();
3546 string i = ctxt.get_id_for_type(member_type);
3547 o <<
" member-type-id='" << i <<
"'";
3548 ctxt.record_type_as_referenced(member_type);
3550 type_base_sptr containing_type = decl->get_containing_type();
3551 i = ctxt.get_id_for_type(containing_type);
3552 o <<
" containing-type-id='" << i <<
"'";
3553 ctxt.record_type_as_referenced(containing_type);
3555 write_common_type_info(decl, ctxt,
id);
3573 write_context& ctxt,
unsigned indent)
3574{
return write_ptr_to_mbr_type(decl,
"", ctxt, indent);}
3587 write_context& ctxt,
3593 annotate(decl, ctxt, indent);
3595 ostream& o = ctxt.get_ostream();
3597 do_indent(o, indent);
3601 if (!decl->get_name().empty())
3602 o <<
" name='" << decl->get_name() <<
"'";
3605 if (decl->is_non_finite())
3608 o << decl->get_length();
3613 || decl->get_length() == 0
3614 || (decl->get_length() ==
3615 (uint64_t) (decl->get_upper_bound()
3616 - decl->get_lower_bound() + 1)));
3617 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
3618 << decl->get_upper_bound() <<
"'";
3620 type_base_sptr underlying_type = decl->get_underlying_type();
3621 if (underlying_type)
3624 << ctxt.get_id_for_type(underlying_type)
3626 ctxt.record_type_as_referenced(underlying_type);
3629 write_common_type_info(decl, ctxt);
3656 write_context& ctxt,
3662 annotate(decl, ctxt, indent);
3664 ostream& o = ctxt.get_ostream();
3666 do_indent(o, indent);
3667 o <<
"<array-type-def";
3669 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
3671 type_base_sptr element_type = decl->get_element_type();
3672 string type_id = ctxt.get_id_for_type(element_type);
3673 o <<
" type-id='" << type_id <<
"'";
3675 ctxt.record_type_as_referenced(element_type);
3677 write_common_type_info(decl, ctxt,
id);
3679 if (!decl->get_dimension_count())
3685 vector<array_type_def::subrange_sptr>::const_iterator si;
3687 for (si = decl->get_subranges().begin();
3688 si != decl->get_subranges().end(); ++si)
3690 unsigned local_indent =
3691 indent + ctxt.get_config().get_xml_element_indent();
3692 write_array_subrange_type(*si, ctxt, local_indent);
3695 do_indent(o, indent);
3696 o <<
"</array-type-def>\n";
3713 write_context& ctxt,
3715{
return write_array_type_def(decl,
"", ctxt, indent);}
3737 write_context& ctxt,
3745 annotate(decl->get_canonical_type(), ctxt, indent);
3747 ostream& o = ctxt.get_ostream();
3749 do_indent(o, indent);
3752 write_is_artificial(decl, o);
3754 if (!decl->get_linkage_name().empty())
3755 o <<
" linkage-name='"
3759 write_common_type_info(decl, ctxt,
id);
3763 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3764 auto underlying_type = decl->get_underlying_type();
3765 o <<
"<underlying-type type-id='"
3766 << ctxt.get_id_for_type(underlying_type)
3769 ctxt.record_type_as_referenced(underlying_type);
3771 for (enum_type_decl::enumerators::const_iterator i =
3772 decl->get_enumerators().begin();
3773 i != decl->get_enumerators().end();
3776 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3777 o <<
"<enumerator name='"
3784 do_indent(o, indent);
3785 o <<
"</enum-decl>\n";
3801 write_context& ctxt,
3803{
return write_enum_type_decl(decl,
"", ctxt, indent);}
3817 write_context& ctxt,
3823 ostream &o = ctxt.get_ostream();
3825 annotate(sym, ctxt, indent);
3826 do_indent(o, indent);
3828 if (sym->is_variable() && sym->get_size())
3829 o <<
" size='" << sym->get_size() <<
"'";
3831 if (!sym->get_version().is_empty())
3833 o <<
" version='" << sym->get_version().str() <<
"'";
3834 o <<
" is-default-version='";
3835 if (sym->get_version().is_default())
3842 write_elf_symbol_type(sym->get_type(), o);
3844 write_elf_symbol_binding(sym->get_binding(), o);
3846 write_elf_symbol_visibility(sym->get_visibility(), o);
3848 write_elf_symbol_aliases(*sym, o);
3850 o <<
" is-defined='";
3851 if (sym->is_defined())
3857 if (sym->is_common_symbol())
3858 o <<
" is-common='yes'";
3860 if (sym->get_crc().has_value())
3862 << std::hex << std::showbase << sym->get_crc().value()
3863 << std::dec << std::noshowbase <<
"'";
3865 if (sym->get_namespace().has_value())
3866 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3885 write_context& ctxt,
3893 if (ctxt.get_environment().analyze_exported_interfaces_only())
3894 if (!symbol->is_defined())
3896 write_elf_symbol(symbol, ctxt, indent);
3913write_elf_needed(
const vector<string>& needed,
3914 write_context& ctxt,
3920 ostream& o = ctxt.get_ostream();
3922 for (vector<string>::const_iterator i = needed.begin();
3926 do_indent(o, indent);
3927 o <<
"<dependency name='" << *i <<
"'/>\n";
3952 write_context& ctxt,
3958 ostream &o = ctxt.get_ostream();
3960 annotate(decl, ctxt, indent);
3962 do_indent(o, indent);
3964 o <<
"<typedef-decl name='"
3968 type_base_sptr underlying_type = decl->get_underlying_type();
3969 string type_id = ctxt.get_id_for_type(underlying_type);
3970 o <<
" type-id='" << type_id <<
"'";
3971 ctxt.record_type_as_referenced(underlying_type);
3973 write_common_type_info(decl, ctxt,
id);
3991 write_context& ctxt,
3993{
return write_typedef_decl(decl,
"", ctxt, indent);}
4008write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
4009 bool write_linkage_name,
unsigned indent)
4014 string annotation_addendum;
4016 annotation_addendum = maybe_emit_type_hash(ctxt, decl->get_type());
4017 annotate(decl, ctxt, indent, annotation_addendum);
4019 ostream &o = ctxt.get_ostream();
4021 do_indent(o, indent);
4024 type_base_sptr var_type = decl->get_type();
4026 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
4027 ctxt.record_type_as_referenced(var_type);
4029 if (write_linkage_name)
4031 const string& linkage_name = decl->get_linkage_name();
4032 if (!linkage_name.empty())
4033 o <<
" mangled-name='" << linkage_name <<
"'";
4036 write_visibility(decl, o);
4038 write_binding(decl, o);
4040 write_location(decl, ctxt);
4043 if (corpus* abi = decl->get_corpus())
4044 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
4048 ctxt.record_decl_as_emitted(decl);
4064 bool has_member_decls =
false;
4065 for (function_decl* fn = decl.get();
4068 if (!fn->get_member_decls().empty())
4070 has_member_decls =
true;
4074 return has_member_decls;
4088 write_context& ctxt,
unsigned indent)
4093 ostream &o = ctxt.get_ostream();
4094 string annotation_addendum;
4097 && decl->get_type())
4098 annotation_addendum = maybe_emit_type_hash(ctxt, decl->get_type());
4099 annotate(decl, ctxt, indent, annotation_addendum);
4101 do_indent(o, indent);
4102 o <<
"<function-decl name='"
4106 type_base_sptr fn_type = decl->get_type();
4107 string type_id = ctxt.get_id_for_type(fn_type);
4108 o <<
" type-id='" << type_id <<
"'";
4109 ctxt.record_type_as_referenced(fn_type);
4111 if (!decl->get_linkage_name().empty())
4112 o <<
" mangled-name='"
4115 write_location(decl, ctxt);
4117 if (decl->is_declared_inline())
4118 o <<
" declared-inline='yes'";
4120 write_visibility(decl, o);
4122 write_binding(decl, o);
4124 write_size_and_alignment(decl->get_type(), o,
4125 (ctxt.get_write_default_sizes()
4130 if (corpus* abi = decl->get_corpus())
4131 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
4133 if (!function_has_member_decls(decl))
4151 write_context& ctxt,
unsigned indent)
4155 || !function_has_member_decls(decl))
4158 ostream &o = ctxt.get_ostream();
4159 do_indent(o, indent);
4160 o <<
"</function-decl>\n";
4182 bool skip_first_parm,
4183 write_context& ctxt,
4188 unsigned cur_indent =
4189 indent + ctxt.get_config().get_xml_element_indent();
4191 ostream &o = ctxt.get_ostream();
4193 type_base_sptr parm_type;
4194 auto pi = t->get_parameters().begin();
4195 for ((skip_first_parm && pi != t->get_parameters().end()) ? ++pi: pi;
4196 pi != t->get_parameters().end();
4199 if ((*pi)->get_variadic_marker())
4201 do_indent(o, cur_indent);
4202 o <<
"<parameter is-variadic='yes'";
4208 annotate(*pi, ctxt, cur_indent);
4209 do_indent(o, cur_indent);
4211 o <<
"<parameter type-id='"
4212 << ctxt.get_id_for_type(parm_type)
4214 ctxt.record_type_as_referenced(parm_type);
4216 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
4219 write_is_artificial(*pi, o);
4220 write_location((*pi)->get_location(), ctxt);
4227 annotate(return_type , ctxt, cur_indent);
4228 do_indent(o, cur_indent);
4229 o <<
"<return type-id='"
4230 << ctxt.get_id_for_type(return_type)
4232 ctxt.record_type_as_referenced(return_type);
4245 write_context& ctxt,
unsigned indent)
4247 const config &c = ctxt.get_config();
4248 function_decl* fn = decl.get();
4251 write_canonical_types_of_scope(*fn, ctxt,
4252 indent + c.get_xml_element_indent());
4254 for (
const auto& d :decls)
4256 if (type_base_sptr t =
is_type(d))
4257 if (ctxt.type_is_emitted(t))
4261 write_decl(d, ctxt, indent + c.get_xml_element_indent());
4278 write_context& ctxt,
unsigned indent)
4280 if (!write_function_decl_opening_tag(decl, ctxt, indent))
4283 write_function_member_decls(decl, ctxt, indent);
4285 write_function_decl_closing_tag(decl, ctxt, indent);
4287 ctxt.record_decl_as_emitted(decl);
4303 write_context& ctxt,
unsigned indent)
4312 fun_type->get_canonical_type()
4316 ostream &o = ctxt.get_ostream();
4318 annotate(fn_type, ctxt, indent);
4320 do_indent(o, indent);
4322 o <<
"<function-type";
4327 o <<
" method-class-id='"
4328 << ctxt.get_id_for_type(method_type->get_class_type())
4331 write_cdtor_const_static(
false,
false,
4332 method_type->get_is_const(),
4333 method_type->get_is_static(),
4337 write_common_type_info(fn_type, ctxt);
4341 write_fn_parm_and_return_types(fn_type,
false,
4344 do_indent(o, indent);
4346 o <<
"</function-type>\n";
4363 write_context& ctxt,
unsigned indent)
4368 ostream& o = ctxt.get_ostream();
4370 do_indent_to_level(ctxt, indent, 0);
4372 o <<
"<member-function";
4380 write_voffset(fn_decl, o);
4398 write_context& ctxt,
unsigned indent)
4403 ostream& o = ctxt.get_ostream();
4405 do_indent_to_level(ctxt, indent, 0);
4406 o <<
"</member-function>\n";
4423 write_context& ctxt,
unsigned indent)
4428 write_member_function_opening_tag(fn_decl, ctxt,
4429 get_indent_to_level(ctxt, indent, 0));
4431 write_function_decl(fn_decl, ctxt, get_indent_to_level(ctxt, indent, 1));
4433 write_member_function_closing_tag(fn_decl, ctxt,
4434 get_indent_to_level(ctxt, indent, 0));
4459 write_context& ctxt,
4461 bool prepare_to_handle_empty)
4466 ostream& o = ctxt.get_ostream();
4468 do_indent_to_level(ctxt, indent, 0);
4472 write_is_struct(decl, o);
4474 write_is_artificial(decl, o);
4476 write_visibility(decl, o);
4478 if (decl->get_earlier_declaration())
4481 o <<
" def-of-decl-id='"
4482 << ctxt.get_id_for_type(
is_type(decl->get_earlier_declaration()))
4486 write_common_type_info(decl, ctxt,
id);
4488 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
4514write_union_decl_opening_tag(
const union_decl_sptr& decl,
4516 write_context& ctxt,
4518 bool prepare_to_handle_empty)
4523 ostream& o = ctxt.get_ostream();
4525 do_indent_to_level(ctxt, indent, 0);
4529 write_visibility(decl, o);
4531 write_is_artificial(decl, o);
4533 write_common_type_info(decl, ctxt,
id);
4535 if (prepare_to_handle_empty && decl->has_no_member())
4551maybe_emit_type_hash(write_context& ctxt, type_base_sptr type)
4553 if (ctxt.get_write_member_hashes())
4558 os <<
", type hash: " << std::hex << *h;
4584 write_context& ctxt,
4592 annotate(decl, ctxt, indent);
4594 ostream& o = ctxt.get_ostream();
4596 write_class_decl_opening_tag(decl,
id, ctxt, indent,
4599 if (!decl->has_no_base_nor_member())
4601 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4602 type_base_sptr base_type;
4603 for (class_decl::base_specs::const_iterator base =
4604 decl->get_base_specifiers().begin();
4605 base != decl->get_base_specifiers().end();
4611 annotate(base_class, ctxt, nb_ws,
4612 maybe_emit_type_hash(ctxt, base_class));
4613 do_indent(o, nb_ws);
4616 write_access((*base)->get_access_specifier(), o);
4618 write_layout_offset (*base, o);
4620 if ((*base)->get_is_virtual ())
4621 o <<
" is-virtual='yes'";
4623 base_type = (*base)->get_base_class();
4625 << ctxt.get_id_for_type(base_type)
4628 ctxt.record_type_as_referenced(base_type);
4635 for (
auto member_type : decl->get_sorted_member_types())
4636 if (ctxt.type_to_be_emitted(member_type))
4637 mem_types.insert(member_type);
4639 vector<type_base_sptr> sorted_types;
4642 for (
auto type : sorted_types)
4643 write_member_type(type, ctxt, nb_ws);
4646 for (
const auto& s_dm : decl->get_static_data_members())
4648 do_indent(o, nb_ws);
4649 o <<
"<data-member";
4654 write_cdtor_const_static(
false,
4659 write_layout_offset(s_dm, o);
4662 write_var_decl(s_dm, ctxt, is_static,
4663 get_indent_to_level(ctxt, indent, 2));
4665 do_indent_to_level(ctxt, indent, 1);
4666 o <<
"</data-member>\n";
4670 for (
const auto& dm : decl->get_non_static_data_members())
4672 do_indent(o, nb_ws);
4673 o <<
"<data-member";
4677 write_cdtor_const_static(
false,
4682 write_layout_offset(dm, o);
4685 write_var_decl(dm, ctxt, is_static,
4686 get_indent_to_level(ctxt, indent, 2));
4688 do_indent_to_level(ctxt, indent, 1);
4689 o <<
"</data-member>\n";
4692 for (class_decl::member_functions::const_iterator f =
4693 decl->get_member_functions().begin();
4694 f != decl->get_member_functions().end();
4705 write_member_function(fn, ctxt, get_indent_to_level(ctxt, indent, 1));
4708 for (
auto& fn : decl->get_virtual_mem_fns())
4711 write_member_function(fn, ctxt, get_indent_to_level(ctxt, indent, 1));
4714 for (member_function_templates::const_iterator fn =
4715 decl->get_member_function_templates().begin();
4716 fn != decl->get_member_function_templates().end();
4719 do_indent(o, nb_ws);
4720 o <<
"<member-template";
4721 write_access((*fn)->get_access_specifier(), o);
4722 write_cdtor_const_static((*fn)->is_constructor(),
4725 (*fn)->get_is_static(), o);
4727 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4728 get_indent_to_level(ctxt, indent, 2));
4729 do_indent(o, nb_ws);
4730 o <<
"</member-template>\n";
4733 for (member_class_templates::const_iterator cl =
4734 decl->get_member_class_templates().begin();
4735 cl != decl->get_member_class_templates().end();
4738 do_indent(o, nb_ws);
4739 o <<
"<member-template";
4740 write_access((*cl)->get_access_specifier(), o);
4741 write_cdtor_const_static(
false,
false,
false,
4742 (*cl)->get_is_static(), o);
4744 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4745 get_indent_to_level(ctxt, indent, 2));
4746 do_indent(o, nb_ws);
4747 o <<
"</member-template>\n";
4750 do_indent_to_level(ctxt, indent, 0);
4752 o <<
"</class-decl>\n";
4755 ctxt.record_type_as_emitted(decl);
4771 write_context& ctxt,
4773{
return write_class_decl(decl,
"", ctxt, indent);}
4785write_union_decl(
const union_decl_sptr& d,
4787 write_context& ctxt,
4795 annotate(decl, ctxt, indent);
4797 ostream& o = ctxt.get_ostream();
4799 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4801 if (!decl->has_no_member())
4803 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4804 for (
auto& member_type: decl->get_sorted_member_types())
4805 if (!ctxt.type_is_emitted(member_type))
4806 write_member_type(member_type, ctxt, nb_ws);
4808 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4811 for (union_decl::data_members::const_iterator data =
4812 decl->get_data_members().begin();
4813 data != decl->get_data_members().end();
4816 do_indent(o, nb_ws);
4817 o <<
"<data-member";
4821 write_cdtor_const_static(
false,
4828 write_var_decl(*data, ctxt, is_static,
4829 get_indent_to_level(ctxt, indent, 2));
4831 do_indent_to_level(ctxt, indent, 1);
4832 o <<
"</data-member>\n";
4835 for (union_decl::member_functions::const_iterator f =
4836 decl->get_member_functions().begin();
4837 f != decl->get_member_functions().end();
4848 write_member_function(fn, ctxt, get_indent_to_level(ctxt, indent, 1));
4851 for (member_function_templates::const_iterator fn =
4852 decl->get_member_function_templates().begin();
4853 fn != decl->get_member_function_templates().end();
4856 do_indent(o, nb_ws);
4857 o <<
"<member-template";
4858 write_access((*fn)->get_access_specifier(), o);
4859 write_cdtor_const_static((*fn)->is_constructor(),
4862 (*fn)->get_is_static(), o);
4864 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4865 get_indent_to_level(ctxt, indent, 2));
4866 do_indent(o, nb_ws);
4867 o <<
"</member-template>\n";
4870 for (member_class_templates::const_iterator cl =
4871 decl->get_member_class_templates().begin();
4872 cl != decl->get_member_class_templates().end();
4875 do_indent(o, nb_ws);
4876 o <<
"<member-template";
4877 write_access((*cl)->get_access_specifier(), o);
4878 write_cdtor_const_static(
false,
false,
false,
4879 (*cl)->get_is_static(), o);
4881 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4882 get_indent_to_level(ctxt, indent, 2));
4883 do_indent(o, nb_ws);
4884 o <<
"</member-template>\n";
4887 do_indent_to_level(ctxt, indent, 0);
4889 o <<
"</union-decl>\n";
4896write_union_decl(
const union_decl_sptr& decl,
4897 write_context& ctxt,
4899{
return write_union_decl(decl,
"", ctxt, indent);}
4911write_member_type_opening_tag(
const type_base_sptr& t,
4912 write_context& ctxt,
4915 ostream& o = ctxt.get_ostream();
4917 do_indent_to_level(ctxt, indent, 0);
4922 o <<
"<member-type";
4924 write_access(decl, o);
4943write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4948 ostream& o = ctxt.get_ostream();
4950 write_member_type_opening_tag(t, ctxt, indent);
4952 string id = ctxt.get_id_for_type(t);
4954 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4955 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4957 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4959 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4961 || write_ptr_to_mbr_type(dynamic_pointer_cast<ptr_to_mbr_type>(t),
4963 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4965 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4967 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4969 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4973 do_indent_to_level(ctxt, indent, 0);
4974 o <<
"</member-type>\n";
4990 write_context& ctxt,
4996 ostream &o = ctxt.get_ostream();
4997 do_indent_to_level(ctxt, indent, 0);
4999 string id_attr_name;
5000 if (ctxt.type_has_existing_id(decl))
5001 id_attr_name =
"type-id";
5003 id_attr_name =
"id";
5005 o <<
"<template-type-parameter "
5006 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
5010 o <<
" name='" << name <<
"'";
5012 write_location(decl, ctxt);
5016 ctxt.record_type_as_emitted(decl);
5031write_non_type_tparameter(
5032 const shared_ptr<non_type_tparameter> decl,
5033 write_context& ctxt,
unsigned indent)
5038 ostream &o = ctxt.get_ostream();
5039 do_indent_to_level(ctxt, indent, 0);
5041 o <<
"<template-non-type-parameter type-id='"
5042 << ctxt.get_id_for_type(decl->get_type())
5047 o <<
" name='" << name <<
"'";
5049 write_location(decl, ctxt);
5068 write_context& ctxt,
5074 ostream& o = ctxt.get_ostream();
5075 do_indent_to_level(ctxt, indent, 0);
5077 string id_attr_name =
"id";
5078 if (ctxt.type_has_existing_id(decl))
5079 id_attr_name =
"type-id";
5081 o <<
"<template-template-parameter " << id_attr_name <<
"='"
5082 << ctxt.get_id_for_type(decl) <<
"'";
5086 o <<
" name='" << name <<
"'";
5090 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
5091 for (list<shared_ptr<template_parameter> >::const_iterator p =
5092 decl->get_template_parameters().begin();
5093 p != decl->get_template_parameters().end();
5095 write_template_parameter(decl, ctxt, nb_spaces);
5097 do_indent_to_level(ctxt, indent, 0);
5098 o <<
"</template-template-parameter>\n";
5100 ctxt.record_type_as_emitted(decl);
5115write_type_composition
5116(
const shared_ptr<type_composition> decl,
5117 write_context& ctxt,
unsigned indent)
5122 ostream& o = ctxt.get_ostream();
5124 do_indent_to_level(ctxt, indent, 0);
5126 o <<
"<template-parameter-type-composition>\n";
5128 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
5129 (write_pointer_type_def
5130 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
5132 || write_reference_type_def
5133 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
5135 || write_array_type_def
5136 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
5138 || write_qualified_type_def
5139 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
5142 do_indent_to_level(ctxt, indent, 0);
5143 o <<
"</template-parameter-type-composition>\n";
5158write_template_parameter(
const shared_ptr<template_parameter> decl,
5159 write_context& ctxt,
unsigned indent)
5161 if ((!write_type_tparameter
5162 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
5163 && (!write_non_type_tparameter
5164 (dynamic_pointer_cast<non_type_tparameter>(decl),
5166 && (!write_template_tparameter
5167 (dynamic_pointer_cast<template_tparameter>(decl),
5169 && (!write_type_composition
5170 (dynamic_pointer_cast<type_composition>(decl),
5181write_template_parameters(
const shared_ptr<template_decl> tmpl,
5182 write_context& ctxt,
unsigned indent)
5187 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
5188 for (list<shared_ptr<template_parameter> >::const_iterator p =
5189 tmpl->get_template_parameters().begin();
5190 p != tmpl->get_template_parameters().end();
5192 write_template_parameter(*p, ctxt, nb_spaces);
5203write_function_tdecl(
const shared_ptr<function_tdecl> decl,
5204 write_context& ctxt,
unsigned indent)
5209 ostream& o = ctxt.get_ostream();
5211 do_indent_to_level(ctxt, indent, 0);
5213 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
5215 write_location(decl, ctxt);
5217 write_visibility(decl, o);
5219 write_binding(decl, o);
5223 write_template_parameters(decl, ctxt, indent);
5225 write_function_decl(decl->get_pattern(), ctxt,
5226 get_indent_to_level(ctxt, indent, 1));
5228 do_indent_to_level(ctxt, indent, 0);
5230 o <<
"</function-template-decl>\n";
5247write_class_tdecl(
const shared_ptr<class_tdecl> decl,
5248 write_context& ctxt,
unsigned indent)
5253 ostream& o = ctxt.get_ostream();
5255 do_indent_to_level(ctxt, indent, 0);
5257 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
5259 write_location(decl, ctxt);
5261 write_visibility(decl, o);
5265 write_template_parameters(decl, ctxt, indent);
5267 write_class_decl(decl->get_pattern(), ctxt,
5268 get_indent_to_level(ctxt, indent, 1));
5270 do_indent_to_level(ctxt, indent, 0);
5272 o <<
"</class-template-decl>\n";
5281write_version_info(write_context& ctxt)
5283 ostream& o = ctxt.get_ostream();
5284 const config& c = ctxt.get_config();
5287 << c.get_format_major_version_number()
5288 <<
"." << c.get_format_minor_version_number()
5308 const corpus_sptr&
corpus,
5310 bool member_of_group)
5318 do_indent_to_level(ctxt, indent, 0);
5320 std::ostream& out = ctxt.get_ostream();
5321 const config &conf = ctxt.get_config();
5323 out <<
"<abi-corpus ";
5325 write_version_info(ctxt);
5330 if (!ctxt.get_write_corpus_path())
5332 if (member_of_group)
5335 corpus_path.clear();
5339 if (ctxt.get_short_locs())
5342 if (!corpus_path.empty())
5346 && ctxt.get_write_architecture())
5352 write_tracking_non_reachable_types(
corpus, out);
5360 do_indent_to_level(ctxt, indent, 1);
5361 out <<
"<elf-needed>\n";
5363 get_indent_to_level(ctxt, indent, 2));
5364 do_indent_to_level(ctxt, indent, 1);
5365 out <<
"</elf-needed>\n";
5371 do_indent_to_level(ctxt, indent, 1);
5372 out <<
"<elf-function-symbols>\n";
5375 get_indent_to_level(ctxt, indent, 2));
5377 do_indent_to_level(ctxt, indent, 1);
5378 out <<
"</elf-function-symbols>\n";
5384 do_indent_to_level(ctxt, indent, 1);
5385 out <<
"<elf-variable-symbols>\n";
5388 get_indent_to_level(ctxt, indent, 2));
5390 do_indent_to_level(ctxt, indent, 1);
5391 out <<
"</elf-variable-symbols>\n";
5395 if (ctxt.get_write_undefined_symbols()
5398 do_indent_to_level(ctxt, indent, 1);
5399 out <<
"<undefined-elf-function-symbols>\n";
5402 get_indent_to_level(ctxt, indent, 2));
5404 do_indent_to_level(ctxt, indent, 1);
5405 out <<
"</undefined-elf-function-symbols>\n";
5410 if (ctxt.get_write_undefined_symbols()
5413 do_indent_to_level(ctxt, indent, 1);
5414 out <<
"<undefined-elf-variable-symbols>\n";
5417 get_indent_to_level(ctxt, indent, 2));
5419 do_indent_to_level(ctxt, indent, 1);
5420 out <<
"</undefined-elf-variable-symbols>\n";
5430 do_indent_to_level(ctxt, indent, 0);
5431 out <<
"</abi-corpus>\n";
5433 ctxt.clear_referenced_types();
5434 ctxt.record_corpus_as_emitted(
corpus);
5451 const corpus_group_sptr& group,
5458 do_indent_to_level(ctxt, indent, 0);
5460std::ostream& out = ctxt.get_ostream();
5462 out <<
"<abi-corpus-group ";
5463 write_version_info(ctxt);
5465 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
5468 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
5469 out <<
" architecture='" << group->get_architecture_name()<<
"'";
5471 write_tracking_non_reachable_types(group, out);
5473 if (group->is_empty())
5482 for (corpus_group::corpora_type::const_iterator c =
5483 group->get_corpora().begin();
5484 c != group->get_corpora().end();
5488 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
5491 do_indent_to_level(ctxt, indent, 0);
5492 out <<
"</abi-corpus-group>\n";