15 #include <libxml/xmlreader.h>
16 #include <libxml/xmlstring.h>
23 #include <unordered_map>
27 #include "abg-internal.h"
31 ABG_BEGIN_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 static bool read_type_id_string(xmlNodePtr,
string&);
66 #ifdef WITH_DEBUG_SELF_COMPARISON
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);
101 static decl_base_sptr
102 build_ir_node_for_void_type(reader& rdr);
104 static decl_base_sptr
105 build_ir_node_for_void_pointer_type(reader& rdr);
118 typedef unordered_map<string, vector<type_base_sptr> >
121 typedef unordered_map<string,
122 vector<type_base_sptr> >::const_iterator
125 typedef unordered_map<string,
126 vector<type_base_sptr> >::iterator
129 typedef unordered_map<string,
130 shared_ptr<function_tdecl> >::const_iterator
131 const_fn_tmpl_map_it;
133 typedef unordered_map<string,
134 shared_ptr<class_tdecl> >::const_iterator
135 const_class_tmpl_map_it;
137 typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
139 typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
141 friend vector<type_base_sptr>* get_types_from_type_id(reader&,
144 friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
145 get_artifact_used_by_relation_map(reader& rdr);
148 types_map_type m_types_map;
149 unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
150 unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
151 vector<type_base_sptr> m_types_to_canonicalize;
152 string_xml_node_map m_id_xml_node_map;
153 xml_node_decl_base_sptr_map m_xml_node_decl_map;
155 xmlNodePtr m_corp_node;
156 deque<shared_ptr<decl_base> > m_decls_stack;
157 bool m_tracking_non_reachable_types;
158 bool m_drop_undefined_syms;
159 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
161 vector<type_or_decl_base*>> m_artifact_used_by_map;
172 m_tracking_non_reachable_types(),
173 m_drop_undefined_syms()
182 {
return options().do_log;}
190 tracking_non_reachable_types()
const
191 {
return m_tracking_non_reachable_types;}
199 tracking_non_reachable_types(
bool f)
200 {m_tracking_non_reachable_types = f;}
208 drop_undefined_syms()
const
209 {
return m_drop_undefined_syms;}
216 drop_undefined_syms(
bool f)
217 {m_drop_undefined_syms = f;}
224 {
return corpus_path();}
230 set_path(
const string& s)
240 {
return options().env;}
246 get_environment()
const
247 {
return const_cast<reader*
>(
this)->get_environment();}
250 get_libxml_reader()
const
259 get_corpus_node()
const
260 {
return m_corp_node;}
268 set_corpus_node(xmlNodePtr node)
269 {m_corp_node = node;}
271 const string_xml_node_map&
272 get_id_xml_node_map()
const
273 {
return m_id_xml_node_map;}
276 get_id_xml_node_map()
277 {
return m_id_xml_node_map;}
280 clear_id_xml_node_map()
281 {get_id_xml_node_map().clear();}
283 const xml_node_decl_base_sptr_map&
284 get_xml_node_decl_map()
const
285 {
return m_xml_node_decl_map;}
287 xml_node_decl_base_sptr_map&
288 get_xml_node_decl_map()
289 {
return m_xml_node_decl_map;}
292 map_xml_node_to_decl(xmlNodePtr node,
296 get_xml_node_decl_map()[node]= decl;
300 get_decl_for_xml_node(xmlNodePtr node)
const
302 xml_node_decl_base_sptr_map::const_iterator i =
303 get_xml_node_decl_map().find(node);
305 if (i != get_xml_node_decl_map().end())
308 return decl_base_sptr();
312 clear_xml_node_decl_map()
313 {get_xml_node_decl_map().clear();}
316 map_id_and_node (
const string&
id,
322 string_xml_node_map::iterator i = get_id_xml_node_map().find(
id);
323 if (i != get_id_xml_node_map().end())
325 bool is_declaration =
false;
326 read_is_declaration_only(node, is_declaration);
331 get_id_xml_node_map()[id] = node;
335 get_xml_node_from_id(
const string&
id)
const
337 string_xml_node_map::const_iterator i = get_id_xml_node_map().find(
id);
338 if (i != get_id_xml_node_map().end())
344 get_scope_for_node(xmlNodePtr node,
348 get_scope_for_node(xmlNodePtr node);
351 get_scope_ptr_for_node(xmlNodePtr node);
356 build_or_get_type_decl(
const string&
id,
371 get_type_decl(
const string&
id)
const
373 const_types_map_it i = m_types_map.find(
id);
374 if (i == m_types_map.end())
375 return type_base_sptr();
376 type_base_sptr result = i->second[0];
392 const vector<type_base_sptr>*
393 get_all_type_decls(
const string&
id)
const
395 const_types_map_it i = m_types_map.find(
id);
396 if (i == m_types_map.end())
413 shared_ptr<function_tdecl>
414 get_fn_tmpl_decl(
const string&
id)
const
416 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
417 if (i == m_fn_tmpl_map.end())
418 return shared_ptr<function_tdecl>();
432 shared_ptr<class_tdecl>
433 get_class_tmpl_decl(
const string&
id)
const
435 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
436 if (i == m_class_tmpl_map.end())
437 return shared_ptr<class_tdecl>();
443 get_cur_scope()
const
445 shared_ptr<decl_base> cur_decl = get_cur_decl();
447 if (dynamic_cast<scope_decl*>(cur_decl.get()))
449 return dynamic_pointer_cast<
scope_decl>(cur_decl).
get();
453 return cur_decl->get_scope();
462 if (m_decls_stack.empty())
463 return shared_ptr<decl_base>(static_cast<decl_base*>(0));
464 return m_decls_stack.back();
471 for (deque<shared_ptr<decl_base> >::reverse_iterator i =
472 m_decls_stack.rbegin();
473 i != m_decls_stack.rend();
475 if (decl_base_sptr d = *i)
480 return global->get_translation_unit();
491 type_is_from_translation_unit(type_base_sptr type)
503 push_decl(decl_base_sptr d)
505 m_decls_stack.push_back(d);
511 if (m_decls_stack.empty())
512 return decl_base_sptr();
514 shared_ptr<decl_base> t = get_cur_decl();
515 m_decls_stack.pop_back();
542 return dynamic_pointer_cast<
scope_decl>(d) == scope;
555 {m_decls_stack.clear();}
559 {m_types_map.clear();}
564 clear_types_to_canonicalize()
565 {m_types_to_canonicalize.clear();}
581 types_equal(type_base_sptr t1, type_base_sptr t2)
583 if (t1.get() == t2.get())
602 key_type_decl(
const type_base_sptr& type,
const string&
id)
607 m_types_map[id].push_back(type);
622 key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
627 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
628 if (i != m_fn_tmpl_map.end())
631 m_fn_tmpl_map[id] = fn_tmpl_decl;
645 key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
650 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
651 if (i != m_class_tmpl_map.end())
654 m_class_tmpl_map[id] = class_tmpl_decl;
658 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
668 record_artifact_as_used_by(type_or_decl_base* used,
669 type_or_decl_base* user)
671 if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
673 vector<type_or_decl_base*> v;
674 m_artifact_used_by_map[used] = v;
676 m_artifact_used_by_map[used].push_back(user);
690 {record_artifact_as_used_by(used.get(), user.get());}
702 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
706 type_base_sptr t = pit->get_type();
707 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
716 {record_artifacts_as_used_in_fn_decl(fn.get());}
722 record_artifacts_as_used_in_fn_type(
const function_type *fn_type)
728 record_artifact_as_used_by(t.get(),
const_cast<function_type*
>(fn_type));
732 type_base_sptr t = pit->get_type();
733 record_artifact_as_used_by(t.get(),
743 {record_artifacts_as_used_in_fn_type(fn_type.get());}
755 push_decl_to_scope(
const decl_base_sptr& decl, xmlNodePtr node)
758 scope = get_scope_ptr_for_node(node);
759 return push_decl_to_scope(decl, scope);
768 push_decl_to_scope(
const decl_base_sptr& decl,
774 if (!decl->get_translation_unit())
793 push_and_key_type_decl(
const type_base_sptr& t,
800 push_decl_to_scope(decl, scope);
801 if (!t->get_translation_unit())
804 key_type_decl(t,
id);
819 push_and_key_type_decl(
const type_base_sptr& t,
820 const xmlNodePtr node,
821 bool add_to_current_scope)
824 if (!read_type_id_string(node,
id))
829 scope = get_scope_ptr_for_node(node);
830 return push_and_key_type_decl(t,
id, scope);
839 get_exported_decls_builder()
853 corpus_is_suppressed_by_soname_or_filename(
const string& soname,
854 const string& filename)
860 for (suppressions_type::const_iterator s = suppressions().begin();
861 s != suppressions().end();
874 clear_per_translation_unit_data()
881 clear_per_corpus_data()
884 clear_types_to_canonicalize();
885 clear_xml_node_decl_map();
886 clear_id_xml_node_map();
890 #ifdef WITH_DEBUG_SELF_COMPARISON
910 maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
912 if (!get_environment().self_comparison_debug_is_on()
913 || get_environment().get_type_id_canonical_type_map().empty())
925 get_environment().get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));
927 if (!type_id.empty())
932 auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
933 if (j == get_environment().get_type_id_canonical_type_map().end())
935 if (t->get_naked_canonical_type())
936 std::cerr <<
"error: no type with type-id: '"
938 <<
"' could be read back from the typeid file\n";
941 != reinterpret_cast<uintptr_t>(t->get_canonical_type().get()))
946 std::cerr <<
"error: canonical type for type '"
947 << t->get_pretty_representation(
true,
949 <<
"' of type-id '" << type_id
950 <<
"' changed from '" << std::hex
951 << j->second <<
"' to '" << std::hex
952 <<
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get())
966 maybe_canonicalize_type(type_base_sptr t,
967 bool force_delay =
false)
972 if (t->get_canonical_type())
1007 #ifdef WITH_DEBUG_SELF_COMPARISON
1008 maybe_check_abixml_canonical_type_stability(t);
1018 schedule_type_for_late_canonicalizing(t);
1027 schedule_type_for_late_canonicalizing(type_base_sptr t)
1028 {m_types_to_canonicalize.push_back(t);}
1034 perform_late_type_canonicalizing()
1036 for (vector<type_base_sptr>::iterator i = m_types_to_canonicalize.begin();
1037 i != m_types_to_canonicalize.end();
1041 #ifdef WITH_DEBUG_SELF_COMPARISON
1042 maybe_check_abixml_canonical_type_stability(*i);
1060 const string& fn_name)
const
1064 return suppression_matches_function_name(*s, fn_name);
1077 corpus_sptr corp =
corpus();
1079 if (!s.priv_->matches_soname(corp->get_soname()))
1086 if (!s.priv_->matches_binary_name(corp->get_path()))
1109 const string& fn_name)
const
1115 return suppr::suppression_matches_function_name(s, fn_name);
1131 const string& type_name,
1132 const location& type_location)
const
1141 virtual ir::corpus_sptr
1152 bool call_reader_next =
false;
1154 xmlNodePtr node = get_corpus_node();
1161 status = advance_cursor (*
this);
1164 BAD_CAST(
"abi-corpus")))
1167 #ifdef WITH_DEBUG_SELF_COMPARISON
1168 if (get_environment().self_comparison_debug_is_on())
1169 get_environment().set_self_comparison_debug_input(
corpus());
1173 clear_per_corpus_data();
1179 handle_version_attribute(xml_reader, corp);
1186 path =
reinterpret_cast<char*
>(path_str.get());
1191 xml::xml_char_sptr architecture_str =
1193 if (architecture_str)
1195 (reinterpret_cast<char*>(architecture_str.get()));
1197 xml::xml_char_sptr soname_str =
1203 soname =
reinterpret_cast<char*
>(soname_str.get());
1215 if ((!soname.empty() || !path.empty())
1216 && corpus_is_suppressed_by_soname_or_filename(soname, path))
1219 node = xmlTextReaderExpand(xml_reader.get());
1223 call_reader_next =
true;
1227 #ifdef WITH_DEBUG_SELF_COMPARISON
1228 if (get_environment().self_comparison_debug_is_on())
1229 get_environment().set_self_comparison_debug_input(
corpus());
1233 clear_per_corpus_data();
1240 corp.
set_path(reinterpret_cast<char*>(path_str.get()));
1242 xml::xml_char_sptr architecture_str =
1244 if (architecture_str)
1246 (reinterpret_cast<char*>(architecture_str.get()));
1248 xml::xml_char_sptr soname_str =
1251 corp.
set_soname(reinterpret_cast<char*>(soname_str.get()));
1259 xmlNodePtr n = xmlFirstElementChild(node);
1265 walk_xml_node_to_map_type_ids(*
this, node);
1268 vector<string> needed;
1269 read_elf_needed_from_input(*
this, needed);
1270 if (!needed.empty())
1276 read_symbol_db_from_input(*
this, fn_sym_db, var_sym_db);
1282 get_environment().canonicalization_is_done(
false);
1285 while (read_translation_unit_from_input(*
this))
1288 if (tracking_non_reachable_types())
1290 bool is_tracking_non_reachable_types =
false;
1291 read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1295 == is_tracking_non_reachable_types);
1302 std::cerr <<
"perform late type canonicalization ...\n";
1306 perform_late_type_canonicalizing();
1311 std::cerr <<
"late type canonicalization DONE@"
1313 <<
":" << t <<
"\n";
1316 get_environment().canonicalization_is_done(
true);
1318 if (call_reader_next)
1322 xmlTextReaderNext(xml_reader.get());
1330 node = get_corpus_node();
1331 node = xmlNextElementSibling(node);
1334 node = get_corpus_node();
1336 node = xmlNextElementSibling(node->parent);
1338 set_corpus_node(node);
1346 typedef shared_ptr<reader> reader_sptr;
1348 static int advance_cursor(reader&);
1352 static bool read_symbol_db_from_input(reader&,
1355 static bool read_location(
const reader&, xmlNodePtr,
location&);
1356 static bool read_artificial_location(
const reader&,
1358 static bool maybe_set_artificial_location(
const reader&,
1364 static bool read_size_and_alignment(xmlNodePtr,
size_t&,
size_t&);
1365 static bool read_static(xmlNodePtr,
bool&);
1366 static bool read_offset_in_bits(xmlNodePtr,
size_t&);
1367 static bool read_cdtor_const(xmlNodePtr,
bool&,
bool&,
bool&);
1368 static bool read_is_virtual(xmlNodePtr,
bool&);
1369 static bool read_is_struct(xmlNodePtr,
bool&);
1370 static bool read_is_anonymous(xmlNodePtr,
bool&);
1373 static bool read_elf_symbol_visibility(xmlNodePtr,
1377 build_namespace_decl(reader&,
const xmlNodePtr,
bool);
1387 build_elf_symbol(reader&,
const xmlNodePtr,
bool);
1390 build_elf_symbol_from_reference(reader&,
const xmlNodePtr);
1393 build_elf_symbol_db(reader&,
const xmlNodePtr,
bool);
1396 build_function_parameter (reader&,
const xmlNodePtr);
1399 build_function_decl(reader&,
const xmlNodePtr,
1400 class_or_union_sptr,
bool,
bool);
1403 build_function_decl_if_not_suppressed(reader&,
const xmlNodePtr,
1404 class_or_union_sptr,
bool,
bool);
1407 function_is_suppressed(
const reader& rdr,
1411 build_var_decl_if_not_suppressed(reader&,
const xmlNodePtr,
bool);
1414 build_var_decl(reader&,
const xmlNodePtr,
bool);
1417 variable_is_suppressed(
const reader& rdr,
1420 static shared_ptr<type_decl>
1421 build_type_decl(reader&,
const xmlNodePtr,
bool);
1423 static qualified_type_def_sptr
1424 build_qualified_type_decl(reader&,
const xmlNodePtr,
bool);
1426 static shared_ptr<pointer_type_def>
1427 build_pointer_type_def(reader&,
const xmlNodePtr,
bool);
1429 static shared_ptr<reference_type_def>
1430 build_reference_type_def(reader&,
const xmlNodePtr,
bool);
1432 static shared_ptr<function_type>
1433 build_function_type(reader&,
const xmlNodePtr,
bool);
1436 build_subrange_type(reader&,
const xmlNodePtr,
bool);
1439 build_array_type_def(reader&,
const xmlNodePtr,
bool);
1442 build_enum_type_decl(reader&,
const xmlNodePtr,
bool);
1444 static shared_ptr<typedef_decl>
1445 build_typedef_decl(reader&,
const xmlNodePtr,
bool);
1448 build_class_decl(reader&,
const xmlNodePtr,
bool);
1450 static union_decl_sptr
1451 build_union_decl(reader&,
const xmlNodePtr,
bool);
1453 static shared_ptr<function_tdecl>
1454 build_function_tdecl(reader&,
const xmlNodePtr,
bool);
1456 static shared_ptr<class_tdecl>
1457 build_class_tdecl(reader&,
const xmlNodePtr,
bool);
1460 build_type_tparameter(reader&,
const xmlNodePtr,
1464 build_type_composition(reader&,
const xmlNodePtr,
1468 build_non_type_tparameter(reader&,
const xmlNodePtr,
1472 build_template_tparameter(reader&,
const xmlNodePtr,
1476 build_template_parameter(reader&,
const xmlNodePtr,
1483 static shared_ptr<type_base>
1484 build_type(reader&,
const xmlNodePtr,
bool);
1488 static decl_base_sptr handle_type_decl(reader&, xmlNodePtr,
bool);
1489 static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr,
bool);
1490 static decl_base_sptr handle_qualified_type_decl(reader&,
1492 static decl_base_sptr handle_pointer_type_def(reader&,
1494 static decl_base_sptr handle_reference_type_def(reader&,
1496 static type_base_sptr handle_function_type(reader&,
1498 static decl_base_sptr handle_array_type_def(reader&,
1500 static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr,
bool);
1501 static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr,
bool);
1502 static decl_base_sptr handle_var_decl(reader&, xmlNodePtr,
bool);
1503 static decl_base_sptr handle_function_decl(reader&, xmlNodePtr,
bool);
1504 static decl_base_sptr handle_class_decl(reader&, xmlNodePtr,
bool);
1505 static decl_base_sptr handle_union_decl(reader&, xmlNodePtr,
bool);
1506 static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr,
bool);
1507 static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr,
bool);
1509 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1510 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1511 rdr.record_artifact_as_used_by(used,user)
1512 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1513 rdr.record_artifacts_as_used_in_fn_decl(fn)
1514 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1515 rdr.record_artifacts_as_used_in_fn_type(fn_type)
1517 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1518 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1519 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1542 xmlNodePtr parent = node->parent;
1545 && (xmlStrEqual(parent->name, BAD_CAST(
"data-member"))
1546 || xmlStrEqual(parent->name, BAD_CAST(
"member-type"))
1547 || xmlStrEqual(parent->name, BAD_CAST(
"member-function"))
1548 || xmlStrEqual(parent->name, BAD_CAST(
"member-template"))
1549 || xmlStrEqual(parent->name, BAD_CAST(
"template-parameter-type-composition"))
1550 || xmlStrEqual(parent->name, BAD_CAST(
"array-type-def"))))
1552 read_access(parent, access);
1553 parent = parent->parent;
1556 xml_node_decl_base_sptr_map::const_iterator i =
1557 get_xml_node_decl_map().find(parent);
1558 if (i == get_xml_node_decl_map().end())
1560 if (xmlStrEqual(parent->name, BAD_CAST(
"abi-instr")))
1563 get_or_read_and_add_translation_unit(*
this, parent);
1564 return tu->get_global_scope();
1569 push_decl(parent_scope);
1571 (handle_element_node(*
this, parent,
true));
1573 pop_scope_or_abort(parent_scope);
1576 scope = dynamic_pointer_cast<
scope_decl>(i->second);
1591 reader::get_scope_for_node(xmlNodePtr node)
1594 return get_scope_for_node(node, access);
1607 reader::get_scope_ptr_for_node(xmlNodePtr node)
1627 type_base_sptr t = get_type_decl(
id);
1631 xmlNodePtr n = get_xml_node_from_id(
id);
1636 if (add_decl_to_scope)
1638 scope = get_scope_for_node(n, access);
1646 if ((t = get_type_decl(
id)))
1652 t = build_type(*
this, n, add_decl_to_scope);
1663 if (add_decl_to_scope)
1664 pop_scope_or_abort(scope);
1666 maybe_canonicalize_type(t, !add_decl_to_scope);
1678 advance_cursor(reader& rdr)
1681 return xmlTextReaderRead(reader.get());
1693 walk_xml_node_to_map_type_ids(reader& rdr,
1696 xmlNodePtr n = node;
1698 if (!n || n->type != XML_ELEMENT_NODE)
1703 string id = CHAR_STR(s);
1704 rdr.map_id_and_node(
id, n);
1707 for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1708 walk_xml_node_to_map_type_ids(rdr, n);
1714 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1716 if (!rdr.corpus()->is_empty())
1719 xml::xml_char_sptr addrsize_str =
1723 char address_size = atoi(reinterpret_cast<char*>(addrsize_str.get()));
1729 tu.
set_path(reinterpret_cast<char*>(path_str.get()));
1731 xml::xml_char_sptr comp_dir_path_str =
1733 if (comp_dir_path_str)
1735 (comp_dir_path_str.get()));
1740 (reinterpret_cast<char*>(language_str.get())));
1748 if (rdr.get_id_xml_node_map().empty()
1750 walk_xml_node_to_map_type_ids(rdr, node);
1752 for (xmlNodePtr n = xmlFirstElementChild(node);
1754 n = xmlNextElementSibling(n))
1755 handle_element_node(rdr, n,
true);
1763 rdr.clear_per_translation_unit_data();
1782 get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1784 corpus_sptr corp = rdr.corpus();
1792 tu_path =
reinterpret_cast<char*
>(path_str.get());
1795 if (corp && !corp->is_empty())
1796 tu = corp->find_translation_unit(tu_path);
1803 if (corp && !corp->is_empty())
1806 if (read_translation_unit(rdr, *tu, node))
1821 read_translation_unit_from_input(
fe_iface& iface)
1825 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1827 xmlNodePtr node = rdr.get_corpus_node();
1838 status = advance_cursor (rdr);
1841 BAD_CAST(
"abi-instr")))
1844 node = xmlTextReaderExpand(reader.get());
1851 for (xmlNodePtr n = rdr.get_corpus_node();
1853 n = xmlNextElementSibling(n))
1855 if (!xmlStrEqual(n->name, BAD_CAST(
"abi-instr")))
1865 tu = get_or_read_and_add_translation_unit(rdr, node);
1867 if (rdr.get_corpus_node())
1873 node = xmlNextElementSibling(node);
1874 rdr.set_corpus_node(node);
1898 read_symbol_db_from_input(reader& rdr,
1906 if (!rdr.get_corpus_node())
1912 status = advance_cursor (rdr);
1917 bool has_fn_syms =
false, has_var_syms =
false;
1919 BAD_CAST(
"elf-function-symbols")))
1922 BAD_CAST(
"elf-variable-symbols")))
1923 has_var_syms =
true;
1927 xmlNodePtr node = xmlTextReaderExpand(reader.get());
1932 fn_symdb = build_elf_symbol_db(rdr, node,
true);
1933 else if (has_var_syms)
1934 var_symdb = build_elf_symbol_db(rdr, node,
false);
1936 xmlTextReaderNext(reader.get());
1939 for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
1941 bool has_fn_syms =
false, has_var_syms =
false;
1942 if (xmlStrEqual(n->name, BAD_CAST(
"elf-function-symbols")))
1944 else if (xmlStrEqual(n->name, BAD_CAST(
"elf-variable-symbols")))
1945 has_var_syms =
true;
1948 rdr.set_corpus_node(n);
1953 fn_symdb = build_elf_symbol_db(rdr, n,
true);
1954 else if (has_var_syms)
1955 var_symdb = build_elf_symbol_db(rdr, n,
false);
1974 build_needed(xmlNode* node, vector<string>& needed)
1976 if (!node || !xmlStrEqual(node->name,BAD_CAST(
"elf-needed")))
1979 for (xmlNodePtr n = xmlFirstElementChild(node);
1981 n = xmlNextElementSibling(n))
1983 if (!xmlStrEqual(n->name, BAD_CAST(
"dependency")))
1991 needed.push_back(name);
2007 read_elf_needed_from_input(reader& rdr,
2008 vector<string>& needed)
2014 xmlNodePtr node = 0;
2016 if (rdr.get_corpus_node() == 0)
2021 status = advance_cursor (rdr);
2027 BAD_CAST(
"elf-needed")))
2030 node = xmlTextReaderExpand(reader.get());
2036 for (xmlNodePtr n = rdr.get_corpus_node();
2038 n = xmlNextElementSibling(n))
2040 if (!xmlStrEqual(n->name, BAD_CAST(
"elf-needed")))
2047 bool result =
false;
2050 result = build_needed(node, needed);
2051 node = xmlNextElementSibling(node);
2052 rdr.set_corpus_node(node);
2087 for (suppr::suppressions_type::const_iterator i = supprs.begin();
2090 if ((*i)->get_drops_artifact_from_ir())
2091 rdr.suppressions().push_back(*i);
2106 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2107 rdr.tracking_non_reachable_types(flag);
2110 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2119 vector<type_base_sptr>*
2120 get_types_from_type_id(
fe_iface& iface,
const string& type_id)
2122 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2123 auto it = rdr.m_types_map.find(type_id);
2124 if (it == rdr.m_types_map.end())
2135 unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2136 get_artifact_used_by_relation_map(fe_iface& iface)
2138 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2139 return &rdr.m_artifact_used_by_map;
2159 string version_string;
2164 if (version_string.empty())
2171 corp.set_format_major_version_number(v[0]);
2172 corp.set_format_minor_version_number(v[1]);
2185 corpus_group_sptr nil;
2187 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2196 status = advance_cursor (rdr);
2199 BAD_CAST(
"abi-corpus-group")))
2202 if (!rdr.corpus_group())
2204 corpus_group_sptr g(
new corpus_group(rdr.get_environment(),
2206 g->set_origin(corpus::NATIVE_XML_ORIGIN);
2207 rdr.corpus_group(g);
2210 corpus_group_sptr group = rdr.corpus_group();
2212 handle_version_attribute(reader, *group);
2216 group->set_path(reinterpret_cast<char*>(path_str.get()));
2218 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2222 node = xmlFirstElementChild(node);
2223 rdr.set_corpus_node(node);
2227 while ((corp = rdr.read_corpus(sts)))
2228 rdr.corpus_group()->add_corpus(corp);
2230 xmlTextReaderNext(reader.get());
2232 return rdr.corpus_group();
2294 rdr.perform_late_type_canonicalizing();
2316 rdr.perform_late_type_canonicalizing();
2331 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2333 rdr.options().env.canonicalization_is_done(
false);
2334 rdr.perform_late_type_canonicalizing();
2335 rdr.options().env.canonicalization_is_done(
true);
2348 handle_element_node(reader& rdr, xmlNodePtr node,
2349 bool add_to_current_scope)
2355 ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2356 ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2357 ||(decl = handle_qualified_type_decl(rdr, node,
2358 add_to_current_scope))
2359 ||(decl = handle_pointer_type_def(rdr, node,
2360 add_to_current_scope))
2361 || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2362 || (decl = handle_function_type(rdr, node, add_to_current_scope))
2363 || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2364 || (decl = handle_enum_type_decl(rdr, node,
2365 add_to_current_scope))
2366 || (decl = handle_typedef_decl(rdr, node,
2367 add_to_current_scope))
2368 || (decl = handle_var_decl(rdr, node,
2369 add_to_current_scope))
2370 || (decl = handle_function_decl(rdr, node,
2371 add_to_current_scope))
2372 || (decl = handle_class_decl(rdr, node,
2373 add_to_current_scope))
2374 || (decl = handle_union_decl(rdr, node,
2375 add_to_current_scope))
2376 || (decl = handle_function_tdecl(rdr, node,
2377 add_to_current_scope))
2378 || (decl = handle_class_tdecl(rdr, node,
2379 add_to_current_scope)));
2384 if (rdr.tracking_non_reachable_types())
2386 if (type_base_sptr t =
is_type(decl))
2388 corpus_sptr abi = rdr.corpus();
2390 bool is_non_reachable_type =
false;
2391 read_is_non_reachable_type(node, is_non_reachable_type);
2392 if (!is_non_reachable_type)
2393 abi->record_type_as_reachable_from_public_interfaces(*t);
2408 read_location(
const reader& rdr,
2413 size_t line = 0, column = 0;
2416 file_path = CHAR_STR(f);
2418 if (file_path.empty())
2419 return read_artificial_location(rdr, node, loc);
2422 line = atoi(CHAR_STR(l));
2424 return read_artificial_location(rdr, node, loc);
2427 column = atoi(CHAR_STR(c));
2429 reader& c =
const_cast<reader&
>(rdr);
2430 loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2447 read_artificial_location(
const reader& rdr,
2455 size_t line = 0, column = 0;
2460 file_path =
reinterpret_cast<const char*
>(node->doc->URL);
2462 reader& c =
const_cast<reader&
>(rdr);
2464 c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2466 loc.set_is_artificial(
true);
2486 maybe_set_artificial_location(
const reader& rdr,
2490 if (artefact && !artefact->has_artificial_location())
2493 if (read_artificial_location(rdr, node, l))
2495 artefact->set_artificial_location(l);
2514 string v = CHAR_STR(s);
2517 vis = decl_base::VISIBILITY_DEFAULT;
2518 else if (v ==
"hidden")
2519 vis = decl_base::VISIBILITY_HIDDEN;
2520 else if (v ==
"internal")
2521 vis = decl_base::VISIBILITY_INTERNAL;
2522 else if (v ==
"protected")
2523 vis = decl_base::VISIBILITY_PROTECTED;
2525 vis = decl_base::VISIBILITY_DEFAULT;
2543 string b = CHAR_STR(s);
2546 bind = decl_base::BINDING_GLOBAL;
2547 else if (b ==
"local")
2548 bind = decl_base::BINDING_LOCAL;
2549 else if (b ==
"weak")
2550 bind = decl_base::BINDING_WEAK;
2552 bind = decl_base::BINDING_GLOBAL;
2571 string a = CHAR_STR(s);
2574 access = private_access;
2575 else if (a ==
"protected")
2576 access = protected_access;
2577 else if (a ==
"public")
2578 access = public_access;
2606 read_size_and_alignment(xmlNodePtr node,
2607 size_t& size_in_bits,
2608 size_t& align_in_bits)
2611 bool got_something =
false;
2614 size_in_bits = atoll(CHAR_STR(s));
2615 got_something =
true;
2620 align_in_bits = atoll(CHAR_STR(s));
2621 got_something =
true;
2623 return got_something;
2636 read_static(xmlNodePtr node,
bool& is_static)
2640 string b = CHAR_STR(s);
2641 is_static = b ==
"yes";
2654 read_offset_in_bits(xmlNodePtr node,
2655 size_t& offset_in_bits)
2659 offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2687 read_cdtor_const(xmlNodePtr node,
2688 bool& is_constructor,
2689 bool& is_destructor,
2694 string b = CHAR_STR(s);
2696 is_constructor =
true;
2698 is_constructor =
false;
2705 string b = CHAR_STR(s);
2707 is_destructor =
true;
2709 is_destructor =
false;
2716 string b = CHAR_STR(s);
2737 read_is_declaration_only(xmlNodePtr node,
bool& is_decl_only)
2741 string str = CHAR_STR(s);
2743 is_decl_only =
true;
2745 is_decl_only =
false;
2761 read_is_artificial(xmlNodePtr node,
bool& is_artificial)
2765 string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2766 is_artificial = is_artificial_str ==
"yes";
2785 read_tracking_non_reachable_types(xmlNodePtr node,
2786 bool& tracking_non_reachable_types)
2791 string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2792 tracking_non_reachable_types =
2793 (tracking_non_reachable_types_str ==
"yes")
2812 read_is_non_reachable_type(xmlNodePtr node,
bool& is_non_reachable_type)
2817 string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2818 is_non_reachable_type =
2819 (is_non_reachable_type_str ==
"yes")
2837 read_naming_typedef_id_string(xmlNodePtr node,
string& naming_typedef_id)
2856 read_is_virtual(xmlNodePtr node,
bool& is_virtual)
2860 string str = CHAR_STR(s);
2879 read_is_struct(xmlNodePtr node,
bool& is_struct)
2883 string str = CHAR_STR(s);
2902 read_is_anonymous(xmlNodePtr node,
bool& is_anonymous)
2906 string str = CHAR_STR(s);
2907 is_anonymous = (str ==
"yes");
2984 read_type_id_string(xmlNodePtr node,
string& type_id)
2988 type_id = CHAR_STR(s);
2994 #ifdef WITH_DEBUG_SELF_COMPARISON
3009 maybe_map_type_with_type_id(
const type_base_sptr& t,
3010 const string& type_id)
3015 const environment& env = t->get_environment();
3016 if (!env.self_comparison_debug_is_on()
3020 const_cast<environment&
>(env).
3021 get_pointer_type_id_map()[
reinterpret_cast<uintptr_t
>(t.get())] = type_id;
3040 maybe_map_type_with_type_id(
const type_base_sptr& t,
3046 const environment&env = t->get_environment();
3047 if (!env.self_comparison_debug_is_on()
3052 if (!read_type_id_string(node, type_id) || type_id.empty())
3055 return maybe_map_type_with_type_id(t, type_id);
3069 maybe_set_naming_typedef(reader& rdr,
3071 const decl_base_sptr& decl)
3073 string naming_typedef_id;
3074 read_naming_typedef_id_string(node, naming_typedef_id);
3075 if (!naming_typedef_id.empty())
3078 is_typedef(rdr.build_or_get_type_decl(naming_typedef_id,
true));
3080 decl->set_naming_typedef(naming_typedef);
3100 build_namespace_decl(reader& rdr,
3101 const xmlNodePtr node,
3102 bool add_to_current_scope)
3105 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"namespace-decl")))
3108 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3120 read_location(rdr, node, loc);
3122 const environment& env = rdr.get_environment();
3124 maybe_set_artificial_location(rdr, node, decl);
3125 rdr.push_decl_to_scope(decl,
3126 add_to_current_scope
3127 ? rdr.get_scope_ptr_for_node(node)
3129 rdr.map_xml_node_to_decl(node, decl);
3131 for (xmlNodePtr n = xmlFirstElementChild(node);
3133 n = xmlNextElementSibling(n))
3134 handle_element_node(rdr, n,
true);
3136 rdr.pop_scope_or_abort(decl);
3153 build_elf_symbol(reader& rdr,
const xmlNodePtr node,
3154 bool drop_if_suppressed)
3159 || node->type != XML_ELEMENT_NODE
3160 || !xmlStrEqual(node->name, BAD_CAST(
"elf-symbol")))
3169 size = strtol(CHAR_STR(s), NULL, 0);
3171 bool is_defined =
true;
3176 if (value ==
"true" || value ==
"yes")
3182 bool is_common =
false;
3187 if (value ==
"true" || value ==
"yes")
3193 string version_string;
3197 bool is_default_version =
false;
3202 if (value ==
"true" || value ==
"yes")
3203 is_default_version =
true;
3207 read_elf_symbol_type(node, type);
3210 read_elf_symbol_binding(node, binding);
3213 read_elf_symbol_visibility(node, visibility);
3215 elf_symbol::version version(version_string, is_default_version);
3218 if (drop_if_suppressed && is_suppressed)
3221 const environment& env = rdr.get_environment();
3223 size, name, type, binding,
3224 is_defined, is_common,
3225 version, visibility);
3227 e->set_is_suppressed(is_suppressed);
3230 e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3236 e->set_namespace(ns);
3256 build_elf_symbol_from_reference(reader& rdr,
const xmlNodePtr node)
3275 if (rdr.corpus()->get_symtab())
3278 rdr.corpus()->get_symtab()->lookup_symbol(name);
3280 for (
const auto& symbol : symbols)
3281 if (symbol->get_id_string() == sym_id)
3301 build_elf_symbol_db(reader& rdr,
3302 const xmlNodePtr node,
3312 && !xmlStrEqual(node->name, BAD_CAST(
"elf-function-symbols")))
3316 && !xmlStrEqual(node->name, BAD_CAST(
"elf-variable-symbols")))
3319 rdr.set_corpus_node(node);
3321 typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3322 xml_node_ptr_elf_symbol_sptr_map_type;
3323 xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3326 for (xmlNodePtr n = xmlFirstElementChild(node);
3328 n = xmlNextElementSibling(n))
3329 if ((sym = build_elf_symbol(rdr, n,
false)))
3331 id_sym_map[sym->get_id_string()] = sym;
3332 xml_node_ptr_elf_symbol_map[n] = sym;
3335 if (id_sym_map.empty())
3339 string_elf_symbols_map_type::iterator it;
3340 for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3341 i != id_sym_map.end();
3343 (*map)[i->second->get_name()].push_back(i->second);
3346 for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3347 xml_node_ptr_elf_symbol_map.begin();
3348 x != xml_node_ptr_elf_symbol_map.end();
3353 string alias_id = CHAR_STR(s);
3356 std::vector<std::string> elems;
3357 std::stringstream aliases(alias_id);
3359 while (std::getline(aliases, item,
','))
3360 elems.push_back(item);
3361 for (std::vector<string>::iterator alias = elems.begin();
3362 alias != elems.end(); ++alias)
3364 string_elf_symbol_sptr_map_type::const_iterator i =
3365 id_sym_map.find(*alias);
3369 x->second->get_main_symbol()->add_alias(i->second);
3382 static shared_ptr<function_decl::parameter>
3383 build_function_parameter(reader& rdr,
const xmlNodePtr node)
3385 shared_ptr<function_decl::parameter> nil;
3387 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"parameter")))
3390 bool is_variadic =
false;
3391 string is_variadic_str;
3395 is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
3396 is_variadic = is_variadic_str ==
"yes";
3399 bool is_artificial =
false;
3400 read_is_artificial(node, is_artificial);
3404 type_id = CHAR_STR(a);
3406 type_base_sptr type;
3408 type = rdr.get_environment().get_variadic_parameter_type();
3412 type = rdr.build_or_get_type_decl(type_id,
true);
3421 read_location(rdr, node, loc);
3424 (
new function_decl::parameter(type, name, loc,
3425 is_variadic, is_artificial));
3453 build_function_decl(reader& rdr,
3454 const xmlNodePtr node,
3455 class_or_union_sptr as_method_decl,
3456 bool add_to_current_scope,
3457 bool add_to_exported_decls)
3461 if (!xmlStrEqual(node->name, BAD_CAST(
"function-decl")))
3468 string mangled_name;
3473 && !mangled_name.empty()
3474 && as_method_decl->find_member_function_sptr(mangled_name))
3477 as_method_decl->find_member_function_sptr(mangled_name);
3484 inline_prop = CHAR_STR(s);
3485 bool declared_inline = inline_prop ==
"yes";
3488 read_visibility(node, vis);
3491 read_binding(node, bind);
3493 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3494 read_size_and_alignment(node, size, align);
3497 read_location(rdr, node, loc);
3499 const environment& env = rdr.get_environment();
3501 std::vector<function_decl::parameter_sptr> parms;
3502 type_base_sptr return_type = env.get_void_type();
3504 for (xmlNodePtr n = xmlFirstElementChild(node);
3506 n = xmlNextElementSibling(n))
3508 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
3511 build_function_parameter(rdr, n))
3514 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
3519 type_id = CHAR_STR(s);
3520 if (!type_id.empty())
3521 return_type = rdr.build_or_get_type_decl(type_id,
true);
3526 ?
new method_type(return_type, as_method_decl,
3529 :
new function_type(return_type,
3530 parms, size, align));
3534 fn_type->set_is_artificial(
true);
3537 ?
new method_decl (name, fn_type,
3538 declared_inline, loc,
3539 mangled_name, vis, bind)
3540 :
new function_decl(name, fn_type,
3541 declared_inline, loc,
3545 maybe_set_artificial_location(rdr, node, fn_decl);
3546 rdr.push_decl_to_scope(fn_decl,
3547 add_to_current_scope
3548 ? rdr.get_scope_ptr_for_node(node)
3550 RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3554 fn_decl->set_symbol(sym);
3556 if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3557 fn_decl->set_is_in_public_symbol_table(
true);
3559 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3561 rdr.maybe_canonicalize_type(fn_type, !add_to_current_scope);
3563 if (add_to_exported_decls)
3564 rdr.maybe_add_fn_to_exported_decls(fn_decl.get());
3595 build_function_decl_if_not_suppressed(reader& rdr,
3596 const xmlNodePtr node,
3597 class_or_union_sptr as_method_decl,
3598 bool add_to_current_scope,
3599 bool add_to_exported_decls)
3603 if (function_is_suppressed(rdr, node))
3609 fn = build_function_decl(rdr, node, as_method_decl,
3610 add_to_current_scope,
3611 add_to_exported_decls);
3627 function_is_suppressed(
const reader& rdr, xmlNodePtr node)
3633 string flinkage_name;
3637 scope_decl* scope = rdr.get_cur_scope();
3656 type_is_suppressed(
const reader& rdr, xmlNodePtr node)
3662 location type_location;
3663 read_location(rdr, node, type_location);
3665 scope_decl* scope = rdr.get_cur_scope();
3669 bool type_is_private =
false;
3688 build_var_decl_if_not_suppressed(reader& rdr,
3689 const xmlNodePtr node,
3690 bool add_to_current_scope)
3693 if (!variable_is_suppressed(rdr, node))
3694 var = build_var_decl(rdr, node, add_to_current_scope);
3707 variable_is_suppressed(
const reader& rdr, xmlNodePtr node)
3713 string linkage_name;
3717 scope_decl* scope = rdr.get_cur_scope();
3735 variable_is_suppressed(
const reader& rdr,
3736 const scope_decl* scope,
3741 v.get_linkage_name());
3752 static shared_ptr<var_decl>
3753 build_var_decl(reader& rdr,
3754 const xmlNodePtr node,
3755 bool add_to_current_scope)
3757 shared_ptr<var_decl> nil;
3759 if (!xmlStrEqual(node->name, BAD_CAST(
"var-decl")))
3768 type_id = CHAR_STR(s);
3769 type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
3773 string mangled_name;
3778 read_visibility(node, vis);
3781 read_binding(node, bind);
3784 read_location(rdr, node, locus);
3787 locus, mangled_name,
3789 maybe_set_artificial_location(rdr, node, decl);
3793 decl->set_symbol(sym);
3795 rdr.push_decl_to_scope(decl,
3796 add_to_current_scope
3797 ? rdr.get_scope_ptr_for_node(node)
3799 if (add_to_current_scope)
3803 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
3806 if (decl->get_symbol() && decl->get_symbol()->is_public())
3807 decl->set_is_in_public_symbol_table(
true);
3817 static decl_base_sptr
3818 build_ir_node_for_void_type(reader& rdr)
3820 const environment& env = rdr.get_environment();
3822 type_base_sptr t = env.get_void_type();
3826 return type_declaration;
3840 static decl_base_sptr
3841 build_ir_node_for_void_pointer_type(reader& rdr)
3843 const environment& env = rdr.get_environment();
3845 type_base_sptr t = env.get_void_pointer_type();
3849 return type_declaration;
3864 build_type_decl(reader& rdr,
3865 const xmlNodePtr node,
3866 bool add_to_current_scope)
3868 shared_ptr<type_decl> nil;
3870 if (!xmlStrEqual(node->name, BAD_CAST(
"type-decl")))
3873 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3889 size_t size_in_bits= 0;
3891 size_in_bits = atoi(CHAR_STR(s));
3893 size_t alignment_in_bits = 0;
3895 alignment_in_bits = atoi(CHAR_STR(s));
3897 bool is_decl_only =
false;
3898 read_is_declaration_only(node, is_decl_only);
3901 read_location(rdr, node, loc);
3903 bool is_anonymous =
false;
3904 read_is_anonymous(node, is_anonymous);
3906 if (type_base_sptr d = rdr.get_type_decl(
id))
3914 ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
3915 ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
3919 const environment& env = rdr.get_environment();
3921 if (name == env.get_variadic_parameter_type_name())
3922 decl =
is_type_decl(env.get_variadic_parameter_type());
3923 else if (name ==
"void")
3926 decl.reset(
new type_decl(env, name, size_in_bits,
3927 alignment_in_bits, loc));
3928 maybe_set_artificial_location(rdr, node, decl);
3929 decl->set_is_anonymous(is_anonymous);
3930 decl->set_is_declaration_only(is_decl_only);
3931 if (rdr.push_and_key_type_decl(decl, node, add_to_current_scope))
3933 rdr.map_xml_node_to_decl(node, decl);
3951 static qualified_type_def_sptr
3952 build_qualified_type_decl(reader& rdr,
3953 const xmlNodePtr node,
3954 bool add_to_current_scope)
3956 qualified_type_def_sptr nil;
3957 if (!xmlStrEqual(node->name, BAD_CAST(
"qualified-type-def")))
3960 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3962 qualified_type_def_sptr result =
3963 dynamic_pointer_cast<qualified_type_def>(d);
3975 read_location(rdr, node, loc);
3980 const_str = CHAR_STR(s);
3981 bool const_cv = const_str ==
"yes";
3983 string volatile_str;
3985 volatile_str = CHAR_STR(s);
3986 bool volatile_cv = volatile_str ==
"yes";
3988 string restrict_str;
3990 restrict_str = CHAR_STR(s);
3991 bool restrict_cv = restrict_str ==
"yes";
3994 cv = cv | qualified_type_def::CV_CONST;
3996 cv = cv | qualified_type_def::CV_VOLATILE;
3998 cv = cv | qualified_type_def::CV_RESTRICT;
4002 type_id = CHAR_STR(s);
4005 shared_ptr<type_base> underlying_type =
4006 rdr.build_or_get_type_decl(type_id,
true);
4009 qualified_type_def_sptr decl;
4010 if (type_base_sptr t = rdr.get_type_decl(
id))
4017 decl.reset(
new qualified_type_def(underlying_type, cv, loc));
4018 maybe_set_artificial_location(rdr, node, decl);
4019 rdr.push_and_key_type_decl(decl, node, add_to_current_scope);
4020 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4023 rdr.map_xml_node_to_decl(node, decl);
4040 build_pointer_type_def(reader& rdr,
4041 const xmlNodePtr node,
4042 bool add_to_current_scope)
4045 shared_ptr<pointer_type_def> nil;
4047 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-type-def")))
4050 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4053 dynamic_pointer_cast<pointer_type_def>(d);
4063 if (type_base_sptr t = rdr.get_type_decl(
id))
4072 type_id = CHAR_STR(s);
4074 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4075 size_t alignment_in_bits = 0;
4076 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4078 read_location(rdr, node, loc);
4080 type_base_sptr pointed_to_type =
4081 rdr.build_or_get_type_decl(type_id,
true);
4085 if (rdr.get_environment().is_void_type(pointed_to_type))
4093 t.reset(
new pointer_type_def(pointed_to_type,
4098 maybe_set_artificial_location(rdr, node, t);
4100 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4101 rdr.map_xml_node_to_decl(node, t);
4103 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4119 static shared_ptr<reference_type_def>
4120 build_reference_type_def(reader& rdr,
4121 const xmlNodePtr node,
4122 bool add_to_current_scope)
4124 shared_ptr<reference_type_def> nil;
4126 if (!xmlStrEqual(node->name, BAD_CAST(
"reference-type-def")))
4129 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4132 dynamic_pointer_cast<reference_type_def>(d);
4142 if (type_base_sptr d = rdr.get_type_decl(
id))
4150 read_location(rdr, node, loc);
4154 bool is_lvalue = kind ==
"lvalue";
4156 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4157 size_t alignment_in_bits = 0;
4158 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4162 type_id = CHAR_STR(s);
4172 is_lvalue, size_in_bits,
4173 alignment_in_bits, loc));
4174 maybe_set_artificial_location(rdr, node, t);
4175 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4176 rdr.map_xml_node_to_decl(node, t);
4178 type_base_sptr pointed_to_type =
4179 rdr.build_or_get_type_decl(type_id,
true);
4181 t->set_pointed_to_type(pointed_to_type);
4182 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4200 build_function_type(reader& rdr,
4201 const xmlNodePtr node,
4206 if (!xmlStrEqual(node->name, BAD_CAST(
"function-type")))
4214 string method_class_id;
4216 method_class_id = CHAR_STR(s);
4218 bool is_method_t = !method_class_id.empty();
4220 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4221 read_size_and_alignment(node, size, align);
4223 const environment& env = rdr.get_environment();
4224 std::vector<shared_ptr<function_decl::parameter> > parms;
4225 type_base_sptr return_type = env.get_void_type();
4227 class_or_union_sptr method_class_type;
4237 ?
new method_type(method_class_type,
4240 :
new function_type(return_type,
4241 parms, size, align));
4243 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4244 rdr.key_type_decl(fn_type,
id);
4245 RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4247 for (xmlNodePtr n = xmlFirstElementChild(node);
4249 n = xmlNextElementSibling(n))
4251 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
4254 build_function_parameter(rdr, n))
4257 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
4262 type_id = CHAR_STR(s);
4263 if (!type_id.empty())
4264 fn_type->set_return_type(rdr.build_or_get_type_decl
4269 fn_type->set_parameters(parms);
4285 build_subrange_type(reader& rdr,
4286 const xmlNodePtr node,
4287 bool add_to_current_scope)
4291 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"subrange")))
4294 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4297 dynamic_pointer_cast<array_type_def::subrange_type>(d);
4311 if (type_base_sptr d = rdr.get_type_decl(
id))
4322 uint64_t length = 0;
4324 bool is_infinite =
false;
4327 if (
string(CHAR_STR(s)) ==
"infinite" ||
string(CHAR_STR(s)) ==
"unknown")
4330 length = strtoull(CHAR_STR(s), NULL, 0);
4333 int64_t lower_bound = 0, upper_bound = 0;
4334 bool bounds_present =
false;
4337 lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4339 if (!
string(CHAR_STR(s)).empty())
4340 upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4341 bounds_present =
true;
4343 || (length == (uint64_t) upper_bound - lower_bound + 1));
4346 string underlying_type_id;
4348 underlying_type_id = CHAR_STR(s);
4350 type_base_sptr underlying_type;
4351 if (!underlying_type_id.empty())
4353 underlying_type = rdr.build_or_get_type_decl(underlying_type_id,
true);
4358 read_location(rdr, node, loc);
4362 array_type_def::subrange_type::bound_value max_bound;
4363 array_type_def::subrange_type::bound_value min_bound;
4369 max_bound.set_signed(length - 1);
4375 min_bound.set_signed(lower_bound);
4376 max_bound.set_signed(upper_bound);
4380 (
new array_type_def::subrange_type(rdr.get_environment(),
4381 name, min_bound, max_bound,
4382 underlying_type, loc));
4383 maybe_set_artificial_location(rdr, node, p);
4384 p->is_infinite(is_infinite);
4386 if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
4387 rdr.map_xml_node_to_decl(node, p);
4404 build_array_type_def(reader& rdr,
4405 const xmlNodePtr node,
4406 bool add_to_current_scope)
4411 if (!xmlStrEqual(node->name, BAD_CAST(
"array-type-def")))
4414 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4417 dynamic_pointer_cast<array_type_def>(d);
4427 if (type_base_sptr d = rdr.get_type_decl(
id))
4436 dimensions = atoi(CHAR_STR(s));
4440 type_id = CHAR_STR(s);
4444 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4447 dynamic_pointer_cast<array_type_def>(d);
4452 size_t size_in_bits = 0, alignment_in_bits = 0;
4453 bool has_size_in_bits =
false;
4458 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4459 if (*endptr !=
'\0')
4461 if (!strcmp(CHAR_STR(s),
"infinite")
4462 ||!strcmp(CHAR_STR(s),
"unknown"))
4463 size_in_bits = (size_t) -1;
4467 has_size_in_bits =
true;
4472 alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4473 if (*endptr !=
'\0')
4478 read_location(rdr, node, loc);
4481 for (xmlNodePtr n = xmlFirstElementChild(node);
4483 n = xmlNextElementSibling(n))
4484 if (xmlStrEqual(n->name, BAD_CAST(
"subrange")))
4487 build_subrange_type(rdr, n,
true))
4489 MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
4490 if (add_to_current_scope)
4493 rdr.maybe_canonicalize_type(s);
4495 subranges.push_back(s);
4500 type_base_sptr type =
4501 rdr.build_or_get_type_decl(type_id,
true);
4505 maybe_set_artificial_location(rdr, node, ar_type);
4506 if (rdr.push_and_key_type_decl(ar_type, node, add_to_current_scope))
4507 rdr.map_xml_node_to_decl(node, ar_type);
4508 RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
4510 if (dimensions != ar_type->get_dimension_count()
4511 || (alignment_in_bits
4512 != ar_type->get_element_type()->get_alignment_in_bits()))
4515 if (has_size_in_bits && size_in_bits != (
size_t) -1
4516 && size_in_bits != ar_type->get_size_in_bits())
4519 size_t element_size = ar_type->get_element_type()->get_size_in_bits();
4520 if (element_size && element_size != (
size_t)-1)
4523 size_t bad_count = 0;
4524 for (vector<array_type_def::subrange_sptr>::const_iterator i =
4526 i != subranges.end();
4528 bad_count += (*i)->get_length();
4529 if (size_in_bits == bad_count * element_size)
4531 static bool reported =
false;
4534 std::cerr <<
"notice: Found incorrectly calculated array "
4535 <<
"sizes in XML - this is benign.\nOlder versions "
4536 <<
"of libabigail miscalculated multidimensional "
4537 <<
"array sizes." << std::endl;
4543 std::cerr <<
"error: Found incorrectly calculated array size in "
4544 <<
"XML (id=\"" <<
id <<
"\")." << std::endl;
4568 build_enum_type_decl_if_not_suppressed(reader& rdr,
4569 const xmlNodePtr node,
4570 bool add_to_current_scope)
4573 if (!type_is_suppressed(rdr, node))
4574 enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
4590 build_enum_type_decl(reader& rdr,
4591 const xmlNodePtr node,
4592 bool add_to_current_scope)
4596 if (!xmlStrEqual(node->name, BAD_CAST(
"enum-decl")))
4599 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4602 dynamic_pointer_cast<enum_type_decl>(d);
4611 string linkage_name;
4616 read_location(rdr, node, loc);
4618 bool is_decl_only =
false;
4619 read_is_declaration_only(node, is_decl_only);
4621 bool is_anonymous =
false;
4622 read_is_anonymous(node, is_anonymous);
4624 bool is_artificial =
false;
4625 read_is_artificial(node, is_artificial);
4633 string base_type_id;
4635 for (xmlNodePtr n = xmlFirstElementChild(node);
4637 n = xmlNextElementSibling(n))
4639 if (xmlStrEqual(n->name, BAD_CAST(
"underlying-type")))
4643 base_type_id = CHAR_STR(a);
4646 else if (xmlStrEqual(n->name, BAD_CAST(
"enumerator")))
4658 value = strtoll(CHAR_STR(a), NULL, 0);
4662 if ((errno == ERANGE)
4663 && (value == LLONG_MIN || value == LLONG_MAX))
4667 enums.push_back(enum_type_decl::enumerator(name, value));
4671 type_base_sptr underlying_type =
4672 rdr.build_or_get_type_decl(base_type_id,
true);
4677 enums, linkage_name));
4678 maybe_set_artificial_location(rdr, node, t);
4679 t->set_is_anonymous(is_anonymous);
4680 t->set_is_artificial(is_artificial);
4681 t->set_is_declaration_only(is_decl_only);
4682 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4684 maybe_set_naming_typedef(rdr, node, t);
4685 rdr.map_xml_node_to_decl(node, t);
4686 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4701 static shared_ptr<typedef_decl>
4702 build_typedef_decl(reader& rdr,
4703 const xmlNodePtr node,
4704 bool add_to_current_scope)
4706 shared_ptr<typedef_decl> nil;
4708 if (!xmlStrEqual(node->name, BAD_CAST(
"typedef-decl")))
4711 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4728 read_location(rdr, node, loc);
4732 type_id = CHAR_STR(s);
4735 type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id,
true));
4739 maybe_set_artificial_location(rdr, node, t);
4740 rdr.push_and_key_type_decl(t, node, add_to_current_scope);
4741 rdr.map_xml_node_to_decl(node, t);
4742 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4759 build_class_decl_if_not_suppressed(reader& rdr,
4760 const xmlNodePtr node,
4761 bool add_to_current_scope)
4764 if (!type_is_suppressed(rdr, node))
4765 class_type = build_class_decl(rdr, node, add_to_current_scope);
4781 static union_decl_sptr
4782 build_union_decl_if_not_suppressed(reader& rdr,
4783 const xmlNodePtr node,
4784 bool add_to_current_scope)
4786 union_decl_sptr union_type;
4787 if (!type_is_suppressed(rdr, node))
4788 union_type = build_union_decl(rdr, node, add_to_current_scope);
4805 build_class_decl(reader& rdr,
4806 const xmlNodePtr node,
4807 bool add_to_current_scope)
4811 if (!xmlStrEqual(node->name, BAD_CAST(
"class-decl")))
4814 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4825 size_t size_in_bits = 0, alignment_in_bits = 0;
4826 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4829 read_visibility(node, vis);
4831 bool is_artificial =
false;
4832 read_is_artificial(node, is_artificial);
4839 read_location(rdr, node, loc);
4848 bool is_decl_only =
false;
4849 read_is_declaration_only(node, is_decl_only);
4851 bool is_struct =
false;
4852 read_is_struct(node, is_struct);
4854 bool is_anonymous =
false;
4855 read_is_anonymous(node, is_anonymous);
4861 if (type_base_sptr t = rdr.get_type_decl(
id))
4867 const vector<type_base_sptr> *types_ptr = 0;
4868 if (!is_anonymous && !previous_definition)
4869 types_ptr = rdr.get_all_type_decls(
id);
4875 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
4876 i != types_ptr->end();
4881 if (klass->get_is_declaration_only()
4882 && !klass->get_definition_of_declaration())
4883 previous_declaration = klass;
4884 else if (!klass->get_is_declaration_only()
4885 && !previous_definition)
4886 previous_definition = klass;
4887 if (previous_definition && previous_declaration)
4891 if (previous_declaration)
4892 ABG_ASSERT(previous_declaration->get_name() == name);
4894 if (previous_definition)
4895 ABG_ASSERT(previous_definition->get_name() == name);
4897 if (is_decl_only && previous_declaration)
4898 return previous_declaration;
4901 const environment& env = rdr.get_environment();
4903 if (!is_decl_only && previous_definition)
4909 decl = previous_definition;
4914 decl.reset(
new class_decl(env, name, is_struct));
4916 decl->set_size_in_bits(size_in_bits);
4918 decl->set_is_anonymous(is_anonymous);
4919 decl->set_location(loc);
4922 decl.reset(
new class_decl(env, name, size_in_bits, alignment_in_bits,
4923 is_struct, loc, vis, bases, mbrs,
4924 data_mbrs, mbr_functions, is_anonymous));
4927 maybe_set_artificial_location(rdr, node, decl);
4928 decl->set_is_artificial(is_artificial);
4931 bool is_def_of_decl =
false;
4933 def_id = CHAR_STR(s);
4935 if (!def_id.empty())
4937 decl_base_sptr d =
is_decl(rdr.get_type_decl(def_id));
4938 if (d && d->get_is_declaration_only())
4940 is_def_of_decl =
true;
4942 d->set_definition_of_declaration(decl);
4948 && !decl->get_is_declaration_only()
4949 && previous_declaration)
4955 decl->set_earlier_declaration(
is_decl(previous_declaration));
4956 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
4957 i != types_ptr->end();
4962 if (d->get_is_declaration_only()
4963 && !d->get_definition_of_declaration())
4965 previous_declaration->set_definition_of_declaration(decl);
4966 is_def_of_decl =
true;
4971 if (is_decl_only && previous_definition)
4976 && !decl->get_definition_of_declaration());
4977 decl->set_definition_of_declaration(previous_definition);
4980 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
4982 rdr.push_decl_to_scope(decl,
4983 add_to_current_scope
4984 ? rdr.get_scope_ptr_for_node(node)
4987 rdr.map_xml_node_to_decl(node, decl);
4988 rdr.key_type_decl(decl,
id);
4991 maybe_set_naming_typedef(rdr, node, decl);
4993 for (xmlNodePtr n = xmlFirstElementChild(node);
4995 n = xmlNextElementSibling(n))
4997 if (xmlStrEqual(n->name, BAD_CAST(
"base-class")))
5003 read_access(n, access);
5007 type_id = CHAR_STR(s);
5008 shared_ptr<class_decl> b =
5009 dynamic_pointer_cast<class_decl>
5010 (rdr.build_or_get_type_decl(type_id,
true));
5013 if (decl->find_base_class(b->get_qualified_name()))
5019 size_t offset_in_bits = 0;
5020 bool offset_present = read_offset_in_bits (n, offset_in_bits);
5022 bool is_virtual =
false;
5023 read_is_virtual (n, is_virtual);
5025 shared_ptr<class_decl::base_spec> base (
new class_decl::base_spec
5028 ? (
long) offset_in_bits
5031 decl->add_base_specifier(base);
5033 else if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5039 read_access(n, access);
5041 rdr.map_xml_node_to_decl(n, decl);
5043 for (xmlNodePtr p = xmlFirstElementChild(n);
5045 p = xmlNextElementSibling(p))
5047 if (type_base_sptr t =
5048 build_type(rdr, p,
true))
5053 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5055 string id = CHAR_STR(i);
5057 rdr.key_type_decl(t,
id);
5058 rdr.map_xml_node_to_decl(p, td);
5062 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5064 rdr.map_xml_node_to_decl(n, decl);
5070 read_access(n, access);
5072 bool is_laid_out =
false;
5073 size_t offset_in_bits = 0;
5074 if (read_offset_in_bits(n, offset_in_bits))
5077 bool is_static =
false;
5078 read_static(n, is_static);
5080 for (xmlNodePtr p = xmlFirstElementChild(n);
5082 p = xmlNextElementSibling(p))
5085 build_var_decl(rdr, p,
false))
5087 if (decl->find_data_member(v))
5095 decl_base_sptr d = rdr.pop_decl();
5100 if (!variable_is_suppressed(rdr, decl.get(), *v))
5102 decl->add_data_member(v, access,
5107 rdr.maybe_add_var_to_exported_decls(v.get());
5117 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5120 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5121 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5127 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5133 read_access(n, access);
5135 bool is_virtual =
false;
5136 ssize_t vtable_offset = -1;
5141 vtable_offset = atoi(CHAR_STR(s));
5144 bool is_static =
false;
5145 read_static(n, is_static);
5147 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5148 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5150 for (xmlNodePtr p = xmlFirstElementChild(n);
5152 p = xmlNextElementSibling(p))
5155 build_function_decl_if_not_suppressed(rdr, p, decl,
5163 if (vtable_offset != -1)
5169 rdr.map_xml_node_to_decl(p, m);
5170 rdr.maybe_add_fn_to_exported_decls(f.get());
5175 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5177 rdr.map_xml_node_to_decl(n, decl);
5183 read_access(n, access);
5185 bool is_static =
false;
5186 read_static(n, is_static);
5188 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5189 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5191 for (xmlNodePtr p = xmlFirstElementChild(n);
5193 p = xmlNextElementSibling(p))
5195 if (shared_ptr<function_tdecl> f =
5196 build_function_tdecl(rdr, p,
5199 shared_ptr<member_function_template> m
5200 (
new member_function_template(f, access, is_static,
5201 is_ctor, is_const));
5203 decl->add_member_function_template(m);
5205 else if (shared_ptr<class_tdecl> c =
5206 build_class_tdecl(rdr, p,
5209 member_class_template_sptr m(
new member_class_template(c,
5213 decl->add_member_class_template(m);
5219 rdr.pop_scope_or_abort(decl);
5236 static union_decl_sptr
5237 build_union_decl(reader& rdr,
5238 const xmlNodePtr node,
5239 bool add_to_current_scope)
5241 union_decl_sptr nil;
5243 if (!xmlStrEqual(node->name, BAD_CAST(
"union-decl")))
5246 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5248 union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5257 size_t size_in_bits = 0, alignment_in_bits = 0;
5258 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5261 read_visibility(node, vis);
5263 bool is_artificial =
false;
5264 read_is_artificial(node, is_artificial);
5271 read_location(rdr, node, loc);
5277 union_decl_sptr decl;
5279 bool is_decl_only =
false;
5280 read_is_declaration_only(node, is_decl_only);
5282 bool is_anonymous =
false;
5283 read_is_anonymous(node, is_anonymous);
5286 union_decl_sptr previous_definition, previous_declaration;
5287 const vector<type_base_sptr> *types_ptr = 0;
5289 types_ptr = rdr.get_all_type_decls(
id);
5295 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5296 i != types_ptr->end();
5301 if (onion->get_is_declaration_only()
5302 && !onion->get_definition_of_declaration())
5303 previous_declaration = onion;
5304 else if (!onion->get_is_declaration_only()
5305 && !previous_definition)
5306 previous_definition = onion;
5307 if (previous_definition && previous_declaration)
5311 if (previous_declaration)
5312 ABG_ASSERT(previous_declaration->get_name() == name);
5314 if (previous_definition)
5315 ABG_ASSERT(previous_definition->get_name() == name);
5317 if (is_decl_only && previous_declaration)
5318 return previous_declaration;
5321 const environment& env = rdr.get_environment();
5323 if (!is_decl_only && previous_definition)
5329 decl = previous_definition;
5333 decl.reset(
new union_decl(env, name));
5335 decl.reset(
new union_decl(env, name,
5343 maybe_set_artificial_location(rdr, node, decl);
5344 decl->set_is_artificial(is_artificial);
5347 bool is_def_of_decl =
false;
5349 def_id = CHAR_STR(s);
5351 if (!def_id.empty())
5354 dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5355 if (d && d->get_is_declaration_only())
5357 is_def_of_decl =
true;
5358 decl->set_earlier_declaration(d);
5359 d->set_definition_of_declaration(decl);
5365 && !decl->get_is_declaration_only()
5366 && previous_declaration)
5372 decl->set_earlier_declaration(previous_declaration);
5373 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5374 i != types_ptr->end();
5379 if (d->get_is_declaration_only()
5380 && !d->get_definition_of_declaration())
5382 previous_declaration->set_definition_of_declaration(decl);
5383 is_def_of_decl =
true;
5388 if (is_decl_only && previous_definition)
5393 && !decl->get_definition_of_declaration());
5394 decl->set_definition_of_declaration(previous_definition);
5397 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5399 rdr.push_decl_to_scope(decl,
5400 add_to_current_scope
5401 ? rdr.get_scope_ptr_for_node(node)
5404 rdr.map_xml_node_to_decl(node, decl);
5405 rdr.key_type_decl(decl,
id);
5407 maybe_set_naming_typedef(rdr, node, decl);
5409 for (xmlNodePtr n = xmlFirstElementChild(node);
5411 n = xmlNextElementSibling(n))
5413 if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5416 read_access(n, access);
5418 rdr.map_xml_node_to_decl(n, decl);
5420 for (xmlNodePtr p = xmlFirstElementChild(n);
5422 p = xmlNextElementSibling(p))
5424 if (type_base_sptr t =
5425 build_type(rdr, p,
true))
5430 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5432 string id = CHAR_STR(i);
5434 rdr.key_type_decl(t,
id);
5435 rdr.map_xml_node_to_decl(p, td);
5439 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5441 rdr.map_xml_node_to_decl(n, decl);
5444 read_access(n, access);
5446 bool is_laid_out =
true;
5447 size_t offset_in_bits = 0;
5448 bool is_static =
false;
5449 read_static(n, is_static);
5451 for (xmlNodePtr p = xmlFirstElementChild(n);
5453 p = xmlNextElementSibling(p))
5456 build_var_decl(rdr, p,
false))
5458 if (decl->find_data_member(v))
5466 decl_base_sptr d = rdr.pop_decl();
5471 || !variable_is_suppressed(rdr, decl.get(), *v))
5473 decl->add_data_member(v, access,
5486 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5489 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5490 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5496 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5498 rdr.map_xml_node_to_decl(n, decl);
5501 read_access(n, access);
5503 bool is_static =
false;
5504 read_static(n, is_static);
5506 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5507 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5509 for (xmlNodePtr p = xmlFirstElementChild(n);
5511 p = xmlNextElementSibling(p))
5514 build_function_decl_if_not_suppressed(rdr, p, decl,
5525 rdr.maybe_add_fn_to_exported_decls(f.get());
5530 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5532 rdr.map_xml_node_to_decl(n, decl);
5535 read_access(n, access);
5537 bool is_static =
false;
5538 read_static(n, is_static);
5540 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5541 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5543 for (xmlNodePtr p = xmlFirstElementChild(n);
5545 p = xmlNextElementSibling(p))
5548 build_function_tdecl(rdr, p,
5551 member_function_template_sptr m
5552 (
new member_function_template(f, access, is_static,
5553 is_ctor, is_const));
5555 decl->add_member_function_template(m);
5558 build_class_tdecl(rdr, p,
5561 member_class_template_sptr m(
new member_class_template(c,
5565 decl->add_member_class_template(m);
5571 rdr.pop_scope_or_abort(decl);
5588 static shared_ptr<function_tdecl>
5589 build_function_tdecl(reader& rdr,
5590 const xmlNodePtr node,
5591 bool add_to_current_scope)
5593 shared_ptr<function_tdecl> nil, result;
5595 if (!xmlStrEqual(node->name, BAD_CAST(
"function-template-decl")))
5601 if (
id.empty() || rdr.get_fn_tmpl_decl(
id))
5605 read_location(rdr, node, loc);
5608 read_visibility(node, vis);
5611 read_binding(node, bind);
5613 const environment& env = rdr.get_environment();
5616 maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
5618 rdr.push_decl_to_scope(fn_tmpl_decl,
5619 add_to_current_scope
5620 ? rdr.get_scope_ptr_for_node(node)
5622 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5623 rdr.map_xml_node_to_decl(node, fn_tmpl_decl);
5625 unsigned parm_index = 0;
5626 for (xmlNodePtr n = xmlFirstElementChild(node);
5628 n = xmlNextElementSibling(n))
5631 build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
5633 fn_tmpl_decl->add_template_parameter(parm);
5640 fn_tmpl_decl->set_pattern(f);
5643 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5645 return fn_tmpl_decl;
5661 build_class_tdecl(reader& rdr,
5662 const xmlNodePtr node,
5663 bool add_to_current_scope)
5667 if (!xmlStrEqual(node->name, BAD_CAST(
"class-template-decl")))
5673 if (
id.empty() || rdr.get_class_tmpl_decl(
id))
5677 read_location(rdr, node, loc);
5680 read_visibility(node, vis);
5682 const environment& env = rdr.get_environment();
5685 maybe_set_artificial_location(rdr, node, class_tmpl);
5687 if (add_to_current_scope)
5688 rdr.push_decl_to_scope(class_tmpl, node);
5689 rdr.key_class_tmpl_decl(class_tmpl,
id);
5690 rdr.map_xml_node_to_decl(node, class_tmpl);
5692 unsigned parm_index = 0;
5693 for (xmlNodePtr n = xmlFirstElementChild(node);
5695 n = xmlNextElementSibling(n))
5698 build_template_parameter(rdr, n, parm_index, class_tmpl))
5700 class_tmpl->add_template_parameter(parm);
5704 build_class_decl_if_not_suppressed(rdr, n,
5705 add_to_current_scope))
5708 rdr.maybe_canonicalize_type(c,
false);
5709 class_tmpl->set_pattern(c);
5713 rdr.key_class_tmpl_decl(class_tmpl,
id);
5734 build_type_tparameter(reader& rdr,
5735 const xmlNodePtr node,
5741 if (!xmlStrEqual(node->name, BAD_CAST(
"template-type-parameter")))
5752 type_id = CHAR_STR(s);
5753 if (!type_id.empty()
5754 && !(result = dynamic_pointer_cast<type_tparameter>
5755 (rdr.build_or_get_type_decl(type_id,
true))))
5763 read_location(rdr, node,loc);
5765 result.reset(
new type_tparameter(index, tdecl, name, loc));
5766 maybe_set_artificial_location(rdr, node, result);
5769 rdr.push_decl_to_scope(
is_decl(result), node);
5771 rdr.push_and_key_type_decl(result, node,
true);
5773 rdr.maybe_canonicalize_type(result,
false);
5793 build_type_composition(reader& rdr,
5794 const xmlNodePtr node,
5800 if (!xmlStrEqual(node->name, BAD_CAST(
"template-parameter-type-composition")))
5803 type_base_sptr composed_type;
5804 result.reset(
new type_composition(index, tdecl, composed_type));
5805 rdr.push_decl_to_scope(
is_decl(result), node);
5807 for (xmlNodePtr n = xmlFirstElementChild(node);
5809 n = xmlNextElementSibling(n))
5811 if ((composed_type =
5812 build_pointer_type_def(rdr, n,
5815 build_reference_type_def(rdr, n,
5818 build_array_type_def(rdr, n,
5821 build_qualified_type_decl(rdr, n,
5824 rdr.maybe_canonicalize_type(composed_type,
5826 result->set_composed_type(composed_type);
5850 build_non_type_tparameter(reader& rdr,
5851 const xmlNodePtr node,
5857 if (!xmlStrEqual(node->name, BAD_CAST(
"template-non-type-parameter")))
5862 type_id = CHAR_STR(s);
5863 type_base_sptr type;
5865 || !(type = rdr.build_or_get_type_decl(type_id,
true)))
5873 read_location(rdr, node,loc);
5875 r.reset(
new non_type_tparameter(index, tdecl, name, type, loc));
5876 maybe_set_artificial_location(rdr, node, r);
5877 rdr.push_decl_to_scope(
is_decl(r), node);
5897 build_template_tparameter(reader& rdr,
5898 const xmlNodePtr node,
5904 if (!xmlStrEqual(node->name, BAD_CAST(
"template-template-parameter")))
5915 type_id = CHAR_STR(s);
5917 if (!type_id.empty()
5918 && !(dynamic_pointer_cast<template_tparameter>
5919 (rdr.build_or_get_type_decl(type_id,
true))))
5927 read_location(rdr, node, loc);
5931 maybe_set_artificial_location(rdr, node, result);
5932 rdr.push_decl_to_scope(result, node);
5936 for (xmlNodePtr n = xmlFirstElementChild(node);
5938 n = xmlNextElementSibling(n))
5939 if (shared_ptr<template_parameter> p =
5940 build_template_parameter(rdr, n, parm_index, result))
5942 result->add_template_parameter(p);
5948 rdr.key_type_decl(result,
id);
5949 rdr.maybe_canonicalize_type(result,
false);
5971 build_template_parameter(reader& rdr,
5972 const xmlNodePtr node,
5976 shared_ptr<template_parameter> r;
5977 ((r = build_type_tparameter(rdr, node, index, tdecl))
5978 || (r = build_non_type_tparameter(rdr, node, index, tdecl))
5979 || (r = build_template_tparameter(rdr, node, index, tdecl))
5980 || (r = build_type_composition(rdr, node, index, tdecl)));
5993 static type_base_sptr
5994 build_type(reader& rdr,
5995 const xmlNodePtr node,
5996 bool add_to_current_scope)
6000 ((t = build_type_decl(rdr, node, add_to_current_scope))
6001 || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
6002 || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
6003 || (t = build_reference_type_def(rdr, node , add_to_current_scope))
6004 || (t = build_function_type(rdr, node, add_to_current_scope))
6005 || (t = build_array_type_def(rdr, node, add_to_current_scope))
6006 || (t = build_subrange_type(rdr, node, add_to_current_scope))
6007 || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
6008 add_to_current_scope))
6009 || (t = build_typedef_decl(rdr, node, add_to_current_scope))
6010 || (t = build_class_decl_if_not_suppressed(rdr, node,
6011 add_to_current_scope))
6012 || (t = build_union_decl_if_not_suppressed(rdr, node,
6013 add_to_current_scope)));
6015 if (rdr.tracking_non_reachable_types() && t)
6017 corpus_sptr abi = rdr.corpus();
6019 bool is_non_reachable_type =
false;
6020 read_is_non_reachable_type(node, is_non_reachable_type);
6021 if (!is_non_reachable_type)
6022 abi->record_type_as_reachable_from_public_interfaces(*t);
6025 MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
6028 rdr.maybe_canonicalize_type(t,
false );
6037 static decl_base_sptr
6038 handle_type_decl(reader& rdr,
6040 bool add_to_current_scope)
6042 type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
6043 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6044 if (decl && decl->get_scope())
6045 rdr.maybe_canonicalize_type(decl,
false);
6054 static decl_base_sptr
6055 handle_namespace_decl(reader& rdr,
6057 bool add_to_current_scope)
6060 add_to_current_scope);
6069 static decl_base_sptr
6070 handle_qualified_type_decl(reader& rdr,
6072 bool add_to_current_scope)
6074 qualified_type_def_sptr decl =
6075 build_qualified_type_decl(rdr, node,
6076 add_to_current_scope);
6077 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6078 if (decl && decl->get_scope())
6079 rdr.maybe_canonicalize_type(decl,
false);
6088 static decl_base_sptr
6089 handle_pointer_type_def(reader& rdr,
6091 bool add_to_current_scope)
6094 add_to_current_scope);
6095 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6096 if (decl && decl->get_scope())
6097 rdr.maybe_canonicalize_type(decl,
false);
6106 static decl_base_sptr
6107 handle_reference_type_def(reader& rdr,
6109 bool add_to_current_scope)
6112 add_to_current_scope);
6113 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6114 if (decl && decl->get_scope())
6115 rdr.maybe_canonicalize_type(decl,
false);
6124 static type_base_sptr
6125 handle_function_type(reader& rdr,
6127 bool add_to_current_scope)
6130 add_to_current_scope);
6131 MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
6132 rdr.maybe_canonicalize_type(type,
true);
6141 static decl_base_sptr
6142 handle_array_type_def(reader& rdr,
6144 bool add_to_current_scope)
6147 add_to_current_scope);
6148 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6149 rdr.maybe_canonicalize_type(decl,
false);
6156 static decl_base_sptr
6157 handle_enum_type_decl(reader& rdr,
6159 bool add_to_current_scope)
6162 build_enum_type_decl_if_not_suppressed(rdr, node,
6163 add_to_current_scope);
6164 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6165 if (decl && decl->get_scope())
6166 rdr.maybe_canonicalize_type(decl,
false);
6173 static decl_base_sptr
6174 handle_typedef_decl(reader& rdr,
6176 bool add_to_current_scope)
6179 add_to_current_scope);
6180 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6181 if (decl && decl->get_scope())
6182 rdr.maybe_canonicalize_type(decl,
false);
6194 static decl_base_sptr
6195 handle_var_decl(reader& rdr,
6197 bool add_to_current_scope)
6199 decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6200 add_to_current_scope);
6201 rdr.maybe_add_var_to_exported_decls(
is_var_decl(decl).
get());
6211 static decl_base_sptr
6212 handle_function_decl(reader& rdr,
6214 bool add_to_current_scope)
6216 return build_function_decl_if_not_suppressed(rdr, node,
class_decl_sptr(),
6217 add_to_current_scope,
6227 static decl_base_sptr
6228 handle_class_decl(reader& rdr,
6230 bool add_to_current_scope)
6233 build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6234 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6235 if (decl && decl->get_scope())
6236 rdr.maybe_canonicalize_type(decl,
false);
6246 static decl_base_sptr
6247 handle_union_decl(reader& rdr,
6249 bool add_to_current_scope)
6251 union_decl_sptr decl =
6252 build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6253 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6254 if (decl && decl->get_scope())
6255 rdr.maybe_canonicalize_type(decl,
false);
6265 static decl_base_sptr
6266 handle_function_tdecl(reader& rdr,
6268 bool add_to_current_scope)
6271 add_to_current_scope);
6280 static decl_base_sptr
6281 handle_class_tdecl(reader& rdr,
6283 bool add_to_current_scope)
6286 add_to_current_scope);
6303 return read_translation_unit_from_input(read_rdr);
6305 template<
typename T>
6306 struct array_deleter
6328 corpus_sptr corp = result->corpus();
6329 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6330 #ifdef WITH_DEBUG_SELF_COMPARISON
6331 if (env.self_comparison_debug_is_on())
6332 env.set_self_comparison_debug_input(result->corpus());
6334 result->set_path(path);
6351 corpus_sptr corp = result->corpus();
6352 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6353 #ifdef WITH_DEBUG_SELF_COMPARISON
6354 if (env.self_comparison_debug_is_on())
6355 env.set_self_comparison_debug_input(result->corpus());
6378 return rdr->read_corpus(sts);
6400 corpus_sptr corp = rdr->read_corpus(sts);
6406 #ifdef WITH_DEBUG_SELF_COMPARISON
6425 load_canonical_type_ids(fe_iface& iface,
const string &file_path)
6427 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
6429 xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
6433 xmlNodePtr node = xmlDocGetRootElement(doc);
6456 if (xmlStrcmp(node->name, (xmlChar*)
"abixml-types-check"))
6459 for (node = xmlFirstElementChild(node);
6461 node = xmlNextElementSibling(node))
6463 if (xmlStrcmp(node->name, (xmlChar*)
"type"))
6466 string id, canonical_address;
6467 xmlNodePtr data = xmlFirstElementChild(node);
6468 if (data && !xmlStrcmp(data->name, (xmlChar*)
"id")
6469 && data->children && xmlNodeIsText(data->children))
6470 id = (
char*) XML_GET_CONTENT(data->children);
6472 data = xmlNextElementSibling(data);
6473 if (data && !xmlStrcmp(data->name, (xmlChar*)
"c")
6474 && data->children && xmlNodeIsText(data->children))
6476 canonical_address = (
char*) XML_GET_CONTENT(data->children);
6477 std::stringstream s;
6478 s << canonical_address;
6486 rdr.get_environment().get_type_id_canonical_type_map()[id] = v;
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...
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
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...
const std::vector< parameter_sptr > & get_parameters() const
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
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.
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)...
#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...
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...
shared_ptr< T > build_sptr(T *p)
This is to be specialized for the diverse C types that needs wrapping in shared_ptr.
visibility
The visibility of the symbol.
void set_path(const string &)
Set the file path associated to the corpus file.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
fe_iface_sptr create_reader(const string &path, environment &env)
Create an xml_reader::reader to read a native XML ABI file.
reader_sptr new_reader_from_istream(std::istream *in)
Instanciate an xmlTextReader that parses a content coming from an input stream.
This file contains the declarations for the fe_iface a.k.a "Front End Interface". ...
The base class of all libabigail front-ends: The Front End Interface.
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'.
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.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< xmlChar > xml_char_sptr
A convenience typedef for a shared pointer of xmlChar.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
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.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
The base class of both types and declarations.
A declaration that introduces a scope.
#define XML_NODE_GET_ATTRIBUTE(node, name)
Get the value of attribute 'name' ont the instance of xmlNodePtr denoted by 'node'.
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...
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.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
bool has_file_name_related_property() const
Test if the current suppression has a property related to file name.
This is the abstraction of the set of relevant artefacts (types, variable declarations, functions, templates, etc) bundled together into a translation unit.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool get_drops_artifact_from_ir() const
Tests if the current suppression specification is to avoid adding the matched ABI artifact to the int...
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...
status
The status of the fe_iface::read_corpus call.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< file_suppression > file_suppression_sptr
A convenience typedef for a shared_ptr to file_suppression.
#define XML_READER_GET_NODE_TYPE(reader)
Get the type of the current node of the shared_ptr passed in argument.
file_suppression_sptr is_file_suppression(const suppression_sptr s)
Test if a given suppression specification is a file suppression specification.
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
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< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
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.
void set_soname(const string &)
Setter for the soname property of the corpus.
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...
This contains the declarations for the symtab reader.
shared_ptr< type_composition > type_composition_sptr
Convenience typedef for shared pointer to type_composition.
vector< type_base_sptr > member_types
Convenience typedef.
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.
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...
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
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...
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< xmlTextReader > reader_sptr
A convenience typedef for a shared pointer of xmlTextReader.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Toplevel namespace for libabigail.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
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...
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
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.
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.
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'.
Abstraction for a function declaration.
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'.
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.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
The source location of a token.
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< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
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.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
translation_unit * get_translation_unit(const decl_base &decl)
Return the translation unit a declaration belongs to.
vector< method_decl_sptr > member_functions
Convenience typedef.
This contains the private implementation of the suppression engine of libabigail. ...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
#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_ATTRIBUTE(reader, name)
Get the value of attribute 'name' on the current node of 'reader' which is an instance of shared_ptr<...
Base type of a direct suppression specifications types.
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...
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
Abstracts the building of the set of exported variables and functions.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
string & get_path() const
Get the file path associated to the corpus file.
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.
binding
The binding of a symbol.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
array_type_def * is_array_type(const type_or_decl_base *type)
Test if a type is an array_type_def.
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
Abstraction of a type suppression specification.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
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, by writting their corresponding characters back in. The pre-defined entities are:
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...
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
const type_base_sptr get_return_type() const
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.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
Abstraction of a function suppression specification.
This abstracts the global scope of a given translation unit.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
shared_ptr< non_type_tparameter > non_type_tparameter_sptr
Convenience typedef for shared pointer to non_type_template_parameter.
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.
void set_origin(origin)
Setter for the origin of the corpus.
void set_language(language l)
Setter of the language of the source code of the translation unit.
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 ...
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
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...
reference_type_def * is_reference_type(type_or_decl_base *t)
Test whether a type is a reference_type_def.
Abstraction of a group of corpora.
vector< var_decl_sptr > data_members
Convenience typedef.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
access_specifier
Access specifier for class members.
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...
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
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...
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 ...
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
void set_symtab(symtab_reader::symtab_sptr)
Setter for the symtab object.
vector< base_spec_sptr > base_specs
Convenience typedef.
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'.
shared_ptr< string_elf_symbols_map_type > string_elf_symbols_map_sptr
Convenience typedef for a shared pointer to string_elf_symbols_map_type.
pointer_type_def * is_pointer_type(type_or_decl_base *t)
Test whether a type is a pointer_type_def.
void set_address_size(char)
Setter of the address size in this translation unit.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
shared_ptr< type_tparameter > type_tparameter_sptr
Convenience typedef for a shared pointer to type_tparameter.
bool xml_char_sptr_to_string(xml_char_sptr ssptr, std::string &s)
Convert a shared pointer to xmlChar into an std::string.
Abstraction of a function type.
bool has_soname_related_property() const
Test if the current suppression has a property related to SONAMEs.
CV
Bit field values representing the cv qualifiers of the underlying type.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
visibility
ELF visibility.
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...