15#include <libxml/xmlreader.h>
16#include <libxml/xmlstring.h>
23#include <unordered_map>
27#include "abg-internal.h"
32ABG_BEGIN_EXPORT_DECLARATIONS
40ABG_END_EXPORT_DECLARATIONS
54using std::unordered_map;
55using std::dynamic_pointer_cast;
65static bool read_is_declaration_only(xmlNodePtr,
bool&);
66static bool read_is_artificial(xmlNodePtr,
bool&);
67static bool read_tracking_non_reachable_types(xmlNodePtr,
bool&);
68static bool read_is_non_reachable_type(xmlNodePtr,
bool&);
69static bool read_naming_typedef_id_string(xmlNodePtr,
string&);
70static bool read_type_id_string(xmlNodePtr,
string&);
71#ifdef WITH_DEBUG_SELF_COMPARISON
72static bool maybe_map_type_with_type_id(
const type_base_sptr&,
74static bool maybe_map_type_with_type_id(
const type_base_sptr&,
77#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node) \
78 maybe_map_type_with_type_id(type, xml_node)
80#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node)
82static void maybe_set_naming_typedef(reader& rdr,
84 const decl_base_sptr &);
87static int advance_cursor(reader& rdr);
93walk_xml_node_to_map_type_ids(reader& rdr, xmlNodePtr node);
96read_elf_needed_from_input(reader& rdr, vector<string>& needed);
99read_symbol_db_from_input(reader& rdr,
106read_translation_unit_from_input(
fe_iface& rdr);
109build_ir_node_for_void_type(reader& rdr);
112build_ir_node_for_void_pointer_type(reader& rdr);
131 typedef unordered_map<string, vector<type_base_sptr> >
134 typedef unordered_map<string,
135 vector<type_base_sptr> >::const_iterator
138 typedef unordered_map<string,
139 vector<type_base_sptr> >::iterator
142 typedef unordered_map<string,
143 shared_ptr<function_tdecl> >::const_iterator
144 const_fn_tmpl_map_it;
146 typedef unordered_map<string,
147 shared_ptr<class_tdecl> >::const_iterator
148 const_class_tmpl_map_it;
150 typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
152 typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
154 friend vector<type_base_sptr>* get_types_from_type_id(reader&,
157 friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
158 get_artifact_used_by_relation_map(reader& rdr);
161 types_map_type m_types_map;
162 unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
163 unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
164 vector<type_base_sptr> m_types_to_canonicalize;
165 string_xml_node_map m_id_xml_node_map;
166 xml_node_decl_base_sptr_map m_xml_node_decl_map;
168 xmlNodePtr m_corp_node;
169 deque<shared_ptr<decl_base> > m_decls_stack;
170 bool m_tracking_non_reachable_types;
171 bool m_drop_undefined_syms;
172#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
174 vector<type_or_decl_base*>> m_artifact_used_by_map;
185 m_tracking_non_reachable_types(),
186 m_drop_undefined_syms()
195 {
return options().do_log;}
203 tracking_non_reachable_types()
const
204 {
return m_tracking_non_reachable_types;}
212 tracking_non_reachable_types(
bool f)
213 {m_tracking_non_reachable_types = f;}
221 drop_undefined_syms()
const
222 {
return m_drop_undefined_syms;}
229 drop_undefined_syms(
bool f)
230 {m_drop_undefined_syms = f;}
243 set_path(
const string& s)
259 get_environment()
const
260 {
return const_cast<reader*
>(
this)->get_environment();}
263 get_libxml_reader()
const
272 get_corpus_node()
const
273 {
return m_corp_node;}
281 set_corpus_node(xmlNodePtr node)
282 {m_corp_node = node;}
284 const string_xml_node_map&
285 get_id_xml_node_map()
const
286 {
return m_id_xml_node_map;}
289 get_id_xml_node_map()
290 {
return m_id_xml_node_map;}
293 clear_id_xml_node_map()
294 {get_id_xml_node_map().clear();}
296 const xml_node_decl_base_sptr_map&
297 get_xml_node_decl_map()
const
298 {
return m_xml_node_decl_map;}
300 xml_node_decl_base_sptr_map&
301 get_xml_node_decl_map()
302 {
return m_xml_node_decl_map;}
305 map_xml_node_to_decl(xmlNodePtr node,
309 get_xml_node_decl_map()[node]= decl;
313 get_decl_for_xml_node(xmlNodePtr node)
const
315 xml_node_decl_base_sptr_map::const_iterator i =
316 get_xml_node_decl_map().find(node);
318 if (i != get_xml_node_decl_map().end())
321 return decl_base_sptr();
325 clear_xml_node_decl_map()
326 {get_xml_node_decl_map().clear();}
329 map_id_and_node (
const string&
id,
335 string_xml_node_map::iterator i = get_id_xml_node_map().find(
id);
336 if (i != get_id_xml_node_map().end())
338 bool is_declaration =
false;
339 read_is_declaration_only(node, is_declaration);
344 get_id_xml_node_map()[id] = node;
348 get_xml_node_from_id(
const string&
id)
const
350 string_xml_node_map::const_iterator i = get_id_xml_node_map().find(
id);
351 if (i != get_id_xml_node_map().end())
357 get_scope_for_node(xmlNodePtr node,
361 get_scope_for_node(xmlNodePtr node);
364 get_scope_ptr_for_node(xmlNodePtr node);
369 build_or_get_type_decl(
const string&
id,
384 get_type_decl(
const string&
id)
const
386 const_types_map_it i = m_types_map.find(
id);
387 if (i == m_types_map.end())
388 return type_base_sptr();
389 type_base_sptr result = i->second[0];
405 const vector<type_base_sptr>*
406 get_all_type_decls(
const string&
id)
const
408 const_types_map_it i = m_types_map.find(
id);
409 if (i == m_types_map.end())
426 shared_ptr<function_tdecl>
427 get_fn_tmpl_decl(
const string&
id)
const
429 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
430 if (i == m_fn_tmpl_map.end())
431 return shared_ptr<function_tdecl>();
445 shared_ptr<class_tdecl>
446 get_class_tmpl_decl(
const string&
id)
const
448 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
449 if (i == m_class_tmpl_map.end())
450 return shared_ptr<class_tdecl>();
456 get_cur_scope()
const
458 shared_ptr<decl_base> cur_decl = get_cur_decl();
460 if (
dynamic_cast<scope_decl*
>(cur_decl.get()))
462 return dynamic_pointer_cast<scope_decl>(cur_decl).get();
466 return cur_decl->get_scope();
475 if (m_decls_stack.empty())
476 return shared_ptr<decl_base>(
static_cast<decl_base*
>(0));
477 return m_decls_stack.back();
483 const global_scope* global = 0;
484 for (deque<shared_ptr<decl_base> >::reverse_iterator i =
485 m_decls_stack.rbegin();
486 i != m_decls_stack.rend();
488 if (decl_base_sptr d = *i)
493 return global->get_translation_unit();
504 type_is_from_translation_unit(type_base_sptr type)
516 push_decl(decl_base_sptr d)
518 m_decls_stack.push_back(d);
524 if (m_decls_stack.empty())
525 return decl_base_sptr();
527 shared_ptr<decl_base> t = get_cur_decl();
528 m_decls_stack.pop_back();
555 return dynamic_pointer_cast<scope_decl>(d) == scope;
568 {m_decls_stack.clear();}
572 {m_types_map.clear();}
577 clear_types_to_canonicalize()
578 {m_types_to_canonicalize.clear();}
594 types_equal(type_base_sptr t1, type_base_sptr t2)
596 if (t1.get() == t2.get())
615 key_type_decl(
const type_base_sptr& type,
const string&
id)
620 m_types_map[id].push_back(type);
635 key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
640 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
641 if (i != m_fn_tmpl_map.end())
644 m_fn_tmpl_map[id] = fn_tmpl_decl;
658 key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
663 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
664 if (i != m_class_tmpl_map.end())
667 m_class_tmpl_map[id] = class_tmpl_decl;
671#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
681 record_artifact_as_used_by(type_or_decl_base* used,
682 type_or_decl_base* user)
684 if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
686 vector<type_or_decl_base*> v;
687 m_artifact_used_by_map[used] = v;
689 m_artifact_used_by_map[used].push_back(user);
703 {record_artifact_as_used_by(used.get(), user.get());}
709 record_artifacts_as_used_in_fn_decl(
const function_decl *fn)
714 type_base_sptr t = fn->get_return_type();
715 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
717 for (
auto pit : fn->get_parameters())
719 type_base_sptr t = pit->get_type();
720 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
729 {record_artifacts_as_used_in_fn_decl(fn.get());}
735 record_artifacts_as_used_in_fn_type(
const function_type *fn_type)
740 type_base_sptr t = fn_type->get_return_type();
741 record_artifact_as_used_by(t.get(),
const_cast<function_type*
>(fn_type));
743 for (
auto pit : fn_type->get_parameters())
745 type_base_sptr t = pit->get_type();
746 record_artifact_as_used_by(t.get(),
747 const_cast<function_type*
>(fn_type));
756 {record_artifacts_as_used_in_fn_type(fn_type.get());}
768 push_decl_to_scope(
const decl_base_sptr& decl, xmlNodePtr node)
770 scope_decl* scope =
nullptr;
771 scope = get_scope_ptr_for_node(node);
772 return push_decl_to_scope(decl, scope);
781 push_decl_to_scope(
const decl_base_sptr& decl,
787 if (!decl->get_translation_unit())
806 push_and_key_type_decl(
const type_base_sptr& t,
813 push_decl_to_scope(decl, scope);
814 if (!t->get_translation_unit())
817 key_type_decl(t,
id);
832 push_and_key_type_decl(
const type_base_sptr& t,
833 const xmlNodePtr node,
834 bool add_to_current_scope)
837 if (!read_type_id_string(node,
id))
840 scope_decl* scope =
nullptr;
842 scope = get_scope_ptr_for_node(node);
843 return push_and_key_type_decl(t,
id, scope);
851 corpus::exported_decls_builder*
852 get_exported_decls_builder()
853 {
return corpus()->get_exported_decls_builder().get();}
866 corpus_is_suppressed_by_soname_or_filename(
const string& soname,
867 const string& filename)
873 for (suppressions_type::const_iterator s =
suppressions().begin();
887 clear_per_translation_unit_data()
894 clear_per_corpus_data()
897 clear_types_to_canonicalize();
898 clear_xml_node_decl_map();
899 clear_id_xml_node_map();
903#ifdef WITH_DEBUG_SELF_COMPARISON
923 maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
925 if (!get_environment().self_comparison_debug_is_on()
926 || get_environment().get_type_id_canonical_type_map().empty())
938 get_environment().get_type_id_from_pointer(
reinterpret_cast<uintptr_t
>(t.get()));
940 if (!type_id.empty())
945 auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
946 if (j == get_environment().get_type_id_canonical_type_map().end())
948 if (t->get_naked_canonical_type())
949 std::cerr <<
"error: no type with type-id: '"
951 <<
"' could be read back from the typeid file\n";
954 !=
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get()))
959 std::cerr <<
"error: canonical type for type '"
960 << t->get_pretty_representation(
true,
962 <<
"' of type-id '" << type_id
963 <<
"' changed from '" << std::hex
964 << j->second <<
"' to '" << std::hex
965 <<
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get())
979 maybe_canonicalize_type(type_base_sptr t,
980 bool force_delay =
false)
985 if (t->get_canonical_type())
1020#ifdef WITH_DEBUG_SELF_COMPARISON
1021 maybe_check_abixml_canonical_type_stability(t);
1031 schedule_type_for_late_canonicalizing(t);
1040 schedule_type_for_late_canonicalizing(type_base_sptr t)
1041 {m_types_to_canonicalize.push_back(t);}
1047 perform_late_type_canonicalizing()
1050 m_types_to_canonicalize.end(),
1051 [](
const vector<type_base_sptr>::const_iterator& i)
1068 const string& fn_name)
const
1072 return suppression_matches_function_name(*s, fn_name);
1085 corpus_sptr corp =
corpus();
1087 if (!s.priv_->matches_soname(corp->get_soname()))
1088 if (s.has_soname_related_property())
1094 if (!s.priv_->matches_binary_name(corp->get_path()))
1095 if (s.has_file_name_related_property())
1116 suppression_matches_function_name(
const suppr::function_suppression& s,
1117 const string& fn_name)
const
1119 if (!s.get_drops_artifact_from_ir()
1123 return suppr::suppression_matches_function_name(s, fn_name);
1139 const string& type_name,
1140 const location& type_location)
const
1149 virtual ir::corpus_sptr
1160 bool call_reader_next =
false;
1162 xmlNodePtr node = get_corpus_node();
1169 status = advance_cursor (*
this);
1172 BAD_CAST(
"abi-corpus")))
1175#ifdef WITH_DEBUG_SELF_COMPARISON
1176 if (get_environment().self_comparison_debug_is_on())
1177 get_environment().set_self_comparison_debug_input(
corpus());
1181 clear_per_corpus_data();
1183 ir::corpus& corp = *
corpus();
1185 corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1187 handle_version_attribute(xml_reader, corp);
1194 path =
reinterpret_cast<char*
>(path_str.get());
1196 corp.set_path(path);
1201 if (architecture_str)
1202 corp.set_architecture_name
1203 (
reinterpret_cast<char*
>(architecture_str.get()));
1211 soname =
reinterpret_cast<char*
>(soname_str.get());
1213 corp.set_soname(soname);
1223 if ((!soname.empty() || !path.empty())
1224 && corpus_is_suppressed_by_soname_or_filename(soname, path))
1227 node = xmlTextReaderExpand(xml_reader.get());
1231 call_reader_next =
true;
1235#ifdef WITH_DEBUG_SELF_COMPARISON
1236 if (get_environment().self_comparison_debug_is_on())
1237 get_environment().set_self_comparison_debug_input(
corpus());
1241 clear_per_corpus_data();
1243 ir::corpus& corp = *
corpus();
1244 corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1248 corp.set_path(
reinterpret_cast<char*
>(path_str.get()));
1252 if (architecture_str)
1253 corp.set_architecture_name
1254 (
reinterpret_cast<char*
>(architecture_str.get()));
1259 corp.set_soname(
reinterpret_cast<char*
>(soname_str.get()));
1267 xmlNodePtr n = xmlFirstElementChild(node);
1271 ir::corpus& corp = *
corpus();
1273 walk_xml_node_to_map_type_ids(*
this, node);
1276 vector<string> needed;
1277 read_elf_needed_from_input(*
this, needed);
1278 if (!needed.empty())
1279 corp.set_needed(needed);
1286 read_symbol_db_from_input(*
this, fn_sym_db, var_sym_db,
1287 non_resolved_fn_syms_aliases,
1288 non_resolved_var_syms_aliases);
1289 resolve_symbol_aliases(fn_sym_db, var_sym_db,
1290 non_resolved_fn_syms_aliases,
1291 non_resolved_var_syms_aliases);
1297 get_environment().canonicalization_is_done(
false);
1300 while (read_translation_unit_from_input(*
this))
1303 if (tracking_non_reachable_types())
1305 bool is_tracking_non_reachable_types =
false;
1306 read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1309 (corp.recording_types_reachable_from_public_interface_supported()
1310 == is_tracking_non_reachable_types);
1314 tools_utils::timer t;
1317 std::cerr <<
"perform late type canonicalization ...\n";
1321 perform_late_type_canonicalizing();
1326 std::cerr <<
"late type canonicalization DONE@"
1328 <<
":" << t <<
"\n";
1331 get_environment().canonicalization_is_done(
true);
1333 if (call_reader_next)
1337 xmlTextReaderNext(xml_reader.get());
1345 node = get_corpus_node();
1346 node = xmlNextElementSibling(node);
1349 node = get_corpus_node();
1351 node = xmlNextElementSibling(node->parent);
1353 set_corpus_node(node);
1356 corpus()->sort_functions();
1357 corpus()->sort_variables();
1364typedef shared_ptr<reader> reader_sptr;
1366static int advance_cursor(reader&);
1367static bool read_translation_unit(fe_iface&, translation_unit&, xmlNodePtr);
1370static bool read_symbol_db_from_input(reader&,
1375static bool read_location(
const reader&, xmlNodePtr, location&);
1376static bool read_artificial_location(
const reader&,
1377 xmlNodePtr, location&);
1378static bool maybe_set_artificial_location(
const reader&,
1384static bool read_size_and_alignment(xmlNodePtr,
size_t&,
size_t&);
1385static bool read_static(xmlNodePtr,
bool&);
1386static bool read_offset_in_bits(xmlNodePtr,
size_t&);
1387static bool read_cdtor_const(xmlNodePtr,
bool&,
bool&,
bool&);
1388static bool read_is_virtual(xmlNodePtr,
bool&);
1389static bool read_is_struct(xmlNodePtr,
bool&);
1390static bool read_is_anonymous(xmlNodePtr,
bool&);
1393static bool read_elf_symbol_visibility(xmlNodePtr,
1397build_namespace_decl(reader&,
const xmlNodePtr,
bool);
1407build_elf_symbol(reader&,
const xmlNodePtr,
bool);
1410build_elf_symbol_from_reference(reader&,
const xmlNodePtr);
1413build_elf_symbol_db(reader&,
const xmlNodePtr,
bool,
1418build_function_parameter (reader&,
const xmlNodePtr);
1421build_function_decl(reader&,
const xmlNodePtr,
1422 class_or_union_sptr,
bool,
bool);
1425build_function_decl_if_not_suppressed(reader&,
const xmlNodePtr,
1426 class_or_union_sptr,
bool,
bool);
1429function_is_suppressed(
const reader& rdr,
1433build_var_decl_if_not_suppressed(reader&,
const xmlNodePtr,
bool);
1436build_var_decl(reader&,
const xmlNodePtr,
bool);
1439variable_is_suppressed(
const reader& rdr,
1442static shared_ptr<type_decl>
1443build_type_decl(reader&,
const xmlNodePtr,
bool);
1445static qualified_type_def_sptr
1446build_qualified_type_decl(reader&,
const xmlNodePtr,
bool);
1448static shared_ptr<pointer_type_def>
1449build_pointer_type_def(reader&,
const xmlNodePtr,
bool);
1451static shared_ptr<reference_type_def>
1452build_reference_type_def(reader&,
const xmlNodePtr,
bool);
1455build_ptr_to_mbr_type(reader&,
const xmlNodePtr,
bool);
1457static shared_ptr<function_type>
1458build_function_type(reader&,
const xmlNodePtr,
bool);
1461build_subrange_type(reader&,
const xmlNodePtr,
bool);
1464build_array_type_def(reader&,
const xmlNodePtr,
bool);
1467build_enum_type_decl(reader&,
const xmlNodePtr,
bool);
1469static shared_ptr<typedef_decl>
1470build_typedef_decl(reader&,
const xmlNodePtr,
bool);
1473build_class_decl(reader&,
const xmlNodePtr,
bool);
1475static union_decl_sptr
1476build_union_decl(reader&,
const xmlNodePtr,
bool);
1478static shared_ptr<function_tdecl>
1479build_function_tdecl(reader&,
const xmlNodePtr,
bool);
1481static shared_ptr<class_tdecl>
1482build_class_tdecl(reader&,
const xmlNodePtr,
bool);
1485build_type_tparameter(reader&,
const xmlNodePtr,
1489build_type_composition(reader&,
const xmlNodePtr,
1493build_non_type_tparameter(reader&,
const xmlNodePtr,
1497build_template_tparameter(reader&,
const xmlNodePtr,
1501build_template_parameter(reader&,
const xmlNodePtr,
1508static shared_ptr<type_base>
1509build_type(reader&,
const xmlNodePtr,
bool);
1513static decl_base_sptr handle_type_decl(reader&, xmlNodePtr,
bool);
1514static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr,
bool);
1515static decl_base_sptr handle_qualified_type_decl(reader&,
1517static decl_base_sptr handle_pointer_type_def(reader&,
1519static decl_base_sptr handle_reference_type_def(reader&,
1521static type_base_sptr handle_function_type(reader&,
1523static decl_base_sptr handle_array_type_def(reader&,
1525static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr,
bool);
1526static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr,
bool);
1527static decl_base_sptr handle_var_decl(reader&, xmlNodePtr,
bool);
1528static decl_base_sptr handle_function_decl(reader&, xmlNodePtr,
bool);
1529static decl_base_sptr handle_class_decl(reader&, xmlNodePtr,
bool);
1530static decl_base_sptr handle_union_decl(reader&, xmlNodePtr,
bool);
1531static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr,
bool);
1532static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr,
bool);
1534#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1535#define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1536 rdr.record_artifact_as_used_by(used,user)
1537#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1538 rdr.record_artifacts_as_used_in_fn_decl(fn)
1539#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1540 rdr.record_artifacts_as_used_in_fn_type(fn_type)
1542#define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1543#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1544#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1567 xmlNodePtr parent = node->parent;
1570 && (xmlStrEqual(parent->name, BAD_CAST(
"data-member"))
1571 || xmlStrEqual(parent->name, BAD_CAST(
"member-type"))
1572 || xmlStrEqual(parent->name, BAD_CAST(
"member-function"))
1573 || xmlStrEqual(parent->name, BAD_CAST(
"member-template"))
1574 || xmlStrEqual(parent->name, BAD_CAST(
"template-parameter-type-composition"))
1575 || xmlStrEqual(parent->name, BAD_CAST(
"array-type-def"))))
1577 read_access(parent, access);
1578 parent = parent->parent;
1581 xml_node_decl_base_sptr_map::const_iterator i =
1582 get_xml_node_decl_map().find(parent);
1583 if (i == get_xml_node_decl_map().end())
1585 if (xmlStrEqual(parent->name, BAD_CAST(
"abi-instr")))
1588 get_or_read_and_add_translation_unit(*
this, parent);
1589 return tu->get_global_scope();
1594 push_decl(parent_scope);
1595 scope = dynamic_pointer_cast<scope_decl>
1596 (handle_element_node(*
this, parent,
true));
1598 pop_scope_or_abort(parent_scope);
1601 scope = dynamic_pointer_cast<scope_decl>(i->second);
1616reader::get_scope_for_node(xmlNodePtr node)
1619 return get_scope_for_node(node, access);
1632reader::get_scope_ptr_for_node(xmlNodePtr node)
1652 type_base_sptr t = get_type_decl(
id);
1656 xmlNodePtr n = get_xml_node_from_id(
id);
1663 scope = get_scope_for_node(n, access);
1671 if ((t = get_type_decl(
id)))
1689 pop_scope_or_abort(scope);
1703advance_cursor(reader& rdr)
1706 return xmlTextReaderRead(reader.get());
1718walk_xml_node_to_map_type_ids(reader& rdr,
1721 xmlNodePtr n = node;
1723 if (!n || n->type != XML_ELEMENT_NODE)
1728 string id = CHAR_STR(s);
1729 rdr.map_id_and_node(
id, n);
1732 for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1733 walk_xml_node_to_map_type_ids(rdr, n);
1737read_translation_unit(fe_iface& iface, translation_unit& tu, xmlNodePtr node)
1739 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1741 if (!rdr.corpus()->is_empty())
1742 tu.set_corpus(rdr.corpus().get());
1748 char address_size = atoi(
reinterpret_cast<char*
>(addrsize_str.get()));
1749 tu.set_address_size(address_size);
1754 tu.set_path(
reinterpret_cast<char*
>(path_str.get()));
1758 if (comp_dir_path_str)
1759 tu.set_compilation_dir_path(
reinterpret_cast<char*
>
1760 (comp_dir_path_str.get()));
1765 (
reinterpret_cast<char*
>(language_str.get())));
1770 rdr.push_decl(tu.get_global_scope());
1771 rdr.map_xml_node_to_decl(node, tu.get_global_scope());
1773 if (rdr.get_id_xml_node_map().empty()
1775 walk_xml_node_to_map_type_ids(rdr, node);
1777 for (xmlNodePtr n = xmlFirstElementChild(node);
1779 n = xmlNextElementSibling(n))
1780 handle_element_node(rdr, n,
true);
1782 rdr.pop_scope_or_abort(tu.get_global_scope());
1788 rdr.clear_per_translation_unit_data();
1807get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1809 corpus_sptr corp = rdr.corpus();
1817 tu_path =
reinterpret_cast<char*
>(path_str.get());
1820 if (corp && !corp->is_empty())
1821 tu = corp->find_translation_unit(tu_path);
1827 tu.reset(
new translation_unit(rdr.get_environment(), tu_path));
1828 if (corp && !corp->is_empty())
1831 if (read_translation_unit(rdr, *tu, node))
1846read_translation_unit_from_input(fe_iface& iface)
1850 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1852 xmlNodePtr node = rdr.get_corpus_node();
1863 status = advance_cursor (rdr);
1866 BAD_CAST(
"abi-instr")))
1869 node = xmlTextReaderExpand(reader.get());
1876 for (xmlNodePtr n = rdr.get_corpus_node();
1878 n = xmlNextElementSibling(n))
1880 if (!xmlStrEqual(n->name, BAD_CAST(
"abi-instr")))
1890 tu = get_or_read_and_add_translation_unit(rdr, node);
1892 if (rdr.get_corpus_node())
1898 node = xmlNextElementSibling(node);
1899 rdr.set_corpus_node(node);
1952read_symbol_db_from_input(reader& rdr,
1962 if (!rdr.get_corpus_node())
1968 status = advance_cursor (rdr);
1973 bool has_fn_syms =
false, has_undefined_fn_syms =
false,
1974 has_var_syms =
false, has_undefined_var_syms =
false;
1976 BAD_CAST(
"elf-function-symbols")))
1979 BAD_CAST(
"elf-variable-symbols")))
1980 has_var_syms =
true;
1982 BAD_CAST(
"undefined-elf-function-symbols")))
1983 has_undefined_fn_syms =
true;
1985 BAD_CAST(
"undefined-elf-variable-symbols")))
1986 has_undefined_var_syms =
true;
1990 xmlNodePtr node = xmlTextReaderExpand(reader.get());
1995 build_elf_symbol_db(rdr, node,
true, fn_symdb,
1996 non_resolved_fn_syms_aliases);
1997 else if (has_undefined_fn_syms)
1998 build_elf_symbol_db(rdr, node,
true, fn_symdb,
1999 non_resolved_fn_syms_aliases);
2000 else if (has_var_syms)
2001 build_elf_symbol_db(rdr, node,
false, var_symdb,
2002 non_resolved_var_syms_aliases);
2003 else if (has_undefined_var_syms)
2004 build_elf_symbol_db(rdr, node,
false, var_symdb,
2005 non_resolved_var_syms_aliases);
2007 xmlTextReaderNext(reader.get());
2010 for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
2012 bool has_fn_syms =
false, has_undefined_fn_syms =
false,
2013 has_var_syms =
false, has_undefined_var_syms =
false;
2014 if (xmlStrEqual(n->name, BAD_CAST(
"elf-function-symbols")))
2016 else if (xmlStrEqual(n->name, BAD_CAST(
"undefined-elf-function-symbols")))
2017 has_undefined_fn_syms =
true;
2018 else if (xmlStrEqual(n->name, BAD_CAST(
"elf-variable-symbols")))
2019 has_var_syms =
true;
2020 else if (xmlStrEqual(n->name,
2021 BAD_CAST(
"undefined-elf-variable-symbols")))
2022 has_undefined_var_syms =
true;
2025 rdr.set_corpus_node(n);
2030 build_elf_symbol_db(rdr, n,
true, fn_symdb,
2031 non_resolved_fn_syms_aliases);
2032 else if (has_undefined_fn_syms)
2033 build_elf_symbol_db(rdr, n,
true, fn_symdb,
2034 non_resolved_fn_syms_aliases);
2035 else if (has_var_syms)
2036 build_elf_symbol_db(rdr, n,
false, var_symdb,
2037 non_resolved_var_syms_aliases);
2038 else if (has_undefined_var_syms)
2039 build_elf_symbol_db(rdr, n,
false, var_symdb,
2040 non_resolved_var_syms_aliases);
2059build_needed(xmlNode* node, vector<string>& needed)
2061 if (!node || !xmlStrEqual(node->name,BAD_CAST(
"elf-needed")))
2064 for (xmlNodePtr n = xmlFirstElementChild(node);
2066 n = xmlNextElementSibling(n))
2068 if (!xmlStrEqual(n->name, BAD_CAST(
"dependency")))
2076 needed.push_back(name);
2092read_elf_needed_from_input(reader& rdr,
2093 vector<string>& needed)
2099 xmlNodePtr node = 0;
2101 if (rdr.get_corpus_node() == 0)
2106 status = advance_cursor (rdr);
2112 BAD_CAST(
"elf-needed")))
2115 node = xmlTextReaderExpand(reader.get());
2121 for (xmlNodePtr n = rdr.get_corpus_node();
2123 n = xmlNextElementSibling(n))
2125 if (!xmlStrEqual(n->name, BAD_CAST(
"elf-needed")))
2132 bool result =
false;
2135 result = build_needed(node, needed);
2136 node = xmlNextElementSibling(node);
2137 rdr.set_corpus_node(node);
2172 for (suppr::suppressions_type::const_iterator i = supprs.begin();
2175 if ((*i)->get_drops_artifact_from_ir())
2176 rdr.suppressions().push_back(*i);
2191 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2192 rdr.tracking_non_reachable_types(flag);
2195#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2204vector<type_base_sptr>*
2205get_types_from_type_id(
fe_iface& iface,
const string& type_id)
2207 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2208 auto it = rdr.m_types_map.find(type_id);
2209 if (it == rdr.m_types_map.end())
2220unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2221get_artifact_used_by_relation_map(fe_iface& iface)
2223 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2224 return &rdr.m_artifact_used_by_map;
2244 string version_string;
2249 if (version_string.empty())
2256 corp.set_format_major_version_number(v[0]);
2257 corp.set_format_minor_version_number(v[1]);
2270 corpus_group_sptr nil;
2272 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2281 status = advance_cursor (rdr);
2284 BAD_CAST(
"abi-corpus-group")))
2287 if (!rdr.corpus_group())
2289 corpus_group_sptr g(
new corpus_group(rdr.get_environment(),
2291 g->set_origin(corpus::NATIVE_XML_ORIGIN);
2292 rdr.corpus_group(g);
2295 corpus_group_sptr group = rdr.corpus_group();
2297 handle_version_attribute(reader, *group);
2301 group->set_path(
reinterpret_cast<char*
>(path_str.get()));
2303 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2307 node = xmlFirstElementChild(node);
2308 rdr.set_corpus_node(node);
2312 while ((corp = rdr.read_corpus(sts)))
2313 rdr.corpus_group()->add_corpus(corp);
2315 xmlTextReaderNext(reader.get());
2317 return rdr.corpus_group();
2379 rdr.perform_late_type_canonicalizing();
2401 rdr.perform_late_type_canonicalizing();
2416 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2418 rdr.options().env.canonicalization_is_done(
false);
2419 rdr.perform_late_type_canonicalizing();
2420 rdr.options().env.canonicalization_is_done(
true);
2433handle_element_node(reader& rdr, xmlNodePtr node,
2434 bool add_to_current_scope)
2440 ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2441 ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2442 ||(decl = handle_qualified_type_decl(rdr, node,
2443 add_to_current_scope))
2444 ||(decl = handle_pointer_type_def(rdr, node,
2445 add_to_current_scope))
2446 || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2447 || (decl = handle_function_type(rdr, node, add_to_current_scope))
2448 || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2449 || (decl = handle_enum_type_decl(rdr, node,
2450 add_to_current_scope))
2451 || (decl = handle_typedef_decl(rdr, node,
2452 add_to_current_scope))
2453 || (decl = handle_var_decl(rdr, node,
2454 add_to_current_scope))
2455 || (decl = handle_function_decl(rdr, node,
2456 add_to_current_scope))
2457 || (decl = handle_class_decl(rdr, node,
2458 add_to_current_scope))
2459 || (decl = handle_union_decl(rdr, node,
2460 add_to_current_scope))
2461 || (decl = handle_function_tdecl(rdr, node,
2462 add_to_current_scope))
2463 || (decl = handle_class_tdecl(rdr, node,
2464 add_to_current_scope)));
2469 if (rdr.tracking_non_reachable_types())
2471 if (type_base_sptr t =
is_type(decl))
2473 corpus_sptr abi = rdr.corpus();
2475 bool is_non_reachable_type =
false;
2476 read_is_non_reachable_type(node, is_non_reachable_type);
2477 if (!is_non_reachable_type)
2478 abi->record_type_as_reachable_from_public_interfaces(*t);
2493read_location(
const reader& rdr,
2498 size_t line = 0, column = 0;
2501 file_path = CHAR_STR(f);
2503 if (file_path.empty())
2504 return read_artificial_location(rdr, node, loc);
2507 line = atoi(CHAR_STR(l));
2509 return read_artificial_location(rdr, node, loc);
2512 column = atoi(CHAR_STR(c));
2514 reader& c =
const_cast<reader&
>(rdr);
2515 loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2532read_artificial_location(
const reader& rdr,
2540 size_t line = 0, column = 0;
2545 file_path =
reinterpret_cast<const char*
>(node->doc->URL);
2547 reader& c =
const_cast<reader&
>(rdr);
2549 c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2551 loc.set_is_artificial(
true);
2571maybe_set_artificial_location(
const reader& rdr,
2575 if (artefact && !artefact->has_artificial_location())
2578 if (read_artificial_location(rdr, node, l))
2580 artefact->set_artificial_location(l);
2599 string v = CHAR_STR(s);
2602 vis = decl_base::VISIBILITY_DEFAULT;
2603 else if (v ==
"hidden")
2604 vis = decl_base::VISIBILITY_HIDDEN;
2605 else if (v ==
"internal")
2606 vis = decl_base::VISIBILITY_INTERNAL;
2607 else if (v ==
"protected")
2608 vis = decl_base::VISIBILITY_PROTECTED;
2610 vis = decl_base::VISIBILITY_DEFAULT;
2628 string b = CHAR_STR(s);
2631 bind = decl_base::BINDING_GLOBAL;
2632 else if (b ==
"local")
2633 bind = decl_base::BINDING_LOCAL;
2634 else if (b ==
"weak")
2635 bind = decl_base::BINDING_WEAK;
2637 bind = decl_base::BINDING_GLOBAL;
2656 string a = CHAR_STR(s);
2659 access = private_access;
2660 else if (a ==
"protected")
2661 access = protected_access;
2662 else if (a ==
"public")
2663 access = public_access;
2691read_size_and_alignment(xmlNodePtr node,
2692 size_t& size_in_bits,
2693 size_t& align_in_bits)
2696 bool got_something =
false;
2699 size_in_bits = atoll(CHAR_STR(s));
2700 got_something =
true;
2705 align_in_bits = atoll(CHAR_STR(s));
2706 got_something =
true;
2708 return got_something;
2721read_static(xmlNodePtr node,
bool& is_static)
2725 string b = CHAR_STR(s);
2726 is_static = b ==
"yes";
2739read_offset_in_bits(xmlNodePtr node,
2740 size_t& offset_in_bits)
2744 offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2772read_cdtor_const(xmlNodePtr node,
2773 bool& is_constructor,
2774 bool& is_destructor,
2779 string b = CHAR_STR(s);
2781 is_constructor =
true;
2783 is_constructor =
false;
2790 string b = CHAR_STR(s);
2792 is_destructor =
true;
2794 is_destructor =
false;
2801 string b = CHAR_STR(s);
2822read_is_declaration_only(xmlNodePtr node,
bool& is_decl_only)
2826 string str = CHAR_STR(s);
2828 is_decl_only =
true;
2830 is_decl_only =
false;
2846read_is_artificial(xmlNodePtr node,
bool& is_artificial)
2850 string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2851 is_artificial = is_artificial_str ==
"yes";
2870read_tracking_non_reachable_types(xmlNodePtr node,
2871 bool& tracking_non_reachable_types)
2876 string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2877 tracking_non_reachable_types =
2878 (tracking_non_reachable_types_str ==
"yes")
2897read_is_non_reachable_type(xmlNodePtr node,
bool& is_non_reachable_type)
2902 string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2903 is_non_reachable_type =
2904 (is_non_reachable_type_str ==
"yes")
2922read_naming_typedef_id_string(xmlNodePtr node,
string& naming_typedef_id)
2941read_is_virtual(xmlNodePtr node,
bool& is_virtual)
2945 string str = CHAR_STR(s);
2964read_is_struct(xmlNodePtr node,
bool& is_struct)
2968 string str = CHAR_STR(s);
2987read_is_anonymous(xmlNodePtr node,
bool& is_anonymous)
2991 string str = CHAR_STR(s);
2992 is_anonymous = (str ==
"yes");
3069read_type_id_string(xmlNodePtr node,
string& type_id)
3073 type_id = CHAR_STR(s);
3079#ifdef WITH_DEBUG_SELF_COMPARISON
3094maybe_map_type_with_type_id(
const type_base_sptr& t,
3095 const string& type_id)
3100 const environment& env = t->get_environment();
3101 if (!env.self_comparison_debug_is_on()
3105 const_cast<environment&
>(env).
3106 get_pointer_type_id_map()[
reinterpret_cast<uintptr_t
>(t.get())] = type_id;
3125maybe_map_type_with_type_id(
const type_base_sptr& t,
3131 const environment&env = t->get_environment();
3132 if (!env.self_comparison_debug_is_on()
3137 if (!read_type_id_string(node, type_id) || type_id.empty())
3140 return maybe_map_type_with_type_id(t, type_id);
3154maybe_set_naming_typedef(reader& rdr,
3156 const decl_base_sptr& decl)
3158 string naming_typedef_id;
3159 read_naming_typedef_id_string(node, naming_typedef_id);
3160 if (!naming_typedef_id.empty())
3163 is_typedef(rdr.build_or_get_type_decl(naming_typedef_id,
true));
3165 decl->set_naming_typedef(naming_typedef);
3185build_namespace_decl(reader& rdr,
3186 const xmlNodePtr node,
3187 bool add_to_current_scope)
3190 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"namespace-decl")))
3193 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3205 read_location(rdr, node, loc);
3207 const environment& env = rdr.get_environment();
3209 maybe_set_artificial_location(rdr, node, decl);
3210 rdr.push_decl_to_scope(decl,
3211 add_to_current_scope
3212 ? rdr.get_scope_ptr_for_node(node)
3214 rdr.map_xml_node_to_decl(node, decl);
3216 for (xmlNodePtr n = xmlFirstElementChild(node);
3218 n = xmlNextElementSibling(n))
3219 handle_element_node(rdr, n,
true);
3221 rdr.pop_scope_or_abort(decl);
3238build_elf_symbol(reader& rdr,
const xmlNodePtr node,
3239 bool drop_if_suppressed)
3244 || node->type != XML_ELEMENT_NODE
3245 || !xmlStrEqual(node->name, BAD_CAST(
"elf-symbol")))
3254 size = strtol(CHAR_STR(s), NULL, 0);
3256 bool is_defined =
true;
3261 if (value ==
"true" || value ==
"yes")
3267 bool is_common =
false;
3272 if (value ==
"true" || value ==
"yes")
3278 string version_string;
3282 bool is_default_version =
false;
3287 if (value ==
"true" || value ==
"yes")
3288 is_default_version =
true;
3292 read_elf_symbol_type(node, type);
3295 read_elf_symbol_binding(node, binding);
3298 read_elf_symbol_visibility(node, visibility);
3300 elf_symbol::version version(version_string, is_default_version);
3303 if (drop_if_suppressed && is_suppressed)
3306 const environment& env = rdr.get_environment();
3308 size, name, type, binding,
3309 is_defined, is_common,
3310 version, visibility);
3312 e->set_is_suppressed(is_suppressed);
3315 e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3321 e->set_namespace(ns);
3341build_elf_symbol_from_reference(reader& rdr,
const xmlNodePtr node)
3360 if (rdr.corpus()->get_symtab())
3363 rdr.corpus()->get_symtab()->lookup_symbol(name);
3365 for (
const auto& symbol : symbols)
3366 if (symbol->get_id_string() == sym_id)
3399build_elf_symbol_db(reader& rdr,
3400 const xmlNodePtr node,
3411 && !xmlStrEqual(node->name, BAD_CAST(
"elf-function-symbols"))
3412 && !xmlStrEqual(node->name, BAD_CAST(
"undefined-elf-function-symbols")))
3416 && !xmlStrEqual(node->name, BAD_CAST(
"elf-variable-symbols"))
3417 && !xmlStrEqual(node->name, BAD_CAST(
"undefined-elf-variable-symbols")))
3420 rdr.set_corpus_node(node);
3422 typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3423 xml_node_ptr_elf_symbol_sptr_map_type;
3424 xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3427 for (xmlNodePtr n = xmlFirstElementChild(node);
3429 n = xmlNextElementSibling(n))
3430 if ((sym = build_elf_symbol(rdr, n,
false)))
3432 id_sym_map[sym->get_id_string()] = sym;
3433 xml_node_ptr_elf_symbol_map[n] = sym;
3436 if (id_sym_map.empty())
3439 string_elf_symbols_map_type::iterator it;
3440 for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3441 i != id_sym_map.end();
3443 (*map)[i->second->get_name()].push_back(i->second);
3446 for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3447 xml_node_ptr_elf_symbol_map.begin();
3448 x != xml_node_ptr_elf_symbol_map.end();
3453 string alias_id = CHAR_STR(s);
3456 std::vector<std::string> elems;
3457 std::stringstream aliases(alias_id);
3459 while (std::getline(aliases, item,
','))
3460 elems.push_back(item);
3461 for (std::vector<string>::iterator alias = elems.begin();
3462 alias != elems.end(); ++alias)
3464 string_elf_symbol_sptr_map_type::const_iterator i =
3465 id_sym_map.find(*alias);
3466 if (i == id_sym_map.end())
3472 non_resolved_aliases[x->second->get_name()].push_back(*alias);
3476 x->second->get_main_symbol()->add_alias(i->second);
3514 for (
auto& entry : non_resolved_fn_sym_aliases)
3516 auto i = fn_syms->find(entry.first);
3521 sym = sym->get_main_symbol();
3523 for (
string& alias : entry.second)
3525 auto fn_a = fn_syms->find(alias);
3526 if (fn_a == fn_syms->end())
3530 auto var_a = var_syms->find(alias);
3532 alias_sym = var_a->second.front();
3537 alias_sym = fn_a->second.front();
3540 sym->add_alias(alias_sym);
3544 for (
auto& entry : non_resolved_var_sym_aliases)
3546 auto i = var_syms->find(entry.first);
3551 sym = sym->get_main_symbol();
3553 for (
string& alias : entry.second)
3555 auto var_a = var_syms->find(alias);
3556 if (var_a == var_syms->end())
3560 auto fn_a = fn_syms->find(alias);
3562 alias_sym = fn_a->second.front();
3567 alias_sym = var_a->second.front();
3570 sym->add_alias(alias_sym);
3580static shared_ptr<function_decl::parameter>
3581build_function_parameter(reader& rdr,
const xmlNodePtr node)
3583 shared_ptr<function_decl::parameter> nil;
3585 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"parameter")))
3588 bool is_variadic =
false;
3589 string is_variadic_str;
3593 is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
3594 is_variadic = is_variadic_str ==
"yes";
3597 bool is_artificial =
false;
3598 read_is_artificial(node, is_artificial);
3602 type_id = CHAR_STR(a);
3604 type_base_sptr type;
3606 type = rdr.get_environment().get_variadic_parameter_type();
3610 type = rdr.build_or_get_type_decl(type_id,
true);
3619 read_location(rdr, node, loc);
3622 (
new function_decl::parameter(type, name, loc,
3623 is_variadic, is_artificial));
3651build_function_decl(reader& rdr,
3652 const xmlNodePtr node,
3653 class_or_union_sptr as_method_decl,
3654 bool add_to_current_scope,
3655 bool add_to_exported_decls)
3659 if (!xmlStrEqual(node->name, BAD_CAST(
"function-decl")))
3666 string mangled_name;
3671 && !mangled_name.empty()
3672 && as_method_decl->find_member_function_sptr(mangled_name))
3675 as_method_decl->find_member_function_sptr(mangled_name);
3682 inline_prop = CHAR_STR(s);
3683 bool declared_inline = inline_prop ==
"yes";
3686 read_visibility(node, vis);
3689 read_binding(node, bind);
3691 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3692 read_size_and_alignment(node, size, align);
3695 read_location(rdr, node, loc);
3697 const environment& env = rdr.get_environment();
3699 std::vector<function_decl::parameter_sptr> parms;
3700 type_base_sptr return_type = env.get_void_type();
3702 for (xmlNodePtr n = xmlFirstElementChild(node);
3704 n = xmlNextElementSibling(n))
3706 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
3709 build_function_parameter(rdr, n))
3712 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
3717 type_id = CHAR_STR(s);
3718 if (!type_id.empty())
3719 return_type = rdr.build_or_get_type_decl(type_id,
true);
3724 ?
new method_type(return_type, as_method_decl,
3727 :
new function_type(return_type,
3728 parms, size, align));
3732 fn_type->set_is_artificial(
true);
3735 ?
new method_decl (name, fn_type,
3736 declared_inline, loc,
3737 mangled_name, vis, bind)
3738 :
new function_decl(name, fn_type,
3739 declared_inline, loc,
3743 maybe_set_artificial_location(rdr, node, fn_decl);
3744 rdr.push_decl_to_scope(fn_decl,
3745 add_to_current_scope
3746 ? rdr.get_scope_ptr_for_node(node)
3748 RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3752 fn_decl->set_symbol(sym);
3754 if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3755 fn_decl->set_is_in_public_symbol_table(
true);
3757 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3759 rdr.maybe_canonicalize_type(fn_type, !add_to_current_scope);
3761 if (add_to_exported_decls)
3762 rdr.add_fn_to_exported_or_undefined_decls(fn_decl.get());
3793build_function_decl_if_not_suppressed(reader& rdr,
3794 const xmlNodePtr node,
3795 class_or_union_sptr as_method_decl,
3796 bool add_to_current_scope,
3797 bool add_to_exported_decls)
3801 if (function_is_suppressed(rdr, node))
3807 fn = build_function_decl(rdr, node, as_method_decl,
3808 add_to_current_scope,
3809 add_to_exported_decls);
3825function_is_suppressed(
const reader& rdr, xmlNodePtr node)
3831 string flinkage_name;
3835 scope_decl* scope = rdr.get_cur_scope();
3854type_is_suppressed(
const reader& rdr, xmlNodePtr node)
3860 location type_location;
3861 read_location(rdr, node, type_location);
3863 scope_decl* scope = rdr.get_cur_scope();
3867 bool type_is_private =
false;
3886build_var_decl_if_not_suppressed(reader& rdr,
3887 const xmlNodePtr node,
3888 bool add_to_current_scope)
3891 if (!variable_is_suppressed(rdr, node))
3892 var = build_var_decl(rdr, node, add_to_current_scope);
3905variable_is_suppressed(
const reader& rdr, xmlNodePtr node)
3911 string linkage_name;
3915 scope_decl* scope = rdr.get_cur_scope();
3933variable_is_suppressed(
const reader& rdr,
3934 const scope_decl* scope,
3939 v.get_linkage_name());
3950static shared_ptr<var_decl>
3951build_var_decl(reader& rdr,
3952 const xmlNodePtr node,
3953 bool add_to_current_scope)
3955 shared_ptr<var_decl> nil;
3957 if (!xmlStrEqual(node->name, BAD_CAST(
"var-decl")))
3966 type_id = CHAR_STR(s);
3967 type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
3971 string mangled_name;
3976 read_visibility(node, vis);
3979 read_binding(node, bind);
3982 read_location(rdr, node, locus);
3985 locus, mangled_name,
3987 maybe_set_artificial_location(rdr, node, decl);
3991 decl->set_symbol(sym);
3993 rdr.push_decl_to_scope(decl,
3994 add_to_current_scope
3995 ? rdr.get_scope_ptr_for_node(node)
3997 if (add_to_current_scope)
4001 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4004 if (decl->get_symbol() && decl->get_symbol()->is_public())
4005 decl->set_is_in_public_symbol_table(
true);
4015static decl_base_sptr
4016build_ir_node_for_void_type(reader& rdr)
4018 const environment& env = rdr.get_environment();
4020 type_base_sptr t = env.get_void_type();
4024 return type_declaration;
4038static decl_base_sptr
4039build_ir_node_for_void_pointer_type(reader& rdr)
4041 const environment& env = rdr.get_environment();
4043 type_base_sptr t = env.get_void_pointer_type();
4047 return type_declaration;
4062build_type_decl(reader& rdr,
4063 const xmlNodePtr node,
4064 bool add_to_current_scope)
4066 shared_ptr<type_decl> nil;
4068 if (!xmlStrEqual(node->name, BAD_CAST(
"type-decl")))
4071 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4087 size_t size_in_bits= 0;
4089 size_in_bits = atoi(CHAR_STR(s));
4091 size_t alignment_in_bits = 0;
4093 alignment_in_bits = atoi(CHAR_STR(s));
4095 bool is_decl_only =
false;
4096 read_is_declaration_only(node, is_decl_only);
4099 read_location(rdr, node, loc);
4101 bool is_anonymous =
false;
4102 read_is_anonymous(node, is_anonymous);
4104 if (type_base_sptr d = rdr.get_type_decl(
id))
4112 ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
4113 ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
4117 const environment& env = rdr.get_environment();
4119 if (name == env.get_variadic_parameter_type_name())
4120 decl =
is_type_decl(env.get_variadic_parameter_type());
4121 else if (name ==
"void")
4124 decl.reset(
new type_decl(env, name, size_in_bits,
4125 alignment_in_bits, loc));
4126 maybe_set_artificial_location(rdr, node, decl);
4127 decl->set_is_anonymous(is_anonymous);
4128 decl->set_is_declaration_only(is_decl_only);
4129 if (rdr.push_and_key_type_decl(decl, node, add_to_current_scope))
4131 rdr.map_xml_node_to_decl(node, decl);
4149static qualified_type_def_sptr
4150build_qualified_type_decl(reader& rdr,
4151 const xmlNodePtr node,
4152 bool add_to_current_scope)
4154 qualified_type_def_sptr nil;
4155 if (!xmlStrEqual(node->name, BAD_CAST(
"qualified-type-def")))
4158 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4160 qualified_type_def_sptr result =
4161 dynamic_pointer_cast<qualified_type_def>(d);
4173 read_location(rdr, node, loc);
4178 const_str = CHAR_STR(s);
4179 bool const_cv = const_str ==
"yes";
4181 string volatile_str;
4183 volatile_str = CHAR_STR(s);
4184 bool volatile_cv = volatile_str ==
"yes";
4186 string restrict_str;
4188 restrict_str = CHAR_STR(s);
4189 bool restrict_cv = restrict_str ==
"yes";
4192 cv = cv | qualified_type_def::CV_CONST;
4194 cv = cv | qualified_type_def::CV_VOLATILE;
4196 cv = cv | qualified_type_def::CV_RESTRICT;
4200 type_id = CHAR_STR(s);
4203 shared_ptr<type_base> underlying_type =
4204 rdr.build_or_get_type_decl(type_id,
true);
4207 qualified_type_def_sptr decl;
4208 if (type_base_sptr t = rdr.get_type_decl(
id))
4215 decl.reset(
new qualified_type_def(underlying_type, cv, loc));
4216 maybe_set_artificial_location(rdr, node, decl);
4217 rdr.push_and_key_type_decl(decl, node, add_to_current_scope);
4218 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4221 rdr.map_xml_node_to_decl(node, decl);
4238build_pointer_type_def(reader& rdr,
4239 const xmlNodePtr node,
4240 bool add_to_current_scope)
4243 shared_ptr<pointer_type_def> nil;
4245 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-type-def")))
4248 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4251 dynamic_pointer_cast<pointer_type_def>(d);
4261 if (type_base_sptr t = rdr.get_type_decl(
id))
4270 type_id = CHAR_STR(s);
4272 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4273 size_t alignment_in_bits = 0;
4274 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4276 read_location(rdr, node, loc);
4278 type_base_sptr pointed_to_type =
4279 rdr.build_or_get_type_decl(type_id,
true);
4283 if (rdr.get_environment().is_void_type(pointed_to_type))
4291 t.reset(
new pointer_type_def(pointed_to_type,
4296 maybe_set_artificial_location(rdr, node, t);
4298 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4299 rdr.map_xml_node_to_decl(node, t);
4301 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4317static shared_ptr<reference_type_def>
4318build_reference_type_def(reader& rdr,
4319 const xmlNodePtr node,
4320 bool add_to_current_scope)
4322 shared_ptr<reference_type_def> nil;
4324 if (!xmlStrEqual(node->name, BAD_CAST(
"reference-type-def")))
4327 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4330 dynamic_pointer_cast<reference_type_def>(d);
4340 if (type_base_sptr d = rdr.get_type_decl(
id))
4348 read_location(rdr, node, loc);
4352 bool is_lvalue = kind ==
"lvalue";
4354 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4355 size_t alignment_in_bits = 0;
4356 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4360 type_id = CHAR_STR(s);
4370 is_lvalue, size_in_bits,
4371 alignment_in_bits, loc));
4372 maybe_set_artificial_location(rdr, node, t);
4373 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4374 rdr.map_xml_node_to_decl(node, t);
4376 type_base_sptr pointed_to_type =
4377 rdr.build_or_get_type_decl(type_id,
true);
4379 t->set_pointed_to_type(pointed_to_type);
4380 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4398build_ptr_to_mbr_type(reader& rdr,
4399 const xmlNodePtr node,
4400 bool add_to_current_scope)
4404 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-to-member-type")))
4407 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4421 if (type_base_sptr d = rdr.get_type_decl(
id))
4428 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4429 size_t alignment_in_bits = 0;
4430 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4433 read_location(rdr, node, loc);
4435 string member_type_id;
4437 member_type_id = CHAR_STR(s);
4438 if (member_type_id.empty())
4440 type_base_sptr member_type =
4441 is_type(rdr.build_or_get_type_decl(member_type_id,
true));
4445 string containing_type_id;
4447 containing_type_id = CHAR_STR(s);
4448 if (containing_type_id.empty())
4450 type_base_sptr containing_type =
4451 rdr.build_or_get_type_decl(containing_type_id,
true);
4455 result.reset(
new ptr_to_mbr_type(rdr.get_environment(),
4456 member_type, containing_type,
4457 size_in_bits, alignment_in_bits,
4460 if (rdr.push_and_key_type_decl(result, node, add_to_current_scope))
4461 rdr.map_xml_node_to_decl(node, result);
4479build_function_type(reader& rdr,
4480 const xmlNodePtr node,
4485 if (!xmlStrEqual(node->name, BAD_CAST(
"function-type")))
4493 string method_class_id;
4495 method_class_id = CHAR_STR(s);
4497 bool is_method_t = !method_class_id.empty();
4499 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4500 read_size_and_alignment(node, size, align);
4502 const environment& env = rdr.get_environment();
4503 std::vector<shared_ptr<function_decl::parameter> > parms;
4504 type_base_sptr return_type = env.get_void_type();
4506 class_or_union_sptr method_class_type;
4516 ?
new method_type(method_class_type,
4519 :
new function_type(return_type,
4520 parms, size, align));
4522 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4523 rdr.key_type_decl(fn_type,
id);
4524 RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4526 for (xmlNodePtr n = xmlFirstElementChild(node);
4528 n = xmlNextElementSibling(n))
4530 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
4533 build_function_parameter(rdr, n))
4536 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
4541 type_id = CHAR_STR(s);
4542 if (!type_id.empty())
4543 fn_type->set_return_type(rdr.build_or_get_type_decl
4548 fn_type->set_parameters(parms);
4564build_subrange_type(reader& rdr,
4565 const xmlNodePtr node,
4566 bool add_to_current_scope)
4570 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"subrange")))
4573 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4576 dynamic_pointer_cast<array_type_def::subrange_type>(d);
4590 if (type_base_sptr d = rdr.get_type_decl(
id))
4601 uint64_t length = 0;
4603 bool is_non_finite =
false;
4606 if (
string(CHAR_STR(s)) ==
"infinite" ||
string(CHAR_STR(s)) ==
"unknown")
4607 is_non_finite =
true;
4609 length = strtoull(CHAR_STR(s), NULL, 0);
4612 uint64_t size_in_bits = 0;
4615 char *endptr =
nullptr;
4616 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4617 if (*endptr !=
'\0')
4619 if (!strcmp(CHAR_STR(s),
"infinite")
4620 ||!strcmp(CHAR_STR(s),
"unknown"))
4621 size_in_bits = (size_t) -1;
4627 int64_t lower_bound = 0, upper_bound = 0;
4628 bool bounds_present =
false;
4631 lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4633 if (!
string(CHAR_STR(s)).empty())
4634 upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4635 bounds_present =
true;
4637 || (length == (uint64_t) upper_bound - lower_bound + 1));
4640 string underlying_type_id;
4642 underlying_type_id = CHAR_STR(s);
4644 type_base_sptr underlying_type;
4645 if (!underlying_type_id.empty())
4647 underlying_type = rdr.build_or_get_type_decl(underlying_type_id,
true);
4652 read_location(rdr, node, loc);
4657 array_type_def::subrange_type::bound_value max_bound;
4658 array_type_def::subrange_type::bound_value min_bound;
4664 max_bound.set_signed(length - 1);
4670 min_bound.set_signed(lower_bound);
4671 max_bound.set_signed(upper_bound);
4675 (
new array_type_def::subrange_type(rdr.get_environment(),
4676 name, min_bound, max_bound,
4677 underlying_type, loc));
4678 maybe_set_artificial_location(rdr, node, p);
4679 p->is_non_finite(is_non_finite);
4681 p->set_size_in_bits(size_in_bits);
4683 if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
4684 rdr.map_xml_node_to_decl(node, p);
4701build_array_type_def(reader& rdr,
4702 const xmlNodePtr node,
4703 bool add_to_current_scope)
4708 if (!xmlStrEqual(node->name, BAD_CAST(
"array-type-def")))
4711 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4714 dynamic_pointer_cast<array_type_def>(d);
4724 if (type_base_sptr d = rdr.get_type_decl(
id))
4733 dimensions = atoi(CHAR_STR(s));
4737 type_id = CHAR_STR(s);
4741 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4744 dynamic_pointer_cast<array_type_def>(d);
4749 size_t size_in_bits = 0, alignment_in_bits = 0;
4750 bool has_size_in_bits =
false;
4755 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4756 if (*endptr !=
'\0')
4758 if (!strcmp(CHAR_STR(s),
"infinite")
4759 ||!strcmp(CHAR_STR(s),
"unknown"))
4760 size_in_bits = (size_t) -1;
4764 has_size_in_bits =
true;
4769 alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4770 if (*endptr !=
'\0')
4775 read_location(rdr, node, loc);
4778 for (xmlNodePtr n = xmlFirstElementChild(node);
4780 n = xmlNextElementSibling(n))
4781 if (xmlStrEqual(n->name, BAD_CAST(
"subrange")))
4784 build_subrange_type(rdr, n,
true))
4786 MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
4787 if (add_to_current_scope)
4790 rdr.maybe_canonicalize_type(s);
4792 subranges.push_back(s);
4797 type_base_sptr type =
4798 rdr.build_or_get_type_decl(type_id,
true);
4802 maybe_set_artificial_location(rdr, node, ar_type);
4803 if (rdr.push_and_key_type_decl(ar_type, node, add_to_current_scope))
4804 rdr.map_xml_node_to_decl(node, ar_type);
4805 RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
4807 if (dimensions != ar_type->get_dimension_count()
4808 || (alignment_in_bits
4809 != ar_type->get_element_type()->get_alignment_in_bits()))
4812 if (has_size_in_bits && size_in_bits != (
size_t) -1
4813 && size_in_bits != ar_type->get_size_in_bits())
4816 size_t element_size = ar_type->get_element_type()->get_size_in_bits();
4817 if (element_size && element_size != (
size_t)-1)
4820 size_t bad_count = 0;
4821 for (vector<array_type_def::subrange_sptr>::const_iterator i =
4823 i != subranges.end();
4825 bad_count += (*i)->get_length();
4826 if (size_in_bits == bad_count * element_size)
4828 static bool reported =
false;
4831 std::cerr <<
"notice: Found incorrectly calculated array "
4832 <<
"sizes in XML - this is benign.\nOlder versions "
4833 <<
"of libabigail miscalculated multidimensional "
4834 <<
"array sizes." << std::endl;
4840 std::cerr <<
"error: Found incorrectly calculated array size in "
4841 <<
"XML (id=\"" <<
id <<
"\")." << std::endl;
4865build_enum_type_decl_if_not_suppressed(reader& rdr,
4866 const xmlNodePtr node,
4867 bool add_to_current_scope)
4870 if (!type_is_suppressed(rdr, node))
4871 enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
4887build_enum_type_decl(reader& rdr,
4888 const xmlNodePtr node,
4889 bool add_to_current_scope)
4893 if (!xmlStrEqual(node->name, BAD_CAST(
"enum-decl")))
4896 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4899 dynamic_pointer_cast<enum_type_decl>(d);
4908 string linkage_name;
4913 read_location(rdr, node, loc);
4915 bool is_decl_only =
false;
4916 read_is_declaration_only(node, is_decl_only);
4918 bool is_anonymous =
false;
4919 read_is_anonymous(node, is_anonymous);
4921 bool is_artificial =
false;
4922 read_is_artificial(node, is_artificial);
4930 string base_type_id;
4932 for (xmlNodePtr n = xmlFirstElementChild(node);
4934 n = xmlNextElementSibling(n))
4936 if (xmlStrEqual(n->name, BAD_CAST(
"underlying-type")))
4940 base_type_id = CHAR_STR(a);
4943 else if (xmlStrEqual(n->name, BAD_CAST(
"enumerator")))
4955 value = strtoll(CHAR_STR(a), NULL, 0);
4959 if ((errno == ERANGE)
4960 && (value == LLONG_MIN || value == LLONG_MAX))
4964 enums.push_back(enum_type_decl::enumerator(name, value));
4968 type_base_sptr underlying_type =
4969 rdr.build_or_get_type_decl(base_type_id,
true);
4974 enums, linkage_name));
4975 maybe_set_artificial_location(rdr, node, t);
4976 t->set_is_anonymous(is_anonymous);
4977 t->set_is_artificial(is_artificial);
4978 t->set_is_declaration_only(is_decl_only);
4979 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4981 maybe_set_naming_typedef(rdr, node, t);
4982 rdr.map_xml_node_to_decl(node, t);
4983 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4998static shared_ptr<typedef_decl>
4999build_typedef_decl(reader& rdr,
5000 const xmlNodePtr node,
5001 bool add_to_current_scope)
5003 shared_ptr<typedef_decl> nil;
5005 if (!xmlStrEqual(node->name, BAD_CAST(
"typedef-decl")))
5008 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5025 read_location(rdr, node, loc);
5029 type_id = CHAR_STR(s);
5032 type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id,
true));
5036 maybe_set_artificial_location(rdr, node, t);
5037 rdr.push_and_key_type_decl(t, node, add_to_current_scope);
5038 rdr.map_xml_node_to_decl(node, t);
5039 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
5056build_class_decl_if_not_suppressed(reader& rdr,
5057 const xmlNodePtr node,
5058 bool add_to_current_scope)
5061 if (!type_is_suppressed(rdr, node))
5062 class_type = build_class_decl(rdr, node, add_to_current_scope);
5078static union_decl_sptr
5079build_union_decl_if_not_suppressed(reader& rdr,
5080 const xmlNodePtr node,
5081 bool add_to_current_scope)
5083 union_decl_sptr union_type;
5084 if (!type_is_suppressed(rdr, node))
5085 union_type = build_union_decl(rdr, node, add_to_current_scope);
5102build_class_decl(reader& rdr,
5103 const xmlNodePtr node,
5104 bool add_to_current_scope)
5108 if (!xmlStrEqual(node->name, BAD_CAST(
"class-decl")))
5111 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5122 size_t size_in_bits = 0, alignment_in_bits = 0;
5123 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5126 read_visibility(node, vis);
5128 bool is_artificial =
false;
5129 read_is_artificial(node, is_artificial);
5136 read_location(rdr, node, loc);
5145 bool is_decl_only =
false;
5146 read_is_declaration_only(node, is_decl_only);
5148 bool is_struct =
false;
5149 read_is_struct(node, is_struct);
5151 bool is_anonymous =
false;
5152 read_is_anonymous(node, is_anonymous);
5158 if (type_base_sptr t = rdr.get_type_decl(
id))
5164 const vector<type_base_sptr> *types_ptr = 0;
5165 if (!is_anonymous && !previous_definition)
5166 types_ptr = rdr.get_all_type_decls(
id);
5172 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5173 i != types_ptr->end();
5178 if (klass->get_is_declaration_only()
5179 && !klass->get_definition_of_declaration())
5180 previous_declaration = klass;
5181 else if (!klass->get_is_declaration_only()
5182 && !previous_definition)
5183 previous_definition = klass;
5184 if (previous_definition && previous_declaration)
5188 if (previous_declaration)
5189 ABG_ASSERT(previous_declaration->get_name() == name);
5191 if (previous_definition)
5192 ABG_ASSERT(previous_definition->get_name() == name);
5194 if (is_decl_only && previous_declaration)
5195 return previous_declaration;
5198 const environment& env = rdr.get_environment();
5200 if (!is_decl_only && previous_definition)
5206 decl = previous_definition;
5211 decl.reset(
new class_decl(env, name, is_struct));
5213 decl->set_size_in_bits(size_in_bits);
5215 decl->set_is_anonymous(is_anonymous);
5216 decl->set_location(loc);
5219 decl.reset(
new class_decl(env, name, size_in_bits, alignment_in_bits,
5220 is_struct, loc, vis, bases, mbrs,
5221 data_mbrs, mbr_functions, is_anonymous));
5224 maybe_set_artificial_location(rdr, node, decl);
5225 decl->set_is_artificial(is_artificial);
5228 bool is_def_of_decl =
false;
5230 def_id = CHAR_STR(s);
5232 if (!def_id.empty())
5234 decl_base_sptr d =
is_decl(rdr.get_type_decl(def_id));
5235 if (d && d->get_is_declaration_only())
5237 is_def_of_decl =
true;
5238 decl->set_earlier_declaration(d);
5239 d->set_definition_of_declaration(decl);
5245 && !decl->get_is_declaration_only()
5246 && previous_declaration)
5252 decl->set_earlier_declaration(
is_decl(previous_declaration));
5253 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5254 i != types_ptr->end();
5259 if (d->get_is_declaration_only()
5260 && !d->get_definition_of_declaration())
5262 previous_declaration->set_definition_of_declaration(decl);
5263 is_def_of_decl =
true;
5268 if (is_decl_only && previous_definition)
5273 && !decl->get_definition_of_declaration());
5274 decl->set_definition_of_declaration(previous_definition);
5277 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5279 rdr.push_decl_to_scope(decl,
5280 add_to_current_scope
5281 ? rdr.get_scope_ptr_for_node(node)
5284 rdr.map_xml_node_to_decl(node, decl);
5285 rdr.key_type_decl(decl,
id);
5288 maybe_set_naming_typedef(rdr, node, decl);
5290 for (xmlNodePtr n = xmlFirstElementChild(node);
5292 n = xmlNextElementSibling(n))
5294 if (xmlStrEqual(n->name, BAD_CAST(
"base-class")))
5300 read_access(n, access);
5304 type_id = CHAR_STR(s);
5305 shared_ptr<class_decl> b =
5306 dynamic_pointer_cast<class_decl>
5307 (rdr.build_or_get_type_decl(type_id,
true));
5310 if (decl->find_base_class(b->get_qualified_name()))
5316 size_t offset_in_bits = 0;
5317 bool offset_present = read_offset_in_bits (n, offset_in_bits);
5319 bool is_virtual =
false;
5320 read_is_virtual (n, is_virtual);
5322 shared_ptr<class_decl::base_spec> base (
new class_decl::base_spec
5325 ? (
long) offset_in_bits
5328 decl->add_base_specifier(base);
5330 else if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5336 read_access(n, access);
5338 rdr.map_xml_node_to_decl(n, decl);
5340 for (xmlNodePtr p = xmlFirstElementChild(n);
5342 p = xmlNextElementSibling(p))
5344 if (type_base_sptr t =
5345 build_type(rdr, p,
true))
5350 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5352 string id = CHAR_STR(i);
5354 rdr.key_type_decl(t,
id);
5355 rdr.map_xml_node_to_decl(p, td);
5359 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5361 rdr.map_xml_node_to_decl(n, decl);
5367 read_access(n, access);
5369 bool is_laid_out =
false;
5370 size_t offset_in_bits = 0;
5371 if (read_offset_in_bits(n, offset_in_bits))
5374 bool is_static =
false;
5375 read_static(n, is_static);
5377 for (xmlNodePtr p = xmlFirstElementChild(n);
5379 p = xmlNextElementSibling(p))
5382 build_var_decl(rdr, p,
false))
5384 if (decl->find_data_member(v))
5392 decl_base_sptr d = rdr.pop_decl();
5397 if (!variable_is_suppressed(rdr, decl.get(), *v))
5399 decl->add_data_member(v, access,
5404 rdr.add_var_to_exported_or_undefined_decls(v.get());
5414 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5417 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5418 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5424 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5430 read_access(n, access);
5432 bool is_virtual =
false;
5433 ssize_t vtable_offset = -1;
5438 vtable_offset = atoi(CHAR_STR(s));
5441 bool is_static =
false;
5442 read_static(n, is_static);
5444 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5445 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5447 for (xmlNodePtr p = xmlFirstElementChild(n);
5449 p = xmlNextElementSibling(p))
5452 build_function_decl_if_not_suppressed(rdr, p, decl,
5460 if (vtable_offset != -1)
5466 rdr.map_xml_node_to_decl(p, m);
5467 rdr.add_fn_to_exported_or_undefined_decls(f.get());
5472 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5474 rdr.map_xml_node_to_decl(n, decl);
5480 read_access(n, access);
5482 bool is_static =
false;
5483 read_static(n, is_static);
5485 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5486 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5488 for (xmlNodePtr p = xmlFirstElementChild(n);
5490 p = xmlNextElementSibling(p))
5492 if (shared_ptr<function_tdecl> f =
5493 build_function_tdecl(rdr, p,
5496 shared_ptr<member_function_template> m
5497 (
new member_function_template(f, access, is_static,
5498 is_ctor, is_const));
5500 decl->add_member_function_template(m);
5502 else if (shared_ptr<class_tdecl> c =
5503 build_class_tdecl(rdr, p,
5506 member_class_template_sptr m(
new member_class_template(c,
5510 decl->add_member_class_template(m);
5516 rdr.pop_scope_or_abort(decl);
5533static union_decl_sptr
5534build_union_decl(reader& rdr,
5535 const xmlNodePtr node,
5536 bool add_to_current_scope)
5538 union_decl_sptr nil;
5540 if (!xmlStrEqual(node->name, BAD_CAST(
"union-decl")))
5543 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5545 union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5554 size_t size_in_bits = 0, alignment_in_bits = 0;
5555 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5558 read_visibility(node, vis);
5560 bool is_artificial =
false;
5561 read_is_artificial(node, is_artificial);
5568 read_location(rdr, node, loc);
5574 union_decl_sptr decl;
5576 bool is_decl_only =
false;
5577 read_is_declaration_only(node, is_decl_only);
5579 bool is_anonymous =
false;
5580 read_is_anonymous(node, is_anonymous);
5583 union_decl_sptr previous_definition, previous_declaration;
5584 const vector<type_base_sptr> *types_ptr = 0;
5586 types_ptr = rdr.get_all_type_decls(
id);
5592 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5593 i != types_ptr->end();
5598 if (onion->get_is_declaration_only()
5599 && !onion->get_definition_of_declaration())
5600 previous_declaration = onion;
5601 else if (!onion->get_is_declaration_only()
5602 && !previous_definition)
5603 previous_definition = onion;
5604 if (previous_definition && previous_declaration)
5608 if (previous_declaration)
5609 ABG_ASSERT(previous_declaration->get_name() == name);
5611 if (previous_definition)
5612 ABG_ASSERT(previous_definition->get_name() == name);
5614 if (is_decl_only && previous_declaration)
5615 return previous_declaration;
5618 const environment& env = rdr.get_environment();
5620 if (!is_decl_only && previous_definition)
5626 decl = previous_definition;
5630 decl.reset(
new union_decl(env, name));
5632 decl.reset(
new union_decl(env, name,
5640 maybe_set_artificial_location(rdr, node, decl);
5641 decl->set_is_artificial(is_artificial);
5644 bool is_def_of_decl =
false;
5646 def_id = CHAR_STR(s);
5648 if (!def_id.empty())
5651 dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5652 if (d && d->get_is_declaration_only())
5654 is_def_of_decl =
true;
5655 decl->set_earlier_declaration(d);
5656 d->set_definition_of_declaration(decl);
5662 && !decl->get_is_declaration_only()
5663 && previous_declaration)
5669 decl->set_earlier_declaration(previous_declaration);
5670 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5671 i != types_ptr->end();
5676 if (d->get_is_declaration_only()
5677 && !d->get_definition_of_declaration())
5679 previous_declaration->set_definition_of_declaration(decl);
5680 is_def_of_decl =
true;
5685 if (is_decl_only && previous_definition)
5690 && !decl->get_definition_of_declaration());
5691 decl->set_definition_of_declaration(previous_definition);
5694 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5696 rdr.push_decl_to_scope(decl,
5697 add_to_current_scope
5698 ? rdr.get_scope_ptr_for_node(node)
5701 rdr.map_xml_node_to_decl(node, decl);
5702 rdr.key_type_decl(decl,
id);
5704 maybe_set_naming_typedef(rdr, node, decl);
5706 for (xmlNodePtr n = xmlFirstElementChild(node);
5708 n = xmlNextElementSibling(n))
5710 if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5713 read_access(n, access);
5715 rdr.map_xml_node_to_decl(n, decl);
5717 for (xmlNodePtr p = xmlFirstElementChild(n);
5719 p = xmlNextElementSibling(p))
5721 if (type_base_sptr t =
5722 build_type(rdr, p,
true))
5727 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5729 string id = CHAR_STR(i);
5731 rdr.key_type_decl(t,
id);
5732 rdr.map_xml_node_to_decl(p, td);
5736 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5738 rdr.map_xml_node_to_decl(n, decl);
5741 read_access(n, access);
5743 bool is_laid_out =
true;
5744 size_t offset_in_bits = 0;
5745 bool is_static =
false;
5746 read_static(n, is_static);
5748 for (xmlNodePtr p = xmlFirstElementChild(n);
5750 p = xmlNextElementSibling(p))
5753 build_var_decl(rdr, p,
false))
5755 if (decl->find_data_member(v))
5763 decl_base_sptr d = rdr.pop_decl();
5768 || !variable_is_suppressed(rdr, decl.get(), *v))
5770 decl->add_data_member(v, access,
5783 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5786 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5787 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5793 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5795 rdr.map_xml_node_to_decl(n, decl);
5798 read_access(n, access);
5800 bool is_static =
false;
5801 read_static(n, is_static);
5803 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5804 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5806 for (xmlNodePtr p = xmlFirstElementChild(n);
5808 p = xmlNextElementSibling(p))
5811 build_function_decl_if_not_suppressed(rdr, p, decl,
5822 rdr.add_fn_to_exported_or_undefined_decls(f.get());
5827 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5829 rdr.map_xml_node_to_decl(n, decl);
5832 read_access(n, access);
5834 bool is_static =
false;
5835 read_static(n, is_static);
5837 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5838 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5840 for (xmlNodePtr p = xmlFirstElementChild(n);
5842 p = xmlNextElementSibling(p))
5845 build_function_tdecl(rdr, p,
5848 member_function_template_sptr m
5849 (
new member_function_template(f, access, is_static,
5850 is_ctor, is_const));
5852 decl->add_member_function_template(m);
5855 build_class_tdecl(rdr, p,
5858 member_class_template_sptr m(
new member_class_template(c,
5862 decl->add_member_class_template(m);
5868 rdr.pop_scope_or_abort(decl);
5885static shared_ptr<function_tdecl>
5886build_function_tdecl(reader& rdr,
5887 const xmlNodePtr node,
5888 bool add_to_current_scope)
5890 shared_ptr<function_tdecl> nil, result;
5892 if (!xmlStrEqual(node->name, BAD_CAST(
"function-template-decl")))
5898 if (
id.empty() || rdr.get_fn_tmpl_decl(
id))
5902 read_location(rdr, node, loc);
5905 read_visibility(node, vis);
5908 read_binding(node, bind);
5910 const environment& env = rdr.get_environment();
5913 maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
5915 rdr.push_decl_to_scope(fn_tmpl_decl,
5916 add_to_current_scope
5917 ? rdr.get_scope_ptr_for_node(node)
5919 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5920 rdr.map_xml_node_to_decl(node, fn_tmpl_decl);
5922 unsigned parm_index = 0;
5923 for (xmlNodePtr n = xmlFirstElementChild(node);
5925 n = xmlNextElementSibling(n))
5928 build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
5930 fn_tmpl_decl->add_template_parameter(parm);
5937 fn_tmpl_decl->set_pattern(f);
5940 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5942 return fn_tmpl_decl;
5958build_class_tdecl(reader& rdr,
5959 const xmlNodePtr node,
5960 bool add_to_current_scope)
5964 if (!xmlStrEqual(node->name, BAD_CAST(
"class-template-decl")))
5970 if (
id.empty() || rdr.get_class_tmpl_decl(
id))
5974 read_location(rdr, node, loc);
5977 read_visibility(node, vis);
5979 const environment& env = rdr.get_environment();
5982 maybe_set_artificial_location(rdr, node, class_tmpl);
5984 if (add_to_current_scope)
5985 rdr.push_decl_to_scope(class_tmpl, node);
5986 rdr.key_class_tmpl_decl(class_tmpl,
id);
5987 rdr.map_xml_node_to_decl(node, class_tmpl);
5989 unsigned parm_index = 0;
5990 for (xmlNodePtr n = xmlFirstElementChild(node);
5992 n = xmlNextElementSibling(n))
5995 build_template_parameter(rdr, n, parm_index, class_tmpl))
5997 class_tmpl->add_template_parameter(parm);
6001 build_class_decl_if_not_suppressed(rdr, n,
6002 add_to_current_scope))
6005 rdr.maybe_canonicalize_type(c,
false);
6006 class_tmpl->set_pattern(c);
6010 rdr.key_class_tmpl_decl(class_tmpl,
id);
6031build_type_tparameter(reader& rdr,
6032 const xmlNodePtr node,
6038 if (!xmlStrEqual(node->name, BAD_CAST(
"template-type-parameter")))
6049 type_id = CHAR_STR(s);
6050 if (!type_id.empty()
6051 && !(result = dynamic_pointer_cast<type_tparameter>
6052 (rdr.build_or_get_type_decl(type_id,
true))))
6060 read_location(rdr, node,loc);
6062 result.reset(
new type_tparameter(index, tdecl, name, loc));
6063 maybe_set_artificial_location(rdr, node, result);
6066 rdr.push_decl_to_scope(
is_decl(result), node);
6068 rdr.push_and_key_type_decl(result, node,
true);
6070 rdr.maybe_canonicalize_type(result,
false);
6090build_type_composition(reader& rdr,
6091 const xmlNodePtr node,
6097 if (!xmlStrEqual(node->name, BAD_CAST(
"template-parameter-type-composition")))
6100 type_base_sptr composed_type;
6101 result.reset(
new type_composition(index, tdecl, composed_type));
6102 rdr.push_decl_to_scope(
is_decl(result), node);
6104 for (xmlNodePtr n = xmlFirstElementChild(node);
6106 n = xmlNextElementSibling(n))
6108 if ((composed_type =
6109 build_pointer_type_def(rdr, n,
6112 build_reference_type_def(rdr, n,
6115 build_array_type_def(rdr, n,
6118 build_qualified_type_decl(rdr, n,
6121 rdr.maybe_canonicalize_type(composed_type,
6123 result->set_composed_type(composed_type);
6147build_non_type_tparameter(reader& rdr,
6148 const xmlNodePtr node,
6154 if (!xmlStrEqual(node->name, BAD_CAST(
"template-non-type-parameter")))
6159 type_id = CHAR_STR(s);
6160 type_base_sptr type;
6162 || !(type = rdr.build_or_get_type_decl(type_id,
true)))
6170 read_location(rdr, node,loc);
6172 r.reset(
new non_type_tparameter(index, tdecl, name, type, loc));
6173 maybe_set_artificial_location(rdr, node, r);
6174 rdr.push_decl_to_scope(
is_decl(r), node);
6194build_template_tparameter(reader& rdr,
6195 const xmlNodePtr node,
6201 if (!xmlStrEqual(node->name, BAD_CAST(
"template-template-parameter")))
6212 type_id = CHAR_STR(s);
6214 if (!type_id.empty()
6215 && !(dynamic_pointer_cast<template_tparameter>
6216 (rdr.build_or_get_type_decl(type_id,
true))))
6224 read_location(rdr, node, loc);
6228 maybe_set_artificial_location(rdr, node, result);
6229 rdr.push_decl_to_scope(result, node);
6233 for (xmlNodePtr n = xmlFirstElementChild(node);
6235 n = xmlNextElementSibling(n))
6236 if (shared_ptr<template_parameter> p =
6237 build_template_parameter(rdr, n, parm_index, result))
6239 result->add_template_parameter(p);
6245 rdr.key_type_decl(result,
id);
6246 rdr.maybe_canonicalize_type(result,
false);
6268build_template_parameter(reader& rdr,
6269 const xmlNodePtr node,
6273 shared_ptr<template_parameter> r;
6274 ((r = build_type_tparameter(rdr, node, index, tdecl))
6275 || (r = build_non_type_tparameter(rdr, node, index, tdecl))
6276 || (r = build_template_tparameter(rdr, node, index, tdecl))
6277 || (r = build_type_composition(rdr, node, index, tdecl)));
6290static type_base_sptr
6291build_type(reader& rdr,
6292 const xmlNodePtr node,
6293 bool add_to_current_scope)
6297 ((t = build_type_decl(rdr, node, add_to_current_scope))
6298 || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
6299 || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
6300 || (t = build_reference_type_def(rdr, node , add_to_current_scope))
6301 || (t = build_ptr_to_mbr_type(rdr, node , add_to_current_scope))
6302 || (t = build_function_type(rdr, node, add_to_current_scope))
6303 || (t = build_array_type_def(rdr, node, add_to_current_scope))
6304 || (t = build_subrange_type(rdr, node, add_to_current_scope))
6305 || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
6306 add_to_current_scope))
6307 || (t = build_typedef_decl(rdr, node, add_to_current_scope))
6308 || (t = build_class_decl_if_not_suppressed(rdr, node,
6309 add_to_current_scope))
6310 || (t = build_union_decl_if_not_suppressed(rdr, node,
6311 add_to_current_scope)));
6313 if (rdr.tracking_non_reachable_types() && t)
6315 corpus_sptr abi = rdr.corpus();
6317 bool is_non_reachable_type =
false;
6318 read_is_non_reachable_type(node, is_non_reachable_type);
6319 if (!is_non_reachable_type)
6320 abi->record_type_as_reachable_from_public_interfaces(*t);
6323 MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
6326 rdr.maybe_canonicalize_type(t,
false );
6335static decl_base_sptr
6336handle_type_decl(reader& rdr,
6338 bool add_to_current_scope)
6340 type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
6341 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6342 if (decl && decl->get_scope())
6343 rdr.maybe_canonicalize_type(decl,
false);
6352static decl_base_sptr
6353handle_namespace_decl(reader& rdr,
6355 bool add_to_current_scope)
6358 add_to_current_scope);
6367static decl_base_sptr
6368handle_qualified_type_decl(reader& rdr,
6370 bool add_to_current_scope)
6372 qualified_type_def_sptr decl =
6373 build_qualified_type_decl(rdr, node,
6374 add_to_current_scope);
6375 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6376 if (decl && decl->get_scope())
6377 rdr.maybe_canonicalize_type(decl,
false);
6386static decl_base_sptr
6387handle_pointer_type_def(reader& rdr,
6389 bool add_to_current_scope)
6392 add_to_current_scope);
6393 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6394 if (decl && decl->get_scope())
6395 rdr.maybe_canonicalize_type(decl,
false);
6404static decl_base_sptr
6405handle_reference_type_def(reader& rdr,
6407 bool add_to_current_scope)
6410 add_to_current_scope);
6411 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6412 if (decl && decl->get_scope())
6413 rdr.maybe_canonicalize_type(decl,
false);
6422static type_base_sptr
6423handle_function_type(reader& rdr,
6425 bool add_to_current_scope)
6428 add_to_current_scope);
6429 MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
6430 rdr.maybe_canonicalize_type(type,
true);
6439static decl_base_sptr
6440handle_array_type_def(reader& rdr,
6442 bool add_to_current_scope)
6445 add_to_current_scope);
6446 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6447 rdr.maybe_canonicalize_type(decl,
false);
6454static decl_base_sptr
6455handle_enum_type_decl(reader& rdr,
6457 bool add_to_current_scope)
6460 build_enum_type_decl_if_not_suppressed(rdr, node,
6461 add_to_current_scope);
6462 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6463 if (decl && decl->get_scope())
6464 rdr.maybe_canonicalize_type(decl,
false);
6471static decl_base_sptr
6472handle_typedef_decl(reader& rdr,
6474 bool add_to_current_scope)
6477 add_to_current_scope);
6478 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6479 if (decl && decl->get_scope())
6480 rdr.maybe_canonicalize_type(decl,
false);
6492static decl_base_sptr
6493handle_var_decl(reader& rdr,
6495 bool add_to_current_scope)
6497 decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6498 add_to_current_scope);
6499 rdr.add_var_to_exported_or_undefined_decls(
is_var_decl(decl).get());
6509static decl_base_sptr
6510handle_function_decl(reader& rdr,
6512 bool add_to_current_scope)
6514 return build_function_decl_if_not_suppressed(rdr, node,
class_decl_sptr(),
6515 add_to_current_scope,
6525static decl_base_sptr
6526handle_class_decl(reader& rdr,
6528 bool add_to_current_scope)
6531 build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6532 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6533 if (decl && decl->get_scope())
6534 rdr.maybe_canonicalize_type(decl,
false);
6544static decl_base_sptr
6545handle_union_decl(reader& rdr,
6547 bool add_to_current_scope)
6549 union_decl_sptr decl =
6550 build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6551 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6552 if (decl && decl->get_scope())
6553 rdr.maybe_canonicalize_type(decl,
false);
6563static decl_base_sptr
6564handle_function_tdecl(reader& rdr,
6566 bool add_to_current_scope)
6569 add_to_current_scope);
6578static decl_base_sptr
6579handle_class_tdecl(reader& rdr,
6581 bool add_to_current_scope)
6584 add_to_current_scope);
6601 return read_translation_unit_from_input(read_rdr);
6626 corpus_sptr corp = result->corpus();
6627 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6628#ifdef WITH_DEBUG_SELF_COMPARISON
6629 if (env.self_comparison_debug_is_on())
6630 env.set_self_comparison_debug_input(result->corpus());
6632 result->set_path(path);
6649 corpus_sptr corp = result->corpus();
6650 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6651#ifdef WITH_DEBUG_SELF_COMPARISON
6652 if (env.self_comparison_debug_is_on())
6653 env.set_self_comparison_debug_input(result->corpus());
6676 return rdr->read_corpus(sts);
6698 corpus_sptr corp = rdr->read_corpus(sts);
6704#ifdef WITH_DEBUG_SELF_COMPARISON
6723load_canonical_type_ids(fe_iface& iface,
const string &file_path)
6725 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
6727 xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
6731 xmlNodePtr node = xmlDocGetRootElement(doc);
6754 if (xmlStrcmp(node->name, (xmlChar*)
"abixml-types-check"))
6757 for (node = xmlFirstElementChild(node);
6759 node = xmlNextElementSibling(node))
6761 if (xmlStrcmp(node->name, (xmlChar*)
"type"))
6764 string id, canonical_address;
6765 xmlNodePtr data = xmlFirstElementChild(node);
6766 if (data && !xmlStrcmp(data->name, (xmlChar*)
"id")
6767 && data->children && xmlNodeIsText(data->children))
6768 id = (
char*) XML_GET_CONTENT(data->children);
6770 data = xmlNextElementSibling(data);
6771 if (data && !xmlStrcmp(data->name, (xmlChar*)
"c")
6772 && data->children && xmlNodeIsText(data->children))
6774 canonical_address = (
char*) XML_GET_CONTENT(data->children);
6775 std::stringstream s;
6776 s << canonical_address;
6784 rdr.get_environment().get_type_id_canonical_type_map()[id] = v;
This file contains the declarations for the fe_iface a.k.a "Front End Interface".
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
#define XML_READER_GET_NODE_NAME(reader)
Get the name of the current element node the reader is pointing to. Note that this macro returns an i...
#define XML_READER_GET_ATTRIBUTE(reader, name)
Get the value of attribute 'name' on the current node of 'reader' which is an instance of shared_ptr<...
#define XML_NODE_GET_ATTRIBUTE(node, name)
Get the value of attribute 'name' ont the instance of xmlNodePtr denoted by 'node'.
#define XML_READER_GET_NODE_TYPE(reader)
Get the type of the current node of the shared_ptr<xmlTextReader> passed in argument.
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
The base class of all libabigail front-ends: The Front End Interface.
status
The status of the fe_iface::read_corpus call.
@ STATUS_OK
This status is for when the call went OK.
const options_type & options() const
Getter of the the options of the current Front End Interface.
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
suppr::suppressions_type & suppressions()
Getter of the vector of suppression specifications associated with the current front-end.
corpus_group_sptr & corpus_group()
Getter for the ABI corpus group being built by the current front-end.
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
vector< base_spec_sptr > base_specs
Convenience typedef.
vector< method_decl_sptr > member_functions
Convenience typedef.
vector< var_decl_sptr > data_members
Convenience typedef.
vector< type_base_sptr > member_types
Convenience typedef.
Abstraction of a group of corpora.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
visibility
ELF visibility.
binding
The binding of a symbol.
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
type
The type of a symbol.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
visibility
The visibility of the symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
CV
Bit field values representing the cv qualifiers of the underlying type.
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
The base class of both types and declarations.
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
static symtab_ptr load(Elf *elf_handle, const ir::environment &env, symbol_predicate is_suppressed=NULL)
Construct a symtab object and instantiate it from an ELF handle. Also pass in the ir::environment we ...
translation_unit_sptr read_translation_unit_from_buffer(const string &buffer, environment &env)
Parse an ABI instrumentation file (in XML format) from an in-memory buffer.
void add_reader_suppressions(reader &rdr, const suppr::suppressions_type &supprs)
Add suppressions specifications to the set of suppressions to be used during the construction of the ...
unordered_map< string, vector< string > > string_strings_map_type
Convenience typedef for an unordered map of string to a vector of strings.
translation_unit_sptr read_translation_unit_from_istream(istream *in, environment &env)
De-serialize a translation unit from an ABI Instrumentation xml file coming from an input stream.
corpus_sptr read_corpus_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus from an input XML document which root node is 'abi-corpus'.
corpus_group_sptr read_corpus_group_from_input(fe_iface &iface)
Parse the input XML document containing an ABI corpus group, represented by an 'abi-corpus-group' ele...
corpus_sptr read_corpus_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus from an XML document file which root node is 'abi-corpus'.
translation_unit_sptr read_translation_unit_from_file(const string &input_file, environment &env)
Parse an ABI instrumentation file (in XML format) at a given path.
corpus_group_sptr read_corpus_group_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus group from an input XML document which root node is 'abi-corpus-group'.
fe_iface_sptr create_reader(const string &path, environment &env)
Create an xml_reader::reader to read a native XML ABI file.
void consider_types_not_reachable_from_public_interfaces(fe_iface &iface, bool flag)
Configure the reader so that types not reachable from public interface are taken into account when th...
corpus_group_sptr read_corpus_group_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus group from an XML document file which root node is 'abi-corpus-group'.
shared_ptr< type_tparameter > type_tparameter_sptr
Convenience typedef for a shared pointer to type_tparameter.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
shared_ptr< non_type_tparameter > non_type_tparameter_sptr
Convenience typedef for shared pointer to non_type_template_parameter.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
void canonicalize_types(const input_iterator &begin, const input_iterator &end, deref_lambda deref)
Compute the canonical type for all the IR types of the system.
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
std::unordered_map< string, elf_symbol_sptr > string_elf_symbol_sptr_map_type
Convenience typedef for a map which key is a string and which value if the elf symbol of the same nam...
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< string_elf_symbols_map_type > string_elf_symbols_map_sptr
Convenience typedef for a shared pointer to string_elf_symbols_map_type.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< type_composition > type_composition_sptr
Convenience typedef for shared pointer to type_composition.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
translation_unit * get_translation_unit(const decl_base &decl)
Return the translation unit a declaration belongs to.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
shared_ptr< T > build_sptr(T *p)
This is to be specialized for the diverse C types that needs wrapping in shared_ptr.
shared_ptr< file_suppression > file_suppression_sptr
A convenience typedef for a shared_ptr to file_suppression.
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
bool suppression_can_match(const fe_iface &fe, const suppression_base &s)
Test if a given suppression specification can match an ABI artifact coming from the corpus being anal...
file_suppression_sptr is_file_suppression(const suppression_sptr s)
Test if a given suppression specification is a file suppression specification.
bool is_elf_symbol_suppressed(const fe_iface &fe, const elf_symbol_sptr &symbol)
Test if an ELF symbol is suppressed by at least one of the suppression specifications associated with...
bool suppression_matches_soname_or_filename(const string &soname, const string &filename, const suppression_base &suppr)
Test if a given SONAME or file name is matched by a given suppression specification.
bool suppression_matches_type_name_or_location(const type_suppression &s, const string &type_name, const location &type_location)
Test if a type suppression matches a type name and location.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_opaque, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
reader_sptr new_reader_from_file(const std::string &path)
Instantiate an xmlTextReader that parses the content of an on-disk file, wrap it into a smart pointer...
bool xml_char_sptr_to_string(xml_char_sptr ssptr, std::string &s)
Convert a shared pointer to xmlChar into an std::string.
reader_sptr new_reader_from_buffer(const std::string &buffer)
Instanciate an xmlTextReader that parses the content of an in-memory buffer, wrap it into a smart poi...
shared_ptr< xmlChar > xml_char_sptr
A convenience typedef for a shared pointer of xmlChar.
void unescape_xml_string(const std::string &str, std::string &escaped)
Read a string, detect the 5 predefined XML entities it may contain and un-escape them,...
reader_sptr new_reader_from_istream(std::istream *in)
Instanciate an xmlTextReader that parses a content coming from an input stream.
shared_ptr< xmlTextReader > reader_sptr
A convenience typedef for a shared pointer of xmlTextReader.
Toplevel namespace for libabigail.