15#include <libxml/xmlreader.h>
16#include <libxml/xmlstring.h>
23#include <unordered_map>
27#include "abg-internal.h"
31ABG_BEGIN_EXPORT_DECLARATIONS
39ABG_END_EXPORT_DECLARATIONS
53using std::unordered_map;
54using std::dynamic_pointer_cast;
60static bool read_is_declaration_only(xmlNodePtr,
bool&);
61static bool read_is_artificial(xmlNodePtr,
bool&);
62static bool read_tracking_non_reachable_types(xmlNodePtr,
bool&);
63static bool read_is_non_reachable_type(xmlNodePtr,
bool&);
64static bool read_naming_typedef_id_string(xmlNodePtr,
string&);
65static bool read_type_id_string(xmlNodePtr,
string&);
66#ifdef WITH_DEBUG_SELF_COMPARISON
67static bool maybe_map_type_with_type_id(
const type_base_sptr&,
69static bool maybe_map_type_with_type_id(
const type_base_sptr&,
72#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node) \
73 maybe_map_type_with_type_id(type, xml_node)
75#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node)
77static void maybe_set_naming_typedef(reader& rdr,
79 const decl_base_sptr &);
82static int advance_cursor(reader& rdr);
88walk_xml_node_to_map_type_ids(reader& rdr, xmlNodePtr node);
91read_elf_needed_from_input(reader& rdr, vector<string>& needed);
94read_symbol_db_from_input(reader& rdr,
99read_translation_unit_from_input(
fe_iface& rdr);
102build_ir_node_for_void_type(reader& rdr);
105build_ir_node_for_void_pointer_type(reader& rdr);
118 typedef unordered_map<string, vector<type_base_sptr> >
121 typedef unordered_map<string,
122 vector<type_base_sptr> >::const_iterator
125 typedef unordered_map<string,
126 vector<type_base_sptr> >::iterator
129 typedef unordered_map<string,
130 shared_ptr<function_tdecl> >::const_iterator
131 const_fn_tmpl_map_it;
133 typedef unordered_map<string,
134 shared_ptr<class_tdecl> >::const_iterator
135 const_class_tmpl_map_it;
137 typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
139 typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
141 friend vector<type_base_sptr>* get_types_from_type_id(reader&,
144 friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
145 get_artifact_used_by_relation_map(reader& rdr);
148 types_map_type m_types_map;
149 unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
150 unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
151 vector<type_base_sptr> m_types_to_canonicalize;
152 string_xml_node_map m_id_xml_node_map;
153 xml_node_decl_base_sptr_map m_xml_node_decl_map;
155 xmlNodePtr m_corp_node;
156 deque<shared_ptr<decl_base> > m_decls_stack;
157 bool m_tracking_non_reachable_types;
158 bool m_drop_undefined_syms;
159#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
161 vector<type_or_decl_base*>> m_artifact_used_by_map;
172 m_tracking_non_reachable_types(),
173 m_drop_undefined_syms()
182 {
return options().do_log;}
190 tracking_non_reachable_types()
const
191 {
return m_tracking_non_reachable_types;}
199 tracking_non_reachable_types(
bool f)
200 {m_tracking_non_reachable_types = f;}
208 drop_undefined_syms()
const
209 {
return m_drop_undefined_syms;}
216 drop_undefined_syms(
bool f)
217 {m_drop_undefined_syms = f;}
224 {
return corpus_path();}
230 set_path(
const string& s)
240 {
return options().env;}
246 get_environment()
const
247 {
return const_cast<reader*
>(
this)->get_environment();}
250 get_libxml_reader()
const
259 get_corpus_node()
const
260 {
return m_corp_node;}
268 set_corpus_node(xmlNodePtr node)
269 {m_corp_node = node;}
271 const string_xml_node_map&
272 get_id_xml_node_map()
const
273 {
return m_id_xml_node_map;}
276 get_id_xml_node_map()
277 {
return m_id_xml_node_map;}
280 clear_id_xml_node_map()
281 {get_id_xml_node_map().clear();}
283 const xml_node_decl_base_sptr_map&
284 get_xml_node_decl_map()
const
285 {
return m_xml_node_decl_map;}
287 xml_node_decl_base_sptr_map&
288 get_xml_node_decl_map()
289 {
return m_xml_node_decl_map;}
292 map_xml_node_to_decl(xmlNodePtr node,
296 get_xml_node_decl_map()[node]= decl;
300 get_decl_for_xml_node(xmlNodePtr node)
const
302 xml_node_decl_base_sptr_map::const_iterator i =
303 get_xml_node_decl_map().find(node);
305 if (i != get_xml_node_decl_map().end())
308 return decl_base_sptr();
312 clear_xml_node_decl_map()
313 {get_xml_node_decl_map().clear();}
316 map_id_and_node (
const string&
id,
322 string_xml_node_map::iterator i = get_id_xml_node_map().find(
id);
323 if (i != get_id_xml_node_map().end())
325 bool is_declaration =
false;
326 read_is_declaration_only(node, is_declaration);
331 get_id_xml_node_map()[id] = node;
335 get_xml_node_from_id(
const string&
id)
const
337 string_xml_node_map::const_iterator i = get_id_xml_node_map().find(
id);
338 if (i != get_id_xml_node_map().end())
344 get_scope_for_node(xmlNodePtr node,
348 get_scope_for_node(xmlNodePtr node);
351 get_scope_ptr_for_node(xmlNodePtr node);
356 build_or_get_type_decl(
const string&
id,
371 get_type_decl(
const string&
id)
const
373 const_types_map_it i = m_types_map.find(
id);
374 if (i == m_types_map.end())
375 return type_base_sptr();
376 type_base_sptr result = i->second[0];
392 const vector<type_base_sptr>*
393 get_all_type_decls(
const string&
id)
const
395 const_types_map_it i = m_types_map.find(
id);
396 if (i == m_types_map.end())
413 shared_ptr<function_tdecl>
414 get_fn_tmpl_decl(
const string&
id)
const
416 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
417 if (i == m_fn_tmpl_map.end())
418 return shared_ptr<function_tdecl>();
432 shared_ptr<class_tdecl>
433 get_class_tmpl_decl(
const string&
id)
const
435 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
436 if (i == m_class_tmpl_map.end())
437 return shared_ptr<class_tdecl>();
443 get_cur_scope()
const
445 shared_ptr<decl_base> cur_decl = get_cur_decl();
447 if (
dynamic_cast<scope_decl*
>(cur_decl.get()))
449 return dynamic_pointer_cast<scope_decl>(cur_decl).get();
453 return cur_decl->get_scope();
462 if (m_decls_stack.empty())
463 return shared_ptr<decl_base>(
static_cast<decl_base*
>(0));
464 return m_decls_stack.back();
471 for (deque<shared_ptr<decl_base> >::reverse_iterator i =
472 m_decls_stack.rbegin();
473 i != m_decls_stack.rend();
475 if (decl_base_sptr d = *i)
480 return global->get_translation_unit();
491 type_is_from_translation_unit(type_base_sptr type)
503 push_decl(decl_base_sptr d)
505 m_decls_stack.push_back(d);
511 if (m_decls_stack.empty())
512 return decl_base_sptr();
514 shared_ptr<decl_base> t = get_cur_decl();
515 m_decls_stack.pop_back();
542 return dynamic_pointer_cast<scope_decl>(d) == scope;
555 {m_decls_stack.clear();}
559 {m_types_map.clear();}
564 clear_types_to_canonicalize()
565 {m_types_to_canonicalize.clear();}
581 types_equal(type_base_sptr t1, type_base_sptr t2)
583 if (t1.get() == t2.get())
602 key_type_decl(
const type_base_sptr& type,
const string&
id)
607 m_types_map[id].push_back(type);
622 key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
627 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
628 if (i != m_fn_tmpl_map.end())
631 m_fn_tmpl_map[id] = fn_tmpl_decl;
645 key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
650 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
651 if (i != m_class_tmpl_map.end())
654 m_class_tmpl_map[id] = class_tmpl_decl;
658#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
671 if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
673 vector<type_or_decl_base*> v;
674 m_artifact_used_by_map[used] = v;
676 m_artifact_used_by_map[used].push_back(user);
690 {record_artifact_as_used_by(used.get(), user.get());}
702 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
706 type_base_sptr t = pit->get_type();
707 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
716 {record_artifacts_as_used_in_fn_decl(fn.get());}
722 record_artifacts_as_used_in_fn_type(
const function_type *fn_type)
728 record_artifact_as_used_by(t.get(),
const_cast<function_type*
>(fn_type));
732 type_base_sptr t = pit->get_type();
733 record_artifact_as_used_by(t.get(),
743 {record_artifacts_as_used_in_fn_type(fn_type.get());}
755 push_decl_to_scope(
const decl_base_sptr& decl, xmlNodePtr node)
758 scope = get_scope_ptr_for_node(node);
759 return push_decl_to_scope(decl, scope);
768 push_decl_to_scope(
const decl_base_sptr& decl,
774 if (!decl->get_translation_unit())
793 push_and_key_type_decl(
const type_base_sptr& t,
800 push_decl_to_scope(decl, scope);
801 if (!t->get_translation_unit())
804 key_type_decl(t,
id);
819 push_and_key_type_decl(
const type_base_sptr& t,
820 const xmlNodePtr node,
821 bool add_to_current_scope)
824 if (!read_type_id_string(node,
id))
829 scope = get_scope_ptr_for_node(node);
830 return push_and_key_type_decl(t,
id, scope);
839 get_exported_decls_builder()
853 corpus_is_suppressed_by_soname_or_filename(
const string& soname,
854 const string& filename)
860 for (suppressions_type::const_iterator s = suppressions().begin();
861 s != suppressions().end();
874 clear_per_translation_unit_data()
881 clear_per_corpus_data()
884 clear_types_to_canonicalize();
885 clear_xml_node_decl_map();
886 clear_id_xml_node_map();
890#ifdef WITH_DEBUG_SELF_COMPARISON
910 maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
912 if (!get_environment().self_comparison_debug_is_on()
913 || get_environment().get_type_id_canonical_type_map().empty())
925 get_environment().get_type_id_from_pointer(
reinterpret_cast<uintptr_t
>(t.get()));
927 if (!type_id.empty())
932 auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
933 if (j == get_environment().get_type_id_canonical_type_map().end())
935 if (t->get_naked_canonical_type())
936 std::cerr <<
"error: no type with type-id: '"
938 <<
"' could be read back from the typeid file\n";
941 !=
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get()))
946 std::cerr <<
"error: canonical type for type '"
947 << t->get_pretty_representation(
true,
949 <<
"' of type-id '" << type_id
950 <<
"' changed from '" << std::hex
951 << j->second <<
"' to '" << std::hex
952 <<
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get())
966 maybe_canonicalize_type(type_base_sptr t,
967 bool force_delay =
false)
972 if (t->get_canonical_type())
1007#ifdef WITH_DEBUG_SELF_COMPARISON
1008 maybe_check_abixml_canonical_type_stability(t);
1018 schedule_type_for_late_canonicalizing(t);
1027 schedule_type_for_late_canonicalizing(type_base_sptr t)
1028 {m_types_to_canonicalize.push_back(t);}
1034 perform_late_type_canonicalizing()
1036 for (vector<type_base_sptr>::iterator i = m_types_to_canonicalize.begin();
1037 i != m_types_to_canonicalize.end();
1041#ifdef WITH_DEBUG_SELF_COMPARISON
1042 maybe_check_abixml_canonical_type_stability(*i);
1060 const string& fn_name)
const
1064 return suppression_matches_function_name(*s, fn_name);
1077 corpus_sptr corp =
corpus();
1079 if (!s.priv_->matches_soname(corp->get_soname()))
1086 if (!s.priv_->matches_binary_name(corp->get_path()))
1109 const string& fn_name)
const
1111 if (!s.get_drops_artifact_from_ir()
1115 return suppr::suppression_matches_function_name(s, fn_name);
1131 const string& type_name,
1132 const location& type_location)
const
1141 virtual ir::corpus_sptr
1152 bool call_reader_next =
false;
1154 xmlNodePtr node = get_corpus_node();
1161 status = advance_cursor (*
this);
1164 BAD_CAST(
"abi-corpus")))
1167#ifdef WITH_DEBUG_SELF_COMPARISON
1168 if (get_environment().self_comparison_debug_is_on())
1169 get_environment().set_self_comparison_debug_input(
corpus());
1173 clear_per_corpus_data();
1179 handle_version_attribute(xml_reader, corp);
1186 path =
reinterpret_cast<char*
>(path_str.get());
1193 if (architecture_str)
1195 (
reinterpret_cast<char*
>(architecture_str.get()));
1203 soname =
reinterpret_cast<char*
>(soname_str.get());
1215 if ((!soname.empty() || !path.empty())
1216 && corpus_is_suppressed_by_soname_or_filename(soname, path))
1219 node = xmlTextReaderExpand(xml_reader.get());
1223 call_reader_next =
true;
1227#ifdef WITH_DEBUG_SELF_COMPARISON
1228 if (get_environment().self_comparison_debug_is_on())
1229 get_environment().set_self_comparison_debug_input(
corpus());
1233 clear_per_corpus_data();
1240 corp.
set_path(
reinterpret_cast<char*
>(path_str.get()));
1244 if (architecture_str)
1246 (
reinterpret_cast<char*
>(architecture_str.get()));
1251 corp.
set_soname(
reinterpret_cast<char*
>(soname_str.get()));
1259 xmlNodePtr n = xmlFirstElementChild(node);
1265 walk_xml_node_to_map_type_ids(*
this, node);
1268 vector<string> needed;
1269 read_elf_needed_from_input(*
this, needed);
1270 if (!needed.empty())
1276 read_symbol_db_from_input(*
this, fn_sym_db, var_sym_db);
1282 get_environment().canonicalization_is_done(
false);
1285 while (read_translation_unit_from_input(*
this))
1288 if (tracking_non_reachable_types())
1290 bool is_tracking_non_reachable_types =
false;
1291 read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1295 == is_tracking_non_reachable_types);
1302 std::cerr <<
"perform late type canonicalization ...\n";
1306 perform_late_type_canonicalizing();
1311 std::cerr <<
"late type canonicalization DONE@"
1313 <<
":" << t <<
"\n";
1316 get_environment().canonicalization_is_done(
true);
1318 if (call_reader_next)
1322 xmlTextReaderNext(xml_reader.get());
1330 node = get_corpus_node();
1331 node = xmlNextElementSibling(node);
1334 node = get_corpus_node();
1336 node = xmlNextElementSibling(node->parent);
1338 set_corpus_node(node);
1346typedef shared_ptr<reader> reader_sptr;
1348static int advance_cursor(reader&);
1352static bool read_symbol_db_from_input(reader&,
1355static bool read_location(
const reader&, xmlNodePtr,
location&);
1356static bool read_artificial_location(
const reader&,
1358static bool maybe_set_artificial_location(
const reader&,
1364static bool read_size_and_alignment(xmlNodePtr,
size_t&,
size_t&);
1365static bool read_static(xmlNodePtr,
bool&);
1366static bool read_offset_in_bits(xmlNodePtr,
size_t&);
1367static bool read_cdtor_const(xmlNodePtr,
bool&,
bool&,
bool&);
1368static bool read_is_virtual(xmlNodePtr,
bool&);
1369static bool read_is_struct(xmlNodePtr,
bool&);
1370static bool read_is_anonymous(xmlNodePtr,
bool&);
1373static bool read_elf_symbol_visibility(xmlNodePtr,
1377build_namespace_decl(reader&,
const xmlNodePtr,
bool);
1387build_elf_symbol(reader&,
const xmlNodePtr,
bool);
1390build_elf_symbol_from_reference(reader&,
const xmlNodePtr);
1393build_elf_symbol_db(reader&,
const xmlNodePtr,
bool);
1396build_function_parameter (reader&,
const xmlNodePtr);
1399build_function_decl(reader&,
const xmlNodePtr,
1400 class_or_union_sptr,
bool,
bool);
1403build_function_decl_if_not_suppressed(reader&,
const xmlNodePtr,
1404 class_or_union_sptr,
bool,
bool);
1407function_is_suppressed(
const reader& rdr,
1411build_var_decl_if_not_suppressed(reader&,
const xmlNodePtr,
bool);
1414build_var_decl(reader&,
const xmlNodePtr,
bool);
1417variable_is_suppressed(
const reader& rdr,
1420static shared_ptr<type_decl>
1421build_type_decl(reader&,
const xmlNodePtr,
bool);
1423static qualified_type_def_sptr
1424build_qualified_type_decl(reader&,
const xmlNodePtr,
bool);
1426static shared_ptr<pointer_type_def>
1427build_pointer_type_def(reader&,
const xmlNodePtr,
bool);
1429static shared_ptr<reference_type_def>
1430build_reference_type_def(reader&,
const xmlNodePtr,
bool);
1433build_ptr_to_mbr_type(reader&,
const xmlNodePtr,
bool);
1435static shared_ptr<function_type>
1436build_function_type(reader&,
const xmlNodePtr,
bool);
1439build_subrange_type(reader&,
const xmlNodePtr,
bool);
1442build_array_type_def(reader&,
const xmlNodePtr,
bool);
1445build_enum_type_decl(reader&,
const xmlNodePtr,
bool);
1447static shared_ptr<typedef_decl>
1448build_typedef_decl(reader&,
const xmlNodePtr,
bool);
1451build_class_decl(reader&,
const xmlNodePtr,
bool);
1453static union_decl_sptr
1454build_union_decl(reader&,
const xmlNodePtr,
bool);
1456static shared_ptr<function_tdecl>
1457build_function_tdecl(reader&,
const xmlNodePtr,
bool);
1459static shared_ptr<class_tdecl>
1460build_class_tdecl(reader&,
const xmlNodePtr,
bool);
1463build_type_tparameter(reader&,
const xmlNodePtr,
1467build_type_composition(reader&,
const xmlNodePtr,
1471build_non_type_tparameter(reader&,
const xmlNodePtr,
1475build_template_tparameter(reader&,
const xmlNodePtr,
1479build_template_parameter(reader&,
const xmlNodePtr,
1486static shared_ptr<type_base>
1487build_type(reader&,
const xmlNodePtr,
bool);
1491static decl_base_sptr handle_type_decl(reader&, xmlNodePtr,
bool);
1492static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr,
bool);
1493static decl_base_sptr handle_qualified_type_decl(reader&,
1495static decl_base_sptr handle_pointer_type_def(reader&,
1497static decl_base_sptr handle_reference_type_def(reader&,
1499static type_base_sptr handle_function_type(reader&,
1501static decl_base_sptr handle_array_type_def(reader&,
1503static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr,
bool);
1504static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr,
bool);
1505static decl_base_sptr handle_var_decl(reader&, xmlNodePtr,
bool);
1506static decl_base_sptr handle_function_decl(reader&, xmlNodePtr,
bool);
1507static decl_base_sptr handle_class_decl(reader&, xmlNodePtr,
bool);
1508static decl_base_sptr handle_union_decl(reader&, xmlNodePtr,
bool);
1509static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr,
bool);
1510static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr,
bool);
1512#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1513#define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1514 rdr.record_artifact_as_used_by(used,user)
1515#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1516 rdr.record_artifacts_as_used_in_fn_decl(fn)
1517#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1518 rdr.record_artifacts_as_used_in_fn_type(fn_type)
1520#define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1521#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1522#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1545 xmlNodePtr parent = node->parent;
1548 && (xmlStrEqual(parent->name, BAD_CAST(
"data-member"))
1549 || xmlStrEqual(parent->name, BAD_CAST(
"member-type"))
1550 || xmlStrEqual(parent->name, BAD_CAST(
"member-function"))
1551 || xmlStrEqual(parent->name, BAD_CAST(
"member-template"))
1552 || xmlStrEqual(parent->name, BAD_CAST(
"template-parameter-type-composition"))
1553 || xmlStrEqual(parent->name, BAD_CAST(
"array-type-def"))))
1555 read_access(parent, access);
1556 parent = parent->parent;
1559 xml_node_decl_base_sptr_map::const_iterator i =
1560 get_xml_node_decl_map().find(parent);
1561 if (i == get_xml_node_decl_map().end())
1563 if (xmlStrEqual(parent->name, BAD_CAST(
"abi-instr")))
1566 get_or_read_and_add_translation_unit(*
this, parent);
1567 return tu->get_global_scope();
1572 push_decl(parent_scope);
1573 scope = dynamic_pointer_cast<scope_decl>
1574 (handle_element_node(*
this, parent,
true));
1576 pop_scope_or_abort(parent_scope);
1579 scope = dynamic_pointer_cast<scope_decl>(i->second);
1594reader::get_scope_for_node(xmlNodePtr node)
1597 return get_scope_for_node(node, access);
1610reader::get_scope_ptr_for_node(xmlNodePtr node)
1630 type_base_sptr t = get_type_decl(
id);
1634 xmlNodePtr n = get_xml_node_from_id(
id);
1641 scope = get_scope_for_node(n, access);
1649 if ((t = get_type_decl(
id)))
1667 pop_scope_or_abort(scope);
1681advance_cursor(reader& rdr)
1684 return xmlTextReaderRead(reader.get());
1696walk_xml_node_to_map_type_ids(reader& rdr,
1699 xmlNodePtr n = node;
1701 if (!n || n->type != XML_ELEMENT_NODE)
1706 string id = CHAR_STR(s);
1707 rdr.map_id_and_node(
id, n);
1710 for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1711 walk_xml_node_to_map_type_ids(rdr, n);
1717 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1719 if (!rdr.corpus()->is_empty())
1726 char address_size = atoi(
reinterpret_cast<char*
>(addrsize_str.get()));
1732 tu.
set_path(
reinterpret_cast<char*
>(path_str.get()));
1736 if (comp_dir_path_str)
1738 (comp_dir_path_str.get()));
1743 (
reinterpret_cast<char*
>(language_str.get())));
1751 if (rdr.get_id_xml_node_map().empty()
1753 walk_xml_node_to_map_type_ids(rdr, node);
1755 for (xmlNodePtr n = xmlFirstElementChild(node);
1757 n = xmlNextElementSibling(n))
1758 handle_element_node(rdr, n,
true);
1766 rdr.clear_per_translation_unit_data();
1785get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1787 corpus_sptr corp = rdr.corpus();
1795 tu_path =
reinterpret_cast<char*
>(path_str.get());
1798 if (corp && !corp->is_empty())
1799 tu = corp->find_translation_unit(tu_path);
1806 if (corp && !corp->is_empty())
1809 if (read_translation_unit(rdr, *tu, node))
1824read_translation_unit_from_input(
fe_iface& iface)
1828 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1830 xmlNodePtr node = rdr.get_corpus_node();
1841 status = advance_cursor (rdr);
1844 BAD_CAST(
"abi-instr")))
1847 node = xmlTextReaderExpand(reader.get());
1854 for (xmlNodePtr n = rdr.get_corpus_node();
1856 n = xmlNextElementSibling(n))
1858 if (!xmlStrEqual(n->name, BAD_CAST(
"abi-instr")))
1868 tu = get_or_read_and_add_translation_unit(rdr, node);
1870 if (rdr.get_corpus_node())
1876 node = xmlNextElementSibling(node);
1877 rdr.set_corpus_node(node);
1901read_symbol_db_from_input(reader& rdr,
1909 if (!rdr.get_corpus_node())
1915 status = advance_cursor (rdr);
1920 bool has_fn_syms =
false, has_var_syms =
false;
1922 BAD_CAST(
"elf-function-symbols")))
1925 BAD_CAST(
"elf-variable-symbols")))
1926 has_var_syms =
true;
1930 xmlNodePtr node = xmlTextReaderExpand(reader.get());
1935 fn_symdb = build_elf_symbol_db(rdr, node,
true);
1936 else if (has_var_syms)
1937 var_symdb = build_elf_symbol_db(rdr, node,
false);
1939 xmlTextReaderNext(reader.get());
1942 for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
1944 bool has_fn_syms =
false, has_var_syms =
false;
1945 if (xmlStrEqual(n->name, BAD_CAST(
"elf-function-symbols")))
1947 else if (xmlStrEqual(n->name, BAD_CAST(
"elf-variable-symbols")))
1948 has_var_syms =
true;
1951 rdr.set_corpus_node(n);
1956 fn_symdb = build_elf_symbol_db(rdr, n,
true);
1957 else if (has_var_syms)
1958 var_symdb = build_elf_symbol_db(rdr, n,
false);
1977build_needed(xmlNode* node, vector<string>& needed)
1979 if (!node || !xmlStrEqual(node->name,BAD_CAST(
"elf-needed")))
1982 for (xmlNodePtr n = xmlFirstElementChild(node);
1984 n = xmlNextElementSibling(n))
1986 if (!xmlStrEqual(n->name, BAD_CAST(
"dependency")))
1994 needed.push_back(name);
2010read_elf_needed_from_input(reader& rdr,
2011 vector<string>& needed)
2017 xmlNodePtr node = 0;
2019 if (rdr.get_corpus_node() == 0)
2024 status = advance_cursor (rdr);
2030 BAD_CAST(
"elf-needed")))
2033 node = xmlTextReaderExpand(reader.get());
2039 for (xmlNodePtr n = rdr.get_corpus_node();
2041 n = xmlNextElementSibling(n))
2043 if (!xmlStrEqual(n->name, BAD_CAST(
"elf-needed")))
2050 bool result =
false;
2053 result = build_needed(node, needed);
2054 node = xmlNextElementSibling(node);
2055 rdr.set_corpus_node(node);
2090 for (suppr::suppressions_type::const_iterator i = supprs.begin();
2093 if ((*i)->get_drops_artifact_from_ir())
2094 rdr.suppressions().push_back(*i);
2109 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2110 rdr.tracking_non_reachable_types(flag);
2113#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2122vector<type_base_sptr>*
2123get_types_from_type_id(
fe_iface& iface,
const string& type_id)
2125 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2126 auto it = rdr.m_types_map.find(type_id);
2127 if (it == rdr.m_types_map.end())
2138unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2139get_artifact_used_by_relation_map(fe_iface& iface)
2141 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2142 return &rdr.m_artifact_used_by_map;
2162 string version_string;
2167 if (version_string.empty())
2174 corp.set_format_major_version_number(v[0]);
2175 corp.set_format_minor_version_number(v[1]);
2188 corpus_group_sptr nil;
2190 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2199 status = advance_cursor (rdr);
2202 BAD_CAST(
"abi-corpus-group")))
2205 if (!rdr.corpus_group())
2207 corpus_group_sptr g(
new corpus_group(rdr.get_environment(),
2209 g->set_origin(corpus::NATIVE_XML_ORIGIN);
2210 rdr.corpus_group(g);
2213 corpus_group_sptr group = rdr.corpus_group();
2215 handle_version_attribute(reader, *group);
2219 group->set_path(
reinterpret_cast<char*
>(path_str.get()));
2221 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2225 node = xmlFirstElementChild(node);
2226 rdr.set_corpus_node(node);
2230 while ((corp = rdr.read_corpus(sts)))
2231 rdr.corpus_group()->add_corpus(corp);
2233 xmlTextReaderNext(reader.get());
2235 return rdr.corpus_group();
2297 rdr.perform_late_type_canonicalizing();
2319 rdr.perform_late_type_canonicalizing();
2334 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2336 rdr.options().env.canonicalization_is_done(
false);
2337 rdr.perform_late_type_canonicalizing();
2338 rdr.options().env.canonicalization_is_done(
true);
2351handle_element_node(reader& rdr, xmlNodePtr node,
2352 bool add_to_current_scope)
2358 ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2359 ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2360 ||(decl = handle_qualified_type_decl(rdr, node,
2361 add_to_current_scope))
2362 ||(decl = handle_pointer_type_def(rdr, node,
2363 add_to_current_scope))
2364 || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2365 || (decl = handle_function_type(rdr, node, add_to_current_scope))
2366 || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2367 || (decl = handle_enum_type_decl(rdr, node,
2368 add_to_current_scope))
2369 || (decl = handle_typedef_decl(rdr, node,
2370 add_to_current_scope))
2371 || (decl = handle_var_decl(rdr, node,
2372 add_to_current_scope))
2373 || (decl = handle_function_decl(rdr, node,
2374 add_to_current_scope))
2375 || (decl = handle_class_decl(rdr, node,
2376 add_to_current_scope))
2377 || (decl = handle_union_decl(rdr, node,
2378 add_to_current_scope))
2379 || (decl = handle_function_tdecl(rdr, node,
2380 add_to_current_scope))
2381 || (decl = handle_class_tdecl(rdr, node,
2382 add_to_current_scope)));
2387 if (rdr.tracking_non_reachable_types())
2389 if (type_base_sptr t =
is_type(decl))
2391 corpus_sptr abi = rdr.corpus();
2393 bool is_non_reachable_type =
false;
2394 read_is_non_reachable_type(node, is_non_reachable_type);
2395 if (!is_non_reachable_type)
2396 abi->record_type_as_reachable_from_public_interfaces(*t);
2411read_location(
const reader& rdr,
2416 size_t line = 0, column = 0;
2419 file_path = CHAR_STR(f);
2421 if (file_path.empty())
2422 return read_artificial_location(rdr, node, loc);
2425 line = atoi(CHAR_STR(l));
2427 return read_artificial_location(rdr, node, loc);
2430 column = atoi(CHAR_STR(c));
2432 reader& c =
const_cast<reader&
>(rdr);
2433 loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2450read_artificial_location(
const reader& rdr,
2458 size_t line = 0, column = 0;
2463 file_path =
reinterpret_cast<const char*
>(node->doc->URL);
2465 reader& c =
const_cast<reader&
>(rdr);
2467 c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2469 loc.set_is_artificial(
true);
2489maybe_set_artificial_location(
const reader& rdr,
2493 if (artefact && !artefact->has_artificial_location())
2496 if (read_artificial_location(rdr, node, l))
2498 artefact->set_artificial_location(l);
2517 string v = CHAR_STR(s);
2520 vis = decl_base::VISIBILITY_DEFAULT;
2521 else if (v ==
"hidden")
2522 vis = decl_base::VISIBILITY_HIDDEN;
2523 else if (v ==
"internal")
2524 vis = decl_base::VISIBILITY_INTERNAL;
2525 else if (v ==
"protected")
2526 vis = decl_base::VISIBILITY_PROTECTED;
2528 vis = decl_base::VISIBILITY_DEFAULT;
2546 string b = CHAR_STR(s);
2549 bind = decl_base::BINDING_GLOBAL;
2550 else if (b ==
"local")
2551 bind = decl_base::BINDING_LOCAL;
2552 else if (b ==
"weak")
2553 bind = decl_base::BINDING_WEAK;
2555 bind = decl_base::BINDING_GLOBAL;
2574 string a = CHAR_STR(s);
2577 access = private_access;
2578 else if (a ==
"protected")
2579 access = protected_access;
2580 else if (a ==
"public")
2581 access = public_access;
2609read_size_and_alignment(xmlNodePtr node,
2610 size_t& size_in_bits,
2611 size_t& align_in_bits)
2614 bool got_something =
false;
2617 size_in_bits = atoll(CHAR_STR(s));
2618 got_something =
true;
2623 align_in_bits = atoll(CHAR_STR(s));
2624 got_something =
true;
2626 return got_something;
2639read_static(xmlNodePtr node,
bool& is_static)
2643 string b = CHAR_STR(s);
2644 is_static = b ==
"yes";
2657read_offset_in_bits(xmlNodePtr node,
2658 size_t& offset_in_bits)
2662 offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2690read_cdtor_const(xmlNodePtr node,
2691 bool& is_constructor,
2692 bool& is_destructor,
2697 string b = CHAR_STR(s);
2699 is_constructor =
true;
2701 is_constructor =
false;
2708 string b = CHAR_STR(s);
2710 is_destructor =
true;
2712 is_destructor =
false;
2719 string b = CHAR_STR(s);
2740read_is_declaration_only(xmlNodePtr node,
bool& is_decl_only)
2744 string str = CHAR_STR(s);
2746 is_decl_only =
true;
2748 is_decl_only =
false;
2764read_is_artificial(xmlNodePtr node,
bool& is_artificial)
2768 string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2769 is_artificial = is_artificial_str ==
"yes";
2788read_tracking_non_reachable_types(xmlNodePtr node,
2789 bool& tracking_non_reachable_types)
2794 string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2795 tracking_non_reachable_types =
2796 (tracking_non_reachable_types_str ==
"yes")
2815read_is_non_reachable_type(xmlNodePtr node,
bool& is_non_reachable_type)
2820 string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2821 is_non_reachable_type =
2822 (is_non_reachable_type_str ==
"yes")
2840read_naming_typedef_id_string(xmlNodePtr node,
string& naming_typedef_id)
2859read_is_virtual(xmlNodePtr node,
bool& is_virtual)
2863 string str = CHAR_STR(s);
2882read_is_struct(xmlNodePtr node,
bool& is_struct)
2886 string str = CHAR_STR(s);
2905read_is_anonymous(xmlNodePtr node,
bool& is_anonymous)
2909 string str = CHAR_STR(s);
2910 is_anonymous = (str ==
"yes");
2987read_type_id_string(xmlNodePtr node,
string& type_id)
2991 type_id = CHAR_STR(s);
2997#ifdef WITH_DEBUG_SELF_COMPARISON
3012maybe_map_type_with_type_id(
const type_base_sptr& t,
3013 const string& type_id)
3018 const environment& env = t->get_environment();
3019 if (!env.self_comparison_debug_is_on()
3023 const_cast<environment&
>(env).
3024 get_pointer_type_id_map()[
reinterpret_cast<uintptr_t
>(t.get())] = type_id;
3043maybe_map_type_with_type_id(
const type_base_sptr& t,
3049 const environment&env = t->get_environment();
3050 if (!env.self_comparison_debug_is_on()
3055 if (!read_type_id_string(node, type_id) || type_id.empty())
3058 return maybe_map_type_with_type_id(t, type_id);
3072maybe_set_naming_typedef(reader& rdr,
3074 const decl_base_sptr& decl)
3076 string naming_typedef_id;
3077 read_naming_typedef_id_string(node, naming_typedef_id);
3078 if (!naming_typedef_id.empty())
3081 is_typedef(rdr.build_or_get_type_decl(naming_typedef_id,
true));
3083 decl->set_naming_typedef(naming_typedef);
3103build_namespace_decl(reader& rdr,
3104 const xmlNodePtr node,
3105 bool add_to_current_scope)
3108 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"namespace-decl")))
3111 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3123 read_location(rdr, node, loc);
3125 const environment& env = rdr.get_environment();
3127 maybe_set_artificial_location(rdr, node, decl);
3128 rdr.push_decl_to_scope(decl,
3129 add_to_current_scope
3130 ? rdr.get_scope_ptr_for_node(node)
3132 rdr.map_xml_node_to_decl(node, decl);
3134 for (xmlNodePtr n = xmlFirstElementChild(node);
3136 n = xmlNextElementSibling(n))
3137 handle_element_node(rdr, n,
true);
3139 rdr.pop_scope_or_abort(decl);
3156build_elf_symbol(reader& rdr,
const xmlNodePtr node,
3157 bool drop_if_suppressed)
3162 || node->type != XML_ELEMENT_NODE
3163 || !xmlStrEqual(node->name, BAD_CAST(
"elf-symbol")))
3172 size = strtol(CHAR_STR(s), NULL, 0);
3174 bool is_defined =
true;
3179 if (value ==
"true" || value ==
"yes")
3185 bool is_common =
false;
3190 if (value ==
"true" || value ==
"yes")
3196 string version_string;
3200 bool is_default_version =
false;
3205 if (value ==
"true" || value ==
"yes")
3206 is_default_version =
true;
3210 read_elf_symbol_type(node, type);
3213 read_elf_symbol_binding(node, binding);
3216 read_elf_symbol_visibility(node, visibility);
3218 elf_symbol::version version(version_string, is_default_version);
3221 if (drop_if_suppressed && is_suppressed)
3224 const environment& env = rdr.get_environment();
3226 size, name, type, binding,
3227 is_defined, is_common,
3228 version, visibility);
3230 e->set_is_suppressed(is_suppressed);
3233 e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3239 e->set_namespace(ns);
3259build_elf_symbol_from_reference(reader& rdr,
const xmlNodePtr node)
3278 if (rdr.corpus()->get_symtab())
3281 rdr.corpus()->get_symtab()->lookup_symbol(name);
3283 for (
const auto& symbol : symbols)
3284 if (symbol->get_id_string() == sym_id)
3304build_elf_symbol_db(reader& rdr,
3305 const xmlNodePtr node,
3315 && !xmlStrEqual(node->name, BAD_CAST(
"elf-function-symbols")))
3319 && !xmlStrEqual(node->name, BAD_CAST(
"elf-variable-symbols")))
3322 rdr.set_corpus_node(node);
3324 typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3325 xml_node_ptr_elf_symbol_sptr_map_type;
3326 xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3329 for (xmlNodePtr n = xmlFirstElementChild(node);
3331 n = xmlNextElementSibling(n))
3332 if ((sym = build_elf_symbol(rdr, n,
false)))
3334 id_sym_map[sym->get_id_string()] = sym;
3335 xml_node_ptr_elf_symbol_map[n] = sym;
3338 if (id_sym_map.empty())
3342 string_elf_symbols_map_type::iterator it;
3343 for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3344 i != id_sym_map.end();
3346 (*map)[i->second->get_name()].push_back(i->second);
3349 for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3350 xml_node_ptr_elf_symbol_map.begin();
3351 x != xml_node_ptr_elf_symbol_map.end();
3356 string alias_id = CHAR_STR(s);
3359 std::vector<std::string> elems;
3360 std::stringstream aliases(alias_id);
3362 while (std::getline(aliases, item,
','))
3363 elems.push_back(item);
3364 for (std::vector<string>::iterator alias = elems.begin();
3365 alias != elems.end(); ++alias)
3367 string_elf_symbol_sptr_map_type::const_iterator i =
3368 id_sym_map.find(*alias);
3372 x->second->get_main_symbol()->add_alias(i->second);
3385static shared_ptr<function_decl::parameter>
3386build_function_parameter(reader& rdr,
const xmlNodePtr node)
3388 shared_ptr<function_decl::parameter> nil;
3390 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"parameter")))
3393 bool is_variadic =
false;
3394 string is_variadic_str;
3398 is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
3399 is_variadic = is_variadic_str ==
"yes";
3402 bool is_artificial =
false;
3403 read_is_artificial(node, is_artificial);
3407 type_id = CHAR_STR(a);
3409 type_base_sptr type;
3411 type = rdr.get_environment().get_variadic_parameter_type();
3415 type = rdr.build_or_get_type_decl(type_id,
true);
3424 read_location(rdr, node, loc);
3427 (
new function_decl::parameter(type, name, loc,
3428 is_variadic, is_artificial));
3456build_function_decl(reader& rdr,
3457 const xmlNodePtr node,
3458 class_or_union_sptr as_method_decl,
3459 bool add_to_current_scope,
3460 bool add_to_exported_decls)
3464 if (!xmlStrEqual(node->name, BAD_CAST(
"function-decl")))
3471 string mangled_name;
3476 && !mangled_name.empty()
3477 && as_method_decl->find_member_function_sptr(mangled_name))
3480 as_method_decl->find_member_function_sptr(mangled_name);
3487 inline_prop = CHAR_STR(s);
3488 bool declared_inline = inline_prop ==
"yes";
3491 read_visibility(node, vis);
3494 read_binding(node, bind);
3496 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3497 read_size_and_alignment(node, size, align);
3500 read_location(rdr, node, loc);
3502 const environment& env = rdr.get_environment();
3504 std::vector<function_decl::parameter_sptr> parms;
3505 type_base_sptr return_type = env.get_void_type();
3507 for (xmlNodePtr n = xmlFirstElementChild(node);
3509 n = xmlNextElementSibling(n))
3511 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
3514 build_function_parameter(rdr, n))
3517 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
3522 type_id = CHAR_STR(s);
3523 if (!type_id.empty())
3524 return_type = rdr.build_or_get_type_decl(type_id,
true);
3529 ?
new method_type(return_type, as_method_decl,
3532 :
new function_type(return_type,
3533 parms, size, align));
3537 fn_type->set_is_artificial(
true);
3540 ?
new method_decl (name, fn_type,
3541 declared_inline, loc,
3542 mangled_name, vis, bind)
3543 :
new function_decl(name, fn_type,
3544 declared_inline, loc,
3548 maybe_set_artificial_location(rdr, node, fn_decl);
3549 rdr.push_decl_to_scope(fn_decl,
3550 add_to_current_scope
3551 ? rdr.get_scope_ptr_for_node(node)
3553 RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3557 fn_decl->set_symbol(sym);
3559 if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3560 fn_decl->set_is_in_public_symbol_table(
true);
3562 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3564 rdr.maybe_canonicalize_type(fn_type, !add_to_current_scope);
3566 if (add_to_exported_decls)
3567 rdr.maybe_add_fn_to_exported_decls(fn_decl.get());
3598build_function_decl_if_not_suppressed(reader& rdr,
3599 const xmlNodePtr node,
3600 class_or_union_sptr as_method_decl,
3601 bool add_to_current_scope,
3602 bool add_to_exported_decls)
3606 if (function_is_suppressed(rdr, node))
3612 fn = build_function_decl(rdr, node, as_method_decl,
3613 add_to_current_scope,
3614 add_to_exported_decls);
3630function_is_suppressed(
const reader& rdr, xmlNodePtr node)
3636 string flinkage_name;
3640 scope_decl* scope = rdr.get_cur_scope();
3659type_is_suppressed(
const reader& rdr, xmlNodePtr node)
3665 location type_location;
3666 read_location(rdr, node, type_location);
3668 scope_decl* scope = rdr.get_cur_scope();
3672 bool type_is_private =
false;
3691build_var_decl_if_not_suppressed(reader& rdr,
3692 const xmlNodePtr node,
3693 bool add_to_current_scope)
3696 if (!variable_is_suppressed(rdr, node))
3697 var = build_var_decl(rdr, node, add_to_current_scope);
3710variable_is_suppressed(
const reader& rdr, xmlNodePtr node)
3716 string linkage_name;
3720 scope_decl* scope = rdr.get_cur_scope();
3738variable_is_suppressed(
const reader& rdr,
3739 const scope_decl* scope,
3744 v.get_linkage_name());
3755static shared_ptr<var_decl>
3756build_var_decl(reader& rdr,
3757 const xmlNodePtr node,
3758 bool add_to_current_scope)
3760 shared_ptr<var_decl> nil;
3762 if (!xmlStrEqual(node->name, BAD_CAST(
"var-decl")))
3771 type_id = CHAR_STR(s);
3772 type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
3776 string mangled_name;
3781 read_visibility(node, vis);
3784 read_binding(node, bind);
3787 read_location(rdr, node, locus);
3790 locus, mangled_name,
3792 maybe_set_artificial_location(rdr, node, decl);
3796 decl->set_symbol(sym);
3798 rdr.push_decl_to_scope(decl,
3799 add_to_current_scope
3800 ? rdr.get_scope_ptr_for_node(node)
3802 if (add_to_current_scope)
3806 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
3809 if (decl->get_symbol() && decl->get_symbol()->is_public())
3810 decl->set_is_in_public_symbol_table(
true);
3820static decl_base_sptr
3821build_ir_node_for_void_type(reader& rdr)
3823 const environment& env = rdr.get_environment();
3825 type_base_sptr t = env.get_void_type();
3829 return type_declaration;
3843static decl_base_sptr
3844build_ir_node_for_void_pointer_type(reader& rdr)
3846 const environment& env = rdr.get_environment();
3848 type_base_sptr t = env.get_void_pointer_type();
3852 return type_declaration;
3867build_type_decl(reader& rdr,
3868 const xmlNodePtr node,
3869 bool add_to_current_scope)
3871 shared_ptr<type_decl> nil;
3873 if (!xmlStrEqual(node->name, BAD_CAST(
"type-decl")))
3876 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3892 size_t size_in_bits= 0;
3894 size_in_bits = atoi(CHAR_STR(s));
3896 size_t alignment_in_bits = 0;
3898 alignment_in_bits = atoi(CHAR_STR(s));
3900 bool is_decl_only =
false;
3901 read_is_declaration_only(node, is_decl_only);
3904 read_location(rdr, node, loc);
3906 bool is_anonymous =
false;
3907 read_is_anonymous(node, is_anonymous);
3909 if (type_base_sptr d = rdr.get_type_decl(
id))
3917 ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
3918 ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
3922 const environment& env = rdr.get_environment();
3924 if (name == env.get_variadic_parameter_type_name())
3925 decl =
is_type_decl(env.get_variadic_parameter_type());
3926 else if (name ==
"void")
3929 decl.reset(
new type_decl(env, name, size_in_bits,
3930 alignment_in_bits, loc));
3931 maybe_set_artificial_location(rdr, node, decl);
3932 decl->set_is_anonymous(is_anonymous);
3933 decl->set_is_declaration_only(is_decl_only);
3934 if (rdr.push_and_key_type_decl(decl, node, add_to_current_scope))
3936 rdr.map_xml_node_to_decl(node, decl);
3954static qualified_type_def_sptr
3955build_qualified_type_decl(reader& rdr,
3956 const xmlNodePtr node,
3957 bool add_to_current_scope)
3959 qualified_type_def_sptr nil;
3960 if (!xmlStrEqual(node->name, BAD_CAST(
"qualified-type-def")))
3963 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3965 qualified_type_def_sptr result =
3966 dynamic_pointer_cast<qualified_type_def>(d);
3978 read_location(rdr, node, loc);
3983 const_str = CHAR_STR(s);
3984 bool const_cv = const_str ==
"yes";
3986 string volatile_str;
3988 volatile_str = CHAR_STR(s);
3989 bool volatile_cv = volatile_str ==
"yes";
3991 string restrict_str;
3993 restrict_str = CHAR_STR(s);
3994 bool restrict_cv = restrict_str ==
"yes";
3997 cv = cv | qualified_type_def::CV_CONST;
3999 cv = cv | qualified_type_def::CV_VOLATILE;
4001 cv = cv | qualified_type_def::CV_RESTRICT;
4005 type_id = CHAR_STR(s);
4008 shared_ptr<type_base> underlying_type =
4009 rdr.build_or_get_type_decl(type_id,
true);
4012 qualified_type_def_sptr decl;
4013 if (type_base_sptr t = rdr.get_type_decl(
id))
4020 decl.reset(
new qualified_type_def(underlying_type, cv, loc));
4021 maybe_set_artificial_location(rdr, node, decl);
4022 rdr.push_and_key_type_decl(decl, node, add_to_current_scope);
4023 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4026 rdr.map_xml_node_to_decl(node, decl);
4043build_pointer_type_def(reader& rdr,
4044 const xmlNodePtr node,
4045 bool add_to_current_scope)
4048 shared_ptr<pointer_type_def> nil;
4050 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-type-def")))
4053 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4056 dynamic_pointer_cast<pointer_type_def>(d);
4066 if (type_base_sptr t = rdr.get_type_decl(
id))
4075 type_id = CHAR_STR(s);
4077 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4078 size_t alignment_in_bits = 0;
4079 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4081 read_location(rdr, node, loc);
4083 type_base_sptr pointed_to_type =
4084 rdr.build_or_get_type_decl(type_id,
true);
4088 if (rdr.get_environment().is_void_type(pointed_to_type))
4096 t.reset(
new pointer_type_def(pointed_to_type,
4101 maybe_set_artificial_location(rdr, node, t);
4103 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4104 rdr.map_xml_node_to_decl(node, t);
4106 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4122static shared_ptr<reference_type_def>
4123build_reference_type_def(reader& rdr,
4124 const xmlNodePtr node,
4125 bool add_to_current_scope)
4127 shared_ptr<reference_type_def> nil;
4129 if (!xmlStrEqual(node->name, BAD_CAST(
"reference-type-def")))
4132 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4135 dynamic_pointer_cast<reference_type_def>(d);
4145 if (type_base_sptr d = rdr.get_type_decl(
id))
4153 read_location(rdr, node, loc);
4157 bool is_lvalue = kind ==
"lvalue";
4159 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4160 size_t alignment_in_bits = 0;
4161 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4165 type_id = CHAR_STR(s);
4175 is_lvalue, size_in_bits,
4176 alignment_in_bits, loc));
4177 maybe_set_artificial_location(rdr, node, t);
4178 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4179 rdr.map_xml_node_to_decl(node, t);
4181 type_base_sptr pointed_to_type =
4182 rdr.build_or_get_type_decl(type_id,
true);
4184 t->set_pointed_to_type(pointed_to_type);
4185 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4203build_ptr_to_mbr_type(reader& rdr,
4204 const xmlNodePtr node,
4205 bool add_to_current_scope)
4209 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-to-member-type")))
4212 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4226 if (type_base_sptr d = rdr.get_type_decl(
id))
4233 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4234 size_t alignment_in_bits = 0;
4235 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4238 read_location(rdr, node, loc);
4240 string member_type_id;
4242 member_type_id = CHAR_STR(s);
4243 if (member_type_id.empty())
4245 type_base_sptr member_type =
4246 is_type(rdr.build_or_get_type_decl(member_type_id,
true));
4250 string containing_type_id;
4252 containing_type_id = CHAR_STR(s);
4253 if (containing_type_id.empty())
4255 type_base_sptr containing_type =
4256 rdr.build_or_get_type_decl(containing_type_id,
true);
4260 result.reset(
new ptr_to_mbr_type(rdr.get_environment(),
4261 member_type, containing_type,
4262 size_in_bits, alignment_in_bits,
4265 if (rdr.push_and_key_type_decl(result, node, add_to_current_scope))
4266 rdr.map_xml_node_to_decl(node, result);
4284build_function_type(reader& rdr,
4285 const xmlNodePtr node,
4290 if (!xmlStrEqual(node->name, BAD_CAST(
"function-type")))
4298 string method_class_id;
4300 method_class_id = CHAR_STR(s);
4302 bool is_method_t = !method_class_id.empty();
4304 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4305 read_size_and_alignment(node, size, align);
4307 const environment& env = rdr.get_environment();
4308 std::vector<shared_ptr<function_decl::parameter> > parms;
4309 type_base_sptr return_type = env.get_void_type();
4311 class_or_union_sptr method_class_type;
4321 ?
new method_type(method_class_type,
4324 :
new function_type(return_type,
4325 parms, size, align));
4327 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4328 rdr.key_type_decl(fn_type,
id);
4329 RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4331 for (xmlNodePtr n = xmlFirstElementChild(node);
4333 n = xmlNextElementSibling(n))
4335 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
4338 build_function_parameter(rdr, n))
4341 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
4346 type_id = CHAR_STR(s);
4347 if (!type_id.empty())
4348 fn_type->set_return_type(rdr.build_or_get_type_decl
4353 fn_type->set_parameters(parms);
4369build_subrange_type(reader& rdr,
4370 const xmlNodePtr node,
4371 bool add_to_current_scope)
4375 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"subrange")))
4378 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4381 dynamic_pointer_cast<array_type_def::subrange_type>(d);
4395 if (type_base_sptr d = rdr.get_type_decl(
id))
4406 uint64_t length = 0;
4408 bool is_non_finite =
false;
4411 if (
string(CHAR_STR(s)) ==
"infinite" ||
string(CHAR_STR(s)) ==
"unknown")
4412 is_non_finite =
true;
4414 length = strtoull(CHAR_STR(s), NULL, 0);
4417 int64_t lower_bound = 0, upper_bound = 0;
4418 bool bounds_present =
false;
4421 lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4423 if (!
string(CHAR_STR(s)).empty())
4424 upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4425 bounds_present =
true;
4427 || (length == (uint64_t) upper_bound - lower_bound + 1));
4430 string underlying_type_id;
4432 underlying_type_id = CHAR_STR(s);
4434 type_base_sptr underlying_type;
4435 if (!underlying_type_id.empty())
4437 underlying_type = rdr.build_or_get_type_decl(underlying_type_id,
true);
4442 read_location(rdr, node, loc);
4447 array_type_def::subrange_type::bound_value max_bound;
4448 array_type_def::subrange_type::bound_value min_bound;
4454 max_bound.set_signed(length - 1);
4460 min_bound.set_signed(lower_bound);
4461 max_bound.set_signed(upper_bound);
4465 (
new array_type_def::subrange_type(rdr.get_environment(),
4466 name, min_bound, max_bound,
4467 underlying_type, loc));
4468 maybe_set_artificial_location(rdr, node, p);
4469 p->is_non_finite(is_non_finite);
4471 if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
4472 rdr.map_xml_node_to_decl(node, p);
4489build_array_type_def(reader& rdr,
4490 const xmlNodePtr node,
4491 bool add_to_current_scope)
4496 if (!xmlStrEqual(node->name, BAD_CAST(
"array-type-def")))
4499 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4502 dynamic_pointer_cast<array_type_def>(d);
4512 if (type_base_sptr d = rdr.get_type_decl(
id))
4521 dimensions = atoi(CHAR_STR(s));
4525 type_id = CHAR_STR(s);
4529 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4532 dynamic_pointer_cast<array_type_def>(d);
4537 size_t size_in_bits = 0, alignment_in_bits = 0;
4538 bool has_size_in_bits =
false;
4543 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4544 if (*endptr !=
'\0')
4546 if (!strcmp(CHAR_STR(s),
"infinite")
4547 ||!strcmp(CHAR_STR(s),
"unknown"))
4548 size_in_bits = (size_t) -1;
4552 has_size_in_bits =
true;
4557 alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4558 if (*endptr !=
'\0')
4563 read_location(rdr, node, loc);
4566 for (xmlNodePtr n = xmlFirstElementChild(node);
4568 n = xmlNextElementSibling(n))
4569 if (xmlStrEqual(n->name, BAD_CAST(
"subrange")))
4572 build_subrange_type(rdr, n,
true))
4574 MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
4575 if (add_to_current_scope)
4578 rdr.maybe_canonicalize_type(s);
4580 subranges.push_back(s);
4585 type_base_sptr type =
4586 rdr.build_or_get_type_decl(type_id,
true);
4590 maybe_set_artificial_location(rdr, node, ar_type);
4591 if (rdr.push_and_key_type_decl(ar_type, node, add_to_current_scope))
4592 rdr.map_xml_node_to_decl(node, ar_type);
4593 RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
4595 if (dimensions != ar_type->get_dimension_count()
4596 || (alignment_in_bits
4597 != ar_type->get_element_type()->get_alignment_in_bits()))
4600 if (has_size_in_bits && size_in_bits != (
size_t) -1
4601 && size_in_bits != ar_type->get_size_in_bits())
4604 size_t element_size = ar_type->get_element_type()->get_size_in_bits();
4605 if (element_size && element_size != (
size_t)-1)
4608 size_t bad_count = 0;
4609 for (vector<array_type_def::subrange_sptr>::const_iterator i =
4611 i != subranges.end();
4613 bad_count += (*i)->get_length();
4614 if (size_in_bits == bad_count * element_size)
4616 static bool reported =
false;
4619 std::cerr <<
"notice: Found incorrectly calculated array "
4620 <<
"sizes in XML - this is benign.\nOlder versions "
4621 <<
"of libabigail miscalculated multidimensional "
4622 <<
"array sizes." << std::endl;
4628 std::cerr <<
"error: Found incorrectly calculated array size in "
4629 <<
"XML (id=\"" <<
id <<
"\")." << std::endl;
4653build_enum_type_decl_if_not_suppressed(reader& rdr,
4654 const xmlNodePtr node,
4655 bool add_to_current_scope)
4658 if (!type_is_suppressed(rdr, node))
4659 enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
4675build_enum_type_decl(reader& rdr,
4676 const xmlNodePtr node,
4677 bool add_to_current_scope)
4681 if (!xmlStrEqual(node->name, BAD_CAST(
"enum-decl")))
4684 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4687 dynamic_pointer_cast<enum_type_decl>(d);
4696 string linkage_name;
4701 read_location(rdr, node, loc);
4703 bool is_decl_only =
false;
4704 read_is_declaration_only(node, is_decl_only);
4706 bool is_anonymous =
false;
4707 read_is_anonymous(node, is_anonymous);
4709 bool is_artificial =
false;
4710 read_is_artificial(node, is_artificial);
4718 string base_type_id;
4720 for (xmlNodePtr n = xmlFirstElementChild(node);
4722 n = xmlNextElementSibling(n))
4724 if (xmlStrEqual(n->name, BAD_CAST(
"underlying-type")))
4728 base_type_id = CHAR_STR(a);
4731 else if (xmlStrEqual(n->name, BAD_CAST(
"enumerator")))
4743 value = strtoll(CHAR_STR(a), NULL, 0);
4747 if ((errno == ERANGE)
4748 && (value == LLONG_MIN || value == LLONG_MAX))
4752 enums.push_back(enum_type_decl::enumerator(name, value));
4756 type_base_sptr underlying_type =
4757 rdr.build_or_get_type_decl(base_type_id,
true);
4762 enums, linkage_name));
4763 maybe_set_artificial_location(rdr, node, t);
4764 t->set_is_anonymous(is_anonymous);
4765 t->set_is_artificial(is_artificial);
4766 t->set_is_declaration_only(is_decl_only);
4767 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4769 maybe_set_naming_typedef(rdr, node, t);
4770 rdr.map_xml_node_to_decl(node, t);
4771 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4786static shared_ptr<typedef_decl>
4787build_typedef_decl(reader& rdr,
4788 const xmlNodePtr node,
4789 bool add_to_current_scope)
4791 shared_ptr<typedef_decl> nil;
4793 if (!xmlStrEqual(node->name, BAD_CAST(
"typedef-decl")))
4796 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4813 read_location(rdr, node, loc);
4817 type_id = CHAR_STR(s);
4820 type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id,
true));
4824 maybe_set_artificial_location(rdr, node, t);
4825 rdr.push_and_key_type_decl(t, node, add_to_current_scope);
4826 rdr.map_xml_node_to_decl(node, t);
4827 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4844build_class_decl_if_not_suppressed(reader& rdr,
4845 const xmlNodePtr node,
4846 bool add_to_current_scope)
4849 if (!type_is_suppressed(rdr, node))
4850 class_type = build_class_decl(rdr, node, add_to_current_scope);
4866static union_decl_sptr
4867build_union_decl_if_not_suppressed(reader& rdr,
4868 const xmlNodePtr node,
4869 bool add_to_current_scope)
4871 union_decl_sptr union_type;
4872 if (!type_is_suppressed(rdr, node))
4873 union_type = build_union_decl(rdr, node, add_to_current_scope);
4890build_class_decl(reader& rdr,
4891 const xmlNodePtr node,
4892 bool add_to_current_scope)
4896 if (!xmlStrEqual(node->name, BAD_CAST(
"class-decl")))
4899 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4910 size_t size_in_bits = 0, alignment_in_bits = 0;
4911 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4914 read_visibility(node, vis);
4916 bool is_artificial =
false;
4917 read_is_artificial(node, is_artificial);
4924 read_location(rdr, node, loc);
4933 bool is_decl_only =
false;
4934 read_is_declaration_only(node, is_decl_only);
4936 bool is_struct =
false;
4937 read_is_struct(node, is_struct);
4939 bool is_anonymous =
false;
4940 read_is_anonymous(node, is_anonymous);
4946 if (type_base_sptr t = rdr.get_type_decl(
id))
4952 const vector<type_base_sptr> *types_ptr = 0;
4953 if (!is_anonymous && !previous_definition)
4954 types_ptr = rdr.get_all_type_decls(
id);
4960 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
4961 i != types_ptr->end();
4966 if (klass->get_is_declaration_only()
4967 && !klass->get_definition_of_declaration())
4968 previous_declaration = klass;
4969 else if (!klass->get_is_declaration_only()
4970 && !previous_definition)
4971 previous_definition = klass;
4972 if (previous_definition && previous_declaration)
4976 if (previous_declaration)
4977 ABG_ASSERT(previous_declaration->get_name() == name);
4979 if (previous_definition)
4980 ABG_ASSERT(previous_definition->get_name() == name);
4982 if (is_decl_only && previous_declaration)
4983 return previous_declaration;
4986 const environment& env = rdr.get_environment();
4988 if (!is_decl_only && previous_definition)
4994 decl = previous_definition;
4999 decl.reset(
new class_decl(env, name, is_struct));
5001 decl->set_size_in_bits(size_in_bits);
5003 decl->set_is_anonymous(is_anonymous);
5004 decl->set_location(loc);
5007 decl.reset(
new class_decl(env, name, size_in_bits, alignment_in_bits,
5008 is_struct, loc, vis, bases, mbrs,
5009 data_mbrs, mbr_functions, is_anonymous));
5012 maybe_set_artificial_location(rdr, node, decl);
5013 decl->set_is_artificial(is_artificial);
5016 bool is_def_of_decl =
false;
5018 def_id = CHAR_STR(s);
5020 if (!def_id.empty())
5022 decl_base_sptr d =
is_decl(rdr.get_type_decl(def_id));
5023 if (d && d->get_is_declaration_only())
5025 is_def_of_decl =
true;
5026 decl->set_earlier_declaration(d);
5027 d->set_definition_of_declaration(decl);
5033 && !decl->get_is_declaration_only()
5034 && previous_declaration)
5040 decl->set_earlier_declaration(
is_decl(previous_declaration));
5041 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5042 i != types_ptr->end();
5047 if (d->get_is_declaration_only()
5048 && !d->get_definition_of_declaration())
5050 previous_declaration->set_definition_of_declaration(decl);
5051 is_def_of_decl =
true;
5056 if (is_decl_only && previous_definition)
5061 && !decl->get_definition_of_declaration());
5062 decl->set_definition_of_declaration(previous_definition);
5065 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5067 rdr.push_decl_to_scope(decl,
5068 add_to_current_scope
5069 ? rdr.get_scope_ptr_for_node(node)
5072 rdr.map_xml_node_to_decl(node, decl);
5073 rdr.key_type_decl(decl,
id);
5076 maybe_set_naming_typedef(rdr, node, decl);
5078 for (xmlNodePtr n = xmlFirstElementChild(node);
5080 n = xmlNextElementSibling(n))
5082 if (xmlStrEqual(n->name, BAD_CAST(
"base-class")))
5088 read_access(n, access);
5092 type_id = CHAR_STR(s);
5093 shared_ptr<class_decl> b =
5094 dynamic_pointer_cast<class_decl>
5095 (rdr.build_or_get_type_decl(type_id,
true));
5098 if (decl->find_base_class(b->get_qualified_name()))
5104 size_t offset_in_bits = 0;
5105 bool offset_present = read_offset_in_bits (n, offset_in_bits);
5107 bool is_virtual =
false;
5108 read_is_virtual (n, is_virtual);
5110 shared_ptr<class_decl::base_spec> base (
new class_decl::base_spec
5113 ? (
long) offset_in_bits
5116 decl->add_base_specifier(base);
5118 else if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5124 read_access(n, access);
5126 rdr.map_xml_node_to_decl(n, decl);
5128 for (xmlNodePtr p = xmlFirstElementChild(n);
5130 p = xmlNextElementSibling(p))
5132 if (type_base_sptr t =
5133 build_type(rdr, p,
true))
5138 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5140 string id = CHAR_STR(i);
5142 rdr.key_type_decl(t,
id);
5143 rdr.map_xml_node_to_decl(p, td);
5147 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5149 rdr.map_xml_node_to_decl(n, decl);
5155 read_access(n, access);
5157 bool is_laid_out =
false;
5158 size_t offset_in_bits = 0;
5159 if (read_offset_in_bits(n, offset_in_bits))
5162 bool is_static =
false;
5163 read_static(n, is_static);
5165 for (xmlNodePtr p = xmlFirstElementChild(n);
5167 p = xmlNextElementSibling(p))
5170 build_var_decl(rdr, p,
false))
5172 if (decl->find_data_member(v))
5180 decl_base_sptr d = rdr.pop_decl();
5185 if (!variable_is_suppressed(rdr, decl.get(), *v))
5187 decl->add_data_member(v, access,
5192 rdr.maybe_add_var_to_exported_decls(v.get());
5202 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5205 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5206 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5212 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5218 read_access(n, access);
5220 bool is_virtual =
false;
5221 ssize_t vtable_offset = -1;
5226 vtable_offset = atoi(CHAR_STR(s));
5229 bool is_static =
false;
5230 read_static(n, is_static);
5232 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5233 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5235 for (xmlNodePtr p = xmlFirstElementChild(n);
5237 p = xmlNextElementSibling(p))
5240 build_function_decl_if_not_suppressed(rdr, p, decl,
5248 if (vtable_offset != -1)
5254 rdr.map_xml_node_to_decl(p, m);
5255 rdr.maybe_add_fn_to_exported_decls(f.get());
5260 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5262 rdr.map_xml_node_to_decl(n, decl);
5268 read_access(n, access);
5270 bool is_static =
false;
5271 read_static(n, is_static);
5273 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5274 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5276 for (xmlNodePtr p = xmlFirstElementChild(n);
5278 p = xmlNextElementSibling(p))
5280 if (shared_ptr<function_tdecl> f =
5281 build_function_tdecl(rdr, p,
5284 shared_ptr<member_function_template> m
5285 (
new member_function_template(f, access, is_static,
5286 is_ctor, is_const));
5288 decl->add_member_function_template(m);
5290 else if (shared_ptr<class_tdecl> c =
5291 build_class_tdecl(rdr, p,
5294 member_class_template_sptr m(
new member_class_template(c,
5298 decl->add_member_class_template(m);
5304 rdr.pop_scope_or_abort(decl);
5321static union_decl_sptr
5322build_union_decl(reader& rdr,
5323 const xmlNodePtr node,
5324 bool add_to_current_scope)
5326 union_decl_sptr nil;
5328 if (!xmlStrEqual(node->name, BAD_CAST(
"union-decl")))
5331 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5333 union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5342 size_t size_in_bits = 0, alignment_in_bits = 0;
5343 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5346 read_visibility(node, vis);
5348 bool is_artificial =
false;
5349 read_is_artificial(node, is_artificial);
5356 read_location(rdr, node, loc);
5362 union_decl_sptr decl;
5364 bool is_decl_only =
false;
5365 read_is_declaration_only(node, is_decl_only);
5367 bool is_anonymous =
false;
5368 read_is_anonymous(node, is_anonymous);
5371 union_decl_sptr previous_definition, previous_declaration;
5372 const vector<type_base_sptr> *types_ptr = 0;
5374 types_ptr = rdr.get_all_type_decls(
id);
5380 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5381 i != types_ptr->end();
5386 if (onion->get_is_declaration_only()
5387 && !onion->get_definition_of_declaration())
5388 previous_declaration = onion;
5389 else if (!onion->get_is_declaration_only()
5390 && !previous_definition)
5391 previous_definition = onion;
5392 if (previous_definition && previous_declaration)
5396 if (previous_declaration)
5397 ABG_ASSERT(previous_declaration->get_name() == name);
5399 if (previous_definition)
5400 ABG_ASSERT(previous_definition->get_name() == name);
5402 if (is_decl_only && previous_declaration)
5403 return previous_declaration;
5406 const environment& env = rdr.get_environment();
5408 if (!is_decl_only && previous_definition)
5414 decl = previous_definition;
5418 decl.reset(
new union_decl(env, name));
5420 decl.reset(
new union_decl(env, name,
5428 maybe_set_artificial_location(rdr, node, decl);
5429 decl->set_is_artificial(is_artificial);
5432 bool is_def_of_decl =
false;
5434 def_id = CHAR_STR(s);
5436 if (!def_id.empty())
5439 dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5440 if (d && d->get_is_declaration_only())
5442 is_def_of_decl =
true;
5443 decl->set_earlier_declaration(d);
5444 d->set_definition_of_declaration(decl);
5450 && !decl->get_is_declaration_only()
5451 && previous_declaration)
5457 decl->set_earlier_declaration(previous_declaration);
5458 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5459 i != types_ptr->end();
5464 if (d->get_is_declaration_only()
5465 && !d->get_definition_of_declaration())
5467 previous_declaration->set_definition_of_declaration(decl);
5468 is_def_of_decl =
true;
5473 if (is_decl_only && previous_definition)
5478 && !decl->get_definition_of_declaration());
5479 decl->set_definition_of_declaration(previous_definition);
5482 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5484 rdr.push_decl_to_scope(decl,
5485 add_to_current_scope
5486 ? rdr.get_scope_ptr_for_node(node)
5489 rdr.map_xml_node_to_decl(node, decl);
5490 rdr.key_type_decl(decl,
id);
5492 maybe_set_naming_typedef(rdr, node, decl);
5494 for (xmlNodePtr n = xmlFirstElementChild(node);
5496 n = xmlNextElementSibling(n))
5498 if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5501 read_access(n, access);
5503 rdr.map_xml_node_to_decl(n, decl);
5505 for (xmlNodePtr p = xmlFirstElementChild(n);
5507 p = xmlNextElementSibling(p))
5509 if (type_base_sptr t =
5510 build_type(rdr, p,
true))
5515 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5517 string id = CHAR_STR(i);
5519 rdr.key_type_decl(t,
id);
5520 rdr.map_xml_node_to_decl(p, td);
5524 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5526 rdr.map_xml_node_to_decl(n, decl);
5529 read_access(n, access);
5531 bool is_laid_out =
true;
5532 size_t offset_in_bits = 0;
5533 bool is_static =
false;
5534 read_static(n, is_static);
5536 for (xmlNodePtr p = xmlFirstElementChild(n);
5538 p = xmlNextElementSibling(p))
5541 build_var_decl(rdr, p,
false))
5543 if (decl->find_data_member(v))
5551 decl_base_sptr d = rdr.pop_decl();
5556 || !variable_is_suppressed(rdr, decl.get(), *v))
5558 decl->add_data_member(v, access,
5571 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5574 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5575 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5581 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5583 rdr.map_xml_node_to_decl(n, decl);
5586 read_access(n, access);
5588 bool is_static =
false;
5589 read_static(n, is_static);
5591 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5592 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5594 for (xmlNodePtr p = xmlFirstElementChild(n);
5596 p = xmlNextElementSibling(p))
5599 build_function_decl_if_not_suppressed(rdr, p, decl,
5610 rdr.maybe_add_fn_to_exported_decls(f.get());
5615 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5617 rdr.map_xml_node_to_decl(n, decl);
5620 read_access(n, access);
5622 bool is_static =
false;
5623 read_static(n, is_static);
5625 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5626 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5628 for (xmlNodePtr p = xmlFirstElementChild(n);
5630 p = xmlNextElementSibling(p))
5633 build_function_tdecl(rdr, p,
5636 member_function_template_sptr m
5637 (
new member_function_template(f, access, is_static,
5638 is_ctor, is_const));
5640 decl->add_member_function_template(m);
5643 build_class_tdecl(rdr, p,
5646 member_class_template_sptr m(
new member_class_template(c,
5650 decl->add_member_class_template(m);
5656 rdr.pop_scope_or_abort(decl);
5673static shared_ptr<function_tdecl>
5674build_function_tdecl(reader& rdr,
5675 const xmlNodePtr node,
5676 bool add_to_current_scope)
5678 shared_ptr<function_tdecl> nil, result;
5680 if (!xmlStrEqual(node->name, BAD_CAST(
"function-template-decl")))
5686 if (
id.empty() || rdr.get_fn_tmpl_decl(
id))
5690 read_location(rdr, node, loc);
5693 read_visibility(node, vis);
5696 read_binding(node, bind);
5698 const environment& env = rdr.get_environment();
5701 maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
5703 rdr.push_decl_to_scope(fn_tmpl_decl,
5704 add_to_current_scope
5705 ? rdr.get_scope_ptr_for_node(node)
5707 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5708 rdr.map_xml_node_to_decl(node, fn_tmpl_decl);
5710 unsigned parm_index = 0;
5711 for (xmlNodePtr n = xmlFirstElementChild(node);
5713 n = xmlNextElementSibling(n))
5716 build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
5718 fn_tmpl_decl->add_template_parameter(parm);
5725 fn_tmpl_decl->set_pattern(f);
5728 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5730 return fn_tmpl_decl;
5746build_class_tdecl(reader& rdr,
5747 const xmlNodePtr node,
5748 bool add_to_current_scope)
5752 if (!xmlStrEqual(node->name, BAD_CAST(
"class-template-decl")))
5758 if (
id.empty() || rdr.get_class_tmpl_decl(
id))
5762 read_location(rdr, node, loc);
5765 read_visibility(node, vis);
5767 const environment& env = rdr.get_environment();
5770 maybe_set_artificial_location(rdr, node, class_tmpl);
5772 if (add_to_current_scope)
5773 rdr.push_decl_to_scope(class_tmpl, node);
5774 rdr.key_class_tmpl_decl(class_tmpl,
id);
5775 rdr.map_xml_node_to_decl(node, class_tmpl);
5777 unsigned parm_index = 0;
5778 for (xmlNodePtr n = xmlFirstElementChild(node);
5780 n = xmlNextElementSibling(n))
5783 build_template_parameter(rdr, n, parm_index, class_tmpl))
5785 class_tmpl->add_template_parameter(parm);
5789 build_class_decl_if_not_suppressed(rdr, n,
5790 add_to_current_scope))
5793 rdr.maybe_canonicalize_type(c,
false);
5794 class_tmpl->set_pattern(c);
5798 rdr.key_class_tmpl_decl(class_tmpl,
id);
5819build_type_tparameter(reader& rdr,
5820 const xmlNodePtr node,
5826 if (!xmlStrEqual(node->name, BAD_CAST(
"template-type-parameter")))
5837 type_id = CHAR_STR(s);
5838 if (!type_id.empty()
5839 && !(result = dynamic_pointer_cast<type_tparameter>
5840 (rdr.build_or_get_type_decl(type_id,
true))))
5848 read_location(rdr, node,loc);
5850 result.reset(
new type_tparameter(index, tdecl, name, loc));
5851 maybe_set_artificial_location(rdr, node, result);
5854 rdr.push_decl_to_scope(
is_decl(result), node);
5856 rdr.push_and_key_type_decl(result, node,
true);
5858 rdr.maybe_canonicalize_type(result,
false);
5878build_type_composition(reader& rdr,
5879 const xmlNodePtr node,
5885 if (!xmlStrEqual(node->name, BAD_CAST(
"template-parameter-type-composition")))
5888 type_base_sptr composed_type;
5889 result.reset(
new type_composition(index, tdecl, composed_type));
5890 rdr.push_decl_to_scope(
is_decl(result), node);
5892 for (xmlNodePtr n = xmlFirstElementChild(node);
5894 n = xmlNextElementSibling(n))
5896 if ((composed_type =
5897 build_pointer_type_def(rdr, n,
5900 build_reference_type_def(rdr, n,
5903 build_array_type_def(rdr, n,
5906 build_qualified_type_decl(rdr, n,
5909 rdr.maybe_canonicalize_type(composed_type,
5911 result->set_composed_type(composed_type);
5935build_non_type_tparameter(reader& rdr,
5936 const xmlNodePtr node,
5942 if (!xmlStrEqual(node->name, BAD_CAST(
"template-non-type-parameter")))
5947 type_id = CHAR_STR(s);
5948 type_base_sptr type;
5950 || !(type = rdr.build_or_get_type_decl(type_id,
true)))
5958 read_location(rdr, node,loc);
5960 r.reset(
new non_type_tparameter(index, tdecl, name, type, loc));
5961 maybe_set_artificial_location(rdr, node, r);
5962 rdr.push_decl_to_scope(
is_decl(r), node);
5982build_template_tparameter(reader& rdr,
5983 const xmlNodePtr node,
5989 if (!xmlStrEqual(node->name, BAD_CAST(
"template-template-parameter")))
6000 type_id = CHAR_STR(s);
6002 if (!type_id.empty()
6003 && !(dynamic_pointer_cast<template_tparameter>
6004 (rdr.build_or_get_type_decl(type_id,
true))))
6012 read_location(rdr, node, loc);
6016 maybe_set_artificial_location(rdr, node, result);
6017 rdr.push_decl_to_scope(result, node);
6021 for (xmlNodePtr n = xmlFirstElementChild(node);
6023 n = xmlNextElementSibling(n))
6024 if (shared_ptr<template_parameter> p =
6025 build_template_parameter(rdr, n, parm_index, result))
6027 result->add_template_parameter(p);
6033 rdr.key_type_decl(result,
id);
6034 rdr.maybe_canonicalize_type(result,
false);
6056build_template_parameter(reader& rdr,
6057 const xmlNodePtr node,
6061 shared_ptr<template_parameter> r;
6062 ((r = build_type_tparameter(rdr, node, index, tdecl))
6063 || (r = build_non_type_tparameter(rdr, node, index, tdecl))
6064 || (r = build_template_tparameter(rdr, node, index, tdecl))
6065 || (r = build_type_composition(rdr, node, index, tdecl)));
6078static type_base_sptr
6079build_type(reader& rdr,
6080 const xmlNodePtr node,
6081 bool add_to_current_scope)
6085 ((t = build_type_decl(rdr, node, add_to_current_scope))
6086 || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
6087 || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
6088 || (t = build_reference_type_def(rdr, node , add_to_current_scope))
6089 || (t = build_ptr_to_mbr_type(rdr, node , add_to_current_scope))
6090 || (t = build_function_type(rdr, node, add_to_current_scope))
6091 || (t = build_array_type_def(rdr, node, add_to_current_scope))
6092 || (t = build_subrange_type(rdr, node, add_to_current_scope))
6093 || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
6094 add_to_current_scope))
6095 || (t = build_typedef_decl(rdr, node, add_to_current_scope))
6096 || (t = build_class_decl_if_not_suppressed(rdr, node,
6097 add_to_current_scope))
6098 || (t = build_union_decl_if_not_suppressed(rdr, node,
6099 add_to_current_scope)));
6101 if (rdr.tracking_non_reachable_types() && t)
6103 corpus_sptr abi = rdr.corpus();
6105 bool is_non_reachable_type =
false;
6106 read_is_non_reachable_type(node, is_non_reachable_type);
6107 if (!is_non_reachable_type)
6108 abi->record_type_as_reachable_from_public_interfaces(*t);
6111 MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
6114 rdr.maybe_canonicalize_type(t,
false );
6123static decl_base_sptr
6124handle_type_decl(reader& rdr,
6126 bool add_to_current_scope)
6128 type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
6129 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6130 if (decl && decl->get_scope())
6131 rdr.maybe_canonicalize_type(decl,
false);
6140static decl_base_sptr
6141handle_namespace_decl(reader& rdr,
6143 bool add_to_current_scope)
6146 add_to_current_scope);
6155static decl_base_sptr
6156handle_qualified_type_decl(reader& rdr,
6158 bool add_to_current_scope)
6160 qualified_type_def_sptr decl =
6161 build_qualified_type_decl(rdr, node,
6162 add_to_current_scope);
6163 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6164 if (decl && decl->get_scope())
6165 rdr.maybe_canonicalize_type(decl,
false);
6174static decl_base_sptr
6175handle_pointer_type_def(reader& rdr,
6177 bool add_to_current_scope)
6180 add_to_current_scope);
6181 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6182 if (decl && decl->get_scope())
6183 rdr.maybe_canonicalize_type(decl,
false);
6192static decl_base_sptr
6193handle_reference_type_def(reader& rdr,
6195 bool add_to_current_scope)
6198 add_to_current_scope);
6199 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6200 if (decl && decl->get_scope())
6201 rdr.maybe_canonicalize_type(decl,
false);
6210static type_base_sptr
6211handle_function_type(reader& rdr,
6213 bool add_to_current_scope)
6216 add_to_current_scope);
6217 MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
6218 rdr.maybe_canonicalize_type(type,
true);
6227static decl_base_sptr
6228handle_array_type_def(reader& rdr,
6230 bool add_to_current_scope)
6233 add_to_current_scope);
6234 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6235 rdr.maybe_canonicalize_type(decl,
false);
6242static decl_base_sptr
6243handle_enum_type_decl(reader& rdr,
6245 bool add_to_current_scope)
6248 build_enum_type_decl_if_not_suppressed(rdr, node,
6249 add_to_current_scope);
6250 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6251 if (decl && decl->get_scope())
6252 rdr.maybe_canonicalize_type(decl,
false);
6259static decl_base_sptr
6260handle_typedef_decl(reader& rdr,
6262 bool add_to_current_scope)
6265 add_to_current_scope);
6266 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6267 if (decl && decl->get_scope())
6268 rdr.maybe_canonicalize_type(decl,
false);
6280static decl_base_sptr
6281handle_var_decl(reader& rdr,
6283 bool add_to_current_scope)
6285 decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6286 add_to_current_scope);
6287 rdr.maybe_add_var_to_exported_decls(
is_var_decl(decl).get());
6297static decl_base_sptr
6298handle_function_decl(reader& rdr,
6300 bool add_to_current_scope)
6302 return build_function_decl_if_not_suppressed(rdr, node,
class_decl_sptr(),
6303 add_to_current_scope,
6313static decl_base_sptr
6314handle_class_decl(reader& rdr,
6316 bool add_to_current_scope)
6319 build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6320 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6321 if (decl && decl->get_scope())
6322 rdr.maybe_canonicalize_type(decl,
false);
6332static decl_base_sptr
6333handle_union_decl(reader& rdr,
6335 bool add_to_current_scope)
6337 union_decl_sptr decl =
6338 build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6339 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6340 if (decl && decl->get_scope())
6341 rdr.maybe_canonicalize_type(decl,
false);
6351static decl_base_sptr
6352handle_function_tdecl(reader& rdr,
6354 bool add_to_current_scope)
6357 add_to_current_scope);
6366static decl_base_sptr
6367handle_class_tdecl(reader& rdr,
6369 bool add_to_current_scope)
6372 add_to_current_scope);
6389 return read_translation_unit_from_input(read_rdr);
6414 corpus_sptr corp = result->corpus();
6415 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6416#ifdef WITH_DEBUG_SELF_COMPARISON
6417 if (env.self_comparison_debug_is_on())
6418 env.set_self_comparison_debug_input(result->corpus());
6420 result->set_path(path);
6437 corpus_sptr corp = result->corpus();
6438 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6439#ifdef WITH_DEBUG_SELF_COMPARISON
6440 if (env.self_comparison_debug_is_on())
6441 env.set_self_comparison_debug_input(result->corpus());
6464 return rdr->read_corpus(sts);
6486 corpus_sptr corp = rdr->read_corpus(sts);
6492#ifdef WITH_DEBUG_SELF_COMPARISON
6511load_canonical_type_ids(fe_iface& iface,
const string &file_path)
6513 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
6515 xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
6519 xmlNodePtr node = xmlDocGetRootElement(doc);
6542 if (xmlStrcmp(node->name, (xmlChar*)
"abixml-types-check"))
6545 for (node = xmlFirstElementChild(node);
6547 node = xmlNextElementSibling(node))
6549 if (xmlStrcmp(node->name, (xmlChar*)
"type"))
6552 string id, canonical_address;
6553 xmlNodePtr data = xmlFirstElementChild(node);
6554 if (data && !xmlStrcmp(data->name, (xmlChar*)
"id")
6555 && data->children && xmlNodeIsText(data->children))
6556 id = (
char*) XML_GET_CONTENT(data->children);
6558 data = xmlNextElementSibling(data);
6559 if (data && !xmlStrcmp(data->name, (xmlChar*)
"c")
6560 && data->children && xmlNodeIsText(data->children))
6562 canonical_address = (
char*) XML_GET_CONTENT(data->children);
6563 std::stringstream s;
6564 s << canonical_address;
6572 rdr.get_environment().get_type_id_canonical_type_map()[id] = v;
This file contains the declarations for the fe_iface a.k.a "Front End Interface".
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
#define XML_READER_GET_NODE_NAME(reader)
Get the name of the current element node the reader is pointing to. Note that this macro returns an i...
#define XML_READER_GET_ATTRIBUTE(reader, name)
Get the value of attribute 'name' on the current node of 'reader' which is an instance of shared_ptr<...
#define XML_NODE_GET_ATTRIBUTE(node, name)
Get the value of attribute 'name' ont the instance of xmlNodePtr denoted by 'node'.
#define XML_READER_GET_NODE_TYPE(reader)
Get the type of the current node of the shared_ptr<xmlTextReader> passed in argument.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
The base class of all libabigail front-ends: The Front End Interface.
status
The status of the fe_iface::read_corpus call.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
vector< base_spec_sptr > base_specs
Convenience typedef.
vector< method_decl_sptr > member_functions
Convenience typedef.
vector< var_decl_sptr > data_members
Convenience typedef.
vector< type_base_sptr > member_types
Convenience typedef.
Abstracts the building of the set of exported variables and functions.
Abstraction of a group of corpora.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
void set_soname(const string &)
Setter for the soname property of the corpus.
exported_decls_builder_sptr get_exported_decls_builder() const
Getter for the object that is responsible for determining what decls ought to be in the set of export...
string & get_path() const
Get the file path associated to the corpus file.
void set_origin(origin)
Setter for the origin of the corpus.
void set_path(const string &)
Set the file path associated to the corpus file.
virtual bool recording_types_reachable_from_public_interface_supported()
Test if the recording of reachable types (and thus, indirectly, the recording of non-reachable types)...
void set_needed(const vector< string > &)
Setter of the needed property of the corpus.
void set_architecture_name(const string &)
Setter for the architecture name of the corpus.
void set_symtab(symtab_reader::symtab_sptr)
Setter for the symtab object.
The base type of all declarations.
visibility
ELF visibility.
binding
The binding of a symbol.
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
type
The type of a symbol.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
visibility
The visibility of the symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
Abstraction for a function declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
const type_base_sptr get_return_type() const
const std::vector< parameter_sptr > & get_parameters() const
Abstraction of a function type.
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
This abstracts the global scope of a given translation unit.
The source location of a token.
CV
Bit field values representing the cv qualifiers of the underlying type.
A declaration that introduces a scope.
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
void set_address_size(char)
Setter of the address size in this translation unit.
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
void set_language(language l)
Setter of the language of the source code of the translation unit.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
The base class of both types and declarations.
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Abstraction of a function suppression specification.
Base type of a direct suppression specifications types.
bool has_soname_related_property() const
Test if the current suppression has a property related to SONAMEs.
bool has_file_name_related_property() const
Test if the current suppression has a property related to file name.
Abstraction of a type suppression specification.
static symtab_ptr load(Elf *elf_handle, const ir::environment &env, symbol_predicate is_suppressed=NULL)
Construct a symtab object and instantiate it from an ELF handle. Also pass in the ir::environment we ...
translation_unit_sptr read_translation_unit_from_buffer(const string &buffer, environment &env)
Parse an ABI instrumentation file (in XML format) from an in-memory buffer.
void add_reader_suppressions(reader &rdr, const suppr::suppressions_type &supprs)
Add suppressions specifications to the set of suppressions to be used during the construction of the ...
translation_unit_sptr read_translation_unit_from_istream(istream *in, environment &env)
De-serialize a translation unit from an ABI Instrumentation xml file coming from an input stream.
corpus_sptr read_corpus_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus from an input XML document which root node is 'abi-corpus'.
corpus_group_sptr read_corpus_group_from_input(fe_iface &iface)
Parse the input XML document containing an ABI corpus group, represented by an 'abi-corpus-group' ele...
corpus_sptr read_corpus_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus from an XML document file which root node is 'abi-corpus'.
translation_unit_sptr read_translation_unit_from_file(const string &input_file, environment &env)
Parse an ABI instrumentation file (in XML format) at a given path.
corpus_group_sptr read_corpus_group_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus group from an input XML document which root node is 'abi-corpus-group'.
fe_iface_sptr create_reader(const string &path, environment &env)
Create an xml_reader::reader to read a native XML ABI file.
void consider_types_not_reachable_from_public_interfaces(fe_iface &iface, bool flag)
Configure the reader so that types not reachable from public interface are taken into account when th...
corpus_group_sptr read_corpus_group_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus group from an XML document file which root node is 'abi-corpus-group'.
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.
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.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
shared_ptr< non_type_tparameter > non_type_tparameter_sptr
Convenience typedef for shared pointer to non_type_template_parameter.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
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.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
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.
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
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...
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
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< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< string_elf_symbols_map_type > string_elf_symbols_map_sptr
Convenience typedef for a shared pointer to string_elf_symbols_map_type.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< type_composition > type_composition_sptr
Convenience typedef for shared pointer to type_composition.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
translation_unit * get_translation_unit(const decl_base &decl)
Return the translation unit a declaration belongs to.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
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.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
shared_ptr< T > build_sptr(T *p)
This is to be specialized for the diverse C types that needs wrapping in shared_ptr.
shared_ptr< file_suppression > file_suppression_sptr
A convenience typedef for a shared_ptr to file_suppression.
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
bool suppression_can_match(const fe_iface &fe, const suppression_base &s)
Test if a given suppression specification can match an ABI artifact coming from the corpus being anal...
file_suppression_sptr is_file_suppression(const suppression_sptr s)
Test if a given suppression specification is a file suppression specification.
bool is_elf_symbol_suppressed(const fe_iface &fe, const elf_symbol_sptr &symbol)
Test if an ELF symbol is suppressed by at least one of the suppression specifications associated with...
bool suppression_matches_soname_or_filename(const string &soname, const string &filename, const suppression_base &suppr)
Test if a given SONAME or file name is matched by a given suppression specification.
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_private, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool suppression_matches_type_name_or_location(const type_suppression &s, const string &type_name, const location &type_location)
Test if a type suppression matches a type name and location.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
reader_sptr new_reader_from_file(const std::string &path)
Instantiate an xmlTextReader that parses the content of an on-disk file, wrap it into a smart pointer...
bool xml_char_sptr_to_string(xml_char_sptr ssptr, std::string &s)
Convert a shared pointer to xmlChar into an std::string.
reader_sptr new_reader_from_buffer(const std::string &buffer)
Instanciate an xmlTextReader that parses the content of an in-memory buffer, wrap it into a smart poi...
shared_ptr< xmlChar > xml_char_sptr
A convenience typedef for a shared pointer of xmlChar.
void unescape_xml_string(const std::string &str, std::string &escaped)
Read a string, detect the 5 predefined XML entities it may contain and un-escape them,...
reader_sptr new_reader_from_istream(std::istream *in)
Instanciate an xmlTextReader that parses a content coming from an input stream.
shared_ptr< xmlTextReader > reader_sptr
A convenience typedef for a shared pointer of xmlTextReader.
Toplevel namespace for libabigail.