23#include <unordered_map>
29#include "abg-internal.h"
31ABG_BEGIN_EXPORT_DECLARATIONS
42ABG_END_EXPORT_DECLARATIONS
49using std::dynamic_pointer_cast;
50using std::static_pointer_cast;
53using std::ostringstream;
57using std::unordered_map;
70 mutable unsigned long long m_cur_id;
74 {
return ++m_cur_id; }
82 get_environment()
const
92 return env.
intern(o.str());
100 get_id_with_prefix(
const string& prefix)
const
103 o << prefix << get_new_id();
105 return env.
intern(o.str());
115struct non_canonicalized_type_hash
134 return h(p->get_pretty_representation(
false,
150struct non_canonicalized_type_equal
176typedef std::unordered_set<const type_base*> type_ptr_set_type;
182typedef std::unordered_set<
const type_base*,
183 non_canonicalized_type_hash,
184 non_canonicalized_type_equal>
192 non_canonicalized_type_hash,
193 non_canonicalized_type_equal>
199typedef unordered_map<shared_ptr<function_tdecl>,
203typedef unordered_map<shared_ptr<class_tdecl>,
210 id_manager m_id_manager;
214 bool m_write_architecture;
215 bool m_write_corpus_path;
216 bool m_write_comp_dir;
217 bool m_write_elf_needed;
218 bool m_write_undefined_symbols;
219 bool m_write_parameter_names;
221 bool m_write_default_sizes;
225 mutable unordered_set<uint32_t> m_used_type_id_hashes;
226 mutable type_ptr_set_type m_emitted_type_set;
229 type_ptr_set_type m_referenced_types_set;
231 fn_tmpl_shared_ptr_map m_fn_tmpl_id_map;
232 class_tmpl_shared_ptr_map m_class_tmpl_id_map;
235 unordered_set<interned_string, hash_interned_string> m_emitted_decls_set;
236 unordered_set<string> m_emitted_corpora_set;
253 m_write_architecture(
true),
254 m_write_corpus_path(
true),
255 m_write_comp_dir(
true),
256 m_write_elf_needed(
true),
257 m_write_undefined_symbols(
true),
258 m_write_parameter_names(
true),
260 m_write_default_sizes(
true),
261 m_type_id_style(SEQUENCE_TYPE_ID_STYLE)
268 get_environment()
const
273 {
return get_environment().get_config();}
307 get_write_architecture()
308 {
return m_write_architecture;}
315 {m_write_architecture = f;}
321 get_write_elf_needed()
322 {
return m_write_elf_needed;}
329 {m_write_elf_needed = f;}
335 get_write_undefined_symbols()
const
336 {
return m_write_undefined_symbols;}
343 {m_write_undefined_symbols = f;}
349 get_write_default_sizes()
350 {
return m_write_default_sizes;}
357 {m_write_default_sizes = f;}
363 get_write_corpus_path()
364 {
return m_write_corpus_path;}
371 {m_write_corpus_path = f;}
378 {
return m_write_comp_dir;}
385 {m_write_comp_dir = f;}
392 {
return m_short_locs;}
405 get_write_parameter_names()
const
406 {
return m_write_parameter_names;}
413 {m_write_parameter_names = f;}
422 get_show_locs()
const
423 {
return m_show_locs;}
441 get_type_id_style()
const
442 {
return m_type_id_style;}
451 {m_type_id_style =
style;}
458 get_id_manager()
const
459 {
return m_id_manager;}
463 {
return m_id_manager;}
467 type_has_existing_id(type_base_sptr type)
const
468 {
return type_has_existing_id(type.get());}
472 type_has_existing_id(
type_base* type)
const
475 return m_type_id_map.find(type) != m_type_id_map.end();
483 get_id_for_type(
const type_base_sptr& t)
484 {
return get_id_for_type(t.get());}
495 auto it = m_type_id_map.find(c);
496 if (it != m_type_id_map.end())
499 switch (m_type_id_style)
501 case SEQUENCE_TYPE_ID_STYLE:
504 return m_type_id_map[c] = id;
506 case HASH_TYPE_ID_STYLE:
510 while (!m_used_type_id_hashes.insert(hash).second)
512 std::ostringstream os;
513 os << std::hex << std::setfill(
'0') << std::setw(8) << hash;
524 fn_tmpl_shared_ptr_map::const_iterator it = m_fn_tmpl_id_map.find(f);
525 if (it == m_fn_tmpl_id_map.end())
527 string id = get_id_manager().get_id_with_prefix(
"fn-tmpl-id-");
528 m_fn_tmpl_id_map[f] = id;
531 return m_fn_tmpl_id_map[f];
537 class_tmpl_shared_ptr_map::const_iterator it = m_class_tmpl_id_map.find(c);
538 if (it == m_class_tmpl_id_map.end())
540 string id = get_id_manager().get_id_with_prefix(
"class-tmpl-id-");
541 m_class_tmpl_id_map[c] = id;
544 return m_class_tmpl_id_map[c];
550 m_type_id_map.clear();
561 const type_ptr_set_type&
562 get_referenced_types()
const
563 {
return m_referenced_types_set;}
570 get_referenced_function_types()
const
571 {
return m_referenced_fn_types_set;}
577 has_non_emitted_referenced_types()
const
579 for (
const auto t : get_referenced_types())
580 if (!type_is_emitted(t))
592 record_type_as_referenced(
const type_base_sptr& type)
598 m_referenced_fn_types_set.insert(f);
600 m_referenced_types_set.insert(t);
611 type_is_referenced(
const type_base_sptr& type)
615 return (m_referenced_fn_types_set.find(f)
616 != m_referenced_fn_types_set.end());
618 return m_referenced_types_set.find(t) != m_referenced_types_set.end();
632 vector<type_base*>& sorted)
635 for (type_ptr_set_type::const_iterator i = types.begin();
638 sorted.push_back(
const_cast<type_base*
>(*i));
640 sort(sorted.begin(), sorted.end(), comp);
654 vector<type_base_sptr> &sorted)
656 for (istring_type_base_wptr_map_type::const_iterator i = types.begin();
659 sorted.push_back(type_base_sptr(i->second));
661 sort(sorted.begin(), sorted.end(), comp);
675 sort_types(
const vector<function_type_sptr>& types,
676 vector<type_base_sptr> &sorted)
678 for (vector<function_type_sptr>::const_iterator i = types.begin();
681 sorted.push_back(*i);
683 sort(sorted.begin(), sorted.end(), comp);
690 record_type_as_emitted(
const type_base_sptr &t)
691 {record_type_as_emitted(t.get());}
697 record_type_as_emitted(
const type_base* t)
700 m_emitted_type_set.insert(c);
710 type_is_emitted(
const type_base* t)
const
713 return (m_emitted_type_set.find(c) != m_emitted_type_set.end());
723 type_is_emitted(
const type_base_sptr& t)
const
724 {
return type_is_emitted(t.get());}
733 decl_is_emitted(
const decl_base& decl)
const
737 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
747 decl_is_emitted(
const decl_base_sptr& decl)
const
752 return m_emitted_decls_set.find(irepr) != m_emitted_decls_set.end();
759 record_decl_as_emitted(
const decl_base_sptr& decl)
763 m_emitted_decls_set.insert(irepr);
775 corpus_is_emitted(
const corpus_sptr& corp)
780 if (m_emitted_corpora_set.find(corp->get_path())
781 == m_emitted_corpora_set.end())
791 record_corpus_as_emitted(
const corpus_sptr& corp)
796 const string& path = corp->get_path();
799 m_emitted_corpora_set.insert(path);
805 const type_ptr_set_type&
806 get_emitted_types_set()
const
807 {
return m_emitted_type_set;}
812 clear_referenced_types()
814 m_referenced_types_set.clear();
815 m_referenced_fn_types_set.clear();
819 get_fun_symbol_map()
const
820 {
return m_fun_symbol_map;}
824 {
return m_fun_symbol_map;}
828static void write_location(
const location&, write_context&);
829static void write_location(
const decl_base_sptr&, write_context&);
830static bool write_visibility(
const decl_base_sptr&, ostream&);
831static bool write_binding(
const decl_base_sptr&, ostream&);
832static bool write_is_artificial(
const decl_base_sptr&, ostream&);
833static bool write_is_non_reachable(
const type_base_sptr&, ostream&);
834static bool write_tracking_non_reachable_types(
const corpus_sptr&, ostream&);
837static void write_size_and_alignment(
const type_base_sptr, ostream&,
838 size_t default_size = 0,
839 size_t default_alignment = 0);
843static void write_cdtor_const_static(
bool,
bool,
bool,
bool, ostream&);
847static bool write_elf_symbol_aliases(
const elf_symbol&, ostream&);
848static bool write_elf_symbol_reference(write_context&,
852static bool write_elf_symbol_reference(write_context&,
856static void write_is_declaration_only(
const decl_base_sptr&, ostream&);
858static void write_is_anonymous(
const decl_base_sptr&, ostream&);
859static void write_naming_typedef(
const decl_base_sptr&, write_context&);
860static bool write_decl(
const decl_base_sptr&, write_context&,
unsigned);
861static void write_decl_in_scope(
const decl_base_sptr&,
862 write_context&,
unsigned);
863static bool write_type_decl(
const type_decl_sptr&, write_context&,
unsigned);
865 write_context&,
unsigned);
866static bool write_qualified_type_def(
const qualified_type_def_sptr&,
867 write_context&,
unsigned);
869 write_context&,
unsigned);
871 write_context&,
unsigned);
873 write_context&,
unsigned);
875 write_context&,
unsigned);
880 write_context&,
unsigned);
882 write_context&,
unsigned);
884 write_context&,
unsigned);
885static bool write_elf_symbols_table(
const elf_symbols&,
886 write_context&,
unsigned);
888 write_context&,
bool,
unsigned);
890 write_context&,
bool,
unsigned);
892 write_context&,
unsigned);
893static bool write_member_type_opening_tag(
const type_base_sptr&,
894 write_context&,
unsigned);
895static bool write_member_type(
const type_base_sptr&,
896 write_context&,
unsigned);
897static bool write_class_decl_opening_tag(
const class_decl_sptr&,
const string&,
898 write_context&,
unsigned,
bool);
900 write_context&,
unsigned);
901static bool write_union_decl_opening_tag(
const union_decl_sptr&,
const string&,
902 write_context&,
unsigned,
bool);
903static bool write_union_decl(
const union_decl_sptr&,
const string&,
904 write_context&,
unsigned);
905static bool write_union_decl(
const union_decl_sptr&, write_context&,
unsigned);
906static bool write_type_tparameter
907(
const shared_ptr<type_tparameter>, write_context&,
unsigned);
908static bool write_non_type_tparameter
909(
const shared_ptr<non_type_tparameter>, write_context&,
unsigned);
910static bool write_template_tparameter
911(
const shared_ptr<template_tparameter>, write_context&,
unsigned);
912static bool write_type_composition
913(
const shared_ptr<type_composition>, write_context&,
unsigned);
914static bool write_template_parameter(
const shared_ptr<template_parameter>,
915 write_context&,
unsigned);
916static void write_template_parameters(
const shared_ptr<template_decl>,
917 write_context&,
unsigned);
918static bool write_function_tdecl
919(
const shared_ptr<function_tdecl>,
920 write_context&,
unsigned);
921static bool write_class_tdecl
922(
const shared_ptr<class_tdecl>,
923 write_context&,
unsigned);
924static void do_indent(ostream&,
unsigned);
925static void do_indent_to_level(write_context&,
unsigned,
unsigned);
926static unsigned get_indent_to_level(write_context&,
unsigned,
unsigned);
930do_indent(ostream& o,
unsigned nb_whitespaces)
932 for (
unsigned i = 0; i < nb_whitespaces; ++i)
944do_indent_to_level(write_context& ctxt,
945 unsigned initial_indent,
948 do_indent(ctxt.get_ostream(),
949 get_indent_to_level(ctxt, initial_indent, level));
961get_indent_to_level(write_context& ctxt,
unsigned initial_indent,
964 int nb_ws = initial_indent +
965 level * ctxt.get_config().get_xml_element_indent();
987annotate(
const T& decl,
994 if (!ctxt.get_annotate())
997 ostream& o = ctxt.get_ostream();
999 do_indent(o, indent);
1021 write_context& ctxt,
1027 if (!ctxt.get_annotate())
1030 ostream& o = ctxt.get_ostream();
1032 do_indent(o, indent);
1052 write_context& ctxt,
1058 if (!ctxt.get_annotate())
1061 ostream& o = ctxt.get_ostream();
1063 do_indent(o, indent);
1065 o <<
"<!-- typedef "
1088 write_context& ctxt,
1094 if (!ctxt.get_annotate())
1097 ostream& o = ctxt.get_ostream();
1099 do_indent(o, indent);
1121 write_context& ctxt,
1127 if (!ctxt.get_annotate())
1130 ostream& o = ctxt.get_ostream();
1132 do_indent(o, indent);
1144 vector<function_decl::parameter_sptr>::const_iterator pi =
1145 fn->get_first_non_implicit_parm();
1147 for (; pi != fn->get_parameters().end(); ++pi)
1151 if (distance(pi, fn->get_parameters().end()) > 1)
1171 write_context& ctxt,
1177 if (!ctxt.get_annotate())
1180 ostream &o = ctxt.get_ostream();
1182 do_indent(o, indent);
1186 if (parm->get_variadic_marker())
1187 o <<
"variadic parameter";
1190 if (parm->get_is_artificial())
1192 if (parm->get_index() == 0)
1197 o <<
"parameter of type '"
1216write_location(
const location& loc, write_context& ctxt)
1221 if (!ctxt.get_show_locs())
1225 unsigned line = 0, column = 0;
1227 loc.
expand(filepath, line, column);
1229 ostream &o = ctxt.get_ostream();
1231 if (ctxt.get_short_locs())
1235 <<
" line='" << line <<
"'"
1236 <<
" column='" << column <<
"'";
1247write_location(
const decl_base_sptr& decl,
1248 write_context& ctxt)
1253 location loc = decl->get_location();
1257 write_location(loc, ctxt);
1269write_visibility(
const shared_ptr<decl_base>& decl, ostream& o)
1279 case decl_base::VISIBILITY_NONE:
1281 case decl_base::VISIBILITY_DEFAULT:
1284 case decl_base::VISIBILITY_PROTECTED:
1287 case decl_base::VISIBILITY_HIDDEN:
1290 case decl_base::VISIBILITY_INTERNAL:
1298 o <<
" visibility='" << str <<
"'";
1309write_binding(
const shared_ptr<decl_base>& decl, ostream& o)
1316 shared_ptr<var_decl> var =
1317 dynamic_pointer_cast<var_decl>(decl);
1319 bind = var->get_binding();
1322 shared_ptr<function_decl> fun =
1323 dynamic_pointer_cast<function_decl>(decl);
1325 bind = fun->get_binding();
1331 case decl_base::BINDING_NONE:
1333 case decl_base::BINDING_LOCAL:
1336 case decl_base::BINDING_GLOBAL:
1339 case decl_base::BINDING_WEAK:
1345 o <<
" binding='" << str <<
"'";
1359write_is_artificial(
const decl_base_sptr& decl, ostream& o)
1364 if (decl->get_is_artificial())
1365 o <<
" is-artificial='yes'";
1379write_is_non_reachable(
const type_base_sptr& t, ostream& o)
1384 corpus* c = t->get_corpus();
1388 if (!c->recording_types_reachable_from_public_interface_supported()
1389 || c->type_is_reachable_from_public_interfaces(*t))
1392 o <<
" is-non-reachable='yes'";
1405write_tracking_non_reachable_types(
const corpus_sptr& corpus,
1408 corpus_group* group = corpus->get_group();
1410 if (corpus->recording_types_reachable_from_public_interface_supported())
1412 o <<
" tracking-non-reachable-types='yes'";
1433write_size_and_alignment(
const shared_ptr<type_base> decl, ostream& o,
1434 size_t default_size,
size_t default_alignment)
1436 size_t size_in_bits = decl->get_size_in_bits();
1437 if (size_in_bits != default_size)
1438 o <<
" size-in-bits='" << size_in_bits <<
"'";
1440 size_t alignment_in_bits = decl->get_alignment_in_bits();
1441 if (alignment_in_bits != default_alignment)
1442 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1450write_array_size_and_alignment(
const shared_ptr<array_type_def> decl, ostream& o)
1452 if (decl->is_non_finite())
1453 o <<
" size-in-bits='" <<
"unknown" <<
"'";
1455 size_t size_in_bits = decl->get_size_in_bits();
1457 o <<
" size-in-bits='" << size_in_bits <<
"'";
1460 size_t alignment_in_bits = decl->get_alignment_in_bits();
1461 if (alignment_in_bits)
1462 o <<
" alignment-in-bits='" << alignment_in_bits <<
"'";
1472 string access_str =
"private";
1476 case private_access:
1477 access_str =
"private";
1480 case protected_access:
1481 access_str =
"protected";
1485 access_str =
"public";
1492 o <<
" access='" << access_str <<
"'";
1503 o <<
" layout-offset-in-bits='"
1510write_layout_offset(shared_ptr<class_decl::base_spec> base, ostream& o)
1515 if (base->get_offset_in_bits() >= 0)
1516 o <<
" layout-offset-in-bits='" << base->get_offset_in_bits() <<
"'";
1525write_access(decl_base_sptr member, ostream& o)
1542 o <<
" vtable-offset='" << voffset <<
"'";
1559 case elf_symbol::NOTYPE_TYPE:
1562 case elf_symbol::OBJECT_TYPE:
1563 repr =
"object-type";
1565 case elf_symbol::FUNC_TYPE:
1568 case elf_symbol::SECTION_TYPE:
1569 repr =
"section-type";
1571 case elf_symbol::FILE_TYPE:
1574 case elf_symbol::COMMON_TYPE:
1575 repr =
"common-type";
1577 case elf_symbol::TLS_TYPE:
1580 case elf_symbol::GNU_IFUNC_TYPE:
1581 repr =
"gnu-ifunc-type";
1588 o <<
" type='" << repr <<
"'";
1604 case elf_symbol::LOCAL_BINDING:
1605 repr =
"local-binding";
1607 case elf_symbol::GLOBAL_BINDING:
1608 repr =
"global-binding";
1610 case elf_symbol::WEAK_BINDING:
1611 repr =
"weak-binding";
1613 case elf_symbol::GNU_UNIQUE_BINDING:
1614 repr =
"gnu-unique-binding";
1617 repr =
"no-binding";
1621 o <<
" binding='" << repr <<
"'";
1637 case elf_symbol::DEFAULT_VISIBILITY:
1638 repr =
"default-visibility";
1640 case elf_symbol::PROTECTED_VISIBILITY:
1641 repr =
"protected-visibility";
1643 case elf_symbol::HIDDEN_VISIBILITY:
1644 repr =
"hidden-visibility";
1646 case elf_symbol::INTERNAL_VISIBILITY:
1647 repr =
"internal-visibility";
1650 repr =
"default-visibility";
1654 o <<
" visibility='" << repr <<
"'";
1665write_elf_symbol_aliases(
const elf_symbol& sym, ostream& out)
1667 if (!sym.is_main_symbol() || !sym.has_aliases())
1671 std::vector<std::string> aliases;
1672 for (
elf_symbol_sptr s = sym.get_next_alias(); s && !s->is_main_symbol();
1673 s = s->get_next_alias())
1675 if (!s->is_public())
1678 if (s->is_suppressed())
1681 if (sym.is_in_ksymtab() != s->is_in_ksymtab())
1684 aliases.push_back(s->get_id_string());
1687 if (!aliases.empty())
1690 std::string separator;
1691 for (
const auto& alias : aliases)
1693 out << separator << alias;
1720write_elf_symbol_reference(write_context& ctxt,
1721 const elf_symbol& sym,
1727 s = abi.lookup_variable_symbol(sym);
1733 || (!ctxt.get_write_undefined_symbols() && !s->is_defined()))
1737 const elf_symbol* main = sym.get_main_symbol().get();
1738 const elf_symbol* alias = &sym;
1739 bool found = !alias->is_suppressed();
1744 found = !alias->is_suppressed();
1749 alias = alias->get_next_alias().get();
1751 if (!alias || alias == main)
1753 found = !alias->is_suppressed();
1758 o <<
" elf-symbol-id='"
1779write_elf_symbol_reference(write_context& ctxt,
1787 return write_elf_symbol_reference(ctxt, *sym, abi, o);
1804write_cdtor_const_static(
bool is_ctor,
1811 o <<
" static='yes'";
1813 o <<
" constructor='yes'";
1815 o <<
" destructor='yes'";
1817 o <<
" const='yes'";
1827write_is_declaration_only(
const decl_base_sptr& d, ostream& o)
1829 if (d->get_is_declaration_only())
1830 o <<
" is-declaration-only='yes'";
1842 if (klass->is_struct())
1843 o <<
" is-struct='yes'";
1853write_is_anonymous(
const decl_base_sptr& decl, ostream& o)
1855 if (decl->get_is_anonymous())
1856 o <<
" is-anonymous='yes'";
1866write_naming_typedef(
const decl_base_sptr& decl, write_context& ctxt)
1871 ostream &o = ctxt.get_ostream();
1875 string id = ctxt.get_id_for_type(typedef_type);
1876 o <<
" naming-typedef-id='" <<
id <<
"'";
1877 ctxt.record_type_as_referenced(typedef_type);
1891write_type(
const type_base_sptr& type, write_context& ctxt,
unsigned indent)
1893 if (write_type_decl(dynamic_pointer_cast<type_decl> (type),
1895 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1898 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(type),
1900 || write_reference_type_def(dynamic_pointer_cast
1901 <reference_type_def>(type), ctxt, indent)
1902 || write_ptr_to_mbr_type(dynamic_pointer_cast
1903 <ptr_to_mbr_type>(type),
1905 || write_array_type_def(dynamic_pointer_cast
1906 <array_type_def>(type), ctxt, indent)
1907 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(type),
1909 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(type),
1913 || (write_function_tdecl
1914 (dynamic_pointer_cast<function_tdecl>(type), ctxt, indent))
1915 || (write_class_tdecl
1916 (dynamic_pointer_cast<class_tdecl>(type), ctxt, indent)))
1934write_decl(
const decl_base_sptr& decl, write_context& ctxt,
unsigned indent)
1936 if (write_type_decl(dynamic_pointer_cast<type_decl> (decl),
1938 || write_namespace_decl(dynamic_pointer_cast<namespace_decl>(decl),
1940 || write_qualified_type_def (dynamic_pointer_cast<qualified_type_def>
1943 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(decl),
1945 || write_reference_type_def(dynamic_pointer_cast
1946 <reference_type_def>(decl), ctxt, indent)
1947 || write_ptr_to_mbr_type(dynamic_pointer_cast
1948 <ptr_to_mbr_type>(decl),
1950 || write_array_type_def(dynamic_pointer_cast
1951 <array_type_def>(decl), ctxt, indent)
1952 || write_array_subrange_type(dynamic_pointer_cast
1953 <array_type_def::subrange_type>(decl),
1955 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(decl),
1957 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(decl),
1959 || write_var_decl(dynamic_pointer_cast<var_decl>(decl), ctxt,
1961 || write_function_decl(dynamic_pointer_cast<method_decl>
1964 || write_function_decl(dynamic_pointer_cast<function_decl>(decl),
1965 ctxt,
false, indent)
1968 || (write_function_tdecl
1969 (dynamic_pointer_cast<function_tdecl>(decl), ctxt, indent))
1970 || (write_class_tdecl
1971 (dynamic_pointer_cast<class_tdecl>(decl), ctxt, indent)))
1989write_decl_in_scope(
const decl_base_sptr& decl,
1990 write_context& ctxt,
1991 unsigned initial_indent)
1993 type_base_sptr type =
is_type(decl);
1996 if (ctxt.type_is_emitted(type))
1999 list<scope_decl*> scopes;
2000 for (scope_decl* s = decl->get_scope();
2003 scopes.push_front(s);
2005 ostream& o = ctxt.get_ostream();
2006 const config& c = ctxt.get_config();
2007 stack<string> closing_tags;
2008 stack<unsigned> closing_indents;
2009 unsigned indent = initial_indent;
2010 for (list<scope_decl*>::const_iterator i = scopes.begin();
2019 do_indent(o, indent);
2020 o <<
"<namespace-decl name='"
2023 closing_tags.push(
"</namespace-decl>");
2024 closing_indents.push(indent);
2031 if (!ctxt.type_is_emitted(c))
2033 write_type(class_type, ctxt, initial_indent);
2038 write_class_decl_opening_tag(class_type,
"", ctxt, indent,
2040 closing_tags.push(
"</class-decl>");
2041 closing_indents.push(indent);
2043 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2044 write_member_type_opening_tag(type, ctxt, nb_ws);
2046 closing_tags.push(
"</member-type>");
2047 closing_indents.push(nb_ws);
2053 union_decl_sptr union_type(u, noop_deleter());
2054 if (!ctxt.type_is_emitted(u))
2056 write_type(union_type, ctxt, initial_indent);
2061 write_union_decl_opening_tag(union_type,
"", ctxt, indent,
2063 closing_tags.push(
"</union-decl>");
2064 closing_indents.push(indent);
2066 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
2067 write_member_type_opening_tag(type, ctxt, nb_ws);
2069 closing_tags.push(
"</member-type>");
2070 closing_indents.push(nb_ws);
2076 indent += c.get_xml_element_indent();
2079 bool do_write =
false;
2080 if (type_base_sptr type =
is_type(decl))
2082 if (!ctxt.type_is_emitted(type))
2087 if (!ctxt.decl_is_emitted(decl))
2092 write_decl(decl, ctxt, indent);
2094 while (!closing_tags.empty())
2096 do_indent(o, closing_indents.top());
2097 o << closing_tags.top() <<
"\n";
2099 closing_indents.pop();
2113 ostream& default_output_stream)
2130{ctxt.set_show_locs(flag);}
2142{ctxt.set_annotate(flag);}
2153{ctxt.set_ostream(os);}
2165{ctxt.set_write_architecture(flag);}
2177{ctxt.set_write_corpus_path(flag);}
2189{ctxt.set_write_comp_dir(flag);}
2201{ctxt.set_short_locs(flag);}
2213{ctxt.set_write_parameter_names(flag);}
2225{ctxt.set_write_elf_needed(flag);}
2237{ctxt.set_write_undefined_symbols(flag);}
2252{ctxt.set_write_default_sizes(flag);}
2263{ctxt.set_type_id_style(
style);}
2278write_canonical_types_of_scope(
const scope_decl &scope,
2279 write_context &ctxt,
2280 const unsigned indent,
2286 for (type_base_sptrs_type::const_iterator i = canonical_types.begin();
2287 i != canonical_types.end();
2290 if (ctxt.type_is_emitted(*i))
2293 write_member_type(*i, ctxt, indent);
2295 write_type(*i, ctxt, indent);
2317referenced_type_should_be_emitted(
const type_base *t,
2318 const write_context& ctxt,
2319 const translation_unit& tu,
2322 if ((tu_is_last || (t->get_translation_unit()
2323 && (t->get_translation_unit()->get_absolute_path()
2324 == tu.get_absolute_path())))
2325 && !ctxt.type_is_emitted(t))
2342write_referenced_types(write_context & ctxt,
2343 const translation_unit& tu,
2344 const unsigned indent,
2347 const config& c = ctxt.get_config();
2355 type_ptr_set_type referenced_types_to_emit;
2360 for (type_ptr_set_type::const_iterator i =
2361 ctxt.get_referenced_types().begin();
2362 i != ctxt.get_referenced_types().end();
2364 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2365 referenced_types_to_emit.insert(*i);
2367 for (fn_type_ptr_set_type::const_iterator i =
2368 ctxt.get_referenced_function_types().begin();
2369 i != ctxt.get_referenced_function_types().end();
2371 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2372 referenced_types_to_emit.insert(*i);
2375 while (!referenced_types_to_emit.empty())
2380 vector<type_base*> sorted_referenced_types;
2381 ctxt.sort_types(referenced_types_to_emit,
2382 sorted_referenced_types);
2385 for (vector<type_base*>::const_iterator i =
2386 sorted_referenced_types.begin();
2387 i != sorted_referenced_types.end();
2393 if (!ctxt.type_is_emitted(t))
2397 decl_base_sptr decl(d, noop_deleter());
2398 write_decl_in_scope(decl, ctxt,
2399 indent + c.get_xml_element_indent());
2404 write_function_type(fn_type, ctxt,
2405 indent + c.get_xml_element_indent());
2414 referenced_types_to_emit.clear();
2426 for (type_ptr_set_type::const_iterator i =
2427 ctxt.get_referenced_types().begin();
2428 i != ctxt.get_referenced_types().end();
2430 if (referenced_type_should_be_emitted(*i, ctxt, tu, is_last))
2431 referenced_types_to_emit.insert(*i);
2459 const unsigned indent,
2467 && ctxt.has_non_emitted_referenced_types())
2470 ostream& o = ctxt.get_ostream();
2471 const config& c = ctxt.get_config();
2473 do_indent(o, indent);
2480 std::string tu_path = tu.
get_path();
2481 if (ctxt.get_short_locs())
2483 if (!tu_path.empty())
2487 o <<
" comp-dir-path='"
2490 if (tu.
get_language() != translation_unit::LANG_UNKNOWN)
2504 ctxt, indent + c.get_xml_element_indent());
2507 const declarations& decls = tu.
get_global_scope()->get_sorted_member_decls();
2509 for (
const decl_base_sptr& decl : decls)
2511 if (type_base_sptr t =
is_type(decl))
2518 if (class_type->get_is_declaration_only()
2519 && !ctxt.type_is_emitted(class_type))
2520 write_type(class_type, ctxt,
2521 indent + c.get_xml_element_indent());
2524 write_type(t, ctxt, indent + c.get_xml_element_indent());
2528 if (!ctxt.decl_is_emitted(decl))
2529 write_decl(decl, ctxt, indent + c.get_xml_element_indent());
2536 for (
auto undefined_function : abi->get_sorted_undefined_functions())
2540 if (f->get_translation_unit() != &tu || ctxt.decl_is_emitted(f))
2543 write_decl(f, ctxt, indent + c.get_xml_element_indent());
2549 for (
auto undefined_var : abi->get_sorted_undefined_variables())
2553 if (v->get_translation_unit() != &tu || ctxt.decl_is_emitted(v))
2556 write_decl(v, ctxt, indent + c.get_xml_element_indent());
2559 write_referenced_types(ctxt, tu, indent, is_last);
2564 vector<type_base_sptr> sorted_types;
2565 ctxt.sort_types(t, sorted_types);
2567 for (vector<type_base_sptr>::const_iterator i = sorted_types.begin();
2568 i != sorted_types.end();
2573 if (fn_type->get_is_artificial() || ctxt.type_is_emitted(fn_type))
2580 write_function_type(fn_type, ctxt, indent + c.get_xml_element_indent());
2585 write_referenced_types(ctxt, tu, indent, is_last);
2587 do_indent(o, indent);
2588 o <<
"</abi-instr>\n";
2606write_type_decl(
const type_decl_sptr& d, write_context& ctxt,
unsigned indent)
2611 ostream& o = ctxt.get_ostream();
2613 annotate(d, ctxt, indent);
2615 do_indent(o, indent);
2619 write_is_anonymous(d, o);
2621 write_size_and_alignment(d, o);
2623 write_is_declaration_only(d, o);
2625 write_location(d, ctxt);
2627 o <<
" id='" << ctxt.get_id_for_type(d) <<
"'" <<
"/>\n";
2629 ctxt.record_type_as_emitted(d);
2647 write_context& ctxt,
unsigned indent)
2649 if (!decl || decl->is_empty_or_has_empty_sub_namespaces())
2652 ostream& o = ctxt.get_ostream();
2653 const config &c = ctxt.get_config();
2655 annotate(decl, ctxt, indent);
2657 do_indent(o, indent);
2659 o <<
"<namespace-decl name='"
2664 typedef declarations::const_iterator const_iterator;
2665 const declarations& d = decl->get_sorted_member_decls();
2667 write_canonical_types_of_scope(*decl, ctxt,
2668 indent + c.get_xml_element_indent());
2670 for (const_iterator i = d.begin(); i != d.end(); ++i)
2672 if (type_base_sptr t =
is_type(*i))
2673 if (ctxt.type_is_emitted(t))
2677 write_decl(*i, ctxt, indent + c.get_xml_element_indent());
2680 do_indent(o, indent);
2681 o <<
"</namespace-decl>\n";
2705write_qualified_type_def(
const qualified_type_def_sptr& decl,
2707 write_context& ctxt,
2713 ostream& o = ctxt.get_ostream();
2716 type_base_sptr underlying_type = decl->get_underlying_type();
2718 annotate(decl, ctxt, indent);
2720 do_indent(o, indent);
2721 o <<
"<qualified-type-def type-id='"
2722 << ctxt.get_id_for_type(underlying_type)
2725 ctxt.record_type_as_referenced(underlying_type);
2727 if (decl->get_cv_quals() & qualified_type_def::CV_CONST)
2728 o <<
" const='yes'";
2729 if (decl->get_cv_quals() & qualified_type_def::CV_VOLATILE)
2730 o <<
" volatile='yes'";
2731 if (decl->get_cv_quals() & qualified_type_def::CV_RESTRICT)
2732 o <<
" restrict='yes'";
2734 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2738 i = ctxt.get_id_for_type(decl);
2740 o <<
" id='" << i <<
"'/>\n";
2742 ctxt.record_type_as_emitted(decl);
2758write_qualified_type_def(
const qualified_type_def_sptr& decl,
2759 write_context& ctxt,
2761{
return write_qualified_type_def(decl,
"", ctxt, indent);}
2783 write_context& ctxt,
2789 ostream& o = ctxt.get_ostream();
2791 annotate(decl, ctxt, indent);
2793 do_indent(o, indent);
2797 o <<
"<pointer-type-def ";
2799 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2801 i = ctxt.get_id_for_type(pointed_to_type);
2803 o <<
"type-id='" << i <<
"'";
2805 ctxt.record_type_as_referenced(pointed_to_type);
2807 write_size_and_alignment(decl, o,
2808 (ctxt.get_write_default_sizes()
2810 : decl->get_translation_unit()->get_address_size()),
2815 i = ctxt.get_id_for_type(decl);
2817 o <<
" id='" << i <<
"'";
2819 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2822 ctxt.record_type_as_emitted(decl);
2838 write_context& ctxt,
2840{
return write_pointer_type_def(decl,
"", ctxt, indent);}
2862 write_context& ctxt,
2868 annotate(decl->get_canonical_type(), ctxt, indent);
2870 ostream& o = ctxt.get_ostream();
2872 do_indent(o, indent);
2874 o <<
"<reference-type-def kind='";
2875 if (decl->is_lvalue())
2881 type_base_sptr pointed_to_type = decl->get_pointed_to_type();
2882 o <<
" type-id='" << ctxt.get_id_for_type(pointed_to_type) <<
"'";
2884 ctxt.record_type_as_referenced(pointed_to_type);
2887 ctxt.record_type_as_referenced(f);
2889 write_size_and_alignment(decl, o,
2890 (ctxt.get_write_default_sizes()
2892 : decl->get_translation_unit()->get_address_size()),
2897 i = ctxt.get_id_for_type(decl);
2898 o <<
" id='" << i <<
"'";
2900 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2904 ctxt.record_type_as_emitted(decl);
2920 write_context& ctxt,
2922{
return write_reference_type_def(decl,
"", ctxt, indent);}
2938 const string&
id, write_context& ctxt,
2944 annotate(decl->get_canonical_type(), ctxt, indent);
2946 ostream& o = ctxt.get_ostream();
2948 do_indent(o, indent);
2950 o <<
"<pointer-to-member-type";
2952 write_size_and_alignment(decl, o,
2953 (ctxt.get_write_default_sizes()
2955 : decl->get_translation_unit()->get_address_size()),
2958 write_location(static_pointer_cast<decl_base>(decl), ctxt);
2960 type_base_sptr member_type = decl->get_member_type();
2961 string i = ctxt.get_id_for_type(member_type);
2962 o <<
" member-type-id='" << i <<
"'";
2963 ctxt.record_type_as_referenced(member_type);
2965 type_base_sptr containing_type = decl->get_containing_type();
2966 i = ctxt.get_id_for_type(containing_type);
2967 o <<
" containing-type-id='" << i <<
"'";
2968 ctxt.record_type_as_referenced(containing_type);
2972 i = ctxt.get_id_for_type(decl);
2973 o <<
" id ='" << i <<
"'";
2977 ctxt.record_type_as_emitted(decl);
2993 write_context& ctxt,
unsigned indent)
2994{
return write_ptr_to_mbr_type(decl,
"", ctxt, indent);}
3007 write_context& ctxt,
3013 annotate(decl, ctxt, indent);
3015 ostream& o = ctxt.get_ostream();
3017 do_indent(o, indent);
3021 if (!decl->get_name().empty())
3022 o <<
" name='" << decl->get_name() <<
"'";
3025 if (decl->is_non_finite())
3028 o << decl->get_length();
3033 || decl->get_length() == 0
3034 || (decl->get_length() ==
3035 (uint64_t) (decl->get_upper_bound()
3036 - decl->get_lower_bound() + 1)));
3037 o <<
" lower-bound='" << decl->get_lower_bound() <<
"' upper-bound='"
3038 << decl->get_upper_bound() <<
"'";
3040 type_base_sptr underlying_type = decl->get_underlying_type();
3041 if (underlying_type)
3044 << ctxt.get_id_for_type(underlying_type)
3046 ctxt.record_type_as_referenced(underlying_type);
3049 o <<
" id='" << ctxt.get_id_for_type(decl) <<
"'";
3051 write_location(decl->get_location(), ctxt);
3055 ctxt.record_type_as_emitted(decl);
3080 write_context& ctxt,
3086 annotate(decl, ctxt, indent);
3088 ostream& o = ctxt.get_ostream();
3090 do_indent(o, indent);
3091 o <<
"<array-type-def";
3093 o <<
" dimensions='" << decl->get_dimension_count() <<
"'";
3095 type_base_sptr element_type = decl->get_element_type();
3096 o <<
" type-id='" << ctxt.get_id_for_type(element_type) <<
"'";
3098 ctxt.record_type_as_referenced(element_type);
3100 write_array_size_and_alignment(decl, o);
3104 i = ctxt.get_id_for_type(decl);
3105 o <<
" id='" << i <<
"'";
3107 write_location(static_pointer_cast<decl_base>(decl), ctxt);
3109 if (!decl->get_dimension_count())
3115 vector<array_type_def::subrange_sptr>::const_iterator si;
3117 for (si = decl->get_subranges().begin();
3118 si != decl->get_subranges().end(); ++si)
3120 unsigned local_indent =
3121 indent + ctxt.get_config().get_xml_element_indent();
3122 write_array_subrange_type(*si, ctxt, local_indent);
3125 do_indent(o, indent);
3126 o <<
"</array-type-def>\n";
3129 ctxt.record_type_as_emitted(decl);
3145 write_context& ctxt,
3147{
return write_array_type_def(decl,
"", ctxt, indent);}
3169 write_context& ctxt,
3177 annotate(decl->get_canonical_type(), ctxt, indent);
3179 ostream& o = ctxt.get_ostream();
3181 do_indent(o, indent);
3184 write_is_anonymous(decl, o);
3185 write_naming_typedef(decl, ctxt);
3186 write_is_artificial(decl, o);
3187 write_is_non_reachable(
is_type(decl), o);
3189 if (!decl->get_linkage_name().empty())
3190 o <<
" linkage-name='"
3194 write_location(decl, ctxt);
3195 write_is_declaration_only(decl, o);
3199 i = ctxt.get_id_for_type(decl);
3200 o <<
" id='" << i <<
"'>\n";
3202 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3203 o <<
"<underlying-type type-id='"
3204 << ctxt.get_id_for_type(decl->get_underlying_type())
3207 for (enum_type_decl::enumerators::const_iterator i =
3208 decl->get_enumerators().begin();
3209 i != decl->get_enumerators().end();
3212 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3213 o <<
"<enumerator name='"
3220 do_indent(o, indent);
3221 o <<
"</enum-decl>\n";
3223 ctxt.record_type_as_emitted(decl);
3239 write_context& ctxt,
3241{
return write_enum_type_decl(decl,
"", ctxt, indent);}
3255 write_context& ctxt,
3261 ostream &o = ctxt.get_ostream();
3263 annotate(sym, ctxt, indent);
3264 do_indent(o, indent);
3266 if (sym->is_variable() && sym->get_size())
3267 o <<
" size='" << sym->get_size() <<
"'";
3269 if (!sym->get_version().is_empty())
3271 o <<
" version='" << sym->get_version().str() <<
"'";
3272 o <<
" is-default-version='";
3273 if (sym->get_version().is_default())
3280 write_elf_symbol_type(sym->get_type(), o);
3282 write_elf_symbol_binding(sym->get_binding(), o);
3284 write_elf_symbol_visibility(sym->get_visibility(), o);
3286 write_elf_symbol_aliases(*sym, o);
3288 o <<
" is-defined='";
3289 if (sym->is_defined())
3295 if (sym->is_common_symbol())
3296 o <<
" is-common='yes'";
3298 if (sym->get_crc().has_value())
3300 << std::hex << std::showbase << sym->get_crc().value()
3301 << std::dec << std::noshowbase <<
"'";
3303 if (sym->get_namespace().has_value())
3304 o <<
" namespace='" << sym->get_namespace().value() <<
"'";
3323 write_context& ctxt,
3329 for (elf_symbols::const_iterator it = syms.begin(); it != syms.end(); ++it)
3330 write_elf_symbol(*it, ctxt, indent);
3346write_elf_needed(
const vector<string>& needed,
3347 write_context& ctxt,
3353 ostream& o = ctxt.get_ostream();
3355 for (vector<string>::const_iterator i = needed.begin();
3359 do_indent(o, indent);
3360 o <<
"<dependency name='" << *i <<
"'/>\n";
3385 write_context& ctxt,
3391 ostream &o = ctxt.get_ostream();
3393 annotate(decl, ctxt, indent);
3395 do_indent(o, indent);
3397 o <<
"<typedef-decl name='"
3401 type_base_sptr underlying_type = decl->get_underlying_type();
3402 string type_id = ctxt.get_id_for_type(underlying_type);
3403 o <<
" type-id='" << type_id <<
"'";
3404 ctxt.record_type_as_referenced(underlying_type);
3406 write_location(decl, ctxt);
3410 i = ctxt.get_id_for_type(decl);
3412 o <<
" id='" << i <<
"'/>\n";
3414 ctxt.record_type_as_emitted(decl);
3430 write_context& ctxt,
3432{
return write_typedef_decl(decl,
"", ctxt, indent);}
3447write_var_decl(
const var_decl_sptr& decl, write_context& ctxt,
3448 bool write_linkage_name,
unsigned indent)
3453 annotate(decl, ctxt, indent);
3455 ostream &o = ctxt.get_ostream();
3457 do_indent(o, indent);
3460 type_base_sptr var_type = decl->get_type();
3461 o <<
" type-id='" << ctxt.get_id_for_type(var_type) <<
"'";
3462 ctxt.record_type_as_referenced(var_type);
3464 if (write_linkage_name)
3466 const string& linkage_name = decl->get_linkage_name();
3467 if (!linkage_name.empty())
3468 o <<
" mangled-name='" << linkage_name <<
"'";
3471 write_visibility(decl, o);
3473 write_binding(decl, o);
3475 write_location(decl, ctxt);
3478 if (corpus* abi = decl->get_corpus())
3479 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3483 ctxt.record_decl_as_emitted(decl);
3502 bool skip_first_parm,
unsigned indent)
3507 annotate(decl, ctxt, indent);
3509 ostream &o = ctxt.get_ostream();
3511 do_indent(o, indent);
3513 o <<
"<function-decl name='"
3517 if (!decl->get_linkage_name().empty())
3518 o <<
" mangled-name='"
3521 write_location(decl, ctxt);
3523 if (decl->is_declared_inline())
3524 o <<
" declared-inline='yes'";
3526 write_visibility(decl, o);
3528 write_binding(decl, o);
3530 write_size_and_alignment(decl->get_type(), o,
3531 (ctxt.get_write_default_sizes()
3533 : decl->get_translation_unit()->get_address_size()),
3536 if (corpus* abi = decl->get_corpus())
3537 write_elf_symbol_reference(ctxt, decl->get_symbol(), *abi, o);
3541 type_base_sptr parm_type;
3542 vector<shared_ptr<function_decl::parameter> >::const_iterator pi =
3543 decl->get_parameters().begin();
3544 for ((skip_first_parm && pi != decl->get_parameters().end()) ? ++pi: pi;
3545 pi != decl->get_parameters().end();
3548 if ((*pi)->get_variadic_marker())
3550 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3551 o <<
"<parameter is-variadic='yes'";
3555 parm_type = (*pi)->get_type();
3558 indent + ctxt.get_config().get_xml_element_indent());
3560 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3562 o <<
"<parameter type-id='"
3563 << ctxt.get_id_for_type(parm_type)
3565 ctxt.record_type_as_referenced(parm_type);
3567 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3570 write_is_artificial(*pi, o);
3571 write_location((*pi)->get_location(), ctxt);
3575 if (shared_ptr<type_base> return_type = decl->get_return_type())
3577 annotate(return_type , ctxt,
3578 indent + ctxt.get_config().get_xml_element_indent());
3579 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3580 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3581 ctxt.record_type_as_referenced(return_type);
3584 do_indent(o, indent);
3585 o <<
"</function-decl>\n";
3587 ctxt.record_decl_as_emitted(decl);
3603 write_context& ctxt,
unsigned indent)
3608 ostream &o = ctxt.get_ostream();
3610 annotate(fn_type, ctxt, indent);
3612 do_indent(o, indent);
3614 o <<
"<function-type";
3616 write_size_and_alignment(fn_type, o,
3617 (ctxt.get_write_default_sizes()
3619 : fn_type->get_translation_unit()->get_address_size()),
3624 o <<
" method-class-id='"
3625 << ctxt.get_id_for_type(method_type->get_class_type())
3628 write_cdtor_const_static(
false,
false,
3629 method_type->get_is_const(),
3633 interned_string
id = ctxt.get_id_for_type(fn_type);
3639 type_base_sptr parm_type;
3640 for (vector<function_decl::parameter_sptr>::const_iterator pi =
3641 fn_type->get_parameters().begin();
3642 pi != fn_type->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();
3655 annotate(*pi, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3657 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3658 o <<
"<parameter type-id='"
3659 << ctxt.get_id_for_type(parm_type)
3661 ctxt.record_type_as_referenced(parm_type);
3663 if (ctxt.get_write_parameter_names() && !(*pi)->get_name().empty())
3666 o <<
" name='" << name <<
"'";
3669 write_is_artificial(*pi, o);
3673 if (type_base_sptr return_type = fn_type->get_return_type())
3675 annotate(return_type, ctxt, indent + ctxt.get_config().get_xml_element_indent());
3676 do_indent(o, indent + ctxt.get_config().get_xml_element_indent());
3677 o <<
"<return type-id='" << ctxt.get_id_for_type(return_type) <<
"'/>\n";
3678 ctxt.record_type_as_referenced(return_type);
3681 do_indent(o, indent);
3682 o <<
"</function-type>\n";
3684 ctxt.record_type_as_emitted(fn_type);
3708 write_context& ctxt,
3710 bool prepare_to_handle_empty)
3715 ostream& o = ctxt.get_ostream();
3717 do_indent_to_level(ctxt, indent, 0);
3721 write_size_and_alignment(decl, o);
3723 write_is_struct(decl, o);
3725 write_is_anonymous(decl, o);
3727 write_is_artificial(decl, o);
3729 write_is_non_reachable(
is_type(decl), o);
3731 write_naming_typedef(decl, ctxt);
3733 write_visibility(decl, o);
3735 write_location(decl, ctxt);
3737 write_is_declaration_only(decl, o);
3739 if (decl->get_earlier_declaration())
3742 o <<
" def-of-decl-id='"
3743 << ctxt.get_id_for_type(
is_type(decl->get_earlier_declaration()))
3749 i = ctxt.get_id_for_type(decl);
3750 o <<
" id='" << i <<
"'";
3752 if (prepare_to_handle_empty && decl->has_no_base_nor_member())
3778write_union_decl_opening_tag(
const union_decl_sptr& decl,
3780 write_context& ctxt,
3782 bool prepare_to_handle_empty)
3787 ostream& o = ctxt.get_ostream();
3789 do_indent_to_level(ctxt, indent, 0);
3793 if (!decl->get_is_declaration_only())
3794 write_size_and_alignment(decl, o);
3796 write_is_anonymous(decl, o);
3798 write_naming_typedef(decl, ctxt);
3800 write_visibility(decl, o);
3802 write_is_artificial(decl, o);
3804 write_is_non_reachable(
is_type(decl), o);
3806 write_location(decl, ctxt);
3808 write_is_declaration_only(decl, o);
3812 i = ctxt.get_id_for_type(decl);
3813 o <<
" id='" << i <<
"'";
3815 if (prepare_to_handle_empty && decl->has_no_member())
3841 write_context& ctxt,
3849 annotate(decl, ctxt, indent);
3851 ostream& o = ctxt.get_ostream();
3853 if (decl->get_is_declaration_only())
3857 const environment& env = ctxt.get_environment();
3875 *decl->get_corpus(),
3878 for (
auto t : result)
3880 type_base_sptr type(t);
3882 for (
auto m : c->get_member_types())
3883 if (member_types.find(m) != member_types.end())
3884 member_types.insert(m);
3888 if (!member_types.empty())
3894 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3896 member_types.empty());
3898 vector<type_base_sptr> sorted_types;
3901 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3903 for (
auto t : sorted_types)
3904 if (!ctxt.type_is_emitted(t))
3905 write_member_type(t, ctxt, nb_ws);
3907 if (!member_types.empty())
3908 o << indent <<
"</class-decl>\n";
3913 for (
auto t : result)
3914 ctxt.record_type_as_emitted(type_base_sptr(t));
3919 write_class_decl_opening_tag(decl,
id, ctxt, indent,
3922 if (!decl->has_no_base_nor_member())
3924 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
3925 type_base_sptr base_type;
3926 for (class_decl::base_specs::const_iterator base =
3927 decl->get_base_specifiers().begin();
3928 base != decl->get_base_specifiers().end();
3931 annotate((*base)->get_base_class(), ctxt, nb_ws);
3932 do_indent(o, nb_ws);
3935 write_access((*base)->get_access_specifier(), o);
3937 write_layout_offset (*base, o);
3939 if ((*base)->get_is_virtual ())
3940 o <<
" is-virtual='yes'";
3942 base_type = (*base)->get_base_class();
3944 << ctxt.get_id_for_type(base_type)
3947 ctxt.record_type_as_referenced(base_type);
3950 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
3953 for (class_decl::member_types::const_iterator ti =
3954 decl->get_sorted_member_types().begin();
3955 ti != decl->get_sorted_member_types().end();
3957 if (!(*ti)->get_naked_canonical_type())
3958 write_member_type(*ti, ctxt, nb_ws);
3960 for (class_decl::data_members::const_iterator data =
3961 decl->get_data_members().begin();
3962 data != decl->get_data_members().end();
3965 do_indent(o, nb_ws);
3966 o <<
"<data-member";
3970 write_cdtor_const_static(
false,
3975 write_layout_offset(*data, o);
3978 write_var_decl(*data, ctxt, is_static,
3979 get_indent_to_level(ctxt, indent, 2));
3981 do_indent_to_level(ctxt, indent, 1);
3982 o <<
"</data-member>\n";
3985 for (class_decl::member_functions::const_iterator f =
3986 decl->get_member_functions().begin();
3987 f != decl->get_member_functions().end();
3998 do_indent(o, nb_ws);
3999 o <<
"<member-function";
4008 write_function_decl(fn, ctxt,
4010 get_indent_to_level(ctxt, indent, 2));
4012 do_indent_to_level(ctxt, indent, 1);
4013 o <<
"</member-function>\n";
4016 for (class_decl::member_functions::const_iterator f =
4017 decl->get_virtual_mem_fns().begin();
4018 f != decl->get_virtual_mem_fns().end();
4025 do_indent(o, nb_ws);
4026 o <<
"<member-function";
4033 write_voffset(fn, o);
4036 write_function_decl(fn, ctxt,
4038 get_indent_to_level(ctxt, indent, 2));
4040 do_indent_to_level(ctxt, indent, 1);
4041 o <<
"</member-function>\n";
4044 for (member_function_templates::const_iterator fn =
4045 decl->get_member_function_templates().begin();
4046 fn != decl->get_member_function_templates().end();
4049 do_indent(o, nb_ws);
4050 o <<
"<member-template";
4051 write_access((*fn)->get_access_specifier(), o);
4052 write_cdtor_const_static((*fn)->is_constructor(),
4055 (*fn)->get_is_static(), o);
4057 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4058 get_indent_to_level(ctxt, indent, 2));
4059 do_indent(o, nb_ws);
4060 o <<
"</member-template>\n";
4063 for (member_class_templates::const_iterator cl =
4064 decl->get_member_class_templates().begin();
4065 cl != decl->get_member_class_templates().end();
4068 do_indent(o, nb_ws);
4069 o <<
"<member-template";
4070 write_access((*cl)->get_access_specifier(), o);
4071 write_cdtor_const_static(
false,
false,
false,
4072 (*cl)->get_is_static(), o);
4074 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4075 get_indent_to_level(ctxt, indent, 2));
4076 do_indent(o, nb_ws);
4077 o <<
"</member-template>\n";
4080 do_indent_to_level(ctxt, indent, 0);
4082 o <<
"</class-decl>\n";
4085 ctxt.record_type_as_emitted(decl);
4101 write_context& ctxt,
4103{
return write_class_decl(decl,
"", ctxt, indent);}
4115write_union_decl(
const union_decl_sptr& d,
4117 write_context& ctxt,
4125 annotate(decl, ctxt, indent);
4127 ostream& o = ctxt.get_ostream();
4129 write_union_decl_opening_tag(decl,
id, ctxt, indent,
4131 if (!decl->has_no_member())
4133 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4134 for (class_decl::member_types::const_iterator ti =
4135 decl->get_member_types().begin();
4136 ti != decl->get_member_types().end();
4138 if (!(*ti)->get_naked_canonical_type())
4139 write_member_type(*ti, ctxt, nb_ws);
4141 write_canonical_types_of_scope(*decl, ctxt, nb_ws,
4144 for (union_decl::data_members::const_iterator data =
4145 decl->get_data_members().begin();
4146 data != decl->get_data_members().end();
4149 do_indent(o, nb_ws);
4150 o <<
"<data-member";
4154 write_cdtor_const_static(
false,
4161 write_var_decl(*data, ctxt, is_static,
4162 get_indent_to_level(ctxt, indent, 2));
4164 do_indent_to_level(ctxt, indent, 1);
4165 o <<
"</data-member>\n";
4168 for (union_decl::member_functions::const_iterator f =
4169 decl->get_member_functions().begin();
4170 f != decl->get_member_functions().end();
4181 do_indent(o, nb_ws);
4182 o <<
"<member-function";
4191 write_function_decl(fn, ctxt,
4193 get_indent_to_level(ctxt, indent, 2));
4195 do_indent_to_level(ctxt, indent, 1);
4196 o <<
"</member-function>\n";
4199 for (member_function_templates::const_iterator fn =
4200 decl->get_member_function_templates().begin();
4201 fn != decl->get_member_function_templates().end();
4204 do_indent(o, nb_ws);
4205 o <<
"<member-template";
4206 write_access((*fn)->get_access_specifier(), o);
4207 write_cdtor_const_static((*fn)->is_constructor(),
4210 (*fn)->get_is_static(), o);
4212 write_function_tdecl((*fn)->as_function_tdecl(), ctxt,
4213 get_indent_to_level(ctxt, indent, 2));
4214 do_indent(o, nb_ws);
4215 o <<
"</member-template>\n";
4218 for (member_class_templates::const_iterator cl =
4219 decl->get_member_class_templates().begin();
4220 cl != decl->get_member_class_templates().end();
4223 do_indent(o, nb_ws);
4224 o <<
"<member-template";
4225 write_access((*cl)->get_access_specifier(), o);
4226 write_cdtor_const_static(
false,
false,
false,
4227 (*cl)->get_is_static(), o);
4229 write_class_tdecl((*cl)->as_class_tdecl(), ctxt,
4230 get_indent_to_level(ctxt, indent, 2));
4231 do_indent(o, nb_ws);
4232 o <<
"</member-template>\n";
4235 do_indent_to_level(ctxt, indent, 0);
4237 o <<
"</union-decl>\n";
4240 ctxt.record_type_as_emitted(decl);
4246write_union_decl(
const union_decl_sptr& decl,
4247 write_context& ctxt,
4249{
return write_union_decl(decl,
"", ctxt, indent);}
4261write_member_type_opening_tag(
const type_base_sptr& t,
4262 write_context& ctxt,
4265 ostream& o = ctxt.get_ostream();
4267 do_indent_to_level(ctxt, indent, 0);
4272 o <<
"<member-type";
4273 write_access(decl, o);
4292write_member_type(
const type_base_sptr& t, write_context& ctxt,
unsigned indent)
4297 ostream& o = ctxt.get_ostream();
4299 write_member_type_opening_tag(t, ctxt, indent);
4301 string id = ctxt.get_id_for_type(t);
4303 unsigned nb_ws = get_indent_to_level(ctxt, indent, 1);
4304 ABG_ASSERT(write_qualified_type_def(dynamic_pointer_cast<qualified_type_def>(t),
4306 || write_pointer_type_def(dynamic_pointer_cast<pointer_type_def>(t),
4308 || write_reference_type_def(dynamic_pointer_cast<reference_type_def>(t),
4310 || write_ptr_to_mbr_type(dynamic_pointer_cast<ptr_to_mbr_type>(t),
4312 || write_array_type_def(dynamic_pointer_cast<array_type_def>(t),
4314 || write_enum_type_decl(dynamic_pointer_cast<enum_type_decl>(t),
4316 || write_typedef_decl(dynamic_pointer_cast<typedef_decl>(t),
4318 || write_union_decl(dynamic_pointer_cast<union_decl>(t),
4320 || write_class_decl(dynamic_pointer_cast<class_decl>(t),
4323 do_indent_to_level(ctxt, indent, 0);
4324 o <<
"</member-type>\n";
4340 write_context& ctxt,
4346 ostream &o = ctxt.get_ostream();
4347 do_indent_to_level(ctxt, indent, 0);
4349 string id_attr_name;
4350 if (ctxt.type_has_existing_id(decl))
4351 id_attr_name =
"type-id";
4353 id_attr_name =
"id";
4355 o <<
"<template-type-parameter "
4356 << id_attr_name <<
"='" << ctxt.get_id_for_type(decl) <<
"'";
4360 o <<
" name='" << name <<
"'";
4362 write_location(decl, ctxt);
4366 ctxt.record_type_as_emitted(decl);
4381write_non_type_tparameter(
4382 const shared_ptr<non_type_tparameter> decl,
4383 write_context& ctxt,
unsigned indent)
4388 ostream &o = ctxt.get_ostream();
4389 do_indent_to_level(ctxt, indent, 0);
4391 o <<
"<template-non-type-parameter type-id='"
4392 << ctxt.get_id_for_type(decl->get_type())
4397 o <<
" name='" << name <<
"'";
4399 write_location(decl, ctxt);
4418 write_context& ctxt,
4424 ostream& o = ctxt.get_ostream();
4425 do_indent_to_level(ctxt, indent, 0);
4427 string id_attr_name =
"id";
4428 if (ctxt.type_has_existing_id(decl))
4429 id_attr_name =
"type-id";
4431 o <<
"<template-template-parameter " << id_attr_name <<
"='"
4432 << ctxt.get_id_for_type(decl) <<
"'";
4436 o <<
" name='" << name <<
"'";
4440 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4441 for (list<shared_ptr<template_parameter> >::const_iterator p =
4442 decl->get_template_parameters().begin();
4443 p != decl->get_template_parameters().end();
4445 write_template_parameter(decl, ctxt, nb_spaces);
4447 do_indent_to_level(ctxt, indent, 0);
4448 o <<
"</template-template-parameter>\n";
4450 ctxt.record_type_as_emitted(decl);
4465write_type_composition
4466(
const shared_ptr<type_composition> decl,
4467 write_context& ctxt,
unsigned indent)
4472 ostream& o = ctxt.get_ostream();
4474 do_indent_to_level(ctxt, indent, 0);
4476 o <<
"<template-parameter-type-composition>\n";
4478 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4479 (write_pointer_type_def
4480 (dynamic_pointer_cast<pointer_type_def>(decl->get_composed_type()),
4482 || write_reference_type_def
4483 (dynamic_pointer_cast<reference_type_def>(decl->get_composed_type()),
4485 || write_array_type_def
4486 (dynamic_pointer_cast<array_type_def>(decl->get_composed_type()),
4488 || write_qualified_type_def
4489 (dynamic_pointer_cast<qualified_type_def>(decl->get_composed_type()),
4492 do_indent_to_level(ctxt, indent, 0);
4493 o <<
"</template-parameter-type-composition>\n";
4508write_template_parameter(
const shared_ptr<template_parameter> decl,
4509 write_context& ctxt,
unsigned indent)
4511 if ((!write_type_tparameter
4512 (dynamic_pointer_cast<type_tparameter>(decl), ctxt, indent))
4513 && (!write_non_type_tparameter
4514 (dynamic_pointer_cast<non_type_tparameter>(decl),
4516 && (!write_template_tparameter
4517 (dynamic_pointer_cast<template_tparameter>(decl),
4519 && (!write_type_composition
4520 (dynamic_pointer_cast<type_composition>(decl),
4531write_template_parameters(
const shared_ptr<template_decl> tmpl,
4532 write_context& ctxt,
unsigned indent)
4537 unsigned nb_spaces = get_indent_to_level(ctxt, indent, 1);
4538 for (list<shared_ptr<template_parameter> >::const_iterator p =
4539 tmpl->get_template_parameters().begin();
4540 p != tmpl->get_template_parameters().end();
4542 write_template_parameter(*p, ctxt, nb_spaces);
4553write_function_tdecl(
const shared_ptr<function_tdecl> decl,
4554 write_context& ctxt,
unsigned indent)
4559 ostream& o = ctxt.get_ostream();
4561 do_indent_to_level(ctxt, indent, 0);
4563 o <<
"<function-template-decl id='" << ctxt.get_id_for_fn_tmpl(decl) <<
"'";
4565 write_location(decl, ctxt);
4567 write_visibility(decl, o);
4569 write_binding(decl, o);
4573 write_template_parameters(decl, ctxt, indent);
4575 write_function_decl(decl->get_pattern(), ctxt,
4577 get_indent_to_level(ctxt, indent, 1));
4579 do_indent_to_level(ctxt, indent, 0);
4581 o <<
"</function-template-decl>\n";
4598write_class_tdecl(
const shared_ptr<class_tdecl> decl,
4599 write_context& ctxt,
unsigned indent)
4604 ostream& o = ctxt.get_ostream();
4606 do_indent_to_level(ctxt, indent, 0);
4608 o <<
"<class-template-decl id='" << ctxt.get_id_for_class_tmpl(decl) <<
"'";
4610 write_location(decl, ctxt);
4612 write_visibility(decl, o);
4616 write_template_parameters(decl, ctxt, indent);
4618 write_class_decl(decl->get_pattern(), ctxt,
4619 get_indent_to_level(ctxt, indent, 1));
4621 do_indent_to_level(ctxt, indent, 0);
4623 o <<
"</class-template-decl>\n";
4632write_version_info(write_context& ctxt)
4634 ostream& o = ctxt.get_ostream();
4635 const config& c = ctxt.get_config();
4638 << c.get_format_major_version_number()
4639 <<
"." << c.get_format_minor_version_number()
4659 const corpus_sptr&
corpus,
4661 bool member_of_group)
4669 do_indent_to_level(ctxt, indent, 0);
4671 std::ostream& out = ctxt.get_ostream();
4673 out <<
"<abi-corpus ";
4675 write_version_info(ctxt);
4680 if (!ctxt.get_write_corpus_path())
4682 if (member_of_group)
4685 corpus_path.clear();
4689 if (ctxt.get_short_locs())
4692 if (!corpus_path.empty())
4696 && ctxt.get_write_architecture())
4702 write_tracking_non_reachable_types(
corpus, out);
4710 do_indent_to_level(ctxt, indent, 1);
4711 out <<
"<elf-needed>\n";
4713 get_indent_to_level(ctxt, indent, 2));
4714 do_indent_to_level(ctxt, indent, 1);
4715 out <<
"</elf-needed>\n";
4721 do_indent_to_level(ctxt, indent, 1);
4722 out <<
"<elf-function-symbols>\n";
4725 get_indent_to_level(ctxt, indent, 2));
4727 do_indent_to_level(ctxt, indent, 1);
4728 out <<
"</elf-function-symbols>\n";
4734 do_indent_to_level(ctxt, indent, 1);
4735 out <<
"<elf-variable-symbols>\n";
4738 get_indent_to_level(ctxt, indent, 2));
4740 do_indent_to_level(ctxt, indent, 1);
4741 out <<
"</elf-variable-symbols>\n";
4745 if (ctxt.get_write_undefined_symbols()
4748 do_indent_to_level(ctxt, indent, 1);
4749 out <<
"<undefined-elf-function-symbols>\n";
4752 get_indent_to_level(ctxt, indent, 2));
4754 do_indent_to_level(ctxt, indent, 1);
4755 out <<
"</undefined-elf-function-symbols>\n";
4760 if (ctxt.get_write_undefined_symbols()
4763 do_indent_to_level(ctxt, indent, 1);
4764 out <<
"<undefined-elf-variable-symbols>\n";
4767 get_indent_to_level(ctxt, indent, 2));
4769 do_indent_to_level(ctxt, indent, 1);
4770 out <<
"</undefined-elf-variable-symbols>\n";
4775 for (translation_units::const_iterator i =
4782 get_indent_to_level(ctxt, indent, 1),
4786 do_indent_to_level(ctxt, indent, 0);
4787 out <<
"</abi-corpus>\n";
4789 ctxt.clear_referenced_types();
4790 ctxt.record_corpus_as_emitted(
corpus);
4807 const corpus_group_sptr& group,
4814 do_indent_to_level(ctxt, indent, 0);
4816std::ostream& out = ctxt.get_ostream();
4818 out <<
"<abi-corpus-group ";
4819 write_version_info(ctxt);
4821 if (!group->get_path().empty() && ctxt.get_write_corpus_path())
4824 if (!group->get_architecture_name().empty() && ctxt.get_write_architecture())
4825 out <<
" architecture='" << group->get_architecture_name()<<
"'";
4827 write_tracking_non_reachable_types(group, out);
4829 if (group->is_empty())
4838 for (corpus_group::corpora_type::const_iterator c =
4839 group->get_corpora().begin();
4840 c != group->get_corpora().end();
4844 write_corpus(ctxt, *c, get_indent_to_level(ctxt, indent, 1),
true);
4847 do_indent_to_level(ctxt, indent, 0);
4848 out <<
"</abi-corpus-group>\n";
4869 xml_writer::write_context ctxt(d->get_environment(), o);
4871 write_decl(d, ctxt, 0);
4913 xml_writer::write_context ctxt(v->get_environment(), o);
4915 write_var_decl(v, ctxt,
true, 0);
4984 unsigned line = 0, col = 0;
4986 l.
expand(path, line, col);
4987 o << path <<
":" << line <<
"," << col <<
"\n";
5037#ifdef WITH_DEBUG_SELF_COMPARISON
5048write_type_record(xml_writer::write_context& ctxt,
5071 id = ctxt.get_id_for_type (
const_cast<type_base*
>(type));
5074 <<
" <id>" <<
id <<
"</id>\n"
5077 <<
reinterpret_cast<uintptr_t
>(canonical)
5093write_canonical_type_ids(xml_writer::write_context& ctxt, ostream& o)
5112 o <<
"<abixml-types-check>\n";
5114 for (
const auto &type : ctxt.get_emitted_types_set())
5115 write_type_record(ctxt, type, o);
5117 o <<
"</abixml-types-check>\n";
5130write_canonical_type_ids(xml_writer::write_context& ctxt,
5131 const string &file_path)
5133 std:: ofstream o (file_path);
5137 write_canonical_type_ids(ctxt, o);
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
This type abstracts the configuration information of the library.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
virtual const elf_symbols & get_sorted_var_symbols() const
Getter for the sorted vector of variable symbols for this corpus.
const vector< string > & get_needed() const
Getter of the needed property of the corpus.
virtual const string_elf_symbols_map_type & get_var_symbol_map() const
Getter for the variable symbols map.
virtual const elf_symbols & get_sorted_fun_symbols() const
Return a sorted vector of function symbols for this corpus.
const string & get_soname()
Getter for the soname property of the corpus.
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
virtual bool is_empty() const
Tests if the corpus is empty from an ABI surface perspective. I.e. if all of these criteria are true:
const elf_symbols & get_sorted_undefined_fun_symbols() const
Getter for a sorted vector of the function symbols undefined in this corpus.
string & get_path() const
Get the file path associated to the corpus file.
virtual const string_elf_symbols_map_type & get_fun_symbol_map() const
Getter for the function symbols map.
const elf_symbols & get_sorted_undefined_var_symbols() const
Getter for a sorted vector of the variable symbols undefined in this corpus.
const string & get_architecture_name() const
Getter for the architecture name of the corpus.
The base type of all declarations.
const location & get_location() const
Get the location of a given declaration.
visibility
ELF visibility.
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.
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.
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
The abstraction of a typedef declaration.
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
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.
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.
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.
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
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*.
void set_write_parameter_names(write_context &ctxt, bool flag)
Set the 'parameter-names' flag.
bool annotate(const function_decl::parameter_sptr &parm, write_context &ctxt, unsigned indent)
Annotate a function parameter in form of an ABIXML comment.
void set_ostream(write_context &ctxt, ostream &os)
Set the new ostream.
shared_ptr< write_context > write_context_sptr
A convenience typedef for a shared pointer to write_context.
bool write_corpus_group(write_context &ctxt, const corpus_group_sptr &group, unsigned indent)
Serialize an ABI corpus group to a single native xml document. The root note of the resulting XML doc...
void set_annotate(write_context &ctxt, bool flag)
Set the 'annotate' flag.
bool write_translation_unit(write_context &ctxt, const translation_unit &tu, const unsigned indent, bool is_last)
Serialize a translation unit to an output stream.
void set_write_default_sizes(write_context &ctxt, bool flag)
Set the 'default-sizes' flag.
void set_write_elf_needed(write_context &ctxt, bool flag)
Set the 'elf-needed' flag.
bool write_corpus(write_context &ctxt, const corpus_sptr &corpus, unsigned indent, bool member_of_group)
Serialize an ABI corpus to a single native xml document. The root note of the resulting XML document ...
void set_write_corpus_path(write_context &ctxt, bool flag)
Set the 'write-corpus-path' flag.
void set_write_architecture(write_context &ctxt, bool flag)
Set the 'write-architecture' flag.
type_id_style_kind
The style of type id the XML writer will output.
void set_show_locs(write_context &ctxt, bool flag)
Set the "show-locs" flag.
unordered_map< type_base *, interned_string > type_ptr_map
A convenience typedef for a map that associates a pointer to type to a string.
std::unordered_map< const type_base *, interned_string, non_canonicalized_type_hash, non_canonicalized_type_equal > nc_type_ptr_istr_map_type
A map meant to carry non canonicalized types as key.
void set_type_id_style(write_context &ctxt, type_id_style_kind style)
Set the 'type-id-style' property.
void set_write_comp_dir(write_context &ctxt, bool flag)
Set the 'write-comp-dir' flag.
std::unordered_set< const type_base *, non_canonicalized_type_hash, non_canonicalized_type_equal > nc_type_ptr_set_type
A set meant to carry non canonicalized types.
void escape_xml_comment(const std::string &str, std::string &escaped)
Escape the '-' character, to avoid having a '–' in a comment.
void escape_xml_string(const std::string &str, std::string &escaped)
Escape the 5 characters representing the predefined XML entities.
Toplevel namespace for libabigail.
void dump(const decl_base_sptr d, std::ostream &o, const bool annotate)
Serialize a pointer to decl_base to an output stream.
void dump_decl_location(const decl_base &d, ostream &o)
Serialize the source location of a decl to an output stream for debugging purposes.
void dump_location(const location &l, ostream &o)
Serialize a source location to an output stream.
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.
Datum consolidating style preferences.