15#include <libxml/xmlreader.h>
16#include <libxml/xmlstring.h>
23#include <unordered_map>
28#include "abg-internal.h"
34ABG_BEGIN_EXPORT_DECLARATIONS
42ABG_END_EXPORT_DECLARATIONS
56using std::unordered_map;
57using std::dynamic_pointer_cast;
67static bool read_is_declaration_only(xmlNodePtr,
bool&);
68static bool read_is_artificial(xmlNodePtr,
bool&);
69static bool read_tracking_non_reachable_types(xmlNodePtr,
bool&);
70static bool read_is_non_reachable_type(xmlNodePtr,
bool&);
71static bool read_naming_typedef_id_string(xmlNodePtr,
string&);
72static bool read_type_id_string(xmlNodePtr,
string&);
73static bool read_name(xmlNodePtr,
string&);
74#ifdef WITH_DEBUG_SELF_COMPARISON
75static bool maybe_map_type_with_type_id(
const type_base_sptr&,
77static bool maybe_map_type_with_type_id(
const type_base_sptr&,
80#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node) \
81 maybe_map_type_with_type_id(type, xml_node)
83#define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node)
85static void maybe_set_naming_typedef(reader& rdr,
87 const decl_base_sptr &);
90static int advance_cursor(reader& rdr);
96walk_xml_node_to_map_type_ids(reader& rdr, xmlNodePtr node);
99read_elf_needed_from_input(reader& rdr, vector<string>& needed);
102read_symbol_db_from_input(reader& rdr,
109read_translation_unit_from_input(
fe_iface& rdr);
112build_ir_node_for_void_type(reader& rdr);
115build_ir_node_for_void_pointer_type(reader& rdr);
118build_ir_node_for_variadic_parameter_type(reader& rdr);
137 typedef unordered_map<string, vector<type_base_sptr> >
140 typedef unordered_map<string,
141 vector<type_base_sptr> >::const_iterator
144 typedef unordered_map<string,
145 vector<type_base_sptr> >::iterator
148 typedef unordered_map<string,
149 shared_ptr<function_tdecl> >::const_iterator
150 const_fn_tmpl_map_it;
152 typedef unordered_map<string,
153 shared_ptr<class_tdecl> >::const_iterator
154 const_class_tmpl_map_it;
156 typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
158 typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
160 friend vector<type_base_sptr>* get_types_from_type_id(reader&,
163 friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
164 get_artifact_used_by_relation_map(reader& rdr);
167 types_map_type m_types_map;
168 unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
169 unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
170 vector<type_base_sptr> m_types_to_canonicalize;
171 string_xml_node_map m_id_xml_node_map;
172 xml_node_decl_base_sptr_map m_xml_node_decl_map;
174 xmlNodePtr m_corp_node;
175 deque<shared_ptr<decl_base> > m_decls_stack;
176 bool m_tracking_non_reachable_types;
177 bool m_drop_undefined_syms;
178#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
180 vector<type_or_decl_base*>> m_artifact_used_by_map;
191 m_tracking_non_reachable_types(),
192 m_drop_undefined_syms()
209 clear_types_to_canonicalize();
217 {
return options().do_log;}
225 tracking_non_reachable_types()
const
226 {
return m_tracking_non_reachable_types;}
234 tracking_non_reachable_types(
bool f)
235 {m_tracking_non_reachable_types = f;}
243 drop_undefined_syms()
const
244 {
return m_drop_undefined_syms;}
251 drop_undefined_syms(
bool f)
252 {m_drop_undefined_syms = f;}
265 set_path(
const string& s)
281 get_environment()
const
282 {
return const_cast<reader*
>(
this)->get_environment();}
285 get_libxml_reader()
const
294 get_corpus_node()
const
295 {
return m_corp_node;}
303 set_corpus_node(xmlNodePtr node)
304 {m_corp_node = node;}
306 const string_xml_node_map&
307 get_id_xml_node_map()
const
308 {
return m_id_xml_node_map;}
311 get_id_xml_node_map()
312 {
return m_id_xml_node_map;}
315 clear_id_xml_node_map()
316 {get_id_xml_node_map().clear();}
318 const xml_node_decl_base_sptr_map&
319 get_xml_node_decl_map()
const
320 {
return m_xml_node_decl_map;}
322 xml_node_decl_base_sptr_map&
323 get_xml_node_decl_map()
324 {
return m_xml_node_decl_map;}
327 map_xml_node_to_decl(xmlNodePtr node,
331 get_xml_node_decl_map()[node]= decl;
335 get_decl_for_xml_node(xmlNodePtr node)
const
337 xml_node_decl_base_sptr_map::const_iterator i =
338 get_xml_node_decl_map().find(node);
340 if (i != get_xml_node_decl_map().end())
343 return decl_base_sptr();
347 clear_xml_node_decl_map()
348 {get_xml_node_decl_map().clear();}
351 map_id_and_node (
const string&
id,
357 string_xml_node_map::iterator i = get_id_xml_node_map().find(
id);
358 if (i != get_id_xml_node_map().end())
360 bool is_declaration =
false;
361 read_is_declaration_only(node, is_declaration);
366 get_id_xml_node_map()[id] = node;
370 get_xml_node_from_id(
const string&
id)
const
372 string_xml_node_map::const_iterator i = get_id_xml_node_map().find(
id);
373 if (i != get_id_xml_node_map().end())
379 get_scope_for_node(xmlNodePtr node,
383 get_scope_for_node(xmlNodePtr node);
386 get_scope_ptr_for_node(xmlNodePtr node);
391 build_or_get_type_decl(
const string&
id,
406 get_type_decl(
const string&
id)
const
408 const_types_map_it i = m_types_map.find(
id);
409 if (i == m_types_map.end())
410 return type_base_sptr();
411 type_base_sptr result = i->second[0];
427 const vector<type_base_sptr>*
428 get_all_type_decls(
const string&
id)
const
430 const_types_map_it i = m_types_map.find(
id);
431 if (i == m_types_map.end())
448 shared_ptr<function_tdecl>
449 get_fn_tmpl_decl(
const string&
id)
const
451 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
452 if (i == m_fn_tmpl_map.end())
453 return shared_ptr<function_tdecl>();
467 shared_ptr<class_tdecl>
468 get_class_tmpl_decl(
const string&
id)
const
470 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
471 if (i == m_class_tmpl_map.end())
472 return shared_ptr<class_tdecl>();
478 get_cur_scope()
const
480 shared_ptr<decl_base> cur_decl = get_cur_decl();
482 if (
dynamic_cast<scope_decl*
>(cur_decl.get()))
484 return dynamic_pointer_cast<scope_decl>(cur_decl).get();
488 return cur_decl->get_scope();
497 if (m_decls_stack.empty())
498 return shared_ptr<decl_base>(
static_cast<decl_base*
>(0));
499 return m_decls_stack.back();
505 const global_scope* global = 0;
506 for (deque<shared_ptr<decl_base> >::reverse_iterator i =
507 m_decls_stack.rbegin();
508 i != m_decls_stack.rend();
510 if (decl_base_sptr d = *i)
515 return global->get_translation_unit();
526 type_is_from_translation_unit(type_base_sptr type)
538 push_decl(decl_base_sptr d)
540 m_decls_stack.push_back(d);
546 if (m_decls_stack.empty())
547 return decl_base_sptr();
549 shared_ptr<decl_base> t = get_cur_decl();
550 m_decls_stack.pop_back();
577 return dynamic_pointer_cast<scope_decl>(d) == scope;
590 {m_decls_stack.clear();}
594 {m_types_map.clear();}
599 clear_types_to_canonicalize()
600 {m_types_to_canonicalize.clear();}
616 types_equal(type_base_sptr t1, type_base_sptr t2)
618 if (t1.get() == t2.get())
637 key_type_decl(
const type_base_sptr& type,
const string&
id)
642 m_types_map[id].push_back(type);
657 key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
662 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
663 if (i != m_fn_tmpl_map.end())
666 m_fn_tmpl_map[id] = fn_tmpl_decl;
680 key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
685 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
686 if (i != m_class_tmpl_map.end())
689 m_class_tmpl_map[id] = class_tmpl_decl;
693#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
703 record_artifact_as_used_by(type_or_decl_base* used,
704 type_or_decl_base* user)
706 if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
708 vector<type_or_decl_base*> v;
709 m_artifact_used_by_map[used] = v;
711 m_artifact_used_by_map[used].push_back(user);
725 {record_artifact_as_used_by(used.get(), user.get());}
731 record_artifacts_as_used_in_fn_decl(
const function_decl *fn)
736 type_base_sptr t = fn->get_return_type();
737 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
739 for (
auto pit : fn->get_parameters())
741 type_base_sptr t = pit->get_type();
742 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
751 {record_artifacts_as_used_in_fn_decl(fn.get());}
757 record_artifacts_as_used_in_fn_type(
const function_type *fn_type)
762 type_base_sptr t = fn_type->get_return_type();
763 record_artifact_as_used_by(t.get(),
const_cast<function_type*
>(fn_type));
765 for (
auto pit : fn_type->get_parameters())
767 type_base_sptr t = pit->get_type();
768 record_artifact_as_used_by(t.get(),
769 const_cast<function_type*
>(fn_type));
778 {record_artifacts_as_used_in_fn_type(fn_type.get());}
790 push_decl_to_scope(
const decl_base_sptr& decl, xmlNodePtr node)
792 scope_decl* scope =
nullptr;
793 scope = get_scope_ptr_for_node(node);
794 return push_decl_to_scope(decl, scope);
803 push_decl_to_scope(
const decl_base_sptr& decl,
810 if (!decl->get_translation_unit())
830 push_and_key_type_decl(
const type_base_sptr& t,
837 push_decl_to_scope(decl, scope);
838 if (!t->get_translation_unit())
841 key_type_decl(t,
id);
856 push_and_key_type_decl(
const type_base_sptr& t,
857 const xmlNodePtr node,
858 bool add_to_current_scope)
861 if (!read_type_id_string(node,
id))
864 scope_decl* scope =
nullptr;
866 scope = get_scope_ptr_for_node(node);
867 return push_and_key_type_decl(t,
id, scope);
875 corpus::exported_decls_builder*
876 get_exported_decls_builder()
877 {
return corpus()->get_exported_decls_builder().get();}
890 corpus_is_suppressed_by_soname_or_filename(
const string& soname,
891 const string& filename)
897 for (suppressions_type::const_iterator s =
suppressions().begin();
911 clear_per_translation_unit_data()
915#ifdef WITH_DEBUG_SELF_COMPARISON
935 maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
937 if (!get_environment().self_comparison_debug_is_on()
938 || get_environment().get_type_id_canonical_type_map().empty())
950 get_environment().get_type_id_from_pointer(
reinterpret_cast<uintptr_t
>(t.get()));
952 if (!type_id.empty())
957 auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
958 if (j == get_environment().get_type_id_canonical_type_map().end())
960 if (t->get_naked_canonical_type())
961 std::cerr <<
"error: no type with type-id: '"
963 <<
"' could be read back from the typeid file\n";
966 !=
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get()))
971 std::cerr <<
"error: canonical type for type '"
972 << t->get_pretty_representation(
true,
974 <<
"' of type-id '" << type_id
975 <<
"' changed from '" << std::hex
976 << j->second <<
"' to '" << std::hex
977 <<
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get())
989 schedule_type_for_canonicalization(type_base_sptr t)
992 m_types_to_canonicalize.push_back(t);
999 perform_type_canonicalization()
1001 tools_utils::timer cn_timer;
1004 std::cerr <<
"ABIXML Reader is going to canonicalize "
1005 << m_types_to_canonicalize.size()
1007 corpus_sptr c =
corpus();
1009 std::cerr <<
" of corpus " <<
corpus()->get_path() <<
"\n";
1015 m_types_to_canonicalize.end(),
1016 [](
const vector<type_base_sptr>::const_iterator& i)
1023 std::cerr <<
"ABIXML Reader: canonicalized all types in: " << cn_timer <<
"\n";
1040 const string& fn_name)
const
1044 return suppression_matches_function_name(*s, fn_name);
1057 corpus_sptr corp =
corpus();
1059 if (!s.priv_->matches_soname(corp->get_soname()))
1060 if (s.has_soname_related_property())
1066 if (!s.priv_->matches_binary_name(corp->get_path()))
1067 if (s.has_file_name_related_property())
1088 suppression_matches_function_name(
const suppr::function_suppression& s,
1089 const string& fn_name)
const
1091 if (!s.get_drops_artifact_from_ir()
1095 return suppr::suppression_matches_function_name(s, fn_name);
1111 const string& type_name,
1112 const location& type_location)
const
1121 virtual ir::corpus_sptr
1124 tools_utils::timer global_timer;
1125 global_timer.start();
1135 bool call_reader_next =
false;
1137 xmlNodePtr node = get_corpus_node();
1144 status = advance_cursor (*
this);
1147 BAD_CAST(
"abi-corpus")))
1150#ifdef WITH_DEBUG_SELF_COMPARISON
1151 if (get_environment().self_comparison_debug_is_on())
1152 get_environment().set_self_comparison_debug_input(
corpus());
1155 ir::corpus& corp = *
corpus();
1157 corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1159 handle_version_attribute(xml_reader, corp);
1166 path =
reinterpret_cast<char*
>(path_str.get());
1168 corp.set_path(path);
1173 if (architecture_str)
1174 corp.set_architecture_name
1175 (
reinterpret_cast<char*
>(architecture_str.get()));
1183 soname =
reinterpret_cast<char*
>(soname_str.get());
1185 corp.set_soname(soname);
1195 if ((!soname.empty() || !path.empty())
1196 && corpus_is_suppressed_by_soname_or_filename(soname, path))
1199 node = xmlTextReaderExpand(xml_reader.get());
1203 call_reader_next =
true;
1207#ifdef WITH_DEBUG_SELF_COMPARISON
1208 if (get_environment().self_comparison_debug_is_on())
1209 get_environment().set_self_comparison_debug_input(
corpus());
1212 ir::corpus& corp = *
corpus();
1213 corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1217 corp.set_path(
reinterpret_cast<char*
>(path_str.get()));
1221 if (architecture_str)
1222 corp.set_architecture_name
1223 (
reinterpret_cast<char*
>(architecture_str.get()));
1228 corp.set_soname(
reinterpret_cast<char*
>(soname_str.get()));
1236 xmlNodePtr n = xmlFirstElementChild(node);
1240 ir::corpus& corp = *
corpus();
1242 tools_utils::timer t;
1246 std::cerr <<
"ABIXML Reader: mapping XML nodes to type ID "
1247 <<
"for corpus " << corp.get_path()
1252 walk_xml_node_to_map_type_ids(*
this, node);
1257 std::cerr <<
"ABIXML Reader: mapped XML nodes to type ID "
1258 <<
"for corpus " << corp.get_path()
1265 vector<string> needed;
1266 read_elf_needed_from_input(*
this, needed);
1267 if (!needed.empty())
1268 corp.set_needed(needed);
1275 std::cerr <<
"ABIXML Reader: reading symbols information "
1276 <<
"for corpus " << corp.get_path()
1283 read_symbol_db_from_input(*
this, fn_sym_db, var_sym_db,
1284 non_resolved_fn_syms_aliases,
1285 non_resolved_var_syms_aliases);
1286 resolve_symbol_aliases(fn_sym_db, var_sym_db,
1287 non_resolved_fn_syms_aliases,
1288 non_resolved_var_syms_aliases);
1297 std::cerr <<
"ABIXML Reader: read symbols information "
1298 <<
"for corpus " << corp.get_path()
1304 get_environment().canonicalization_is_done(
false);
1308 std::cerr <<
"ABIXML Reader: building IR "
1309 <<
"for corpus " << corp.get_path()
1315 while (read_translation_unit_from_input(*
this))
1321 std::cerr <<
"ABIXML Reader: built IR "
1322 <<
"for corpus " << corp.get_path()
1323 <<
" in: " << t <<
"\n";
1326 if (tracking_non_reachable_types())
1328 bool is_tracking_non_reachable_types =
false;
1329 read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1332 (corp.recording_types_reachable_from_public_interface_supported()
1333 == is_tracking_non_reachable_types);
1339 std::cerr <<
"ABIXML Reader: canonicalizing types "
1340 <<
"for corpus " << corp.get_path()
1345 perform_type_canonicalization();
1350 std::cerr <<
"ABIXML Reader: canonicalized types for corpus "
1352 <<
" in :" << t <<
"\n";
1355 get_environment().canonicalization_is_done(
true);
1357 if (call_reader_next)
1361 xmlTextReaderNext(xml_reader.get());
1369 node = get_corpus_node();
1370 node = xmlNextElementSibling(node);
1373 node = get_corpus_node();
1375 node = xmlNextElementSibling(node->parent);
1377 set_corpus_node(node);
1382 std::cerr <<
"ABIXML Reader: sorting functions and variables for corpus "
1388 corpus()->sort_functions();
1389 corpus()->sort_variables();
1394 std::cerr <<
"ABIXML Reader: sorted functions and variables for corpus "
1402 global_timer.stop();
1403 std::cerr <<
"ABIXML Reader: Analyzed corpus " <<
corpus()->get_path()
1404 <<
" in " << global_timer <<
"\n";
1405 std::cerr <<
"======================================================\n";
1413typedef shared_ptr<reader> reader_sptr;
1415static int advance_cursor(reader&);
1416static bool read_translation_unit(fe_iface&, translation_unit&, xmlNodePtr);
1419static bool read_symbol_db_from_input(reader&,
1424static bool read_location(
const reader&, xmlNodePtr, location&);
1425static bool read_artificial_location(
const reader&,
1426 xmlNodePtr, location&);
1427static bool maybe_set_artificial_location(
const reader&,
1433static bool read_size_and_alignment(xmlNodePtr,
size_t&,
size_t&);
1434static bool read_static(xmlNodePtr,
bool&);
1435static bool read_offset_in_bits(xmlNodePtr,
size_t&);
1436static bool read_cdtor_const(xmlNodePtr,
bool&,
bool&,
bool&);
1437static bool read_is_virtual(xmlNodePtr,
bool&);
1438static bool read_is_struct(xmlNodePtr,
bool&);
1439static bool read_is_anonymous(xmlNodePtr,
bool&);
1442static bool read_elf_symbol_visibility(xmlNodePtr,
1444static bool read_type_hash_and_cti(xmlNodePtr, uint64_t&
hash,
1446static void read_hash_and_stash(
const xmlNodePtr,
1449build_namespace_decl(reader&,
const xmlNodePtr,
bool);
1459build_elf_symbol(reader&,
const xmlNodePtr,
bool);
1462build_elf_symbol_from_reference(reader&,
const xmlNodePtr);
1465build_elf_symbol_db(reader&,
const xmlNodePtr,
bool,
1470build_function_parameter (reader&,
const xmlNodePtr);
1473build_function_decl(reader&,
const xmlNodePtr,
1474 class_or_union_sptr,
bool,
bool);
1477build_function_decl_if_not_suppressed(reader&,
const xmlNodePtr,
1478 class_or_union_sptr,
bool,
bool);
1481function_is_suppressed(
const reader& rdr,
1485build_var_decl_if_not_suppressed(reader&,
const xmlNodePtr,
bool);
1488build_var_decl(reader&,
const xmlNodePtr,
bool);
1491variable_is_suppressed(
const reader& rdr,
1494static shared_ptr<type_decl>
1495build_type_decl(reader&,
const xmlNodePtr,
bool);
1497static qualified_type_def_sptr
1498build_qualified_type_decl(reader&,
const xmlNodePtr,
bool);
1500static shared_ptr<pointer_type_def>
1501build_pointer_type_def(reader&,
const xmlNodePtr,
bool);
1503static shared_ptr<reference_type_def>
1504build_reference_type_def(reader&,
const xmlNodePtr,
bool);
1507build_ptr_to_mbr_type(reader&,
const xmlNodePtr,
bool);
1509static shared_ptr<function_type>
1510build_function_type(reader&,
const xmlNodePtr,
bool);
1513build_subrange_type(reader&,
const xmlNodePtr,
bool);
1516build_array_type_def(reader&,
const xmlNodePtr,
bool);
1519build_enum_type_decl(reader&,
const xmlNodePtr,
bool);
1521static shared_ptr<typedef_decl>
1522build_typedef_decl(reader&,
const xmlNodePtr,
bool);
1525build_class_decl(reader&,
const xmlNodePtr,
bool);
1527static union_decl_sptr
1528build_union_decl(reader&,
const xmlNodePtr,
bool);
1530static shared_ptr<function_tdecl>
1531build_function_tdecl(reader&,
const xmlNodePtr,
bool);
1533static shared_ptr<class_tdecl>
1534build_class_tdecl(reader&,
const xmlNodePtr,
bool);
1537build_type_tparameter(reader&,
const xmlNodePtr,
1541build_type_composition(reader&,
const xmlNodePtr,
1545build_non_type_tparameter(reader&,
const xmlNodePtr,
1549build_template_tparameter(reader&,
const xmlNodePtr,
1553build_template_parameter(reader&,
const xmlNodePtr,
1560static shared_ptr<type_base>
1561build_type(reader&,
const xmlNodePtr,
bool);
1565static decl_base_sptr handle_type_decl(reader&, xmlNodePtr,
bool);
1566static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr,
bool);
1567static decl_base_sptr handle_qualified_type_decl(reader&,
1569static decl_base_sptr handle_pointer_type_def(reader&,
1571static decl_base_sptr handle_reference_type_def(reader&,
1573static type_base_sptr handle_function_type(reader&,
1575static decl_base_sptr handle_array_type_def(reader&,
1577static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr,
bool);
1578static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr,
bool);
1579static decl_base_sptr handle_var_decl(reader&, xmlNodePtr,
bool);
1580static decl_base_sptr handle_function_decl(reader&, xmlNodePtr,
bool);
1581static decl_base_sptr handle_class_decl(reader&, xmlNodePtr,
bool);
1582static decl_base_sptr handle_union_decl(reader&, xmlNodePtr,
bool);
1583static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr,
bool);
1584static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr,
bool);
1586#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1587#define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1588 rdr.record_artifact_as_used_by(used,user)
1589#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1590 rdr.record_artifacts_as_used_in_fn_decl(fn)
1591#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1592 rdr.record_artifacts_as_used_in_fn_type(fn_type)
1594#define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1595#define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1596#define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1619 xmlNodePtr parent = node->parent;
1622 && (xmlStrEqual(parent->name, BAD_CAST(
"data-member"))
1623 || xmlStrEqual(parent->name, BAD_CAST(
"member-type"))
1624 || xmlStrEqual(parent->name, BAD_CAST(
"member-function"))
1625 || xmlStrEqual(parent->name, BAD_CAST(
"member-template"))
1626 || xmlStrEqual(parent->name, BAD_CAST(
"template-parameter-type-composition"))
1627 || xmlStrEqual(parent->name, BAD_CAST(
"array-type-def"))))
1629 read_access(parent, access);
1630 parent = parent->parent;
1633 xml_node_decl_base_sptr_map::const_iterator i =
1634 get_xml_node_decl_map().find(parent);
1635 if (i == get_xml_node_decl_map().end())
1637 if (xmlStrEqual(parent->name, BAD_CAST(
"abi-instr")))
1640 get_or_read_and_add_translation_unit(*
this, parent);
1641 return tu->get_global_scope();
1646 push_decl(parent_scope);
1647 scope = dynamic_pointer_cast<scope_decl>
1648 (handle_element_node(*
this, parent,
true));
1650 pop_scope_or_abort(parent_scope);
1653 scope = dynamic_pointer_cast<scope_decl>(i->second);
1668reader::get_scope_for_node(xmlNodePtr node)
1671 return get_scope_for_node(node, access);
1684reader::get_scope_ptr_for_node(xmlNodePtr node)
1704 type_base_sptr t = get_type_decl(
id);
1708 xmlNodePtr n = get_xml_node_from_id(
id);
1715 scope = get_scope_for_node(n, access);
1723 if ((t = get_type_decl(
id)))
1741 pop_scope_or_abort(scope);
1743 schedule_type_for_canonicalization(t);
1755advance_cursor(reader& rdr)
1758 return xmlTextReaderRead(reader.get());
1770walk_xml_node_to_map_type_ids(reader& rdr,
1773 xmlNodePtr n = node;
1775 if (!n || n->type != XML_ELEMENT_NODE)
1780 string id = CHAR_STR(s);
1781 rdr.map_id_and_node(
id, n);
1784 for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1785 walk_xml_node_to_map_type_ids(rdr, n);
1789read_translation_unit(fe_iface& iface, translation_unit& tu, xmlNodePtr node)
1791 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1793 if (!rdr.corpus()->is_empty())
1794 tu.set_corpus(rdr.corpus().get());
1800 char address_size = atoi(
reinterpret_cast<char*
>(addrsize_str.get()));
1801 tu.set_address_size(address_size);
1806 tu.set_path(
reinterpret_cast<char*
>(path_str.get()));
1810 if (comp_dir_path_str)
1811 tu.set_compilation_dir_path(
reinterpret_cast<char*
>
1812 (comp_dir_path_str.get()));
1817 (
reinterpret_cast<char*
>(language_str.get())));
1822 rdr.push_decl(tu.get_global_scope());
1823 rdr.map_xml_node_to_decl(node, tu.get_global_scope());
1825 if (rdr.get_id_xml_node_map().empty()
1827 walk_xml_node_to_map_type_ids(rdr, node);
1829 for (xmlNodePtr n = xmlFirstElementChild(node);
1831 n = xmlNextElementSibling(n))
1832 handle_element_node(rdr, n,
true);
1834 rdr.pop_scope_or_abort(tu.get_global_scope());
1840 rdr.clear_per_translation_unit_data();
1859get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1861 corpus_sptr corp = rdr.corpus();
1867 if (corp && !corp->is_empty())
1870 tu_path =
reinterpret_cast<char*
>(path_str.get());
1871 tu = corp->find_translation_unit(tu_path);
1876 tu.reset(
new translation_unit(rdr.get_environment(), tu_path));
1877 if (corp && !corp->is_empty())
1880 if (read_translation_unit(rdr, *tu, node))
1895read_translation_unit_from_input(fe_iface& iface)
1899 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1901 xmlNodePtr node = rdr.get_corpus_node();
1912 status = advance_cursor (rdr);
1915 BAD_CAST(
"abi-instr")))
1918 node = xmlTextReaderExpand(reader.get());
1925 for (xmlNodePtr n = rdr.get_corpus_node();
1927 n = xmlNextElementSibling(n))
1929 if (!xmlStrEqual(n->name, BAD_CAST(
"abi-instr")))
1939 tu = get_or_read_and_add_translation_unit(rdr, node);
1941 if (rdr.get_corpus_node())
1947 node = xmlNextElementSibling(node);
1948 rdr.set_corpus_node(node);
2001read_symbol_db_from_input(reader& rdr,
2011 if (!rdr.get_corpus_node())
2017 status = advance_cursor (rdr);
2022 bool has_fn_syms =
false, has_undefined_fn_syms =
false,
2023 has_var_syms =
false, has_undefined_var_syms =
false;
2025 BAD_CAST(
"elf-function-symbols")))
2028 BAD_CAST(
"elf-variable-symbols")))
2029 has_var_syms =
true;
2031 BAD_CAST(
"undefined-elf-function-symbols")))
2032 has_undefined_fn_syms =
true;
2034 BAD_CAST(
"undefined-elf-variable-symbols")))
2035 has_undefined_var_syms =
true;
2039 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2044 build_elf_symbol_db(rdr, node,
true, fn_symdb,
2045 non_resolved_fn_syms_aliases);
2046 else if (has_undefined_fn_syms)
2047 build_elf_symbol_db(rdr, node,
true, fn_symdb,
2048 non_resolved_fn_syms_aliases);
2049 else if (has_var_syms)
2050 build_elf_symbol_db(rdr, node,
false, var_symdb,
2051 non_resolved_var_syms_aliases);
2052 else if (has_undefined_var_syms)
2053 build_elf_symbol_db(rdr, node,
false, var_symdb,
2054 non_resolved_var_syms_aliases);
2056 xmlTextReaderNext(reader.get());
2059 for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
2061 bool has_fn_syms =
false, has_undefined_fn_syms =
false,
2062 has_var_syms =
false, has_undefined_var_syms =
false;
2063 if (xmlStrEqual(n->name, BAD_CAST(
"elf-function-symbols")))
2065 else if (xmlStrEqual(n->name, BAD_CAST(
"undefined-elf-function-symbols")))
2066 has_undefined_fn_syms =
true;
2067 else if (xmlStrEqual(n->name, BAD_CAST(
"elf-variable-symbols")))
2068 has_var_syms =
true;
2069 else if (xmlStrEqual(n->name,
2070 BAD_CAST(
"undefined-elf-variable-symbols")))
2071 has_undefined_var_syms =
true;
2074 rdr.set_corpus_node(n);
2079 build_elf_symbol_db(rdr, n,
true, fn_symdb,
2080 non_resolved_fn_syms_aliases);
2081 else if (has_undefined_fn_syms)
2082 build_elf_symbol_db(rdr, n,
true, fn_symdb,
2083 non_resolved_fn_syms_aliases);
2084 else if (has_var_syms)
2085 build_elf_symbol_db(rdr, n,
false, var_symdb,
2086 non_resolved_var_syms_aliases);
2087 else if (has_undefined_var_syms)
2088 build_elf_symbol_db(rdr, n,
false, var_symdb,
2089 non_resolved_var_syms_aliases);
2108build_needed(xmlNode* node, vector<string>& needed)
2110 if (!node || !xmlStrEqual(node->name,BAD_CAST(
"elf-needed")))
2113 for (xmlNodePtr n = xmlFirstElementChild(node);
2115 n = xmlNextElementSibling(n))
2117 if (!xmlStrEqual(n->name, BAD_CAST(
"dependency")))
2125 needed.push_back(name);
2141read_elf_needed_from_input(reader& rdr,
2142 vector<string>& needed)
2148 xmlNodePtr node = 0;
2150 if (rdr.get_corpus_node() == 0)
2155 status = advance_cursor (rdr);
2161 BAD_CAST(
"elf-needed")))
2164 node = xmlTextReaderExpand(reader.get());
2170 for (xmlNodePtr n = rdr.get_corpus_node();
2172 n = xmlNextElementSibling(n))
2174 if (!xmlStrEqual(n->name, BAD_CAST(
"elf-needed")))
2181 bool result =
false;
2184 result = build_needed(node, needed);
2185 node = xmlNextElementSibling(node);
2186 rdr.set_corpus_node(node);
2221 for (suppr::suppressions_type::const_iterator i = supprs.begin();
2224 if ((*i)->get_drops_artifact_from_ir())
2225 rdr.suppressions().push_back(*i);
2240 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2241 rdr.tracking_non_reachable_types(flag);
2244#ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2253vector<type_base_sptr>*
2254get_types_from_type_id(
fe_iface& iface,
const string& type_id)
2256 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2257 auto it = rdr.m_types_map.find(type_id);
2258 if (it == rdr.m_types_map.end())
2269unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2270get_artifact_used_by_relation_map(fe_iface& iface)
2272 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2273 return &rdr.m_artifact_used_by_map;
2293 string version_string;
2298 if (version_string.empty())
2305 corp.set_format_major_version_number(v[0]);
2306 corp.set_format_minor_version_number(v[1]);
2319 corpus_group_sptr nil;
2321 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2330 status = advance_cursor (rdr);
2333 BAD_CAST(
"abi-corpus-group")))
2338 if (!rdr.corpus_group())
2340 corpus_group_sptr g(
new corpus_group(rdr.get_environment(),
2342 g->set_origin(corpus::NATIVE_XML_ORIGIN);
2343 rdr.corpus_group(g);
2346 corpus_group_sptr group = rdr.corpus_group();
2348 handle_version_attribute(reader, *group);
2352 group->set_path(
reinterpret_cast<char*
>(path_str.get()));
2356 std::cerr <<
"ABIXML Reader: reading corpus group : '"
2357 << group->get_path()
2362 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2366 node = xmlFirstElementChild(node);
2367 rdr.set_corpus_node(node);
2371 while ((corp = rdr.read_corpus(sts)))
2373 rdr.corpus_group()->add_corpus(corp);
2374 node = xmlNextElementSibling(node);
2375 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"abi-corpus")))
2378 rdr.set_corpus_node(node);
2381 xmlTextReaderNext(reader.get());
2386 std::cerr <<
"ABIXML Reader: Read corpus group : "
2387 << group->get_path()
2388 <<
" in: " << t <<
"\n";
2391 return rdr.corpus_group();
2453 rdr.perform_type_canonicalization();
2475 rdr.perform_type_canonicalization();
2490 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2492 rdr.options().env.canonicalization_is_done(
false);
2493 rdr.perform_type_canonicalization();
2494 rdr.options().env.canonicalization_is_done(
true);
2507handle_element_node(reader& rdr, xmlNodePtr node,
2508 bool add_to_current_scope)
2514 ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2515 ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2516 ||(decl = handle_qualified_type_decl(rdr, node,
2517 add_to_current_scope))
2518 ||(decl = handle_pointer_type_def(rdr, node,
2519 add_to_current_scope))
2520 || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2521 || (decl = handle_function_type(rdr, node, add_to_current_scope))
2522 || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2523 || (decl = handle_enum_type_decl(rdr, node,
2524 add_to_current_scope))
2525 || (decl = handle_typedef_decl(rdr, node,
2526 add_to_current_scope))
2527 || (decl = handle_var_decl(rdr, node,
2528 add_to_current_scope))
2529 || (decl = handle_function_decl(rdr, node,
2530 add_to_current_scope))
2531 || (decl = handle_class_decl(rdr, node,
2532 add_to_current_scope))
2533 || (decl = handle_union_decl(rdr, node,
2534 add_to_current_scope))
2535 || (decl = handle_function_tdecl(rdr, node,
2536 add_to_current_scope))
2537 || (decl = handle_class_tdecl(rdr, node,
2538 add_to_current_scope)));
2543 if (rdr.tracking_non_reachable_types())
2545 if (type_base_sptr t =
is_type(decl))
2547 corpus_sptr abi = rdr.corpus();
2549 bool is_non_reachable_type =
false;
2550 read_is_non_reachable_type(node, is_non_reachable_type);
2551 if (!is_non_reachable_type)
2552 abi->record_type_as_reachable_from_public_interfaces(*t);
2567read_location(
const reader& rdr,
2572 size_t line = 0, column = 0;
2575 file_path = CHAR_STR(f);
2577 if (file_path.empty())
2578 return read_artificial_location(rdr, node, loc);
2581 line = atoi(CHAR_STR(l));
2583 return read_artificial_location(rdr, node, loc);
2586 column = atoi(CHAR_STR(c));
2588 reader& c =
const_cast<reader&
>(rdr);
2589 loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2606read_artificial_location(
const reader& rdr,
2614 size_t line = 0, column = 0;
2619 file_path =
reinterpret_cast<const char*
>(node->doc->URL);
2621 reader& c =
const_cast<reader&
>(rdr);
2623 c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2625 loc.set_is_artificial(
true);
2645maybe_set_artificial_location(
const reader& rdr,
2649 if (artefact && !artefact->has_artificial_location())
2652 if (read_artificial_location(rdr, node, l))
2654 artefact->set_artificial_location(l);
2673 string v = CHAR_STR(s);
2676 vis = decl_base::VISIBILITY_DEFAULT;
2677 else if (v ==
"hidden")
2678 vis = decl_base::VISIBILITY_HIDDEN;
2679 else if (v ==
"internal")
2680 vis = decl_base::VISIBILITY_INTERNAL;
2681 else if (v ==
"protected")
2682 vis = decl_base::VISIBILITY_PROTECTED;
2684 vis = decl_base::VISIBILITY_DEFAULT;
2702 string b = CHAR_STR(s);
2705 bind = decl_base::BINDING_GLOBAL;
2706 else if (b ==
"local")
2707 bind = decl_base::BINDING_LOCAL;
2708 else if (b ==
"weak")
2709 bind = decl_base::BINDING_WEAK;
2711 bind = decl_base::BINDING_GLOBAL;
2730 string a = CHAR_STR(s);
2733 access = private_access;
2734 else if (a ==
"protected")
2735 access = protected_access;
2736 else if (a ==
"public")
2737 access = public_access;
2765read_size_and_alignment(xmlNodePtr node,
2766 size_t& size_in_bits,
2767 size_t& align_in_bits)
2770 bool got_something =
false;
2773 size_in_bits = atoll(CHAR_STR(s));
2774 got_something =
true;
2779 align_in_bits = atoll(CHAR_STR(s));
2780 got_something =
true;
2782 return got_something;
2795read_static(xmlNodePtr node,
bool& is_static)
2799 string b = CHAR_STR(s);
2800 is_static = b ==
"yes";
2813read_offset_in_bits(xmlNodePtr node,
2814 size_t& offset_in_bits)
2818 offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2846read_cdtor_const(xmlNodePtr node,
2847 bool& is_constructor,
2848 bool& is_destructor,
2853 string b = CHAR_STR(s);
2855 is_constructor =
true;
2857 is_constructor =
false;
2864 string b = CHAR_STR(s);
2866 is_destructor =
true;
2868 is_destructor =
false;
2875 string b = CHAR_STR(s);
2896read_is_declaration_only(xmlNodePtr node,
bool& is_decl_only)
2900 string str = CHAR_STR(s);
2902 is_decl_only =
true;
2904 is_decl_only =
false;
2920read_is_artificial(xmlNodePtr node,
bool& is_artificial)
2924 string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2925 is_artificial = is_artificial_str ==
"yes";
2944read_tracking_non_reachable_types(xmlNodePtr node,
2945 bool& tracking_non_reachable_types)
2950 string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2951 tracking_non_reachable_types =
2952 (tracking_non_reachable_types_str ==
"yes")
2971read_is_non_reachable_type(xmlNodePtr node,
bool& is_non_reachable_type)
2976 string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2977 is_non_reachable_type =
2978 (is_non_reachable_type_str ==
"yes")
2996read_naming_typedef_id_string(xmlNodePtr node,
string& naming_typedef_id)
3015read_is_virtual(xmlNodePtr node,
bool& is_virtual)
3019 string str = CHAR_STR(s);
3038read_is_struct(xmlNodePtr node,
bool& is_struct)
3042 string str = CHAR_STR(s);
3061read_is_anonymous(xmlNodePtr node,
bool& is_anonymous)
3065 string str = CHAR_STR(s);
3066 is_anonymous = (str ==
"yes");
3143read_type_id_string(xmlNodePtr node,
string& type_id)
3147 type_id = CHAR_STR(s);
3163read_name(xmlNodePtr node,
string& name)
3189read_type_hash_and_cti(xmlNodePtr node, uint64_t&
hash, uint64_t& cti)
3193 string str = CHAR_STR(s);
3194 vector<string> parts;
3196 if (!parts.empty() && !parts.front().empty())
3199 if (parts.size() > 1)
3200 cti = atoll(parts[1].c_str());
3214read_hash_and_stash(
const xmlNodePtr node,
3217 uint64_t
hash = 0, cti = 0;
3218 if (read_type_hash_and_cti(node,
hash, cti))
3220 ir_node->priv_->force_set_hash_value(
hash);
3221 type_base_sptr type;
3223 type = fn->get_type();
3229 type->type_or_decl_base::priv_->force_set_hash_value(
hash);
3230 type->priv_->canonical_type_index = cti;
3235#ifdef WITH_DEBUG_SELF_COMPARISON
3250maybe_map_type_with_type_id(
const type_base_sptr& t,
3251 const string& type_id)
3256 const environment& env = t->get_environment();
3257 if (!env.self_comparison_debug_is_on()
3261 const_cast<environment&
>(env).
3262 get_pointer_type_id_map()[
reinterpret_cast<uintptr_t
>(t.get())] = type_id;
3281maybe_map_type_with_type_id(
const type_base_sptr& t,
3287 const environment&env = t->get_environment();
3288 if (!env.self_comparison_debug_is_on()
3293 if (!read_type_id_string(node, type_id) || type_id.empty())
3296 return maybe_map_type_with_type_id(t, type_id);
3310maybe_set_naming_typedef(reader& rdr,
3312 const decl_base_sptr& decl)
3314 string naming_typedef_id;
3315 read_naming_typedef_id_string(node, naming_typedef_id);
3316 if (!naming_typedef_id.empty())
3319 is_typedef(rdr.build_or_get_type_decl(naming_typedef_id,
true));
3321 decl->set_naming_typedef(naming_typedef);
3341build_namespace_decl(reader& rdr,
3342 const xmlNodePtr node,
3343 bool add_to_current_scope)
3346 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"namespace-decl")))
3349 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3361 read_location(rdr, node, loc);
3363 const environment& env = rdr.get_environment();
3365 maybe_set_artificial_location(rdr, node, decl);
3366 rdr.push_decl_to_scope(decl,
3367 add_to_current_scope
3368 ? rdr.get_scope_ptr_for_node(node)
3370 rdr.map_xml_node_to_decl(node, decl);
3372 for (xmlNodePtr n = xmlFirstElementChild(node);
3374 n = xmlNextElementSibling(n))
3375 handle_element_node(rdr, n,
true);
3377 rdr.pop_scope_or_abort(decl);
3394build_elf_symbol(reader& rdr,
const xmlNodePtr node,
3395 bool drop_if_suppressed)
3400 || node->type != XML_ELEMENT_NODE
3401 || !xmlStrEqual(node->name, BAD_CAST(
"elf-symbol")))
3410 size = strtol(CHAR_STR(s), NULL, 0);
3412 bool is_defined =
true;
3417 if (value ==
"true" || value ==
"yes")
3423 bool is_common =
false;
3428 if (value ==
"true" || value ==
"yes")
3434 string version_string;
3438 bool is_default_version =
false;
3443 if (value ==
"true" || value ==
"yes")
3444 is_default_version =
true;
3448 read_elf_symbol_type(node, type);
3451 read_elf_symbol_binding(node, binding);
3454 read_elf_symbol_visibility(node, visibility);
3456 elf_symbol::version version(version_string, is_default_version);
3459 if (drop_if_suppressed && is_suppressed)
3462 const environment& env = rdr.get_environment();
3464 size, name, type, binding,
3465 is_defined, is_common,
3466 version, visibility);
3468 e->set_is_suppressed(is_suppressed);
3471 e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3477 e->set_namespace(ns);
3497build_elf_symbol_from_reference(reader& rdr,
const xmlNodePtr node)
3516 if (rdr.corpus()->get_symtab())
3519 rdr.corpus()->get_symtab()->lookup_symbol(name);
3521 for (
const auto& symbol : symbols)
3522 if (symbol->get_id_string() == sym_id)
3555build_elf_symbol_db(reader& rdr,
3556 const xmlNodePtr node,
3567 && !xmlStrEqual(node->name, BAD_CAST(
"elf-function-symbols"))
3568 && !xmlStrEqual(node->name, BAD_CAST(
"undefined-elf-function-symbols")))
3572 && !xmlStrEqual(node->name, BAD_CAST(
"elf-variable-symbols"))
3573 && !xmlStrEqual(node->name, BAD_CAST(
"undefined-elf-variable-symbols")))
3576 rdr.set_corpus_node(node);
3578 typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3579 xml_node_ptr_elf_symbol_sptr_map_type;
3580 xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3583 for (xmlNodePtr n = xmlFirstElementChild(node);
3585 n = xmlNextElementSibling(n))
3586 if ((sym = build_elf_symbol(rdr, n,
false)))
3588 id_sym_map[sym->get_id_string()] = sym;
3589 xml_node_ptr_elf_symbol_map[n] = sym;
3592 if (id_sym_map.empty())
3595 string_elf_symbols_map_type::iterator it;
3596 for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3597 i != id_sym_map.end();
3599 (*map)[i->second->get_name()].push_back(i->second);
3602 for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3603 xml_node_ptr_elf_symbol_map.begin();
3604 x != xml_node_ptr_elf_symbol_map.end();
3609 string alias_id = CHAR_STR(s);
3612 std::vector<std::string> elems;
3613 std::stringstream aliases(alias_id);
3615 while (std::getline(aliases, item,
','))
3616 elems.push_back(item);
3617 for (std::vector<string>::iterator alias = elems.begin();
3618 alias != elems.end(); ++alias)
3620 string_elf_symbol_sptr_map_type::const_iterator i =
3621 id_sym_map.find(*alias);
3622 if (i == id_sym_map.end())
3628 non_resolved_aliases[x->second->get_name()].push_back(*alias);
3632 x->second->get_main_symbol()->add_alias(i->second);
3670 for (
auto& entry : non_resolved_fn_sym_aliases)
3672 auto i = fn_syms->find(entry.first);
3677 sym = sym->get_main_symbol();
3679 for (
string& alias : entry.second)
3681 auto fn_a = fn_syms->find(alias);
3682 if (fn_a == fn_syms->end())
3686 auto var_a = var_syms->find(alias);
3688 alias_sym = var_a->second.front();
3693 alias_sym = fn_a->second.front();
3696 sym->add_alias(alias_sym);
3700 for (
auto& entry : non_resolved_var_sym_aliases)
3702 auto i = var_syms->find(entry.first);
3707 sym = sym->get_main_symbol();
3709 for (
string& alias : entry.second)
3711 auto var_a = var_syms->find(alias);
3712 if (var_a == var_syms->end())
3716 auto fn_a = fn_syms->find(alias);
3718 alias_sym = fn_a->second.front();
3723 alias_sym = var_a->second.front();
3726 sym->add_alias(alias_sym);
3736static shared_ptr<function_decl::parameter>
3737build_function_parameter(reader& rdr,
const xmlNodePtr node)
3739 shared_ptr<function_decl::parameter> nil;
3741 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"parameter")))
3744 bool is_variadic =
false;
3745 string is_variadic_str;
3749 is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
3750 is_variadic = is_variadic_str ==
"yes";
3753 bool is_artificial =
false;
3754 read_is_artificial(node, is_artificial);
3758 type_id = CHAR_STR(a);
3760 type_base_sptr type;
3762 type =
is_type(build_ir_node_for_variadic_parameter_type(rdr));
3766 type = rdr.build_or_get_type_decl(type_id,
true);
3775 read_location(rdr, node, loc);
3778 (
new function_decl::parameter(type, name, loc,
3779 is_variadic, is_artificial));
3807build_function_decl(reader& rdr,
3808 const xmlNodePtr node,
3809 class_or_union_sptr as_method_decl,
3810 bool add_to_current_scope,
3811 bool add_to_exported_decls)
3815 if (!xmlStrEqual(node->name, BAD_CAST(
"function-decl")))
3822 string mangled_name;
3827 && !mangled_name.empty()
3828 && as_method_decl->find_member_function_sptr(mangled_name))
3831 as_method_decl->find_member_function_sptr(mangled_name);
3838 inline_prop = CHAR_STR(s);
3839 bool declared_inline = inline_prop ==
"yes";
3842 read_visibility(node, vis);
3845 read_binding(node, bind);
3847 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3848 read_size_and_alignment(node, size, align);
3851 read_location(rdr, node, loc);
3853 const environment& env = rdr.get_environment();
3855 std::vector<function_decl::parameter_sptr> parms;
3856 type_base_sptr return_type = env.get_void_type();
3858 for (xmlNodePtr n = xmlFirstElementChild(node);
3860 n = xmlNextElementSibling(n))
3862 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
3865 build_function_parameter(rdr, n))
3868 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
3873 type_id = CHAR_STR(s);
3874 if (!type_id.empty())
3875 return_type = rdr.build_or_get_type_decl(type_id,
true);
3880 ?
new method_type(return_type, as_method_decl,
3883 :
new function_type(return_type,
3884 parms, size, align));
3888 read_hash_and_stash(node, fn_type);
3890 fn_type->set_is_artificial(
true);
3893 ?
new method_decl (name, fn_type,
3894 declared_inline, loc,
3895 mangled_name, vis, bind)
3896 :
new function_decl(name, fn_type,
3897 declared_inline, loc,
3901 maybe_set_artificial_location(rdr, node, fn_decl);
3902 rdr.push_decl_to_scope(fn_decl,
3903 add_to_current_scope
3904 ? rdr.get_scope_ptr_for_node(node)
3906 RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3910 fn_decl->set_symbol(sym);
3912 if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3913 fn_decl->set_is_in_public_symbol_table(
true);
3915 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3917 rdr.schedule_type_for_canonicalization(fn_type);
3919 if (add_to_exported_decls)
3920 rdr.add_fn_to_exported_or_undefined_decls(fn_decl.get());
3951build_function_decl_if_not_suppressed(reader& rdr,
3952 const xmlNodePtr node,
3953 class_or_union_sptr as_method_decl,
3954 bool add_to_current_scope,
3955 bool add_to_exported_decls)
3959 if (function_is_suppressed(rdr, node))
3965 fn = build_function_decl(rdr, node, as_method_decl,
3966 add_to_current_scope,
3967 add_to_exported_decls);
3983function_is_suppressed(
const reader& rdr, xmlNodePtr node)
3989 string flinkage_name;
3993 scope_decl* scope = rdr.get_cur_scope();
4012type_is_suppressed(
const reader& rdr, xmlNodePtr node)
4018 location type_location;
4019 read_location(rdr, node, type_location);
4021 scope_decl* scope = rdr.get_cur_scope();
4025 bool type_is_private =
false;
4044build_var_decl_if_not_suppressed(reader& rdr,
4045 const xmlNodePtr node,
4046 bool add_to_current_scope)
4049 if (!variable_is_suppressed(rdr, node))
4050 var = build_var_decl(rdr, node, add_to_current_scope);
4063variable_is_suppressed(
const reader& rdr, xmlNodePtr node)
4069 string linkage_name;
4073 scope_decl* scope = rdr.get_cur_scope();
4091variable_is_suppressed(
const reader& rdr,
4092 const scope_decl* scope,
4097 v.get_linkage_name());
4108static shared_ptr<var_decl>
4109build_var_decl(reader& rdr,
4110 const xmlNodePtr node,
4111 bool add_to_current_scope)
4113 shared_ptr<var_decl> nil;
4115 if (!xmlStrEqual(node->name, BAD_CAST(
"var-decl")))
4124 type_id = CHAR_STR(s);
4125 type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
4129 string mangled_name;
4134 read_visibility(node, vis);
4137 read_binding(node, bind);
4140 read_location(rdr, node, locus);
4143 locus, mangled_name,
4145 maybe_set_artificial_location(rdr, node, decl);
4149 decl->set_symbol(sym);
4151 rdr.push_decl_to_scope(decl,
4152 add_to_current_scope
4153 ? rdr.get_scope_ptr_for_node(node)
4155 if (add_to_current_scope)
4159 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4162 if (decl->get_symbol() && decl->get_symbol()->is_public())
4163 decl->set_is_in_public_symbol_table(
true);
4173static decl_base_sptr
4174build_ir_node_for_void_type(reader& rdr)
4176 const environment& env = rdr.get_environment();
4178 type_base_sptr t = env.get_void_type();
4183 rdr.schedule_type_for_canonicalization(t);
4186 return type_declaration;
4200static decl_base_sptr
4201build_ir_node_for_void_pointer_type(reader& rdr)
4203 const environment& env = rdr.get_environment();
4205 type_base_sptr t = env.get_void_pointer_type();
4210 rdr.schedule_type_for_canonicalization(t);
4213 return type_declaration;
4221static decl_base_sptr
4222build_ir_node_for_variadic_parameter_type(reader& rdr)
4224 const environment& env = rdr.get_environment();
4226 type_base_sptr t = env.get_variadic_parameter_type();
4231 rdr.schedule_type_for_canonicalization(t);
4234 return type_declaration;
4249build_type_decl(reader& rdr,
4250 const xmlNodePtr node,
4251 bool add_to_current_scope)
4253 shared_ptr<type_decl> nil;
4255 if (!xmlStrEqual(node->name, BAD_CAST(
"type-decl")))
4258 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4274 size_t size_in_bits= 0;
4276 size_in_bits = atoi(CHAR_STR(s));
4278 size_t alignment_in_bits = 0;
4280 alignment_in_bits = atoi(CHAR_STR(s));
4282 bool is_decl_only =
false;
4283 read_is_declaration_only(node, is_decl_only);
4286 read_location(rdr, node, loc);
4288 bool is_anonymous =
false;
4289 read_is_anonymous(node, is_anonymous);
4291 if (type_base_sptr d = rdr.get_type_decl(
id))
4299 ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
4300 ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
4304 const environment& env = rdr.get_environment();
4306 if (name == env.get_variadic_parameter_type_name())
4307 decl =
is_type_decl(build_ir_node_for_variadic_parameter_type(rdr));
4308 else if (name ==
"void")
4311 decl.reset(
new type_decl(env, name, size_in_bits,
4312 alignment_in_bits, loc));
4313 maybe_set_artificial_location(rdr, node, decl);
4314 decl->set_is_anonymous(is_anonymous);
4315 decl->set_is_declaration_only(is_decl_only);
4317 read_hash_and_stash(node, decl);
4319 if (rdr.push_and_key_type_decl(decl, node, add_to_current_scope))
4321 rdr.map_xml_node_to_decl(node, decl);
4339static qualified_type_def_sptr
4340build_qualified_type_decl(reader& rdr,
4341 const xmlNodePtr node,
4342 bool add_to_current_scope)
4344 qualified_type_def_sptr nil;
4345 if (!xmlStrEqual(node->name, BAD_CAST(
"qualified-type-def")))
4348 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4350 qualified_type_def_sptr result =
4351 dynamic_pointer_cast<qualified_type_def>(d);
4363 read_location(rdr, node, loc);
4368 const_str = CHAR_STR(s);
4369 bool const_cv = const_str ==
"yes";
4371 string volatile_str;
4373 volatile_str = CHAR_STR(s);
4374 bool volatile_cv = volatile_str ==
"yes";
4376 string restrict_str;
4378 restrict_str = CHAR_STR(s);
4379 bool restrict_cv = restrict_str ==
"yes";
4382 cv = cv | qualified_type_def::CV_CONST;
4384 cv = cv | qualified_type_def::CV_VOLATILE;
4386 cv = cv | qualified_type_def::CV_RESTRICT;
4390 type_id = CHAR_STR(s);
4393 shared_ptr<type_base> underlying_type =
4394 rdr.build_or_get_type_decl(type_id,
true);
4397 if (type_base_sptr t = rdr.get_type_decl(
id))
4404 qualified_type_def_sptr decl;
4405 if (type_base_sptr t = rdr.get_type_decl(
id))
4412 decl.reset(
new qualified_type_def(underlying_type, cv, loc));
4413 maybe_set_artificial_location(rdr, node, decl);
4414 rdr.push_and_key_type_decl(decl, node, add_to_current_scope);
4415 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4418 read_hash_and_stash(node, decl);
4420 rdr.map_xml_node_to_decl(node, decl);
4437build_pointer_type_def(reader& rdr,
4438 const xmlNodePtr node,
4439 bool add_to_current_scope)
4442 shared_ptr<pointer_type_def> nil;
4444 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-type-def")))
4447 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4450 dynamic_pointer_cast<pointer_type_def>(d);
4460 if (type_base_sptr t = rdr.get_type_decl(
id))
4469 type_id = CHAR_STR(s);
4471 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4472 size_t alignment_in_bits = 0;
4473 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4475 read_location(rdr, node, loc);
4477 type_base_sptr pointed_to_type =
4478 rdr.build_or_get_type_decl(type_id,
true);
4481 if (type_base_sptr t = rdr.get_type_decl(
id))
4489 if (rdr.get_environment().is_void_type(pointed_to_type))
4497 t.reset(
new pointer_type_def(pointed_to_type,
4502 maybe_set_artificial_location(rdr, node, t);
4504 rdr.push_and_key_type_decl(t, node, add_to_current_scope);
4505 rdr.map_xml_node_to_decl(node, t);
4508 read_hash_and_stash(node, t);
4510 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4526static shared_ptr<reference_type_def>
4527build_reference_type_def(reader& rdr,
4528 const xmlNodePtr node,
4529 bool add_to_current_scope)
4531 shared_ptr<reference_type_def> nil;
4533 if (!xmlStrEqual(node->name, BAD_CAST(
"reference-type-def")))
4536 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4539 dynamic_pointer_cast<reference_type_def>(d);
4549 if (type_base_sptr d = rdr.get_type_decl(
id))
4557 read_location(rdr, node, loc);
4561 bool is_lvalue = kind ==
"lvalue";
4563 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4564 size_t alignment_in_bits = 0;
4565 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4569 type_id = CHAR_STR(s);
4573 type_base_sptr pointed_to_type =
4574 rdr.build_or_get_type_decl(type_id,
true);
4579 if (type_base_sptr t = rdr.get_type_decl(
id))
4593 is_lvalue, size_in_bits,
4594 alignment_in_bits, loc));
4595 maybe_set_artificial_location(rdr, node, t);
4596 ABG_ASSERT(rdr.push_and_key_type_decl(t, node, add_to_current_scope));
4597 rdr.map_xml_node_to_decl(node, t);
4600 read_hash_and_stash(node, t);
4602 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4620build_ptr_to_mbr_type(reader& rdr,
4621 const xmlNodePtr node,
4622 bool add_to_current_scope)
4626 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-to-member-type")))
4629 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4643 if (type_base_sptr d = rdr.get_type_decl(
id))
4650 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4651 size_t alignment_in_bits = 0;
4652 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4655 read_location(rdr, node, loc);
4657 string member_type_id;
4659 member_type_id = CHAR_STR(s);
4660 if (member_type_id.empty())
4662 type_base_sptr member_type =
4663 is_type(rdr.build_or_get_type_decl(member_type_id,
true));
4667 if (type_base_sptr t = rdr.get_type_decl(
id))
4674 string containing_type_id;
4676 containing_type_id = CHAR_STR(s);
4677 if (containing_type_id.empty())
4679 type_base_sptr containing_type =
4680 rdr.build_or_get_type_decl(containing_type_id,
true);
4684 if (type_base_sptr t = rdr.get_type_decl(
id))
4691 result.reset(
new ptr_to_mbr_type(rdr.get_environment(),
4692 member_type, containing_type,
4693 size_in_bits, alignment_in_bits,
4697 read_hash_and_stash(node, result);
4699 if (rdr.push_and_key_type_decl(result, node, add_to_current_scope))
4700 rdr.map_xml_node_to_decl(node, result);
4718build_function_type(reader& rdr,
4719 const xmlNodePtr node,
4724 if (!xmlStrEqual(node->name, BAD_CAST(
"function-type")))
4732 string method_class_id;
4734 method_class_id = CHAR_STR(s);
4736 bool is_method_t = !method_class_id.empty();
4738 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4739 read_size_and_alignment(node, size, align);
4741 const environment& env = rdr.get_environment();
4742 std::vector<shared_ptr<function_decl::parameter> > parms;
4743 type_base_sptr return_type = env.get_void_type();
4745 class_or_union_sptr method_class_type;
4755 ?
new method_type(method_class_type,
4758 :
new function_type(return_type,
4759 parms, size, align));
4762 read_hash_and_stash(node, fn_type);
4764 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4765 rdr.key_type_decl(fn_type,
id);
4766 RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4768 for (xmlNodePtr n = xmlFirstElementChild(node);
4770 n = xmlNextElementSibling(n))
4772 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
4775 build_function_parameter(rdr, n))
4778 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
4783 type_id = CHAR_STR(s);
4784 type_base_sptr ret_type;
4785 if (!type_id.empty())
4786 ret_type = rdr.build_or_get_type_decl (type_id,
true);
4788 ret_type = return_type;
4789 fn_type->set_return_type(ret_type);
4792 if (!fn_type->get_return_type())
4793 fn_type->set_return_type(return_type);
4795 fn_type->set_parameters(parms);
4811build_subrange_type(reader& rdr,
4812 const xmlNodePtr node,
4813 bool add_to_current_scope)
4817 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"subrange")))
4820 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4823 dynamic_pointer_cast<array_type_def::subrange_type>(d);
4837 if (type_base_sptr d = rdr.get_type_decl(
id))
4848 uint64_t length = 0;
4850 bool is_non_finite =
false;
4853 if (
string(CHAR_STR(s)) ==
"infinite" ||
string(CHAR_STR(s)) ==
"unknown")
4854 is_non_finite =
true;
4856 length = strtoull(CHAR_STR(s), NULL, 0);
4859 uint64_t size_in_bits = 0;
4862 char *endptr =
nullptr;
4863 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4864 if (*endptr !=
'\0')
4866 if (!strcmp(CHAR_STR(s),
"infinite")
4867 ||!strcmp(CHAR_STR(s),
"unknown"))
4868 size_in_bits = (size_t) -1;
4874 int64_t lower_bound = 0, upper_bound = 0;
4875 bool bounds_present =
false;
4878 lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4880 if (!
string(CHAR_STR(s)).empty())
4881 upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4882 bounds_present =
true;
4884 || (length == (uint64_t) upper_bound - lower_bound + 1));
4887 string underlying_type_id;
4889 underlying_type_id = CHAR_STR(s);
4891 type_base_sptr underlying_type;
4892 if (!underlying_type_id.empty())
4894 underlying_type = rdr.build_or_get_type_decl(underlying_type_id,
true);
4898 if (type_base_sptr t = rdr.get_type_decl(
id))
4906 read_location(rdr, node, loc);
4911 array_type_def::subrange_type::bound_value max_bound;
4912 array_type_def::subrange_type::bound_value min_bound;
4918 max_bound.set_signed(length - 1);
4924 min_bound.set_signed(lower_bound);
4925 max_bound.set_signed(upper_bound);
4929 (
new array_type_def::subrange_type(rdr.get_environment(),
4930 name, min_bound, max_bound,
4931 underlying_type, loc));
4932 maybe_set_artificial_location(rdr, node, p);
4933 p->is_non_finite(is_non_finite);
4935 p->set_size_in_bits(size_in_bits);
4938 read_hash_and_stash(node, p);
4940 if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
4941 rdr.map_xml_node_to_decl(node, p);
4958build_array_type_def(reader& rdr,
4959 const xmlNodePtr node,
4960 bool add_to_current_scope)
4965 if (!xmlStrEqual(node->name, BAD_CAST(
"array-type-def")))
4968 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4971 dynamic_pointer_cast<array_type_def>(d);
4981 if (type_base_sptr d = rdr.get_type_decl(
id))
4990 dimensions = atoi(CHAR_STR(s));
4994 type_id = CHAR_STR(s);
4996 size_t size_in_bits = 0, alignment_in_bits = 0;
4997 bool has_size_in_bits =
false;
5002 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
5003 if (*endptr !=
'\0')
5005 if (!strcmp(CHAR_STR(s),
"infinite")
5006 ||!strcmp(CHAR_STR(s),
"unknown"))
5007 size_in_bits = (size_t) -1;
5011 has_size_in_bits =
true;
5016 alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
5017 if (*endptr !=
'\0')
5022 read_location(rdr, node, loc);
5025 for (xmlNodePtr n = xmlFirstElementChild(node);
5027 n = xmlNextElementSibling(n))
5028 if (xmlStrEqual(n->name, BAD_CAST(
"subrange")))
5031 build_subrange_type(rdr, n,
true))
5033 MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
5034 if (add_to_current_scope)
5037 rdr.schedule_type_for_canonicalization(s);
5039 subranges.push_back(s);
5044 type_base_sptr type =
5045 rdr.build_or_get_type_decl(type_id,
true);
5050 if (type_base_sptr t = rdr.get_type_decl(
id))
5059 read_hash_and_stash(node, ar_type);
5061 maybe_set_artificial_location(rdr, node, ar_type);
5062 if (rdr.push_and_key_type_decl(ar_type, node, add_to_current_scope))
5063 rdr.map_xml_node_to_decl(node, ar_type);
5064 RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
5066 if (dimensions != ar_type->get_dimension_count()
5067 || (alignment_in_bits
5068 != ar_type->get_element_type()->get_alignment_in_bits()))
5071 if (has_size_in_bits && size_in_bits != (
size_t) -1
5072 && size_in_bits != ar_type->get_size_in_bits())
5075 size_t element_size = ar_type->get_element_type()->get_size_in_bits();
5076 if (element_size && element_size != (
size_t)-1)
5079 size_t bad_count = 0;
5080 for (vector<array_type_def::subrange_sptr>::const_iterator i =
5082 i != subranges.end();
5084 bad_count += (*i)->get_length();
5085 if (size_in_bits == bad_count * element_size)
5087 static bool reported =
false;
5090 std::cerr <<
"notice: Found incorrectly calculated array "
5091 <<
"sizes in XML - this is benign.\nOlder versions "
5092 <<
"of libabigail miscalculated multidimensional "
5093 <<
"array sizes." << std::endl;
5099 std::cerr <<
"error: Found incorrectly calculated array size in "
5100 <<
"XML (id=\"" <<
id <<
"\")." << std::endl;
5124build_enum_type_decl_if_not_suppressed(reader& rdr,
5125 const xmlNodePtr node,
5126 bool add_to_current_scope)
5129 if (!type_is_suppressed(rdr, node))
5130 enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
5146build_enum_type_decl(reader& rdr,
5147 const xmlNodePtr node,
5148 bool add_to_current_scope)
5152 if (!xmlStrEqual(node->name, BAD_CAST(
"enum-decl")))
5155 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5158 dynamic_pointer_cast<enum_type_decl>(d);
5167 string linkage_name;
5172 read_location(rdr, node, loc);
5174 bool is_decl_only =
false;
5175 read_is_declaration_only(node, is_decl_only);
5177 bool is_anonymous =
false;
5178 read_is_anonymous(node, is_anonymous);
5180 bool is_artificial =
false;
5181 read_is_artificial(node, is_artificial);
5189 if (type_base_sptr t = rdr.get_type_decl(
id))
5196 string base_type_id;
5198 for (xmlNodePtr n = xmlFirstElementChild(node);
5200 n = xmlNextElementSibling(n))
5202 if (xmlStrEqual(n->name, BAD_CAST(
"underlying-type")))
5206 base_type_id = CHAR_STR(a);
5209 else if (xmlStrEqual(n->name, BAD_CAST(
"enumerator")))
5221 value = strtoll(CHAR_STR(a), NULL, 0);
5225 if ((errno == ERANGE)
5226 && (value == LLONG_MIN || value == LLONG_MAX))
5230 enums.push_back(enum_type_decl::enumerator(name, value));
5234 type_base_sptr underlying_type =
5235 rdr.build_or_get_type_decl(base_type_id,
true);
5238 if (type_base_sptr t = rdr.get_type_decl(
id))
5247 enums, linkage_name));
5248 maybe_set_artificial_location(rdr, node, t);
5249 t->set_is_anonymous(is_anonymous);
5250 t->set_is_artificial(is_artificial);
5251 t->set_is_declaration_only(is_decl_only);
5253 read_hash_and_stash(node, t);
5255 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
5257 maybe_set_naming_typedef(rdr, node, t);
5258 rdr.map_xml_node_to_decl(node, t);
5259 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
5274static shared_ptr<typedef_decl>
5275build_typedef_decl(reader& rdr,
5276 const xmlNodePtr node,
5277 bool add_to_current_scope)
5279 shared_ptr<typedef_decl> nil;
5281 if (!xmlStrEqual(node->name, BAD_CAST(
"typedef-decl")))
5284 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5296 if (type_base_sptr t = rdr.get_type_decl(
id))
5308 read_location(rdr, node, loc);
5312 type_id = CHAR_STR(s);
5315 type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id,
true));
5320 if (type_base_sptr t = rdr.get_type_decl(
id))
5328 maybe_set_artificial_location(rdr, node, t);
5331 read_hash_and_stash(node, t);
5333 rdr.push_and_key_type_decl(t, node, add_to_current_scope);
5334 rdr.map_xml_node_to_decl(node, t);
5335 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
5352build_class_decl_if_not_suppressed(reader& rdr,
5353 const xmlNodePtr node,
5354 bool add_to_current_scope)
5357 if (!type_is_suppressed(rdr, node))
5358 class_type = build_class_decl(rdr, node, add_to_current_scope);
5374static union_decl_sptr
5375build_union_decl_if_not_suppressed(reader& rdr,
5376 const xmlNodePtr node,
5377 bool add_to_current_scope)
5379 union_decl_sptr union_type;
5380 if (!type_is_suppressed(rdr, node))
5381 union_type = build_union_decl(rdr, node, add_to_current_scope);
5398build_class_decl(reader& rdr,
5399 const xmlNodePtr node,
5400 bool add_to_current_scope)
5404 if (!xmlStrEqual(node->name, BAD_CAST(
"class-decl")))
5407 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5418 size_t size_in_bits = 0, alignment_in_bits = 0;
5419 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5422 read_visibility(node, vis);
5424 bool is_artificial =
false;
5425 read_is_artificial(node, is_artificial);
5432 read_location(rdr, node, loc);
5441 bool is_decl_only =
false;
5442 read_is_declaration_only(node, is_decl_only);
5444 bool is_struct =
false;
5445 read_is_struct(node, is_struct);
5447 bool is_anonymous =
false;
5448 read_is_anonymous(node, is_anonymous);
5454 if (type_base_sptr t = rdr.get_type_decl(
id))
5460 const vector<type_base_sptr> *types_ptr = 0;
5461 if (!is_anonymous && !previous_definition)
5462 types_ptr = rdr.get_all_type_decls(
id);
5468 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5469 i != types_ptr->end();
5474 if (klass->get_is_declaration_only()
5475 && !klass->get_definition_of_declaration())
5476 previous_declaration = klass;
5477 else if (!klass->get_is_declaration_only()
5478 && !previous_definition)
5479 previous_definition = klass;
5480 if (previous_definition && previous_declaration)
5484 if (previous_declaration)
5485 ABG_ASSERT(previous_declaration->get_name() == name);
5487 if (previous_definition)
5488 ABG_ASSERT(previous_definition->get_name() == name);
5490 if (is_decl_only && previous_declaration)
5491 return previous_declaration;
5494 const environment& env = rdr.get_environment();
5496 if (!is_decl_only && previous_definition)
5502 decl = previous_definition;
5507 decl.reset(
new class_decl(env, name, is_struct));
5509 decl->set_size_in_bits(size_in_bits);
5511 decl->set_is_anonymous(is_anonymous);
5512 decl->set_location(loc);
5515 decl.reset(
new class_decl(env, name, size_in_bits, alignment_in_bits,
5516 is_struct, loc, vis, bases, mbrs,
5517 data_mbrs, mbr_functions, is_anonymous));
5520 maybe_set_artificial_location(rdr, node, decl);
5521 decl->set_is_artificial(is_artificial);
5524 read_hash_and_stash(node, decl);
5527 bool is_def_of_decl =
false;
5529 def_id = CHAR_STR(s);
5531 if (!def_id.empty())
5533 decl_base_sptr d =
is_decl(rdr.get_type_decl(def_id));
5534 if (d && d->get_is_declaration_only())
5536 is_def_of_decl =
true;
5537 decl->set_earlier_declaration(d);
5538 d->set_definition_of_declaration(decl);
5544 && !decl->get_is_declaration_only()
5545 && previous_declaration)
5551 decl->set_earlier_declaration(
is_decl(previous_declaration));
5552 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5553 i != types_ptr->end();
5558 if (d->get_is_declaration_only()
5559 && !d->get_definition_of_declaration())
5561 previous_declaration->set_definition_of_declaration(decl);
5562 is_def_of_decl =
true;
5567 if (is_decl_only && previous_definition)
5572 && !decl->get_definition_of_declaration());
5573 decl->set_definition_of_declaration(previous_definition);
5576 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5578 rdr.push_decl_to_scope(decl,
5579 add_to_current_scope
5580 ? rdr.get_scope_ptr_for_node(node)
5583 rdr.map_xml_node_to_decl(node, decl);
5584 rdr.key_type_decl(decl,
id);
5587 maybe_set_naming_typedef(rdr, node, decl);
5589 for (xmlNodePtr n = xmlFirstElementChild(node);
5591 n = xmlNextElementSibling(n))
5593 if (xmlStrEqual(n->name, BAD_CAST(
"base-class")))
5599 read_access(n, access);
5603 type_id = CHAR_STR(s);
5604 shared_ptr<class_decl> b =
5605 dynamic_pointer_cast<class_decl>
5606 (rdr.build_or_get_type_decl(type_id,
true));
5609 if (decl->find_base_class(b->get_qualified_name()))
5615 size_t offset_in_bits = 0;
5616 bool offset_present = read_offset_in_bits (n, offset_in_bits);
5618 bool is_virtual =
false;
5619 read_is_virtual (n, is_virtual);
5621 shared_ptr<class_decl::base_spec> base (
new class_decl::base_spec
5624 ? (
long) offset_in_bits
5627 decl->add_base_specifier(base);
5629 else if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5635 read_access(n, access);
5637 rdr.map_xml_node_to_decl(n, decl);
5639 for (xmlNodePtr p = xmlFirstElementChild(n);
5641 p = xmlNextElementSibling(p))
5644 string member_type_name;
5645 read_name(p, member_type_name);
5647 if (!member_type_name.empty())
5648 t = decl->find_member_type(member_type_name);
5652 if ((t = build_type(rdr, p,
true)))
5656 if (!td->get_scope())
5657 decl->add_member_type(t);
5659 rdr.schedule_type_for_canonicalization(t);
5661 string id = CHAR_STR(i);
5663 rdr.key_type_decl(t,
id);
5664 rdr.map_xml_node_to_decl(p, td);
5668 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5670 rdr.map_xml_node_to_decl(n, decl);
5676 read_access(n, access);
5678 bool is_laid_out =
false;
5679 size_t offset_in_bits = 0;
5680 if (read_offset_in_bits(n, offset_in_bits))
5683 bool is_static =
false;
5684 read_static(n, is_static);
5686 for (xmlNodePtr p = xmlFirstElementChild(n);
5688 p = xmlNextElementSibling(p))
5691 build_var_decl(rdr, p,
false))
5693 if (decl->find_data_member(v))
5701 decl_base_sptr d = rdr.pop_decl();
5706 if (!variable_is_suppressed(rdr, decl.get(), *v))
5708 decl->add_data_member(v, access,
5713 rdr.add_var_to_exported_or_undefined_decls(v);
5723 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5726 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5727 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5733 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5739 read_access(n, access);
5741 bool is_virtual =
false;
5742 ssize_t vtable_offset = -1;
5747 vtable_offset = atoi(CHAR_STR(s));
5750 bool is_static =
false;
5751 read_static(n, is_static);
5753 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5754 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5756 for (xmlNodePtr p = xmlFirstElementChild(n);
5758 p = xmlNextElementSibling(p))
5761 build_function_decl_if_not_suppressed(rdr, p, decl,
5774 rdr.map_xml_node_to_decl(p, m);
5775 rdr.add_fn_to_exported_or_undefined_decls(f.get());
5780 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5782 rdr.map_xml_node_to_decl(n, decl);
5788 read_access(n, access);
5790 bool is_static =
false;
5791 read_static(n, is_static);
5793 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5794 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5796 for (xmlNodePtr p = xmlFirstElementChild(n);
5798 p = xmlNextElementSibling(p))
5800 if (shared_ptr<function_tdecl> f =
5801 build_function_tdecl(rdr, p,
5804 shared_ptr<member_function_template> m
5805 (
new member_function_template(f, access, is_static,
5806 is_ctor, is_const));
5808 decl->add_member_function_template(m);
5810 else if (shared_ptr<class_tdecl> c =
5811 build_class_tdecl(rdr, p,
5814 member_class_template_sptr m(
new member_class_template(c,
5818 decl->add_member_class_template(m);
5824 rdr.pop_scope_or_abort(decl);
5841static union_decl_sptr
5842build_union_decl(reader& rdr,
5843 const xmlNodePtr node,
5844 bool add_to_current_scope)
5846 union_decl_sptr nil;
5848 if (!xmlStrEqual(node->name, BAD_CAST(
"union-decl")))
5851 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5853 union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5862 size_t size_in_bits = 0, alignment_in_bits = 0;
5863 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5866 read_visibility(node, vis);
5868 bool is_artificial =
false;
5869 read_is_artificial(node, is_artificial);
5876 read_location(rdr, node, loc);
5882 union_decl_sptr decl;
5884 bool is_decl_only =
false;
5885 read_is_declaration_only(node, is_decl_only);
5887 bool is_anonymous =
false;
5888 read_is_anonymous(node, is_anonymous);
5891 union_decl_sptr previous_definition, previous_declaration;
5892 const vector<type_base_sptr> *types_ptr = 0;
5894 types_ptr = rdr.get_all_type_decls(
id);
5900 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5901 i != types_ptr->end();
5906 if (onion->get_is_declaration_only()
5907 && !onion->get_definition_of_declaration())
5908 previous_declaration = onion;
5909 else if (!onion->get_is_declaration_only()
5910 && !previous_definition)
5911 previous_definition = onion;
5912 if (previous_definition && previous_declaration)
5916 if (previous_declaration)
5917 ABG_ASSERT(previous_declaration->get_name() == name);
5919 if (previous_definition)
5920 ABG_ASSERT(previous_definition->get_name() == name);
5922 if (is_decl_only && previous_declaration)
5923 return previous_declaration;
5926 const environment& env = rdr.get_environment();
5928 if (!is_decl_only && previous_definition)
5934 decl = previous_definition;
5938 decl.reset(
new union_decl(env, name));
5940 decl.reset(
new union_decl(env, name,
5949 read_hash_and_stash(node, decl);
5951 maybe_set_artificial_location(rdr, node, decl);
5952 decl->set_is_artificial(is_artificial);
5955 bool is_def_of_decl =
false;
5957 def_id = CHAR_STR(s);
5959 if (!def_id.empty())
5962 dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5963 if (d && d->get_is_declaration_only())
5965 is_def_of_decl =
true;
5966 decl->set_earlier_declaration(d);
5967 d->set_definition_of_declaration(decl);
5973 && !decl->get_is_declaration_only()
5974 && previous_declaration)
5980 decl->set_earlier_declaration(previous_declaration);
5981 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5982 i != types_ptr->end();
5987 if (d->get_is_declaration_only()
5988 && !d->get_definition_of_declaration())
5990 previous_declaration->set_definition_of_declaration(decl);
5991 is_def_of_decl =
true;
5996 if (is_decl_only && previous_definition)
6001 && !decl->get_definition_of_declaration());
6002 decl->set_definition_of_declaration(previous_definition);
6005 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
6007 rdr.push_decl_to_scope(decl,
6008 add_to_current_scope
6009 ? rdr.get_scope_ptr_for_node(node)
6012 rdr.map_xml_node_to_decl(node, decl);
6013 rdr.key_type_decl(decl,
id);
6015 maybe_set_naming_typedef(rdr, node, decl);
6017 for (xmlNodePtr n = xmlFirstElementChild(node);
6019 n = xmlNextElementSibling(n))
6021 if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
6024 read_access(n, access);
6026 rdr.map_xml_node_to_decl(n, decl);
6028 for (xmlNodePtr p = xmlFirstElementChild(n);
6030 p = xmlNextElementSibling(p))
6032 string member_type_name;
6033 read_name(p, member_type_name);
6035 if (!member_type_name.empty())
6036 t = decl->find_member_type(member_type_name);
6039 if ((t = build_type(rdr, p,
true)))
6043 if (!td->get_scope())
6044 decl->add_member_type(t);
6046 rdr.schedule_type_for_canonicalization(t);
6049 string id = CHAR_STR(i);
6051 rdr.key_type_decl(t,
id);
6052 rdr.map_xml_node_to_decl(p, td);
6056 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
6058 rdr.map_xml_node_to_decl(n, decl);
6061 read_access(n, access);
6063 bool is_laid_out =
true;
6064 size_t offset_in_bits = 0;
6065 bool is_static =
false;
6066 read_static(n, is_static);
6068 for (xmlNodePtr p = xmlFirstElementChild(n);
6070 p = xmlNextElementSibling(p))
6073 build_var_decl(rdr, p,
false))
6075 if (decl->find_data_member(v))
6083 decl_base_sptr d = rdr.pop_decl();
6088 || !variable_is_suppressed(rdr, decl.get(), *v))
6090 decl->add_data_member(v, access,
6103 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
6106 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
6107 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
6113 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
6115 rdr.map_xml_node_to_decl(n, decl);
6118 read_access(n, access);
6120 bool is_static =
false;
6121 read_static(n, is_static);
6123 bool is_ctor =
false, is_dtor =
false, is_const =
false;
6124 read_cdtor_const(n, is_ctor, is_dtor, is_const);
6126 for (xmlNodePtr p = xmlFirstElementChild(n);
6128 p = xmlNextElementSibling(p))
6131 build_function_decl_if_not_suppressed(rdr, p, decl,
6142 rdr.add_fn_to_exported_or_undefined_decls(f.get());
6147 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
6149 rdr.map_xml_node_to_decl(n, decl);
6152 read_access(n, access);
6154 bool is_static =
false;
6155 read_static(n, is_static);
6157 bool is_ctor =
false, is_dtor =
false, is_const =
false;
6158 read_cdtor_const(n, is_ctor, is_dtor, is_const);
6160 for (xmlNodePtr p = xmlFirstElementChild(n);
6162 p = xmlNextElementSibling(p))
6165 build_function_tdecl(rdr, p,
6168 member_function_template_sptr m
6169 (
new member_function_template(f, access, is_static,
6170 is_ctor, is_const));
6172 decl->add_member_function_template(m);
6175 build_class_tdecl(rdr, p,
6178 member_class_template_sptr m(
new member_class_template(c,
6182 decl->add_member_class_template(m);
6188 rdr.pop_scope_or_abort(decl);
6205static shared_ptr<function_tdecl>
6206build_function_tdecl(reader& rdr,
6207 const xmlNodePtr node,
6208 bool add_to_current_scope)
6210 shared_ptr<function_tdecl> nil, result;
6212 if (!xmlStrEqual(node->name, BAD_CAST(
"function-template-decl")))
6218 if (
id.empty() || rdr.get_fn_tmpl_decl(
id))
6222 read_location(rdr, node, loc);
6225 read_visibility(node, vis);
6228 read_binding(node, bind);
6230 const environment& env = rdr.get_environment();
6233 maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
6235 rdr.push_decl_to_scope(fn_tmpl_decl,
6236 add_to_current_scope
6237 ? rdr.get_scope_ptr_for_node(node)
6239 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
6240 rdr.map_xml_node_to_decl(node, fn_tmpl_decl);
6242 unsigned parm_index = 0;
6243 for (xmlNodePtr n = xmlFirstElementChild(node);
6245 n = xmlNextElementSibling(n))
6248 build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
6250 fn_tmpl_decl->add_template_parameter(parm);
6257 fn_tmpl_decl->set_pattern(f);
6260 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
6262 return fn_tmpl_decl;
6278build_class_tdecl(reader& rdr,
6279 const xmlNodePtr node,
6280 bool add_to_current_scope)
6284 if (!xmlStrEqual(node->name, BAD_CAST(
"class-template-decl")))
6290 if (
id.empty() || rdr.get_class_tmpl_decl(
id))
6294 read_location(rdr, node, loc);
6297 read_visibility(node, vis);
6299 const environment& env = rdr.get_environment();
6302 maybe_set_artificial_location(rdr, node, class_tmpl);
6304 if (add_to_current_scope)
6305 rdr.push_decl_to_scope(class_tmpl, node);
6306 rdr.key_class_tmpl_decl(class_tmpl,
id);
6307 rdr.map_xml_node_to_decl(node, class_tmpl);
6309 unsigned parm_index = 0;
6310 for (xmlNodePtr n = xmlFirstElementChild(node);
6312 n = xmlNextElementSibling(n))
6315 build_template_parameter(rdr, n, parm_index, class_tmpl))
6317 class_tmpl->add_template_parameter(parm);
6321 build_class_decl_if_not_suppressed(rdr, n,
6322 add_to_current_scope))
6325 rdr.schedule_type_for_canonicalization(c);
6326 class_tmpl->set_pattern(c);
6330 rdr.key_class_tmpl_decl(class_tmpl,
id);
6351build_type_tparameter(reader& rdr,
6352 const xmlNodePtr node,
6358 if (!xmlStrEqual(node->name, BAD_CAST(
"template-type-parameter")))
6369 type_id = CHAR_STR(s);
6370 if (!type_id.empty()
6371 && !(result = dynamic_pointer_cast<type_tparameter>
6372 (rdr.build_or_get_type_decl(type_id,
true))))
6380 read_location(rdr, node,loc);
6382 result.reset(
new type_tparameter(index, tdecl, name, loc));
6383 maybe_set_artificial_location(rdr, node, result);
6386 rdr.push_decl_to_scope(
is_decl(result), node);
6388 rdr.push_and_key_type_decl(result, node,
true);
6390 rdr.schedule_type_for_canonicalization(result);
6410build_type_composition(reader& rdr,
6411 const xmlNodePtr node,
6417 if (!xmlStrEqual(node->name, BAD_CAST(
"template-parameter-type-composition")))
6420 type_base_sptr composed_type;
6421 result.reset(
new type_composition(index, tdecl, composed_type));
6422 rdr.push_decl_to_scope(
is_decl(result), node);
6424 for (xmlNodePtr n = xmlFirstElementChild(node);
6426 n = xmlNextElementSibling(n))
6428 if ((composed_type =
6429 build_pointer_type_def(rdr, n,
6432 build_reference_type_def(rdr, n,
6435 build_array_type_def(rdr, n,
6438 build_qualified_type_decl(rdr, n,
6441 rdr.schedule_type_for_canonicalization(composed_type);
6442 result->set_composed_type(composed_type);
6466build_non_type_tparameter(reader& rdr,
6467 const xmlNodePtr node,
6473 if (!xmlStrEqual(node->name, BAD_CAST(
"template-non-type-parameter")))
6478 type_id = CHAR_STR(s);
6479 type_base_sptr type;
6481 || !(type = rdr.build_or_get_type_decl(type_id,
true)))
6489 read_location(rdr, node,loc);
6491 r.reset(
new non_type_tparameter(index, tdecl, name, type, loc));
6492 maybe_set_artificial_location(rdr, node, r);
6493 rdr.push_decl_to_scope(
is_decl(r), node);
6513build_template_tparameter(reader& rdr,
6514 const xmlNodePtr node,
6520 if (!xmlStrEqual(node->name, BAD_CAST(
"template-template-parameter")))
6531 type_id = CHAR_STR(s);
6533 if (!type_id.empty()
6534 && !(dynamic_pointer_cast<template_tparameter>
6535 (rdr.build_or_get_type_decl(type_id,
true))))
6543 read_location(rdr, node, loc);
6547 maybe_set_artificial_location(rdr, node, result);
6548 rdr.push_decl_to_scope(result, node);
6552 for (xmlNodePtr n = xmlFirstElementChild(node);
6554 n = xmlNextElementSibling(n))
6555 if (shared_ptr<template_parameter> p =
6556 build_template_parameter(rdr, n, parm_index, result))
6558 result->add_template_parameter(p);
6564 rdr.key_type_decl(result,
id);
6565 rdr.schedule_type_for_canonicalization(result);
6587build_template_parameter(reader& rdr,
6588 const xmlNodePtr node,
6592 shared_ptr<template_parameter> r;
6593 ((r = build_type_tparameter(rdr, node, index, tdecl))
6594 || (r = build_non_type_tparameter(rdr, node, index, tdecl))
6595 || (r = build_template_tparameter(rdr, node, index, tdecl))
6596 || (r = build_type_composition(rdr, node, index, tdecl)));
6609static type_base_sptr
6610build_type(reader& rdr,
6611 const xmlNodePtr node,
6612 bool add_to_current_scope)
6616 ((t = build_type_decl(rdr, node, add_to_current_scope))
6617 || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
6618 || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
6619 || (t = build_reference_type_def(rdr, node , add_to_current_scope))
6620 || (t = build_ptr_to_mbr_type(rdr, node , add_to_current_scope))
6621 || (t = build_function_type(rdr, node, add_to_current_scope))
6622 || (t = build_array_type_def(rdr, node, add_to_current_scope))
6623 || (t = build_subrange_type(rdr, node, add_to_current_scope))
6624 || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
6625 add_to_current_scope))
6626 || (t = build_typedef_decl(rdr, node, add_to_current_scope))
6627 || (t = build_class_decl_if_not_suppressed(rdr, node,
6628 add_to_current_scope))
6629 || (t = build_union_decl_if_not_suppressed(rdr, node,
6630 add_to_current_scope)));
6632 if (rdr.tracking_non_reachable_types() && t)
6634 corpus_sptr abi = rdr.corpus();
6636 bool is_non_reachable_type =
false;
6637 read_is_non_reachable_type(node, is_non_reachable_type);
6638 if (!is_non_reachable_type)
6639 abi->record_type_as_reachable_from_public_interfaces(*t);
6642 MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
6645 rdr.schedule_type_for_canonicalization(t);
6654static decl_base_sptr
6655handle_type_decl(reader& rdr,
6657 bool add_to_current_scope)
6659 type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
6660 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6661 if (decl && decl->get_scope())
6662 rdr.schedule_type_for_canonicalization(decl);
6671static decl_base_sptr
6672handle_namespace_decl(reader& rdr,
6674 bool add_to_current_scope)
6677 add_to_current_scope);
6686static decl_base_sptr
6687handle_qualified_type_decl(reader& rdr,
6689 bool add_to_current_scope)
6691 qualified_type_def_sptr decl =
6692 build_qualified_type_decl(rdr, node,
6693 add_to_current_scope);
6694 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6695 if (decl && decl->get_scope())
6696 rdr.schedule_type_for_canonicalization(decl);
6705static decl_base_sptr
6706handle_pointer_type_def(reader& rdr,
6708 bool add_to_current_scope)
6711 add_to_current_scope);
6712 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6713 if (decl && decl->get_scope())
6714 rdr.schedule_type_for_canonicalization(decl);
6723static decl_base_sptr
6724handle_reference_type_def(reader& rdr,
6726 bool add_to_current_scope)
6729 add_to_current_scope);
6730 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6731 if (decl && decl->get_scope())
6732 rdr.schedule_type_for_canonicalization(decl);
6741static type_base_sptr
6742handle_function_type(reader& rdr,
6744 bool add_to_current_scope)
6747 add_to_current_scope);
6748 MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
6749 rdr.schedule_type_for_canonicalization(type);
6758static decl_base_sptr
6759handle_array_type_def(reader& rdr,
6761 bool add_to_current_scope)
6764 add_to_current_scope);
6765 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6766 rdr.schedule_type_for_canonicalization(decl);
6773static decl_base_sptr
6774handle_enum_type_decl(reader& rdr,
6776 bool add_to_current_scope)
6779 build_enum_type_decl_if_not_suppressed(rdr, node,
6780 add_to_current_scope);
6781 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6782 if (decl && decl->get_scope())
6783 rdr.schedule_type_for_canonicalization(decl);
6790static decl_base_sptr
6791handle_typedef_decl(reader& rdr,
6793 bool add_to_current_scope)
6796 add_to_current_scope);
6797 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6798 if (decl && decl->get_scope())
6799 rdr.schedule_type_for_canonicalization(decl);
6811static decl_base_sptr
6812handle_var_decl(reader& rdr,
6814 bool add_to_current_scope)
6816 decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6817 add_to_current_scope);
6818 rdr.add_var_to_exported_or_undefined_decls(
is_var_decl(decl));
6828static decl_base_sptr
6829handle_function_decl(reader& rdr,
6831 bool add_to_current_scope)
6833 return build_function_decl_if_not_suppressed(rdr, node,
class_decl_sptr(),
6834 add_to_current_scope,
6844static decl_base_sptr
6845handle_class_decl(reader& rdr,
6847 bool add_to_current_scope)
6850 build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6851 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6852 if (decl && decl->get_scope())
6853 rdr.schedule_type_for_canonicalization(decl);
6863static decl_base_sptr
6864handle_union_decl(reader& rdr,
6866 bool add_to_current_scope)
6868 union_decl_sptr decl =
6869 build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6870 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6871 if (decl && decl->get_scope())
6872 rdr.schedule_type_for_canonicalization(decl);
6882static decl_base_sptr
6883handle_function_tdecl(reader& rdr,
6885 bool add_to_current_scope)
6888 add_to_current_scope);
6897static decl_base_sptr
6898handle_class_tdecl(reader& rdr,
6900 bool add_to_current_scope)
6903 add_to_current_scope);
6920 return read_translation_unit_from_input(read_rdr);
6945 corpus_sptr corp = result->corpus();
6946 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6947#ifdef WITH_DEBUG_SELF_COMPARISON
6948 if (env.self_comparison_debug_is_on())
6949 env.set_self_comparison_debug_input(result->corpus());
6951 result->set_path(path);
6968 corpus_sptr corp = result->corpus();
6969 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6970#ifdef WITH_DEBUG_SELF_COMPARISON
6971 if (env.self_comparison_debug_is_on())
6972 env.set_self_comparison_debug_input(result->corpus());
6995 return rdr->read_corpus(sts);
7017 corpus_sptr corp = rdr->read_corpus(sts);
7023#ifdef WITH_DEBUG_SELF_COMPARISON
7042load_canonical_type_ids(fe_iface& iface,
const string &file_path)
7044 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
7046 xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
7050 xmlNodePtr node = xmlDocGetRootElement(doc);
7073 if (xmlStrcmp(node->name, (xmlChar*)
"abixml-types-check"))
7076 for (node = xmlFirstElementChild(node);
7078 node = xmlNextElementSibling(node))
7080 if (xmlStrcmp(node->name, (xmlChar*)
"type"))
7083 string id, canonical_address;
7084 xmlNodePtr data = xmlFirstElementChild(node);
7085 if (data && !xmlStrcmp(data->name, (xmlChar*)
"id")
7086 && data->children && xmlNodeIsText(data->children))
7087 id = (
char*) XML_GET_CONTENT(data->children);
7089 data = xmlNextElementSibling(data);
7090 if (data && !xmlStrcmp(data->name, (xmlChar*)
"c")
7091 && data->children && xmlNodeIsText(data->children))
7093 canonical_address = (
char*) XML_GET_CONTENT(data->children);
7094 std::stringstream s;
7095 s << canonical_address;
7103 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.
virtual void initialize(const std::string &corpus_path)
Re-initialize 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'.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
bool deserialize_hash(const string &input, uint64_t &hash)
Read a string of characters representing a string of hexadecimal digits which itself represents a has...
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.
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
shared_ptr< non_type_tparameter > non_type_tparameter_sptr
Convenience typedef for shared pointer to non_type_template_parameter.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
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.
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
bool is_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
std::unordered_map< string, elf_symbol_sptr > string_elf_symbol_sptr_map_type
Convenience typedef for a map which key is a string and which value if the elf symbol of the same nam...
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< string_elf_symbols_map_type > string_elf_symbols_map_sptr
Convenience typedef for a shared pointer to string_elf_symbols_map_type.
void hash_and_canonicalize_types(IteratorType begin, IteratorType end, deref_lambda deref, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
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.
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.
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
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.
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.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
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.