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_parameter_names;
219 bool m_write_default_sizes;
223 mutable unordered_set<uint32_t> m_used_type_id_hashes;
224 mutable type_ptr_set_type m_emitted_type_set;
227 type_ptr_set_type m_referenced_types_set;
229 fn_tmpl_shared_ptr_map m_fn_tmpl_id_map;
230 class_tmpl_shared_ptr_map m_class_tmpl_id_map;
233 unordered_set<interned_string, hash_interned_string> m_emitted_decls_set;
234 unordered_set<string> m_emitted_corpora_set;
251 m_write_architecture(
true),
252 m_write_corpus_path(
true),
253 m_write_comp_dir(
true),
254 m_write_elf_needed(
true),
255 m_write_parameter_names(
true),
257 m_write_default_sizes(
true),
258 m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
265 get_environment()
const
270 {
return get_environment().get_config();}
304 get_write_architecture()
305 {
return m_write_architecture;}
312 {m_write_architecture = f;}
318 get_write_elf_needed()
319 {
return m_write_elf_needed;}
326 {m_write_elf_needed = f;}
332 get_write_default_sizes()
333 {
return m_write_default_sizes;}
340 {m_write_default_sizes = f;}
346 get_write_corpus_path()
347 {
return m_write_corpus_path;}
354 {m_write_corpus_path = f;}
361 {
return m_write_comp_dir;}
368 {m_write_comp_dir = f;}
375 {
return m_short_locs;}
388 get_write_parameter_names()
const
389 {
return m_write_parameter_names;}
396 {m_write_parameter_names = f;}
405 get_show_locs()
const
406 {
return m_show_locs;}
424 get_type_id_style()
const
425 {
return m_type_id_style;}
434 {m_type_id_style =
style;}
441 get_id_manager()
const
442 {
return m_id_manager;}
446 {
return m_id_manager;}
450 type_has_existing_id(type_base_sptr type)
const
451 {
return type_has_existing_id(type.get());}
455 type_has_existing_id(
type_base* type)
const
458 return m_type_id_map.find(type) != m_type_id_map.end();
466 get_id_for_type(
const type_base_sptr& t)
467 {
return get_id_for_type(t.get());}
478 auto it = m_type_id_map.find(c);
479 if (it != m_type_id_map.end())
482 switch (m_type_id_style)
484 case SEQUENCE_TYPE_ID_STYLE:
487 return m_type_id_map[c] = id;
489 case HASH_TYPE_ID_STYLE:
493 while (!m_used_type_id_hashes.insert(hash).second)
495 std::ostringstream os;
496 os << std::hex << std::setfill(
'0') << std::setw(8) << hash;
507 fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
508 if (it == m_fn_tmpl_id_map.end())
510 string id = get_id_manager().get_id_with_prefix(
"fn-tmpl-id-");
511 m_fn_tmpl_id_map[f] = id;
514 return m_fn_tmpl_id_map[f];
520 class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
521 if (it == m_class_tmpl_id_map.end())
523 string id = get_id_manager().get_id_with_prefix(
"class-tmpl-id-");
524 m_class_tmpl_id_map[c] = id;
527 return m_class_tmpl_id_map[c];
533 m_type_id_map.clear();
544 const type_ptr_set_type&
545 get_referenced_types()
const
546 {
return m_referenced_types_set;}
553 get_referenced_function_types()
const
554 {
return m_referenced_fn_types_set;}
560 has_non_emitted_referenced_types()
const
562 for (
const auto t : get_referenced_types())
563 if (!type_is_emitted(t))
575 record_type_as_referenced(
const type_base_sptr& type)
581 m_referenced_fn_types_set.insert(f);
583 m_referenced_types_set.insert(t);
594 type_is_referenced(
const type_base_sptr& type)
598 return (m_referenced_fn_types_set.find(f)
599 != m_referenced_fn_types_set.end());
601 return m_referenced_types_set.find(t) != m_referenced_types_set.end();
660 type_ptr_map::const_iterator i =
664 i = map->find(
const_cast<type_base*
>(r));
687 operator()(
const type_base_sptr& l,
const type_base_sptr& r)
const
688 {
return operator()(l.get(), r.get());}
702 vector<type_base*>& sorted)
705 for (type_ptr_set_type::const_iterator i = types.begin();
708 sorted.push_back(
const_cast<type_base*
>(*i));
709 type_ptr_cmp comp(&m_type_id_map);
710 sort(sorted.begin(), sorted.end(), comp);
724 vector<type_base_sptr> &sorted)
726 for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
729 sorted.push_back(type_base_sptr(i->second));
730 type_ptr_cmp comp(&m_type_id_map);
731 sort(sorted.begin(), sorted.end(), comp);
745 sort_types(
const vector<function_type_sptr>& types,
746 vector<type_base_sptr> &sorted)
748 for (vector<function_type_sptr>::const_iterator i = types.begin();
751 sorted.push_back(*i);
752 type_ptr_cmp comp(&m_type_id_map);
753 sort(sorted.begin(), sorted.end(), comp);
760 record_type_as_emitted(
const type_base_sptr &t)
761 {record_type_as_emitted(t.get());}
767 record_type_as_emitted(
const type_base* t)
770 m_emitted_type_set.insert(c);
780 type_is_emitted(
const type_base* t)
const
783 return (m_emitted_type_set.find(c) != m_emitted_type_set.end());
793 type_is_emitted(
const type_base_sptr& t)
const
794 {
return type_is_emitted(t.get());}
803 decl_is_emitted(
const decl_base_sptr& decl)
const
808 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
815 record_decl_as_emitted(
const decl_base_sptr& decl)
819 m_emitted_decls_set.insert(irepr);
831 corpus_is_emitted(
const corpus_sptr& corp)
836 if (m_emitted_corpora_set.find(corp->get_path())
837 == m_emitted_corpora_set.end())
847 record_corpus_as_emitted(
const corpus_sptr& corp)
852 const string& path = corp->get_path();
855 m_emitted_corpora_set.insert(path);
861 const type_ptr_set_type&
862 get_emitted_types_set()
const
863 {
return m_emitted_type_set;}
868 clear_referenced_types()
870 m_referenced_types_set.clear();
871 m_referenced_fn_types_set.clear();
875 get_fun_symbol_map()
const
876 {
return m_fun_symbol_map;}
880 {
return m_fun_symbol_map;}
884 static void write_location(
const location&, write_context&);
885 static void write_location(
const decl_base_sptr&, write_context&);
886 static bool write_visibility(
const decl_base_sptr&, ostream&);
887 static bool write_binding(
const decl_base_sptr&, ostream&);
888 static bool write_is_artificial(
const decl_base_sptr&, ostream&);
889 static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
890 static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
893 static void write_size_and_alignment(
const type_base_sptr, ostream&,
894 size_t default_size = 0,
895 size_t default_alignment = 0);
899 static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
903 static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
904 static bool write_elf_symbol_reference(
const elf_symbol&, ostream&);
905 static bool write_elf_symbol_reference(
const elf_symbol_sptr, ostream&);
906 static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
908 static void write_is_anonymous(
const decl_base_sptr&, ostream&);
909 static void write_naming_typedef(
const decl_base_sptr&, write_context&);
910 static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
911 static void write_decl_in_scope(
const decl_base_sptr&,
912 write_context&,
unsigned);
913 static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
915 write_context&,
unsigned);
916 static bool write_qualified_type_def(
const qualified_type_def_sptr&,
917 write_context&,
unsigned);
919 write_context&,
unsigned);
921 write_context&,
unsigned);
923 write_context&,
unsigned);
928 write_context&,
unsigned);
930 write_context&,
unsigned);
932 write_context&,
unsigned);
933 static bool write_elf_symbols_table(
const elf_symbols&,
934 write_context&,
unsigned);
936 write_context&,
bool,
unsigned);
938 write_context&,
bool,
unsigned);
940 write_context&,
unsigned);
941 static bool write_member_type_opening_tag(
const type_base_sptr&,
942 write_context&,
unsigned);
943 static bool write_member_type(
const type_base_sptr&,
944 write_context&,
unsigned);
945 static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
946 write_context&,
unsigned,
bool);
948 write_context&,
unsigned);
949 static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
950 write_context&,
unsigned,
bool);
951 static bool write_union_decl(
const union_decl_sptr&,
const string&,
952 write_context&,
unsigned);
953 static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
954 static bool write_type_tparameter
955 (
const shared_ptr<type_tparameter>, write_context&,
unsigned);
956 static bool write_non_type_tparameter
957 (
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
958 static bool write_template_tparameter
959 (
const shared_ptr<template_tparameter>, write_context&,
unsigned);
960 static bool write_type_composition
961 (
const shared_ptr<type_composition>, write_context&,
unsigned);
962 static bool write_template_parameter(
const shared_ptr<template_parameter>,
963 write_context&,
unsigned);
964 static void write_template_parameters(
const shared_ptr<template_decl>,
965 write_context&,
unsigned);
966 static bool write_function_tdecl
967 (
const shared_ptr<function_tdecl>,
968 write_context&,
unsigned);
969 static bool write_class_tdecl
970 (
const shared_ptr<class_tdecl>,
971 write_context&,
unsigned);
972 static void do_indent(ostream&,
unsigned);
973 static void do_indent_to_level(write_context&,
unsigned,
unsigned);
974 static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
978 do_indent(ostream& o,
unsigned nb_whitespaces)
980 for (
unsigned i = 0; i < nb_whitespaces; ++i)
992 do_indent_to_level(write_context& ctxt,
993 unsigned initial_indent,
996 do_indent(ctxt.get_ostream(),
997 get_indent_to_level(ctxt, initial_indent, level));
1009 get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
1012 int nb_ws = initial_indent +
1013 level * ctxt.get_config().get_xml_element_indent();
1033 template <
typename T>
1035 annotate(
const T& decl,
1036 write_context& ctxt,
1042 if (!ctxt.get_annotate())
1045 ostream& o = ctxt.get_ostream();
1047 do_indent(o, indent);
1069 write_context& ctxt,
1075 if (!ctxt.get_annotate())
1078 ostream& o = ctxt.get_ostream();
1080 do_indent(o, indent);
1100 write_context& ctxt,
1106 if (!ctxt.get_annotate())
1109 ostream& o = ctxt.get_ostream();
1111 do_indent(o, indent);
1113 o <<
"<!-- typedef "
1136 write_context& ctxt,
1142 if (!ctxt.get_annotate())
1145 ostream& o = ctxt.get_ostream();
1147 do_indent(o, indent);
1152 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
1181 write_context& ctxt,
1187 if (!ctxt.get_annotate())
1190 ostream& o = ctxt.get_ostream();
1192 do_indent(o, indent);
1204 vector<function_decl::parameter_sptr>::const_iterator pi =
1205 fn->get_first_non_implicit_parm();
1207 for (; pi != fn->get_parameters().end(); ++pi)
1211 if (distance(pi, fn->get_parameters().end()) > 1)
1231 write_context& ctxt,
1237 if (!ctxt.get_annotate())
1240 ostream &o = ctxt.get_ostream();
1242 do_indent(o, indent);
1246 if (parm->get_variadic_marker())
1247 o <<
"variadic parameter";
1250 if (parm->get_is_artificial())
1252 if (parm->get_index() == 0)
1257 o <<
"parameter of type '"
1276 write_location(
const location& loc, write_context& ctxt)
1281 if (!ctxt.get_show_locs())
1285 unsigned line = 0, column = 0;
1287 loc.
expand(filepath, line, column);
1289 ostream &o = ctxt.get_ostream();
1291 if (ctxt.get_short_locs())
1295 <<
" line='" << line <<
"'"
1296 <<
" column='" << column <<
"'";
1307 write_location(
const decl_base_sptr& decl,
1308 write_context& ctxt)
1313 location loc = decl->get_location();
1317 write_location(loc, ctxt);
1329 write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1339 case decl_base::VISIBILITY_NONE:
1341 case decl_base::VISIBILITY_DEFAULT:
1344 case decl_base::VISIBILITY_PROTECTED:
1347 case decl_base::VISIBILITY_HIDDEN:
1350 case decl_base::VISIBILITY_INTERNAL:
1358 o <<
" visibility='" << str <<
"'";
1369 write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1376 shared_ptr<var_decl> var =
1377 dynamic_pointer_cast<var_decl>(decl);
1379 bind = var->get_binding();
1382 shared_ptr<function_decl> fun =
1383 dynamic_pointer_cast<function_decl>(decl);
1385 bind = fun->get_binding();
1391 case decl_base::BINDING_NONE:
1393 case decl_base::BINDING_LOCAL:
1396 case decl_base::BINDING_GLOBAL:
1399 case decl_base::BINDING_WEAK:
1405 o <<
" binding='" << str <<
"'";
1419 write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1424 if (decl->get_is_artificial())
1425 o <<
" is-artificial='yes'";
1439 write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1444 corpus* c = t->get_corpus();
1448 if (!c->recording_types_reachable_from_public_interface_supported()
1449 || c->type_is_reachable_from_public_interfaces(*t))
1452 o <<
" is-non-reachable='yes'";
1465 write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1468 corpus_group* group = corpus->get_group();
1470 if (corpus->recording_types_reachable_from_public_interface_supported())
1472 o <<
" tracking-non-reachable-types='yes'";
1493 write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1494 size_t default_size,
size_t default_alignment)
1496 size_t size_in_bits = decl->get_size_in_bits();
1497 if (size_in_bits != default_size)
1498 o <<
" size-in-bits='" << size_in_bits <<
"'";
1500 size_t alignment_in_bits = decl->get_alignment_in_bits();
1501 if (alignment_in_bits != default_alignment)
1502 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1510 write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1512 if (decl->is_infinite())
1513 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1515 size_t size_in_bits = decl->get_size_in_bits();
1517 o <<
" size-in-bits='" << size_in_bits <<
"'";
1520 size_t alignment_in_bits = decl->get_alignment_in_bits();
1521 if (alignment_in_bits)
1522 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1532 string access_str =
"private";
1536 case private_access:
1537 access_str =
"private";
1540 case protected_access:
1541 access_str =
"protected";
1545 access_str =
"public";
1552 o <<
" access='" << access_str <<
"'";
1563 o <<
" layout-offset-in-bits='"
1570 write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1575 if (base->get_offset_in_bits() >= 0)
1576 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1585 write_access(decl_base_sptr member, ostream& o)
1602 o <<
" vtable-offset='" << voffset <<
"'";
1619 case elf_symbol::NOTYPE_TYPE:
1622 case elf_symbol::OBJECT_TYPE:
1623 repr =
"object-type";
1625 case elf_symbol::FUNC_TYPE:
1628 case elf_symbol::SECTION_TYPE:
1629 repr =
"section-type";
1631 case elf_symbol::FILE_TYPE:
1634 case elf_symbol::COMMON_TYPE:
1635 repr =
"common-type";
1637 case elf_symbol::TLS_TYPE:
1640 case elf_symbol::GNU_IFUNC_TYPE:
1641 repr =
"gnu-ifunc-type";
1648 o <<
" type='" << repr <<
"'";
1664 case elf_symbol::LOCAL_BINDING:
1665 repr =
"local-binding";
1667 case elf_symbol::GLOBAL_BINDING:
1668 repr =
"global-binding";
1670 case elf_symbol::WEAK_BINDING:
1671 repr =
"weak-binding";
1673 case elf_symbol::GNU_UNIQUE_BINDING:
1674 repr =
"gnu-unique-binding";
1677 repr =
"no-binding";
1681 o <<
" binding='" << repr <<
"'";
1697 case elf_symbol::DEFAULT_VISIBILITY:
1698 repr =
"default-visibility";
1700 case elf_symbol::PROTECTED_VISIBILITY:
1701 repr =
"protected-visibility";
1703 case elf_symbol::HIDDEN_VISIBILITY:
1704 repr =
"hidden-visibility";
1706 case elf_symbol::INTERNAL_VISIBILITY:
1707 repr =
"internal-visibility";
1710 repr =
"default-visibility";
1714 o <<
" visibility='" << repr <<
"'";
1725 write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1727 if (!sym.is_main_symbol() || !sym.has_aliases())
1731 std::vector<std::string> aliases;
1732 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1733 s = s->get_next_alias())
1735 if (!s->is_public())
1738 if (s->is_suppressed())
1741 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1744 aliases.push_back(s->get_id_string());
1747 if (!aliases.empty())
1750 std::string separator;
1751 for (
const auto& alias : aliases)
1753 out << separator << alias;
1773 write_elf_symbol_reference(
const elf_symbol& sym, ostream& o)
1775 const elf_symbol* main = sym.get_main_symbol().get();
1776 const elf_symbol* alias = &sym;
1777 bool found = !alias->is_suppressed();
1782 found = !alias->is_suppressed();
1787 alias = alias->get_next_alias().get();
1789 if (!alias || alias == main)
1791 found = !alias->is_suppressed();
1796 o <<
" elf-symbol-id='"
1816 return write_elf_symbol_reference(*sym, o);
1833 write_cdtor_const_static(
bool is_ctor,
1840 o <<
" static='yes'";
1842 o <<
" constructor='yes'";
1844 o <<
" destructor='yes'";
1846 o <<
" const='yes'";
1856 write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
1858 if (d->get_is_declaration_only())
1859 o <<
" is-declaration-only='yes'";
1871 if (klass->is_struct())
1872 o <<
" is-struct='yes'";
1882 write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1884 if (decl->get_is_anonymous())
1885 o <<
" is-anonymous='yes'";
1895 write_naming_typedef(
const decl_base_sptr& decl, write_context& ctxt)
1900 ostream &o = ctxt.get_ostream();
1904 string id = ctxt.get_id_for_type(typedef_type);
1905 o <<
" naming-typedef-id='" <<
id <<
"'";
1906 ctxt.record_type_as_referenced(typedef_type);
1920 write_type(
const type_base_sptr& type, write_context& ctxt,
unsigned indent)
1922 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
1924 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1927 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
1929 || write_reference_type_def(dynamic_pointer_cast
1930 <reference_type_def>(type), ctxt, indent)
1931 || write_array_type_def(dynamic_pointer_cast
1932 <array_type_def>(type), ctxt, indent)
1933 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
1935 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
1939 || (write_function_tdecl
1940 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
1941 || (write_class_tdecl
1942 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
1960 write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
1962 if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
1964 || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
1966 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1969 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
1971 || write_reference_type_def(dynamic_pointer_cast
1972 <reference_type_def>(decl), ctxt, indent)
1973 || write_array_type_def(dynamic_pointer_cast
1974 <array_type_def>(decl), ctxt, indent)
1975 || write_array_subrange_type(dynamic_pointer_cast
1976 <array_type_def::subrange_type>(decl),
1978 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
1980 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
1982 || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
1984 || write_function_decl(dynamic_pointer_cast<method_decl>
1987 || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
1988 ctxt,
false, indent)
1991 || (write_function_tdecl
1992 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
1993 || (write_class_tdecl
1994 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
2012 write_decl_in_scope(
const decl_base_sptr& decl,
2013 write_context& ctxt,
2014 unsigned initial_indent)
2016 type_base_sptr type =
is_type(decl);
2019 if (ctxt.type_is_emitted(type))
2022 list<scope_decl*> scopes;
2023 for (scope_decl* s = decl->get_scope();
2026 scopes.push_front(s);
2028 ostream& o = ctxt.get_ostream();
2029 const config& c = ctxt.get_config();
2030 stack<string> closing_tags;
2031 stack<unsigned> closing_indents;
2032 unsigned indent = initial_indent;
2033 for (list<scope_decl*>::const_iterator i = scopes.begin();
2042 do_indent(o, indent);
2043 o <<
"<namespace-decl name='"
2046 closing_tags.push(
"</namespace-decl>");
2047 closing_indents.push(indent);
2054 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2056 closing_tags.push(
"</class-decl>");
2057 closing_indents.push(indent);
2059 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2060 write_member_type_opening_tag(type, ctxt, nb_ws);
2062 closing_tags.push(
"</member-type>");
2063 closing_indents.push(nb_ws);
2067 union_decl_sptr union_type(u, noop_deleter());
2068 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2070 closing_tags.push(
"</union-decl>");
2071 closing_indents.push(indent);
2073 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2074 write_member_type_opening_tag(type, ctxt, nb_ws);
2076 closing_tags.push(
"</member-type>");
2077 closing_indents.push(nb_ws);
2082 indent += c.get_xml_element_indent();
2085 write_decl(decl, ctxt, indent);
2087 while (!closing_tags.empty())
2089 do_indent(o, closing_indents.top());
2090 o << closing_tags.top() <<
"\n";
2092 closing_indents.pop();
2106 ostream& default_output_stream)
2123 {ctxt.set_show_locs(flag);}
2135 {ctxt.set_annotate(flag);}
2146 {ctxt.set_ostream(os);}
2158 {ctxt.set_write_architecture(flag);}
2170 {ctxt.set_write_corpus_path(flag);}
2182 {ctxt.set_write_comp_dir(flag);}
2194 {ctxt.set_short_locs(flag);}
2206 {ctxt.set_write_parameter_names(flag);}
2218 {ctxt.set_write_elf_needed(flag);}
2233 {ctxt.set_write_default_sizes(flag);}
2244 {ctxt.set_type_id_style(
style);}
2259 write_canonical_types_of_scope(
const scope_decl &scope,
2260 write_context &ctxt,
2261 const unsigned indent,
2267 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2268 i != canonical_types.end();
2272 write_member_type(*i, ctxt, indent);
2274 write_type(*i, ctxt, indent);
2296 referenced_type_should_be_emitted(
const type_base *t,
2297 const write_context& ctxt,
2298 const translation_unit& tu,
2301 if ((tu_is_last || (t->get_translation_unit()
2302 && (t->get_translation_unit()->get_absolute_path()
2303 == tu.get_absolute_path())))
2304 && !ctxt.type_is_emitted(t))
2321 write_referenced_types(write_context & ctxt,
2322 const translation_unit& tu,
2323 const unsigned indent,
2326 const config& c = ctxt.get_config();
2334 type_ptr_set_type referenced_types_to_emit;
2339 for (type_ptr_set_type::const_iterator i =
2340 ctxt.get_referenced_types().begin();
2341 i != ctxt.get_referenced_types().end();
2343 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2344 referenced_types_to_emit.insert(*i);
2346 for (fn_type_ptr_set_type::const_iterator i =
2347 ctxt.get_referenced_function_types().begin();
2348 i != ctxt.get_referenced_function_types().end();
2350 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2351 referenced_types_to_emit.insert(*i);
2354 while (!referenced_types_to_emit.empty())
2359 vector<type_base*> sorted_referenced_types;
2360 ctxt.sort_types(referenced_types_to_emit,
2361 sorted_referenced_types);
2364 for (vector<type_base*>::const_iterator i =
2365 sorted_referenced_types.begin();
2366 i != sorted_referenced_types.end();
2372 if (!ctxt.type_is_emitted(t))
2376 decl_base_sptr decl(d, noop_deleter());
2377 write_decl_in_scope(decl, ctxt,
2378 indent + c.get_xml_element_indent());
2383 write_function_type(fn_type, ctxt,
2384 indent + c.get_xml_element_indent());
2393 referenced_types_to_emit.clear();
2405 for (type_ptr_set_type::const_iterator i =
2406 ctxt.get_referenced_types().begin();
2407 i != ctxt.get_referenced_types().end();
2409 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2410 referenced_types_to_emit.insert(*i);
2438 const unsigned indent,
2446 && ctxt.has_non_emitted_referenced_types())
2449 ostream& o = ctxt.get_ostream();
2450 const config& c = ctxt.get_config();
2452 do_indent(o, indent);
2459 std::string tu_path = tu.
get_path();
2460 if (ctxt.get_short_locs())
2462 if (!tu_path.empty())
2466 o <<
" comp-dir-path='"
2469 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
2483 ctxt, indent + c.get_xml_element_indent());
2486 const declarations& decls = tu.
get_global_scope()->get_sorted_member_decls();
2488 for (
const decl_base_sptr& decl : decls)
2490 if (type_base_sptr t =
is_type(decl))
2497 if (class_type->get_is_declaration_only()
2498 && !ctxt.type_is_emitted(class_type))
2499 write_type(class_type, ctxt,
2500 indent + c.get_xml_element_indent());
2503 write_type(t, ctxt, indent + c.get_xml_element_indent());
2507 if (!ctxt.decl_is_emitted(decl))
2508 write_decl(decl, ctxt, indent + c.get_xml_element_indent());
2512 write_referenced_types(ctxt, tu, indent, is_last);
2517 vector<type_base_sptr> sorted_types;
2518 ctxt.sort_types(t, sorted_types);
2520 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
2521 i != sorted_types.end();
2526 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
2533 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
2538 write_referenced_types(ctxt, tu, indent, is_last);
2540 do_indent(o, indent);
2541 o <<
"</abi-instr>\n";
2559 write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
2564 ostream& o = ctxt.get_ostream();
2566 annotate(d, ctxt, indent);
2568 do_indent(o, indent);
2572 write_is_anonymous(d, o);
2574 write_size_and_alignment(d, o);
2576 write_is_declaration_only(d, o);
2578 write_location(d, ctxt);
2580 o <<
" id='" << ctxt.get_id_for_type(d) <<
"'" <<
"/>\n";
2582 ctxt.record_type_as_emitted(d);
2600 write_context& ctxt,
unsigned indent)
2602 if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
2605 ostream& o = ctxt.get_ostream();
2606 const config &c = ctxt.get_config();
2608 annotate(decl, ctxt, indent);
2610 do_indent(o, indent);
2612 o <<
"<namespace-decl name='"
2617 typedef declarations::const_iterator const_iterator;
2618 const declarations& d = decl->get_sorted_member_decls();
2620 write_canonical_types_of_scope(*decl, ctxt,
2621 indent + c.get_xml_element_indent());
2623 for (const_iterator i = d.begin(); i != d.end(); ++i)
2625 if (type_base_sptr t =
is_type(*i))
2626 if (ctxt.type_is_emitted(t))
2630 write_decl(*i, ctxt, indent + c.get_xml_element_indent());
2633 do_indent(o, indent);
2634 o <<
"</namespace-decl>\n";
2658 write_qualified_type_def(
const qualified_type_def_sptr& decl,
2660 write_context& ctxt,
2666 ostream& o = ctxt.get_ostream();
2669 type_base_sptr underlying_type = decl->get_underlying_type();
2671 annotate(decl, ctxt, indent);
2673 do_indent(o, indent);
2674 o <<
"<qualified-type-def type-id='"
2675 << ctxt.get_id_for_type(underlying_type)
2678 ctxt.record_type_as_referenced(underlying_type);
2680 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
2681 o <<
" const='yes'";
2682 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
2683 o <<
" volatile='yes'";
2684 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
2685 o <<
" restrict='yes'";
2687 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2691 i = ctxt.get_id_for_type(decl);
2693 o <<
" id='" << i <<
"'/>\n";
2695 ctxt.record_type_as_emitted(decl);
2711 write_qualified_type_def(
const qualified_type_def_sptr& decl,
2712 write_context& ctxt,
2714 {
return write_qualified_type_def(decl,
"", ctxt, indent);}
2736 write_context& ctxt,
2742 ostream& o = ctxt.get_ostream();
2744 annotate(decl, ctxt, indent);
2746 do_indent(o, indent);
2750 o <<
"<pointer-type-def ";
2752 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2754 i = ctxt.get_id_for_type(pointed_to_type);
2756 o <<
"type-id='" << i <<
"'";
2758 ctxt.record_type_as_referenced(pointed_to_type);
2760 write_size_and_alignment(decl, o,
2761 (ctxt.get_write_default_sizes()
2763 : decl->get_translation_unit()->get_address_size()),
2768 i = ctxt.get_id_for_type(decl);
2770 o <<
" id='" << i <<
"'";
2772 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2775 ctxt.record_type_as_emitted(decl);
2791 write_context& ctxt,
2793 {
return write_pointer_type_def(decl,
"", ctxt, indent);}
2815 write_context& ctxt,
2821 annotate(decl->get_canonical_type(), ctxt, indent);
2823 ostream& o = ctxt.get_ostream();
2825 do_indent(o, indent);
2827 o <<
"<reference-type-def kind='";
2828 if (decl->is_lvalue())
2834 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2835 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
2837 ctxt.record_type_as_referenced(pointed_to_type);
2840 ctxt.record_type_as_referenced(f);
2842 write_size_and_alignment(decl, o,
2843 (ctxt.get_write_default_sizes()
2845 : decl->get_translation_unit()->get_address_size()),
2850 i = ctxt.get_id_for_type(decl);
2851 o <<
" id='" << i <<
"'";
2853 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2857 ctxt.record_type_as_emitted(decl);
2873 write_context& ctxt,
2875 {
return write_reference_type_def(decl,
"", ctxt, indent);}
2888 write_context& ctxt,
2894 annotate(decl, ctxt, indent);
2896 ostream& o = ctxt.get_ostream();
2898 do_indent(o, indent);
2902 if (!decl->get_name().empty())
2903 o <<
" name='" << decl->get_name() <<
"'";
2906 if (decl->is_infinite())
2909 o << decl->get_length();
2914 || decl->get_length() == 0
2915 || (decl->get_length() ==
2916 (uint64_t) (decl->get_upper_bound()
2917 - decl->get_lower_bound() + 1)));
2918 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
2919 << decl->get_upper_bound() <<
"'";
2921 type_base_sptr underlying_type = decl->get_underlying_type();
2922 if (underlying_type)
2925 << ctxt.get_id_for_type(underlying_type)
2927 ctxt.record_type_as_referenced(underlying_type);
2930 o <<
" id='" << ctxt.get_id_for_type(decl) <<
"'";
2932 write_location(decl->get_location(), ctxt);
2936 ctxt.record_type_as_emitted(decl);
2961 write_context& ctxt,
2967 annotate(decl, ctxt, indent);
2969 ostream& o = ctxt.get_ostream();
2971 do_indent(o, indent);
2972 o <<
"<array-type-def";
2974 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
2976 type_base_sptr element_type = decl->get_element_type();
2977 o <<
" type-id='" << ctxt.get_id_for_type(element_type) <<
"'";
2979 ctxt.record_type_as_referenced(element_type);
2981 write_array_size_and_alignment(decl, o);
2985 i = ctxt.get_id_for_type(decl);
2986 o <<
" id='" << i <<
"'";
2988 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2990 if (!decl->get_dimension_count())
2996 vector<array_type_def::subrange_sptr>::const_iterator si;
2998 for (si = decl->get_subranges().begin();
2999 si != decl->get_subranges().end(); ++si)
3001 unsigned local_indent =
3002 indent + ctxt.get_config().get_xml_element_indent();
3003 write_array_subrange_type(*si, ctxt, local_indent);
3006 do_indent(o, indent);
3007 o <<
"</array-type-def>\n";
3010 ctxt.record_type_as_emitted(decl);
3026 write_context& ctxt,
3028 {
return write_array_type_def(decl,
"", ctxt, indent);}
3050 write_context& ctxt,
3058 annotate(decl->get_canonical_type(), ctxt, indent);
3060 ostream& o = ctxt.get_ostream();
3062 do_indent(o, indent);
3065 write_is_anonymous(decl, o);
3066 write_naming_typedef(decl, ctxt);
3067 write_is_artificial(decl, o);
3068 write_is_non_reachable(
is_type(decl), o);
3070 if (!decl->get_linkage_name().empty())
3071 o <<
" linkage-name='"
3075 write_location(decl, ctxt);
3076 write_is_declaration_only(decl, o);
3080 i = ctxt.get_id_for_type(decl);
3081 o <<
" id='" << i <<
"'>\n";
3083 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3084 o <<
"<underlying-type type-id='"
3085 << ctxt.get_id_for_type(decl->get_underlying_type())
3088 for (enum_type_decl::enumerators::const_iterator i =
3089 decl->get_enumerators().begin();
3090 i != decl->get_enumerators().end();
3093 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3094 o <<
"<enumerator name='"
3101 do_indent(o, indent);
3102 o <<
"</enum-decl>\n";
3104 ctxt.record_type_as_emitted(decl);
3120 write_context& ctxt,
3122 {
return write_enum_type_decl(decl,
"", ctxt, indent);}
3136 write_context& ctxt,
3142 ostream &o = ctxt.get_ostream();
3144 annotate(sym, ctxt, indent);
3145 do_indent(o, indent);
3147 if (sym->is_variable() && sym->get_size())
3148 o <<
" size='" << sym->get_size() <<
"'";
3150 if (!sym->get_version().is_empty())
3152 o <<
" version='" << sym->get_version().str() <<
"'";
3153 o <<
" is-default-version='";
3154 if (sym->get_version().is_default())
3161 write_elf_symbol_type(sym->get_type(), o);
3163 write_elf_symbol_binding(sym->get_binding(), o);
3165 write_elf_symbol_visibility(sym->get_visibility(), o);
3167 write_elf_symbol_aliases(*sym, o);
3169 o <<
" is-defined='";
3170 if (sym->is_defined())
3176 if (sym->is_common_symbol())
3177 o <<
" is-common='yes'";
3179 if (sym->get_crc().has_value())
3181 << std::hex << std::showbase << sym->get_crc().value()
3182 << std::dec << std::noshowbase <<
"'";
3184 if (sym->get_namespace().has_value())
3185 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3204 write_context& ctxt,
3210 for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
3211 write_elf_symbol(*it, ctxt, indent);
3227 write_elf_needed(
const vector<string>& needed,
3228 write_context& ctxt,
3234 ostream& o = ctxt.get_ostream();
3236 for (vector<string>::const_iterator i = needed.begin();
3240 do_indent(o, indent);
3241 o <<
"<dependency name='" << *i <<
"'/>\n";
3266 write_context& ctxt,
3272 ostream &o = ctxt.get_ostream();
3274 annotate(decl, ctxt, indent);
3276 do_indent(o, indent);
3278 o <<
"<typedef-decl name='"
3282 type_base_sptr underlying_type = decl->get_underlying_type();
3283 string type_id = ctxt.get_id_for_type(underlying_type);
3284 o <<
" type-id='" << type_id <<
"'";
3285 ctxt.record_type_as_referenced(underlying_type);
3287 write_location(decl, ctxt);
3291 i = ctxt.get_id_for_type(decl);
3293 o <<
" id='" << i <<
"'/>\n";
3295 ctxt.record_type_as_emitted(decl);
3311 write_context& ctxt,
3313 {
return write_typedef_decl(decl,
"", ctxt, indent);}
3328 write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
3329 bool write_linkage_name,
unsigned indent)
3334 annotate(decl, ctxt, indent);
3336 ostream &o = ctxt.get_ostream();
3338 do_indent(o, indent);
3341 type_base_sptr var_type = decl->get_type();
3342 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
3343 ctxt.record_type_as_referenced(var_type);
3345 if (write_linkage_name)
3347 const string& linkage_name = decl->get_linkage_name();
3348 if (!linkage_name.empty())
3349 o <<
" mangled-name='" << linkage_name <<
"'";
3352 write_visibility(decl, o);
3354 write_binding(decl, o);
3356 write_location(decl, ctxt);
3358 write_elf_symbol_reference(decl->get_symbol(), o);
3362 ctxt.record_decl_as_emitted(decl);
3381 bool skip_first_parm,
unsigned indent)
3386 annotate(decl, ctxt, indent);
3388 ostream &o = ctxt.get_ostream();
3390 do_indent(o, indent);
3392 o <<
"<function-decl name='"
3396 if (!decl->get_linkage_name().empty())
3397 o <<
" mangled-name='"
3400 write_location(decl, ctxt);
3402 if (decl->is_declared_inline())
3403 o <<
" declared-inline='yes'";
3405 write_visibility(decl, o);
3407 write_binding(decl, o);
3409 write_size_and_alignment(decl->get_type(), o,
3410 (ctxt.get_write_default_sizes()
3412 : decl->get_translation_unit()->get_address_size()),
3414 write_elf_symbol_reference(decl->get_symbol(), o);
3418 type_base_sptr parm_type;
3419 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
3420 decl->get_parameters().begin();
3421 for ((skip_first_parm && pi != decl->get_parameters().end()) ? ++pi: pi;
3422 pi != decl->get_parameters().end();
3425 if ((*pi)->get_variadic_marker())
3427 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3428 o <<
"<parameter is-variadic='yes'";
3432 parm_type = (*pi)->get_type();
3435 indent + ctxt.get_config().get_xml_element_indent());
3437 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3439 o <<
"<parameter type-id='"
3440 << ctxt.get_id_for_type(parm_type)
3442 ctxt.record_type_as_referenced(parm_type);
3444 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3447 write_is_artificial(*pi, o);
3448 write_location((*pi)->get_location(), ctxt);
3452 if (shared_ptr<type_base> return_type = decl->get_return_type())
3454 annotate(return_type , ctxt,
3455 indent + ctxt.get_config().get_xml_element_indent());
3456 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3457 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3458 ctxt.record_type_as_referenced(return_type);
3461 do_indent(o, indent);
3462 o <<
"</function-decl>\n";
3464 ctxt.record_decl_as_emitted(decl);
3480 write_context& ctxt,
unsigned indent)
3485 ostream &o = ctxt.get_ostream();
3487 annotate(fn_type, ctxt, indent);
3489 do_indent(o, indent);
3491 o <<
"<function-type";
3493 write_size_and_alignment(fn_type, o,
3494 (ctxt.get_write_default_sizes()
3496 : fn_type->get_translation_unit()->get_address_size()),
3501 o <<
" method-class-id='"
3502 << ctxt.get_id_for_type(method_type->get_class_type())
3505 write_cdtor_const_static(
false,
false,
3506 method_type->get_is_const(),
3510 interned_string
id = ctxt.get_id_for_type(fn_type);
3516 type_base_sptr parm_type;
3517 for (vector<function_decl::parameter_sptr>::const_iterator pi =
3518 fn_type->get_parameters().begin();
3519 pi != fn_type->get_parameters().end();
3523 if ((*pi)->get_variadic_marker())
3525 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3526 o <<
"<parameter is-variadic='yes'";
3530 parm_type = (*pi)->get_type();
3532 annotate(*pi, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3534 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3535 o <<
"<parameter type-id='"
3536 << ctxt.get_id_for_type(parm_type)
3538 ctxt.record_type_as_referenced(parm_type);
3540 if (!(*pi)->get_name().empty())
3543 o <<
" name='" << name <<
"'";
3546 write_is_artificial(*pi, o);
3550 if (type_base_sptr return_type = fn_type->get_return_type())
3552 annotate(return_type, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3553 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3554 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3555 ctxt.record_type_as_referenced(return_type);
3558 do_indent(o, indent);
3559 o <<
"</function-type>\n";
3561 ctxt.record_type_as_emitted(fn_type);
3585 write_context& ctxt,
3587 bool prepare_to_handle_empty)
3592 ostream& o = ctxt.get_ostream();
3594 do_indent_to_level(ctxt, indent, 0);
3598 write_size_and_alignment(decl, o);
3600 write_is_struct(decl, o);
3602 write_is_anonymous(decl, o);
3604 write_is_artificial(decl, o);
3606 write_is_non_reachable(
is_type(decl), o);
3608 write_naming_typedef(decl, ctxt);
3610 write_visibility(decl, o);
3612 write_location(decl, ctxt);
3614 write_is_declaration_only(decl, o);
3616 if (decl->get_earlier_declaration())
3619 o <<
" def-of-decl-id='"
3620 << ctxt.get_id_for_type(
is_type(decl->get_earlier_declaration()))
3626 i = ctxt.get_id_for_type(decl);
3627 o <<
" id='" << i <<
"'";
3629 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
3655 write_union_decl_opening_tag(
const union_decl_sptr& decl,
3657 write_context& ctxt,
3659 bool prepare_to_handle_empty)
3664 ostream& o = ctxt.get_ostream();
3666 do_indent_to_level(ctxt, indent, 0);
3670 if (!decl->get_is_declaration_only())
3671 write_size_and_alignment(decl, o);
3673 write_is_anonymous(decl, o);
3675 write_naming_typedef(decl, ctxt);
3677 write_visibility(decl, o);
3679 write_is_artificial(decl, o);
3681 write_is_non_reachable(
is_type(decl), o);
3683 write_location(decl, ctxt);
3685 write_is_declaration_only(decl, o);
3689 i = ctxt.get_id_for_type(decl);
3690 o <<
" id='" << i <<
"'";
3692 if (prepare_to_handle_empty && decl->has_no_member())
3718 write_context& ctxt,
3726 annotate(decl, ctxt, indent);
3728 ostream& o = ctxt.get_ostream();
3730 if (decl->get_is_declaration_only())
3734 const environment& env = ctxt.get_environment();
3752 *decl->get_corpus(),
3755 for (
auto t : result)
3757 type_base_sptr type(t);
3759 for (
auto m : c->get_member_types())
3760 if (member_types.find(m) != member_types.end())
3761 member_types.insert(m);
3765 if (!member_types.empty())
3771 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3773 member_types.empty());
3775 vector<type_base_sptr> sorted_types;
3778 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3780 for (
auto t : sorted_types)
3781 if (!ctxt.type_is_emitted(t))
3782 write_member_type(t, ctxt, nb_ws);
3784 if (!member_types.empty())
3785 o << indent <<
"</class-decl>\n";
3790 for (
auto t : result)
3791 ctxt.record_type_as_emitted(type_base_sptr(t));
3796 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3799 if (!decl->has_no_base_nor_member())
3801 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3802 type_base_sptr base_type;
3803 for (class_decl::base_specs::const_iterator base =
3804 decl->get_base_specifiers().begin();
3805 base != decl->get_base_specifiers().end();
3808 annotate((*base)->get_base_class(), ctxt, nb_ws);
3809 do_indent(o, nb_ws);
3812 write_access((*base)->get_access_specifier(), o);
3814 write_layout_offset (*base, o);
3816 if ((*base)->get_is_virtual ())
3817 o <<
" is-virtual='yes'";
3819 base_type = (*base)->get_base_class();
3821 << ctxt.get_id_for_type(base_type)
3824 ctxt.record_type_as_referenced(base_type);
3827 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
3830 for (class_decl::member_types::const_iterator ti =
3831 decl->get_sorted_member_types().begin();
3832 ti != decl->get_sorted_member_types().end();
3834 if (!(*ti)->get_naked_canonical_type())
3835 write_member_type(*ti, ctxt, nb_ws);
3837 for (class_decl::data_members::const_iterator data =
3838 decl->get_data_members().begin();
3839 data != decl->get_data_members().end();
3842 do_indent(o, nb_ws);
3843 o <<
"<data-member";
3847 write_cdtor_const_static(
false,
3852 write_layout_offset(*data, o);
3855 write_var_decl(*data, ctxt, is_static,
3856 get_indent_to_level(ctxt, indent, 2));
3858 do_indent_to_level(ctxt, indent, 1);
3859 o <<
"</data-member>\n";
3862 for (class_decl::member_functions::const_iterator f =
3863 decl->get_member_functions().begin();
3864 f != decl->get_member_functions().end();
3875 do_indent(o, nb_ws);
3876 o <<
"<member-function";
3885 write_function_decl(fn, ctxt,
3887 get_indent_to_level(ctxt, indent, 2));
3889 do_indent_to_level(ctxt, indent, 1);
3890 o <<
"</member-function>\n";
3893 for (class_decl::member_functions::const_iterator f =
3894 decl->get_virtual_mem_fns().begin();
3895 f != decl->get_virtual_mem_fns().end();
3902 do_indent(o, nb_ws);
3903 o <<
"<member-function";
3910 write_voffset(fn, o);
3913 write_function_decl(fn, ctxt,
3915 get_indent_to_level(ctxt, indent, 2));
3917 do_indent_to_level(ctxt, indent, 1);
3918 o <<
"</member-function>\n";
3921 for (member_function_templates::const_iterator fn =
3922 decl->get_member_function_templates().begin();
3923 fn != decl->get_member_function_templates().end();
3926 do_indent(o, nb_ws);
3927 o <<
"<member-template";
3928 write_access((*fn)->get_access_specifier(), o);
3929 write_cdtor_const_static((*fn)->is_constructor(),
3932 (*fn)->get_is_static(), o);
3934 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
3935 get_indent_to_level(ctxt, indent, 2));
3936 do_indent(o, nb_ws);
3937 o <<
"</member-template>\n";
3940 for (member_class_templates::const_iterator cl =
3941 decl->get_member_class_templates().begin();
3942 cl != decl->get_member_class_templates().end();
3945 do_indent(o, nb_ws);
3946 o <<
"<member-template";
3947 write_access((*cl)->get_access_specifier(), o);
3948 write_cdtor_const_static(
false,
false,
false,
3949 (*cl)->get_is_static(), o);
3951 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
3952 get_indent_to_level(ctxt, indent, 2));
3953 do_indent(o, nb_ws);
3954 o <<
"</member-template>\n";
3957 do_indent_to_level(ctxt, indent, 0);
3959 o <<
"</class-decl>\n";
3962 ctxt.record_type_as_emitted(decl);
3978 write_context& ctxt,
3980 {
return write_class_decl(decl,
"", ctxt, indent);}
3992 write_union_decl(
const union_decl_sptr& d,
3994 write_context& ctxt,
4002 annotate(decl, ctxt, indent);
4004 ostream& o = ctxt.get_ostream();
4006 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4008 if (!decl->has_no_member())
4010 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4011 for (class_decl::member_types::const_iterator ti =
4012 decl->get_member_types().begin();
4013 ti != decl->get_member_types().end();
4015 if (!(*ti)->get_naked_canonical_type())
4016 write_member_type(*ti, ctxt, nb_ws);
4018 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4021 for (union_decl::data_members::const_iterator data =
4022 decl->get_data_members().begin();
4023 data != decl->get_data_members().end();
4026 do_indent(o, nb_ws);
4027 o <<
"<data-member";
4031 write_cdtor_const_static(
false,
4038 write_var_decl(*data, ctxt, is_static,
4039 get_indent_to_level(ctxt, indent, 2));
4041 do_indent_to_level(ctxt, indent, 1);
4042 o <<
"</data-member>\n";
4045 for (union_decl::member_functions::const_iterator f =
4046 decl->get_member_functions().begin();
4047 f != decl->get_member_functions().end();
4058 do_indent(o, nb_ws);
4059 o <<
"<member-function";
4068 write_function_decl(fn, ctxt,
4070 get_indent_to_level(ctxt, indent, 2));
4072 do_indent_to_level(ctxt, indent, 1);
4073 o <<
"</member-function>\n";
4076 for (member_function_templates::const_iterator fn =
4077 decl->get_member_function_templates().begin();
4078 fn != decl->get_member_function_templates().end();
4081 do_indent(o, nb_ws);
4082 o <<
"<member-template";
4083 write_access((*fn)->get_access_specifier(), o);
4084 write_cdtor_const_static((*fn)->is_constructor(),
4087 (*fn)->get_is_static(), o);
4089 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4090 get_indent_to_level(ctxt, indent, 2));
4091 do_indent(o, nb_ws);
4092 o <<
"</member-template>\n";
4095 for (member_class_templates::const_iterator cl =
4096 decl->get_member_class_templates().begin();
4097 cl != decl->get_member_class_templates().end();
4100 do_indent(o, nb_ws);
4101 o <<
"<member-template";
4102 write_access((*cl)->get_access_specifier(), o);
4103 write_cdtor_const_static(
false,
false,
false,
4104 (*cl)->get_is_static(), o);
4106 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4107 get_indent_to_level(ctxt, indent, 2));
4108 do_indent(o, nb_ws);
4109 o <<
"</member-template>\n";
4112 do_indent_to_level(ctxt, indent, 0);
4114 o <<
"</union-decl>\n";
4117 ctxt.record_type_as_emitted(decl);
4123 write_union_decl(
const union_decl_sptr& decl,
4124 write_context& ctxt,
4126 {
return write_union_decl(decl,
"", ctxt, indent);}
4138 write_member_type_opening_tag(
const type_base_sptr& t,
4139 write_context& ctxt,
4142 ostream& o = ctxt.get_ostream();
4144 do_indent_to_level(ctxt, indent, 0);
4149 o <<
"<member-type";
4150 write_access(decl, o);
4169 write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4174 ostream& o = ctxt.get_ostream();
4176 write_member_type_opening_tag(t, ctxt, indent);
4178 string id = ctxt.get_id_for_type(t);
4180 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4181 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4183 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4185 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4187 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4189 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4191 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4193 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4195 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
4198 do_indent_to_level(ctxt, indent, 0);
4199 o <<
"</member-type>\n";
4215 write_context& ctxt,
4221 ostream &o = ctxt.get_ostream();
4222 do_indent_to_level(ctxt, indent, 0);
4224 string id_attr_name;
4225 if (ctxt.type_has_existing_id(decl))
4226 id_attr_name =
"type-id";
4228 id_attr_name =
"id";
4230 o <<
"<template-type-parameter "
4231 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
4235 o <<
" name='" << name <<
"'";
4237 write_location(decl, ctxt);
4241 ctxt.record_type_as_emitted(decl);
4256 write_non_type_tparameter(
4257 const shared_ptr<non_type_tparameter> decl,
4258 write_context& ctxt,
unsigned indent)
4263 ostream &o = ctxt.get_ostream();
4264 do_indent_to_level(ctxt, indent, 0);
4266 o <<
"<template-non-type-parameter type-id='"
4267 << ctxt.get_id_for_type(decl->get_type())
4272 o <<
" name='" << name <<
"'";
4274 write_location(decl, ctxt);
4293 write_context& ctxt,
4299 ostream& o = ctxt.get_ostream();
4300 do_indent_to_level(ctxt, indent, 0);
4302 string id_attr_name =
"id";
4303 if (ctxt.type_has_existing_id(decl))
4304 id_attr_name =
"type-id";
4306 o <<
"<template-template-parameter " << id_attr_name <<
"='"
4307 << ctxt.get_id_for_type(decl) <<
"'";
4311 o <<
" name='" << name <<
"'";
4315 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4316 for (list<shared_ptr<template_parameter> >::const_iterator p =
4317 decl->get_template_parameters().begin();
4318 p != decl->get_template_parameters().end();
4320 write_template_parameter(decl, ctxt, nb_spaces);
4322 do_indent_to_level(ctxt, indent, 0);
4323 o <<
"</template-template-parameter>\n";
4325 ctxt.record_type_as_emitted(decl);
4340 write_type_composition
4341 (
const shared_ptr<type_composition> decl,
4342 write_context& ctxt,
unsigned indent)
4347 ostream& o = ctxt.get_ostream();
4349 do_indent_to_level(ctxt, indent, 0);
4351 o <<
"<template-parameter-type-composition>\n";
4353 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4354 (write_pointer_type_def
4355 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
4357 || write_reference_type_def
4358 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
4360 || write_array_type_def
4361 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
4363 || write_qualified_type_def
4364 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
4367 do_indent_to_level(ctxt, indent, 0);
4368 o <<
"</template-parameter-type-composition>\n";
4383 write_template_parameter(
const shared_ptr<template_parameter> decl,
4384 write_context& ctxt,
unsigned indent)
4386 if ((!write_type_tparameter
4387 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
4388 && (!write_non_type_tparameter
4389 (dynamic_pointer_cast<non_type_tparameter>(decl),
4391 && (!write_template_tparameter
4392 (dynamic_pointer_cast<template_tparameter>(decl),
4394 && (!write_type_composition
4395 (dynamic_pointer_cast<type_composition>(decl),
4406 write_template_parameters(
const shared_ptr<template_decl> tmpl,
4407 write_context& ctxt,
unsigned indent)
4412 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4413 for (list<shared_ptr<template_parameter> >::const_iterator p =
4414 tmpl->get_template_parameters().begin();
4415 p != tmpl->get_template_parameters().end();
4417 write_template_parameter(*p, ctxt, nb_spaces);
4428 write_function_tdecl(
const shared_ptr<function_tdecl> decl,
4429 write_context& ctxt,
unsigned indent)
4434 ostream& o = ctxt.get_ostream();
4436 do_indent_to_level(ctxt, indent, 0);
4438 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
4440 write_location(decl, ctxt);
4442 write_visibility(decl, o);
4444 write_binding(decl, o);
4448 write_template_parameters(decl, ctxt, indent);
4450 write_function_decl(decl->get_pattern(), ctxt,
4452 get_indent_to_level(ctxt, indent, 1));
4454 do_indent_to_level(ctxt, indent, 0);
4456 o <<
"</function-template-decl>\n";
4473 write_class_tdecl(
const shared_ptr<class_tdecl> decl,
4474 write_context& ctxt,
unsigned indent)
4479 ostream& o = ctxt.get_ostream();
4481 do_indent_to_level(ctxt, indent, 0);
4483 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
4485 write_location(decl, ctxt);
4487 write_visibility(decl, o);
4491 write_template_parameters(decl, ctxt, indent);
4493 write_class_decl(decl->get_pattern(), ctxt,
4494 get_indent_to_level(ctxt, indent, 1));
4496 do_indent_to_level(ctxt, indent, 0);
4498 o <<
"</class-template-decl>\n";
4507 write_version_info(write_context& ctxt)
4509 ostream& o = ctxt.get_ostream();
4510 const config& c = ctxt.get_config();
4513 << c.get_format_major_version_number()
4514 <<
"." << c.get_format_minor_version_number()
4534 const corpus_sptr&
corpus,
4536 bool member_of_group)
4544 do_indent_to_level(ctxt, indent, 0);
4546 std::ostream& out = ctxt.get_ostream();
4548 out <<
"<abi-corpus ";
4550 write_version_info(ctxt);
4555 if (!ctxt.get_write_corpus_path())
4557 if (member_of_group)
4560 corpus_path.clear();
4564 if (ctxt.get_short_locs())
4567 if (!corpus_path.empty())
4571 && ctxt.get_write_architecture())
4577 write_tracking_non_reachable_types(
corpus, out);
4585 do_indent_to_level(ctxt, indent, 1);
4586 out <<
"<elf-needed>\n";
4588 get_indent_to_level(ctxt, indent, 2));
4589 do_indent_to_level(ctxt, indent, 1);
4590 out <<
"</elf-needed>\n";
4596 do_indent_to_level(ctxt, indent, 1);
4597 out <<
"<elf-function-symbols>\n";
4600 get_indent_to_level(ctxt, indent, 2));
4602 do_indent_to_level(ctxt, indent, 1);
4603 out <<
"</elf-function-symbols>\n";
4609 do_indent_to_level(ctxt, indent, 1);
4610 out <<
"<elf-variable-symbols>\n";
4613 get_indent_to_level(ctxt, indent, 2));
4615 do_indent_to_level(ctxt, indent, 1);
4616 out <<
"</elf-variable-symbols>\n";
4621 for (translation_units::const_iterator i =
4628 get_indent_to_level(ctxt, indent, 1),
4632 do_indent_to_level(ctxt, indent, 0);
4633 out <<
"</abi-corpus>\n";
4635 ctxt.clear_referenced_types();
4636 ctxt.record_corpus_as_emitted(
corpus);
4653 const corpus_group_sptr& group,
4660 do_indent_to_level(ctxt, indent, 0);
4662 std::ostream& out = ctxt.get_ostream();
4664 out <<
"<abi-corpus-group ";
4665 write_version_info(ctxt);
4667 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
4670 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
4671 out <<
" architecture='" << group->get_architecture_name()<<
"'";
4673 write_tracking_non_reachable_types(group, out);
4675 if (group->is_empty())
4684 for (corpus_group::corpora_type::const_iterator c =
4685 group->get_corpora().begin();
4686 c != group->get_corpora().end();
4690 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
4693 do_indent_to_level(ctxt, indent, 0);
4694 out <<
"</abi-corpus-group>\n";
4715 xml_writer::write_context ctxt(d->get_environment(), o);
4717 write_decl(d, ctxt, 0);
4759 xml_writer::write_context ctxt(v->get_environment(), o);
4761 write_var_decl(v, ctxt,
true, 0);
4830 unsigned line = 0, col = 0;
4832 l.
expand(path, line, col);
4833 o << path <<
":" << line <<
"," << col <<
"\n";
4883 #ifdef WITH_DEBUG_SELF_COMPARISON
4894 write_type_record(xml_writer::write_context& ctxt,
4895 const type_base* type,
4913 type_base* canonical = type->get_naked_canonical_type();
4917 id = ctxt.get_id_for_type (
const_cast<type_base*
>(type));
4920 <<
" <id>" <<
id <<
"</id>\n"
4923 <<
reinterpret_cast<uintptr_t
>(canonical)
4939 write_canonical_type_ids(xml_writer::write_context& ctxt, ostream& o)
4958 o <<
"<abixml-types-check>\n";
4960 for (
const auto &type : ctxt.get_emitted_types_set())
4961 write_type_record(ctxt, type, o);
4963 o <<
"</abixml-types-check>\n";
4976 write_canonical_type_ids(xml_writer::write_context& ctxt,
4977 const string &file_path)
4979 std:: ofstream o (file_path);
4983 write_canonical_type_ids(ctxt, o);
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Utilities to ease the wrapping of C types into std::shared_ptr.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
This type abstracts the configuration information of the library.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
virtual const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
virtual const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
const string & get_soname()
Getter for the soname property of the corpus.
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
virtual bool is_empty() const
Tests if the corpus is empty from an ABI surface perspective. I.e. if all of these criteria are true:
string & get_path() const
Get the file path associated to the corpus file.
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
The base type of all declarations.
const location & get_location() const
Get the location of a given declaration.
visibility
ELF visibility.
Abstraction of an elf symbol.
binding
The binding of a symbol.
type
The type of a symbol.
visibility
The visibility of the symbol.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
interned_string intern(const string &) const
Do intern a string.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
Abstraction of a function type.
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
The source location of a token.
bool get_is_artificial() const
Test if the location is artificial.
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
A declaration that introduces a scope.
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
char get_address_size() const
Getter of the address size in this translation unit.
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
const std::string & get_path() const
Get the path of the current translation unit.
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
const environment & get_environment() const
Getter of the environment of the current translation_unit.
language get_language() const
Getter of the language of the source code of the translation unit.
An abstraction helper for type declarations.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
The abstraction of a typedef declaration.
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
uint32_t fnv_hash(const std::string &str)
Compute a stable string hash.
The namespace of the internal representation of ABI artifacts like types and decls.
shared_ptr< type_tparameter > type_tparameter_sptr
Convenience typedef for a shared pointer to type_tparameter.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
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< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
unordered_map< interned_string, type_base_wptr, hash_interned_string > istring_type_base_wptr_map_type
A convenience typedef for a map which key is an interned_string and which value is a type_base_wptr.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
void set_short_locs(write_context &ctxt, bool flag)
Set the 'short-locs' flag.
write_context_sptr create_write_context(const environment &env, ostream &default_output_stream)
Create a write_context object that can be used to emit abixml files.
std::unordered_set< function_type * > fn_type_ptr_set_type
A convenience typedef for a set of function type*.
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.