15 #include <libxml/xmlreader.h>
16 #include <libxml/xmlstring.h>
23 #include <unordered_map>
27 #include "abg-internal.h"
31 ABG_BEGIN_EXPORT_DECLARATIONS
39 ABG_END_EXPORT_DECLARATIONS
52 using std::shared_ptr;
53 using std::unordered_map;
54 using std::dynamic_pointer_cast;
60 static bool read_is_declaration_only(xmlNodePtr,
bool&);
61 static bool read_is_artificial(xmlNodePtr,
bool&);
62 static bool read_tracking_non_reachable_types(xmlNodePtr,
bool&);
63 static bool read_is_non_reachable_type(xmlNodePtr,
bool&);
64 static bool read_naming_typedef_id_string(xmlNodePtr,
string&);
65 #ifdef WITH_DEBUG_SELF_COMPARISON
66 static bool read_type_id_string(xmlNodePtr,
string&);
67 static bool maybe_map_type_with_type_id(
const type_base_sptr&,
69 static 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)
77 static void maybe_set_naming_typedef(reader& rdr,
79 const decl_base_sptr &);
82 static int advance_cursor(reader& rdr);
88 walk_xml_node_to_map_type_ids(reader& rdr, xmlNodePtr node);
91 read_elf_needed_from_input(reader& rdr, vector<string>& needed);
94 read_symbol_db_from_input(reader& rdr,
99 read_translation_unit_from_input(
fe_iface& rdr);
112 typedef unordered_map<string,
113 vector<type_base_sptr> >::const_iterator
116 typedef unordered_map<string,
117 vector<type_base_sptr> >::iterator
120 typedef unordered_map<string,
121 shared_ptr<function_tdecl> >::const_iterator
122 const_fn_tmpl_map_it;
124 typedef unordered_map<string,
125 shared_ptr<class_tdecl> >::const_iterator
126 const_class_tmpl_map_it;
128 typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
130 typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
132 friend vector<type_base_sptr>* get_types_from_type_id(reader&,
135 friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
136 get_artifact_used_by_relation_map(reader& rdr);
139 unordered_map<string, vector<type_base_sptr> > m_types_map;
140 unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
141 unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
142 vector<type_base_sptr> m_types_to_canonicalize;
143 string_xml_node_map m_id_xml_node_map;
144 xml_node_decl_base_sptr_map m_xml_node_decl_map;
146 xmlNodePtr m_corp_node;
147 deque<shared_ptr<decl_base> > m_decls_stack;
148 bool m_tracking_non_reachable_types;
149 bool m_drop_undefined_syms;
150 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
152 vector<type_or_decl_base*>> m_artifact_used_by_map;
163 m_tracking_non_reachable_types(),
164 m_drop_undefined_syms()
173 {
return options().do_log;}
181 tracking_non_reachable_types()
const
182 {
return m_tracking_non_reachable_types;}
190 tracking_non_reachable_types(
bool f)
191 {m_tracking_non_reachable_types = f;}
199 drop_undefined_syms()
const
200 {
return m_drop_undefined_syms;}
207 drop_undefined_syms(
bool f)
208 {m_drop_undefined_syms = f;}
215 {
return corpus_path();}
221 set_path(
const string& s)
231 {
return options().env;}
237 get_environment()
const
238 {
return const_cast<reader*
>(
this)->get_environment();}
241 get_libxml_reader()
const
250 get_corpus_node()
const
251 {
return m_corp_node;}
259 set_corpus_node(xmlNodePtr node)
260 {m_corp_node = node;}
262 const string_xml_node_map&
263 get_id_xml_node_map()
const
264 {
return m_id_xml_node_map;}
267 get_id_xml_node_map()
268 {
return m_id_xml_node_map;}
271 clear_id_xml_node_map()
272 {get_id_xml_node_map().clear();}
274 const xml_node_decl_base_sptr_map&
275 get_xml_node_decl_map()
const
276 {
return m_xml_node_decl_map;}
278 xml_node_decl_base_sptr_map&
279 get_xml_node_decl_map()
280 {
return m_xml_node_decl_map;}
283 map_xml_node_to_decl(xmlNodePtr node,
287 get_xml_node_decl_map()[node]= decl;
291 get_decl_for_xml_node(xmlNodePtr node)
const
293 xml_node_decl_base_sptr_map::const_iterator i =
294 get_xml_node_decl_map().find(node);
296 if (i != get_xml_node_decl_map().end())
299 return decl_base_sptr();
303 clear_xml_node_decl_map()
304 {get_xml_node_decl_map().clear();}
307 map_id_and_node (
const string&
id,
313 string_xml_node_map::iterator i = get_id_xml_node_map().find(
id);
314 if (i != get_id_xml_node_map().end())
316 bool is_declaration =
false;
317 read_is_declaration_only(node, is_declaration);
322 get_id_xml_node_map()[id] = node;
326 get_xml_node_from_id(
const string&
id)
const
328 string_xml_node_map::const_iterator i = get_id_xml_node_map().find(
id);
329 if (i != get_id_xml_node_map().end())
335 get_scope_for_node(xmlNodePtr node,
341 build_or_get_type_decl(
const string&
id,
356 get_type_decl(
const string&
id)
const
358 const_types_map_it i = m_types_map.find(
id);
359 if (i == m_types_map.end())
360 return type_base_sptr();
361 type_base_sptr result = i->second[0];
377 const vector<type_base_sptr>*
378 get_all_type_decls(
const string&
id)
const
380 const_types_map_it i = m_types_map.find(
id);
381 if (i == m_types_map.end())
398 shared_ptr<function_tdecl>
399 get_fn_tmpl_decl(
const string&
id)
const
401 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
402 if (i == m_fn_tmpl_map.end())
403 return shared_ptr<function_tdecl>();
417 shared_ptr<class_tdecl>
418 get_class_tmpl_decl(
const string&
id)
const
420 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
421 if (i == m_class_tmpl_map.end())
422 return shared_ptr<class_tdecl>();
428 get_cur_scope()
const
430 shared_ptr<decl_base> cur_decl = get_cur_decl();
432 if (
dynamic_cast<scope_decl*
>(cur_decl.get()))
434 return dynamic_pointer_cast<scope_decl>(cur_decl).get();
438 return cur_decl->get_scope();
447 if (m_decls_stack.empty())
448 return shared_ptr<decl_base>(
static_cast<decl_base*
>(0));
449 return m_decls_stack.back();
456 for (deque<shared_ptr<decl_base> >::reverse_iterator i =
457 m_decls_stack.rbegin();
458 i != m_decls_stack.rend();
460 if (decl_base_sptr d = *i)
465 return global->get_translation_unit();
476 type_is_from_translation_unit(type_base_sptr type)
488 push_decl(decl_base_sptr d)
490 m_decls_stack.push_back(d);
496 if (m_decls_stack.empty())
497 return decl_base_sptr();
499 shared_ptr<decl_base> t = get_cur_decl();
500 m_decls_stack.pop_back();
527 return dynamic_pointer_cast<scope_decl>(d) == scope;
540 {m_decls_stack.clear();}
544 {m_types_map.clear();}
549 clear_types_to_canonicalize()
550 {m_types_to_canonicalize.clear();}
566 types_equal(type_base_sptr t1, type_base_sptr t2)
568 if (t1.get() == t2.get())
587 key_type_decl(
const type_base_sptr& type,
const string&
id)
592 m_types_map[id].push_back(type);
607 key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
612 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
613 if (i != m_fn_tmpl_map.end())
616 m_fn_tmpl_map[id] = fn_tmpl_decl;
630 key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
635 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
636 if (i != m_class_tmpl_map.end())
639 m_class_tmpl_map[id] = class_tmpl_decl;
643 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
656 if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
658 vector<type_or_decl_base*> v;
659 m_artifact_used_by_map[used] = v;
661 m_artifact_used_by_map[used].push_back(user);
675 {record_artifact_as_used_by(used.get(), user.get());}
687 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
691 type_base_sptr t = pit->get_type();
692 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
701 {record_artifacts_as_used_in_fn_decl(fn.get());}
707 record_artifacts_as_used_in_fn_type(
const function_type *fn_type)
713 record_artifact_as_used_by(t.get(),
const_cast<function_type*
>(fn_type));
717 type_base_sptr t = pit->get_type();
718 record_artifact_as_used_by(t.get(),
728 {record_artifacts_as_used_in_fn_type(fn_type.get());}
737 push_decl_to_current_scope(decl_base_sptr decl,
738 bool add_to_current_scope)
742 if (add_to_current_scope)
744 if (!decl->get_translation_unit())
761 push_and_key_type_decl(shared_ptr<type_base> t,
const string&
id,
762 bool add_to_current_scope)
764 shared_ptr<decl_base> decl = dynamic_pointer_cast<decl_base>(t);
767 push_decl_to_current_scope(decl, add_to_current_scope);
768 if (!t->get_translation_unit())
771 key_type_decl(t,
id);
781 get_exported_decls_builder()
795 corpus_is_suppressed_by_soname_or_filename(
const string& soname,
796 const string& filename)
802 for (suppressions_type::const_iterator s = suppressions().begin();
803 s != suppressions().end();
816 clear_per_translation_unit_data()
823 clear_per_corpus_data()
826 clear_types_to_canonicalize();
827 clear_xml_node_decl_map();
828 clear_id_xml_node_map();
832 #ifdef WITH_DEBUG_SELF_COMPARISON
852 maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
854 if (!get_environment().self_comparison_debug_is_on()
855 || get_environment().get_type_id_canonical_type_map().empty())
867 get_environment().get_type_id_from_pointer(
reinterpret_cast<uintptr_t
>(t.get()));
869 if (!type_id.empty())
874 auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
875 if (j == get_environment().get_type_id_canonical_type_map().end())
877 if (t->get_naked_canonical_type())
878 std::cerr <<
"error: no type with type-id: '"
880 <<
"' could be read back from the typeid file\n";
883 !=
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get()))
888 std::cerr <<
"error: canonical type for type '"
889 << t->get_pretty_representation(
true,
891 <<
"' of type-id '" << type_id
892 <<
"' changed from '" << std::hex
893 << j->second <<
"' to '" << std::hex
894 <<
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get())
908 maybe_canonicalize_type(type_base_sptr t,
909 bool force_delay =
false)
914 if (t->get_canonical_type())
949 #ifdef WITH_DEBUG_SELF_COMPARISON
950 maybe_check_abixml_canonical_type_stability(t);
960 schedule_type_for_late_canonicalizing(t);
969 schedule_type_for_late_canonicalizing(type_base_sptr t)
970 {m_types_to_canonicalize.push_back(t);}
976 perform_late_type_canonicalizing()
978 for (vector<type_base_sptr>::iterator i = m_types_to_canonicalize.begin();
979 i != m_types_to_canonicalize.end();
983 #ifdef WITH_DEBUG_SELF_COMPARISON
984 maybe_check_abixml_canonical_type_stability(*i);
1002 const string& fn_name)
const
1006 return suppression_matches_function_name(*s, fn_name);
1019 corpus_sptr corp =
corpus();
1021 if (!s.priv_->matches_soname(corp->get_soname()))
1028 if (!s.priv_->matches_binary_name(corp->get_path()))
1051 const string& fn_name)
const
1053 if (!s.get_drops_artifact_from_ir()
1057 return suppr::suppression_matches_function_name(s, fn_name);
1073 const string& type_name,
1074 const location& type_location)
const
1083 virtual ir::corpus_sptr
1094 bool call_reader_next =
false;
1096 xmlNodePtr node = get_corpus_node();
1103 status = advance_cursor (*
this);
1106 BAD_CAST(
"abi-corpus")))
1109 #ifdef WITH_DEBUG_SELF_COMPARISON
1110 if (get_environment().self_comparison_debug_is_on())
1111 get_environment().set_self_comparison_debug_input(
corpus());
1115 clear_per_corpus_data();
1121 handle_version_attribute(xml_reader, corp);
1128 path =
reinterpret_cast<char*
>(path_str.get());
1135 if (architecture_str)
1137 (
reinterpret_cast<char*
>(architecture_str.get()));
1145 soname =
reinterpret_cast<char*
>(soname_str.get());
1157 if ((!soname.empty() || !path.empty())
1158 && corpus_is_suppressed_by_soname_or_filename(soname, path))
1161 node = xmlTextReaderExpand(xml_reader.get());
1165 call_reader_next =
true;
1169 #ifdef WITH_DEBUG_SELF_COMPARISON
1170 if (get_environment().self_comparison_debug_is_on())
1171 get_environment().set_self_comparison_debug_input(
corpus());
1175 clear_per_corpus_data();
1182 corp.
set_path(
reinterpret_cast<char*
>(path_str.get()));
1186 if (architecture_str)
1188 (
reinterpret_cast<char*
>(architecture_str.get()));
1193 corp.
set_soname(
reinterpret_cast<char*
>(soname_str.get()));
1201 xmlNodePtr n = xmlFirstElementChild(node);
1207 walk_xml_node_to_map_type_ids(*
this, node);
1210 vector<string> needed;
1211 read_elf_needed_from_input(*
this, needed);
1212 if (!needed.empty())
1218 read_symbol_db_from_input(*
this, fn_sym_db, var_sym_db);
1224 get_environment().canonicalization_is_done(
false);
1227 while (read_translation_unit_from_input(*
this))
1230 if (tracking_non_reachable_types())
1232 bool is_tracking_non_reachable_types =
false;
1233 read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1237 == is_tracking_non_reachable_types);
1244 std::cerr <<
"perform late type canonicalization ...\n";
1248 perform_late_type_canonicalizing();
1253 std::cerr <<
"late type canonicalization DONE@"
1255 <<
":" << t <<
"\n";
1258 get_environment().canonicalization_is_done(
true);
1260 if (call_reader_next)
1264 xmlTextReaderNext(xml_reader.get());
1272 node = get_corpus_node();
1273 node = xmlNextElementSibling(node);
1276 node = get_corpus_node();
1278 node = xmlNextElementSibling(node->parent);
1280 set_corpus_node(node);
1288 typedef shared_ptr<reader> reader_sptr;
1290 static int advance_cursor(reader&);
1294 static bool read_symbol_db_from_input(reader&,
1297 static bool read_location(
const reader&, xmlNodePtr,
location&);
1298 static bool read_artificial_location(
const reader&,
1300 static bool maybe_set_artificial_location(
const reader&,
1306 static bool read_size_and_alignment(xmlNodePtr,
size_t&,
size_t&);
1307 static bool read_static(xmlNodePtr,
bool&);
1308 static bool read_offset_in_bits(xmlNodePtr,
size_t&);
1309 static bool read_cdtor_const(xmlNodePtr,
bool&,
bool&,
bool&);
1310 static bool read_is_virtual(xmlNodePtr,
bool&);
1311 static bool read_is_struct(xmlNodePtr,
bool&);
1312 static bool read_is_anonymous(xmlNodePtr,
bool&);
1315 static bool read_elf_symbol_visibility(xmlNodePtr,
1319 build_namespace_decl(reader&,
const xmlNodePtr,
bool);
1329 build_elf_symbol(reader&,
const xmlNodePtr,
bool);
1332 build_elf_symbol_from_reference(reader&,
const xmlNodePtr);
1335 build_elf_symbol_db(reader&,
const xmlNodePtr,
bool);
1338 build_function_parameter (reader&,
const xmlNodePtr);
1341 build_function_decl(reader&,
const xmlNodePtr,
1342 class_or_union_sptr,
bool);
1345 build_function_decl_if_not_suppressed(reader&,
const xmlNodePtr,
1346 class_or_union_sptr,
bool);
1349 function_is_suppressed(
const reader& rdr,
1353 build_var_decl_if_not_suppressed(reader&,
const xmlNodePtr,
bool);
1356 build_var_decl(reader&,
const xmlNodePtr,
bool);
1359 variable_is_suppressed(
const reader& rdr,
1362 static shared_ptr<type_decl>
1363 build_type_decl(reader&,
const xmlNodePtr,
bool);
1365 static qualified_type_def_sptr
1366 build_qualified_type_decl(reader&,
const xmlNodePtr,
bool);
1368 static shared_ptr<pointer_type_def>
1369 build_pointer_type_def(reader&,
const xmlNodePtr,
bool);
1371 static shared_ptr<reference_type_def>
1372 build_reference_type_def(reader&,
const xmlNodePtr,
bool);
1374 static shared_ptr<function_type>
1375 build_function_type(reader&,
const xmlNodePtr,
bool);
1378 build_subrange_type(reader&,
const xmlNodePtr,
bool);
1381 build_array_type_def(reader&,
const xmlNodePtr,
bool);
1384 build_enum_type_decl(reader&,
const xmlNodePtr,
bool);
1386 static shared_ptr<typedef_decl>
1387 build_typedef_decl(reader&,
const xmlNodePtr,
bool);
1390 build_class_decl(reader&,
const xmlNodePtr,
bool);
1392 static union_decl_sptr
1393 build_union_decl(reader&,
const xmlNodePtr,
bool);
1395 static shared_ptr<function_tdecl>
1396 build_function_tdecl(reader&,
const xmlNodePtr,
bool);
1398 static shared_ptr<class_tdecl>
1399 build_class_tdecl(reader&,
const xmlNodePtr,
bool);
1402 build_type_tparameter(reader&,
const xmlNodePtr,
1406 build_type_composition(reader&,
const xmlNodePtr,
1410 build_non_type_tparameter(reader&,
const xmlNodePtr,
1414 build_template_tparameter(reader&,
const xmlNodePtr,
1418 build_template_parameter(reader&,
const xmlNodePtr,
1425 static shared_ptr<type_base>
1426 build_type(reader&,
const xmlNodePtr,
bool);
1430 static decl_base_sptr handle_type_decl(reader&, xmlNodePtr,
bool);
1431 static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr,
bool);
1432 static decl_base_sptr handle_qualified_type_decl(reader&,
1434 static decl_base_sptr handle_pointer_type_def(reader&,
1436 static decl_base_sptr handle_reference_type_def(reader&,
1438 static type_base_sptr handle_function_type(reader&,
1440 static decl_base_sptr handle_array_type_def(reader&,
1442 static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr,
bool);
1443 static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr,
bool);
1444 static decl_base_sptr handle_var_decl(reader&, xmlNodePtr,
bool);
1445 static decl_base_sptr handle_function_decl(reader&, xmlNodePtr,
bool);
1446 static decl_base_sptr handle_class_decl(reader&, xmlNodePtr,
bool);
1447 static decl_base_sptr handle_union_decl(reader&, xmlNodePtr,
bool);
1448 static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr,
bool);
1449 static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr,
bool);
1451 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1452 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1453 rdr.record_artifact_as_used_by(used,user)
1454 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1455 rdr.record_artifacts_as_used_in_fn_decl(fn)
1456 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1457 rdr.record_artifacts_as_used_in_fn_type(fn_type)
1459 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1460 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1461 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1478 reader::get_scope_for_node(xmlNodePtr node,
1485 xmlNodePtr parent = node->parent;
1488 && (xmlStrEqual(parent->name, BAD_CAST(
"data-member"))
1489 || xmlStrEqual(parent->name, BAD_CAST(
"member-type"))
1490 || xmlStrEqual(parent->name, BAD_CAST(
"member-function"))
1491 || xmlStrEqual(parent->name, BAD_CAST(
"member-template"))
1492 || xmlStrEqual(parent->name, BAD_CAST(
"array-type-def"))))
1494 read_access(parent, access);
1495 parent = parent->parent;
1498 xml_node_decl_base_sptr_map::const_iterator i =
1499 get_xml_node_decl_map().find(parent);
1500 if (i == get_xml_node_decl_map().end())
1502 if (xmlStrEqual(parent->name, BAD_CAST(
"abi-instr")))
1505 get_or_read_and_add_translation_unit(*
this, parent);
1506 return tu->get_global_scope();
1511 push_decl(parent_scope);
1512 scope = dynamic_pointer_cast<scope_decl>
1513 (handle_element_node(*
this, parent,
true));
1515 pop_scope_or_abort(parent_scope);
1518 scope = dynamic_pointer_cast<scope_decl>(i->second);
1533 reader::build_or_get_type_decl(
const string&
id,
1536 type_base_sptr t = get_type_decl(
id);
1540 xmlNodePtr n = get_xml_node_from_id(
id);
1547 scope = get_scope_for_node(n, access);
1555 if ((t = get_type_decl(
id)))
1573 pop_scope_or_abort(scope);
1587 advance_cursor(reader& rdr)
1590 return xmlTextReaderRead(reader.get());
1602 walk_xml_node_to_map_type_ids(reader& rdr,
1605 xmlNodePtr n = node;
1607 if (!n || n->type != XML_ELEMENT_NODE)
1612 string id = CHAR_STR(s);
1613 rdr.map_id_and_node(
id, n);
1616 for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1617 walk_xml_node_to_map_type_ids(rdr, n);
1623 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1625 if (!rdr.corpus()->is_empty())
1632 char address_size = atoi(
reinterpret_cast<char*
>(addrsize_str.get()));
1638 tu.
set_path(
reinterpret_cast<char*
>(path_str.get()));
1642 if (comp_dir_path_str)
1644 (comp_dir_path_str.get()));
1649 (
reinterpret_cast<char*
>(language_str.get())));
1657 if (rdr.get_id_xml_node_map().empty()
1659 walk_xml_node_to_map_type_ids(rdr, node);
1661 for (xmlNodePtr n = xmlFirstElementChild(node);
1663 n = xmlNextElementSibling(n))
1664 handle_element_node(rdr, n,
true);
1672 rdr.clear_per_translation_unit_data();
1691 get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1693 corpus_sptr corp = rdr.corpus();
1701 tu_path =
reinterpret_cast<char*
>(path_str.get());
1704 if (corp && !corp->is_empty())
1705 tu = corp->find_translation_unit(tu_path);
1712 if (corp && !corp->is_empty())
1715 if (read_translation_unit(rdr, *tu, node))
1730 read_translation_unit_from_input(
fe_iface& iface)
1734 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1736 xmlNodePtr node = rdr.get_corpus_node();
1747 status = advance_cursor (rdr);
1750 BAD_CAST(
"abi-instr")))
1753 node = xmlTextReaderExpand(reader.get());
1760 for (xmlNodePtr n = rdr.get_corpus_node();
1762 n = xmlNextElementSibling(n))
1764 if (!xmlStrEqual(n->name, BAD_CAST(
"abi-instr")))
1774 tu = get_or_read_and_add_translation_unit(rdr, node);
1776 if (rdr.get_corpus_node())
1782 node = xmlNextElementSibling(node);
1783 rdr.set_corpus_node(node);
1807 read_symbol_db_from_input(reader& rdr,
1815 if (!rdr.get_corpus_node())
1821 status = advance_cursor (rdr);
1826 bool has_fn_syms =
false, has_var_syms =
false;
1828 BAD_CAST(
"elf-function-symbols")))
1831 BAD_CAST(
"elf-variable-symbols")))
1832 has_var_syms =
true;
1836 xmlNodePtr node = xmlTextReaderExpand(reader.get());
1841 fn_symdb = build_elf_symbol_db(rdr, node,
true);
1842 else if (has_var_syms)
1843 var_symdb = build_elf_symbol_db(rdr, node,
false);
1845 xmlTextReaderNext(reader.get());
1848 for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
1850 bool has_fn_syms =
false, has_var_syms =
false;
1851 if (xmlStrEqual(n->name, BAD_CAST(
"elf-function-symbols")))
1853 else if (xmlStrEqual(n->name, BAD_CAST(
"elf-variable-symbols")))
1854 has_var_syms =
true;
1857 rdr.set_corpus_node(n);
1862 fn_symdb = build_elf_symbol_db(rdr, n,
true);
1863 else if (has_var_syms)
1864 var_symdb = build_elf_symbol_db(rdr, n,
false);
1883 build_needed(xmlNode* node, vector<string>& needed)
1885 if (!node || !xmlStrEqual(node->name,BAD_CAST(
"elf-needed")))
1888 for (xmlNodePtr n = xmlFirstElementChild(node);
1890 n = xmlNextElementSibling(n))
1892 if (!xmlStrEqual(n->name, BAD_CAST(
"dependency")))
1900 needed.push_back(name);
1916 read_elf_needed_from_input(reader& rdr,
1917 vector<string>& needed)
1923 xmlNodePtr node = 0;
1925 if (rdr.get_corpus_node() == 0)
1930 status = advance_cursor (rdr);
1936 BAD_CAST(
"elf-needed")))
1939 node = xmlTextReaderExpand(reader.get());
1945 for (xmlNodePtr n = rdr.get_corpus_node();
1947 n = xmlNextElementSibling(n))
1949 if (!xmlStrEqual(n->name, BAD_CAST(
"elf-needed")))
1956 bool result =
false;
1959 result = build_needed(node, needed);
1960 node = xmlNextElementSibling(node);
1961 rdr.set_corpus_node(node);
1996 for (suppr::suppressions_type::const_iterator i = supprs.begin();
1999 if ((*i)->get_drops_artifact_from_ir())
2000 rdr.suppressions().push_back(*i);
2015 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2016 rdr.tracking_non_reachable_types(flag);
2019 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2028 vector<type_base_sptr>*
2029 get_types_from_type_id(
fe_iface& iface,
const string& type_id)
2031 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2032 auto it = rdr.m_types_map.find(type_id);
2033 if (it == rdr.m_types_map.end())
2044 unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2045 get_artifact_used_by_relation_map(fe_iface& iface)
2047 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2048 return &rdr.m_artifact_used_by_map;
2068 string version_string;
2073 if (version_string.empty())
2080 corp.set_format_major_version_number(v[0]);
2081 corp.set_format_minor_version_number(v[1]);
2094 corpus_group_sptr nil;
2096 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2105 status = advance_cursor (rdr);
2108 BAD_CAST(
"abi-corpus-group")))
2111 if (!rdr.corpus_group())
2113 corpus_group_sptr g(
new corpus_group(rdr.get_environment(),
2115 g->set_origin(corpus::NATIVE_XML_ORIGIN);
2116 rdr.corpus_group(g);
2119 corpus_group_sptr group = rdr.corpus_group();
2121 handle_version_attribute(reader, *group);
2125 group->set_path(
reinterpret_cast<char*
>(path_str.get()));
2127 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2131 node = xmlFirstElementChild(node);
2132 rdr.set_corpus_node(node);
2136 while ((corp = rdr.read_corpus(sts)))
2137 rdr.corpus_group()->add_corpus(corp);
2139 xmlTextReaderNext(reader.get());
2141 return rdr.corpus_group();
2203 rdr.perform_late_type_canonicalizing();
2225 rdr.perform_late_type_canonicalizing();
2240 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2242 rdr.options().env.canonicalization_is_done(
false);
2243 rdr.perform_late_type_canonicalizing();
2244 rdr.options().env.canonicalization_is_done(
true);
2257 handle_element_node(reader& rdr, xmlNodePtr node,
2258 bool add_to_current_scope)
2264 ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2265 ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2266 ||(decl = handle_qualified_type_decl(rdr, node,
2267 add_to_current_scope))
2268 ||(decl = handle_pointer_type_def(rdr, node,
2269 add_to_current_scope))
2270 || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2271 || (decl = handle_function_type(rdr, node, add_to_current_scope))
2272 || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2273 || (decl = handle_enum_type_decl(rdr, node,
2274 add_to_current_scope))
2275 || (decl = handle_typedef_decl(rdr, node,
2276 add_to_current_scope))
2277 || (decl = handle_var_decl(rdr, node,
2278 add_to_current_scope))
2279 || (decl = handle_function_decl(rdr, node,
2280 add_to_current_scope))
2281 || (decl = handle_class_decl(rdr, node,
2282 add_to_current_scope))
2283 || (decl = handle_union_decl(rdr, node,
2284 add_to_current_scope))
2285 || (decl = handle_function_tdecl(rdr, node,
2286 add_to_current_scope))
2287 || (decl = handle_class_tdecl(rdr, node,
2288 add_to_current_scope)));
2293 if (rdr.tracking_non_reachable_types())
2295 if (type_base_sptr t =
is_type(decl))
2297 corpus_sptr abi = rdr.corpus();
2299 bool is_non_reachable_type =
false;
2300 read_is_non_reachable_type(node, is_non_reachable_type);
2301 if (!is_non_reachable_type)
2302 abi->record_type_as_reachable_from_public_interfaces(*t);
2317 read_location(
const reader& rdr,
2322 size_t line = 0, column = 0;
2325 file_path = CHAR_STR(f);
2327 if (file_path.empty())
2328 return read_artificial_location(rdr, node, loc);
2331 line = atoi(CHAR_STR(l));
2333 return read_artificial_location(rdr, node, loc);
2336 column = atoi(CHAR_STR(c));
2338 reader& c =
const_cast<reader&
>(rdr);
2339 loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2356 read_artificial_location(
const reader& rdr,
2364 size_t line = 0, column = 0;
2369 file_path =
reinterpret_cast<const char*
>(node->doc->URL);
2371 reader& c =
const_cast<reader&
>(rdr);
2373 c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2375 loc.set_is_artificial(
true);
2395 maybe_set_artificial_location(
const reader& rdr,
2399 if (artefact && !artefact->has_artificial_location())
2402 if (read_artificial_location(rdr, node, l))
2404 artefact->set_artificial_location(l);
2423 string v = CHAR_STR(s);
2426 vis = decl_base::VISIBILITY_DEFAULT;
2427 else if (v ==
"hidden")
2428 vis = decl_base::VISIBILITY_HIDDEN;
2429 else if (v ==
"internal")
2430 vis = decl_base::VISIBILITY_INTERNAL;
2431 else if (v ==
"protected")
2432 vis = decl_base::VISIBILITY_PROTECTED;
2434 vis = decl_base::VISIBILITY_DEFAULT;
2452 string b = CHAR_STR(s);
2455 bind = decl_base::BINDING_GLOBAL;
2456 else if (b ==
"local")
2457 bind = decl_base::BINDING_LOCAL;
2458 else if (b ==
"weak")
2459 bind = decl_base::BINDING_WEAK;
2461 bind = decl_base::BINDING_GLOBAL;
2480 string a = CHAR_STR(s);
2483 access = private_access;
2484 else if (a ==
"protected")
2485 access = protected_access;
2486 else if (a ==
"public")
2487 access = public_access;
2515 read_size_and_alignment(xmlNodePtr node,
2516 size_t& size_in_bits,
2517 size_t& align_in_bits)
2520 bool got_something =
false;
2523 size_in_bits = atoll(CHAR_STR(s));
2524 got_something =
true;
2529 align_in_bits = atoll(CHAR_STR(s));
2530 got_something =
true;
2532 return got_something;
2545 read_static(xmlNodePtr node,
bool& is_static)
2549 string b = CHAR_STR(s);
2550 is_static = b ==
"yes";
2563 read_offset_in_bits(xmlNodePtr node,
2564 size_t& offset_in_bits)
2568 offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2596 read_cdtor_const(xmlNodePtr node,
2597 bool& is_constructor,
2598 bool& is_destructor,
2603 string b = CHAR_STR(s);
2605 is_constructor =
true;
2607 is_constructor =
false;
2614 string b = CHAR_STR(s);
2616 is_destructor =
true;
2618 is_destructor =
false;
2625 string b = CHAR_STR(s);
2646 read_is_declaration_only(xmlNodePtr node,
bool& is_decl_only)
2650 string str = CHAR_STR(s);
2652 is_decl_only =
true;
2654 is_decl_only =
false;
2670 read_is_artificial(xmlNodePtr node,
bool& is_artificial)
2674 string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2675 is_artificial = is_artificial_str ==
"yes";
2694 read_tracking_non_reachable_types(xmlNodePtr node,
2695 bool& tracking_non_reachable_types)
2700 string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2701 tracking_non_reachable_types =
2702 (tracking_non_reachable_types_str ==
"yes")
2721 read_is_non_reachable_type(xmlNodePtr node,
bool& is_non_reachable_type)
2726 string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2727 is_non_reachable_type =
2728 (is_non_reachable_type_str ==
"yes")
2746 read_naming_typedef_id_string(xmlNodePtr node,
string& naming_typedef_id)
2765 read_is_virtual(xmlNodePtr node,
bool& is_virtual)
2769 string str = CHAR_STR(s);
2788 read_is_struct(xmlNodePtr node,
bool& is_struct)
2792 string str = CHAR_STR(s);
2811 read_is_anonymous(xmlNodePtr node,
bool& is_anonymous)
2815 string str = CHAR_STR(s);
2816 is_anonymous = (str ==
"yes");
2886 #ifdef WITH_DEBUG_SELF_COMPARISON
2895 read_type_id_string(xmlNodePtr node,
string& type_id)
2899 type_id = CHAR_STR(s);
2919 maybe_map_type_with_type_id(
const type_base_sptr& t,
2920 const string& type_id)
2925 const environment& env = t->get_environment();
2926 if (!env.self_comparison_debug_is_on()
2930 const_cast<environment&
>(env).
2931 get_pointer_type_id_map()[
reinterpret_cast<uintptr_t
>(t.get())] = type_id;
2950 maybe_map_type_with_type_id(
const type_base_sptr& t,
2956 const environment&env = t->get_environment();
2957 if (!env.self_comparison_debug_is_on()
2962 if (!read_type_id_string(node, type_id) || type_id.empty())
2965 return maybe_map_type_with_type_id(t, type_id);
2979 maybe_set_naming_typedef(reader& rdr,
2981 const decl_base_sptr& decl)
2983 string naming_typedef_id;
2984 read_naming_typedef_id_string(node, naming_typedef_id);
2985 if (!naming_typedef_id.empty())
2988 is_typedef(rdr.build_or_get_type_decl(naming_typedef_id,
true));
2990 decl->set_naming_typedef(naming_typedef);
3010 build_namespace_decl(reader& rdr,
3011 const xmlNodePtr node,
3012 bool add_to_current_scope)
3015 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"namespace-decl")))
3018 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3030 read_location(rdr, node, loc);
3032 const environment& env = rdr.get_environment();
3034 maybe_set_artificial_location(rdr, node, decl);
3035 rdr.push_decl_to_current_scope(decl, add_to_current_scope);
3036 rdr.map_xml_node_to_decl(node, decl);
3038 for (xmlNodePtr n = xmlFirstElementChild(node);
3040 n = xmlNextElementSibling(n))
3041 handle_element_node(rdr, n,
true);
3043 rdr.pop_scope_or_abort(decl);
3060 build_elf_symbol(reader& rdr,
const xmlNodePtr node,
3061 bool drop_if_suppressed)
3066 || node->type != XML_ELEMENT_NODE
3067 || !xmlStrEqual(node->name, BAD_CAST(
"elf-symbol")))
3076 size = strtol(CHAR_STR(s), NULL, 0);
3078 bool is_defined =
true;
3083 if (value ==
"true" || value ==
"yes")
3089 bool is_common =
false;
3094 if (value ==
"true" || value ==
"yes")
3100 string version_string;
3104 bool is_default_version =
false;
3109 if (value ==
"true" || value ==
"yes")
3110 is_default_version =
true;
3114 read_elf_symbol_type(node, type);
3117 read_elf_symbol_binding(node, binding);
3120 read_elf_symbol_visibility(node, visibility);
3122 elf_symbol::version version(version_string, is_default_version);
3125 if (drop_if_suppressed && is_suppressed)
3128 const environment& env = rdr.get_environment();
3130 size, name, type, binding,
3131 is_defined, is_common,
3132 version, visibility);
3134 e->set_is_suppressed(is_suppressed);
3137 e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3143 e->set_namespace(ns);
3163 build_elf_symbol_from_reference(reader& rdr,
const xmlNodePtr node)
3183 rdr.corpus()->get_symtab()->lookup_symbol(name);
3185 for (
const auto& symbol : symbols)
3186 if (symbol->get_id_string() == sym_id)
3205 build_elf_symbol_db(reader& rdr,
3206 const xmlNodePtr node,
3216 && !xmlStrEqual(node->name, BAD_CAST(
"elf-function-symbols")))
3220 && !xmlStrEqual(node->name, BAD_CAST(
"elf-variable-symbols")))
3223 rdr.set_corpus_node(node);
3225 typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3226 xml_node_ptr_elf_symbol_sptr_map_type;
3227 xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3230 for (xmlNodePtr n = xmlFirstElementChild(node);
3232 n = xmlNextElementSibling(n))
3233 if ((sym = build_elf_symbol(rdr, n,
false)))
3235 id_sym_map[sym->get_id_string()] = sym;
3236 xml_node_ptr_elf_symbol_map[n] = sym;
3239 if (id_sym_map.empty())
3243 string_elf_symbols_map_type::iterator it;
3244 for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3245 i != id_sym_map.end();
3247 (*map)[i->second->get_name()].push_back(i->second);
3250 for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3251 xml_node_ptr_elf_symbol_map.begin();
3252 x != xml_node_ptr_elf_symbol_map.end();
3257 string alias_id = CHAR_STR(s);
3260 std::vector<std::string> elems;
3261 std::stringstream aliases(alias_id);
3263 while (std::getline(aliases, item,
','))
3264 elems.push_back(item);
3265 for (std::vector<string>::iterator alias = elems.begin();
3266 alias != elems.end(); ++alias)
3268 string_elf_symbol_sptr_map_type::const_iterator i =
3269 id_sym_map.find(*alias);
3273 x->second->get_main_symbol()->add_alias(i->second);
3286 static shared_ptr<function_decl::parameter>
3287 build_function_parameter(reader& rdr,
const xmlNodePtr node)
3289 shared_ptr<function_decl::parameter> nil;
3291 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"parameter")))
3294 bool is_variadic =
false;
3295 string is_variadic_str;
3299 is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
3300 is_variadic = is_variadic_str ==
"yes";
3303 bool is_artificial =
false;
3304 read_is_artificial(node, is_artificial);
3308 type_id = CHAR_STR(a);
3310 type_base_sptr type;
3312 type = rdr.get_environment().get_variadic_parameter_type();
3316 type = rdr.build_or_get_type_decl(type_id,
true);
3325 read_location(rdr, node, loc);
3328 (
new function_decl::parameter(type, name, loc,
3329 is_variadic, is_artificial));
3353 build_function_decl(reader& rdr,
3354 const xmlNodePtr node,
3355 class_or_union_sptr as_method_decl,
3356 bool add_to_current_scope)
3360 if (!xmlStrEqual(node->name, BAD_CAST(
"function-decl")))
3367 string mangled_name;
3373 inline_prop = CHAR_STR(s);
3374 bool declared_inline = inline_prop ==
"yes";
3377 read_visibility(node, vis);
3380 read_binding(node, bind);
3382 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3383 read_size_and_alignment(node, size, align);
3386 read_location(rdr, node, loc);
3388 const environment& env = rdr.get_environment();
3390 std::vector<function_decl::parameter_sptr> parms;
3391 type_base_sptr return_type = env.get_void_type();
3393 for (xmlNodePtr n = xmlFirstElementChild(node);
3395 n = xmlNextElementSibling(n))
3397 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
3400 build_function_parameter(rdr, n))
3403 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
3408 type_id = CHAR_STR(s);
3409 if (!type_id.empty())
3410 return_type = rdr.build_or_get_type_decl(type_id,
true);
3415 ?
new method_type(return_type, as_method_decl,
3418 :
new function_type(return_type,
3419 parms, size, align));
3423 fn_type->set_is_artificial(
true);
3426 ?
new method_decl (name, fn_type,
3427 declared_inline, loc,
3428 mangled_name, vis, bind)
3429 :
new function_decl(name, fn_type,
3430 declared_inline, loc,
3434 maybe_set_artificial_location(rdr, node, fn_decl);
3435 rdr.push_decl_to_current_scope(fn_decl, add_to_current_scope);
3436 RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3440 fn_decl->set_symbol(sym);
3442 if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3443 fn_decl->set_is_in_public_symbol_table(
true);
3445 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3447 rdr.maybe_canonicalize_type(fn_type, !add_to_current_scope);
3449 rdr.maybe_add_fn_to_exported_decls(fn_decl.get());
3476 build_function_decl_if_not_suppressed(reader& rdr,
3477 const xmlNodePtr node,
3478 class_or_union_sptr as_method_decl,
3479 bool add_to_current_scope)
3483 if (function_is_suppressed(rdr, node))
3489 fn = build_function_decl(rdr, node, as_method_decl,
3490 add_to_current_scope);
3506 function_is_suppressed(
const reader& rdr, xmlNodePtr node)
3512 string flinkage_name;
3516 scope_decl* scope = rdr.get_cur_scope();
3535 type_is_suppressed(
const reader& rdr, xmlNodePtr node)
3541 location type_location;
3542 read_location(rdr, node, type_location);
3544 scope_decl* scope = rdr.get_cur_scope();
3548 bool type_is_private =
false;
3567 build_var_decl_if_not_suppressed(reader& rdr,
3568 const xmlNodePtr node,
3569 bool add_to_current_scope)
3572 if (!variable_is_suppressed(rdr, node))
3573 var = build_var_decl(rdr, node, add_to_current_scope);
3586 variable_is_suppressed(
const reader& rdr, xmlNodePtr node)
3592 string linkage_name;
3596 scope_decl* scope = rdr.get_cur_scope();
3614 variable_is_suppressed(
const reader& rdr,
3615 const scope_decl* scope,
3620 v.get_linkage_name());
3631 static shared_ptr<var_decl>
3632 build_var_decl(reader& rdr,
3633 const xmlNodePtr node,
3634 bool add_to_current_scope)
3636 shared_ptr<var_decl> nil;
3638 if (!xmlStrEqual(node->name, BAD_CAST(
"var-decl")))
3647 type_id = CHAR_STR(s);
3648 type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
3652 string mangled_name;
3657 read_visibility(node, vis);
3660 read_binding(node, bind);
3663 read_location(rdr, node, locus);
3666 locus, mangled_name,
3668 maybe_set_artificial_location(rdr, node, decl);
3672 decl->set_symbol(sym);
3674 rdr.push_decl_to_current_scope(decl, add_to_current_scope);
3675 if (add_to_current_scope)
3679 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
3682 if (decl->get_symbol() && decl->get_symbol()->is_public())
3683 decl->set_is_in_public_symbol_table(
true);
3699 static shared_ptr<type_decl>
3700 build_type_decl(reader& rdr,
3701 const xmlNodePtr node,
3702 bool add_to_current_scope)
3704 shared_ptr<type_decl> nil;
3706 if (!xmlStrEqual(node->name, BAD_CAST(
"type-decl")))
3709 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3725 size_t size_in_bits= 0;
3727 size_in_bits = atoi(CHAR_STR(s));
3729 size_t alignment_in_bits = 0;
3731 alignment_in_bits = atoi(CHAR_STR(s));
3733 bool is_decl_only =
false;
3734 read_is_declaration_only(node, is_decl_only);
3737 read_location(rdr, node, loc);
3739 bool is_anonymous =
false;
3740 read_is_anonymous(node, is_anonymous);
3742 if (type_base_sptr d = rdr.get_type_decl(
id))
3750 ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
3751 ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
3755 const environment& env = rdr.get_environment();
3757 if (name == env.get_variadic_parameter_type_name())
3758 decl =
is_type_decl(env.get_variadic_parameter_type());
3760 decl.reset(
new type_decl(env, name, size_in_bits,
3761 alignment_in_bits, loc));
3762 maybe_set_artificial_location(rdr, node, decl);
3763 decl->set_is_anonymous(is_anonymous);
3764 decl->set_is_declaration_only(is_decl_only);
3765 if (rdr.push_and_key_type_decl(decl,
id, add_to_current_scope))
3767 rdr.map_xml_node_to_decl(node, decl);
3785 static qualified_type_def_sptr
3786 build_qualified_type_decl(reader& rdr,
3787 const xmlNodePtr node,
3788 bool add_to_current_scope)
3790 qualified_type_def_sptr nil;
3791 if (!xmlStrEqual(node->name, BAD_CAST(
"qualified-type-def")))
3794 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3796 qualified_type_def_sptr result =
3797 dynamic_pointer_cast<qualified_type_def>(d);
3809 read_location(rdr, node, loc);
3814 const_str = CHAR_STR(s);
3815 bool const_cv = const_str ==
"yes";
3817 string volatile_str;
3819 volatile_str = CHAR_STR(s);
3820 bool volatile_cv = volatile_str ==
"yes";
3822 string restrict_str;
3824 restrict_str = CHAR_STR(s);
3825 bool restrict_cv = restrict_str ==
"yes";
3828 cv = cv | qualified_type_def::CV_CONST;
3830 cv = cv | qualified_type_def::CV_VOLATILE;
3832 cv = cv | qualified_type_def::CV_RESTRICT;
3836 type_id = CHAR_STR(s);
3839 shared_ptr<type_base> underlying_type =
3840 rdr.build_or_get_type_decl(type_id,
true);
3843 qualified_type_def_sptr decl;
3844 if (type_base_sptr t = rdr.get_type_decl(
id))
3851 decl.reset(
new qualified_type_def(underlying_type, cv, loc));
3852 maybe_set_artificial_location(rdr, node, decl);
3853 rdr.push_and_key_type_decl(decl,
id, add_to_current_scope);
3854 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
3857 rdr.map_xml_node_to_decl(node, decl);
3874 build_pointer_type_def(reader& rdr,
3875 const xmlNodePtr node,
3876 bool add_to_current_scope)
3879 shared_ptr<pointer_type_def> nil;
3881 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-type-def")))
3884 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3887 dynamic_pointer_cast<pointer_type_def>(d);
3897 if (type_base_sptr t = rdr.get_type_decl(
id))
3906 type_id = CHAR_STR(s);
3908 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
3909 size_t alignment_in_bits = 0;
3910 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
3912 read_location(rdr, node, loc);
3923 maybe_set_artificial_location(rdr, node, t);
3925 if (rdr.push_and_key_type_decl(t,
id, add_to_current_scope))
3926 rdr.map_xml_node_to_decl(node, t);
3928 type_base_sptr pointed_to_type =
3929 rdr.build_or_get_type_decl(type_id,
true);
3932 t->set_pointed_to_type(pointed_to_type);
3933 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
3949 static shared_ptr<reference_type_def>
3950 build_reference_type_def(reader& rdr,
3951 const xmlNodePtr node,
3952 bool add_to_current_scope)
3954 shared_ptr<reference_type_def> nil;
3956 if (!xmlStrEqual(node->name, BAD_CAST(
"reference-type-def")))
3959 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3962 dynamic_pointer_cast<reference_type_def>(d);
3972 if (type_base_sptr d = rdr.get_type_decl(
id))
3980 read_location(rdr, node, loc);
3984 bool is_lvalue = kind ==
"lvalue";
3986 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
3987 size_t alignment_in_bits = 0;
3988 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
3992 type_id = CHAR_STR(s);
4002 is_lvalue, size_in_bits,
4003 alignment_in_bits, loc));
4004 maybe_set_artificial_location(rdr, node, t);
4005 if (rdr.push_and_key_type_decl(t,
id, add_to_current_scope))
4006 rdr.map_xml_node_to_decl(node, t);
4008 type_base_sptr pointed_to_type =
4009 rdr.build_or_get_type_decl(type_id,
true);
4011 t->set_pointed_to_type(pointed_to_type);
4012 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4030 build_function_type(reader& rdr,
4031 const xmlNodePtr node,
4036 if (!xmlStrEqual(node->name, BAD_CAST(
"function-type")))
4044 string method_class_id;
4046 method_class_id = CHAR_STR(s);
4048 bool is_method_t = !method_class_id.empty();
4050 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4051 read_size_and_alignment(node, size, align);
4053 const environment& env = rdr.get_environment();
4054 std::vector<shared_ptr<function_decl::parameter> > parms;
4055 type_base_sptr return_type = env.get_void_type();
4057 class_or_union_sptr method_class_type;
4067 ?
new method_type(method_class_type,
4070 :
new function_type(return_type,
4071 parms, size, align));
4073 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4074 rdr.key_type_decl(fn_type,
id);
4075 RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4077 for (xmlNodePtr n = xmlFirstElementChild(node);
4079 n = xmlNextElementSibling(n))
4081 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
4084 build_function_parameter(rdr, n))
4087 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
4092 type_id = CHAR_STR(s);
4093 if (!type_id.empty())
4094 fn_type->set_return_type(rdr.build_or_get_type_decl
4099 fn_type->set_parameters(parms);
4115 build_subrange_type(reader& rdr,
4116 const xmlNodePtr node,
4117 bool add_to_current_scope)
4121 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"subrange")))
4124 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4127 dynamic_pointer_cast<array_type_def::subrange_type>(d);
4141 if (type_base_sptr d = rdr.get_type_decl(
id))
4152 uint64_t length = 0;
4154 bool is_infinite =
false;
4157 if (
string(CHAR_STR(s)) ==
"infinite" ||
string(CHAR_STR(s)) ==
"unknown")
4160 length = strtoull(CHAR_STR(s), NULL, 0);
4163 int64_t lower_bound = 0, upper_bound = 0;
4164 bool bounds_present =
false;
4167 lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4169 if (!
string(CHAR_STR(s)).empty())
4170 upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4171 bounds_present =
true;
4173 || (length == (uint64_t) upper_bound - lower_bound + 1));
4176 string underlying_type_id;
4178 underlying_type_id = CHAR_STR(s);
4180 type_base_sptr underlying_type;
4181 if (!underlying_type_id.empty())
4183 underlying_type = rdr.build_or_get_type_decl(underlying_type_id,
true);
4188 read_location(rdr, node, loc);
4192 array_type_def::subrange_type::bound_value max_bound;
4193 array_type_def::subrange_type::bound_value min_bound;
4199 max_bound.set_signed(length - 1);
4205 min_bound.set_signed(lower_bound);
4206 max_bound.set_signed(upper_bound);
4210 (
new array_type_def::subrange_type(rdr.get_environment(),
4211 name, min_bound, max_bound,
4212 underlying_type, loc));
4213 maybe_set_artificial_location(rdr, node, p);
4214 p->is_infinite(is_infinite);
4216 if (rdr.push_and_key_type_decl(p,
id, add_to_current_scope))
4217 rdr.map_xml_node_to_decl(node, p);
4234 build_array_type_def(reader& rdr,
4235 const xmlNodePtr node,
4236 bool add_to_current_scope)
4241 if (!xmlStrEqual(node->name, BAD_CAST(
"array-type-def")))
4244 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4247 dynamic_pointer_cast<array_type_def>(d);
4257 if (type_base_sptr d = rdr.get_type_decl(
id))
4266 dimensions = atoi(CHAR_STR(s));
4270 type_id = CHAR_STR(s);
4274 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4277 dynamic_pointer_cast<array_type_def>(d);
4282 size_t size_in_bits = 0, alignment_in_bits = 0;
4283 bool has_size_in_bits =
false;
4288 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4289 if (*endptr !=
'\0')
4291 if (!strcmp(CHAR_STR(s),
"infinite")
4292 ||!strcmp(CHAR_STR(s),
"unknown"))
4293 size_in_bits = (size_t) -1;
4297 has_size_in_bits =
true;
4302 alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4303 if (*endptr !=
'\0')
4308 read_location(rdr, node, loc);
4311 for (xmlNodePtr n = xmlFirstElementChild(node);
4313 n = xmlNextElementSibling(n))
4314 if (xmlStrEqual(n->name, BAD_CAST(
"subrange")))
4317 build_subrange_type(rdr, n,
true))
4319 MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
4320 if (add_to_current_scope)
4323 rdr.maybe_canonicalize_type(s);
4325 subranges.push_back(s);
4330 type_base_sptr type =
4331 rdr.build_or_get_type_decl(type_id,
true);
4335 maybe_set_artificial_location(rdr, node, ar_type);
4336 if (rdr.push_and_key_type_decl(ar_type,
id, add_to_current_scope))
4337 rdr.map_xml_node_to_decl(node, ar_type);
4338 RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
4340 if (dimensions != ar_type->get_dimension_count()
4341 || (alignment_in_bits
4342 != ar_type->get_element_type()->get_alignment_in_bits()))
4345 if (has_size_in_bits && size_in_bits != (
size_t) -1
4346 && size_in_bits != ar_type->get_size_in_bits())
4349 size_t element_size = ar_type->get_element_type()->get_size_in_bits();
4350 if (element_size && element_size != (
size_t)-1)
4353 size_t bad_count = 0;
4354 for (vector<array_type_def::subrange_sptr>::const_iterator i =
4356 i != subranges.end();
4358 bad_count += (*i)->get_length();
4359 if (size_in_bits == bad_count * element_size)
4361 static bool reported =
false;
4364 std::cerr <<
"notice: Found incorrectly calculated array "
4365 <<
"sizes in XML - this is benign.\nOlder versions "
4366 <<
"of libabigail miscalculated multidimensional "
4367 <<
"array sizes." << std::endl;
4373 std::cerr <<
"error: Found incorrectly calculated array size in "
4374 <<
"XML (id=\"" <<
id <<
"\")." << std::endl;
4398 build_enum_type_decl_if_not_suppressed(reader& rdr,
4399 const xmlNodePtr node,
4400 bool add_to_current_scope)
4403 if (!type_is_suppressed(rdr, node))
4404 enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
4420 build_enum_type_decl(reader& rdr,
4421 const xmlNodePtr node,
4422 bool add_to_current_scope)
4426 if (!xmlStrEqual(node->name, BAD_CAST(
"enum-decl")))
4429 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4432 dynamic_pointer_cast<enum_type_decl>(d);
4441 string linkage_name;
4446 read_location(rdr, node, loc);
4448 bool is_decl_only =
false;
4449 read_is_declaration_only(node, is_decl_only);
4451 bool is_anonymous =
false;
4452 read_is_anonymous(node, is_anonymous);
4454 bool is_artificial =
false;
4455 read_is_artificial(node, is_artificial);
4463 string base_type_id;
4465 for (xmlNodePtr n = xmlFirstElementChild(node);
4467 n = xmlNextElementSibling(n))
4469 if (xmlStrEqual(n->name, BAD_CAST(
"underlying-type")))
4473 base_type_id = CHAR_STR(a);
4476 else if (xmlStrEqual(n->name, BAD_CAST(
"enumerator")))
4488 value = strtoll(CHAR_STR(a), NULL, 0);
4492 if ((errno == ERANGE)
4493 && (value == LLONG_MIN || value == LLONG_MAX))
4497 enums.push_back(enum_type_decl::enumerator(name, value));
4501 type_base_sptr underlying_type =
4502 rdr.build_or_get_type_decl(base_type_id,
true);
4507 enums, linkage_name));
4508 maybe_set_artificial_location(rdr, node, t);
4509 t->set_is_anonymous(is_anonymous);
4510 t->set_is_artificial(is_artificial);
4511 t->set_is_declaration_only(is_decl_only);
4512 if (rdr.push_and_key_type_decl(t,
id, add_to_current_scope))
4514 maybe_set_naming_typedef(rdr, node, t);
4515 rdr.map_xml_node_to_decl(node, t);
4516 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4531 static shared_ptr<typedef_decl>
4532 build_typedef_decl(reader& rdr,
4533 const xmlNodePtr node,
4534 bool add_to_current_scope)
4536 shared_ptr<typedef_decl> nil;
4538 if (!xmlStrEqual(node->name, BAD_CAST(
"typedef-decl")))
4541 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4553 if (type_base_sptr t = rdr.get_type_decl(
id))
4565 read_location(rdr, node, loc);
4569 type_id = CHAR_STR(s);
4572 type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id,
true));
4576 maybe_set_artificial_location(rdr, node, t);
4577 rdr.push_and_key_type_decl(t,
id, add_to_current_scope);
4578 rdr.map_xml_node_to_decl(node, t);
4579 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4596 build_class_decl_if_not_suppressed(reader& rdr,
4597 const xmlNodePtr node,
4598 bool add_to_current_scope)
4601 if (!type_is_suppressed(rdr, node))
4602 class_type = build_class_decl(rdr, node, add_to_current_scope);
4618 static union_decl_sptr
4619 build_union_decl_if_not_suppressed(reader& rdr,
4620 const xmlNodePtr node,
4621 bool add_to_current_scope)
4623 union_decl_sptr union_type;
4624 if (!type_is_suppressed(rdr, node))
4625 union_type = build_union_decl(rdr, node, add_to_current_scope);
4642 build_class_decl(reader& rdr,
4643 const xmlNodePtr node,
4644 bool add_to_current_scope)
4648 if (!xmlStrEqual(node->name, BAD_CAST(
"class-decl")))
4651 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4662 size_t size_in_bits = 0, alignment_in_bits = 0;
4663 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4666 read_visibility(node, vis);
4668 bool is_artificial =
false;
4669 read_is_artificial(node, is_artificial);
4676 read_location(rdr, node, loc);
4685 bool is_decl_only =
false;
4686 read_is_declaration_only(node, is_decl_only);
4688 bool is_struct =
false;
4689 read_is_struct(node, is_struct);
4691 bool is_anonymous =
false;
4692 read_is_anonymous(node, is_anonymous);
4698 if (type_base_sptr t = rdr.get_type_decl(
id))
4704 const vector<type_base_sptr> *types_ptr = 0;
4705 if (!is_anonymous && !previous_definition)
4706 types_ptr = rdr.get_all_type_decls(
id);
4712 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
4713 i != types_ptr->end();
4718 if (klass->get_is_declaration_only()
4719 && !klass->get_definition_of_declaration())
4720 previous_declaration = klass;
4721 else if (!klass->get_is_declaration_only()
4722 && !previous_definition)
4723 previous_definition = klass;
4724 if (previous_definition && previous_declaration)
4728 if (previous_declaration)
4729 ABG_ASSERT(previous_declaration->get_name() == name);
4731 if (previous_definition)
4732 ABG_ASSERT(previous_definition->get_name() == name);
4734 if (is_decl_only && previous_declaration)
4735 return previous_declaration;
4738 const environment& env = rdr.get_environment();
4740 if (!is_decl_only && previous_definition)
4746 decl = previous_definition;
4751 decl.reset(
new class_decl(env, name, is_struct));
4753 decl->set_size_in_bits(size_in_bits);
4755 decl->set_is_anonymous(is_anonymous);
4756 decl->set_location(loc);
4759 decl.reset(
new class_decl(env, name, size_in_bits, alignment_in_bits,
4760 is_struct, loc, vis, bases, mbrs,
4761 data_mbrs, mbr_functions, is_anonymous));
4764 maybe_set_artificial_location(rdr, node, decl);
4765 decl->set_is_artificial(is_artificial);
4768 bool is_def_of_decl =
false;
4770 def_id = CHAR_STR(s);
4772 if (!def_id.empty())
4774 decl_base_sptr d =
is_decl(rdr.get_type_decl(def_id));
4775 if (d && d->get_is_declaration_only())
4777 is_def_of_decl =
true;
4778 decl->set_earlier_declaration(d);
4779 d->set_definition_of_declaration(decl);
4785 && !decl->get_is_declaration_only()
4786 && previous_declaration)
4792 decl->set_earlier_declaration(
is_decl(previous_declaration));
4793 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
4794 i != types_ptr->end();
4799 if (d->get_is_declaration_only()
4800 && !d->get_definition_of_declaration())
4802 previous_declaration->set_definition_of_declaration(decl);
4803 is_def_of_decl =
true;
4808 if (is_decl_only && previous_definition)
4813 && !decl->get_definition_of_declaration());
4814 decl->set_definition_of_declaration(previous_definition);
4817 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
4819 rdr.push_decl_to_current_scope(decl, add_to_current_scope);
4821 rdr.map_xml_node_to_decl(node, decl);
4822 rdr.key_type_decl(decl,
id);
4825 maybe_set_naming_typedef(rdr, node, decl);
4827 for (xmlNodePtr n = xmlFirstElementChild(node);
4829 n = xmlNextElementSibling(n))
4831 if (xmlStrEqual(n->name, BAD_CAST(
"base-class")))
4837 read_access(n, access);
4841 type_id = CHAR_STR(s);
4842 shared_ptr<class_decl> b =
4843 dynamic_pointer_cast<class_decl>
4844 (rdr.build_or_get_type_decl(type_id,
true));
4847 if (decl->find_base_class(b->get_qualified_name()))
4853 size_t offset_in_bits = 0;
4854 bool offset_present = read_offset_in_bits (n, offset_in_bits);
4856 bool is_virtual =
false;
4857 read_is_virtual (n, is_virtual);
4859 shared_ptr<class_decl::base_spec> base (
new class_decl::base_spec
4862 ? (
long) offset_in_bits
4865 decl->add_base_specifier(base);
4867 else if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
4873 read_access(n, access);
4875 rdr.map_xml_node_to_decl(n, decl);
4877 for (xmlNodePtr p = xmlFirstElementChild(n);
4879 p = xmlNextElementSibling(p))
4881 if (type_base_sptr t =
4882 build_type(rdr, p,
true))
4887 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
4889 string id = CHAR_STR(i);
4891 rdr.key_type_decl(t,
id);
4892 rdr.map_xml_node_to_decl(p, td);
4896 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
4898 rdr.map_xml_node_to_decl(n, decl);
4904 read_access(n, access);
4906 bool is_laid_out =
false;
4907 size_t offset_in_bits = 0;
4908 if (read_offset_in_bits(n, offset_in_bits))
4911 bool is_static =
false;
4912 read_static(n, is_static);
4914 for (xmlNodePtr p = xmlFirstElementChild(n);
4916 p = xmlNextElementSibling(p))
4919 build_var_decl(rdr, p,
false))
4921 if (decl->find_data_member(v))
4929 decl_base_sptr d = rdr.pop_decl();
4934 if (!variable_is_suppressed(rdr, decl.get(), *v))
4936 decl->add_data_member(v, access,
4941 rdr.maybe_add_var_to_exported_decls(v.get());
4951 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
4954 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
4955 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
4961 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
4963 rdr.map_xml_node_to_decl(n, decl);
4969 read_access(n, access);
4971 bool is_virtual =
false;
4972 ssize_t vtable_offset = -1;
4977 vtable_offset = atoi(CHAR_STR(s));
4980 bool is_static =
false;
4981 read_static(n, is_static);
4983 bool is_ctor =
false, is_dtor =
false, is_const =
false;
4984 read_cdtor_const(n, is_ctor, is_dtor, is_const);
4986 for (xmlNodePtr p = xmlFirstElementChild(n);
4988 p = xmlNextElementSibling(p))
4991 build_function_decl_if_not_suppressed(rdr, p, decl,
4998 if (vtable_offset != -1)
5008 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5010 rdr.map_xml_node_to_decl(n, decl);
5016 read_access(n, access);
5018 bool is_static =
false;
5019 read_static(n, is_static);
5021 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5022 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5024 for (xmlNodePtr p = xmlFirstElementChild(n);
5026 p = xmlNextElementSibling(p))
5028 if (shared_ptr<function_tdecl> f =
5029 build_function_tdecl(rdr, p,
5032 shared_ptr<member_function_template> m
5033 (
new member_function_template(f, access, is_static,
5034 is_ctor, is_const));
5036 decl->add_member_function_template(m);
5038 else if (shared_ptr<class_tdecl> c =
5039 build_class_tdecl(rdr, p,
5042 member_class_template_sptr m(
new member_class_template(c,
5046 decl->add_member_class_template(m);
5052 rdr.pop_scope_or_abort(decl);
5069 static union_decl_sptr
5070 build_union_decl(reader& rdr,
5071 const xmlNodePtr node,
5072 bool add_to_current_scope)
5074 union_decl_sptr nil;
5076 if (!xmlStrEqual(node->name, BAD_CAST(
"union-decl")))
5079 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5081 union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5090 size_t size_in_bits = 0, alignment_in_bits = 0;
5091 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5094 read_visibility(node, vis);
5096 bool is_artificial =
false;
5097 read_is_artificial(node, is_artificial);
5104 read_location(rdr, node, loc);
5110 union_decl_sptr decl;
5112 bool is_decl_only =
false;
5113 read_is_declaration_only(node, is_decl_only);
5115 bool is_anonymous =
false;
5116 read_is_anonymous(node, is_anonymous);
5119 union_decl_sptr previous_definition, previous_declaration;
5120 const vector<type_base_sptr> *types_ptr = 0;
5122 types_ptr = rdr.get_all_type_decls(
id);
5128 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5129 i != types_ptr->end();
5134 if (onion->get_is_declaration_only()
5135 && !onion->get_definition_of_declaration())
5136 previous_declaration = onion;
5137 else if (!onion->get_is_declaration_only()
5138 && !previous_definition)
5139 previous_definition = onion;
5140 if (previous_definition && previous_declaration)
5144 if (previous_declaration)
5145 ABG_ASSERT(previous_declaration->get_name() == name);
5147 if (previous_definition)
5148 ABG_ASSERT(previous_definition->get_name() == name);
5150 if (is_decl_only && previous_declaration)
5151 return previous_declaration;
5154 const environment& env = rdr.get_environment();
5156 if (!is_decl_only && previous_definition)
5162 decl = previous_definition;
5166 decl.reset(
new union_decl(env, name));
5168 decl.reset(
new union_decl(env, name,
5176 maybe_set_artificial_location(rdr, node, decl);
5177 decl->set_is_artificial(is_artificial);
5180 bool is_def_of_decl =
false;
5182 def_id = CHAR_STR(s);
5184 if (!def_id.empty())
5187 dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5188 if (d && d->get_is_declaration_only())
5190 is_def_of_decl =
true;
5191 decl->set_earlier_declaration(d);
5192 d->set_definition_of_declaration(decl);
5198 && !decl->get_is_declaration_only()
5199 && previous_declaration)
5205 decl->set_earlier_declaration(previous_declaration);
5206 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5207 i != types_ptr->end();
5212 if (d->get_is_declaration_only()
5213 && !d->get_definition_of_declaration())
5215 previous_declaration->set_definition_of_declaration(decl);
5216 is_def_of_decl =
true;
5221 if (is_decl_only && previous_definition)
5226 && !decl->get_definition_of_declaration());
5227 decl->set_definition_of_declaration(previous_definition);
5230 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5232 rdr.push_decl_to_current_scope(decl, add_to_current_scope);
5234 rdr.map_xml_node_to_decl(node, decl);
5235 rdr.key_type_decl(decl,
id);
5237 maybe_set_naming_typedef(rdr, node, decl);
5239 for (xmlNodePtr n = xmlFirstElementChild(node);
5241 n = xmlNextElementSibling(n))
5243 if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5246 read_access(n, access);
5248 rdr.map_xml_node_to_decl(n, decl);
5250 for (xmlNodePtr p = xmlFirstElementChild(n);
5252 p = xmlNextElementSibling(p))
5254 if (type_base_sptr t =
5255 build_type(rdr, p,
true))
5260 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5262 string id = CHAR_STR(i);
5264 rdr.key_type_decl(t,
id);
5265 rdr.map_xml_node_to_decl(p, td);
5269 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5271 rdr.map_xml_node_to_decl(n, decl);
5274 read_access(n, access);
5276 bool is_laid_out =
true;
5277 size_t offset_in_bits = 0;
5278 bool is_static =
false;
5279 read_static(n, is_static);
5281 for (xmlNodePtr p = xmlFirstElementChild(n);
5283 p = xmlNextElementSibling(p))
5286 build_var_decl(rdr, p,
false))
5288 if (decl->find_data_member(v))
5296 decl_base_sptr d = rdr.pop_decl();
5301 || !variable_is_suppressed(rdr, decl.get(), *v))
5303 decl->add_data_member(v, access,
5316 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5319 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5320 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5326 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5328 rdr.map_xml_node_to_decl(n, decl);
5331 read_access(n, access);
5333 bool is_static =
false;
5334 read_static(n, is_static);
5336 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5337 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5339 for (xmlNodePtr p = xmlFirstElementChild(n);
5341 p = xmlNextElementSibling(p))
5344 build_function_decl_if_not_suppressed(rdr, p, decl,
5358 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5360 rdr.map_xml_node_to_decl(n, decl);
5363 read_access(n, access);
5365 bool is_static =
false;
5366 read_static(n, is_static);
5368 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5369 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5371 for (xmlNodePtr p = xmlFirstElementChild(n);
5373 p = xmlNextElementSibling(p))
5376 build_function_tdecl(rdr, p,
5379 member_function_template_sptr m
5380 (
new member_function_template(f, access, is_static,
5381 is_ctor, is_const));
5383 decl->add_member_function_template(m);
5386 build_class_tdecl(rdr, p,
5389 member_class_template_sptr m(
new member_class_template(c,
5393 decl->add_member_class_template(m);
5399 rdr.pop_scope_or_abort(decl);
5416 static shared_ptr<function_tdecl>
5417 build_function_tdecl(reader& rdr,
5418 const xmlNodePtr node,
5419 bool add_to_current_scope)
5421 shared_ptr<function_tdecl> nil, result;
5423 if (!xmlStrEqual(node->name, BAD_CAST(
"function-template-decl")))
5429 if (
id.empty() || rdr.get_fn_tmpl_decl(
id))
5433 read_location(rdr, node, loc);
5436 read_visibility(node, vis);
5439 read_binding(node, bind);
5441 const environment& env = rdr.get_environment();
5444 maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
5446 rdr.push_decl_to_current_scope(fn_tmpl_decl, add_to_current_scope);
5448 unsigned parm_index = 0;
5449 for (xmlNodePtr n = xmlFirstElementChild(node);
5451 n = xmlNextElementSibling(n))
5454 build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
5456 fn_tmpl_decl->add_template_parameter(parm);
5462 fn_tmpl_decl->set_pattern(f);
5465 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5467 return fn_tmpl_decl;
5482 static shared_ptr<class_tdecl>
5483 build_class_tdecl(reader& rdr,
5484 const xmlNodePtr node,
5485 bool add_to_current_scope)
5487 shared_ptr<class_tdecl> nil, result;
5489 if (!xmlStrEqual(node->name, BAD_CAST(
"class-template-decl")))
5495 if (
id.empty() || rdr.get_class_tmpl_decl(
id))
5499 read_location(rdr, node, loc);
5502 read_visibility(node, vis);
5504 const environment& env = rdr.get_environment();
5507 maybe_set_artificial_location(rdr, node, class_tmpl);
5509 rdr.push_decl_to_current_scope(class_tmpl, add_to_current_scope);
5511 unsigned parm_index = 0;
5512 for (xmlNodePtr n = xmlFirstElementChild(node);
5514 n = xmlNextElementSibling(n))
5517 build_template_parameter(rdr, n, parm_index, class_tmpl))
5519 class_tmpl->add_template_parameter(parm);
5523 build_class_decl_if_not_suppressed(rdr, n,
5524 add_to_current_scope))
5527 rdr.maybe_canonicalize_type(c,
false);
5528 class_tmpl->set_pattern(c);
5532 rdr.key_class_tmpl_decl(class_tmpl,
id);
5553 build_type_tparameter(reader& rdr,
5554 const xmlNodePtr node,
5560 if (!xmlStrEqual(node->name, BAD_CAST(
"template-type-parameter")))
5571 type_id = CHAR_STR(s);
5572 if (!type_id.empty()
5573 && !(result = dynamic_pointer_cast<type_tparameter>
5574 (rdr.build_or_get_type_decl(type_id,
true))))
5582 read_location(rdr, node,loc);
5584 result.reset(
new type_tparameter(index, tdecl, name, loc));
5585 maybe_set_artificial_location(rdr, node, result);
5588 rdr.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(result),
5591 rdr.push_and_key_type_decl(result,
id,
true);
5593 rdr.maybe_canonicalize_type(result,
false);
5613 build_type_composition(reader& rdr,
5614 const xmlNodePtr node,
5620 if (!xmlStrEqual(node->name, BAD_CAST(
"template-parameter-type-composition")))
5623 type_base_sptr composed_type;
5624 result.reset(
new type_composition(index, tdecl, composed_type));
5625 rdr.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(result),
5628 for (xmlNodePtr n = xmlFirstElementChild(node);
5630 n = xmlNextElementSibling(n))
5632 if ((composed_type =
5633 build_pointer_type_def(rdr, n,
5636 build_reference_type_def(rdr, n,
5639 build_array_type_def(rdr, n,
5642 build_qualified_type_decl(rdr, n,
5645 rdr.maybe_canonicalize_type(composed_type,
5647 result->set_composed_type(composed_type);
5671 build_non_type_tparameter(reader& rdr,
5672 const xmlNodePtr node,
5678 if (!xmlStrEqual(node->name, BAD_CAST(
"template-non-type-parameter")))
5683 type_id = CHAR_STR(s);
5684 type_base_sptr type;
5686 || !(type = rdr.build_or_get_type_decl(type_id,
true)))
5694 read_location(rdr, node,loc);
5696 r.reset(
new non_type_tparameter(index, tdecl, name, type, loc));
5697 maybe_set_artificial_location(rdr, node, r);
5698 rdr.push_decl_to_current_scope(dynamic_pointer_cast<decl_base>(r),
5719 build_template_tparameter(reader& rdr,
5720 const xmlNodePtr node,
5726 if (!xmlStrEqual(node->name, BAD_CAST(
"template-template-parameter")))
5737 type_id = CHAR_STR(s);
5739 if (!type_id.empty()
5740 && !(dynamic_pointer_cast<template_tparameter>
5741 (rdr.build_or_get_type_decl(type_id,
true))))
5749 read_location(rdr, node, loc);
5753 maybe_set_artificial_location(rdr, node, result);
5754 rdr.push_decl_to_current_scope(result,
true);
5758 for (xmlNodePtr n = xmlFirstElementChild(node);
5760 n = xmlNextElementSibling(n))
5761 if (shared_ptr<template_parameter> p =
5762 build_template_parameter(rdr, n, parm_index, result))
5764 result->add_template_parameter(p);
5770 rdr.key_type_decl(result,
id);
5771 rdr.maybe_canonicalize_type(result,
false);
5793 build_template_parameter(reader& rdr,
5794 const xmlNodePtr node,
5798 shared_ptr<template_parameter> r;
5799 ((r = build_type_tparameter(rdr, node, index, tdecl))
5800 || (r = build_non_type_tparameter(rdr, node, index, tdecl))
5801 || (r = build_template_tparameter(rdr, node, index, tdecl))
5802 || (r = build_type_composition(rdr, node, index, tdecl)));
5815 static type_base_sptr
5816 build_type(reader& rdr,
5817 const xmlNodePtr node,
5818 bool add_to_current_scope)
5822 ((t = build_type_decl(rdr, node, add_to_current_scope))
5823 || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
5824 || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
5825 || (t = build_reference_type_def(rdr, node , add_to_current_scope))
5826 || (t = build_function_type(rdr, node, add_to_current_scope))
5827 || (t = build_array_type_def(rdr, node, add_to_current_scope))
5828 || (t = build_subrange_type(rdr, node, add_to_current_scope))
5829 || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
5830 add_to_current_scope))
5831 || (t = build_typedef_decl(rdr, node, add_to_current_scope))
5832 || (t = build_class_decl_if_not_suppressed(rdr, node,
5833 add_to_current_scope))
5834 || (t = build_union_decl_if_not_suppressed(rdr, node,
5835 add_to_current_scope)));
5837 if (rdr.tracking_non_reachable_types() && t)
5839 corpus_sptr abi = rdr.corpus();
5841 bool is_non_reachable_type =
false;
5842 read_is_non_reachable_type(node, is_non_reachable_type);
5843 if (!is_non_reachable_type)
5844 abi->record_type_as_reachable_from_public_interfaces(*t);
5847 MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
5850 rdr.maybe_canonicalize_type(t,
false );
5859 static decl_base_sptr
5860 handle_type_decl(reader& rdr,
5862 bool add_to_current_scope)
5864 type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
5865 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
5866 if (decl && decl->get_scope())
5867 rdr.maybe_canonicalize_type(decl,
false);
5876 static decl_base_sptr
5877 handle_namespace_decl(reader& rdr,
5879 bool add_to_current_scope)
5882 add_to_current_scope);
5891 static decl_base_sptr
5892 handle_qualified_type_decl(reader& rdr,
5894 bool add_to_current_scope)
5896 qualified_type_def_sptr decl =
5897 build_qualified_type_decl(rdr, node,
5898 add_to_current_scope);
5899 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
5900 if (decl && decl->get_scope())
5901 rdr.maybe_canonicalize_type(decl,
false);
5910 static decl_base_sptr
5911 handle_pointer_type_def(reader& rdr,
5913 bool add_to_current_scope)
5916 add_to_current_scope);
5917 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
5918 if (decl && decl->get_scope())
5919 rdr.maybe_canonicalize_type(decl,
false);
5928 static decl_base_sptr
5929 handle_reference_type_def(reader& rdr,
5931 bool add_to_current_scope)
5934 add_to_current_scope);
5935 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
5936 if (decl && decl->get_scope())
5937 rdr.maybe_canonicalize_type(decl,
false);
5946 static type_base_sptr
5947 handle_function_type(reader& rdr,
5949 bool add_to_current_scope)
5952 add_to_current_scope);
5953 MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
5954 rdr.maybe_canonicalize_type(type,
true);
5963 static decl_base_sptr
5964 handle_array_type_def(reader& rdr,
5966 bool add_to_current_scope)
5969 add_to_current_scope);
5970 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
5971 rdr.maybe_canonicalize_type(decl,
false);
5978 static decl_base_sptr
5979 handle_enum_type_decl(reader& rdr,
5981 bool add_to_current_scope)
5984 build_enum_type_decl_if_not_suppressed(rdr, node,
5985 add_to_current_scope);
5986 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
5987 if (decl && decl->get_scope())
5988 rdr.maybe_canonicalize_type(decl,
false);
5995 static decl_base_sptr
5996 handle_typedef_decl(reader& rdr,
5998 bool add_to_current_scope)
6001 add_to_current_scope);
6002 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6003 if (decl && decl->get_scope())
6004 rdr.maybe_canonicalize_type(decl,
false);
6016 static decl_base_sptr
6017 handle_var_decl(reader& rdr,
6019 bool add_to_current_scope)
6021 decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6022 add_to_current_scope);
6023 rdr.maybe_add_var_to_exported_decls(
is_var_decl(decl).get());
6033 static decl_base_sptr
6034 handle_function_decl(reader& rdr,
6036 bool add_to_current_scope)
6038 return build_function_decl_if_not_suppressed(rdr, node,
class_decl_sptr(),
6039 add_to_current_scope);
6048 static decl_base_sptr
6049 handle_class_decl(reader& rdr,
6051 bool add_to_current_scope)
6054 build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6055 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6056 if (decl && decl->get_scope())
6057 rdr.maybe_canonicalize_type(decl,
false);
6067 static decl_base_sptr
6068 handle_union_decl(reader& rdr,
6070 bool add_to_current_scope)
6072 union_decl_sptr decl =
6073 build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6074 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6075 if (decl && decl->get_scope())
6076 rdr.maybe_canonicalize_type(decl,
false);
6086 static decl_base_sptr
6087 handle_function_tdecl(reader& rdr,
6089 bool add_to_current_scope)
6092 add_to_current_scope);
6101 static decl_base_sptr
6102 handle_class_tdecl(reader& rdr,
6104 bool add_to_current_scope)
6107 add_to_current_scope);
6124 return read_translation_unit_from_input(read_rdr);
6126 template<
typename T>
6127 struct array_deleter
6149 corpus_sptr corp = result->corpus();
6150 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6151 #ifdef WITH_DEBUG_SELF_COMPARISON
6152 if (env.self_comparison_debug_is_on())
6153 env.set_self_comparison_debug_input(result->corpus());
6155 result->set_path(path);
6172 corpus_sptr corp = result->corpus();
6173 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6174 #ifdef WITH_DEBUG_SELF_COMPARISON
6175 if (env.self_comparison_debug_is_on())
6176 env.set_self_comparison_debug_input(result->corpus());
6199 return rdr->read_corpus(sts);
6221 corpus_sptr corp = rdr->read_corpus(sts);
6227 #ifdef WITH_DEBUG_SELF_COMPARISON
6246 load_canonical_type_ids(fe_iface& iface,
const string &file_path)
6248 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
6250 xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
6254 xmlNodePtr node = xmlDocGetRootElement(doc);
6277 if (xmlStrcmp(node->name, (xmlChar*)
"abixml-types-check"))
6280 for (node = xmlFirstElementChild(node);
6282 node = xmlNextElementSibling(node))
6284 if (xmlStrcmp(node->name, (xmlChar*)
"type"))
6287 string id, canonical_address;
6288 xmlNodePtr data = xmlFirstElementChild(node);
6289 if (data && !xmlStrcmp(data->name, (xmlChar*)
"id")
6290 && data->children && xmlNodeIsText(data->children))
6291 id = (
char*) XML_GET_CONTENT(data->children);
6293 data = xmlNextElementSibling(data);
6294 if (data && !xmlStrcmp(data->name, (xmlChar*)
"c")
6295 && data->children && xmlNodeIsText(data->children))
6297 canonical_address = (
char*) XML_GET_CONTENT(data->children);
6298 std::stringstream s;
6299 s << canonical_address;
6307 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.
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 ...
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 ...
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'.
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_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_buffer(const string &buffer, environment &env)
Parse an ABI instrumentation file (in XML format) from an in-memory buffer.
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.
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.
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.
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...
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
array_type_def * is_array_type(const type_or_decl_base *type)
Test if a type is an array_type_def.
reference_type_def * is_reference_type(type_or_decl_base *t)
Test whether a type is a reference_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.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
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.
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< 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.
pointer_type_def * is_pointer_type(type_or_decl_base *t)
Test whether a type is 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.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
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.
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.
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.
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
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.