23 #include <unordered_map>
28 #include "abg-internal.h"
30 ABG_BEGIN_EXPORT_DECLARATIONS
41 ABG_END_EXPORT_DECLARATIONS
47 using std::shared_ptr;
48 using std::dynamic_pointer_cast;
49 using std::static_pointer_cast;
52 using std::ostringstream;
56 using 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());
114 struct non_canonicalized_type_hash
133 return h(p->get_pretty_representation(
false,
149 struct non_canonicalized_type_equal
175 typedef std::unordered_set<const type_base*> type_ptr_set_type;
181 typedef 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>
198 typedef unordered_map<shared_ptr<function_tdecl>,
202 typedef 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_undefined_symbols;
218 bool m_write_parameter_names;
220 bool m_write_default_sizes;
224 mutable unordered_set<uint32_t> m_used_type_id_hashes;
225 mutable type_ptr_set_type m_emitted_type_set;
228 type_ptr_set_type m_referenced_types_set;
230 fn_tmpl_shared_ptr_map m_fn_tmpl_id_map;
231 class_tmpl_shared_ptr_map m_class_tmpl_id_map;
234 unordered_set<interned_string, hash_interned_string> m_emitted_decls_set;
235 unordered_set<string> m_emitted_corpora_set;
252 m_write_architecture(
true),
253 m_write_corpus_path(
true),
254 m_write_comp_dir(
true),
255 m_write_elf_needed(
true),
256 m_write_undefined_symbols(
true),
257 m_write_parameter_names(
true),
259 m_write_default_sizes(
true),
260 m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
267 get_environment()
const
272 {
return get_environment().get_config();}
306 get_write_architecture()
307 {
return m_write_architecture;}
314 {m_write_architecture = f;}
320 get_write_elf_needed()
321 {
return m_write_elf_needed;}
328 {m_write_elf_needed = f;}
334 get_write_undefined_symbols()
const
335 {
return m_write_undefined_symbols;}
342 {m_write_undefined_symbols = f;}
348 get_write_default_sizes()
349 {
return m_write_default_sizes;}
356 {m_write_default_sizes = f;}
362 get_write_corpus_path()
363 {
return m_write_corpus_path;}
370 {m_write_corpus_path = f;}
377 {
return m_write_comp_dir;}
384 {m_write_comp_dir = f;}
391 {
return m_short_locs;}
404 get_write_parameter_names()
const
405 {
return m_write_parameter_names;}
412 {m_write_parameter_names = f;}
421 get_show_locs()
const
422 {
return m_show_locs;}
440 get_type_id_style()
const
441 {
return m_type_id_style;}
450 {m_type_id_style =
style;}
457 get_id_manager()
const
458 {
return m_id_manager;}
462 {
return m_id_manager;}
466 type_has_existing_id(type_base_sptr type)
const
467 {
return type_has_existing_id(type.get());}
471 type_has_existing_id(
type_base* type)
const
474 return m_type_id_map.find(type) != m_type_id_map.end();
482 get_id_for_type(
const type_base_sptr& t)
483 {
return get_id_for_type(t.get());}
494 auto it = m_type_id_map.find(c);
495 if (it != m_type_id_map.end())
498 switch (m_type_id_style)
500 case SEQUENCE_TYPE_ID_STYLE:
503 return m_type_id_map[c] = id;
505 case HASH_TYPE_ID_STYLE:
509 while (!m_used_type_id_hashes.insert(hash).second)
511 std::ostringstream os;
512 os << std::hex << std::setfill(
'0') << std::setw(8) << hash;
523 fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
524 if (it == m_fn_tmpl_id_map.end())
526 string id = get_id_manager().get_id_with_prefix(
"fn-tmpl-id-");
527 m_fn_tmpl_id_map[f] = id;
530 return m_fn_tmpl_id_map[f];
536 class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
537 if (it == m_class_tmpl_id_map.end())
539 string id = get_id_manager().get_id_with_prefix(
"class-tmpl-id-");
540 m_class_tmpl_id_map[c] = id;
543 return m_class_tmpl_id_map[c];
549 m_type_id_map.clear();
560 const type_ptr_set_type&
561 get_referenced_types()
const
562 {
return m_referenced_types_set;}
569 get_referenced_function_types()
const
570 {
return m_referenced_fn_types_set;}
576 has_non_emitted_referenced_types()
const
578 for (
const auto t : get_referenced_types())
579 if (!type_is_emitted(t))
591 record_type_as_referenced(
const type_base_sptr& type)
597 m_referenced_fn_types_set.insert(f);
599 m_referenced_types_set.insert(t);
610 type_is_referenced(
const type_base_sptr& type)
614 return (m_referenced_fn_types_set.find(f)
615 != m_referenced_fn_types_set.end());
617 return m_referenced_types_set.find(t) != m_referenced_types_set.end();
676 type_ptr_map::const_iterator i =
680 i = map->find(
const_cast<type_base*
>(r));
703 operator()(
const type_base_sptr& l,
const type_base_sptr& r)
const
704 {
return operator()(l.get(), r.get());}
718 vector<type_base*>& sorted)
721 for (type_ptr_set_type::const_iterator i = types.begin();
724 sorted.push_back(
const_cast<type_base*
>(*i));
725 type_ptr_cmp comp(&m_type_id_map);
726 sort(sorted.begin(), sorted.end(), comp);
740 vector<type_base_sptr> &sorted)
742 for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
745 sorted.push_back(type_base_sptr(i->second));
746 type_ptr_cmp comp(&m_type_id_map);
747 sort(sorted.begin(), sorted.end(), comp);
761 sort_types(
const vector<function_type_sptr>& types,
762 vector<type_base_sptr> &sorted)
764 for (vector<function_type_sptr>::const_iterator i = types.begin();
767 sorted.push_back(*i);
768 type_ptr_cmp comp(&m_type_id_map);
769 sort(sorted.begin(), sorted.end(), comp);
776 record_type_as_emitted(
const type_base_sptr &t)
777 {record_type_as_emitted(t.get());}
783 record_type_as_emitted(
const type_base* t)
786 m_emitted_type_set.insert(c);
796 type_is_emitted(
const type_base* t)
const
799 return (m_emitted_type_set.find(c) != m_emitted_type_set.end());
809 type_is_emitted(
const type_base_sptr& t)
const
810 {
return type_is_emitted(t.get());}
819 decl_is_emitted(
const decl_base& decl)
const
823 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
833 decl_is_emitted(
const decl_base_sptr& decl)
const
838 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
845 record_decl_as_emitted(
const decl_base_sptr& decl)
849 m_emitted_decls_set.insert(irepr);
861 corpus_is_emitted(
const corpus_sptr& corp)
866 if (m_emitted_corpora_set.find(corp->get_path())
867 == m_emitted_corpora_set.end())
877 record_corpus_as_emitted(
const corpus_sptr& corp)
882 const string& path = corp->get_path();
885 m_emitted_corpora_set.insert(path);
891 const type_ptr_set_type&
892 get_emitted_types_set()
const
893 {
return m_emitted_type_set;}
898 clear_referenced_types()
900 m_referenced_types_set.clear();
901 m_referenced_fn_types_set.clear();
905 get_fun_symbol_map()
const
906 {
return m_fun_symbol_map;}
910 {
return m_fun_symbol_map;}
914 static void write_location(
const location&, write_context&);
915 static void write_location(
const decl_base_sptr&, write_context&);
916 static bool write_visibility(
const decl_base_sptr&, ostream&);
917 static bool write_binding(
const decl_base_sptr&, ostream&);
918 static bool write_is_artificial(
const decl_base_sptr&, ostream&);
919 static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
920 static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
923 static void write_size_and_alignment(
const type_base_sptr, ostream&,
924 size_t default_size = 0,
925 size_t default_alignment = 0);
929 static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
933 static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
934 static bool write_elf_symbol_reference(write_context&,
938 static bool write_elf_symbol_reference(write_context&,
942 static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
944 static void write_is_anonymous(
const decl_base_sptr&, ostream&);
945 static void write_naming_typedef(
const decl_base_sptr&, write_context&);
946 static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
947 static void write_decl_in_scope(
const decl_base_sptr&,
948 write_context&,
unsigned);
949 static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
951 write_context&,
unsigned);
952 static bool write_qualified_type_def(
const qualified_type_def_sptr&,
953 write_context&,
unsigned);
955 write_context&,
unsigned);
957 write_context&,
unsigned);
959 write_context&,
unsigned);
961 write_context&,
unsigned);
966 write_context&,
unsigned);
968 write_context&,
unsigned);
970 write_context&,
unsigned);
971 static bool write_elf_symbols_table(
const elf_symbols&,
972 write_context&,
unsigned);
974 write_context&,
bool,
unsigned);
976 write_context&,
bool,
unsigned);
978 write_context&,
unsigned);
979 static bool write_member_type_opening_tag(
const type_base_sptr&,
980 write_context&,
unsigned);
981 static bool write_member_type(
const type_base_sptr&,
982 write_context&,
unsigned);
983 static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
984 write_context&,
unsigned,
bool);
986 write_context&,
unsigned);
987 static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
988 write_context&,
unsigned,
bool);
989 static bool write_union_decl(
const union_decl_sptr&,
const string&,
990 write_context&,
unsigned);
991 static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
992 static bool write_type_tparameter
993 (
const shared_ptr<type_tparameter>, write_context&,
unsigned);
994 static bool write_non_type_tparameter
995 (
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
996 static bool write_template_tparameter
997 (
const shared_ptr<template_tparameter>, write_context&,
unsigned);
998 static bool write_type_composition
999 (
const shared_ptr<type_composition>, write_context&,
unsigned);
1000 static bool write_template_parameter(
const shared_ptr<template_parameter>,
1001 write_context&,
unsigned);
1002 static void write_template_parameters(
const shared_ptr<template_decl>,
1003 write_context&,
unsigned);
1004 static bool write_function_tdecl
1005 (
const shared_ptr<function_tdecl>,
1006 write_context&,
unsigned);
1007 static bool write_class_tdecl
1008 (
const shared_ptr<class_tdecl>,
1009 write_context&,
unsigned);
1010 static void do_indent(ostream&,
unsigned);
1011 static void do_indent_to_level(write_context&,
unsigned,
unsigned);
1012 static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
1016 do_indent(ostream& o,
unsigned nb_whitespaces)
1018 for (
unsigned i = 0; i < nb_whitespaces; ++i)
1030 do_indent_to_level(write_context& ctxt,
1031 unsigned initial_indent,
1034 do_indent(ctxt.get_ostream(),
1035 get_indent_to_level(ctxt, initial_indent, level));
1047 get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
1050 int nb_ws = initial_indent +
1051 level * ctxt.get_config().get_xml_element_indent();
1071 template <
typename T>
1073 annotate(
const T& decl,
1074 write_context& ctxt,
1080 if (!ctxt.get_annotate())
1083 ostream& o = ctxt.get_ostream();
1085 do_indent(o, indent);
1107 write_context& ctxt,
1113 if (!ctxt.get_annotate())
1116 ostream& o = ctxt.get_ostream();
1118 do_indent(o, indent);
1138 write_context& ctxt,
1144 if (!ctxt.get_annotate())
1147 ostream& o = ctxt.get_ostream();
1149 do_indent(o, indent);
1151 o <<
"<!-- typedef "
1174 write_context& ctxt,
1180 if (!ctxt.get_annotate())
1183 ostream& o = ctxt.get_ostream();
1185 do_indent(o, indent);
1190 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
1219 write_context& ctxt,
1225 if (!ctxt.get_annotate())
1228 ostream& o = ctxt.get_ostream();
1230 do_indent(o, indent);
1242 vector<function_decl::parameter_sptr>::const_iterator pi =
1243 fn->get_first_non_implicit_parm();
1245 for (; pi != fn->get_parameters().end(); ++pi)
1249 if (distance(pi, fn->get_parameters().end()) > 1)
1269 write_context& ctxt,
1275 if (!ctxt.get_annotate())
1278 ostream &o = ctxt.get_ostream();
1280 do_indent(o, indent);
1284 if (parm->get_variadic_marker())
1285 o <<
"variadic parameter";
1288 if (parm->get_is_artificial())
1290 if (parm->get_index() == 0)
1295 o <<
"parameter of type '"
1314 write_location(
const location& loc, write_context& ctxt)
1319 if (!ctxt.get_show_locs())
1323 unsigned line = 0, column = 0;
1325 loc.
expand(filepath, line, column);
1327 ostream &o = ctxt.get_ostream();
1329 if (ctxt.get_short_locs())
1333 <<
" line='" << line <<
"'"
1334 <<
" column='" << column <<
"'";
1345 write_location(
const decl_base_sptr& decl,
1346 write_context& ctxt)
1351 location loc = decl->get_location();
1355 write_location(loc, ctxt);
1367 write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1377 case decl_base::VISIBILITY_NONE:
1379 case decl_base::VISIBILITY_DEFAULT:
1382 case decl_base::VISIBILITY_PROTECTED:
1385 case decl_base::VISIBILITY_HIDDEN:
1388 case decl_base::VISIBILITY_INTERNAL:
1396 o <<
" visibility='" << str <<
"'";
1407 write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1414 shared_ptr<var_decl> var =
1415 dynamic_pointer_cast<var_decl>(decl);
1417 bind = var->get_binding();
1420 shared_ptr<function_decl> fun =
1421 dynamic_pointer_cast<function_decl>(decl);
1423 bind = fun->get_binding();
1429 case decl_base::BINDING_NONE:
1431 case decl_base::BINDING_LOCAL:
1434 case decl_base::BINDING_GLOBAL:
1437 case decl_base::BINDING_WEAK:
1443 o <<
" binding='" << str <<
"'";
1457 write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1462 if (decl->get_is_artificial())
1463 o <<
" is-artificial='yes'";
1477 write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1482 corpus* c = t->get_corpus();
1486 if (!c->recording_types_reachable_from_public_interface_supported()
1487 || c->type_is_reachable_from_public_interfaces(*t))
1490 o <<
" is-non-reachable='yes'";
1503 write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1506 corpus_group* group = corpus->get_group();
1508 if (corpus->recording_types_reachable_from_public_interface_supported())
1510 o <<
" tracking-non-reachable-types='yes'";
1531 write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1532 size_t default_size,
size_t default_alignment)
1534 size_t size_in_bits = decl->get_size_in_bits();
1535 if (size_in_bits != default_size)
1536 o <<
" size-in-bits='" << size_in_bits <<
"'";
1538 size_t alignment_in_bits = decl->get_alignment_in_bits();
1539 if (alignment_in_bits != default_alignment)
1540 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1548 write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1550 if (decl->is_non_finite())
1551 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1553 size_t size_in_bits = decl->get_size_in_bits();
1555 o <<
" size-in-bits='" << size_in_bits <<
"'";
1558 size_t alignment_in_bits = decl->get_alignment_in_bits();
1559 if (alignment_in_bits)
1560 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1570 string access_str =
"private";
1574 case private_access:
1575 access_str =
"private";
1578 case protected_access:
1579 access_str =
"protected";
1583 access_str =
"public";
1590 o <<
" access='" << access_str <<
"'";
1601 o <<
" layout-offset-in-bits='"
1608 write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1613 if (base->get_offset_in_bits() >= 0)
1614 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1623 write_access(decl_base_sptr member, ostream& o)
1640 o <<
" vtable-offset='" << voffset <<
"'";
1657 case elf_symbol::NOTYPE_TYPE:
1660 case elf_symbol::OBJECT_TYPE:
1661 repr =
"object-type";
1663 case elf_symbol::FUNC_TYPE:
1666 case elf_symbol::SECTION_TYPE:
1667 repr =
"section-type";
1669 case elf_symbol::FILE_TYPE:
1672 case elf_symbol::COMMON_TYPE:
1673 repr =
"common-type";
1675 case elf_symbol::TLS_TYPE:
1678 case elf_symbol::GNU_IFUNC_TYPE:
1679 repr =
"gnu-ifunc-type";
1686 o <<
" type='" << repr <<
"'";
1702 case elf_symbol::LOCAL_BINDING:
1703 repr =
"local-binding";
1705 case elf_symbol::GLOBAL_BINDING:
1706 repr =
"global-binding";
1708 case elf_symbol::WEAK_BINDING:
1709 repr =
"weak-binding";
1711 case elf_symbol::GNU_UNIQUE_BINDING:
1712 repr =
"gnu-unique-binding";
1715 repr =
"no-binding";
1719 o <<
" binding='" << repr <<
"'";
1735 case elf_symbol::DEFAULT_VISIBILITY:
1736 repr =
"default-visibility";
1738 case elf_symbol::PROTECTED_VISIBILITY:
1739 repr =
"protected-visibility";
1741 case elf_symbol::HIDDEN_VISIBILITY:
1742 repr =
"hidden-visibility";
1744 case elf_symbol::INTERNAL_VISIBILITY:
1745 repr =
"internal-visibility";
1748 repr =
"default-visibility";
1752 o <<
" visibility='" << repr <<
"'";
1763 write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1765 if (!sym.is_main_symbol() || !sym.has_aliases())
1769 std::vector<std::string> aliases;
1770 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1771 s = s->get_next_alias())
1773 if (!s->is_public())
1776 if (s->is_suppressed())
1779 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1782 aliases.push_back(s->get_id_string());
1785 if (!aliases.empty())
1788 std::string separator;
1789 for (
const auto& alias : aliases)
1791 out << separator << alias;
1818 write_elf_symbol_reference(write_context& ctxt,
1819 const elf_symbol& sym,
1825 s = abi.lookup_variable_symbol(sym);
1831 || (!ctxt.get_write_undefined_symbols() && !s->is_defined()))
1835 const elf_symbol* main = sym.get_main_symbol().get();
1836 const elf_symbol* alias = &sym;
1837 bool found = !alias->is_suppressed();
1842 found = !alias->is_suppressed();
1847 alias = alias->get_next_alias().get();
1849 if (!alias || alias == main)
1851 found = !alias->is_suppressed();
1856 o <<
" elf-symbol-id='"
1877 write_elf_symbol_reference(write_context& ctxt,
1885 return write_elf_symbol_reference(ctxt, *sym, abi, o);
1902 write_cdtor_const_static(
bool is_ctor,
1909 o <<
" static='yes'";
1911 o <<
" constructor='yes'";
1913 o <<
" destructor='yes'";
1915 o <<
" const='yes'";
1925 write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
1927 if (d->get_is_declaration_only())
1928 o <<
" is-declaration-only='yes'";
1940 if (klass->is_struct())
1941 o <<
" is-struct='yes'";
1951 write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1953 if (decl->get_is_anonymous())
1954 o <<
" is-anonymous='yes'";
1964 write_naming_typedef(
const decl_base_sptr& decl, write_context& ctxt)
1969 ostream &o = ctxt.get_ostream();
1973 string id = ctxt.get_id_for_type(typedef_type);
1974 o <<
" naming-typedef-id='" <<
id <<
"'";
1975 ctxt.record_type_as_referenced(typedef_type);
1989 write_type(
const type_base_sptr& type, write_context& ctxt,
unsigned indent)
1991 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
1993 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1996 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
1998 || write_reference_type_def(dynamic_pointer_cast
1999 <reference_type_def>(type), ctxt, indent)
2000 || write_ptr_to_mbr_type(dynamic_pointer_cast
2001 <ptr_to_mbr_type>(type),
2003 || write_array_type_def(dynamic_pointer_cast
2004 <array_type_def>(type), ctxt, indent)
2005 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
2007 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
2011 || (write_function_tdecl
2012 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
2013 || (write_class_tdecl
2014 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
2032 write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
2034 if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
2036 || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
2038 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
2041 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
2043 || write_reference_type_def(dynamic_pointer_cast
2044 <reference_type_def>(decl), ctxt, indent)
2045 || write_ptr_to_mbr_type(dynamic_pointer_cast
2046 <ptr_to_mbr_type>(decl),
2048 || write_array_type_def(dynamic_pointer_cast
2049 <array_type_def>(decl), ctxt, indent)
2050 || write_array_subrange_type(dynamic_pointer_cast
2051 <array_type_def::subrange_type>(decl),
2053 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
2055 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
2057 || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
2059 || write_function_decl(dynamic_pointer_cast<method_decl>
2062 || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
2063 ctxt,
false, indent)
2066 || (write_function_tdecl
2067 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
2068 || (write_class_tdecl
2069 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
2087 write_decl_in_scope(
const decl_base_sptr& decl,
2088 write_context& ctxt,
2089 unsigned initial_indent)
2091 type_base_sptr type =
is_type(decl);
2094 if (ctxt.type_is_emitted(type))
2097 list<scope_decl*> scopes;
2098 for (scope_decl* s = decl->get_scope();
2101 scopes.push_front(s);
2103 ostream& o = ctxt.get_ostream();
2104 const config& c = ctxt.get_config();
2105 stack<string> closing_tags;
2106 stack<unsigned> closing_indents;
2107 unsigned indent = initial_indent;
2108 for (list<scope_decl*>::const_iterator i = scopes.begin();
2117 do_indent(o, indent);
2118 o <<
"<namespace-decl name='"
2121 closing_tags.push(
"</namespace-decl>");
2122 closing_indents.push(indent);
2129 if (!ctxt.type_is_emitted(c))
2131 write_type(class_type, ctxt, initial_indent);
2136 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2138 closing_tags.push(
"</class-decl>");
2139 closing_indents.push(indent);
2141 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2142 write_member_type_opening_tag(type, ctxt, nb_ws);
2144 closing_tags.push(
"</member-type>");
2145 closing_indents.push(nb_ws);
2151 union_decl_sptr union_type(u, noop_deleter());
2152 if (!ctxt.type_is_emitted(u))
2154 write_type(union_type, ctxt, initial_indent);
2159 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2161 closing_tags.push(
"</union-decl>");
2162 closing_indents.push(indent);
2164 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2165 write_member_type_opening_tag(type, ctxt, nb_ws);
2167 closing_tags.push(
"</member-type>");
2168 closing_indents.push(nb_ws);
2174 indent += c.get_xml_element_indent();
2177 bool do_write =
false;
2178 if (type_base_sptr type =
is_type(decl))
2180 if (!ctxt.type_is_emitted(type))
2185 if (!ctxt.decl_is_emitted(decl))
2190 write_decl(decl, ctxt, indent);
2192 while (!closing_tags.empty())
2194 do_indent(o, closing_indents.top());
2195 o << closing_tags.top() <<
"\n";
2197 closing_indents.pop();
2211 ostream& default_output_stream)
2228 {ctxt.set_show_locs(flag);}
2240 {ctxt.set_annotate(flag);}
2251 {ctxt.set_ostream(os);}
2263 {ctxt.set_write_architecture(flag);}
2275 {ctxt.set_write_corpus_path(flag);}
2287 {ctxt.set_write_comp_dir(flag);}
2299 {ctxt.set_short_locs(flag);}
2311 {ctxt.set_write_parameter_names(flag);}
2323 {ctxt.set_write_elf_needed(flag);}
2335 {ctxt.set_write_undefined_symbols(flag);}
2350 {ctxt.set_write_default_sizes(flag);}
2361 {ctxt.set_type_id_style(
style);}
2376 write_canonical_types_of_scope(
const scope_decl &scope,
2377 write_context &ctxt,
2378 const unsigned indent,
2384 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2385 i != canonical_types.end();
2388 if (ctxt.type_is_emitted(*i))
2391 write_member_type(*i, ctxt, indent);
2393 write_type(*i, ctxt, indent);
2415 referenced_type_should_be_emitted(
const type_base *t,
2416 const write_context& ctxt,
2417 const translation_unit& tu,
2420 if ((tu_is_last || (t->get_translation_unit()
2421 && (t->get_translation_unit()->get_absolute_path()
2422 == tu.get_absolute_path())))
2423 && !ctxt.type_is_emitted(t))
2440 write_referenced_types(write_context & ctxt,
2441 const translation_unit& tu,
2442 const unsigned indent,
2445 const config& c = ctxt.get_config();
2453 type_ptr_set_type referenced_types_to_emit;
2458 for (type_ptr_set_type::const_iterator i =
2459 ctxt.get_referenced_types().begin();
2460 i != ctxt.get_referenced_types().end();
2462 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2463 referenced_types_to_emit.insert(*i);
2465 for (fn_type_ptr_set_type::const_iterator i =
2466 ctxt.get_referenced_function_types().begin();
2467 i != ctxt.get_referenced_function_types().end();
2469 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2470 referenced_types_to_emit.insert(*i);
2473 while (!referenced_types_to_emit.empty())
2478 vector<type_base*> sorted_referenced_types;
2479 ctxt.sort_types(referenced_types_to_emit,
2480 sorted_referenced_types);
2483 for (vector<type_base*>::const_iterator i =
2484 sorted_referenced_types.begin();
2485 i != sorted_referenced_types.end();
2491 if (!ctxt.type_is_emitted(t))
2495 decl_base_sptr decl(d, noop_deleter());
2496 write_decl_in_scope(decl, ctxt,
2497 indent + c.get_xml_element_indent());
2502 write_function_type(fn_type, ctxt,
2503 indent + c.get_xml_element_indent());
2512 referenced_types_to_emit.clear();
2524 for (type_ptr_set_type::const_iterator i =
2525 ctxt.get_referenced_types().begin();
2526 i != ctxt.get_referenced_types().end();
2528 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2529 referenced_types_to_emit.insert(*i);
2557 const unsigned indent,
2565 && ctxt.has_non_emitted_referenced_types())
2568 ostream& o = ctxt.get_ostream();
2569 const config& c = ctxt.get_config();
2571 do_indent(o, indent);
2578 std::string tu_path = tu.
get_path();
2579 if (ctxt.get_short_locs())
2581 if (!tu_path.empty())
2585 o <<
" comp-dir-path='"
2588 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
2602 ctxt, indent + c.get_xml_element_indent());
2605 const declarations& decls = tu.
get_global_scope()->get_sorted_member_decls();
2607 for (
const decl_base_sptr& decl : decls)
2609 if (type_base_sptr t =
is_type(decl))
2616 if (class_type->get_is_declaration_only()
2617 && !ctxt.type_is_emitted(class_type))
2618 write_type(class_type, ctxt,
2619 indent + c.get_xml_element_indent());
2622 write_type(t, ctxt, indent + c.get_xml_element_indent());
2626 if (!ctxt.decl_is_emitted(decl))
2627 write_decl(decl, ctxt, indent + c.get_xml_element_indent());
2634 for (
auto undefined_function : abi->get_sorted_undefined_functions())
2638 if (f->get_translation_unit() != &tu || ctxt.decl_is_emitted(f))
2641 write_decl(f, ctxt, indent + c.get_xml_element_indent());
2647 for (
auto undefined_var : abi->get_sorted_undefined_variables())
2651 if (v->get_translation_unit() != &tu || ctxt.decl_is_emitted(v))
2654 write_decl(v, ctxt, indent + c.get_xml_element_indent());
2657 write_referenced_types(ctxt, tu, indent, is_last);
2662 vector<type_base_sptr> sorted_types;
2663 ctxt.sort_types(t, sorted_types);
2665 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
2666 i != sorted_types.end();
2671 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
2678 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
2683 write_referenced_types(ctxt, tu, indent, is_last);
2685 do_indent(o, indent);
2686 o <<
"</abi-instr>\n";
2704 write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
2709 ostream& o = ctxt.get_ostream();
2711 annotate(d, ctxt, indent);
2713 do_indent(o, indent);
2717 write_is_anonymous(d, o);
2719 write_size_and_alignment(d, o);
2721 write_is_declaration_only(d, o);
2723 write_location(d, ctxt);
2725 o <<
" id='" << ctxt.get_id_for_type(d) <<
"'" <<
"/>\n";
2727 ctxt.record_type_as_emitted(d);
2745 write_context& ctxt,
unsigned indent)
2747 if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
2750 ostream& o = ctxt.get_ostream();
2751 const config &c = ctxt.get_config();
2753 annotate(decl, ctxt, indent);
2755 do_indent(o, indent);
2757 o <<
"<namespace-decl name='"
2762 typedef declarations::const_iterator const_iterator;
2763 const declarations& d = decl->get_sorted_member_decls();
2765 write_canonical_types_of_scope(*decl, ctxt,
2766 indent + c.get_xml_element_indent());
2768 for (const_iterator i = d.begin(); i != d.end(); ++i)
2770 if (type_base_sptr t =
is_type(*i))
2771 if (ctxt.type_is_emitted(t))
2775 write_decl(*i, ctxt, indent + c.get_xml_element_indent());
2778 do_indent(o, indent);
2779 o <<
"</namespace-decl>\n";
2803 write_qualified_type_def(
const qualified_type_def_sptr& decl,
2805 write_context& ctxt,
2811 ostream& o = ctxt.get_ostream();
2814 type_base_sptr underlying_type = decl->get_underlying_type();
2816 annotate(decl, ctxt, indent);
2818 do_indent(o, indent);
2819 o <<
"<qualified-type-def type-id='"
2820 << ctxt.get_id_for_type(underlying_type)
2823 ctxt.record_type_as_referenced(underlying_type);
2825 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
2826 o <<
" const='yes'";
2827 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
2828 o <<
" volatile='yes'";
2829 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
2830 o <<
" restrict='yes'";
2832 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2836 i = ctxt.get_id_for_type(decl);
2838 o <<
" id='" << i <<
"'/>\n";
2840 ctxt.record_type_as_emitted(decl);
2856 write_qualified_type_def(
const qualified_type_def_sptr& decl,
2857 write_context& ctxt,
2859 {
return write_qualified_type_def(decl,
"", ctxt, indent);}
2881 write_context& ctxt,
2887 ostream& o = ctxt.get_ostream();
2889 annotate(decl, ctxt, indent);
2891 do_indent(o, indent);
2895 o <<
"<pointer-type-def ";
2897 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2899 i = ctxt.get_id_for_type(pointed_to_type);
2901 o <<
"type-id='" << i <<
"'";
2903 ctxt.record_type_as_referenced(pointed_to_type);
2905 write_size_and_alignment(decl, o,
2906 (ctxt.get_write_default_sizes()
2908 : decl->get_translation_unit()->get_address_size()),
2913 i = ctxt.get_id_for_type(decl);
2915 o <<
" id='" << i <<
"'";
2917 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2920 ctxt.record_type_as_emitted(decl);
2936 write_context& ctxt,
2938 {
return write_pointer_type_def(decl,
"", ctxt, indent);}
2960 write_context& ctxt,
2966 annotate(decl->get_canonical_type(), ctxt, indent);
2968 ostream& o = ctxt.get_ostream();
2970 do_indent(o, indent);
2972 o <<
"<reference-type-def kind='";
2973 if (decl->is_lvalue())
2979 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2980 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
2982 ctxt.record_type_as_referenced(pointed_to_type);
2985 ctxt.record_type_as_referenced(f);
2987 write_size_and_alignment(decl, o,
2988 (ctxt.get_write_default_sizes()
2990 : decl->get_translation_unit()->get_address_size()),
2995 i = ctxt.get_id_for_type(decl);
2996 o <<
" id='" << i <<
"'";
2998 write_location(static_pointer_cast<decl_base>(decl), ctxt);
3002 ctxt.record_type_as_emitted(decl);
3018 write_context& ctxt,
3020 {
return write_reference_type_def(decl,
"", ctxt, indent);}
3036 const string&
id, write_context& ctxt,
3042 annotate(decl->get_canonical_type(), ctxt, indent);
3044 ostream& o = ctxt.get_ostream();
3046 do_indent(o, indent);
3048 o <<
"<pointer-to-member-type";
3050 write_size_and_alignment(decl, o,
3051 (ctxt.get_write_default_sizes()
3053 : decl->get_translation_unit()->get_address_size()),
3056 write_location(static_pointer_cast<decl_base>(decl), ctxt);
3058 type_base_sptr member_type = decl->get_member_type();
3059 string i = ctxt.get_id_for_type(member_type);
3060 o <<
" member-type-id='" << i <<
"'";
3061 ctxt.record_type_as_referenced(member_type);
3063 type_base_sptr containing_type = decl->get_containing_type();
3064 i = ctxt.get_id_for_type(containing_type);
3065 o <<
" containing-type-id='" << i <<
"'";
3066 ctxt.record_type_as_referenced(containing_type);
3070 i = ctxt.get_id_for_type(decl);
3071 o <<
" id ='" << i <<
"'";
3075 ctxt.record_type_as_emitted(decl);
3091 write_context& ctxt,
unsigned indent)
3092 {
return write_ptr_to_mbr_type(decl,
"", ctxt, indent);}
3105 write_context& ctxt,
3111 annotate(decl, ctxt, indent);
3113 ostream& o = ctxt.get_ostream();
3115 do_indent(o, indent);
3119 if (!decl->get_name().empty())
3120 o <<
" name='" << decl->get_name() <<
"'";
3123 if (decl->is_non_finite())
3126 o << decl->get_length();
3131 || decl->get_length() == 0
3132 || (decl->get_length() ==
3133 (uint64_t) (decl->get_upper_bound()
3134 - decl->get_lower_bound() + 1)));
3135 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
3136 << decl->get_upper_bound() <<
"'";
3138 type_base_sptr underlying_type = decl->get_underlying_type();
3139 if (underlying_type)
3142 << ctxt.get_id_for_type(underlying_type)
3144 ctxt.record_type_as_referenced(underlying_type);
3147 o <<
" id='" << ctxt.get_id_for_type(decl) <<
"'";
3149 write_location(decl->get_location(), ctxt);
3153 ctxt.record_type_as_emitted(decl);
3178 write_context& ctxt,
3184 annotate(decl, ctxt, indent);
3186 ostream& o = ctxt.get_ostream();
3188 do_indent(o, indent);
3189 o <<
"<array-type-def";
3191 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
3193 type_base_sptr element_type = decl->get_element_type();
3194 o <<
" type-id='" << ctxt.get_id_for_type(element_type) <<
"'";
3196 ctxt.record_type_as_referenced(element_type);
3198 write_array_size_and_alignment(decl, o);
3202 i = ctxt.get_id_for_type(decl);
3203 o <<
" id='" << i <<
"'";
3205 write_location(static_pointer_cast<decl_base>(decl), ctxt);
3207 if (!decl->get_dimension_count())
3213 vector<array_type_def::subrange_sptr>::const_iterator si;
3215 for (si = decl->get_subranges().begin();
3216 si != decl->get_subranges().end(); ++si)
3218 unsigned local_indent =
3219 indent + ctxt.get_config().get_xml_element_indent();
3220 write_array_subrange_type(*si, ctxt, local_indent);
3223 do_indent(o, indent);
3224 o <<
"</array-type-def>\n";
3227 ctxt.record_type_as_emitted(decl);
3243 write_context& ctxt,
3245 {
return write_array_type_def(decl,
"", ctxt, indent);}
3267 write_context& ctxt,
3275 annotate(decl->get_canonical_type(), ctxt, indent);
3277 ostream& o = ctxt.get_ostream();
3279 do_indent(o, indent);
3282 write_is_anonymous(decl, o);
3283 write_naming_typedef(decl, ctxt);
3284 write_is_artificial(decl, o);
3285 write_is_non_reachable(
is_type(decl), o);
3287 if (!decl->get_linkage_name().empty())
3288 o <<
" linkage-name='"
3292 write_location(decl, ctxt);
3293 write_is_declaration_only(decl, o);
3297 i = ctxt.get_id_for_type(decl);
3298 o <<
" id='" << i <<
"'>\n";
3300 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3301 o <<
"<underlying-type type-id='"
3302 << ctxt.get_id_for_type(decl->get_underlying_type())
3305 for (enum_type_decl::enumerators::const_iterator i =
3306 decl->get_enumerators().begin();
3307 i != decl->get_enumerators().end();
3310 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3311 o <<
"<enumerator name='"
3318 do_indent(o, indent);
3319 o <<
"</enum-decl>\n";
3321 ctxt.record_type_as_emitted(decl);
3337 write_context& ctxt,
3339 {
return write_enum_type_decl(decl,
"", ctxt, indent);}
3353 write_context& ctxt,
3359 ostream &o = ctxt.get_ostream();
3361 annotate(sym, ctxt, indent);
3362 do_indent(o, indent);
3364 if (sym->is_variable() && sym->get_size())
3365 o <<
" size='" << sym->get_size() <<
"'";
3367 if (!sym->get_version().is_empty())
3369 o <<
" version='" << sym->get_version().str() <<
"'";
3370 o <<
" is-default-version='";
3371 if (sym->get_version().is_default())
3378 write_elf_symbol_type(sym->get_type(), o);
3380 write_elf_symbol_binding(sym->get_binding(), o);
3382 write_elf_symbol_visibility(sym->get_visibility(), o);
3384 write_elf_symbol_aliases(*sym, o);
3386 o <<
" is-defined='";
3387 if (sym->is_defined())
3393 if (sym->is_common_symbol())
3394 o <<
" is-common='yes'";
3396 if (sym->get_crc().has_value())
3398 << std::hex << std::showbase << sym->get_crc().value()
3399 << std::dec << std::noshowbase <<
"'";
3401 if (sym->get_namespace().has_value())
3402 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3421 write_context& ctxt,
3427 for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
3428 write_elf_symbol(*it, ctxt, indent);
3444 write_elf_needed(
const vector<string>& needed,
3445 write_context& ctxt,
3451 ostream& o = ctxt.get_ostream();
3453 for (vector<string>::const_iterator i = needed.begin();
3457 do_indent(o, indent);
3458 o <<
"<dependency name='" << *i <<
"'/>\n";
3483 write_context& ctxt,
3489 ostream &o = ctxt.get_ostream();
3491 annotate(decl, ctxt, indent);
3493 do_indent(o, indent);
3495 o <<
"<typedef-decl name='"
3499 type_base_sptr underlying_type = decl->get_underlying_type();
3500 string type_id = ctxt.get_id_for_type(underlying_type);
3501 o <<
" type-id='" << type_id <<
"'";
3502 ctxt.record_type_as_referenced(underlying_type);
3504 write_location(decl, ctxt);
3508 i = ctxt.get_id_for_type(decl);
3510 o <<
" id='" << i <<
"'/>\n";
3512 ctxt.record_type_as_emitted(decl);
3528 write_context& ctxt,
3530 {
return write_typedef_decl(decl,
"", ctxt, indent);}
3545 write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
3546 bool write_linkage_name,
unsigned indent)
3551 annotate(decl, ctxt, indent);
3553 ostream &o = ctxt.get_ostream();
3555 do_indent(o, indent);
3558 type_base_sptr var_type = decl->get_type();
3559 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
3560 ctxt.record_type_as_referenced(var_type);
3562 if (write_linkage_name)
3564 const string& linkage_name = decl->get_linkage_name();
3565 if (!linkage_name.empty())
3566 o <<
" mangled-name='" << linkage_name <<
"'";
3569 write_visibility(decl, o);
3571 write_binding(decl, o);
3573 write_location(decl, ctxt);
3576 if (corpus* abi = decl->get_corpus())
3577 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3581 ctxt.record_decl_as_emitted(decl);
3600 bool skip_first_parm,
unsigned indent)
3605 annotate(decl, ctxt, indent);
3607 ostream &o = ctxt.get_ostream();
3609 do_indent(o, indent);
3611 o <<
"<function-decl name='"
3615 if (!decl->get_linkage_name().empty())
3616 o <<
" mangled-name='"
3619 write_location(decl, ctxt);
3621 if (decl->is_declared_inline())
3622 o <<
" declared-inline='yes'";
3624 write_visibility(decl, o);
3626 write_binding(decl, o);
3628 write_size_and_alignment(decl->get_type(), o,
3629 (ctxt.get_write_default_sizes()
3631 : decl->get_translation_unit()->get_address_size()),
3634 if (corpus* abi = decl->get_corpus())
3635 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3639 type_base_sptr parm_type;
3640 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
3641 decl->get_parameters().begin();
3642 for ((skip_first_parm && pi != decl->get_parameters().end()) ? ++pi: pi;
3643 pi != decl->get_parameters().end();
3646 if ((*pi)->get_variadic_marker())
3648 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3649 o <<
"<parameter is-variadic='yes'";
3653 parm_type = (*pi)->get_type();
3656 indent + ctxt.get_config().get_xml_element_indent());
3658 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3660 o <<
"<parameter type-id='"
3661 << ctxt.get_id_for_type(parm_type)
3663 ctxt.record_type_as_referenced(parm_type);
3665 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3668 write_is_artificial(*pi, o);
3669 write_location((*pi)->get_location(), ctxt);
3673 if (shared_ptr<type_base> return_type = decl->get_return_type())
3675 annotate(return_type , ctxt,
3676 indent + ctxt.get_config().get_xml_element_indent());
3677 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3678 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3679 ctxt.record_type_as_referenced(return_type);
3682 do_indent(o, indent);
3683 o <<
"</function-decl>\n";
3685 ctxt.record_decl_as_emitted(decl);
3701 write_context& ctxt,
unsigned indent)
3706 ostream &o = ctxt.get_ostream();
3708 annotate(fn_type, ctxt, indent);
3710 do_indent(o, indent);
3712 o <<
"<function-type";
3714 write_size_and_alignment(fn_type, o,
3715 (ctxt.get_write_default_sizes()
3717 : fn_type->get_translation_unit()->get_address_size()),
3722 o <<
" method-class-id='"
3723 << ctxt.get_id_for_type(method_type->get_class_type())
3726 write_cdtor_const_static(
false,
false,
3727 method_type->get_is_const(),
3731 interned_string
id = ctxt.get_id_for_type(fn_type);
3737 type_base_sptr parm_type;
3738 for (vector<function_decl::parameter_sptr>::const_iterator pi =
3739 fn_type->get_parameters().begin();
3740 pi != fn_type->get_parameters().end();
3744 if ((*pi)->get_variadic_marker())
3746 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3747 o <<
"<parameter is-variadic='yes'";
3751 parm_type = (*pi)->get_type();
3753 annotate(*pi, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3755 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3756 o <<
"<parameter type-id='"
3757 << ctxt.get_id_for_type(parm_type)
3759 ctxt.record_type_as_referenced(parm_type);
3761 if (!(*pi)->get_name().empty())
3764 o <<
" name='" << name <<
"'";
3767 write_is_artificial(*pi, o);
3771 if (type_base_sptr return_type = fn_type->get_return_type())
3773 annotate(return_type, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3774 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3775 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3776 ctxt.record_type_as_referenced(return_type);
3779 do_indent(o, indent);
3780 o <<
"</function-type>\n";
3782 ctxt.record_type_as_emitted(fn_type);
3806 write_context& ctxt,
3808 bool prepare_to_handle_empty)
3813 ostream& o = ctxt.get_ostream();
3815 do_indent_to_level(ctxt, indent, 0);
3819 write_size_and_alignment(decl, o);
3821 write_is_struct(decl, o);
3823 write_is_anonymous(decl, o);
3825 write_is_artificial(decl, o);
3827 write_is_non_reachable(
is_type(decl), o);
3829 write_naming_typedef(decl, ctxt);
3831 write_visibility(decl, o);
3833 write_location(decl, ctxt);
3835 write_is_declaration_only(decl, o);
3837 if (decl->get_earlier_declaration())
3840 o <<
" def-of-decl-id='"
3841 << ctxt.get_id_for_type(
is_type(decl->get_earlier_declaration()))
3847 i = ctxt.get_id_for_type(decl);
3848 o <<
" id='" << i <<
"'";
3850 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
3876 write_union_decl_opening_tag(
const union_decl_sptr& decl,
3878 write_context& ctxt,
3880 bool prepare_to_handle_empty)
3885 ostream& o = ctxt.get_ostream();
3887 do_indent_to_level(ctxt, indent, 0);
3891 if (!decl->get_is_declaration_only())
3892 write_size_and_alignment(decl, o);
3894 write_is_anonymous(decl, o);
3896 write_naming_typedef(decl, ctxt);
3898 write_visibility(decl, o);
3900 write_is_artificial(decl, o);
3902 write_is_non_reachable(
is_type(decl), o);
3904 write_location(decl, ctxt);
3906 write_is_declaration_only(decl, o);
3910 i = ctxt.get_id_for_type(decl);
3911 o <<
" id='" << i <<
"'";
3913 if (prepare_to_handle_empty && decl->has_no_member())
3939 write_context& ctxt,
3947 annotate(decl, ctxt, indent);
3949 ostream& o = ctxt.get_ostream();
3951 if (decl->get_is_declaration_only())
3955 const environment& env = ctxt.get_environment();
3973 *decl->get_corpus(),
3976 for (
auto t : result)
3978 type_base_sptr type(t);
3980 for (
auto m : c->get_member_types())
3981 if (member_types.find(m) != member_types.end())
3982 member_types.insert(m);
3986 if (!member_types.empty())
3992 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3994 member_types.empty());
3996 vector<type_base_sptr> sorted_types;
3999 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4001 for (
auto t : sorted_types)
4002 if (!ctxt.type_is_emitted(t))
4003 write_member_type(t, ctxt, nb_ws);
4005 if (!member_types.empty())
4006 o << indent <<
"</class-decl>\n";
4011 for (
auto t : result)
4012 ctxt.record_type_as_emitted(type_base_sptr(t));
4017 write_class_decl_opening_tag(decl,
id, ctxt, indent,
4020 if (!decl->has_no_base_nor_member())
4022 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4023 type_base_sptr base_type;
4024 for (class_decl::base_specs::const_iterator base =
4025 decl->get_base_specifiers().begin();
4026 base != decl->get_base_specifiers().end();
4029 annotate((*base)->get_base_class(), ctxt, nb_ws);
4030 do_indent(o, nb_ws);
4033 write_access((*base)->get_access_specifier(), o);
4035 write_layout_offset (*base, o);
4037 if ((*base)->get_is_virtual ())
4038 o <<
" is-virtual='yes'";
4040 base_type = (*base)->get_base_class();
4042 << ctxt.get_id_for_type(base_type)
4045 ctxt.record_type_as_referenced(base_type);
4048 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4051 for (class_decl::member_types::const_iterator ti =
4052 decl->get_sorted_member_types().begin();
4053 ti != decl->get_sorted_member_types().end();
4055 if (!(*ti)->get_naked_canonical_type())
4056 write_member_type(*ti, ctxt, nb_ws);
4058 for (class_decl::data_members::const_iterator data =
4059 decl->get_data_members().begin();
4060 data != decl->get_data_members().end();
4063 do_indent(o, nb_ws);
4064 o <<
"<data-member";
4068 write_cdtor_const_static(
false,
4073 write_layout_offset(*data, o);
4076 write_var_decl(*data, ctxt, is_static,
4077 get_indent_to_level(ctxt, indent, 2));
4079 do_indent_to_level(ctxt, indent, 1);
4080 o <<
"</data-member>\n";
4083 for (class_decl::member_functions::const_iterator f =
4084 decl->get_member_functions().begin();
4085 f != decl->get_member_functions().end();
4096 do_indent(o, nb_ws);
4097 o <<
"<member-function";
4106 write_function_decl(fn, ctxt,
4108 get_indent_to_level(ctxt, indent, 2));
4110 do_indent_to_level(ctxt, indent, 1);
4111 o <<
"</member-function>\n";
4114 for (class_decl::member_functions::const_iterator f =
4115 decl->get_virtual_mem_fns().begin();
4116 f != decl->get_virtual_mem_fns().end();
4123 do_indent(o, nb_ws);
4124 o <<
"<member-function";
4131 write_voffset(fn, o);
4134 write_function_decl(fn, ctxt,
4136 get_indent_to_level(ctxt, indent, 2));
4138 do_indent_to_level(ctxt, indent, 1);
4139 o <<
"</member-function>\n";
4142 for (member_function_templates::const_iterator fn =
4143 decl->get_member_function_templates().begin();
4144 fn != decl->get_member_function_templates().end();
4147 do_indent(o, nb_ws);
4148 o <<
"<member-template";
4149 write_access((*fn)->get_access_specifier(), o);
4150 write_cdtor_const_static((*fn)->is_constructor(),
4153 (*fn)->get_is_static(), o);
4155 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4156 get_indent_to_level(ctxt, indent, 2));
4157 do_indent(o, nb_ws);
4158 o <<
"</member-template>\n";
4161 for (member_class_templates::const_iterator cl =
4162 decl->get_member_class_templates().begin();
4163 cl != decl->get_member_class_templates().end();
4166 do_indent(o, nb_ws);
4167 o <<
"<member-template";
4168 write_access((*cl)->get_access_specifier(), o);
4169 write_cdtor_const_static(
false,
false,
false,
4170 (*cl)->get_is_static(), o);
4172 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4173 get_indent_to_level(ctxt, indent, 2));
4174 do_indent(o, nb_ws);
4175 o <<
"</member-template>\n";
4178 do_indent_to_level(ctxt, indent, 0);
4180 o <<
"</class-decl>\n";
4183 ctxt.record_type_as_emitted(decl);
4199 write_context& ctxt,
4201 {
return write_class_decl(decl,
"", ctxt, indent);}
4213 write_union_decl(
const union_decl_sptr& d,
4215 write_context& ctxt,
4223 annotate(decl, ctxt, indent);
4225 ostream& o = ctxt.get_ostream();
4227 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4229 if (!decl->has_no_member())
4231 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4232 for (class_decl::member_types::const_iterator ti =
4233 decl->get_member_types().begin();
4234 ti != decl->get_member_types().end();
4236 if (!(*ti)->get_naked_canonical_type())
4237 write_member_type(*ti, ctxt, nb_ws);
4239 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4242 for (union_decl::data_members::const_iterator data =
4243 decl->get_data_members().begin();
4244 data != decl->get_data_members().end();
4247 do_indent(o, nb_ws);
4248 o <<
"<data-member";
4252 write_cdtor_const_static(
false,
4259 write_var_decl(*data, ctxt, is_static,
4260 get_indent_to_level(ctxt, indent, 2));
4262 do_indent_to_level(ctxt, indent, 1);
4263 o <<
"</data-member>\n";
4266 for (union_decl::member_functions::const_iterator f =
4267 decl->get_member_functions().begin();
4268 f != decl->get_member_functions().end();
4279 do_indent(o, nb_ws);
4280 o <<
"<member-function";
4289 write_function_decl(fn, ctxt,
4291 get_indent_to_level(ctxt, indent, 2));
4293 do_indent_to_level(ctxt, indent, 1);
4294 o <<
"</member-function>\n";
4297 for (member_function_templates::const_iterator fn =
4298 decl->get_member_function_templates().begin();
4299 fn != decl->get_member_function_templates().end();
4302 do_indent(o, nb_ws);
4303 o <<
"<member-template";
4304 write_access((*fn)->get_access_specifier(), o);
4305 write_cdtor_const_static((*fn)->is_constructor(),
4308 (*fn)->get_is_static(), o);
4310 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4311 get_indent_to_level(ctxt, indent, 2));
4312 do_indent(o, nb_ws);
4313 o <<
"</member-template>\n";
4316 for (member_class_templates::const_iterator cl =
4317 decl->get_member_class_templates().begin();
4318 cl != decl->get_member_class_templates().end();
4321 do_indent(o, nb_ws);
4322 o <<
"<member-template";
4323 write_access((*cl)->get_access_specifier(), o);
4324 write_cdtor_const_static(
false,
false,
false,
4325 (*cl)->get_is_static(), o);
4327 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4328 get_indent_to_level(ctxt, indent, 2));
4329 do_indent(o, nb_ws);
4330 o <<
"</member-template>\n";
4333 do_indent_to_level(ctxt, indent, 0);
4335 o <<
"</union-decl>\n";
4338 ctxt.record_type_as_emitted(decl);
4344 write_union_decl(
const union_decl_sptr& decl,
4345 write_context& ctxt,
4347 {
return write_union_decl(decl,
"", ctxt, indent);}
4359 write_member_type_opening_tag(
const type_base_sptr& t,
4360 write_context& ctxt,
4363 ostream& o = ctxt.get_ostream();
4365 do_indent_to_level(ctxt, indent, 0);
4370 o <<
"<member-type";
4371 write_access(decl, o);
4390 write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4395 ostream& o = ctxt.get_ostream();
4397 write_member_type_opening_tag(t, ctxt, indent);
4399 string id = ctxt.get_id_for_type(t);
4401 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4402 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4404 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4406 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4408 || write_ptr_to_mbr_type(dynamic_pointer_cast<ptr_to_mbr_type>(t),
4410 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4412 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4414 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4416 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4418 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
4421 do_indent_to_level(ctxt, indent, 0);
4422 o <<
"</member-type>\n";
4438 write_context& ctxt,
4444 ostream &o = ctxt.get_ostream();
4445 do_indent_to_level(ctxt, indent, 0);
4447 string id_attr_name;
4448 if (ctxt.type_has_existing_id(decl))
4449 id_attr_name =
"type-id";
4451 id_attr_name =
"id";
4453 o <<
"<template-type-parameter "
4454 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
4458 o <<
" name='" << name <<
"'";
4460 write_location(decl, ctxt);
4464 ctxt.record_type_as_emitted(decl);
4479 write_non_type_tparameter(
4480 const shared_ptr<non_type_tparameter> decl,
4481 write_context& ctxt,
unsigned indent)
4486 ostream &o = ctxt.get_ostream();
4487 do_indent_to_level(ctxt, indent, 0);
4489 o <<
"<template-non-type-parameter type-id='"
4490 << ctxt.get_id_for_type(decl->get_type())
4495 o <<
" name='" << name <<
"'";
4497 write_location(decl, ctxt);
4516 write_context& ctxt,
4522 ostream& o = ctxt.get_ostream();
4523 do_indent_to_level(ctxt, indent, 0);
4525 string id_attr_name =
"id";
4526 if (ctxt.type_has_existing_id(decl))
4527 id_attr_name =
"type-id";
4529 o <<
"<template-template-parameter " << id_attr_name <<
"='"
4530 << ctxt.get_id_for_type(decl) <<
"'";
4534 o <<
" name='" << name <<
"'";
4538 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4539 for (list<shared_ptr<template_parameter> >::const_iterator p =
4540 decl->get_template_parameters().begin();
4541 p != decl->get_template_parameters().end();
4543 write_template_parameter(decl, ctxt, nb_spaces);
4545 do_indent_to_level(ctxt, indent, 0);
4546 o <<
"</template-template-parameter>\n";
4548 ctxt.record_type_as_emitted(decl);
4563 write_type_composition
4564 (
const shared_ptr<type_composition> decl,
4565 write_context& ctxt,
unsigned indent)
4570 ostream& o = ctxt.get_ostream();
4572 do_indent_to_level(ctxt, indent, 0);
4574 o <<
"<template-parameter-type-composition>\n";
4576 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4577 (write_pointer_type_def
4578 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
4580 || write_reference_type_def
4581 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
4583 || write_array_type_def
4584 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
4586 || write_qualified_type_def
4587 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
4590 do_indent_to_level(ctxt, indent, 0);
4591 o <<
"</template-parameter-type-composition>\n";
4606 write_template_parameter(
const shared_ptr<template_parameter> decl,
4607 write_context& ctxt,
unsigned indent)
4609 if ((!write_type_tparameter
4610 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
4611 && (!write_non_type_tparameter
4612 (dynamic_pointer_cast<non_type_tparameter>(decl),
4614 && (!write_template_tparameter
4615 (dynamic_pointer_cast<template_tparameter>(decl),
4617 && (!write_type_composition
4618 (dynamic_pointer_cast<type_composition>(decl),
4629 write_template_parameters(
const shared_ptr<template_decl> tmpl,
4630 write_context& ctxt,
unsigned indent)
4635 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4636 for (list<shared_ptr<template_parameter> >::const_iterator p =
4637 tmpl->get_template_parameters().begin();
4638 p != tmpl->get_template_parameters().end();
4640 write_template_parameter(*p, ctxt, nb_spaces);
4651 write_function_tdecl(
const shared_ptr<function_tdecl> decl,
4652 write_context& ctxt,
unsigned indent)
4657 ostream& o = ctxt.get_ostream();
4659 do_indent_to_level(ctxt, indent, 0);
4661 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
4663 write_location(decl, ctxt);
4665 write_visibility(decl, o);
4667 write_binding(decl, o);
4671 write_template_parameters(decl, ctxt, indent);
4673 write_function_decl(decl->get_pattern(), ctxt,
4675 get_indent_to_level(ctxt, indent, 1));
4677 do_indent_to_level(ctxt, indent, 0);
4679 o <<
"</function-template-decl>\n";
4696 write_class_tdecl(
const shared_ptr<class_tdecl> decl,
4697 write_context& ctxt,
unsigned indent)
4702 ostream& o = ctxt.get_ostream();
4704 do_indent_to_level(ctxt, indent, 0);
4706 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
4708 write_location(decl, ctxt);
4710 write_visibility(decl, o);
4714 write_template_parameters(decl, ctxt, indent);
4716 write_class_decl(decl->get_pattern(), ctxt,
4717 get_indent_to_level(ctxt, indent, 1));
4719 do_indent_to_level(ctxt, indent, 0);
4721 o <<
"</class-template-decl>\n";
4730 write_version_info(write_context& ctxt)
4732 ostream& o = ctxt.get_ostream();
4733 const config& c = ctxt.get_config();
4736 << c.get_format_major_version_number()
4737 <<
"." << c.get_format_minor_version_number()
4757 const corpus_sptr&
corpus,
4759 bool member_of_group)
4767 do_indent_to_level(ctxt, indent, 0);
4769 std::ostream& out = ctxt.get_ostream();
4771 out <<
"<abi-corpus ";
4773 write_version_info(ctxt);
4778 if (!ctxt.get_write_corpus_path())
4780 if (member_of_group)
4783 corpus_path.clear();
4787 if (ctxt.get_short_locs())
4790 if (!corpus_path.empty())
4794 && ctxt.get_write_architecture())
4800 write_tracking_non_reachable_types(
corpus, out);
4808 do_indent_to_level(ctxt, indent, 1);
4809 out <<
"<elf-needed>\n";
4811 get_indent_to_level(ctxt, indent, 2));
4812 do_indent_to_level(ctxt, indent, 1);
4813 out <<
"</elf-needed>\n";
4819 do_indent_to_level(ctxt, indent, 1);
4820 out <<
"<elf-function-symbols>\n";
4823 get_indent_to_level(ctxt, indent, 2));
4825 do_indent_to_level(ctxt, indent, 1);
4826 out <<
"</elf-function-symbols>\n";
4832 do_indent_to_level(ctxt, indent, 1);
4833 out <<
"<elf-variable-symbols>\n";
4836 get_indent_to_level(ctxt, indent, 2));
4838 do_indent_to_level(ctxt, indent, 1);
4839 out <<
"</elf-variable-symbols>\n";
4843 if (ctxt.get_write_undefined_symbols()
4846 do_indent_to_level(ctxt, indent, 1);
4847 out <<
"<undefined-elf-function-symbols>\n";
4850 get_indent_to_level(ctxt, indent, 2));
4852 do_indent_to_level(ctxt, indent, 1);
4853 out <<
"</undefined-elf-function-symbols>\n";
4858 if (ctxt.get_write_undefined_symbols()
4861 do_indent_to_level(ctxt, indent, 1);
4862 out <<
"<undefined-elf-variable-symbols>\n";
4865 get_indent_to_level(ctxt, indent, 2));
4867 do_indent_to_level(ctxt, indent, 1);
4868 out <<
"</undefined-elf-variable-symbols>\n";
4873 for (translation_units::const_iterator i =
4880 get_indent_to_level(ctxt, indent, 1),
4884 do_indent_to_level(ctxt, indent, 0);
4885 out <<
"</abi-corpus>\n";
4887 ctxt.clear_referenced_types();
4888 ctxt.record_corpus_as_emitted(
corpus);
4905 const corpus_group_sptr& group,
4912 do_indent_to_level(ctxt, indent, 0);
4914 std::ostream& out = ctxt.get_ostream();
4916 out <<
"<abi-corpus-group ";
4917 write_version_info(ctxt);
4919 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
4922 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
4923 out <<
" architecture='" << group->get_architecture_name()<<
"'";
4925 write_tracking_non_reachable_types(group, out);
4927 if (group->is_empty())
4936 for (corpus_group::corpora_type::const_iterator c =
4937 group->get_corpora().begin();
4938 c != group->get_corpora().end();
4942 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
4945 do_indent_to_level(ctxt, indent, 0);
4946 out <<
"</abi-corpus-group>\n";
4967 xml_writer::write_context ctxt(d->get_environment(), o);
4969 write_decl(d, ctxt, 0);
5011 xml_writer::write_context ctxt(v->get_environment(), o);
5013 write_var_decl(v, ctxt,
true, 0);
5082 unsigned line = 0, col = 0;
5084 l.
expand(path, line, col);
5085 o << path <<
":" << line <<
"," << col <<
"\n";
5135 #ifdef WITH_DEBUG_SELF_COMPARISON
5146 write_type_record(xml_writer::write_context& ctxt,
5147 const type_base* type,
5165 type_base* canonical = type->get_naked_canonical_type();
5169 id = ctxt.get_id_for_type (
const_cast<type_base*
>(type));
5172 <<
" <id>" <<
id <<
"</id>\n"
5175 <<
reinterpret_cast<uintptr_t
>(canonical)
5191 write_canonical_type_ids(xml_writer::write_context& ctxt, ostream& o)
5210 o <<
"<abixml-types-check>\n";
5212 for (
const auto &type : ctxt.get_emitted_types_set())
5213 write_type_record(ctxt, type, o);
5215 o <<
"</abixml-types-check>\n";
5228 write_canonical_type_ids(xml_writer::write_context& ctxt,
5229 const string &file_path)
5231 std:: ofstream o (file_path);
5235 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:
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
string & get_path() const
Get the file path associated to the corpus file.
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
The base type of all declarations.
const location & get_location() const
Get the location of a given declaration.
visibility
ELF visibility.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
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.
Abstraction for a function declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Abstraction of a function type.
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,...
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
char get_address_size() const
Getter of the address size in this translation unit.
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
const std::string & get_path() const
Get the path of the current translation unit.
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
const environment & get_environment() const
Getter of the environment of the current translation_unit.
language get_language() const
Getter of the language of the source code of the translation unit.
An abstraction helper for type declarations.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
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.
Abstracts a variable declaration.
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_write_undefined_symbols(write_context &ctxt, bool flag)
Set the 'undefined-symbols' flag.
void set_short_locs(write_context &ctxt, bool flag)
Set the 'short-locs' flag.
write_context_sptr create_write_context(const environment &env, ostream &default_output_stream)
Create a write_context object that can be used to emit abixml files.
std::unordered_set< function_type * > fn_type_ptr_set_type
A convenience typedef for a set of function type*.
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_write_parameter_names(write_context &ctxt, bool flag)
Set the 'parameter-names' flag.
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_location(const location &l, ostream &o)
Serialize a source location 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(const decl_base_sptr d, std::ostream &o, const bool annotate)
Serialize a pointer to decl_base to an output stream.
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.
Datum consolidating style preferences.