15 #include <libxml/xmlreader.h>
16 #include <libxml/xmlstring.h>
23 #include <unordered_map>
27 #include "abg-internal.h"
31 ABG_BEGIN_EXPORT_DECLARATIONS
52 using std::shared_ptr;
53 using std::unordered_map;
54 using std::dynamic_pointer_cast;
64 static bool read_is_declaration_only(xmlNodePtr,
bool&);
65 static bool read_is_artificial(xmlNodePtr,
bool&);
66 static bool read_tracking_non_reachable_types(xmlNodePtr,
bool&);
67 static bool read_is_non_reachable_type(xmlNodePtr,
bool&);
68 static bool read_naming_typedef_id_string(xmlNodePtr,
string&);
69 static bool read_type_id_string(xmlNodePtr,
string&);
70 #ifdef WITH_DEBUG_SELF_COMPARISON
71 static bool maybe_map_type_with_type_id(
const type_base_sptr&,
73 static bool maybe_map_type_with_type_id(
const type_base_sptr&,
76 #define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node) \
77 maybe_map_type_with_type_id(type, xml_node)
79 #define MAYBE_MAP_TYPE_WITH_TYPE_ID(type, xml_node)
81 static void maybe_set_naming_typedef(reader& rdr,
83 const decl_base_sptr &);
86 static int advance_cursor(reader& rdr);
92 walk_xml_node_to_map_type_ids(reader& rdr, xmlNodePtr node);
95 read_elf_needed_from_input(reader& rdr, vector<string>& needed);
98 read_symbol_db_from_input(reader& rdr,
101 string_strings_map_type& non_resolved_fn_syms_aliases,
102 string_strings_map_type& non_resolved_var_syms_aliases);
105 read_translation_unit_from_input(
fe_iface& rdr);
107 static decl_base_sptr
108 build_ir_node_for_void_type(reader& rdr);
110 static decl_base_sptr
111 build_ir_node_for_void_pointer_type(reader& rdr);
116 string_strings_map_type& non_resolved_fn_sym_aliases,
117 string_strings_map_type& non_resolved_var_sym_aliases);
130 typedef unordered_map<string, vector<type_base_sptr> >
133 typedef unordered_map<string,
134 vector<type_base_sptr> >::const_iterator
137 typedef unordered_map<string,
138 vector<type_base_sptr> >::iterator
141 typedef unordered_map<string,
142 shared_ptr<function_tdecl> >::const_iterator
143 const_fn_tmpl_map_it;
145 typedef unordered_map<string,
146 shared_ptr<class_tdecl> >::const_iterator
147 const_class_tmpl_map_it;
149 typedef unordered_map<string, xmlNodePtr> string_xml_node_map;
151 typedef unordered_map<xmlNodePtr, decl_base_sptr> xml_node_decl_base_sptr_map;
153 friend vector<type_base_sptr>* get_types_from_type_id(reader&,
156 friend unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
157 get_artifact_used_by_relation_map(reader& rdr);
160 types_map_type m_types_map;
161 unordered_map<string, shared_ptr<function_tdecl> > m_fn_tmpl_map;
162 unordered_map<string, shared_ptr<class_tdecl> > m_class_tmpl_map;
163 vector<type_base_sptr> m_types_to_canonicalize;
164 string_xml_node_map m_id_xml_node_map;
165 xml_node_decl_base_sptr_map m_xml_node_decl_map;
167 xmlNodePtr m_corp_node;
168 deque<shared_ptr<decl_base> > m_decls_stack;
169 bool m_tracking_non_reachable_types;
170 bool m_drop_undefined_syms;
171 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
173 vector<type_or_decl_base*>> m_artifact_used_by_map;
184 m_tracking_non_reachable_types(),
185 m_drop_undefined_syms()
194 {
return options().do_log;}
202 tracking_non_reachable_types()
const
203 {
return m_tracking_non_reachable_types;}
211 tracking_non_reachable_types(
bool f)
212 {m_tracking_non_reachable_types = f;}
220 drop_undefined_syms()
const
221 {
return m_drop_undefined_syms;}
228 drop_undefined_syms(
bool f)
229 {m_drop_undefined_syms = f;}
242 set_path(
const string& s)
258 get_environment()
const
259 {
return const_cast<reader*
>(
this)->get_environment();}
262 get_libxml_reader()
const
271 get_corpus_node()
const
272 {
return m_corp_node;}
280 set_corpus_node(xmlNodePtr node)
281 {m_corp_node = node;}
283 const string_xml_node_map&
284 get_id_xml_node_map()
const
285 {
return m_id_xml_node_map;}
288 get_id_xml_node_map()
289 {
return m_id_xml_node_map;}
292 clear_id_xml_node_map()
293 {get_id_xml_node_map().clear();}
295 const xml_node_decl_base_sptr_map&
296 get_xml_node_decl_map()
const
297 {
return m_xml_node_decl_map;}
299 xml_node_decl_base_sptr_map&
300 get_xml_node_decl_map()
301 {
return m_xml_node_decl_map;}
304 map_xml_node_to_decl(xmlNodePtr node,
308 get_xml_node_decl_map()[node]= decl;
312 get_decl_for_xml_node(xmlNodePtr node)
const
314 xml_node_decl_base_sptr_map::const_iterator i =
315 get_xml_node_decl_map().find(node);
317 if (i != get_xml_node_decl_map().end())
320 return decl_base_sptr();
324 clear_xml_node_decl_map()
325 {get_xml_node_decl_map().clear();}
328 map_id_and_node (
const string&
id,
334 string_xml_node_map::iterator i = get_id_xml_node_map().find(
id);
335 if (i != get_id_xml_node_map().end())
337 bool is_declaration =
false;
338 read_is_declaration_only(node, is_declaration);
343 get_id_xml_node_map()[id] = node;
347 get_xml_node_from_id(
const string&
id)
const
349 string_xml_node_map::const_iterator i = get_id_xml_node_map().find(
id);
350 if (i != get_id_xml_node_map().end())
356 get_scope_for_node(xmlNodePtr node,
360 get_scope_for_node(xmlNodePtr node);
363 get_scope_ptr_for_node(xmlNodePtr node);
368 build_or_get_type_decl(
const string&
id,
383 get_type_decl(
const string&
id)
const
385 const_types_map_it i = m_types_map.find(
id);
386 if (i == m_types_map.end())
387 return type_base_sptr();
388 type_base_sptr result = i->second[0];
404 const vector<type_base_sptr>*
405 get_all_type_decls(
const string&
id)
const
407 const_types_map_it i = m_types_map.find(
id);
408 if (i == m_types_map.end())
425 shared_ptr<function_tdecl>
426 get_fn_tmpl_decl(
const string&
id)
const
428 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
429 if (i == m_fn_tmpl_map.end())
430 return shared_ptr<function_tdecl>();
444 shared_ptr<class_tdecl>
445 get_class_tmpl_decl(
const string&
id)
const
447 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
448 if (i == m_class_tmpl_map.end())
449 return shared_ptr<class_tdecl>();
455 get_cur_scope()
const
457 shared_ptr<decl_base> cur_decl = get_cur_decl();
459 if (dynamic_cast<scope_decl*>(cur_decl.get()))
461 return dynamic_pointer_cast<scope_decl>(cur_decl).
get();
465 return cur_decl->get_scope();
474 if (m_decls_stack.empty())
475 return shared_ptr<decl_base>(static_cast<decl_base*>(0));
476 return m_decls_stack.back();
482 const global_scope* global = 0;
483 for (deque<shared_ptr<decl_base> >::reverse_iterator i =
484 m_decls_stack.rbegin();
485 i != m_decls_stack.rend();
487 if (decl_base_sptr d = *i)
492 return global->get_translation_unit();
503 type_is_from_translation_unit(type_base_sptr type)
515 push_decl(decl_base_sptr d)
517 m_decls_stack.push_back(d);
523 if (m_decls_stack.empty())
524 return decl_base_sptr();
526 shared_ptr<decl_base> t = get_cur_decl();
527 m_decls_stack.pop_back();
554 return dynamic_pointer_cast<scope_decl>(d) == scope;
567 {m_decls_stack.clear();}
571 {m_types_map.clear();}
576 clear_types_to_canonicalize()
577 {m_types_to_canonicalize.clear();}
593 types_equal(type_base_sptr t1, type_base_sptr t2)
595 if (t1.get() == t2.get())
614 key_type_decl(
const type_base_sptr& type,
const string&
id)
619 m_types_map[id].push_back(type);
634 key_fn_tmpl_decl(shared_ptr<function_tdecl> fn_tmpl_decl,
639 const_fn_tmpl_map_it i = m_fn_tmpl_map.find(
id);
640 if (i != m_fn_tmpl_map.end())
643 m_fn_tmpl_map[id] = fn_tmpl_decl;
657 key_class_tmpl_decl(shared_ptr<class_tdecl> class_tmpl_decl,
662 const_class_tmpl_map_it i = m_class_tmpl_map.find(
id);
663 if (i != m_class_tmpl_map.end())
666 m_class_tmpl_map[id] = class_tmpl_decl;
670 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
680 record_artifact_as_used_by(type_or_decl_base* used,
681 type_or_decl_base* user)
683 if (m_artifact_used_by_map.find(used) == m_artifact_used_by_map.end())
685 vector<type_or_decl_base*> v;
686 m_artifact_used_by_map[used] = v;
688 m_artifact_used_by_map[used].push_back(user);
702 {record_artifact_as_used_by(used.get(), user.get());}
708 record_artifacts_as_used_in_fn_decl(
const function_decl *fn)
713 type_base_sptr t = fn->get_return_type();
714 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
716 for (
auto pit : fn->get_parameters())
718 type_base_sptr t = pit->get_type();
719 record_artifact_as_used_by(t.get(),
const_cast<function_decl*
>(fn));
728 {record_artifacts_as_used_in_fn_decl(fn.get());}
734 record_artifacts_as_used_in_fn_type(
const function_type *fn_type)
739 type_base_sptr t = fn_type->get_return_type();
740 record_artifact_as_used_by(t.get(),
const_cast<function_type*
>(fn_type));
742 for (
auto pit : fn_type->get_parameters())
744 type_base_sptr t = pit->get_type();
745 record_artifact_as_used_by(t.get(),
746 const_cast<function_type*
>(fn_type));
755 {record_artifacts_as_used_in_fn_type(fn_type.get());}
767 push_decl_to_scope(
const decl_base_sptr& decl, xmlNodePtr node)
769 scope_decl* scope =
nullptr;
770 scope = get_scope_ptr_for_node(node);
771 return push_decl_to_scope(decl, scope);
780 push_decl_to_scope(
const decl_base_sptr& decl,
786 if (!decl->get_translation_unit())
805 push_and_key_type_decl(
const type_base_sptr& t,
812 push_decl_to_scope(decl, scope);
813 if (!t->get_translation_unit())
816 key_type_decl(t,
id);
831 push_and_key_type_decl(
const type_base_sptr& t,
832 const xmlNodePtr node,
833 bool add_to_current_scope)
836 if (!read_type_id_string(node,
id))
839 scope_decl* scope =
nullptr;
841 scope = get_scope_ptr_for_node(node);
842 return push_and_key_type_decl(t,
id, scope);
850 corpus::exported_decls_builder*
851 get_exported_decls_builder()
852 {
return corpus()->get_exported_decls_builder().get();}
865 corpus_is_suppressed_by_soname_or_filename(
const string& soname,
866 const string& filename)
872 for (suppressions_type::const_iterator s =
suppressions().begin();
886 clear_per_translation_unit_data()
893 clear_per_corpus_data()
896 clear_types_to_canonicalize();
897 clear_xml_node_decl_map();
898 clear_id_xml_node_map();
902 #ifdef WITH_DEBUG_SELF_COMPARISON
922 maybe_check_abixml_canonical_type_stability(type_base_sptr& t)
924 if (!get_environment().self_comparison_debug_is_on()
925 || get_environment().get_type_id_canonical_type_map().empty())
937 get_environment().get_type_id_from_pointer(reinterpret_cast<uintptr_t>(t.get()));
939 if (!type_id.empty())
944 auto j = get_environment().get_type_id_canonical_type_map().find(type_id);
945 if (j == get_environment().get_type_id_canonical_type_map().end())
947 if (t->get_naked_canonical_type())
948 std::cerr <<
"error: no type with type-id: '"
950 <<
"' could be read back from the typeid file\n";
953 != reinterpret_cast<uintptr_t>(t->get_canonical_type().get()))
958 std::cerr <<
"error: canonical type for type '"
959 << t->get_pretty_representation(
true,
961 <<
"' of type-id '" << type_id
962 <<
"' changed from '" << std::hex
963 << j->second <<
"' to '" << std::hex
964 <<
reinterpret_cast<uintptr_t
>(t->get_canonical_type().get())
978 maybe_canonicalize_type(type_base_sptr t,
979 bool force_delay =
false)
984 if (t->get_canonical_type())
1019 #ifdef WITH_DEBUG_SELF_COMPARISON
1020 maybe_check_abixml_canonical_type_stability(t);
1030 schedule_type_for_late_canonicalizing(t);
1039 schedule_type_for_late_canonicalizing(type_base_sptr t)
1040 {m_types_to_canonicalize.push_back(t);}
1046 perform_late_type_canonicalizing()
1048 for (vector<type_base_sptr>::iterator i = m_types_to_canonicalize.begin();
1049 i != m_types_to_canonicalize.end();
1053 #ifdef WITH_DEBUG_SELF_COMPARISON
1054 maybe_check_abixml_canonical_type_stability(*i);
1072 const string& fn_name)
const
1076 return suppression_matches_function_name(*s, fn_name);
1089 corpus_sptr corp =
corpus();
1091 if (!s.priv_->matches_soname(corp->get_soname()))
1092 if (s.has_soname_related_property())
1098 if (!s.priv_->matches_binary_name(corp->get_path()))
1099 if (s.has_file_name_related_property())
1120 suppression_matches_function_name(
const suppr::function_suppression& s,
1121 const string& fn_name)
const
1123 if (!s.get_drops_artifact_from_ir()
1127 return suppr::suppression_matches_function_name(s, fn_name);
1143 const string& type_name,
1144 const location& type_location)
const
1153 virtual ir::corpus_sptr
1164 bool call_reader_next =
false;
1166 xmlNodePtr node = get_corpus_node();
1173 status = advance_cursor (*
this);
1176 BAD_CAST(
"abi-corpus")))
1179 #ifdef WITH_DEBUG_SELF_COMPARISON
1180 if (get_environment().self_comparison_debug_is_on())
1181 get_environment().set_self_comparison_debug_input(
corpus());
1185 clear_per_corpus_data();
1187 ir::corpus& corp = *
corpus();
1189 corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1191 handle_version_attribute(xml_reader, corp);
1198 path =
reinterpret_cast<char*
>(path_str.get());
1200 corp.set_path(path);
1203 xml::xml_char_sptr architecture_str =
1205 if (architecture_str)
1206 corp.set_architecture_name
1207 (reinterpret_cast<char*>(architecture_str.get()));
1209 xml::xml_char_sptr soname_str =
1215 soname =
reinterpret_cast<char*
>(soname_str.get());
1217 corp.set_soname(soname);
1227 if ((!soname.empty() || !path.empty())
1228 && corpus_is_suppressed_by_soname_or_filename(soname, path))
1231 node = xmlTextReaderExpand(xml_reader.get());
1235 call_reader_next =
true;
1239 #ifdef WITH_DEBUG_SELF_COMPARISON
1240 if (get_environment().self_comparison_debug_is_on())
1241 get_environment().set_self_comparison_debug_input(
corpus());
1245 clear_per_corpus_data();
1247 ir::corpus& corp = *
corpus();
1248 corp.set_origin(corpus::NATIVE_XML_ORIGIN);
1252 corp.set_path(reinterpret_cast<char*>(path_str.get()));
1254 xml::xml_char_sptr architecture_str =
1256 if (architecture_str)
1257 corp.set_architecture_name
1258 (reinterpret_cast<char*>(architecture_str.get()));
1260 xml::xml_char_sptr soname_str =
1263 corp.set_soname(reinterpret_cast<char*>(soname_str.get()));
1271 xmlNodePtr n = xmlFirstElementChild(node);
1275 ir::corpus& corp = *
corpus();
1277 walk_xml_node_to_map_type_ids(*
this, node);
1280 vector<string> needed;
1281 read_elf_needed_from_input(*
this, needed);
1282 if (!needed.empty())
1283 corp.set_needed(needed);
1289 string_strings_map_type non_resolved_fn_syms_aliases, non_resolved_var_syms_aliases;
1290 read_symbol_db_from_input(*
this, fn_sym_db, var_sym_db,
1291 non_resolved_fn_syms_aliases,
1292 non_resolved_var_syms_aliases);
1293 resolve_symbol_aliases(fn_sym_db, var_sym_db,
1294 non_resolved_fn_syms_aliases,
1295 non_resolved_var_syms_aliases);
1301 get_environment().canonicalization_is_done(
false);
1304 while (read_translation_unit_from_input(*
this))
1307 if (tracking_non_reachable_types())
1309 bool is_tracking_non_reachable_types =
false;
1310 read_tracking_non_reachable_types(node, is_tracking_non_reachable_types);
1313 (corp.recording_types_reachable_from_public_interface_supported()
1314 == is_tracking_non_reachable_types);
1318 tools_utils::timer t;
1321 std::cerr <<
"perform late type canonicalization ...\n";
1325 perform_late_type_canonicalizing();
1330 std::cerr <<
"late type canonicalization DONE@"
1332 <<
":" << t <<
"\n";
1335 get_environment().canonicalization_is_done(
true);
1337 if (call_reader_next)
1341 xmlTextReaderNext(xml_reader.get());
1349 node = get_corpus_node();
1350 node = xmlNextElementSibling(node);
1353 node = get_corpus_node();
1355 node = xmlNextElementSibling(node->parent);
1357 set_corpus_node(node);
1360 corpus()->sort_functions();
1361 corpus()->sort_variables();
1368 typedef shared_ptr<reader> reader_sptr;
1370 static int advance_cursor(reader&);
1371 static bool read_translation_unit(fe_iface&, translation_unit&, xmlNodePtr);
1374 static bool read_symbol_db_from_input(reader&,
1377 string_strings_map_type&,
1378 string_strings_map_type&);
1379 static bool read_location(
const reader&, xmlNodePtr, location&);
1380 static bool read_artificial_location(
const reader&,
1381 xmlNodePtr, location&);
1382 static bool maybe_set_artificial_location(
const reader&,
1388 static bool read_size_and_alignment(xmlNodePtr,
size_t&,
size_t&);
1389 static bool read_static(xmlNodePtr,
bool&);
1390 static bool read_offset_in_bits(xmlNodePtr,
size_t&);
1391 static bool read_cdtor_const(xmlNodePtr,
bool&,
bool&,
bool&);
1392 static bool read_is_virtual(xmlNodePtr,
bool&);
1393 static bool read_is_struct(xmlNodePtr,
bool&);
1394 static bool read_is_anonymous(xmlNodePtr,
bool&);
1397 static bool read_elf_symbol_visibility(xmlNodePtr,
1401 build_namespace_decl(reader&,
const xmlNodePtr,
bool);
1411 build_elf_symbol(reader&,
const xmlNodePtr,
bool);
1414 build_elf_symbol_from_reference(reader&,
const xmlNodePtr);
1417 build_elf_symbol_db(reader&,
const xmlNodePtr,
bool,
1419 string_strings_map_type&);
1422 build_function_parameter (reader&,
const xmlNodePtr);
1425 build_function_decl(reader&,
const xmlNodePtr,
1426 class_or_union_sptr,
bool,
bool);
1429 build_function_decl_if_not_suppressed(reader&,
const xmlNodePtr,
1430 class_or_union_sptr,
bool,
bool);
1433 function_is_suppressed(
const reader& rdr,
1437 build_var_decl_if_not_suppressed(reader&,
const xmlNodePtr,
bool);
1440 build_var_decl(reader&,
const xmlNodePtr,
bool);
1443 variable_is_suppressed(
const reader& rdr,
1446 static shared_ptr<type_decl>
1447 build_type_decl(reader&,
const xmlNodePtr,
bool);
1449 static qualified_type_def_sptr
1450 build_qualified_type_decl(reader&,
const xmlNodePtr,
bool);
1452 static shared_ptr<pointer_type_def>
1453 build_pointer_type_def(reader&,
const xmlNodePtr,
bool);
1455 static shared_ptr<reference_type_def>
1456 build_reference_type_def(reader&,
const xmlNodePtr,
bool);
1459 build_ptr_to_mbr_type(reader&,
const xmlNodePtr,
bool);
1461 static shared_ptr<function_type>
1462 build_function_type(reader&,
const xmlNodePtr,
bool);
1465 build_subrange_type(reader&,
const xmlNodePtr,
bool);
1468 build_array_type_def(reader&,
const xmlNodePtr,
bool);
1471 build_enum_type_decl(reader&,
const xmlNodePtr,
bool);
1473 static shared_ptr<typedef_decl>
1474 build_typedef_decl(reader&,
const xmlNodePtr,
bool);
1477 build_class_decl(reader&,
const xmlNodePtr,
bool);
1479 static union_decl_sptr
1480 build_union_decl(reader&,
const xmlNodePtr,
bool);
1482 static shared_ptr<function_tdecl>
1483 build_function_tdecl(reader&,
const xmlNodePtr,
bool);
1485 static shared_ptr<class_tdecl>
1486 build_class_tdecl(reader&,
const xmlNodePtr,
bool);
1489 build_type_tparameter(reader&,
const xmlNodePtr,
1493 build_type_composition(reader&,
const xmlNodePtr,
1497 build_non_type_tparameter(reader&,
const xmlNodePtr,
1501 build_template_tparameter(reader&,
const xmlNodePtr,
1505 build_template_parameter(reader&,
const xmlNodePtr,
1512 static shared_ptr<type_base>
1513 build_type(reader&,
const xmlNodePtr,
bool);
1517 static decl_base_sptr handle_type_decl(reader&, xmlNodePtr,
bool);
1518 static decl_base_sptr handle_namespace_decl(reader&, xmlNodePtr,
bool);
1519 static decl_base_sptr handle_qualified_type_decl(reader&,
1521 static decl_base_sptr handle_pointer_type_def(reader&,
1523 static decl_base_sptr handle_reference_type_def(reader&,
1525 static type_base_sptr handle_function_type(reader&,
1527 static decl_base_sptr handle_array_type_def(reader&,
1529 static decl_base_sptr handle_enum_type_decl(reader&, xmlNodePtr,
bool);
1530 static decl_base_sptr handle_typedef_decl(reader&, xmlNodePtr,
bool);
1531 static decl_base_sptr handle_var_decl(reader&, xmlNodePtr,
bool);
1532 static decl_base_sptr handle_function_decl(reader&, xmlNodePtr,
bool);
1533 static decl_base_sptr handle_class_decl(reader&, xmlNodePtr,
bool);
1534 static decl_base_sptr handle_union_decl(reader&, xmlNodePtr,
bool);
1535 static decl_base_sptr handle_function_tdecl(reader&, xmlNodePtr,
bool);
1536 static decl_base_sptr handle_class_tdecl(reader&, xmlNodePtr,
bool);
1538 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
1539 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user) \
1540 rdr.record_artifact_as_used_by(used,user)
1541 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn) \
1542 rdr.record_artifacts_as_used_in_fn_decl(fn)
1543 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)\
1544 rdr.record_artifacts_as_used_in_fn_type(fn_type)
1546 #define RECORD_ARTIFACT_AS_USED_BY(rdr, used, user)
1547 #define RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn)
1548 #define RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type)
1571 xmlNodePtr parent = node->parent;
1574 && (xmlStrEqual(parent->name, BAD_CAST(
"data-member"))
1575 || xmlStrEqual(parent->name, BAD_CAST(
"member-type"))
1576 || xmlStrEqual(parent->name, BAD_CAST(
"member-function"))
1577 || xmlStrEqual(parent->name, BAD_CAST(
"member-template"))
1578 || xmlStrEqual(parent->name, BAD_CAST(
"template-parameter-type-composition"))
1579 || xmlStrEqual(parent->name, BAD_CAST(
"array-type-def"))))
1581 read_access(parent, access);
1582 parent = parent->parent;
1585 xml_node_decl_base_sptr_map::const_iterator i =
1586 get_xml_node_decl_map().find(parent);
1587 if (i == get_xml_node_decl_map().end())
1589 if (xmlStrEqual(parent->name, BAD_CAST(
"abi-instr")))
1592 get_or_read_and_add_translation_unit(*
this, parent);
1593 return tu->get_global_scope();
1598 push_decl(parent_scope);
1599 scope = dynamic_pointer_cast<scope_decl>
1600 (handle_element_node(*
this, parent,
true));
1602 pop_scope_or_abort(parent_scope);
1605 scope = dynamic_pointer_cast<scope_decl>(i->second);
1620 reader::get_scope_for_node(xmlNodePtr node)
1623 return get_scope_for_node(node, access);
1636 reader::get_scope_ptr_for_node(xmlNodePtr node)
1656 type_base_sptr t = get_type_decl(
id);
1660 xmlNodePtr n = get_xml_node_from_id(
id);
1665 if (add_decl_to_scope)
1667 scope = get_scope_for_node(n, access);
1675 if ((t = get_type_decl(
id)))
1681 t = build_type(*
this, n, add_decl_to_scope);
1692 if (add_decl_to_scope)
1693 pop_scope_or_abort(scope);
1695 maybe_canonicalize_type(t, !add_decl_to_scope);
1707 advance_cursor(reader& rdr)
1710 return xmlTextReaderRead(reader.get());
1722 walk_xml_node_to_map_type_ids(reader& rdr,
1725 xmlNodePtr n = node;
1727 if (!n || n->type != XML_ELEMENT_NODE)
1732 string id = CHAR_STR(s);
1733 rdr.map_id_and_node(
id, n);
1736 for (n = xmlFirstElementChild(n); n; n = xmlNextElementSibling(n))
1737 walk_xml_node_to_map_type_ids(rdr, n);
1741 read_translation_unit(fe_iface& iface, translation_unit& tu, xmlNodePtr node)
1743 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1745 if (!rdr.corpus()->is_empty())
1746 tu.set_corpus(rdr.corpus().get());
1748 xml::xml_char_sptr addrsize_str =
1752 char address_size = atoi(reinterpret_cast<char*>(addrsize_str.get()));
1753 tu.set_address_size(address_size);
1758 tu.set_path(reinterpret_cast<char*>(path_str.get()));
1760 xml::xml_char_sptr comp_dir_path_str =
1762 if (comp_dir_path_str)
1763 tu.set_compilation_dir_path(reinterpret_cast<char*>
1764 (comp_dir_path_str.get()));
1769 (reinterpret_cast<char*>(language_str.get())));
1774 rdr.push_decl(tu.get_global_scope());
1775 rdr.map_xml_node_to_decl(node, tu.get_global_scope());
1777 if (rdr.get_id_xml_node_map().empty()
1779 walk_xml_node_to_map_type_ids(rdr, node);
1781 for (xmlNodePtr n = xmlFirstElementChild(node);
1783 n = xmlNextElementSibling(n))
1784 handle_element_node(rdr, n,
true);
1786 rdr.pop_scope_or_abort(tu.get_global_scope());
1792 rdr.clear_per_translation_unit_data();
1811 get_or_read_and_add_translation_unit(reader& rdr, xmlNodePtr node)
1813 corpus_sptr corp = rdr.corpus();
1821 tu_path =
reinterpret_cast<char*
>(path_str.get());
1824 if (corp && !corp->is_empty())
1825 tu = corp->find_translation_unit(tu_path);
1831 tu.reset(
new translation_unit(rdr.get_environment(), tu_path));
1832 if (corp && !corp->is_empty())
1835 if (read_translation_unit(rdr, *tu, node))
1850 read_translation_unit_from_input(fe_iface& iface)
1854 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
1856 xmlNodePtr node = rdr.get_corpus_node();
1867 status = advance_cursor (rdr);
1870 BAD_CAST(
"abi-instr")))
1873 node = xmlTextReaderExpand(reader.get());
1880 for (xmlNodePtr n = rdr.get_corpus_node();
1882 n = xmlNextElementSibling(n))
1884 if (!xmlStrEqual(n->name, BAD_CAST(
"abi-instr")))
1894 tu = get_or_read_and_add_translation_unit(rdr, node);
1896 if (rdr.get_corpus_node())
1902 node = xmlNextElementSibling(node);
1903 rdr.set_corpus_node(node);
1956 read_symbol_db_from_input(reader& rdr,
1959 string_strings_map_type& non_resolved_fn_syms_aliases,
1960 string_strings_map_type& non_resolved_var_syms_aliases)
1966 if (!rdr.get_corpus_node())
1972 status = advance_cursor (rdr);
1977 bool has_fn_syms =
false, has_undefined_fn_syms =
false,
1978 has_var_syms =
false, has_undefined_var_syms =
false;
1980 BAD_CAST(
"elf-function-symbols")))
1983 BAD_CAST(
"elf-variable-symbols")))
1984 has_var_syms =
true;
1986 BAD_CAST(
"undefined-elf-function-symbols")))
1987 has_undefined_fn_syms =
true;
1989 BAD_CAST(
"undefined-elf-variable-symbols")))
1990 has_undefined_var_syms =
true;
1994 xmlNodePtr node = xmlTextReaderExpand(reader.get());
1999 build_elf_symbol_db(rdr, node,
true, fn_symdb,
2000 non_resolved_fn_syms_aliases);
2001 else if (has_undefined_fn_syms)
2002 build_elf_symbol_db(rdr, node,
true, fn_symdb,
2003 non_resolved_fn_syms_aliases);
2004 else if (has_var_syms)
2005 build_elf_symbol_db(rdr, node,
false, var_symdb,
2006 non_resolved_var_syms_aliases);
2007 else if (has_undefined_var_syms)
2008 build_elf_symbol_db(rdr, node,
false, var_symdb,
2009 non_resolved_var_syms_aliases);
2011 xmlTextReaderNext(reader.get());
2014 for (xmlNodePtr n = rdr.get_corpus_node(); n; n = xmlNextElementSibling(n))
2016 bool has_fn_syms =
false, has_undefined_fn_syms =
false,
2017 has_var_syms =
false, has_undefined_var_syms =
false;
2018 if (xmlStrEqual(n->name, BAD_CAST(
"elf-function-symbols")))
2020 else if (xmlStrEqual(n->name, BAD_CAST(
"undefined-elf-function-symbols")))
2021 has_undefined_fn_syms =
true;
2022 else if (xmlStrEqual(n->name, BAD_CAST(
"elf-variable-symbols")))
2023 has_var_syms =
true;
2024 else if (xmlStrEqual(n->name,
2025 BAD_CAST(
"undefined-elf-variable-symbols")))
2026 has_undefined_var_syms =
true;
2029 rdr.set_corpus_node(n);
2034 build_elf_symbol_db(rdr, n,
true, fn_symdb,
2035 non_resolved_fn_syms_aliases);
2036 else if (has_undefined_fn_syms)
2037 build_elf_symbol_db(rdr, n,
true, fn_symdb,
2038 non_resolved_fn_syms_aliases);
2039 else if (has_var_syms)
2040 build_elf_symbol_db(rdr, n,
false, var_symdb,
2041 non_resolved_var_syms_aliases);
2042 else if (has_undefined_var_syms)
2043 build_elf_symbol_db(rdr, n,
false, var_symdb,
2044 non_resolved_var_syms_aliases);
2063 build_needed(xmlNode* node, vector<string>& needed)
2065 if (!node || !xmlStrEqual(node->name,BAD_CAST(
"elf-needed")))
2068 for (xmlNodePtr n = xmlFirstElementChild(node);
2070 n = xmlNextElementSibling(n))
2072 if (!xmlStrEqual(n->name, BAD_CAST(
"dependency")))
2080 needed.push_back(name);
2096 read_elf_needed_from_input(reader& rdr,
2097 vector<string>& needed)
2103 xmlNodePtr node = 0;
2105 if (rdr.get_corpus_node() == 0)
2110 status = advance_cursor (rdr);
2116 BAD_CAST(
"elf-needed")))
2119 node = xmlTextReaderExpand(reader.get());
2125 for (xmlNodePtr n = rdr.get_corpus_node();
2127 n = xmlNextElementSibling(n))
2129 if (!xmlStrEqual(n->name, BAD_CAST(
"elf-needed")))
2136 bool result =
false;
2139 result = build_needed(node, needed);
2140 node = xmlNextElementSibling(node);
2141 rdr.set_corpus_node(node);
2176 for (suppr::suppressions_type::const_iterator i = supprs.begin();
2179 if ((*i)->get_drops_artifact_from_ir())
2180 rdr.suppressions().push_back(*i);
2195 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2196 rdr.tracking_non_reachable_types(flag);
2199 #ifdef WITH_SHOW_TYPE_USE_IN_ABILINT
2208 vector<type_base_sptr>*
2209 get_types_from_type_id(
fe_iface& iface,
const string& type_id)
2211 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2212 auto it = rdr.m_types_map.find(type_id);
2213 if (it == rdr.m_types_map.end())
2224 unordered_map<type_or_decl_base*, vector<type_or_decl_base*>>*
2225 get_artifact_used_by_relation_map(fe_iface& iface)
2227 xml_reader::reader& rdr =
dynamic_cast<xml_reader::reader&
>(iface);
2228 return &rdr.m_artifact_used_by_map;
2248 string version_string;
2253 if (version_string.empty())
2260 corp.set_format_major_version_number(v[0]);
2261 corp.set_format_minor_version_number(v[1]);
2274 corpus_group_sptr nil;
2276 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2285 status = advance_cursor (rdr);
2288 BAD_CAST(
"abi-corpus-group")))
2291 if (!rdr.corpus_group())
2293 corpus_group_sptr g(
new corpus_group(rdr.get_environment(),
2295 g->set_origin(corpus::NATIVE_XML_ORIGIN);
2296 rdr.corpus_group(g);
2299 corpus_group_sptr group = rdr.corpus_group();
2301 handle_version_attribute(reader, *group);
2305 group->set_path(reinterpret_cast<char*>(path_str.get()));
2307 xmlNodePtr node = xmlTextReaderExpand(reader.get());
2311 node = xmlFirstElementChild(node);
2312 rdr.set_corpus_node(node);
2316 while ((corp = rdr.read_corpus(sts)))
2317 rdr.corpus_group()->add_corpus(corp);
2319 xmlTextReaderNext(reader.get());
2321 return rdr.corpus_group();
2383 rdr.perform_late_type_canonicalizing();
2405 rdr.perform_late_type_canonicalizing();
2420 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
2422 rdr.options().env.canonicalization_is_done(
false);
2423 rdr.perform_late_type_canonicalizing();
2424 rdr.options().env.canonicalization_is_done(
true);
2437 handle_element_node(reader& rdr, xmlNodePtr node,
2438 bool add_to_current_scope)
2444 ((decl = handle_namespace_decl(rdr, node, add_to_current_scope))
2445 ||(decl = handle_type_decl(rdr, node, add_to_current_scope))
2446 ||(decl = handle_qualified_type_decl(rdr, node,
2447 add_to_current_scope))
2448 ||(decl = handle_pointer_type_def(rdr, node,
2449 add_to_current_scope))
2450 || (decl = handle_reference_type_def(rdr, node, add_to_current_scope))
2451 || (decl = handle_function_type(rdr, node, add_to_current_scope))
2452 || (decl = handle_array_type_def(rdr, node, add_to_current_scope))
2453 || (decl = handle_enum_type_decl(rdr, node,
2454 add_to_current_scope))
2455 || (decl = handle_typedef_decl(rdr, node,
2456 add_to_current_scope))
2457 || (decl = handle_var_decl(rdr, node,
2458 add_to_current_scope))
2459 || (decl = handle_function_decl(rdr, node,
2460 add_to_current_scope))
2461 || (decl = handle_class_decl(rdr, node,
2462 add_to_current_scope))
2463 || (decl = handle_union_decl(rdr, node,
2464 add_to_current_scope))
2465 || (decl = handle_function_tdecl(rdr, node,
2466 add_to_current_scope))
2467 || (decl = handle_class_tdecl(rdr, node,
2468 add_to_current_scope)));
2473 if (rdr.tracking_non_reachable_types())
2475 if (type_base_sptr t =
is_type(decl))
2477 corpus_sptr abi = rdr.corpus();
2479 bool is_non_reachable_type =
false;
2480 read_is_non_reachable_type(node, is_non_reachable_type);
2481 if (!is_non_reachable_type)
2482 abi->record_type_as_reachable_from_public_interfaces(*t);
2497 read_location(
const reader& rdr,
2502 size_t line = 0, column = 0;
2505 file_path = CHAR_STR(f);
2507 if (file_path.empty())
2508 return read_artificial_location(rdr, node, loc);
2511 line = atoi(CHAR_STR(l));
2513 return read_artificial_location(rdr, node, loc);
2516 column = atoi(CHAR_STR(c));
2518 reader& c =
const_cast<reader&
>(rdr);
2519 loc = c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2536 read_artificial_location(
const reader& rdr,
2544 size_t line = 0, column = 0;
2549 file_path =
reinterpret_cast<const char*
>(node->doc->URL);
2551 reader& c =
const_cast<reader&
>(rdr);
2553 c.get_translation_unit()->get_loc_mgr().create_new_location(file_path,
2555 loc.set_is_artificial(
true);
2575 maybe_set_artificial_location(
const reader& rdr,
2579 if (artefact && !artefact->has_artificial_location())
2582 if (read_artificial_location(rdr, node, l))
2584 artefact->set_artificial_location(l);
2603 string v = CHAR_STR(s);
2606 vis = decl_base::VISIBILITY_DEFAULT;
2607 else if (v ==
"hidden")
2608 vis = decl_base::VISIBILITY_HIDDEN;
2609 else if (v ==
"internal")
2610 vis = decl_base::VISIBILITY_INTERNAL;
2611 else if (v ==
"protected")
2612 vis = decl_base::VISIBILITY_PROTECTED;
2614 vis = decl_base::VISIBILITY_DEFAULT;
2632 string b = CHAR_STR(s);
2635 bind = decl_base::BINDING_GLOBAL;
2636 else if (b ==
"local")
2637 bind = decl_base::BINDING_LOCAL;
2638 else if (b ==
"weak")
2639 bind = decl_base::BINDING_WEAK;
2641 bind = decl_base::BINDING_GLOBAL;
2660 string a = CHAR_STR(s);
2663 access = private_access;
2664 else if (a ==
"protected")
2665 access = protected_access;
2666 else if (a ==
"public")
2667 access = public_access;
2695 read_size_and_alignment(xmlNodePtr node,
2696 size_t& size_in_bits,
2697 size_t& align_in_bits)
2700 bool got_something =
false;
2703 size_in_bits = atoll(CHAR_STR(s));
2704 got_something =
true;
2709 align_in_bits = atoll(CHAR_STR(s));
2710 got_something =
true;
2712 return got_something;
2725 read_static(xmlNodePtr node,
bool& is_static)
2729 string b = CHAR_STR(s);
2730 is_static = b ==
"yes";
2743 read_offset_in_bits(xmlNodePtr node,
2744 size_t& offset_in_bits)
2748 offset_in_bits = strtoull(CHAR_STR(s), 0, 0);
2776 read_cdtor_const(xmlNodePtr node,
2777 bool& is_constructor,
2778 bool& is_destructor,
2783 string b = CHAR_STR(s);
2785 is_constructor =
true;
2787 is_constructor =
false;
2794 string b = CHAR_STR(s);
2796 is_destructor =
true;
2798 is_destructor =
false;
2805 string b = CHAR_STR(s);
2826 read_is_declaration_only(xmlNodePtr node,
bool& is_decl_only)
2830 string str = CHAR_STR(s);
2832 is_decl_only =
true;
2834 is_decl_only =
false;
2850 read_is_artificial(xmlNodePtr node,
bool& is_artificial)
2854 string is_artificial_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2855 is_artificial = is_artificial_str ==
"yes";
2874 read_tracking_non_reachable_types(xmlNodePtr node,
2875 bool& tracking_non_reachable_types)
2880 string tracking_non_reachable_types_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2881 tracking_non_reachable_types =
2882 (tracking_non_reachable_types_str ==
"yes")
2901 read_is_non_reachable_type(xmlNodePtr node,
bool& is_non_reachable_type)
2906 string is_non_reachable_type_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
2907 is_non_reachable_type =
2908 (is_non_reachable_type_str ==
"yes")
2926 read_naming_typedef_id_string(xmlNodePtr node,
string& naming_typedef_id)
2945 read_is_virtual(xmlNodePtr node,
bool& is_virtual)
2949 string str = CHAR_STR(s);
2968 read_is_struct(xmlNodePtr node,
bool& is_struct)
2972 string str = CHAR_STR(s);
2991 read_is_anonymous(xmlNodePtr node,
bool& is_anonymous)
2995 string str = CHAR_STR(s);
2996 is_anonymous = (str ==
"yes");
3073 read_type_id_string(xmlNodePtr node,
string& type_id)
3077 type_id = CHAR_STR(s);
3083 #ifdef WITH_DEBUG_SELF_COMPARISON
3098 maybe_map_type_with_type_id(
const type_base_sptr& t,
3099 const string& type_id)
3104 const environment& env = t->get_environment();
3105 if (!env.self_comparison_debug_is_on()
3109 const_cast<environment&
>(env).
3110 get_pointer_type_id_map()[
reinterpret_cast<uintptr_t
>(t.get())] = type_id;
3129 maybe_map_type_with_type_id(
const type_base_sptr& t,
3135 const environment&env = t->get_environment();
3136 if (!env.self_comparison_debug_is_on()
3141 if (!read_type_id_string(node, type_id) || type_id.empty())
3144 return maybe_map_type_with_type_id(t, type_id);
3158 maybe_set_naming_typedef(reader& rdr,
3160 const decl_base_sptr& decl)
3162 string naming_typedef_id;
3163 read_naming_typedef_id_string(node, naming_typedef_id);
3164 if (!naming_typedef_id.empty())
3167 is_typedef(rdr.build_or_get_type_decl(naming_typedef_id,
true));
3169 decl->set_naming_typedef(naming_typedef);
3189 build_namespace_decl(reader& rdr,
3190 const xmlNodePtr node,
3191 bool add_to_current_scope)
3194 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"namespace-decl")))
3197 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
3209 read_location(rdr, node, loc);
3211 const environment& env = rdr.get_environment();
3213 maybe_set_artificial_location(rdr, node, decl);
3214 rdr.push_decl_to_scope(decl,
3215 add_to_current_scope
3216 ? rdr.get_scope_ptr_for_node(node)
3218 rdr.map_xml_node_to_decl(node, decl);
3220 for (xmlNodePtr n = xmlFirstElementChild(node);
3222 n = xmlNextElementSibling(n))
3223 handle_element_node(rdr, n,
true);
3225 rdr.pop_scope_or_abort(decl);
3242 build_elf_symbol(reader& rdr,
const xmlNodePtr node,
3243 bool drop_if_suppressed)
3248 || node->type != XML_ELEMENT_NODE
3249 || !xmlStrEqual(node->name, BAD_CAST(
"elf-symbol")))
3258 size = strtol(CHAR_STR(s), NULL, 0);
3260 bool is_defined =
true;
3265 if (value ==
"true" || value ==
"yes")
3271 bool is_common =
false;
3276 if (value ==
"true" || value ==
"yes")
3282 string version_string;
3286 bool is_default_version =
false;
3291 if (value ==
"true" || value ==
"yes")
3292 is_default_version =
true;
3296 read_elf_symbol_type(node, type);
3299 read_elf_symbol_binding(node, binding);
3302 read_elf_symbol_visibility(node, visibility);
3304 elf_symbol::version version(version_string, is_default_version);
3307 if (drop_if_suppressed && is_suppressed)
3310 const environment& env = rdr.get_environment();
3312 size, name, type, binding,
3313 is_defined, is_common,
3314 version, visibility);
3316 e->set_is_suppressed(is_suppressed);
3319 e->set_crc(strtoull(CHAR_STR(s), NULL, 0));
3325 e->set_namespace(ns);
3345 build_elf_symbol_from_reference(reader& rdr,
const xmlNodePtr node)
3364 if (rdr.corpus()->get_symtab())
3367 rdr.corpus()->get_symtab()->lookup_symbol(name);
3369 for (
const auto& symbol : symbols)
3370 if (symbol->get_id_string() == sym_id)
3403 build_elf_symbol_db(reader& rdr,
3404 const xmlNodePtr node,
3407 string_strings_map_type& non_resolved_aliases)
3415 && !xmlStrEqual(node->name, BAD_CAST(
"elf-function-symbols"))
3416 && !xmlStrEqual(node->name, BAD_CAST(
"undefined-elf-function-symbols")))
3420 && !xmlStrEqual(node->name, BAD_CAST(
"elf-variable-symbols"))
3421 && !xmlStrEqual(node->name, BAD_CAST(
"undefined-elf-variable-symbols")))
3424 rdr.set_corpus_node(node);
3426 typedef std::unordered_map<xmlNodePtr, elf_symbol_sptr>
3427 xml_node_ptr_elf_symbol_sptr_map_type;
3428 xml_node_ptr_elf_symbol_sptr_map_type xml_node_ptr_elf_symbol_map;
3431 for (xmlNodePtr n = xmlFirstElementChild(node);
3433 n = xmlNextElementSibling(n))
3434 if ((sym = build_elf_symbol(rdr, n,
false)))
3436 id_sym_map[sym->get_id_string()] = sym;
3437 xml_node_ptr_elf_symbol_map[n] = sym;
3440 if (id_sym_map.empty())
3443 string_elf_symbols_map_type::iterator it;
3444 for (string_elf_symbol_sptr_map_type::const_iterator i = id_sym_map.begin();
3445 i != id_sym_map.end();
3447 (*map)[i->second->get_name()].push_back(i->second);
3450 for (xml_node_ptr_elf_symbol_sptr_map_type::const_iterator x =
3451 xml_node_ptr_elf_symbol_map.begin();
3452 x != xml_node_ptr_elf_symbol_map.end();
3457 string alias_id = CHAR_STR(s);
3460 std::vector<std::string> elems;
3461 std::stringstream aliases(alias_id);
3463 while (std::getline(aliases, item,
','))
3464 elems.push_back(item);
3465 for (std::vector<string>::iterator alias = elems.begin();
3466 alias != elems.end(); ++alias)
3468 string_elf_symbol_sptr_map_type::const_iterator i =
3469 id_sym_map.find(*alias);
3470 if (i == id_sym_map.end())
3476 non_resolved_aliases[x->second->get_name()].push_back(*alias);
3480 x->second->get_main_symbol()->add_alias(i->second);
3515 string_strings_map_type& non_resolved_fn_sym_aliases,
3516 string_strings_map_type& non_resolved_var_sym_aliases)
3518 for (
auto& entry : non_resolved_fn_sym_aliases)
3520 auto i = fn_syms->find(entry.first);
3525 sym = sym->get_main_symbol();
3527 for (
string& alias : entry.second)
3529 auto fn_a = fn_syms->find(alias);
3530 if (fn_a == fn_syms->end())
3534 auto var_a = var_syms->find(alias);
3536 alias_sym = var_a->second.front();
3541 alias_sym = fn_a->second.front();
3544 sym->add_alias(alias_sym);
3548 for (
auto& entry : non_resolved_var_sym_aliases)
3550 auto i = var_syms->find(entry.first);
3555 sym = sym->get_main_symbol();
3557 for (
string& alias : entry.second)
3559 auto var_a = var_syms->find(alias);
3560 if (var_a == var_syms->end())
3564 auto fn_a = fn_syms->find(alias);
3566 alias_sym = fn_a->second.front();
3571 alias_sym = var_a->second.front();
3574 sym->add_alias(alias_sym);
3584 static shared_ptr<function_decl::parameter>
3585 build_function_parameter(reader& rdr,
const xmlNodePtr node)
3587 shared_ptr<function_decl::parameter> nil;
3589 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"parameter")))
3592 bool is_variadic =
false;
3593 string is_variadic_str;
3597 is_variadic_str = CHAR_STR(s) ? CHAR_STR(s) :
"";
3598 is_variadic = is_variadic_str ==
"yes";
3601 bool is_artificial =
false;
3602 read_is_artificial(node, is_artificial);
3606 type_id = CHAR_STR(a);
3608 type_base_sptr type;
3610 type = rdr.get_environment().get_variadic_parameter_type();
3614 type = rdr.build_or_get_type_decl(type_id,
true);
3623 read_location(rdr, node, loc);
3626 (
new function_decl::parameter(type, name, loc,
3627 is_variadic, is_artificial));
3655 build_function_decl(reader& rdr,
3656 const xmlNodePtr node,
3657 class_or_union_sptr as_method_decl,
3658 bool add_to_current_scope,
3659 bool add_to_exported_decls)
3663 if (!xmlStrEqual(node->name, BAD_CAST(
"function-decl")))
3670 string mangled_name;
3675 && !mangled_name.empty()
3676 && as_method_decl->find_member_function_sptr(mangled_name))
3679 as_method_decl->find_member_function_sptr(mangled_name);
3686 inline_prop = CHAR_STR(s);
3687 bool declared_inline = inline_prop ==
"yes";
3690 read_visibility(node, vis);
3693 read_binding(node, bind);
3695 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
3696 read_size_and_alignment(node, size, align);
3699 read_location(rdr, node, loc);
3701 const environment& env = rdr.get_environment();
3703 std::vector<function_decl::parameter_sptr> parms;
3704 type_base_sptr return_type = env.get_void_type();
3706 for (xmlNodePtr n = xmlFirstElementChild(node);
3708 n = xmlNextElementSibling(n))
3710 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
3713 build_function_parameter(rdr, n))
3716 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
3721 type_id = CHAR_STR(s);
3722 if (!type_id.empty())
3723 return_type = rdr.build_or_get_type_decl(type_id,
true);
3728 ?
new method_type(return_type, as_method_decl,
3731 :
new function_type(return_type,
3732 parms, size, align));
3736 fn_type->set_is_artificial(
true);
3739 ?
new method_decl (name, fn_type,
3740 declared_inline, loc,
3741 mangled_name, vis, bind)
3742 :
new function_decl(name, fn_type,
3743 declared_inline, loc,
3747 maybe_set_artificial_location(rdr, node, fn_decl);
3748 rdr.push_decl_to_scope(fn_decl,
3749 add_to_current_scope
3750 ? rdr.get_scope_ptr_for_node(node)
3752 RECORD_ARTIFACTS_AS_USED_IN_FN_DECL(rdr, fn_decl);
3756 fn_decl->set_symbol(sym);
3758 if (fn_decl->get_symbol() && fn_decl->get_symbol()->is_public())
3759 fn_decl->set_is_in_public_symbol_table(
true);
3761 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
3763 rdr.maybe_canonicalize_type(fn_type, !add_to_current_scope);
3765 if (add_to_exported_decls)
3766 rdr.add_fn_to_exported_or_undefined_decls(fn_decl.get());
3797 build_function_decl_if_not_suppressed(reader& rdr,
3798 const xmlNodePtr node,
3799 class_or_union_sptr as_method_decl,
3800 bool add_to_current_scope,
3801 bool add_to_exported_decls)
3805 if (function_is_suppressed(rdr, node))
3811 fn = build_function_decl(rdr, node, as_method_decl,
3812 add_to_current_scope,
3813 add_to_exported_decls);
3829 function_is_suppressed(
const reader& rdr, xmlNodePtr node)
3835 string flinkage_name;
3839 scope_decl* scope = rdr.get_cur_scope();
3858 type_is_suppressed(
const reader& rdr, xmlNodePtr node)
3864 location type_location;
3865 read_location(rdr, node, type_location);
3867 scope_decl* scope = rdr.get_cur_scope();
3871 bool type_is_private =
false;
3890 build_var_decl_if_not_suppressed(reader& rdr,
3891 const xmlNodePtr node,
3892 bool add_to_current_scope)
3895 if (!variable_is_suppressed(rdr, node))
3896 var = build_var_decl(rdr, node, add_to_current_scope);
3909 variable_is_suppressed(
const reader& rdr, xmlNodePtr node)
3915 string linkage_name;
3919 scope_decl* scope = rdr.get_cur_scope();
3937 variable_is_suppressed(
const reader& rdr,
3938 const scope_decl* scope,
3943 v.get_linkage_name());
3954 static shared_ptr<var_decl>
3955 build_var_decl(reader& rdr,
3956 const xmlNodePtr node,
3957 bool add_to_current_scope)
3959 shared_ptr<var_decl> nil;
3961 if (!xmlStrEqual(node->name, BAD_CAST(
"var-decl")))
3970 type_id = CHAR_STR(s);
3971 type_base_sptr underlying_type = rdr.build_or_get_type_decl(type_id,
3975 string mangled_name;
3980 read_visibility(node, vis);
3983 read_binding(node, bind);
3986 read_location(rdr, node, locus);
3989 locus, mangled_name,
3991 maybe_set_artificial_location(rdr, node, decl);
3995 decl->set_symbol(sym);
3997 rdr.push_decl_to_scope(decl,
3998 add_to_current_scope
3999 ? rdr.get_scope_ptr_for_node(node)
4001 if (add_to_current_scope)
4005 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4008 if (decl->get_symbol() && decl->get_symbol()->is_public())
4009 decl->set_is_in_public_symbol_table(
true);
4019 static decl_base_sptr
4020 build_ir_node_for_void_type(reader& rdr)
4022 const environment& env = rdr.get_environment();
4024 type_base_sptr t = env.get_void_type();
4028 return type_declaration;
4042 static decl_base_sptr
4043 build_ir_node_for_void_pointer_type(reader& rdr)
4045 const environment& env = rdr.get_environment();
4047 type_base_sptr t = env.get_void_pointer_type();
4051 return type_declaration;
4066 build_type_decl(reader& rdr,
4067 const xmlNodePtr node,
4068 bool add_to_current_scope)
4070 shared_ptr<type_decl> nil;
4072 if (!xmlStrEqual(node->name, BAD_CAST(
"type-decl")))
4075 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4091 size_t size_in_bits= 0;
4093 size_in_bits = atoi(CHAR_STR(s));
4095 size_t alignment_in_bits = 0;
4097 alignment_in_bits = atoi(CHAR_STR(s));
4099 bool is_decl_only =
false;
4100 read_is_declaration_only(node, is_decl_only);
4103 read_location(rdr, node, loc);
4105 bool is_anonymous =
false;
4106 read_is_anonymous(node, is_anonymous);
4108 if (type_base_sptr d = rdr.get_type_decl(
id))
4116 ABG_ASSERT(ty->get_size_in_bits() == size_in_bits);
4117 ABG_ASSERT(ty->get_alignment_in_bits() == alignment_in_bits);
4121 const environment& env = rdr.get_environment();
4123 if (name == env.get_variadic_parameter_type_name())
4124 decl =
is_type_decl(env.get_variadic_parameter_type());
4125 else if (name ==
"void")
4128 decl.reset(
new type_decl(env, name, size_in_bits,
4129 alignment_in_bits, loc));
4130 maybe_set_artificial_location(rdr, node, decl);
4131 decl->set_is_anonymous(is_anonymous);
4132 decl->set_is_declaration_only(is_decl_only);
4133 if (rdr.push_and_key_type_decl(decl, node, add_to_current_scope))
4135 rdr.map_xml_node_to_decl(node, decl);
4153 static qualified_type_def_sptr
4154 build_qualified_type_decl(reader& rdr,
4155 const xmlNodePtr node,
4156 bool add_to_current_scope)
4158 qualified_type_def_sptr nil;
4159 if (!xmlStrEqual(node->name, BAD_CAST(
"qualified-type-def")))
4162 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4164 qualified_type_def_sptr result =
4165 dynamic_pointer_cast<qualified_type_def>(d);
4177 read_location(rdr, node, loc);
4182 const_str = CHAR_STR(s);
4183 bool const_cv = const_str ==
"yes";
4185 string volatile_str;
4187 volatile_str = CHAR_STR(s);
4188 bool volatile_cv = volatile_str ==
"yes";
4190 string restrict_str;
4192 restrict_str = CHAR_STR(s);
4193 bool restrict_cv = restrict_str ==
"yes";
4196 cv = cv | qualified_type_def::CV_CONST;
4198 cv = cv | qualified_type_def::CV_VOLATILE;
4200 cv = cv | qualified_type_def::CV_RESTRICT;
4204 type_id = CHAR_STR(s);
4207 shared_ptr<type_base> underlying_type =
4208 rdr.build_or_get_type_decl(type_id,
true);
4211 qualified_type_def_sptr decl;
4212 if (type_base_sptr t = rdr.get_type_decl(
id))
4219 decl.reset(
new qualified_type_def(underlying_type, cv, loc));
4220 maybe_set_artificial_location(rdr, node, decl);
4221 rdr.push_and_key_type_decl(decl, node, add_to_current_scope);
4222 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, decl);
4225 rdr.map_xml_node_to_decl(node, decl);
4242 build_pointer_type_def(reader& rdr,
4243 const xmlNodePtr node,
4244 bool add_to_current_scope)
4247 shared_ptr<pointer_type_def> nil;
4249 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-type-def")))
4252 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4255 dynamic_pointer_cast<pointer_type_def>(d);
4265 if (type_base_sptr t = rdr.get_type_decl(
id))
4274 type_id = CHAR_STR(s);
4276 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4277 size_t alignment_in_bits = 0;
4278 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4280 read_location(rdr, node, loc);
4282 type_base_sptr pointed_to_type =
4283 rdr.build_or_get_type_decl(type_id,
true);
4287 if (rdr.get_environment().is_void_type(pointed_to_type))
4295 t.reset(
new pointer_type_def(pointed_to_type,
4300 maybe_set_artificial_location(rdr, node, t);
4302 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4303 rdr.map_xml_node_to_decl(node, t);
4305 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4321 static shared_ptr<reference_type_def>
4322 build_reference_type_def(reader& rdr,
4323 const xmlNodePtr node,
4324 bool add_to_current_scope)
4326 shared_ptr<reference_type_def> nil;
4328 if (!xmlStrEqual(node->name, BAD_CAST(
"reference-type-def")))
4331 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4334 dynamic_pointer_cast<reference_type_def>(d);
4344 if (type_base_sptr d = rdr.get_type_decl(
id))
4352 read_location(rdr, node, loc);
4356 bool is_lvalue = kind ==
"lvalue";
4358 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4359 size_t alignment_in_bits = 0;
4360 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4364 type_id = CHAR_STR(s);
4374 is_lvalue, size_in_bits,
4375 alignment_in_bits, loc));
4376 maybe_set_artificial_location(rdr, node, t);
4377 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4378 rdr.map_xml_node_to_decl(node, t);
4380 type_base_sptr pointed_to_type =
4381 rdr.build_or_get_type_decl(type_id,
true);
4383 t->set_pointed_to_type(pointed_to_type);
4384 RECORD_ARTIFACT_AS_USED_BY(rdr, pointed_to_type, t);
4402 build_ptr_to_mbr_type(reader& rdr,
4403 const xmlNodePtr node,
4404 bool add_to_current_scope)
4408 if (!xmlStrEqual(node->name, BAD_CAST(
"pointer-to-member-type")))
4411 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4425 if (type_base_sptr d = rdr.get_type_decl(
id))
4432 size_t size_in_bits = rdr.get_translation_unit()->get_address_size();
4433 size_t alignment_in_bits = 0;
4434 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
4437 read_location(rdr, node, loc);
4439 string member_type_id;
4441 member_type_id = CHAR_STR(s);
4442 if (member_type_id.empty())
4444 type_base_sptr member_type =
4445 is_type(rdr.build_or_get_type_decl(member_type_id,
true));
4449 string containing_type_id;
4451 containing_type_id = CHAR_STR(s);
4452 if (containing_type_id.empty())
4454 type_base_sptr containing_type =
4455 rdr.build_or_get_type_decl(containing_type_id,
true);
4459 result.reset(
new ptr_to_mbr_type(rdr.get_environment(),
4460 member_type, containing_type,
4461 size_in_bits, alignment_in_bits,
4464 if (rdr.push_and_key_type_decl(result, node, add_to_current_scope))
4465 rdr.map_xml_node_to_decl(node, result);
4483 build_function_type(reader& rdr,
4484 const xmlNodePtr node,
4489 if (!xmlStrEqual(node->name, BAD_CAST(
"function-type")))
4497 string method_class_id;
4499 method_class_id = CHAR_STR(s);
4501 bool is_method_t = !method_class_id.empty();
4503 size_t size = rdr.get_translation_unit()->get_address_size(), align = 0;
4504 read_size_and_alignment(node, size, align);
4506 const environment& env = rdr.get_environment();
4507 std::vector<shared_ptr<function_decl::parameter> > parms;
4508 type_base_sptr return_type = env.get_void_type();
4510 class_or_union_sptr method_class_type;
4520 ?
new method_type(method_class_type,
4523 :
new function_type(return_type,
4524 parms, size, align));
4526 rdr.get_translation_unit()->bind_function_type_life_time(fn_type);
4527 rdr.key_type_decl(fn_type,
id);
4528 RECORD_ARTIFACTS_AS_USED_IN_FN_TYPE(rdr, fn_type);
4530 for (xmlNodePtr n = xmlFirstElementChild(node);
4532 n = xmlNextElementSibling(n))
4534 if (xmlStrEqual(n->name, BAD_CAST(
"parameter")))
4537 build_function_parameter(rdr, n))
4540 else if (xmlStrEqual(n->name, BAD_CAST(
"return")))
4545 type_id = CHAR_STR(s);
4546 if (!type_id.empty())
4547 fn_type->set_return_type(rdr.build_or_get_type_decl
4552 fn_type->set_parameters(parms);
4568 build_subrange_type(reader& rdr,
4569 const xmlNodePtr node,
4570 bool add_to_current_scope)
4574 if (!node || !xmlStrEqual(node->name, BAD_CAST(
"subrange")))
4577 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4580 dynamic_pointer_cast<array_type_def::subrange_type>(d);
4594 if (type_base_sptr d = rdr.get_type_decl(
id))
4605 uint64_t length = 0;
4607 bool is_non_finite =
false;
4610 if (
string(CHAR_STR(s)) ==
"infinite" ||
string(CHAR_STR(s)) ==
"unknown")
4611 is_non_finite =
true;
4613 length = strtoull(CHAR_STR(s), NULL, 0);
4616 int64_t lower_bound = 0, upper_bound = 0;
4617 bool bounds_present =
false;
4620 lower_bound = strtoll(CHAR_STR(s), NULL, 0);
4622 if (!
string(CHAR_STR(s)).empty())
4623 upper_bound = strtoll(CHAR_STR(s), NULL, 0);
4624 bounds_present =
true;
4626 || (length == (uint64_t) upper_bound - lower_bound + 1));
4629 string underlying_type_id;
4631 underlying_type_id = CHAR_STR(s);
4633 type_base_sptr underlying_type;
4634 if (!underlying_type_id.empty())
4636 underlying_type = rdr.build_or_get_type_decl(underlying_type_id,
true);
4641 read_location(rdr, node, loc);
4646 array_type_def::subrange_type::bound_value max_bound;
4647 array_type_def::subrange_type::bound_value min_bound;
4653 max_bound.set_signed(length - 1);
4659 min_bound.set_signed(lower_bound);
4660 max_bound.set_signed(upper_bound);
4664 (
new array_type_def::subrange_type(rdr.get_environment(),
4665 name, min_bound, max_bound,
4666 underlying_type, loc));
4667 maybe_set_artificial_location(rdr, node, p);
4668 p->is_non_finite(is_non_finite);
4670 if (rdr.push_and_key_type_decl(p, node, add_to_current_scope))
4671 rdr.map_xml_node_to_decl(node, p);
4688 build_array_type_def(reader& rdr,
4689 const xmlNodePtr node,
4690 bool add_to_current_scope)
4695 if (!xmlStrEqual(node->name, BAD_CAST(
"array-type-def")))
4698 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4701 dynamic_pointer_cast<array_type_def>(d);
4711 if (type_base_sptr d = rdr.get_type_decl(
id))
4720 dimensions = atoi(CHAR_STR(s));
4724 type_id = CHAR_STR(s);
4728 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4731 dynamic_pointer_cast<array_type_def>(d);
4736 size_t size_in_bits = 0, alignment_in_bits = 0;
4737 bool has_size_in_bits =
false;
4742 size_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4743 if (*endptr !=
'\0')
4745 if (!strcmp(CHAR_STR(s),
"infinite")
4746 ||!strcmp(CHAR_STR(s),
"unknown"))
4747 size_in_bits = (size_t) -1;
4751 has_size_in_bits =
true;
4756 alignment_in_bits = strtoull(CHAR_STR(s), &endptr, 0);
4757 if (*endptr !=
'\0')
4762 read_location(rdr, node, loc);
4765 for (xmlNodePtr n = xmlFirstElementChild(node);
4767 n = xmlNextElementSibling(n))
4768 if (xmlStrEqual(n->name, BAD_CAST(
"subrange")))
4771 build_subrange_type(rdr, n,
true))
4773 MAYBE_MAP_TYPE_WITH_TYPE_ID(s, n);
4774 if (add_to_current_scope)
4777 rdr.maybe_canonicalize_type(s);
4779 subranges.push_back(s);
4784 type_base_sptr type =
4785 rdr.build_or_get_type_decl(type_id,
true);
4789 maybe_set_artificial_location(rdr, node, ar_type);
4790 if (rdr.push_and_key_type_decl(ar_type, node, add_to_current_scope))
4791 rdr.map_xml_node_to_decl(node, ar_type);
4792 RECORD_ARTIFACT_AS_USED_BY(rdr, type, ar_type);
4794 if (dimensions != ar_type->get_dimension_count()
4795 || (alignment_in_bits
4796 != ar_type->get_element_type()->get_alignment_in_bits()))
4799 if (has_size_in_bits && size_in_bits != (
size_t) -1
4800 && size_in_bits != ar_type->get_size_in_bits())
4803 size_t element_size = ar_type->get_element_type()->get_size_in_bits();
4804 if (element_size && element_size != (
size_t)-1)
4807 size_t bad_count = 0;
4808 for (vector<array_type_def::subrange_sptr>::const_iterator i =
4810 i != subranges.end();
4812 bad_count += (*i)->get_length();
4813 if (size_in_bits == bad_count * element_size)
4815 static bool reported =
false;
4818 std::cerr <<
"notice: Found incorrectly calculated array "
4819 <<
"sizes in XML - this is benign.\nOlder versions "
4820 <<
"of libabigail miscalculated multidimensional "
4821 <<
"array sizes." << std::endl;
4827 std::cerr <<
"error: Found incorrectly calculated array size in "
4828 <<
"XML (id=\"" <<
id <<
"\")." << std::endl;
4852 build_enum_type_decl_if_not_suppressed(reader& rdr,
4853 const xmlNodePtr node,
4854 bool add_to_current_scope)
4857 if (!type_is_suppressed(rdr, node))
4858 enum_type = build_enum_type_decl(rdr, node, add_to_current_scope);
4874 build_enum_type_decl(reader& rdr,
4875 const xmlNodePtr node,
4876 bool add_to_current_scope)
4880 if (!xmlStrEqual(node->name, BAD_CAST(
"enum-decl")))
4883 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
4886 dynamic_pointer_cast<enum_type_decl>(d);
4895 string linkage_name;
4900 read_location(rdr, node, loc);
4902 bool is_decl_only =
false;
4903 read_is_declaration_only(node, is_decl_only);
4905 bool is_anonymous =
false;
4906 read_is_anonymous(node, is_anonymous);
4908 bool is_artificial =
false;
4909 read_is_artificial(node, is_artificial);
4917 string base_type_id;
4919 for (xmlNodePtr n = xmlFirstElementChild(node);
4921 n = xmlNextElementSibling(n))
4923 if (xmlStrEqual(n->name, BAD_CAST(
"underlying-type")))
4927 base_type_id = CHAR_STR(a);
4930 else if (xmlStrEqual(n->name, BAD_CAST(
"enumerator")))
4942 value = strtoll(CHAR_STR(a), NULL, 0);
4946 if ((errno == ERANGE)
4947 && (value == LLONG_MIN || value == LLONG_MAX))
4951 enums.push_back(enum_type_decl::enumerator(name, value));
4955 type_base_sptr underlying_type =
4956 rdr.build_or_get_type_decl(base_type_id,
true);
4961 enums, linkage_name));
4962 maybe_set_artificial_location(rdr, node, t);
4963 t->set_is_anonymous(is_anonymous);
4964 t->set_is_artificial(is_artificial);
4965 t->set_is_declaration_only(is_decl_only);
4966 if (rdr.push_and_key_type_decl(t, node, add_to_current_scope))
4968 maybe_set_naming_typedef(rdr, node, t);
4969 rdr.map_xml_node_to_decl(node, t);
4970 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
4985 static shared_ptr<typedef_decl>
4986 build_typedef_decl(reader& rdr,
4987 const xmlNodePtr node,
4988 bool add_to_current_scope)
4990 shared_ptr<typedef_decl> nil;
4992 if (!xmlStrEqual(node->name, BAD_CAST(
"typedef-decl")))
4995 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5012 read_location(rdr, node, loc);
5016 type_id = CHAR_STR(s);
5019 type_base_sptr underlying_type(rdr.build_or_get_type_decl(type_id,
true));
5023 maybe_set_artificial_location(rdr, node, t);
5024 rdr.push_and_key_type_decl(t, node, add_to_current_scope);
5025 rdr.map_xml_node_to_decl(node, t);
5026 RECORD_ARTIFACT_AS_USED_BY(rdr, underlying_type, t);
5043 build_class_decl_if_not_suppressed(reader& rdr,
5044 const xmlNodePtr node,
5045 bool add_to_current_scope)
5048 if (!type_is_suppressed(rdr, node))
5049 class_type = build_class_decl(rdr, node, add_to_current_scope);
5065 static union_decl_sptr
5066 build_union_decl_if_not_suppressed(reader& rdr,
5067 const xmlNodePtr node,
5068 bool add_to_current_scope)
5070 union_decl_sptr union_type;
5071 if (!type_is_suppressed(rdr, node))
5072 union_type = build_union_decl(rdr, node, add_to_current_scope);
5089 build_class_decl(reader& rdr,
5090 const xmlNodePtr node,
5091 bool add_to_current_scope)
5095 if (!xmlStrEqual(node->name, BAD_CAST(
"class-decl")))
5098 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5109 size_t size_in_bits = 0, alignment_in_bits = 0;
5110 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5113 read_visibility(node, vis);
5115 bool is_artificial =
false;
5116 read_is_artificial(node, is_artificial);
5123 read_location(rdr, node, loc);
5132 bool is_decl_only =
false;
5133 read_is_declaration_only(node, is_decl_only);
5135 bool is_struct =
false;
5136 read_is_struct(node, is_struct);
5138 bool is_anonymous =
false;
5139 read_is_anonymous(node, is_anonymous);
5145 if (type_base_sptr t = rdr.get_type_decl(
id))
5151 const vector<type_base_sptr> *types_ptr = 0;
5152 if (!is_anonymous && !previous_definition)
5153 types_ptr = rdr.get_all_type_decls(
id);
5159 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5160 i != types_ptr->end();
5165 if (klass->get_is_declaration_only()
5166 && !klass->get_definition_of_declaration())
5167 previous_declaration = klass;
5168 else if (!klass->get_is_declaration_only()
5169 && !previous_definition)
5170 previous_definition = klass;
5171 if (previous_definition && previous_declaration)
5175 if (previous_declaration)
5176 ABG_ASSERT(previous_declaration->get_name() == name);
5178 if (previous_definition)
5179 ABG_ASSERT(previous_definition->get_name() == name);
5181 if (is_decl_only && previous_declaration)
5182 return previous_declaration;
5185 const environment& env = rdr.get_environment();
5187 if (!is_decl_only && previous_definition)
5193 decl = previous_definition;
5198 decl.reset(
new class_decl(env, name, is_struct));
5200 decl->set_size_in_bits(size_in_bits);
5202 decl->set_is_anonymous(is_anonymous);
5203 decl->set_location(loc);
5206 decl.reset(
new class_decl(env, name, size_in_bits, alignment_in_bits,
5207 is_struct, loc, vis, bases, mbrs,
5208 data_mbrs, mbr_functions, is_anonymous));
5211 maybe_set_artificial_location(rdr, node, decl);
5212 decl->set_is_artificial(is_artificial);
5215 bool is_def_of_decl =
false;
5217 def_id = CHAR_STR(s);
5219 if (!def_id.empty())
5221 decl_base_sptr d =
is_decl(rdr.get_type_decl(def_id));
5222 if (d && d->get_is_declaration_only())
5224 is_def_of_decl =
true;
5226 d->set_definition_of_declaration(decl);
5232 && !decl->get_is_declaration_only()
5233 && previous_declaration)
5239 decl->set_earlier_declaration(
is_decl(previous_declaration));
5240 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5241 i != types_ptr->end();
5246 if (d->get_is_declaration_only()
5247 && !d->get_definition_of_declaration())
5249 previous_declaration->set_definition_of_declaration(decl);
5250 is_def_of_decl =
true;
5255 if (is_decl_only && previous_definition)
5260 && !decl->get_definition_of_declaration());
5261 decl->set_definition_of_declaration(previous_definition);
5264 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5266 rdr.push_decl_to_scope(decl,
5267 add_to_current_scope
5268 ? rdr.get_scope_ptr_for_node(node)
5271 rdr.map_xml_node_to_decl(node, decl);
5272 rdr.key_type_decl(decl,
id);
5275 maybe_set_naming_typedef(rdr, node, decl);
5277 for (xmlNodePtr n = xmlFirstElementChild(node);
5279 n = xmlNextElementSibling(n))
5281 if (xmlStrEqual(n->name, BAD_CAST(
"base-class")))
5287 read_access(n, access);
5291 type_id = CHAR_STR(s);
5292 shared_ptr<class_decl> b =
5293 dynamic_pointer_cast<class_decl>
5294 (rdr.build_or_get_type_decl(type_id,
true));
5297 if (decl->find_base_class(b->get_qualified_name()))
5303 size_t offset_in_bits = 0;
5304 bool offset_present = read_offset_in_bits (n, offset_in_bits);
5306 bool is_virtual =
false;
5307 read_is_virtual (n, is_virtual);
5309 shared_ptr<class_decl::base_spec> base (
new class_decl::base_spec
5312 ? (
long) offset_in_bits
5315 decl->add_base_specifier(base);
5317 else if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5323 read_access(n, access);
5325 rdr.map_xml_node_to_decl(n, decl);
5327 for (xmlNodePtr p = xmlFirstElementChild(n);
5329 p = xmlNextElementSibling(p))
5331 if (type_base_sptr t =
5332 build_type(rdr, p,
true))
5337 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5339 string id = CHAR_STR(i);
5341 rdr.key_type_decl(t,
id);
5342 rdr.map_xml_node_to_decl(p, td);
5346 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5348 rdr.map_xml_node_to_decl(n, decl);
5354 read_access(n, access);
5356 bool is_laid_out =
false;
5357 size_t offset_in_bits = 0;
5358 if (read_offset_in_bits(n, offset_in_bits))
5361 bool is_static =
false;
5362 read_static(n, is_static);
5364 for (xmlNodePtr p = xmlFirstElementChild(n);
5366 p = xmlNextElementSibling(p))
5369 build_var_decl(rdr, p,
false))
5371 if (decl->find_data_member(v))
5379 decl_base_sptr d = rdr.pop_decl();
5384 if (!variable_is_suppressed(rdr, decl.get(), *v))
5386 decl->add_data_member(v, access,
5391 rdr.add_var_to_exported_or_undefined_decls(v.get());
5401 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5404 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5405 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5411 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5417 read_access(n, access);
5419 bool is_virtual =
false;
5420 ssize_t vtable_offset = -1;
5425 vtable_offset = atoi(CHAR_STR(s));
5428 bool is_static =
false;
5429 read_static(n, is_static);
5431 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5432 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5434 for (xmlNodePtr p = xmlFirstElementChild(n);
5436 p = xmlNextElementSibling(p))
5439 build_function_decl_if_not_suppressed(rdr, p, decl,
5447 if (vtable_offset != -1)
5453 rdr.map_xml_node_to_decl(p, m);
5454 rdr.add_fn_to_exported_or_undefined_decls(f.get());
5459 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5461 rdr.map_xml_node_to_decl(n, decl);
5467 read_access(n, access);
5469 bool is_static =
false;
5470 read_static(n, is_static);
5472 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5473 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5475 for (xmlNodePtr p = xmlFirstElementChild(n);
5477 p = xmlNextElementSibling(p))
5479 if (shared_ptr<function_tdecl> f =
5480 build_function_tdecl(rdr, p,
5483 shared_ptr<member_function_template> m
5484 (
new member_function_template(f, access, is_static,
5485 is_ctor, is_const));
5487 decl->add_member_function_template(m);
5489 else if (shared_ptr<class_tdecl> c =
5490 build_class_tdecl(rdr, p,
5493 member_class_template_sptr m(
new member_class_template(c,
5497 decl->add_member_class_template(m);
5503 rdr.pop_scope_or_abort(decl);
5520 static union_decl_sptr
5521 build_union_decl(reader& rdr,
5522 const xmlNodePtr node,
5523 bool add_to_current_scope)
5525 union_decl_sptr nil;
5527 if (!xmlStrEqual(node->name, BAD_CAST(
"union-decl")))
5530 if (decl_base_sptr d = rdr.get_decl_for_xml_node(node))
5532 union_decl_sptr result = dynamic_pointer_cast<union_decl>(d);
5541 size_t size_in_bits = 0, alignment_in_bits = 0;
5542 read_size_and_alignment(node, size_in_bits, alignment_in_bits);
5545 read_visibility(node, vis);
5547 bool is_artificial =
false;
5548 read_is_artificial(node, is_artificial);
5555 read_location(rdr, node, loc);
5561 union_decl_sptr decl;
5563 bool is_decl_only =
false;
5564 read_is_declaration_only(node, is_decl_only);
5566 bool is_anonymous =
false;
5567 read_is_anonymous(node, is_anonymous);
5570 union_decl_sptr previous_definition, previous_declaration;
5571 const vector<type_base_sptr> *types_ptr = 0;
5573 types_ptr = rdr.get_all_type_decls(
id);
5579 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5580 i != types_ptr->end();
5585 if (onion->get_is_declaration_only()
5586 && !onion->get_definition_of_declaration())
5587 previous_declaration = onion;
5588 else if (!onion->get_is_declaration_only()
5589 && !previous_definition)
5590 previous_definition = onion;
5591 if (previous_definition && previous_declaration)
5595 if (previous_declaration)
5596 ABG_ASSERT(previous_declaration->get_name() == name);
5598 if (previous_definition)
5599 ABG_ASSERT(previous_definition->get_name() == name);
5601 if (is_decl_only && previous_declaration)
5602 return previous_declaration;
5605 const environment& env = rdr.get_environment();
5607 if (!is_decl_only && previous_definition)
5613 decl = previous_definition;
5617 decl.reset(
new union_decl(env, name));
5619 decl.reset(
new union_decl(env, name,
5627 maybe_set_artificial_location(rdr, node, decl);
5628 decl->set_is_artificial(is_artificial);
5631 bool is_def_of_decl =
false;
5633 def_id = CHAR_STR(s);
5635 if (!def_id.empty())
5638 dynamic_pointer_cast<class_decl>(rdr.get_type_decl(def_id));
5639 if (d && d->get_is_declaration_only())
5641 is_def_of_decl =
true;
5642 decl->set_earlier_declaration(d);
5643 d->set_definition_of_declaration(decl);
5649 && !decl->get_is_declaration_only()
5650 && previous_declaration)
5656 decl->set_earlier_declaration(previous_declaration);
5657 for (vector<type_base_sptr>::const_iterator i = types_ptr->begin();
5658 i != types_ptr->end();
5663 if (d->get_is_declaration_only()
5664 && !d->get_definition_of_declaration())
5666 previous_declaration->set_definition_of_declaration(decl);
5667 is_def_of_decl =
true;
5672 if (is_decl_only && previous_definition)
5677 && !decl->get_definition_of_declaration());
5678 decl->set_definition_of_declaration(previous_definition);
5681 ABG_ASSERT(!is_decl_only || !is_def_of_decl);
5683 rdr.push_decl_to_scope(decl,
5684 add_to_current_scope
5685 ? rdr.get_scope_ptr_for_node(node)
5688 rdr.map_xml_node_to_decl(node, decl);
5689 rdr.key_type_decl(decl,
id);
5691 maybe_set_naming_typedef(rdr, node, decl);
5693 for (xmlNodePtr n = xmlFirstElementChild(node);
5695 n = xmlNextElementSibling(n))
5697 if (xmlStrEqual(n->name, BAD_CAST(
"member-type")))
5700 read_access(n, access);
5702 rdr.map_xml_node_to_decl(n, decl);
5704 for (xmlNodePtr p = xmlFirstElementChild(n);
5706 p = xmlNextElementSibling(p))
5708 if (type_base_sptr t =
5709 build_type(rdr, p,
true))
5714 rdr.maybe_canonicalize_type(t, !add_to_current_scope);
5716 string id = CHAR_STR(i);
5718 rdr.key_type_decl(t,
id);
5719 rdr.map_xml_node_to_decl(p, td);
5723 else if (xmlStrEqual(n->name, BAD_CAST(
"data-member")))
5725 rdr.map_xml_node_to_decl(n, decl);
5728 read_access(n, access);
5730 bool is_laid_out =
true;
5731 size_t offset_in_bits = 0;
5732 bool is_static =
false;
5733 read_static(n, is_static);
5735 for (xmlNodePtr p = xmlFirstElementChild(n);
5737 p = xmlNextElementSibling(p))
5740 build_var_decl(rdr, p,
false))
5742 if (decl->find_data_member(v))
5750 decl_base_sptr d = rdr.pop_decl();
5755 || !variable_is_suppressed(rdr, decl.get(), *v))
5757 decl->add_data_member(v, access,
5770 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), decl);
5773 RECORD_ARTIFACT_AS_USED_BY(rdr, v->get_type(), v);
5774 RECORD_ARTIFACT_AS_USED_BY(rdr, v, decl);
5780 else if (xmlStrEqual(n->name, BAD_CAST(
"member-function")))
5782 rdr.map_xml_node_to_decl(n, decl);
5785 read_access(n, access);
5787 bool is_static =
false;
5788 read_static(n, is_static);
5790 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5791 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5793 for (xmlNodePtr p = xmlFirstElementChild(n);
5795 p = xmlNextElementSibling(p))
5798 build_function_decl_if_not_suppressed(rdr, p, decl,
5809 rdr.add_fn_to_exported_or_undefined_decls(f.get());
5814 else if (xmlStrEqual(n->name, BAD_CAST(
"member-template")))
5816 rdr.map_xml_node_to_decl(n, decl);
5819 read_access(n, access);
5821 bool is_static =
false;
5822 read_static(n, is_static);
5824 bool is_ctor =
false, is_dtor =
false, is_const =
false;
5825 read_cdtor_const(n, is_ctor, is_dtor, is_const);
5827 for (xmlNodePtr p = xmlFirstElementChild(n);
5829 p = xmlNextElementSibling(p))
5832 build_function_tdecl(rdr, p,
5835 member_function_template_sptr m
5836 (
new member_function_template(f, access, is_static,
5837 is_ctor, is_const));
5839 decl->add_member_function_template(m);
5842 build_class_tdecl(rdr, p,
5845 member_class_template_sptr m(
new member_class_template(c,
5849 decl->add_member_class_template(m);
5855 rdr.pop_scope_or_abort(decl);
5872 static shared_ptr<function_tdecl>
5873 build_function_tdecl(reader& rdr,
5874 const xmlNodePtr node,
5875 bool add_to_current_scope)
5877 shared_ptr<function_tdecl> nil, result;
5879 if (!xmlStrEqual(node->name, BAD_CAST(
"function-template-decl")))
5885 if (
id.empty() || rdr.get_fn_tmpl_decl(
id))
5889 read_location(rdr, node, loc);
5892 read_visibility(node, vis);
5895 read_binding(node, bind);
5897 const environment& env = rdr.get_environment();
5900 maybe_set_artificial_location(rdr, node, fn_tmpl_decl);
5902 rdr.push_decl_to_scope(fn_tmpl_decl,
5903 add_to_current_scope
5904 ? rdr.get_scope_ptr_for_node(node)
5906 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5907 rdr.map_xml_node_to_decl(node, fn_tmpl_decl);
5909 unsigned parm_index = 0;
5910 for (xmlNodePtr n = xmlFirstElementChild(node);
5912 n = xmlNextElementSibling(n))
5915 build_template_parameter(rdr, n, parm_index, fn_tmpl_decl))
5917 fn_tmpl_decl->add_template_parameter(parm);
5924 fn_tmpl_decl->set_pattern(f);
5927 rdr.key_fn_tmpl_decl(fn_tmpl_decl,
id);
5929 return fn_tmpl_decl;
5945 build_class_tdecl(reader& rdr,
5946 const xmlNodePtr node,
5947 bool add_to_current_scope)
5951 if (!xmlStrEqual(node->name, BAD_CAST(
"class-template-decl")))
5957 if (
id.empty() || rdr.get_class_tmpl_decl(
id))
5961 read_location(rdr, node, loc);
5964 read_visibility(node, vis);
5966 const environment& env = rdr.get_environment();
5969 maybe_set_artificial_location(rdr, node, class_tmpl);
5971 if (add_to_current_scope)
5972 rdr.push_decl_to_scope(class_tmpl, node);
5973 rdr.key_class_tmpl_decl(class_tmpl,
id);
5974 rdr.map_xml_node_to_decl(node, class_tmpl);
5976 unsigned parm_index = 0;
5977 for (xmlNodePtr n = xmlFirstElementChild(node);
5979 n = xmlNextElementSibling(n))
5982 build_template_parameter(rdr, n, parm_index, class_tmpl))
5984 class_tmpl->add_template_parameter(parm);
5988 build_class_decl_if_not_suppressed(rdr, n,
5989 add_to_current_scope))
5992 rdr.maybe_canonicalize_type(c,
false);
5993 class_tmpl->set_pattern(c);
5997 rdr.key_class_tmpl_decl(class_tmpl,
id);
6018 build_type_tparameter(reader& rdr,
6019 const xmlNodePtr node,
6025 if (!xmlStrEqual(node->name, BAD_CAST(
"template-type-parameter")))
6036 type_id = CHAR_STR(s);
6037 if (!type_id.empty()
6038 && !(result = dynamic_pointer_cast<type_tparameter>
6039 (rdr.build_or_get_type_decl(type_id,
true))))
6047 read_location(rdr, node,loc);
6049 result.reset(
new type_tparameter(index, tdecl, name, loc));
6050 maybe_set_artificial_location(rdr, node, result);
6053 rdr.push_decl_to_scope(
is_decl(result), node);
6055 rdr.push_and_key_type_decl(result, node,
true);
6057 rdr.maybe_canonicalize_type(result,
false);
6077 build_type_composition(reader& rdr,
6078 const xmlNodePtr node,
6084 if (!xmlStrEqual(node->name, BAD_CAST(
"template-parameter-type-composition")))
6087 type_base_sptr composed_type;
6088 result.reset(
new type_composition(index, tdecl, composed_type));
6089 rdr.push_decl_to_scope(
is_decl(result), node);
6091 for (xmlNodePtr n = xmlFirstElementChild(node);
6093 n = xmlNextElementSibling(n))
6095 if ((composed_type =
6096 build_pointer_type_def(rdr, n,
6099 build_reference_type_def(rdr, n,
6102 build_array_type_def(rdr, n,
6105 build_qualified_type_decl(rdr, n,
6108 rdr.maybe_canonicalize_type(composed_type,
6110 result->set_composed_type(composed_type);
6134 build_non_type_tparameter(reader& rdr,
6135 const xmlNodePtr node,
6141 if (!xmlStrEqual(node->name, BAD_CAST(
"template-non-type-parameter")))
6146 type_id = CHAR_STR(s);
6147 type_base_sptr type;
6149 || !(type = rdr.build_or_get_type_decl(type_id,
true)))
6157 read_location(rdr, node,loc);
6159 r.reset(
new non_type_tparameter(index, tdecl, name, type, loc));
6160 maybe_set_artificial_location(rdr, node, r);
6161 rdr.push_decl_to_scope(
is_decl(r), node);
6181 build_template_tparameter(reader& rdr,
6182 const xmlNodePtr node,
6188 if (!xmlStrEqual(node->name, BAD_CAST(
"template-template-parameter")))
6199 type_id = CHAR_STR(s);
6201 if (!type_id.empty()
6202 && !(dynamic_pointer_cast<template_tparameter>
6203 (rdr.build_or_get_type_decl(type_id,
true))))
6211 read_location(rdr, node, loc);
6215 maybe_set_artificial_location(rdr, node, result);
6216 rdr.push_decl_to_scope(result, node);
6220 for (xmlNodePtr n = xmlFirstElementChild(node);
6222 n = xmlNextElementSibling(n))
6223 if (shared_ptr<template_parameter> p =
6224 build_template_parameter(rdr, n, parm_index, result))
6226 result->add_template_parameter(p);
6232 rdr.key_type_decl(result,
id);
6233 rdr.maybe_canonicalize_type(result,
false);
6255 build_template_parameter(reader& rdr,
6256 const xmlNodePtr node,
6260 shared_ptr<template_parameter> r;
6261 ((r = build_type_tparameter(rdr, node, index, tdecl))
6262 || (r = build_non_type_tparameter(rdr, node, index, tdecl))
6263 || (r = build_template_tparameter(rdr, node, index, tdecl))
6264 || (r = build_type_composition(rdr, node, index, tdecl)));
6277 static type_base_sptr
6278 build_type(reader& rdr,
6279 const xmlNodePtr node,
6280 bool add_to_current_scope)
6284 ((t = build_type_decl(rdr, node, add_to_current_scope))
6285 || (t = build_qualified_type_decl(rdr, node, add_to_current_scope))
6286 || (t = build_pointer_type_def(rdr, node, add_to_current_scope))
6287 || (t = build_reference_type_def(rdr, node , add_to_current_scope))
6288 || (t = build_ptr_to_mbr_type(rdr, node , add_to_current_scope))
6289 || (t = build_function_type(rdr, node, add_to_current_scope))
6290 || (t = build_array_type_def(rdr, node, add_to_current_scope))
6291 || (t = build_subrange_type(rdr, node, add_to_current_scope))
6292 || (t = build_enum_type_decl_if_not_suppressed(rdr, node,
6293 add_to_current_scope))
6294 || (t = build_typedef_decl(rdr, node, add_to_current_scope))
6295 || (t = build_class_decl_if_not_suppressed(rdr, node,
6296 add_to_current_scope))
6297 || (t = build_union_decl_if_not_suppressed(rdr, node,
6298 add_to_current_scope)));
6300 if (rdr.tracking_non_reachable_types() && t)
6302 corpus_sptr abi = rdr.corpus();
6304 bool is_non_reachable_type =
false;
6305 read_is_non_reachable_type(node, is_non_reachable_type);
6306 if (!is_non_reachable_type)
6307 abi->record_type_as_reachable_from_public_interfaces(*t);
6310 MAYBE_MAP_TYPE_WITH_TYPE_ID(t, node);
6313 rdr.maybe_canonicalize_type(t,
false );
6322 static decl_base_sptr
6323 handle_type_decl(reader& rdr,
6325 bool add_to_current_scope)
6327 type_decl_sptr decl = build_type_decl(rdr, node, add_to_current_scope);
6328 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6329 if (decl && decl->get_scope())
6330 rdr.maybe_canonicalize_type(decl,
false);
6339 static decl_base_sptr
6340 handle_namespace_decl(reader& rdr,
6342 bool add_to_current_scope)
6345 add_to_current_scope);
6354 static decl_base_sptr
6355 handle_qualified_type_decl(reader& rdr,
6357 bool add_to_current_scope)
6359 qualified_type_def_sptr decl =
6360 build_qualified_type_decl(rdr, node,
6361 add_to_current_scope);
6362 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6363 if (decl && decl->get_scope())
6364 rdr.maybe_canonicalize_type(decl,
false);
6373 static decl_base_sptr
6374 handle_pointer_type_def(reader& rdr,
6376 bool add_to_current_scope)
6379 add_to_current_scope);
6380 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6381 if (decl && decl->get_scope())
6382 rdr.maybe_canonicalize_type(decl,
false);
6391 static decl_base_sptr
6392 handle_reference_type_def(reader& rdr,
6394 bool add_to_current_scope)
6397 add_to_current_scope);
6398 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6399 if (decl && decl->get_scope())
6400 rdr.maybe_canonicalize_type(decl,
false);
6409 static type_base_sptr
6410 handle_function_type(reader& rdr,
6412 bool add_to_current_scope)
6415 add_to_current_scope);
6416 MAYBE_MAP_TYPE_WITH_TYPE_ID(type, node);
6417 rdr.maybe_canonicalize_type(type,
true);
6426 static decl_base_sptr
6427 handle_array_type_def(reader& rdr,
6429 bool add_to_current_scope)
6432 add_to_current_scope);
6433 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6434 rdr.maybe_canonicalize_type(decl,
false);
6441 static decl_base_sptr
6442 handle_enum_type_decl(reader& rdr,
6444 bool add_to_current_scope)
6447 build_enum_type_decl_if_not_suppressed(rdr, node,
6448 add_to_current_scope);
6449 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6450 if (decl && decl->get_scope())
6451 rdr.maybe_canonicalize_type(decl,
false);
6458 static decl_base_sptr
6459 handle_typedef_decl(reader& rdr,
6461 bool add_to_current_scope)
6464 add_to_current_scope);
6465 MAYBE_MAP_TYPE_WITH_TYPE_ID(decl, node);
6466 if (decl && decl->get_scope())
6467 rdr.maybe_canonicalize_type(decl,
false);
6479 static decl_base_sptr
6480 handle_var_decl(reader& rdr,
6482 bool add_to_current_scope)
6484 decl_base_sptr decl = build_var_decl_if_not_suppressed(rdr, node,
6485 add_to_current_scope);
6486 rdr.add_var_to_exported_or_undefined_decls(
is_var_decl(decl).
get());
6496 static decl_base_sptr
6497 handle_function_decl(reader& rdr,
6499 bool add_to_current_scope)
6501 return build_function_decl_if_not_suppressed(rdr, node,
class_decl_sptr(),
6502 add_to_current_scope,
6512 static decl_base_sptr
6513 handle_class_decl(reader& rdr,
6515 bool add_to_current_scope)
6518 build_class_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6519 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6520 if (decl && decl->get_scope())
6521 rdr.maybe_canonicalize_type(decl,
false);
6531 static decl_base_sptr
6532 handle_union_decl(reader& rdr,
6534 bool add_to_current_scope)
6536 union_decl_sptr decl =
6537 build_union_decl_if_not_suppressed(rdr, node, add_to_current_scope);
6538 MAYBE_MAP_TYPE_WITH_TYPE_ID(
is_type(decl), node);
6539 if (decl && decl->get_scope())
6540 rdr.maybe_canonicalize_type(decl,
false);
6550 static decl_base_sptr
6551 handle_function_tdecl(reader& rdr,
6553 bool add_to_current_scope)
6556 add_to_current_scope);
6565 static decl_base_sptr
6566 handle_class_tdecl(reader& rdr,
6568 bool add_to_current_scope)
6571 add_to_current_scope);
6588 return read_translation_unit_from_input(read_rdr);
6590 template<
typename T>
6591 struct array_deleter
6613 corpus_sptr corp = result->corpus();
6614 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6615 #ifdef WITH_DEBUG_SELF_COMPARISON
6616 if (env.self_comparison_debug_is_on())
6617 env.set_self_comparison_debug_input(result->corpus());
6619 result->set_path(path);
6636 corpus_sptr corp = result->corpus();
6637 corp->set_origin(corpus::NATIVE_XML_ORIGIN);
6638 #ifdef WITH_DEBUG_SELF_COMPARISON
6639 if (env.self_comparison_debug_is_on())
6640 env.set_self_comparison_debug_input(result->corpus());
6663 return rdr->read_corpus(sts);
6685 corpus_sptr corp = rdr->read_corpus(sts);
6691 #ifdef WITH_DEBUG_SELF_COMPARISON
6710 load_canonical_type_ids(fe_iface& iface,
const string &file_path)
6712 abixml::reader& rdr =
dynamic_cast<abixml::reader&
>(iface);
6714 xmlDocPtr doc = xmlReadFile(file_path.c_str(), NULL, XML_PARSE_NOERROR);
6718 xmlNodePtr node = xmlDocGetRootElement(doc);
6741 if (xmlStrcmp(node->name, (xmlChar*)
"abixml-types-check"))
6744 for (node = xmlFirstElementChild(node);
6746 node = xmlNextElementSibling(node))
6748 if (xmlStrcmp(node->name, (xmlChar*)
"type"))
6751 string id, canonical_address;
6752 xmlNodePtr data = xmlFirstElementChild(node);
6753 if (data && !xmlStrcmp(data->name, (xmlChar*)
"id")
6754 && data->children && xmlNodeIsText(data->children))
6755 id = (
char*) XML_GET_CONTENT(data->children);
6757 data = xmlNextElementSibling(data);
6758 if (data && !xmlStrcmp(data->name, (xmlChar*)
"c")
6759 && data->children && xmlNodeIsText(data->children))
6761 canonical_address = (
char*) XML_GET_CONTENT(data->children);
6762 std::stringstream s;
6763 s << canonical_address;
6771 rdr.get_environment().get_type_id_canonical_type_map()[id] = v;
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
bool is_elf_symbol_suppressed(const fe_iface &fe, const elf_symbol_sptr &symbol)
Test if an ELF symbol is suppressed by at least one of the suppression specifications associated with...
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
suppr::suppressions_type & suppressions()
Getter of the vector of suppression specifications associated with the current front-end.
#define XML_READER_GET_NODE_NAME(reader)
Get the name of the current element node the reader is pointing to. Note that this macro returns an i...
bool suppression_can_match(const fe_iface &fe, const suppression_base &s)
Test if a given suppression specification can match an ABI artifact coming from the corpus being anal...
shared_ptr< T > build_sptr(T *p)
This is to be specialized for the diverse C types that needs wrapping in shared_ptr.
visibility
The visibility of the symbol.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
fe_iface_sptr create_reader(const string &path, environment &env)
Create an xml_reader::reader to read a native XML ABI file.
reader_sptr new_reader_from_istream(std::istream *in)
Instanciate an xmlTextReader that parses a content coming from an input stream.
This file contains the declarations for the fe_iface a.k.a "Front End Interface". ...
The base class of all libabigail front-ends: The Front End Interface.
corpus_group_sptr read_corpus_group_from_abixml(std::istream *in, environment &env)
De-serialize an ABI corpus group from an input XML document which root node is 'abi-corpus-group'.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< xmlChar > xml_char_sptr
A convenience typedef for a shared pointer of xmlChar.
const options_type & options() const
Getter of the the options of the current Front End Interface.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
The base class of both types and declarations.
#define XML_NODE_GET_ATTRIBUTE(node, name)
Get the value of attribute 'name' ont the instance of xmlNodePtr denoted by 'node'.
reader_sptr new_reader_from_buffer(const std::string &buffer)
Instanciate an xmlTextReader that parses the content of an in-memory buffer, wrap it into a smart poi...
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
translation_unit_sptr read_translation_unit_from_istream(istream *in, environment &env)
De-serialize a translation unit from an ABI Instrumentation xml file coming from an input stream...
status
The status of the fe_iface::read_corpus call.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
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.
shared_ptr< file_suppression > file_suppression_sptr
A convenience typedef for a shared_ptr to file_suppression.
#define XML_READER_GET_NODE_TYPE(reader)
Get the type of the current node of the shared_ptr passed in argument.
file_suppression_sptr is_file_suppression(const suppression_sptr s)
Test if a given suppression specification is a file suppression specification.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
bool suppression_matches_type_name_or_location(const type_suppression &s, const string &type_name, const location &type_location)
Test if a type suppression matches a type name and location.
std::unordered_map< string, elf_symbol_sptr > string_elf_symbol_sptr_map_type
Convenience typedef for a map which key is a string and which value if the elf symbol of the same nam...
This contains the declarations for the symtab reader.
shared_ptr< type_composition > type_composition_sptr
Convenience typedef for shared pointer to type_composition.
vector< type_base_sptr > member_types
Convenience typedef.
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
std::vector< elf_symbol_sptr > elf_symbols
Convenience typedef for a vector of elf_symbol.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
corpus_group_sptr & corpus_group()
Getter for the ABI corpus group being built by the current front-end.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< xmlTextReader > reader_sptr
A convenience typedef for a shared pointer of xmlTextReader.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Toplevel namespace for libabigail.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
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...
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol...
shared_ptr< template_tparameter > template_tparameter_sptr
Convenience typedef for a shared_ptr to template_tparameter.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
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_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_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus group from an XML document file which root node is 'abi-corpus-group'.
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
type
The type of a symbol.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
translation_unit_sptr read_translation_unit_from_buffer(const string &buffer, environment &env)
Parse an ABI instrumentation file (in XML format) from an in-memory buffer.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
This file contains the declarations of the entry points to de-serialize an instance of abigail::trans...
translation_unit * get_translation_unit(const decl_base &decl)
Return the translation unit a declaration belongs to.
vector< method_decl_sptr > member_functions
Convenience typedef.
This contains the private implementation of the suppression engine of libabigail. ...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
unordered_map< string, vector< string > > string_strings_map_type
Convenience typedef for an unordered map of string to a vector of strings.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
#define XML_READER_GET_ATTRIBUTE(reader, name)
Get the value of attribute 'name' on the current node of 'reader' which is an instance of shared_ptr<...
vector< suppression_sptr > suppressions_type
Convenience typedef for a vector of suppression_sptr.
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
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.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
bool suppression_matches_soname_or_filename(const string &soname, const string &filename, const suppression_base &suppr)
Test if a given SONAME or file name is matched by a given suppression specification.
binding
The binding of a symbol.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
void unescape_xml_string(const std::string &str, std::string &escaped)
Read a string, detect the 5 predefined XML entities it may contain and un-escape them, by writting their corresponding characters back in. The pre-defined entities are:
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string...
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
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...
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
shared_ptr< non_type_tparameter > non_type_tparameter_sptr
Convenience typedef for shared pointer to non_type_template_parameter.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
static symtab_ptr load(Elf *elf_handle, const ir::environment &env, symbol_predicate is_suppressed=NULL)
Construct a symtab object and instantiate it from an ELF handle. Also pass in the ir::environment we ...
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
reader_sptr new_reader_from_file(const std::string &path)
Instantiate an xmlTextReader that parses the content of an on-disk file, wrap it into a smart pointer...
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
Abstraction of a group of corpora.
vector< var_decl_sptr > data_members
Convenience typedef.
bool is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
access_specifier
Access specifier for class members.
corpus_group_sptr read_corpus_group_from_input(fe_iface &iface)
Parse the input XML document containing an ABI corpus group, represented by an 'abi-corpus-group' ele...
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
shared_ptr< function_suppression > function_suppression_sptr
Convenience typedef for a shared pointer to function_suppression.
void consider_types_not_reachable_from_public_interfaces(fe_iface &iface, bool flag)
Configure the reader so that types not reachable from public interface are taken into account when th...
void add_reader_suppressions(reader &rdr, const suppr::suppressions_type &supprs)
Add suppressions specifications to the set of suppressions to be used during the construction of the ...
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
vector< base_spec_sptr > base_specs
Convenience typedef.
corpus_sptr read_corpus_from_abixml_file(const string &path, environment &env)
De-serialize an ABI corpus from an XML document file which root node is 'abi-corpus'.
shared_ptr< string_elf_symbols_map_type > string_elf_symbols_map_sptr
Convenience typedef for a shared pointer to string_elf_symbols_map_type.
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
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.
shared_ptr< type_tparameter > type_tparameter_sptr
Convenience typedef for a shared pointer to type_tparameter.
This status is for when the call went OK.
bool xml_char_sptr_to_string(xml_char_sptr ssptr, std::string &s)
Convert a shared pointer to xmlChar into an std::string.
CV
Bit field values representing the cv qualifiers of the underlying type.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
visibility
ELF visibility.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...