14 #include "abg-internal.h"
15 #include <sys/types.h>
22 #include <elfutils/libdwfl.h>
33 #include <unordered_map>
34 #include <unordered_set>
43 ABG_BEGIN_EXPORT_DECLARATIONS
55 #define UINT64_MAX 0xffffffffffffffff
69 using std::dynamic_pointer_cast;
70 using std::static_pointer_cast;
71 using std::unordered_map;
72 using std::unordered_set;
79 using namespace elf_helpers;
86 NO_DEBUG_INFO_DIE_SOURCE,
87 PRIMARY_DEBUG_INFO_DIE_SOURCE,
88 ALT_DEBUG_INFO_DIE_SOURCE,
90 NUMBER_OF_DIE_SOURCES,
138 struct dwarf_offset_pair_hash
141 operator()(
const std::pair<Dwarf_Off, Dwarf_Off>& p)
const
145 typedef unordered_set<std::pair<Dwarf_Off,
147 dwarf_offset_pair_hash> dwarf_offset_pair_set_type;
157 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
161 offset_type(
die_source source, Dwarf_Off offset)
166 offset_type(Dwarf_Off offset)
167 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
172 {
return source_ == o.source_ && offset_ == o.offset_;}
174 operator Dwarf_Off()
const
185 operator()(
const offset_type& p)
const
194 struct offset_pair_hash
197 operator()(
const std::pair<offset_type, offset_type>& p)
const
202 hash_t(p.second.offset_));
211 typedef unordered_set<std::pair<offset_type,
220 typedef unordered_map<std::pair<offset_type, offset_type>,
226 typedef unordered_map<std::pair<offset_type, offset_type>,
236 build_translation_unit_and_add_to_ir(reader& rdr,
241 maybe_propagate_canonical_type(
const reader& rdr,
246 propagate_canonical_type(
const reader& rdr,
251 maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
255 cleanup_decl_name(
string&);
263 typedef unordered_map<interned_string,
295 struct imported_unit_point
297 Dwarf_Off offset_of_import;
301 Dwarf_Off imported_unit_die_off;
302 Dwarf_Off imported_unit_cu_off;
303 Dwarf_Off imported_unit_child_off;
306 imported_unit_point()
307 : offset_of_import(),
308 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
309 imported_unit_die_off(),
310 imported_unit_cu_off(),
311 imported_unit_child_off()
318 imported_unit_point(Dwarf_Off import_off)
319 : offset_of_import(import_off),
320 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
321 imported_unit_die_off(),
322 imported_unit_cu_off(),
323 imported_unit_child_off()
334 imported_unit_point(Dwarf_Off import_off,
335 const Dwarf_Die& imported_die,
337 : offset_of_import(import_off),
338 imported_unit_die_source(from),
339 imported_unit_die_off(dwarf_dieoffset
340 (const_cast<Dwarf_Die*>(&imported_die))),
341 imported_unit_cu_off(),
342 imported_unit_child_off()
344 Dwarf_Die imported_unit_child;
346 ABG_ASSERT(dwarf_child(const_cast<Dwarf_Die*>(&imported_die),
347 &imported_unit_child) == 0);
349 imported_unit_child_off =
350 dwarf_dieoffset(const_cast<Dwarf_Die*>(&imported_unit_child));
352 Dwarf_Die cu_die_memory;
355 cu_die = dwarf_diecu(const_cast<Dwarf_Die*>(&imported_unit_child),
356 &cu_die_memory, 0, 0);
357 imported_unit_cu_off = dwarf_dieoffset(cu_die);
365 typedef unordered_map<Dwarf_Off, imported_unit_points_type>
377 operator<(
const imported_unit_point& l,
const imported_unit_point& r)
378 {
return l.offset_of_import < r.offset_of_import;}
381 get_parent_die(
const reader& rdr,
382 const Dwarf_Die* die,
383 Dwarf_Die& parent_die,
384 size_t where_offset);
387 get_scope_die(
const reader& rdr,
388 const Dwarf_Die* die,
390 Dwarf_Die& scope_die);
396 die_is_in_c(
const Dwarf_Die *die);
399 die_is_in_cplus_plus(
const Dwarf_Die *die);
402 die_is_in_c_or_cplusplus(
const Dwarf_Die *die);
405 die_is_anonymous(
const Dwarf_Die* die);
408 die_is_anonymous_data_member(
const Dwarf_Die* die);
411 die_is_type(
const Dwarf_Die* die);
414 die_is_decl(
const Dwarf_Die* die);
417 die_is_declaration_only(Dwarf_Die* die);
420 die_is_variable_decl(
const Dwarf_Die *die);
423 die_is_function_decl(
const Dwarf_Die *die);
426 die_has_size_attribute(
const Dwarf_Die *die);
429 die_has_no_child(
const Dwarf_Die *die);
432 die_is_namespace(
const Dwarf_Die* die);
435 die_is_unspecified(Dwarf_Die* die);
438 die_is_void_type(Dwarf_Die* die);
441 die_is_pointer_type(
const Dwarf_Die* die);
444 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
447 die_is_reference_type(
const Dwarf_Die* die);
450 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
453 die_is_pointer_or_reference_type(
const Dwarf_Die* die);
456 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
459 die_is_class_type(
const Dwarf_Die* die);
462 die_is_qualified_type(
const Dwarf_Die* die);
465 die_is_function_type(
const Dwarf_Die *die);
468 die_has_object_pointer(
const Dwarf_Die* die,
469 Dwarf_Die& object_pointer);
472 die_has_children(
const Dwarf_Die* die);
475 fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die);
478 member_fn_die_has_this_pointer(
const reader& rdr,
479 const Dwarf_Die* die,
481 Dwarf_Die& class_die,
482 Dwarf_Die& object_pointer_die);
485 die_this_pointer_from_object_pointer(Dwarf_Die* die,
486 Dwarf_Die& this_pointer);
489 die_this_pointer_is_const(Dwarf_Die* die);
492 die_object_pointer_is_for_const_method(Dwarf_Die* die);
495 is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
498 die_is_at_class_scope(
const reader& rdr,
499 const Dwarf_Die* die,
501 Dwarf_Die& class_scope_die);
503 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
506 bool& is_tls_address);
509 dwarf_language_to_tu_language(
size_t l);
512 die_unsigned_constant_attribute(
const Dwarf_Die* die,
517 die_signed_constant_attribute(
const Dwarf_Die*die,
522 die_constant_attribute(
const Dwarf_Die *die,
528 die_member_offset(
const reader& rdr,
529 const Dwarf_Die* die,
533 form_is_DW_FORM_strx(
unsigned form);
536 form_is_DW_FORM_line_strp(
unsigned form);
539 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
542 die_name(
const Dwarf_Die* die);
545 die_name_and_linkage_name(
const Dwarf_Die* die,
547 string& linkage_name);
549 die_location(
const reader& rdr,
const Dwarf_Die* die);
552 die_location_address(Dwarf_Die* die,
554 bool& is_tls_address);
557 die_die_attribute(
const Dwarf_Die* die,
560 bool recursively =
true);
563 die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die);
566 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
572 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
574 Dwarf_Die& referenced_subrange);
576 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
579 build_internal_anonymous_die_name(
const string &
base_name,
580 size_t anonymous_type_index);
583 die_qualified_type_name(
const reader& rdr,
584 const Dwarf_Die* die,
586 unordered_set<uint64_t>& guard);
589 die_qualified_decl_name(
const reader& rdr,
590 const Dwarf_Die* die,
592 unordered_set<uint64_t>& guard);
595 die_qualified_name(
const reader& rdr,
596 const Dwarf_Die* die,
598 unordered_set<uint64_t>& guard);
601 die_qualified_name(
const reader& rdr,
602 const Dwarf_Die* die,
606 die_type_name(
const reader& rdr,
const Dwarf_Die* die,
607 bool qualified_name,
size_t where_offset,
608 unordered_set<uint64_t>& infinite_loop_guard);
611 die_type_name(
const reader& rdr,
const Dwarf_Die* die,
612 bool qualified_name,
size_t where_offset);
615 die_qualified_type_name_empty(
const reader& rdr,
616 const Dwarf_Die* die,
size_t where,
617 string &qualified_name,
618 unordered_set<uint64_t>& infinite_loop_guard);
621 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
622 const Dwarf_Die* die,
627 string &return_type_name,
629 vector<string>& parm_names,
632 unordered_set<uint64_t>& infinite_loop_guard);
635 die_function_signature(
const reader& rdr,
636 const Dwarf_Die *die,
639 unordered_set<uint64_t>& infinite_loop_guard);
642 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
645 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
648 die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die);
651 die_function_type_is_method_type(
const reader& rdr,
652 const Dwarf_Die *die,
654 Dwarf_Die& object_pointer_die,
655 Dwarf_Die& class_die,
659 die_enum_flat_representation(
const reader& rdr,
660 const Dwarf_Die* die,
661 const string& indent,
663 bool qualified_names,
664 size_t where_offset);
667 die_class_flat_representation(
const reader& rdr,
668 const Dwarf_Die* die,
669 const string& indent,
671 bool qualified_names,
673 unordered_set<uint64_t>& infinite_loop_guard);
676 die_class_or_enum_flat_representation(
const reader& rdr,
677 const Dwarf_Die* die,
678 const string& indent,
680 bool qualified_names,
682 unordered_set<uint64_t>& infinite_loop_guard);
685 die_class_or_enum_flat_representation(
const reader& rdr,
686 const Dwarf_Die* die,
687 const string& indent,
689 bool qualified_names,
690 size_t where_offset);
693 die_pretty_print_type(
const reader& rdr,
694 const Dwarf_Die* die,
696 unordered_set<uint64_t>& guard);
699 die_pretty_print_decl(
const reader& rdr,
700 const Dwarf_Die* die,
704 unordered_set<uint64_t>& infinite_loop_guard);
707 die_pretty_print(reader& rdr,
708 const Dwarf_Die* die,
710 unordered_set<uint64_t>& infinite_loop_guard);
713 maybe_canonicalize_type(
const type_base_sptr& t,
720 find_lower_bound_in_imported_unit_points(
const imported_unit_points_type&,
722 imported_unit_points_type::const_iterator&);
725 build_subrange_type(reader& rdr,
726 const Dwarf_Die* die,
728 bool associate_type_to_die =
true);
731 build_subranges_from_array_type_die(
const reader& rdr,
732 const Dwarf_Die* die,
735 bool associate_type_to_die =
true);
738 compare_dies(
const reader& rdr,
739 const Dwarf_Die *l,
const Dwarf_Die *r,
740 bool update_canonical_dies_on_the_fly);
743 compare_dies_during_canonicalization(reader& rdr,
744 const Dwarf_Die *l,
const Dwarf_Die *r,
745 bool update_canonical_dies_on_the_fly);
748 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
751 get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member);
764 ABG_ASSERT(dwarf_diecu(const_cast<Dwarf_Die*>(die), &cu_die, 0, 0));
767 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
770 lang = dwarf_language_to_tu_language(l);
782 die_is_in_c(
const Dwarf_Die *die)
785 if (!get_die_language(die, l))
798 die_is_in_cplus_plus(
const Dwarf_Die *die)
801 if (!get_die_language(die, l))
814 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
817 if (!get_die_language(die, l))
834 compare_symbol_name(
const string& symbol_name,
843 return symbol_name == name;
872 lookup_symbol_from_sysv_hash_tab(
const environment& env,
874 const string& sym_name,
876 size_t sym_tab_index,
878 vector<elf_symbol_sptr>& syms_found)
880 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
883 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
886 GElf_Shdr sheader_mem;
887 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
889 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
894 unsigned long hash = elf_hash(sym_name.c_str());
895 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
896 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
897 size_t nb_buckets = ht_data[0];
898 size_t nb_chains = ht_data[1];
906 Elf32_Word* ht_buckets = &ht_data[2];
907 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
910 size_t bucket = hash % nb_buckets;
911 size_t symbol_index = ht_buckets[bucket];
914 const char* sym_name_str;
923 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
924 sym_name_str = elf_strptr(elf_handle,
925 sym_tab_section_header->sh_link,
928 && compare_symbol_name(sym_name_str, sym_name, demangle))
930 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
931 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
933 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
934 sym_size = symbol.st_size;
935 elf_symbol::version ver;
936 if (get_version_for_symbol(elf_handle, symbol_index,
946 symbol.st_shndx != SHN_UNDEF,
947 symbol.st_shndx == SHN_COMMON,
948 ver, sym_visibility);
949 syms_found.push_back(symbol_found);
952 symbol_index = ht_chains[symbol_index];
953 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
964 get_elf_class_size_in_bytes(Elf* elf_handle)
970 int c = hdr.e_ident[EI_CLASS];
1004 bloom_word_at(Elf* elf_handle,
1005 Elf32_Word* bloom_filter,
1008 Elf64_Xword result = 0;
1012 c = h.e_ident[EI_CLASS];
1017 result = bloom_filter[index];
1021 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
1040 Elf32_Word* buckets;
1042 size_t first_sym_index;
1045 Elf32_Word* bloom_filter;
1048 Elf_Scn* sym_tab_section;
1049 GElf_Shdr sym_tab_section_header;
1079 setup_gnu_ht(Elf* elf_handle,
1081 size_t sym_tab_index,
1084 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1086 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
1088 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
1089 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
1094 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
1095 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
1097 ht.nb_buckets = ht_data[0];
1098 if (ht.nb_buckets == 0)
1102 ht.first_sym_index = ht_data[1];
1105 ht.bf_nwords = ht_data[2];
1107 ht.shift = ht_data[3];
1109 ht.bloom_filter = &ht_data[4];
1114 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
1116 ht.buckets = ht.bloom_filter + ht.bf_size;
1118 ht.chain = ht.buckets + ht.nb_buckets;
1149 lookup_symbol_from_gnu_hash_tab(
const environment& env,
1151 const string& sym_name,
1153 size_t sym_tab_index,
1155 vector<elf_symbol_sptr>& syms_found)
1158 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
1164 size_t h1 = elf_gnu_hash(sym_name.c_str());
1165 size_t h2 = h1 >> ht.shift;
1168 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
1169 int n = (h1 / c) % ht.bf_nwords;
1175 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1178 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1181 size_t i = ht.buckets[h1 % ht.nb_buckets];
1185 Elf32_Word stop_word, *stop_wordp;
1186 elf_symbol::version ver;
1188 const char* sym_name_str;
1197 for (i = ht.buckets[h1 % ht.nb_buckets],
1198 stop_wordp = &ht.chain[i - ht.first_sym_index];
1201 < ht.chain + (ht.sym_count - ht.first_sym_index));
1204 stop_word = *stop_wordp;
1205 if ((stop_word & ~ 1)!= (h1 & ~1))
1211 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1213 sym_name_str = elf_strptr(elf_handle,
1214 ht.sym_tab_section_header.sh_link,
1217 && compare_symbol_name(sym_name_str, sym_name, demangle))
1221 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
1222 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
1224 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
1226 if (get_version_for_symbol(elf_handle, i,
1235 sym_type, sym_binding,
1236 symbol.st_shndx != SHN_UNDEF,
1237 symbol.st_shndx == SHN_COMMON,
1238 ver, sym_visibility);
1239 syms_found.push_back(symbol_found);
1281 lookup_symbol_from_elf_hash_tab(
const environment& env,
1283 hash_table_kind ht_kind,
1285 size_t symtab_index,
1286 const string& symbol_name,
1288 vector<elf_symbol_sptr>& syms_found)
1290 if (elf_handle == 0 || symbol_name.empty())
1293 if (ht_kind == NO_HASH_TABLE_KIND)
1296 if (ht_kind == SYSV_HASH_TABLE_KIND)
1297 return lookup_symbol_from_sysv_hash_tab(env,
1298 elf_handle, symbol_name,
1303 else if (ht_kind == GNU_HASH_TABLE_KIND)
1304 return lookup_symbol_from_gnu_hash_tab(env,
1305 elf_handle, symbol_name,
1338 lookup_symbol_from_symtab(
const environment& env,
1340 const string& sym_name,
1341 size_t sym_tab_index,
1343 vector<elf_symbol_sptr>& syms_found)
1348 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1351 GElf_Shdr header_mem;
1352 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1355 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1356 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1359 elf_symbol::version ver;
1362 for (
size_t i = 0; i < symcount; ++i)
1365 sym = gelf_getsym(symtab, i, &sym_mem);
1366 name_str = elf_strptr(elf_handle,
1367 sym_tab_header->sh_link,
1370 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1373 stt_to_elf_symbol_type(GELF_ST_TYPE(sym->st_info));
1375 stb_to_elf_symbol_binding(GELF_ST_BIND(sym->st_info));
1377 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(sym->st_other));
1378 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1379 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1381 if (get_version_for_symbol(elf_handle, i,
1388 sym_binding, sym_is_defined,
1389 sym_is_common, ver, sym_visibility);
1390 syms_found.push_back(symbol_found);
1429 lookup_symbol_from_elf(
const environment& env,
1431 const string& symbol_name,
1433 vector<elf_symbol_sptr>& syms_found)
1435 size_t hash_table_index = 0, symbol_table_index = 0;
1436 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1439 ht_kind = find_hash_table_section_index(elf_handle,
1441 symbol_table_index);
1443 if (ht_kind == NO_HASH_TABLE_KIND)
1445 if (!find_symbol_table_section_index(elf_handle, symbol_table_index))
1448 return lookup_symbol_from_symtab(env,
1456 return lookup_symbol_from_elf_hash_tab(env,
1480 lookup_public_function_symbol_from_elf(environment& env,
1482 const string& symbol_name,
1483 vector<elf_symbol_sptr>& func_syms)
1485 vector<elf_symbol_sptr> syms_found;
1488 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1491 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1492 i != syms_found.end();
1498 if ((type == elf_symbol::FUNC_TYPE
1499 || type == elf_symbol::GNU_IFUNC_TYPE
1500 || type == elf_symbol::COMMON_TYPE)
1501 && (binding == elf_symbol::GLOBAL_BINDING
1502 || binding == elf_symbol::WEAK_BINDING))
1504 func_syms.push_back(*i);
1525 int64_t const_value_;
1533 expr_result(
bool is_const)
1534 : is_const_(is_const),
1538 explicit expr_result(int64_t v)
1564 const_value(int64_t& value)
1568 value = const_value_;
1584 return const_value_;
1587 operator int64_t()
const
1588 {
return const_value();}
1591 operator=(
const int64_t v)
1599 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1602 operator>=(
const expr_result& o)
const
1603 {
return const_value_ >= o.const_value_;}
1606 operator<=(
const expr_result& o)
const
1607 {
return const_value_ <= o.const_value_;}
1610 operator>(
const expr_result& o)
const
1611 {
return const_value_ > o.const_value_;}
1614 operator<(
const expr_result& o)
const
1615 {
return const_value_ < o.const_value_;}
1620 expr_result r(*
this);
1621 r.const_value_ += v.const_value_;
1622 r.is_const_ = r.is_const_ && v.is_const_;
1627 operator+=(int64_t v)
1634 operator-(
const expr_result& v)
const
1636 expr_result r(*
this);
1637 r.const_value_ -= v.const_value_;
1638 r.is_const_ = r.is_const_ && v.is_const_;
1643 operator%(
const expr_result& v)
const
1645 expr_result r(*
this);
1646 r.const_value_ %= v.const_value_;
1647 r.is_const_ = r.is_const_ && v.is_const();
1652 operator*(
const expr_result& v)
const
1654 expr_result r(*
this);
1655 r.const_value_ *= v.const_value_;
1656 r.is_const_ = r.is_const_ && v.is_const();
1663 expr_result r(*
this);
1664 r.const_value_ |= v.const_value_;
1665 r.is_const_ = r.is_const_ && v.is_const_;
1670 operator^(
const expr_result& v)
const
1672 expr_result r(*
this);
1673 r.const_value_ ^= v.const_value_;
1674 r.is_const_ = r.is_const_ && v.is_const_;
1679 operator>>(
const expr_result& v)
const
1681 expr_result r(*
this);
1682 r.const_value_ = r.const_value_ >> v.const_value_;
1683 r.is_const_ = r.is_const_ && v.is_const_;
1690 expr_result r(*
this);
1691 r.const_value_ = r.const_value_ << v.const_value_;
1692 r.is_const_ = r.is_const_ && v.is_const_;
1699 expr_result r(*
this);
1700 r.const_value_ = ~r.const_value_;
1707 expr_result r(*
this);
1708 r.const_value_ = -r.const_value_;
1715 expr_result r = *
this;
1716 r.const_value_ = std::abs(static_cast<long double>(r.const_value()));
1723 expr_result r(*
this);
1724 r.const_value_ &= o.const_value_;
1725 r.is_const_ = r.is_const_ && o.is_const_;
1730 operator/(
const expr_result& o)
1732 expr_result r(*
this);
1733 r.is_const_ = r.is_const_ && o.is_const_;
1734 return r.const_value() / o.const_value();
1740 class expr_result_stack_type
1742 vector<expr_result> elems_;
1746 expr_result_stack_type()
1747 {elems_.reserve(4);}
1750 operator[](
unsigned i)
1752 unsigned s = elems_.size();
1754 return elems_[s - 1 -i];
1758 operator[](
unsigned i)
const
1759 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1763 {
return elems_.size();}
1765 vector<expr_result>::reverse_iterator
1767 {
return elems_.rbegin();}
1769 const vector<expr_result>::reverse_iterator
1771 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1773 vector<expr_result>::reverse_iterator
1775 {
return elems_.rend();}
1777 const vector<expr_result>::reverse_iterator
1779 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1783 {
return elems_.back();}
1787 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1790 push_front(expr_result e)
1791 {elems_.push_back(e);}
1796 expr_result r = front();
1802 erase(vector<expr_result>::reverse_iterator i)
1803 {elems_.erase(--i.base());}
1811 struct dwarf_expr_eval_context
1814 expr_result_stack_type stack;
1819 dwarf_expr_eval_context()
1823 stack.push_front(expr_result(
true));
1830 stack.push_front(expr_result(
true));
1831 accum = expr_result(
false);
1832 set_tls_addr =
false;
1841 set_tls_address(
bool f)
1850 set_tls_address()
const
1851 {
return set_tls_addr;}
1856 expr_result r = stack.front();
1862 push(
const expr_result& v)
1863 {stack.push_front(v);}
1872 typedef shared_ptr<reader> reader_sptr;
1879 class reader :
public elf_based_reader
1886 template <
typename ContainerType>
1887 class die_source_dependant_container_set
1889 ContainerType primary_debug_info_container_;
1890 ContainerType alt_debug_info_container_;
1891 ContainerType type_unit_container_;
1905 ContainerType *result = 0;
1908 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1909 result = &primary_debug_info_container_;
1911 case ALT_DEBUG_INFO_DIE_SOURCE:
1912 result = &alt_debug_info_container_;
1914 case TYPE_UNIT_DIE_SOURCE:
1915 result = &type_unit_container_;
1917 case NO_DEBUG_INFO_DIE_SOURCE:
1918 case NUMBER_OF_DIE_SOURCES:
1931 const ContainerType&
1934 return const_cast<die_source_dependant_container_set*
>(
this)->
1935 get_container(source);
1949 get_container(
const reader& rdr,
const Dwarf_Die *die)
1951 const die_source source = rdr.get_die_source(die);
1952 return get_container(source);
1965 const ContainerType&
1966 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1968 return const_cast<die_source_dependant_container_set*
>(
this)->
1969 get_container(rdr, die);
1976 primary_debug_info_container_.clear();
1977 alt_debug_info_container_.clear();
1978 type_unit_container_.clear();
1985 unsigned number_of_suppressed_functions = 0;
1986 unsigned number_of_suppressed_variables = 0;
1987 unsigned number_of_allowed_functions = 0;
1988 unsigned number_of_allowed_variables = 0;
1994 number_of_suppressed_functions = 0;
1995 number_of_suppressed_variables = 0;
1996 number_of_allowed_functions = 0;
1997 number_of_allowed_variables = 0;
2001 unsigned short dwarf_version_;
2002 Dwarf_Die* cur_tu_die_;
2003 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
2007 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
2008 decl_die_repr_die_offsets_maps_;
2012 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
2013 type_die_repr_die_offsets_maps_;
2014 mutable die_source_dependant_container_set<die_istring_map_type>
2015 die_qualified_name_maps_;
2016 mutable die_source_dependant_container_set<die_istring_map_type>
2017 die_pretty_repr_maps_;
2018 mutable die_source_dependant_container_set<die_istring_map_type>
2019 die_pretty_type_repr_maps_;
2022 mutable die_source_dependant_container_set<die_artefact_map_type>
2023 decl_die_artefact_maps_;
2026 mutable die_source_dependant_container_set<die_artefact_map_type>
2027 type_die_artefact_maps_;
2030 mutable die_source_dependant_container_set<offset_offset_map_type>
2031 canonical_type_die_offsets_;
2034 mutable die_source_dependant_container_set<offset_offset_map_type>
2035 canonical_decl_die_offsets_;
2038 mutable istring_fn_type_map_type per_tu_repr_to_fn_type_maps_;
2041 mutable std::unordered_map<std::pair<offset_type,offset_type>,
2043 dwarf_offset_pair_hash> die_comparison_results_;
2045 mutable offset_pair_set_type propagated_types_;
2046 die_class_or_union_map_type die_wip_classes_map_;
2047 die_class_or_union_map_type alternate_die_wip_classes_map_;
2048 die_class_or_union_map_type type_unit_die_wip_classes_map_;
2049 die_function_type_map_type die_wip_function_types_map_;
2050 die_function_type_map_type alternate_die_wip_function_types_map_;
2051 die_function_type_map_type type_unit_die_wip_function_types_map_;
2052 die_function_decl_map_type die_function_with_no_symbol_map_;
2053 vector<type_base_sptr> types_to_canonicalize_;
2054 string_classes_or_unions_map decl_only_classes_map_;
2055 string_enums_map decl_only_enums_map_;
2056 die_tu_map_type die_tu_map_;
2059 scope_stack_type scope_stack_;
2060 offset_offset_map_type primary_die_parent_map_;
2070 offset_offset_map_type alternate_die_parent_map_;
2071 offset_offset_map_type type_section_die_parent_map_;
2072 list<var_decl_sptr> var_decls_to_add_;
2073 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2074 bool debug_die_canonicalization_is_on_;
2075 bool use_canonical_die_comparison_;
2077 mutable size_t compare_count_;
2078 mutable size_t canonical_propagated_count_;
2079 mutable size_t cancelled_propagation_count_;
2080 mutable optional<bool> leverage_dwarf_factorization_;
2081 mutable stats stats_;
2116 reader(
const string& elf_path,
2117 const vector<string>& debug_info_root_paths,
2118 environment& environment,
2119 bool load_all_types,
2120 bool linux_kernel_mode)
2121 : elf_based_reader(elf_path,
2122 debug_info_root_paths,
2125 reset(load_all_types, linux_kernel_mode);
2150 reset(
bool load_all_types,
bool linux_kernel_mode)
2154 decl_die_repr_die_offsets_maps_.clear();
2155 type_die_repr_die_offsets_maps_.clear();
2156 die_qualified_name_maps_.clear();
2157 die_pretty_repr_maps_.clear();
2158 die_pretty_type_repr_maps_.clear();
2159 decl_die_artefact_maps_.clear();
2160 type_die_artefact_maps_.clear();
2161 canonical_type_die_offsets_.clear();
2162 canonical_decl_die_offsets_.clear();
2163 die_wip_classes_map_.clear();
2164 alternate_die_wip_classes_map_.clear();
2165 type_unit_die_wip_classes_map_.clear();
2166 die_wip_function_types_map_.clear();
2167 alternate_die_wip_function_types_map_.clear();
2168 type_unit_die_wip_function_types_map_.clear();
2169 die_function_with_no_symbol_map_.clear();
2170 types_to_canonicalize_.clear();
2171 decl_only_classes_map_.clear();
2172 die_tu_map_.clear();
2174 corpus_group().reset();
2176 primary_die_parent_map_.clear();
2177 tu_die_imported_unit_points_map_.clear();
2178 alt_tu_die_imported_unit_points_map_.clear();
2179 type_units_tu_die_imported_unit_points_map_.clear();
2180 alternate_die_parent_map_.clear();
2181 type_section_die_parent_map_.clear();
2182 var_decls_to_add_.clear();
2183 clear_per_translation_unit_data();
2184 clear_per_corpus_data();
2185 options().load_in_linux_kernel_mode = linux_kernel_mode;
2186 options().load_all_types = load_all_types;
2187 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2188 debug_die_canonicalization_is_on_ =
2189 env().debug_die_canonicalization_is_on();
2190 use_canonical_die_comparison_ =
true;
2193 canonical_propagated_count_ = 0;
2194 cancelled_propagation_count_ = 0;
2195 load_in_linux_kernel_mode(linux_kernel_mode);
2218 const vector<string>& debug_info_root_paths,
2219 bool load_all_types,
2220 bool linux_kernel_mode)
2223 reset(load_all_types, linux_kernel_mode);
2243 static dwarf::reader_sptr
2244 create(
const std::string& elf_path,
2245 const vector<string>& debug_info_root_paths,
2246 environment& environment,
2247 bool load_all_types,
2248 bool linux_kernel_mode)
2250 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2251 environment, load_all_types,
2252 linux_kernel_mode));
2269 read_corpus(status& status)
2271 status = STATUS_UNKNOWN;
2276 if (!(status & STATUS_OK))
2280 return corpus_sptr();
2284 if (dwarf_debug_info() ==
nullptr)
2285 status |= STATUS_DEBUG_INFO_NOT_FOUND;
2289 if (refers_to_alt_debug_info(alt_di_path)
2290 && !alternate_dwarf_debug_info())
2291 status |= STATUS_ALT_DEBUG_INFO_NOT_FOUND;
2296 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2297 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2299 return corpus_sptr();
2303 corpus_sptr corp = read_debug_info_into_corpus();
2305 status |= STATUS_OK;
2318 read_debug_info_into_corpus()
2323 origin |= corpus::DWARF_ORIGIN;
2324 corpus()->set_origin(origin);
2327 origin |= corpus_group()->get_origin();
2328 corpus_group()->set_origin(origin);
2331 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2332 && !env().user_set_analyze_exported_interfaces_only())
2339 env().analyze_exported_interfaces_only(
true);
2341 corpus()->set_soname(dt_soname());
2342 corpus()->set_needed(dt_needed());
2343 corpus()->set_architecture_name(elf_architecture());
2345 corpus()->set_symtab(symtab());
2349 if (!dwarf_debug_info()
2350 || !corpus()->get_symtab()
2351 || !corpus()->get_symtab()->has_symbols())
2354 uint8_t address_size = 0;
2355 size_t header_size = 0;
2357 #ifdef WITH_DEBUG_SELF_COMPARISON
2358 if (env().self_comparison_debug_is_on())
2360 corpus_group_sptr g = corpus_group();
2362 env().set_self_comparison_debug_input(g);
2364 env().set_self_comparison_debug_input(corpus());
2368 env().priv_->do_log(do_log());
2373 tools_utils::timer t;
2376 cerr <<
"building die -> parent maps ...";
2380 build_die_parent_maps();
2385 cerr <<
" DONE@" << corpus()->get_path()
2392 env().canonicalization_is_done(
false);
2395 tools_utils::timer t;
2398 cerr <<
"DWARF Reader: building the "
2399 "libabigail internal representation ...\n";
2403 Dwarf_Half dwarf_vers = 0;
2404 for (Dwarf_Off offset = 0, next_offset = 0;
2405 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
2406 offset, &next_offset, &header_size,
2407 &dwarf_vers, NULL, &address_size, NULL,
2409 offset = next_offset)
2411 Dwarf_Off die_offset = offset + header_size;
2413 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
2415 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2418 dwarf_version(dwarf_vers);
2425 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2431 cerr <<
"DWARF Reader: building "
2432 <<
"the libabigail internal representation "
2433 <<
"DONE for corpus " << corpus()->get_path()
2438 cerr <<
"DWARF Reader: Number of aggregate types compared: "
2439 << compare_count_ <<
"\n"
2440 <<
"Number of canonical types propagated: "
2441 << canonical_propagated_count_ <<
"\n"
2442 <<
"Number of cancelled propagated canonical types:"
2443 << cancelled_propagation_count_ <<
"\n"
2444 <<
"Number of suppressed functions: "
2445 << stats_.number_of_suppressed_functions <<
"\n"
2446 <<
"Number of allowed functions: "
2447 << stats_.number_of_allowed_functions <<
"\n"
2448 <<
"Total number of fns in the corpus: "
2449 << corpus()->get_functions().size() <<
"\n"
2450 <<
"Total number of variables in the corpus: "
2451 << corpus()->get_variables().size() <<
"\n";
2456 tools_utils::timer t;
2459 cerr <<
"DWARF Reader: resolving declaration only classes ...";
2462 resolve_declaration_only_classes();
2466 cerr <<
" DONE@" << corpus()->get_path()
2474 tools_utils::timer t;
2477 cerr <<
"resolving declaration only enums ...";
2480 resolve_declaration_only_enums();
2484 cerr <<
" DONE@" << corpus()->get_path()
2492 tools_utils::timer t;
2495 cerr <<
"DWARF Reader: fixing up functions with linkage name but "
2496 <<
"no advertised underlying symbols ....";
2499 fixup_functions_with_no_symbols();
2503 cerr <<
" DONE@" << corpus()->get_path()
2510 merge_member_functions_and_variables_in_classes_of_same_names();
2524 tools_utils::timer t;
2527 cerr <<
"DWARF Reader: perform late type canonicalizing ...\n";
2531 perform_late_type_canonicalizing();
2535 cerr <<
"DWARF Reader: late type canonicalizing DONE for "
2536 << corpus()->get_path()
2543 env().canonicalization_is_done(
true);
2546 tools_utils::timer t;
2549 cerr <<
"DWARF Reader: sort functions and variables ...";
2552 corpus()->sort_functions();
2553 corpus()->sort_variables();
2557 cerr <<
" DONE@" << corpus()->get_path()
2571 clear_per_translation_unit_data()
2573 while (!scope_stack().empty())
2574 scope_stack().pop();
2575 var_decls_to_re_add_to_tree().clear();
2576 per_tu_repr_to_fn_type_maps().clear();
2582 clear_per_corpus_data()
2584 die_qualified_name_maps_.clear();
2585 die_pretty_repr_maps_.clear();
2586 die_pretty_type_repr_maps_.clear();
2587 clear_types_to_canonicalize();
2595 {
return options().env;}
2602 {
return const_cast<reader*
>(
this)->env();}
2610 drop_undefined_syms()
const
2611 {
return options().drop_undefined_syms;}
2618 drop_undefined_syms(
bool f)
2619 {options().drop_undefined_syms = f;}
2623 dwarf_version()
const
2624 {
return dwarf_version_;}
2627 dwarf_version(
unsigned short v)
2628 {dwarf_version_ = v;}
2640 dwarf_elf_handle()
const
2641 {
return dwarf_getelf(const_cast<Dwarf*>(dwarf_debug_info()));}
2651 dwarf_is_splitted()
const
2652 {
return dwarf_elf_handle() != elf_handle();}
2661 dwarf_per_die_source(
die_source source)
const
2663 const Dwarf *result = 0;
2666 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2667 case TYPE_UNIT_DIE_SOURCE:
2668 result = dwarf_debug_info();
2670 case ALT_DEBUG_INFO_DIE_SOURCE:
2671 result = alternate_dwarf_debug_info();
2673 case NO_DEBUG_INFO_DIE_SOURCE:
2674 case NUMBER_OF_DIE_SOURCES:
2685 {
return corpus_path();}
2689 {
return cur_tu_die_;}
2692 cur_tu_die(Dwarf_Die* cur_tu_die)
2693 {cur_tu_die_ = cur_tu_die;}
2695 dwarf_expr_eval_context&
2696 dwarf_expr_eval_ctxt()
const
2697 {
return dwarf_expr_eval_context_;}
2704 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2705 decl_die_repr_die_offsets_maps()
const
2706 {
return decl_die_repr_die_offsets_maps_;}
2713 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2714 decl_die_repr_die_offsets_maps()
2715 {
return decl_die_repr_die_offsets_maps_;}
2722 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2723 type_die_repr_die_offsets_maps()
const
2724 {
return type_die_repr_die_offsets_maps_;}
2731 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2732 type_die_repr_die_offsets_maps()
2733 {
return type_die_repr_die_offsets_maps_;}
2746 compute_canonical_die_offset(
const Dwarf_Die *die,
2747 Dwarf_Off &canonical_die_offset,
2748 bool die_as_type)
const
2750 offset_offset_map_type &canonical_dies =
2752 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2753 get_container(*
this, die)
2754 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2755 get_container(*
this, die);
2757 Dwarf_Die canonical_die;
2758 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2760 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2778 compute_canonical_die(
const Dwarf_Die *die,
2779 offset_offset_map_type& canonical_dies,
2780 Dwarf_Die &canonical_die,
2781 bool die_as_type)
const
2783 const die_source source = get_die_source(die);
2785 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2787 compute_canonical_die(die_offset, source,
2789 canonical_die, die_as_type);
2809 compute_canonical_die(Dwarf_Off die_offset,
2811 offset_offset_map_type& canonical_dies,
2812 Dwarf_Die &canonical_die,
2813 bool die_as_type)
const
2819 ? (
const_cast<reader*
>(
this)->
2820 type_die_repr_die_offsets_maps().get_container(source))
2821 : (const_cast<reader*>(
this)->
2822 decl_die_repr_die_offsets_maps().get_container(source));
2825 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2834 interned_string name =
2836 ? get_die_pretty_type_representation(&die, 0)
2837 : get_die_pretty_representation(&die, 0);
2839 Dwarf_Off canonical_die_offset = 0;
2840 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2843 dwarf_offsets_type offsets;
2844 offsets.push_back(die_offset);
2845 map[name] = offsets;
2846 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2847 get_die_from_offset(source, die_offset, &canonical_die);
2851 Dwarf_Off cur_die_offset;
2852 Dwarf_Die potential_canonical_die;
2853 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2854 o != i->second.end();
2857 cur_die_offset = *o;
2858 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2859 if (compare_dies(*
this, &die, &potential_canonical_die,
2862 canonical_die_offset = cur_die_offset;
2863 set_canonical_die_offset(canonical_dies, die_offset,
2864 canonical_die_offset);
2865 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2870 canonical_die_offset = die_offset;
2871 i->second.push_back(die_offset);
2872 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2873 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2892 get_canonical_die(
const Dwarf_Die *die,
2893 Dwarf_Die &canonical_die,
2897 const die_source source = get_die_source(die);
2899 offset_offset_map_type &canonical_dies =
2901 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2902 get_container(source)
2903 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2904 get_container(source);
2906 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2907 if (Dwarf_Off canonical_die_offset =
2908 get_canonical_die_offset(canonical_dies, die_offset))
2910 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2918 ? (
const_cast<reader*
>(
this)->
2919 type_die_repr_die_offsets_maps().get_container(*
this, die))
2920 : (const_cast<reader*>(
this)->
2921 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2929 interned_string name =
2931 ? get_die_pretty_type_representation(die, where)
2932 : get_die_pretty_representation(die, where);
2934 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2938 Dwarf_Off cur_die_offset;
2939 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2940 o != i->second.end();
2943 cur_die_offset = *o;
2944 get_die_from_offset(source, cur_die_offset, &canonical_die);
2946 if (compare_dies_during_canonicalization(const_cast<reader&>(*
this),
2947 die, &canonical_die,
2950 set_canonical_die_offset(canonical_dies,
2984 get_or_compute_canonical_die(
const Dwarf_Die* die,
2985 Dwarf_Die& canonical_die,
2987 bool die_as_type)
const
2989 const die_source source = get_die_source(die);
2991 offset_offset_map_type &canonical_dies =
2993 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2994 get_container(source)
2995 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2996 get_container(source);
2998 Dwarf_Off initial_die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3000 if (Dwarf_Off canonical_die_offset =
3001 get_canonical_die_offset(canonical_dies,
3002 initial_die_offset))
3004 get_die_from_offset(source, canonical_die_offset, &canonical_die);
3008 if (!is_type_die_to_be_canonicalized(die))
3015 ? (
const_cast<reader*
>(
this)->
3016 type_die_repr_die_offsets_maps().get_container(*
this, die))
3017 : (const_cast<reader*>(
this)->
3018 decl_die_repr_die_offsets_maps().get_container(*
this, die));
3026 interned_string name =
3028 ? get_die_pretty_type_representation(die, where)
3029 : get_die_pretty_representation(die, where);
3031 istring_dwarf_offsets_map_type::iterator i = map.find(name);
3034 dwarf_offsets_type offsets;
3035 offsets.push_back(initial_die_offset);
3036 map[name] = offsets;
3037 get_die_from_offset(source, initial_die_offset, &canonical_die);
3038 set_canonical_die_offset(canonical_dies,
3040 initial_die_offset);
3047 dwarf_offsets_type::size_type n = 0, s = i->second.size();
3050 Dwarf_Off die_offset = i->second[n];
3051 get_die_from_offset(source, die_offset, &canonical_die);
3053 if (compare_dies_during_canonicalization(const_cast<reader&>(*
this),
3054 die, &canonical_die,
3057 set_canonical_die_offset(canonical_dies,
3067 get_die_from_offset(source, initial_die_offset, &canonical_die);
3068 i->second.push_back(initial_die_offset);
3069 set_canonical_die_offset(canonical_dies,
3071 initial_die_offset);
3088 get_die_source(
const Dwarf_Die *die)
const
3090 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
3111 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
3115 uint8_t address_size = 0, offset_size = 0;
3116 if (!dwarf_diecu(const_cast<Dwarf_Die*>(&die),
3117 &cu_die, &address_size,
3121 Dwarf_Half version = 0;
3122 Dwarf_Off abbrev_offset = 0;
3123 uint64_t type_signature = 0;
3124 Dwarf_Off type_offset = 0;
3125 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
3126 &version, &abbrev_offset,
3127 &address_size, &offset_size,
3128 &type_signature, &type_offset))
3131 int tag = dwarf_tag(&cu_kind);
3133 if (tag == DW_TAG_compile_unit
3134 || tag == DW_TAG_partial_unit)
3136 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
3137 if (dwarf_debug_info() == die_dwarf)
3138 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
3139 else if (alternate_dwarf_debug_info() == die_dwarf)
3140 source = ALT_DEBUG_INFO_DIE_SOURCE;
3144 else if (tag == DW_TAG_type_unit)
3145 source = TYPE_UNIT_DIE_SOURCE;
3161 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
3163 if (source == TYPE_UNIT_DIE_SOURCE)
3164 ABG_ASSERT(dwarf_offdie_types(const_cast<Dwarf*>(dwarf_per_die_source(source)),
3167 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
3194 associate_die_to_decl(Dwarf_Die* die,
3195 decl_base_sptr decl,
3196 size_t where_offset,
3197 bool do_associate_by_repr =
false)
3199 const die_source source = get_die_source(die);
3201 die_artefact_map_type& m =
3202 decl_die_artefact_maps().get_container(source);
3205 if (do_associate_by_repr)
3207 Dwarf_Die equiv_die;
3208 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
3211 die_offset = dwarf_dieoffset(&equiv_die);
3214 die_offset = dwarf_dieoffset(die);
3216 m[die_offset] = decl;
3238 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3240 decl_base_sptr result =
3241 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3266 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset,
3267 unordered_set<uint64_t>& guard)
const
3270 die_istring_map_type& map =
3271 die_qualified_name_maps_.get_container(*
this, die);
3273 size_t die_offset = dwarf_dieoffset(die);
3274 die_istring_map_type::const_iterator i = map.find(die_offset);
3278 reader& rdr = *
const_cast<reader*
>(
this);
3279 string qualified_name = die_qualified_name(rdr, die,
3282 interned_string istr = env().intern(qualified_name);
3283 map[die_offset] = istr;
3314 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset,
3315 unordered_set<uint64_t>& guard)
const
3320 if (die == cur_tu_die())
3321 return env().intern(
"");
3323 die_istring_map_type& map =
3324 die_qualified_name_maps_.get_container(*const_cast<reader*>(
this),
3327 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3328 die_istring_map_type::const_iterator i =
3329 map.find(die_offset);
3333 reader& rdr = *
const_cast<reader*
>(
this);
3334 string qualified_name;
3335 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
3336 if ((tag == DW_TAG_structure_type
3337 || tag == DW_TAG_class_type
3338 || tag == DW_TAG_union_type)
3339 && die_is_anonymous(die))
3341 die_class_or_enum_flat_representation(*
this, die,
"",
3347 qualified_name = die_qualified_type_name(rdr, die,
3351 interned_string istr = env().intern(qualified_name);
3352 map[die_offset] = istr;
3382 get_die_pretty_type_representation(
const Dwarf_Die *die,
3383 size_t where_offset,
3384 unordered_set<uint64_t>& guard)
const
3387 die_istring_map_type& map =
3388 die_pretty_type_repr_maps_.get_container(*const_cast<reader*>(
this),
3391 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3392 die_istring_map_type::const_iterator i = map.find(die_offset);
3396 reader& rdr = *
const_cast<reader*
>(
this);
3397 string pretty_representation =
3398 die_pretty_print_type(rdr, die, where_offset, guard);
3399 interned_string istr = env().intern(pretty_representation);
3400 map[die_offset] = istr;
3425 get_die_pretty_type_representation(
const Dwarf_Die *die,
3426 size_t where_offset)
const
3428 unordered_set<uint64_t> guard;
3429 return get_die_pretty_type_representation(die, where_offset, guard);
3451 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset,
3452 unordered_set<uint64_t>& guard)
const
3456 die_istring_map_type& map =
3457 die_pretty_repr_maps_.get_container(*const_cast<reader*>(
this),
3460 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3461 die_istring_map_type::const_iterator i = map.find(die_offset);
3465 reader& rdr = *
const_cast<reader*
>(
this);
3466 string pretty_representation =
3467 die_pretty_print(rdr, die, where_offset, guard);
3468 interned_string istr = env().intern(pretty_representation);
3469 map[die_offset] = istr;
3489 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3491 unordered_set<uint64_t> guard;
3492 return get_die_pretty_representation(die, where_offset, guard);
3512 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3515 lookup_artifact_from_die(die,
true);
3517 return fn->get_type();
3541 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3543 Dwarf_Die equiv_die;
3544 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3547 const die_artefact_map_type& m =
3549 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3550 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3552 size_t die_offset = dwarf_dieoffset(&equiv_die);
3553 die_artefact_map_type::const_iterator i = m.find(die_offset);
3580 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3582 bool die_as_type =
false)
const
3584 const die_artefact_map_type& m =
3586 ? type_die_artefact_maps().get_container(source)
3587 : decl_die_artefact_maps().get_container(source);
3589 die_artefact_map_type::const_iterator i = m.find(die_offset);
3632 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
3647 if (!get_die_language(die, lang))
3658 die_source_dependant_container_set<die_artefact_map_type>&
3659 decl_die_artefact_maps()
3660 {
return decl_die_artefact_maps_;}
3667 const die_source_dependant_container_set<die_artefact_map_type>&
3668 decl_die_artefact_maps()
const
3669 {
return decl_die_artefact_maps_;}
3676 die_source_dependant_container_set<die_artefact_map_type>&
3677 type_die_artefact_maps()
3678 {
return type_die_artefact_maps_;}
3685 const die_source_dependant_container_set<die_artefact_map_type>&
3686 type_die_artefact_maps()
const
3687 {
return type_die_artefact_maps_;}
3694 istring_fn_type_map_type&
3695 per_tu_repr_to_fn_type_maps()
3696 {
return per_tu_repr_to_fn_type_maps_;}
3703 const istring_fn_type_map_type&
3704 per_tu_repr_to_fn_type_maps()
const
3705 {
return per_tu_repr_to_fn_type_maps_;}
3715 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3716 const function_type_sptr &fn_type)
3718 if (!die_is_function_type(die))
3721 interned_string repr =
3722 get_die_pretty_type_representation(die, 0);
3725 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3736 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3738 if (!die_is_function_type(die))
3741 interned_string repr = die_name(die).empty() ?
3742 get_die_pretty_type_representation(die, 0)
3743 : get_die_pretty_representation(die, 0);
3746 istring_fn_type_map_type::const_iterator i =
3747 per_tu_repr_to_fn_type_maps().find(repr);
3749 if (i == per_tu_repr_to_fn_type_maps().end())
3765 set_canonical_die_offset(offset_offset_map_type &canonical_dies,
3766 Dwarf_Off die_offset,
3767 Dwarf_Off canonical_die_offset)
const
3769 canonical_dies[die_offset] = canonical_die_offset;}
3785 set_canonical_die_offset(Dwarf_Off die_offset,
3787 Dwarf_Off canonical_die_offset,
3788 bool die_as_type)
const
3790 offset_offset_map_type &canonical_dies =
3792 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3793 get_container(source)
3794 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3795 get_container(source);
3797 set_canonical_die_offset(canonical_dies,
3799 canonical_die_offset);
3813 set_canonical_die_offset(
const Dwarf_Die *die,
3814 Dwarf_Off canonical_die_offset,
3815 bool die_as_type)
const
3817 const die_source source = get_die_source(die);
3819 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3821 set_canonical_die_offset(die_offset, source,
3822 canonical_die_offset,
3835 get_canonical_die_offset(offset_offset_map_type &canonical_dies,
3836 Dwarf_Off die_offset)
const
3838 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3839 if (it == canonical_dies.end())
3856 get_canonical_die_offset(Dwarf_Off die_offset,
3858 bool die_as_type)
const
3860 offset_offset_map_type &canonical_dies =
3862 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3863 get_container(source)
3864 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3865 get_container(source);
3867 return get_canonical_die_offset(canonical_dies, die_offset);
3882 erase_canonical_die_offset(Dwarf_Off die_offset,
3884 bool die_as_type)
const
3886 offset_offset_map_type &canonical_dies =
3888 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3889 get_container(source)
3890 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3891 get_container(source);
3893 return canonical_dies.erase(die_offset);
3906 associate_die_to_type(
const Dwarf_Die *die,
3907 type_base_sptr type,
3913 Dwarf_Die equiv_die;
3914 if (!get_or_compute_canonical_die(die, equiv_die, where,
3918 die_artefact_map_type& m =
3919 type_die_artefact_maps().get_container(*
this, &equiv_die);
3921 size_t die_offset = dwarf_dieoffset(&equiv_die);
3922 m[die_offset] = type;
3936 lookup_type_from_die(
const Dwarf_Die* die)
const
3939 lookup_artifact_from_die(die,
true);
3941 return fn->get_type();
3959 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3961 type_base_sptr result;
3962 const die_artefact_map_type& m =
3963 type_die_artefact_maps().get_container(source);
3964 die_artefact_map_type::const_iterator i = m.find(die_offset);
3968 return fn->get_type();
3975 const die_class_or_union_map_type& m = die_wip_classes_map(source);
3976 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3985 const die_function_type_map_type& m =
3986 die_wip_function_types_map(source);
3987 die_function_type_map_type::const_iterator i = m.find(die_offset);
4004 const die_class_or_union_map_type&
4006 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
4016 die_class_or_union_map_type&
4021 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4023 case ALT_DEBUG_INFO_DIE_SOURCE:
4024 return alternate_die_wip_classes_map_;
4025 case TYPE_UNIT_DIE_SOURCE:
4026 return type_unit_die_wip_classes_map_;
4027 case NO_DEBUG_INFO_DIE_SOURCE:
4028 case NUMBER_OF_DIE_SOURCES:
4031 return die_wip_classes_map_;
4041 const die_function_type_map_type&
4042 die_wip_function_types_map(
die_source source)
const
4043 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
4052 die_function_type_map_type&
4053 die_wip_function_types_map(
die_source source)
4057 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4059 case ALT_DEBUG_INFO_DIE_SOURCE:
4060 return alternate_die_wip_function_types_map_;
4061 case TYPE_UNIT_DIE_SOURCE:
4062 return type_unit_die_wip_function_types_map_;
4063 case NO_DEBUG_INFO_DIE_SOURCE:
4064 case NUMBER_OF_DIE_SOURCES:
4067 return die_wip_function_types_map_;
4077 die_function_decl_map_type&
4078 die_function_decl_with_no_symbol_map()
4079 {
return die_function_with_no_symbol_map_;}
4092 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
4094 die_class_or_union_map_type::const_iterator i =
4095 die_wip_classes_map(source).find(offset);
4096 return (i != die_wip_classes_map(source).end());
4110 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
4112 die_function_type_map_type::const_iterator i =
4113 die_wip_function_types_map(source).find(offset);
4114 return (i != die_wip_function_types_map(source).end());
4133 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
4139 || dwarf_tag(die) != DW_TAG_member
4140 || !die_name(die).empty())
4146 if (die_is_anonymous_data_member(die))
4152 int64_t offset_in_bits = 0;
4153 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
4157 loc = die_location(*
this, die);
4162 std::ostringstream o;
4163 o <<
"unnamed-dm-@-";
4165 o <<
"offset-" << offset_in_bits <<
"bits";
4167 o <<
"loc-" << loc.expand();
4179 const string_classes_or_unions_map&
4180 declaration_only_classes()
const
4181 {
return decl_only_classes_map_;}
4190 string_classes_or_unions_map&
4191 declaration_only_classes()
4192 {
return decl_only_classes_map_;}
4204 maybe_schedule_declaration_only_class_for_resolution(cou);
4206 maybe_schedule_declaration_only_enum_for_resolution(e);
4215 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
4217 if (cou->get_is_declaration_only()
4218 && cou->get_definition_of_declaration() == 0
4223 && !cou->get_qualified_name().empty())
4225 string qn = cou->get_qualified_name();
4226 string_classes_or_unions_map::iterator record =
4227 declaration_only_classes().find(qn);
4228 if (record == declaration_only_classes().end())
4229 declaration_only_classes()[qn].push_back(cou);
4231 record->second.push_back(cou);
4243 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4245 if (cou->get_is_declaration_only())
4246 return ((declaration_only_classes().find(cou->get_qualified_name())
4247 != declaration_only_classes().end())
4248 || (declaration_only_classes().find(cou->get_name())
4249 != declaration_only_classes().end()));
4272 const environment& e = l->get_environment();
4276 && l->
kind() == r->kind()
4277 && ((l->get_corpus() && r->get_corpus()
4278 && (l->get_corpus() == r->get_corpus()))
4279 ||(l->get_translation_unit()
4280 && r->get_translation_unit()
4281 && l->get_translation_unit() == r->get_translation_unit())))
4290 decl_base *ld =
is_decl(l.get());
4291 decl_base *rd =
is_decl(r.get());
4293 if (ld->get_qualified_name() != rd->get_qualified_name())
4296 location ll = ld->get_location(), rl = rd->get_location();
4299 string l1 = ll.expand();
4300 string l2 = rl.expand();
4306 e.priv_->allow_type_comparison_results_caching(
true);
4307 bool s0 = e.decl_only_class_equals_definition();
4308 e.decl_only_class_equals_definition(
true);
4309 bool equal = l == r;
4310 e.decl_only_class_equals_definition(s0);
4311 e.priv_->clear_type_comparison_results_cache();
4312 e.priv_->allow_type_comparison_results_caching(
false);
4319 resolve_declaration_only_classes()
4321 vector<string> resolved_classes;
4323 for (string_classes_or_unions_map::iterator i =
4324 declaration_only_classes().begin();
4325 i != declaration_only_classes().end();
4328 bool to_resolve =
false;
4329 for (classes_or_unions_type::iterator j = i->second.begin();
4330 j != i->second.end();
4332 if ((*j)->get_is_declaration_only()
4333 && ((*j)->get_definition_of_declaration() == 0))
4338 resolved_classes.push_back(i->first);
4383 map<string, class_or_union_sptr> per_tu_class_map;
4384 for (type_base_wptrs_type::const_iterator c = classes->begin();
4385 c != classes->end();
4392 if (klass->get_is_declaration_only())
4395 string tu_path = klass->get_translation_unit()->get_absolute_path();
4396 if (tu_path.empty())
4402 per_tu_class_map[tu_path] = klass;
4405 if (!per_tu_class_map.empty())
4411 for (classes_or_unions_type::iterator j = i->second.begin();
4412 j != i->second.end();
4415 if ((*j)->get_is_declaration_only()
4416 && ((*j)->get_definition_of_declaration() == 0))
4419 (*j)->get_translation_unit()->get_absolute_path();
4420 map<string, class_or_union_sptr>::const_iterator e =
4421 per_tu_class_map.find(tu_path);
4422 if (e != per_tu_class_map.end())
4423 (*j)->set_definition_of_declaration(e->second);
4424 else if (per_tu_class_map.size() == 1)
4425 (*j)->set_definition_of_declaration
4426 (per_tu_class_map.begin()->second);
4436 class_or_union_sptr>::const_iterator it;
4437 class_or_union_sptr first_class =
4438 per_tu_class_map.begin()->second;
4439 bool all_class_definitions_are_equal =
true;
4440 for (it = per_tu_class_map.begin();
4441 it != per_tu_class_map.end();
4444 if (it == per_tu_class_map.begin())
4448 if (!compare_before_canonicalisation(it->second,
4451 all_class_definitions_are_equal =
false;
4456 if (all_class_definitions_are_equal)
4457 (*j)->set_definition_of_declaration(first_class);
4461 resolved_classes.push_back(i->first);
4465 size_t num_decl_only_classes = declaration_only_classes().size(),
4466 num_resolved = resolved_classes.size();
4468 cerr <<
"resolved " << num_resolved
4469 <<
" class declarations out of "
4470 << num_decl_only_classes
4473 for (vector<string>::const_iterator i = resolved_classes.begin();
4474 i != resolved_classes.end();
4476 declaration_only_classes().erase(*i);
4478 if (show_stats() && !declaration_only_classes().empty())
4480 cerr <<
"Here are the "
4481 << num_decl_only_classes - num_resolved
4482 <<
" unresolved class declarations:\n";
4483 for (string_classes_or_unions_map::iterator i =
4484 declaration_only_classes().begin();
4485 i != declaration_only_classes().end();
4487 cerr <<
" " << i->first <<
"\n";
4498 const string_enums_map&
4499 declaration_only_enums()
const
4500 {
return decl_only_enums_map_;}
4510 declaration_only_enums()
4511 {
return decl_only_enums_map_;}
4521 if (enom->get_is_declaration_only()
4522 && enom->get_definition_of_declaration() == 0
4527 && !enom->get_qualified_name().empty())
4529 string qn = enom->get_qualified_name();
4530 string_enums_map::iterator record =
4531 declaration_only_enums().find(qn);
4532 if (record == declaration_only_enums().end())
4533 declaration_only_enums()[qn].push_back(enom);
4535 record->second.push_back(enom);
4549 if (enom->get_is_declaration_only())
4550 return (declaration_only_enums().find(enom->get_qualified_name())
4551 != declaration_only_enums().end());
4564 resolve_declaration_only_enums()
4566 vector<string> resolved_enums;
4568 for (string_enums_map::iterator i =
4569 declaration_only_enums().begin();
4570 i != declaration_only_enums().end();
4573 bool to_resolve =
false;
4574 for (enums_type::iterator j = i->second.begin();
4575 j != i->second.end();
4577 if ((*j)->get_is_declaration_only()
4578 && ((*j)->get_definition_of_declaration() == 0))
4583 resolved_enums.push_back(i->first);
4625 map<string, enum_type_decl_sptr> per_tu_enum_map;
4626 for (type_base_wptrs_type::const_iterator c = enums->begin();
4634 if (enom->get_is_declaration_only())
4637 string tu_path = enom->get_translation_unit()->get_absolute_path();
4638 if (tu_path.empty())
4644 per_tu_enum_map[tu_path] = enom;
4647 if (!per_tu_enum_map.empty())
4653 for (enums_type::iterator j = i->second.begin();
4654 j != i->second.end();
4657 if ((*j)->get_is_declaration_only()
4658 && ((*j)->get_definition_of_declaration() == 0))
4661 (*j)->get_translation_unit()->get_absolute_path();
4662 map<string, enum_type_decl_sptr>::const_iterator e =
4663 per_tu_enum_map.find(tu_path);
4664 if (e != per_tu_enum_map.end())
4665 (*j)->set_definition_of_declaration(e->second);
4666 else if (per_tu_enum_map.size() == 1)
4667 (*j)->set_definition_of_declaration
4668 (per_tu_enum_map.begin()->second);
4680 per_tu_enum_map.begin()->second;
4681 bool all_enum_definitions_are_equal =
true;
4682 for (it = per_tu_enum_map.begin();
4683 it != per_tu_enum_map.end();
4686 if (it == per_tu_enum_map.begin())
4690 if (!compare_before_canonicalisation(it->second,
4693 all_enum_definitions_are_equal =
false;
4698 if (all_enum_definitions_are_equal)
4699 (*j)->set_definition_of_declaration(first_enum);
4703 resolved_enums.push_back(i->first);
4707 size_t num_decl_only_enums = declaration_only_enums().size(),
4708 num_resolved = resolved_enums.size();
4710 cerr <<
"resolved " << num_resolved
4711 <<
" enum declarations out of "
4712 << num_decl_only_enums
4715 for (vector<string>::const_iterator i = resolved_enums.begin();
4716 i != resolved_enums.end();
4718 declaration_only_enums().erase(*i);
4720 if (show_stats() && !declaration_only_enums().empty())
4722 cerr <<
"Here are the "
4723 << num_decl_only_enums - num_resolved
4724 <<
" unresolved enum declarations:\n";
4725 for (string_enums_map::iterator i = declaration_only_enums().begin();
4726 i != declaration_only_enums().end();
4728 cerr <<
" " << i->first <<
"\n";
4744 corpus_sptr corp = corpus();
4748 interned_string
id = corp->get_environment().intern(fn->get_id_string());
4750 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4755 if (f->get_symbol())
4775 fixup_functions_with_no_symbols()
4777 corpus_sptr corp = corpus();
4781 die_function_decl_map_type &fns_with_no_symbol =
4782 die_function_decl_with_no_symbol_map();
4785 cerr << fns_with_no_symbol.size()
4786 <<
" functions to fixup, potentially\n";
4788 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4789 i != fns_with_no_symbol.end();
4792 corp->lookup_function_symbol(i->second->get_linkage_name()))
4807 if (i->second->get_symbol()
4808 || symbol_already_belongs_to_a_function(sym))
4813 i->second->set_symbol(sym);
4816 cerr <<
"fixed up '"
4817 << i->second->get_pretty_representation()
4818 <<
"' with symbol '"
4819 << sym->get_id_string()
4823 fns_with_no_symbol.clear();
4836 for (
auto method : src_class->get_member_functions())
4837 if (!method->get_linkage_name().empty())
4838 if (!dest_class->find_member_function(method->get_linkage_name()))
4840 method_decl_sptr copied_method =
4843 schedule_type_for_late_canonicalization(copied_method->get_type());
4863 for (
auto var : src_class->get_data_members())
4864 if (!var->get_name().empty())
4865 if (!dest_class->find_data_member(var->get_name()))
4880 template <
typename iterator_type>
4882 contains_anonymous_class(
const iterator_type& begin,
4883 const iterator_type& end)
4885 for (
auto i = begin; i < end; ++i)
4887 type_base_sptr t(*i);
4889 if (c && c->get_is_anonymous())
4905 template <
typename iterator_type>
4907 merge_member_functions_of_classes(
const iterator_type& begin,
4908 const iterator_type& end)
4910 if (contains_anonymous_class(begin, end))
4913 for (
auto i = begin; i < end; ++i)
4915 type_base_sptr t(*i);
4917 if (!reference_class)
4920 string n1 = reference_class->get_pretty_representation(
true,
true);
4922 for (
auto j = begin; j < end; ++j)
4927 type_base_sptr type(*j);
4932 n2 = klass->get_pretty_representation(
true,
true);
4936 copy_missing_member_functions(reference_class, klass);
4937 copy_missing_member_functions(klass, reference_class);
4953 template <
typename iterator_type>
4955 merge_member_variables_of_classes(
const iterator_type& begin,
4956 const iterator_type& end)
4958 if (contains_anonymous_class(begin, end))
4961 for (
auto i = begin; i < end; ++i)
4963 type_base_sptr t(*i);
4965 if (!reference_class)
4968 string n1 = reference_class->get_pretty_representation(
true,
true);
4970 for (
auto j = begin; j < end; ++j)
4975 type_base_sptr type(*j);
4980 n2 = klass->get_pretty_representation(
true,
true);
4984 copy_missing_member_variables(reference_class, klass);
4985 copy_missing_member_variables(klass, reference_class);
4994 merge_member_functions_and_variables_in_classes_of_same_names()
4996 corpus_sptr abi = corpus();
5001 abi->get_types().class_types();
5003 for (
auto entry : class_types)
5005 auto& classes = entry.second;
5006 type_base_sptr first(classes.front());
5010 bool a_class_has_member_fns =
false;
5011 bool a_class_has_member_vars =
false;
5012 for (
auto& c : classes)
5014 type_base_sptr t(c);
5017 if (!klass->get_member_functions().empty())
5018 a_class_has_member_fns =
true;
5020 if (!klass->get_static_data_members().empty())
5021 a_class_has_member_vars =
true;
5024 if (a_class_has_member_fns)
5025 merge_member_functions_of_classes(classes.begin(),
5027 if (a_class_has_member_vars)
5028 merge_member_variables_of_classes(classes.begin(),
5036 const vector<type_base_sptr>&
5037 types_to_canonicalize()
const
5038 {
return types_to_canonicalize_;}
5042 vector<type_base_sptr>&
5043 types_to_canonicalize()
5044 {
return types_to_canonicalize_;}
5048 clear_types_to_canonicalize()
5050 types_to_canonicalize_.clear();
5058 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
5060 types_to_canonicalize_.push_back(t);
5070 canonicalize_types_scheduled()
5072 tools_utils::timer cn_timer;
5075 cerr <<
"DWARF Reader is going to canonicalize "
5077 << types_to_canonicalize().size()
5079 corpus_sptr c = corpus();
5081 cerr <<
" from corpus " << corpus()->get_path() <<
"\n";
5086 (types_to_canonicalize().begin(),
5087 types_to_canonicalize().end(),
5088 [](
const vector<type_base_sptr>::const_iterator& i)
5089 {
return *i;}, do_log(), show_stats());
5094 cerr <<
"DWARF Reader finished types "
5095 <<
"sorting, hashing & canonicalizing in: "
5096 << cn_timer <<
"\n";
5113 add_late_canonicalized_types_stats(
size_t& canonicalized,
5114 size_t& missed)
const
5116 for (
auto t : types_to_canonicalize())
5118 if (t->get_canonical_type())
5128 perform_late_type_canonicalizing()
5130 canonicalize_types_scheduled();
5134 size_t num_canonicalized = 0, num_missed = 0, total = 0;
5135 add_late_canonicalized_types_stats(num_canonicalized,
5137 total = num_canonicalized + num_missed;
5141 cerr <<
" # late canonicalized types: "
5142 << num_canonicalized;
5144 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
5146 <<
" # missed canonicalization opportunities: "
5149 cerr <<
" (" << num_missed * 100 / total <<
"%)";
5155 const die_tu_map_type&
5157 {
return die_tu_map_;}
5161 {
return die_tu_map_;}
5170 tu_die_imported_unit_points_map(
die_source source)
const
5171 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
5180 tu_die_imported_unit_points_map(
die_source source)
5184 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
5186 case ALT_DEBUG_INFO_DIE_SOURCE:
5187 return alt_tu_die_imported_unit_points_map_;
5188 case TYPE_UNIT_DIE_SOURCE:
5189 return type_units_tu_die_imported_unit_points_map_;
5190 case NO_DEBUG_INFO_DIE_SOURCE:
5191 case NUMBER_OF_DIE_SOURCES:
5195 return tu_die_imported_unit_points_map_;
5211 const offset_offset_map_type&
5213 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
5221 offset_offset_map_type&
5226 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
5228 case ALT_DEBUG_INFO_DIE_SOURCE:
5229 return alternate_die_parent_map_;
5230 case TYPE_UNIT_DIE_SOURCE:
5231 return type_section_die_parent_map();
5232 case NO_DEBUG_INFO_DIE_SOURCE:
5233 case NUMBER_OF_DIE_SOURCES:
5236 return primary_die_parent_map_;
5239 const offset_offset_map_type&
5240 type_section_die_parent_map()
const
5241 {
return type_section_die_parent_map_;}
5243 offset_offset_map_type&
5244 type_section_die_parent_map()
5245 {
return type_section_die_parent_map_;}
5251 cur_transl_unit()
const
5275 global_scope()
const
5276 {
return cur_transl_unit()->get_global_scope();}
5283 {
return nil_scope_;}
5285 const scope_stack_type&
5287 {
return scope_stack_;}
5291 {
return scope_stack_;}
5296 if (scope_stack().empty())
5298 if (cur_transl_unit())
5301 return scope_stack().top();
5304 list<var_decl_sptr>&
5305 var_decls_to_re_add_to_tree()
5306 {
return var_decls_to_add_;}
5319 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
const
5321 if (!die || !die_is_decl(die))
5324 bool result =
false, address_found =
false, symbol_is_exported =
false;;
5325 Dwarf_Addr decl_symbol_address = 0;
5327 if (die_is_variable_decl(die))
5329 if ((address_found = get_variable_address(die, decl_symbol_address)))
5330 symbol_is_exported =
5331 !!variable_symbol_is_exported(decl_symbol_address);
5333 else if (die_is_function_decl(die))
5335 if ((address_found = get_function_address(die, decl_symbol_address)))
5336 symbol_is_exported =
5337 !!function_symbol_is_exported(decl_symbol_address);
5341 result = symbol_is_exported;
5352 is_decl_die_with_undefined_symbol(
const Dwarf_Die *die)
const
5354 if (is_decl_die_with_exported_symbol(die))
5357 string name, linkage_name;
5358 die_name_and_linkage_name(die, name, linkage_name);
5359 if (linkage_name.empty())
5360 linkage_name = name;
5362 bool result =
false;
5363 if ((die_is_variable_decl(die)
5364 && symtab()->variable_symbol_is_undefined(linkage_name))
5366 (die_is_function_decl(die)
5367 && symtab()->function_symbol_is_undefined(linkage_name)))
5387 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
5393 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
5395 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
5397 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
5398 ABG_ASSERT(get_binary_load_address(dwarf_elf_handle(),
5399 dwarf_elf_load_address));
5400 ABG_ASSERT(get_binary_load_address(elf_handle(),
5402 if (dwarf_is_splitted()
5403 && (dwarf_elf_load_address != elf_load_address))
5414 addr = addr - dwarf_elf_load_address + elf_load_address;
5440 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
5445 Elf* elf = elf_handle();
5447 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5449 if (elf_header->e_type == ET_REL)
5462 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5487 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
5489 Elf* elf = elf_handle();
5491 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5493 if (elf_header->e_type == ET_REL)
5506 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5525 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5526 Dwarf_Addr& address)
const
5529 Dwarf_Addr end_addr;
5530 ptrdiff_t offset = 0;
5534 Dwarf_Addr addr = 0, fn_addr = 0;
5535 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5537 fn_addr = maybe_adjust_fn_sym_address(addr);
5538 if (function_symbol_is_exported(fn_addr))
5544 }
while (offset > 0);
5562 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5564 if (!die_address_attribute(const_cast<Dwarf_Die*>(function_die),
5565 DW_AT_low_pc, address))
5571 if (!get_first_exported_fn_address_from_DW_AT_ranges
5572 (const_cast<Dwarf_Die*>(function_die),
5576 address = maybe_adjust_fn_sym_address(address);
5595 get_variable_address(
const Dwarf_Die* variable_die,
5596 Dwarf_Addr& address)
const
5598 bool is_tls_address =
false;
5599 if (!die_location_address(const_cast<Dwarf_Die*>(variable_die),
5600 address, is_tls_address))
5602 if (!is_tls_address)
5603 address = maybe_adjust_var_sym_address(address);
5610 corpus::exported_decls_builder*
5611 exported_decls_builder()
5612 {
return corpus()->get_exported_decls_builder().get();}
5620 load_all_types()
const
5621 {
return options().load_all_types;}
5629 load_all_types(
bool f)
5630 {options().load_all_types = f;}
5633 load_in_linux_kernel_mode()
const
5634 {
return options().load_in_linux_kernel_mode;}
5637 load_in_linux_kernel_mode(
bool f)
5638 {options().load_in_linux_kernel_mode = f;}
5650 load_undefined_interfaces()
const
5651 {
return options().load_undefined_interfaces;}
5661 leverage_dwarf_factorization()
const
5663 if (!leverage_dwarf_factorization_.has_value())
5665 if (options().leverage_dwarf_factorization
5666 && elf_helpers::find_section_by_name(elf_handle(),
5667 ".gnu_debugaltlink"))
5668 leverage_dwarf_factorization_ =
true;
5670 leverage_dwarf_factorization_ =
false;
5672 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5674 return *leverage_dwarf_factorization_;
5685 {
return options().show_stats;}
5695 {options().show_stats = f;}
5705 {
return options().do_log;}
5714 {options().do_log = f;}
5734 build_die_parent_relations_under(Dwarf_Die* die,
5736 imported_unit_points_type & imported_units)
5741 offset_offset_map_type& parent_of = die_parent_map(source);
5744 if (dwarf_child(die, &child) != 0)
5749 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5750 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5752 Dwarf_Die imported_unit;
5753 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5764 && die_has_children(&imported_unit))
5766 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5767 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5768 imported_units.push_back
5769 (imported_unit_point(dwarf_dieoffset(&child),
5771 imported_unit_die_source));
5774 build_die_parent_relations_under(&child, source, imported_units);
5776 while (dwarf_siblingof(&child, &child) == 0);
5808 case translation_unit::LANG_UNKNOWN:
5809 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5810 case translation_unit::LANG_Mips_Assembler:
5837 build_die_parent_maps()
5839 bool we_do_have_to_build_die_parent_map =
false;
5840 uint8_t address_size = 0;
5841 size_t header_size = 0;
5846 for (Dwarf_Off offset = 0, next_offset = 0;
5847 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5848 offset, &next_offset, &header_size,
5849 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5850 offset = next_offset)
5852 Dwarf_Off die_offset = offset + header_size;
5854 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
5859 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5861 if (do_we_build_die_parent_maps(lang))
5862 we_do_have_to_build_die_parent_map =
true;
5865 if (!we_do_have_to_build_die_parent_map)
5870 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5871 for (Dwarf_Off offset = 0, next_offset = 0;
5872 (dwarf_next_unit(const_cast<Dwarf*>(alternate_dwarf_debug_info()),
5873 offset, &next_offset, &header_size,
5874 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5875 offset = next_offset)
5877 Dwarf_Off die_offset = offset + header_size;
5879 if (!dwarf_offdie(const_cast<Dwarf*>(alternate_dwarf_debug_info()),
5884 imported_unit_points_type& imported_units =
5885 tu_die_imported_unit_points_map(source)[die_offset] =
5887 build_die_parent_relations_under(&cu, source, imported_units);
5892 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5895 for (Dwarf_Off offset = 0, next_offset = 0;
5896 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5897 offset, &next_offset, &header_size,
5898 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5899 offset = next_offset)
5901 Dwarf_Off die_offset = offset + header_size;
5903 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
5907 imported_unit_points_type& imported_units =
5908 tu_die_imported_unit_points_map(source)[die_offset] =
5910 build_die_parent_relations_under(&cu, source, imported_units);
5915 source = TYPE_UNIT_DIE_SOURCE;
5918 uint64_t type_signature = 0;
5919 Dwarf_Off type_offset;
5920 for (Dwarf_Off offset = 0, next_offset = 0;
5921 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5922 offset, &next_offset, &header_size,
5923 NULL, NULL, &address_size, NULL,
5924 &type_signature, &type_offset) == 0);
5925 offset = next_offset)
5927 Dwarf_Off die_offset = offset + header_size;
5930 if (!dwarf_offdie_types(const_cast<Dwarf*>(dwarf_debug_info()),
5934 imported_unit_points_type& imported_units =
5935 tu_die_imported_unit_points_map(source)[die_offset] =
5937 build_die_parent_relations_under(&cu, source, imported_units);
5952 struct offset_pairs_stack_type
5958 offset_pair_set_type set_;
5961 offset_pair_vector_type vect_;
5964 offset_pair_vect_map_type redundant_types_;
5967 offset_pair_vect_map_type dependant_types_;
5969 offset_pairs_stack_type(
const reader& rdr)
5978 add(
const offset_pair_type& p)
5991 erase(
const offset_pair_type& p)
5995 offset_pair_vector_type::iterator i;
5997 for (i = vect_.begin();i < vect_.end(); ++i)
6001 if (i != vect_.end())
6018 contains(
const offset_pair_type &p)
const
6020 if (set_.find(p) == set_.end())
6044 get_pairs_that_depend_on(
const offset_pair_type& p,
6045 offset_pair_vector_type& pairs)
const
6047 bool result =
false;
6052 offset_pair_vector_type::const_iterator i;
6053 for (i = vect_.begin(); i != vect_.end(); ++i)
6057 if (i == vect_.end())
6062 for (++i; i != vect_.end(); ++i)
6064 pairs.push_back(*i);
6081 record_dependant_types(
const offset_pair_type& p,
6082 const offset_pair_vector_type& dependant_types)
6084 for (
auto type_pair : dependant_types)
6085 dependant_types_[type_pair].push_back(p);
6093 record_redundant_type_die_pair(
const offset_pair_type& p)
6095 offset_pair_vector_type dependant_types;
6096 get_pairs_that_depend_on(p, dependant_types);
6099 auto it = redundant_types_.find(p);
6100 if (it == redundant_types_.end())
6102 auto entry = std::make_pair(p, dependant_types);
6103 redundant_types_.insert(entry);
6106 it->second.insert(it->second.end(),
6107 dependant_types.begin(),
6108 dependant_types.end());
6112 record_dependant_types(p, dependant_types);
6121 is_redundant(
const offset_pair_type& p)
6123 auto i = redundant_types_.find(p);
6124 if (i != redundant_types_.end())
6135 depends_on_redundant_types(
const offset_pair_type& p)
6137 auto i = dependant_types_.find(p);
6138 if (i == dependant_types_.end())
6155 erase_redundant_type_pair_entry(
const offset_pair_type& p,
6156 bool erase_cached_results =
false)
6160 auto redundant_type = redundant_types_.find(p);
6161 if (redundant_type != redundant_types_.end())
6163 for (
auto dependant_type : redundant_type->second)
6167 auto dependant_types_it = dependant_types_.find(dependant_type);
6168 ABG_ASSERT(dependant_types_it != dependant_types_.end());
6172 auto i = dependant_types_it->second.begin();
6173 for (; i!= dependant_types_it->second.end();++i)
6176 if (i != dependant_types_it->second.end())
6177 dependant_types_it->second.erase(i);
6182 if (dependant_types_it->second.empty())
6184 if (erase_cached_results)
6185 rdr_.die_comparison_results_.erase(dependant_type);
6186 dependant_types_.erase(dependant_types_it);
6190 if (erase_cached_results)
6191 rdr_.die_comparison_results_.erase(p);
6192 redundant_types_.erase(p);
6203 confirm_canonical_propagated_type(
const offset_pair_type& p)
6204 {erase_redundant_type_pair_entry(p,
true);}
6214 cancel_canonical_propagated_type(
const offset_pair_type& p)
6216 offset_pair_set_type dependant_types;
6217 get_dependant_types(p, dependant_types,
true);
6218 for (
auto dependant_type : dependant_types)
6222 if (rdr_.propagated_types_.find(dependant_type)
6223 != rdr_.propagated_types_.end())
6225 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
6226 dependant_type.first.source_,
6228 rdr_.propagated_types_.erase(dependant_type);
6229 rdr_.cancelled_propagation_count_++;
6233 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
6234 if (comp_result_it != rdr_.die_comparison_results_.end())
6235 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
6239 auto comp_result_it = rdr_.die_comparison_results_.find(p);
6240 if (comp_result_it != rdr_.die_comparison_results_.end())
6247 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
6248 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
6249 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
6252 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
6254 rdr_.erase_canonical_die_offset(p.first.offset_,
6257 rdr_.propagated_types_.erase(p);
6258 rdr_.cancelled_propagation_count_++;
6275 get_dependant_types(
const offset_pair_type& p,
6276 offset_pair_set_type& result,
6277 bool transitive_closure =
false)
6279 auto i = redundant_types_.find(p);
6280 if (i != redundant_types_.end())
6282 for (
auto dependant_type : i->second)
6283 if (result.find(dependant_type) == result.end())
6285 result.insert(dependant_type);
6286 if (transitive_closure)
6287 get_dependant_types(p, result,
true);
6296 build_ir_node_from_die(reader& rdr,
6299 bool called_from_public_decl,
6300 size_t where_offset,
6301 bool is_declaration_only =
true,
6302 bool is_required_decl_spec =
false);
6305 build_ir_node_from_die(reader& rdr,
6307 bool called_from_public_decl,
6308 size_t where_offset);
6310 static decl_base_sptr
6311 build_ir_node_for_void_type(reader& rdr);
6314 build_ir_node_for_void_pointer_type(reader& rdr);
6317 add_or_update_class_type(reader& rdr,
6322 bool called_from_public_decl,
6323 size_t where_offset,
6324 bool is_declaration_only);
6326 static union_decl_sptr
6327 add_or_update_union_type(reader& rdr,
6330 union_decl_sptr union_type,
6331 bool called_from_public_decl,
6332 size_t where_offset,
6333 bool is_declaration_only);
6335 static decl_base_sptr
6336 build_ir_node_for_void_type(reader& rdr);
6338 static decl_base_sptr
6339 build_ir_node_for_variadic_parameter_type(reader &rdr);
6342 build_function_decl(reader& rdr,
6344 size_t where_offset,
6348 function_is_suppressed(
const reader& rdr,
6349 const scope_decl* scope,
6350 Dwarf_Die *function_die,
6351 bool is_declaration_only);
6354 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
6357 size_t where_offset,
6358 bool is_declaration_only,
6362 build_var_decl(reader& rdr,
6364 size_t where_offset,
6368 build_or_get_var_decl_if_not_suppressed(reader& rdr,
6371 size_t where_offset,
6372 bool is_declaration_only,
6374 bool is_required_decl_spec =
false);
6376 variable_is_suppressed(
const reader& rdr,
6377 const scope_decl* scope,
6378 Dwarf_Die *variable_die,
6379 bool is_declaration_only,
6380 bool is_required_decl_spec =
false);
6383 finish_member_function_reading(Dwarf_Die* die,
6385 const class_or_union_sptr klass,
6394 die_is_anonymous(
const Dwarf_Die* die)
6396 Dwarf_Attribute attr;
6397 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), DW_AT_name, &attr))
6411 die_is_anonymous_data_member(
const Dwarf_Die* die)
6414 || dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_member
6415 || !die_name(die).empty())
6419 if (!die_die_attribute(die, DW_AT_type, type_die))
6422 if (dwarf_tag(&type_die) != DW_TAG_structure_type
6423 && dwarf_tag(&type_die) != DW_TAG_union_type)
6440 die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6445 Dwarf_Attribute attr;
6446 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6449 const char* str = dwarf_formstring(&attr);
6450 return str ? str :
"";
6464 die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6469 Dwarf_Attribute attr;
6470 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6473 const char* str = dwarf_formstring(&attr);
6493 die_unsigned_constant_attribute(
const Dwarf_Die* die,
6500 Dwarf_Attribute attr;
6501 Dwarf_Word result = 0;
6502 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6503 || dwarf_formudata(&attr, &result))
6523 die_signed_constant_attribute(
const Dwarf_Die *die,
6530 Dwarf_Attribute attr;
6531 Dwarf_Sword result = 0;
6532 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6533 || dwarf_formsdata(&attr, &result))
6559 die_constant_attribute(
const Dwarf_Die *die,
6562 array_type_def::subrange_type::bound_value &value)
6567 if (!die_unsigned_constant_attribute(die, attr_name, l))
6569 value.set_unsigned(l);
6574 if (!die_signed_constant_attribute(die, attr_name, l))
6576 value.set_signed(l);
6591 form_is_DW_FORM_strx(
unsigned form)
6595 #if defined HAVE_DW_FORM_strx1 \
6596 && defined HAVE_DW_FORM_strx2 \
6597 && defined HAVE_DW_FORM_strx3 \
6598 && defined HAVE_DW_FORM_strx4
6599 if (form == DW_FORM_strx1
6600 || form == DW_FORM_strx2
6601 || form == DW_FORM_strx3
6602 ||form == DW_FORM_strx4)
6619 form_is_DW_FORM_line_strp(
unsigned form)
6623 #if defined HAVE_DW_FORM_line_strp
6624 if (form == DW_FORM_line_strp)
6651 die_flag_attribute(
const Dwarf_Die* die,
6654 bool recursively =
true)
6656 Dwarf_Attribute attr;
6658 ? !dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6659 : !dwarf_attr(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6663 if (dwarf_formflag(&attr, &f))
6677 die_linkage_name(
const Dwarf_Die* die)
6682 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6683 if (linkage_name.empty())
6684 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6685 return linkage_name;
6699 die_decl_file_attribute(
const Dwarf_Die* die)
6704 const char* str = dwarf_decl_file(const_cast<Dwarf_Die*>(die));
6706 return str ? str :
"";
6727 die_die_attribute(
const Dwarf_Die* die,
6732 Dwarf_Attribute attr;
6734 ? !dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6735 : !dwarf_attr(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6738 return dwarf_formref_die(&attr, &result);
6763 die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die)
6765 if (die_die_attribute(die, DW_AT_specification, origin_die,
true)
6766 || die_die_attribute(die, DW_AT_abstract_origin, origin_die,
true))
6768 while (die_die_attribute(&origin_die,
6769 DW_AT_specification,
6771 || die_die_attribute(&origin_die,
6772 DW_AT_abstract_origin,
6810 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6812 Dwarf_Die& referenced_subrange)
6814 bool result =
false;
6816 if (dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subrange_type)
6819 Dwarf_Die referenced_die;
6820 if (die_die_attribute(die, attr_name, referenced_die))
6822 unsigned tag = dwarf_tag(&referenced_die);
6823 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6826 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6828 tag = dwarf_tag(&type_die);
6829 if (tag == DW_TAG_subrange_type)
6831 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6867 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6869 array_type_def::subrange_type::bound_value& v,
6872 bool result =
false;
6874 if (dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subrange_type)
6877 Dwarf_Die subrange_die;
6878 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6881 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6899 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6901 Dwarf_Attribute attr;
6902 if (!dwarf_attr_integrate(die, attr_name, &attr))
6904 return dwarf_formaddr(&attr, &result) == 0;
6915 die_location(
const reader& rdr,
const Dwarf_Die* die)
6920 string file = die_decl_file_attribute(die);
6922 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6924 if (!file.empty() && line != 0)
6927 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6939 die_name(
const Dwarf_Die* die)
6941 string name = die_string_attribute(die, DW_AT_name);
6957 die_loc_and_name(
const reader& rdr,
6961 string& linkage_name)
6963 loc = die_location(rdr, die);
6964 name = die_name(die);
6965 linkage_name = die_linkage_name(die);
6976 die_name_and_linkage_name(
const Dwarf_Die* die,
6978 string& linkage_name)
6980 name = die_name(die);
6981 linkage_name = die_linkage_name(die);
6994 die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6999 uint64_t byte_size = 0, bit_size = 0;
7001 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
7003 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
7007 bit_size = byte_size * 8;
7030 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
7037 case private_access:
7038 result = private_access;
7041 case protected_access:
7042 result = protected_access;
7046 result = public_access;
7065 die_is_public_decl(
const Dwarf_Die* die)
7069 bool is_public =
false;
7075 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7076 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
7077 die_flag_attribute(die, DW_AT_external, is_public);
7078 else if (tag == DW_TAG_namespace)
7080 string name = die_name(die);
7081 is_public = !name.empty();
7095 die_is_effectively_public_decl(
const reader& rdr,
7096 const Dwarf_Die* die)
7098 if (die_is_public_decl(die))
7101 unsigned tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7102 if (tag == DW_TAG_variable || tag == DW_TAG_member)
7105 Dwarf_Die parent_die;
7106 size_t where_offset = 0;
7107 if (!get_parent_die(rdr, die, parent_die, where_offset))
7110 tag = dwarf_tag(&parent_die);
7111 if (tag == DW_TAG_compile_unit
7112 || tag == DW_TAG_partial_unit
7113 || tag == DW_TAG_type_unit)
7117 if (tag == DW_TAG_namespace)
7119 string name = die_name(&parent_die);
7138 die_is_declaration_only(Dwarf_Die* die)
7140 bool is_declaration =
false;
7141 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
7142 if (is_declaration && (!die_has_size_attribute(die)
7143 || !die_has_children(die)))
7154 die_is_function_decl(
const Dwarf_Die *die)
7159 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7160 if (tag == DW_TAG_subprogram)
7171 die_is_variable_decl(
const Dwarf_Die *die)
7176 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7177 if (tag == DW_TAG_variable)
7188 die_has_size_attribute(
const Dwarf_Die *die)
7191 if (die_size_in_bits(die, s))
7202 die_has_no_child(
const Dwarf_Die *die)
7208 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
7221 die_is_declaration_only(
const Dwarf_Die* die)
7222 {
return die_is_declaration_only(const_cast<Dwarf_Die*>(die));}
7230 die_is_artificial(Dwarf_Die* die)
7233 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
7240 is_type_tag(
unsigned tag)
7242 bool result =
false;
7246 case DW_TAG_array_type:
7247 case DW_TAG_class_type:
7248 case DW_TAG_enumeration_type:
7249 case DW_TAG_pointer_type:
7250 case DW_TAG_reference_type:
7251 case DW_TAG_string_type:
7252 case DW_TAG_structure_type:
7253 case DW_TAG_subroutine_type:
7254 case DW_TAG_typedef:
7255 case DW_TAG_union_type:
7256 case DW_TAG_ptr_to_member_type:
7257 case DW_TAG_set_type:
7258 case DW_TAG_subrange_type:
7259 case DW_TAG_base_type:
7260 case DW_TAG_const_type:
7261 case DW_TAG_file_type:
7262 case DW_TAG_packed_type:
7263 case DW_TAG_thrown_type:
7264 case DW_TAG_volatile_type:
7265 case DW_TAG_restrict_type:
7266 case DW_TAG_interface_type:
7267 case DW_TAG_unspecified_type:
7268 case DW_TAG_shared_type:
7269 case DW_TAG_rvalue_reference_type:
7270 case DW_TAG_coarray_type:
7271 case DW_TAG_atomic_type:
7272 case DW_TAG_immutable_type:
7295 is_canon_type_to_be_propagated_tag(
unsigned tag)
7297 bool result =
false;
7301 case DW_TAG_class_type:
7302 case DW_TAG_structure_type:
7303 case DW_TAG_union_type:
7304 case DW_TAG_subroutine_type:
7305 case DW_TAG_subprogram:
7326 type_comparison_result_to_be_cached(
unsigned tag)
7331 case DW_TAG_class_type:
7332 case DW_TAG_structure_type:
7333 case DW_TAG_union_type:
7334 case DW_TAG_subroutine_type:
7335 case DW_TAG_subprogram:
7356 maybe_cache_type_comparison_result(
const reader& rdr,
7358 const offset_pair_type& p,
7361 if (!type_comparison_result_to_be_cached(tag)
7362 || (result != COMPARISON_RESULT_EQUAL
7363 && result != COMPARISON_RESULT_DIFFERENT))
7366 rdr.die_comparison_results_[p] = result;
7386 get_cached_type_comparison_result(
const reader& rdr,
7387 const offset_pair_type& p,
7390 auto i = rdr.die_comparison_results_.find(p);
7391 if (i != rdr.die_comparison_results_.end())
7414 maybe_get_cached_type_comparison_result(
const reader& rdr,
7416 const offset_pair_type& p,
7419 if (type_comparison_result_to_be_cached(tag))
7424 if (get_cached_type_comparison_result(rdr, p, result))
7436 is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
7438 bool result =
false;
7439 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7441 if (!is_type_tag(tag))
7446 case DW_TAG_class_type:
7447 case DW_TAG_structure_type:
7448 case DW_TAG_union_type:
7449 result = !die_is_declaration_only(die);
7452 case DW_TAG_subroutine_type:
7453 case DW_TAG_subprogram:
7454 case DW_TAG_array_type:
7470 is_decl_tag(
unsigned tag)
7474 case DW_TAG_formal_parameter:
7475 case DW_TAG_imported_declaration:
7477 case DW_TAG_unspecified_parameters:
7478 case DW_TAG_subprogram:
7479 case DW_TAG_variable:
7480 case DW_TAG_namespace:
7481 case DW_TAG_GNU_template_template_param:
7482 case DW_TAG_GNU_template_parameter_pack:
7483 case DW_TAG_GNU_formal_parameter_pack:
7495 die_is_type(
const Dwarf_Die* die)
7499 return is_type_tag(dwarf_tag(const_cast<Dwarf_Die*>(die)));
7508 die_is_decl(
const Dwarf_Die* die)
7512 return is_decl_tag(dwarf_tag(const_cast<Dwarf_Die*>(die)));
7521 die_is_namespace(
const Dwarf_Die* die)
7525 return (dwarf_tag(const_cast<Dwarf_Die*>(die)) == DW_TAG_namespace);
7534 die_is_unspecified(Dwarf_Die* die)
7538 return (dwarf_tag(die) == DW_TAG_unspecified_type);
7547 die_is_void_type(Dwarf_Die* die)
7549 if (!die || dwarf_tag(die) != DW_TAG_base_type)
7552 string name = die_name(die);
7565 die_is_pointer_type(
const Dwarf_Die* die)
7570 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7571 if (tag == DW_TAG_pointer_type)
7585 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7587 if (!die_is_pointer_array_or_reference_type(die)
7588 && !die_is_qualified_type(die))
7591 Dwarf_Die underlying_type_die;
7592 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7595 if (!die_is_class_type(&underlying_type_die))
7598 string name = die_name(&underlying_type_die);
7600 return name.empty();
7609 die_is_reference_type(
const Dwarf_Die* die)
7614 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7615 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7627 die_is_array_type(
const Dwarf_Die* die)
7632 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7633 if (tag == DW_TAG_array_type)
7645 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7646 {
return (die_is_pointer_type(die)
7647 || die_is_reference_type(die)
7648 || die_is_array_type(die));}
7656 die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7657 {
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7666 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7667 {
return (die_is_pointer_array_or_reference_type(die)
7668 || dwarf_tag(const_cast<Dwarf_Die*>(die)) == DW_TAG_typedef);}
7676 die_is_class_type(
const Dwarf_Die* die)
7678 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7680 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7692 die_is_qualified_type(
const Dwarf_Die* die)
7694 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7695 if (tag == DW_TAG_const_type
7696 || tag == DW_TAG_volatile_type
7697 || tag == DW_TAG_restrict_type)
7709 die_is_function_type(
const Dwarf_Die *die)
7711 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7712 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7730 die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7735 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7747 die_has_children(
const Dwarf_Die* die)
7753 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
7773 fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die)
7778 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7779 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7782 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
7784 int child_tag = dwarf_tag(&child);
7785 if (child_tag == DW_TAG_formal_parameter)
7787 memcpy(&first_parm_die, &child,
sizeof(Dwarf_Die));
7822 member_fn_die_has_this_pointer(
const reader& rdr,
7823 const Dwarf_Die* die,
7824 size_t where_offset,
7825 Dwarf_Die& class_die,
7826 Dwarf_Die& object_pointer_die)
7831 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7832 if (tag != DW_TAG_subprogram && tag != DW_TAG_subroutine_type)
7835 if (tag == DW_TAG_subprogram
7836 && !die_is_at_class_scope(rdr, die, where_offset, class_die))
7839 Dwarf_Die first_parm_die;
7840 Dwarf_Die parm_type_die;
7841 if (die_has_object_pointer(die, object_pointer_die))
7847 memcpy(&first_parm_die, &object_pointer_die,
sizeof(Dwarf_Die));
7848 if (!die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7850 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7851 die_peel_typedef(&parm_type_die, parm_type_die);
7853 else if (fn_die_first_parameter_die(die, first_parm_die))
7855 memcpy(&object_pointer_die, &first_parm_die,
sizeof(Dwarf_Die));
7856 bool is_artificial =
false;
7857 if (die_flag_attribute(&first_parm_die, DW_AT_artificial, is_artificial))
7859 if (die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7861 tag = dwarf_tag(&parm_type_die);
7862 if (tag == DW_TAG_pointer_type)
7864 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7865 die_peel_typedef(&parm_type_die, parm_type_die);
7879 tag = dwarf_tag(&parm_type_die);
7880 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7882 memcpy(&class_die, &parm_type_die,
sizeof(Dwarf_Die));
7902 die_this_pointer_from_object_pointer(Dwarf_Die* die,
7903 Dwarf_Die& this_pointer_die)
7906 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7908 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7923 die_this_pointer_is_const(Dwarf_Die* dye)
7928 memcpy(&die, dye,
sizeof(Dwarf_Die));
7929 if (dwarf_tag(&die) == DW_TAG_const_type)
7932 if (dwarf_tag(&die) == DW_TAG_pointer_type)
7934 Dwarf_Die pointed_to_type_die;
7935 if (die_die_attribute(&die, DW_AT_type, pointed_to_type_die))
7936 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7952 die_object_pointer_is_for_const_method(Dwarf_Die* die)
7955 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7957 Dwarf_Die this_pointer_die;
7958 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7959 if (die_this_pointer_is_const(&this_pointer_die))
7981 die_is_at_class_scope(
const reader& rdr,
7982 const Dwarf_Die* die,
7983 size_t where_offset,
7984 Dwarf_Die& class_scope_die)
7986 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7989 int tag = dwarf_tag(&class_scope_die);
7991 return (tag == DW_TAG_structure_type
7992 || tag == DW_TAG_class_type
7993 || tag == DW_TAG_union_type);
8006 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
8011 int tag = dwarf_tag(die);
8013 if (tag == DW_TAG_const_type
8014 || tag == DW_TAG_volatile_type
8015 || tag == DW_TAG_restrict_type
8016 || tag == DW_TAG_pointer_type
8017 || tag == DW_TAG_reference_type
8018 || tag == DW_TAG_rvalue_reference_type)
8020 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8026 memcpy(&peeled_die, die,
sizeof(peeled_die));
8028 while (tag == DW_TAG_const_type
8029 || tag == DW_TAG_volatile_type
8030 || tag == DW_TAG_restrict_type
8031 || tag == DW_TAG_pointer_type
8032 || tag == DW_TAG_reference_type
8033 || tag == DW_TAG_rvalue_reference_type)
8035 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8037 tag = dwarf_tag(&peeled_die);
8052 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
8057 memcpy(&peeled_die, die,
sizeof(peeled_die));
8059 int tag = dwarf_tag(&peeled_die);
8061 bool result =
false;
8062 while (tag == DW_TAG_const_type
8063 || tag == DW_TAG_volatile_type
8064 || tag == DW_TAG_restrict_type)
8066 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8068 tag = dwarf_tag(&peeled_die);
8084 die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
8089 int tag = dwarf_tag(die);
8091 memcpy(&peeled_die, die,
sizeof(peeled_die));
8093 if (tag == DW_TAG_typedef)
8095 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8101 while (tag == DW_TAG_typedef)
8103 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8105 tag = dwarf_tag(&peeled_die);
8121 die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
8126 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
8128 if (tag == DW_TAG_pointer_type
8129 || tag == DW_TAG_reference_type
8130 || tag == DW_TAG_rvalue_reference_type
8131 || tag == DW_TAG_typedef)
8133 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8139 while (tag == DW_TAG_pointer_type
8140 || tag == DW_TAG_reference_type
8141 || tag == DW_TAG_rvalue_reference_type
8142 || tag == DW_TAG_typedef)
8144 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8146 tag = dwarf_tag(&peeled_die);
8177 die_function_type_is_method_type(
const reader& rdr,
8178 const Dwarf_Die *die,
8179 size_t where_offset,
8180 Dwarf_Die& object_pointer_die,
8181 Dwarf_Die& class_die,
8187 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
8188 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
8190 if (member_fn_die_has_this_pointer(rdr, die, where_offset, class_die, object_pointer_die))
8195 else if (die_is_at_class_scope(rdr, die, where_offset, class_die))
8206 VIRTUALITY_NOT_VIRTUAL,
8208 VIRTUALITY_PURE_VIRTUAL
8221 die_virtuality(
const Dwarf_Die* die, virtuality& virt)
8227 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
8229 if (v == DW_VIRTUALITY_virtual)
8230 virt = VIRTUALITY_VIRTUAL;
8231 else if (v == DW_VIRTUALITY_pure_virtual)
8232 virt = VIRTUALITY_PURE_VIRTUAL;
8234 virt = VIRTUALITY_NOT_VIRTUAL;
8246 die_is_virtual(
const Dwarf_Die* die)
8249 if (!die_virtuality(die, v))
8252 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
8262 die_is_declared_inline(Dwarf_Die* die)
8264 uint64_t inline_value = 0;
8265 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
8267 return (inline_value == DW_INL_declared_inlined
8268 || inline_value == DW_INL_declared_not_inlined);
8283 slowly_compare_strings(
const Dwarf_Die *l,
8287 const char *l_str = die_char_str_attribute(l, attr_name),
8288 *r_str = die_char_str_attribute(r, attr_name);
8289 if (!l_str && !r_str)
8291 return l_str && r_str && !strcmp(l_str, r_str);
8317 compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
8321 Dwarf_Attribute l_attr, r_attr;
8322 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(l), attr_name, &l_attr)
8323 || !dwarf_attr_integrate(const_cast<Dwarf_Die*>(r), attr_name, &r_attr))
8327 || l_attr.form == DW_FORM_string
8328 || l_attr.form == DW_FORM_GNU_strp_alt
8329 || form_is_DW_FORM_strx(l_attr.form)
8330 || form_is_DW_FORM_line_strp(l_attr.form));
8333 || r_attr.form == DW_FORM_string
8334 || r_attr.form == DW_FORM_GNU_strp_alt
8335 || form_is_DW_FORM_strx(r_attr.form)
8336 || form_is_DW_FORM_line_strp(r_attr.form));
8338 if ((l_attr.form == DW_FORM_strp
8339 && r_attr.form == DW_FORM_strp)
8340 || (l_attr.form == DW_FORM_GNU_strp_alt
8341 && r_attr.form == DW_FORM_GNU_strp_alt)
8342 || (form_is_DW_FORM_strx(l_attr.form)
8343 && form_is_DW_FORM_strx(r_attr.form))
8344 || (form_is_DW_FORM_line_strp(l_attr.form)
8345 && form_is_DW_FORM_line_strp(r_attr.form)))
8352 if (l_attr.valp == r_attr.valp)
8354 #if WITH_DEBUG_TYPE_CANONICALIZATION
8355 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
8366 result = slowly_compare_strings(l, r, attr_name);
8384 compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
8386 Dwarf_Die l_cu, r_cu;
8387 if (!dwarf_diecu(const_cast<Dwarf_Die*>(l), &l_cu, 0, 0)
8388 ||!dwarf_diecu(const_cast<Dwarf_Die*>(r), &r_cu, 0, 0))
8392 compare_dies_string_attribute_value(&l_cu, &r_cu,
8395 if (compared && result)
8397 Dwarf_Die peeled_l, peeled_r;
8398 if (die_is_pointer_reference_or_typedef_type(l)
8399 && die_is_pointer_reference_or_typedef_type(r)
8400 && die_peel_pointer_and_typedef(l, peeled_l)
8401 && die_peel_pointer_and_typedef(r, peeled_r))
8403 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
8404 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
8407 compare_dies_string_attribute_value(&l_cu, &r_cu,
8438 die_location_expr(
const Dwarf_Die* die,
8446 Dwarf_Attribute attr;
8447 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
8451 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
8486 op_pushes_constant_value(Dwarf_Op* ops,
8490 dwarf_expr_eval_context& ctxt)
8494 Dwarf_Op& op = ops[index];
8500 value = ops[index].number;
8513 value = ops[index].number;
8617 expr_result r(value);
8620 next_index = index + 1;
8650 op_pushes_non_constant_value(Dwarf_Op* ops,
8654 dwarf_expr_eval_context& ctxt)
8657 Dwarf_Op& op = ops[index];
8693 next_index = index + 1;
8728 next_index = index + 1;
8732 next_index = index + 2;
8736 next_index = index + 1;
8740 next_index = index + 1;
8743 case DW_OP_GNU_variable_value:
8744 next_index = index + 1;
8751 expr_result r(
false);
8780 op_manipulates_stack(Dwarf_Op* expr,
8784 dwarf_expr_eval_context& ctxt)
8786 Dwarf_Op& op = expr[index];
8792 v = ctxt.stack.front();
8797 v = ctxt.stack.front();
8816 ctxt.stack.erase(ctxt.stack.begin() + 1);
8823 ctxt.stack.erase(ctxt.stack.begin() + 2);
8828 case DW_OP_deref_size:
8836 case DW_OP_xderef_size:
8844 case DW_OP_push_object_address:
8849 case DW_OP_form_tls_address:
8850 case DW_OP_GNU_push_tls_address:
8853 if (op.atom == DW_OP_form_tls_address)
8858 case DW_OP_call_frame_cfa:
8870 if (op.atom == DW_OP_form_tls_address
8871 || op.atom == DW_OP_GNU_push_tls_address)
8872 ctxt.set_tls_address(
true);
8874 ctxt.set_tls_address(
false);
8876 next_index = index + 1;
8904 op_is_arith_logic(Dwarf_Op* expr,
8908 dwarf_expr_eval_context& ctxt)
8912 Dwarf_Op& op = expr[index];
8913 expr_result val1, val2;
8914 bool result =
false;
8930 ctxt.push(val1 & val2);
8937 if (!val1.is_const())
8939 ctxt.push(val2 / val1);
8947 ctxt.push(val2 - val1);
8955 ctxt.push(val2 % val1);
8963 ctxt.push(val2 * val1);
8985 ctxt.push(val1 | val2);
8993 ctxt.push(val2 + val1);
8997 case DW_OP_plus_uconst:
9009 ctxt.push(val2 << val1);
9018 ctxt.push(val2 >> val1);
9026 ctxt.push(val2 ^ val1);
9036 if (ctxt.stack.front().is_const())
9037 ctxt.accum = ctxt.stack.front();
9039 next_index = index + 1;
9067 op_is_control_flow(Dwarf_Op* expr,
9071 dwarf_expr_eval_context& ctxt)
9075 Dwarf_Op& op = expr[index];
9076 expr_result val1, val2;
9090 if (op.atom == DW_OP_eq)
9091 value = val2 == val1;
9092 else if (op.atom == DW_OP_ge)
9093 value = val2 >= val1;
9094 else if (op.atom == DW_OP_gt)
9095 value = val2 > val1;
9096 else if (op.atom == DW_OP_le)
9097 value = val2 <= val1;
9098 else if (op.atom == DW_OP_lt)
9099 value = val2 < val1;
9100 else if (op.atom == DW_OP_ne)
9101 value = val2 != val1;
9103 val1 = value ? 1 : 0;
9110 index += op.number - 1;
9115 if (val1.const_value() != 0)
9116 index += val1.const_value() - 1;
9121 case DW_OP_call_ref:
9129 if (ctxt.stack.front().is_const())
9130 ctxt.accum = ctxt.stack.front();
9132 next_index = index + 1;
9153 eval_quickly(Dwarf_Op* expr,
9157 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
9159 value = expr[0].number;
9186 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
9189 bool& is_tls_address,
9190 dwarf_expr_eval_context &eval_ctxt)
9196 size_t index = 0, next_index = 0;
9199 if (op_is_arith_logic(expr, expr_len, index,
9200 next_index, eval_ctxt)
9201 || op_pushes_constant_value(expr, expr_len, index,
9202 next_index, eval_ctxt)
9203 || op_manipulates_stack(expr, expr_len, index,
9204 next_index, eval_ctxt)
9205 || op_pushes_non_constant_value(expr, expr_len, index,
9206 next_index, eval_ctxt)
9207 || op_is_control_flow(expr, expr_len, index,
9208 next_index, eval_ctxt))
9211 next_index = index + 1;
9215 }
while (index < expr_len);
9217 is_tls_address = eval_ctxt.set_tls_address();
9218 if (eval_ctxt.accum.is_const())
9220 value = eval_ctxt.accum;
9240 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
9243 bool& is_tls_address)
9245 dwarf_expr_eval_context eval_ctxt;
9246 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
9247 is_tls_address, eval_ctxt);
9439 read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
9444 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
9457 uint64_t containing_anonymous_object_size = 0;
9458 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
9459 containing_anonymous_object_size));
9460 containing_anonymous_object_size *= 8;
9462 uint64_t bitfield_size = 0;
9463 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
9474 offset = containing_anonymous_object_size - off - bitfield_size;
9490 die_constant_data_member_location(
const Dwarf_Die *die,
9496 Dwarf_Attribute attr;
9497 if (!dwarf_attr(const_cast<Dwarf_Die*>(die),
9498 DW_AT_data_member_location,
9503 if (dwarf_formudata(&attr, &val) != 0)
9559 die_member_offset(
const reader& rdr,
9560 const Dwarf_Die* die,
9563 Dwarf_Op* expr = NULL;
9564 size_t expr_len = 0;
9565 uint64_t bit_offset = 0;
9569 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
9571 offset = bit_offset;
9583 if (!die_constant_data_member_location(die, offset))
9588 if (!die_location_expr(die, DW_AT_data_member_location,
9595 if (!eval_quickly(expr, expr_len, offset))
9597 bool is_tls_address =
false;
9598 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
9599 offset, is_tls_address,
9600 rdr.dwarf_expr_eval_ctxt()))
9617 bool is_big_endian = architecture_is_big_endian(rdr.elf_handle());
9618 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
9619 offset += bit_offset;
9636 die_location_address(Dwarf_Die* die,
9637 Dwarf_Addr& address,
9638 bool& is_tls_address)
9640 Dwarf_Op* expr = NULL;
9641 size_t expr_len = 0;
9643 is_tls_address =
false;
9648 Dwarf_Attribute attr;
9649 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), DW_AT_location, &attr))
9652 if (dwarf_getlocation(&attr, &expr, &expr_len))
9659 Dwarf_Attribute result;
9660 if (!dwarf_getlocation_attr(&attr, expr, &result))
9662 return !dwarf_formaddr(&result, &address);
9665 address = expr->number;
9680 die_virtual_function_index(Dwarf_Die* die,
9686 Dwarf_Op* expr = NULL;
9687 size_t expr_len = 0;
9688 if (die_is_virtual(die))
9690 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9695 bool is_tls_addr =
false;
9696 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9714 int tag = dwarf_tag(die);
9716 if (tag == DW_TAG_class_type
9717 || tag == DW_TAG_structure_type
9718 || tag == DW_TAG_union_type
9719 || tag == DW_TAG_enumeration_type)
9720 return die_is_anonymous(die);
9742 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9745 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9747 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
9749 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9751 else if (tag == DW_TAG_union_type)
9753 else if (tag == DW_TAG_enumeration_type)
9772 build_internal_anonymous_die_name(
const string &
base_name,
9773 size_t anonymous_type_index)
9776 if (anonymous_type_index && !base_name.empty())
9778 std::ostringstream o;
9779 o << base_name << anonymous_type_index;
9808 die_qualified_type_name(
const reader& rdr,
9809 const Dwarf_Die* die,
9810 size_t where_offset,
9811 unordered_set<uint64_t>& guard)
9816 int tag = dwarf_tag (const_cast<Dwarf_Die*>(die));
9817 if (tag == DW_TAG_compile_unit
9818 || tag == DW_TAG_partial_unit
9819 || tag == DW_TAG_type_unit)
9822 string name = die_name(die);
9824 Dwarf_Die scope_die;
9825 if (!get_scope_die(rdr, die, where_offset, scope_die))
9828 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9829 string separator = colon_colon ?
"::" :
".";
9835 case DW_TAG_unspecified_type:
9838 case DW_TAG_base_type:
9848 case DW_TAG_typedef:
9852 case DW_TAG_enumeration_type:
9853 case DW_TAG_structure_type:
9854 case DW_TAG_class_type:
9855 case DW_TAG_union_type:
9857 if (die_is_anonymous(die))
9858 repr = die_class_or_enum_flat_representation(rdr, die,
"",
9861 where_offset, guard);
9864 string parent_name = die_qualified_name(rdr, &scope_die,
9865 where_offset, guard);
9866 repr = parent_name.empty() ? name : parent_name + separator + name;
9871 case DW_TAG_const_type:
9872 case DW_TAG_volatile_type:
9873 case DW_TAG_restrict_type:
9875 Dwarf_Die underlying_type_die;
9876 bool has_underlying_type_die =
9877 die_die_attribute(die, DW_AT_type, underlying_type_die);
9879 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9882 if (tag == DW_TAG_const_type)
9884 if (has_underlying_type_die
9885 && die_is_reference_type(&underlying_type_die))
9895 else if (!has_underlying_type_die
9896 || die_is_void_type(&underlying_type_die))
9904 else if (tag == DW_TAG_volatile_type)
9906 else if (tag == DW_TAG_restrict_type)
9911 string underlying_type_repr;
9912 if (has_underlying_type_die)
9913 underlying_type_repr =
9914 die_qualified_type_name(rdr, &underlying_type_die,
9915 where_offset, guard);
9917 underlying_type_repr =
"void";
9919 if (underlying_type_repr.empty())
9923 if (has_underlying_type_die)
9926 die_peel_qualified(&underlying_type_die, peeled);
9927 if (die_is_pointer_or_reference_type(&peeled))
9928 repr = underlying_type_repr +
" " + repr;
9930 repr +=
" " + underlying_type_repr;
9933 repr +=
" " + underlying_type_repr;
9938 case DW_TAG_pointer_type:
9939 case DW_TAG_reference_type:
9940 case DW_TAG_rvalue_reference_type:
9942 Dwarf_Die pointed_to_type_die;
9943 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9945 if (tag == DW_TAG_pointer_type)
9950 if (die_is_unspecified(&pointed_to_type_die))
9953 string pointed_type_repr =
9954 die_qualified_type_name(rdr, &pointed_to_type_die,
9955 where_offset, guard);
9957 repr = pointed_type_repr;
9961 if (tag == DW_TAG_pointer_type)
9963 else if (tag == DW_TAG_reference_type)
9965 else if (tag == DW_TAG_rvalue_reference_type)
9972 case DW_TAG_subrange_type:
9985 build_subrange_type(const_cast<reader&>(rdr),
9988 repr += s->as_string();
9992 case DW_TAG_array_type:
9994 Dwarf_Die element_type_die;
9995 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9997 string element_type_name =
9998 die_qualified_type_name(rdr, &element_type_die, where_offset, guard);
9999 if (element_type_name.empty())
10003 build_subranges_from_array_type_die(const_cast<reader&>(rdr),
10004 die, subranges, where_offset,
10007 repr = element_type_name;
10008 repr += array_type_def::subrange_type::vector_as_string(subranges);
10012 case DW_TAG_subroutine_type:
10013 case DW_TAG_subprogram:
10015 string return_type_name;
10017 vector<string> parm_names;
10018 bool is_const =
false;
10019 bool is_static =
false;
10021 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
10025 return_type_name, class_name,
10026 parm_names, is_const,
10028 if (return_type_name.empty())
10029 return_type_name =
"void";
10031 repr = return_type_name;
10033 if (is_method_type)
10035 repr +=
" (" + class_name +
"::*)";
10039 for (vector<string>::const_iterator i = parm_names.begin();
10040 i != parm_names.end();
10043 if (i != parm_names.begin())
10052 case DW_TAG_string_type:
10053 case DW_TAG_ptr_to_member_type:
10054 case DW_TAG_set_type:
10055 case DW_TAG_file_type:
10056 case DW_TAG_packed_type:
10057 case DW_TAG_thrown_type:
10058 case DW_TAG_interface_type:
10059 case DW_TAG_shared_type:
10085 die_type_name(
const reader& rdr,
10086 const Dwarf_Die* die,
10087 bool qualified_name,
10088 size_t where_offset,
10089 unordered_set<uint64_t>& guard)
10094 int tag = dwarf_tag (const_cast<Dwarf_Die*>(die));
10095 if (tag == DW_TAG_compile_unit
10096 || tag == DW_TAG_partial_unit
10097 || tag == DW_TAG_type_unit)
10100 string name = die_name(die);
10102 Dwarf_Die scope_die;
10103 if (!get_scope_die(rdr, die, where_offset, scope_die))
10106 bool colon_colon = die_is_type(die) || die_is_namespace(die);
10107 string separator = colon_colon ?
"::" :
".";
10113 case DW_TAG_unspecified_type:
10116 case DW_TAG_base_type:
10126 case DW_TAG_typedef:
10130 case DW_TAG_enumeration_type:
10131 case DW_TAG_structure_type:
10132 case DW_TAG_class_type:
10133 case DW_TAG_union_type:
10135 if (die_is_anonymous(die))
10136 repr = die_class_or_enum_flat_representation(rdr, die,
"",
10143 string parent_name;
10144 if (qualified_name)
10147 parent_name = die_qualified_name(rdr, &scope_die,
10148 where_offset, guard);
10150 repr = parent_name.empty() ? name : parent_name + separator + name;
10155 case DW_TAG_const_type:
10156 case DW_TAG_volatile_type:
10157 case DW_TAG_restrict_type:
10159 Dwarf_Die underlying_type_die;
10160 bool has_underlying_type_die =
10161 die_die_attribute(die, DW_AT_type, underlying_type_die);
10163 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
10166 if (tag == DW_TAG_const_type)
10168 if (has_underlying_type_die
10169 && die_is_reference_type(&underlying_type_die))
10179 else if (!has_underlying_type_die
10180 || die_is_void_type(&underlying_type_die))
10188 else if (tag == DW_TAG_volatile_type)
10190 else if (tag == DW_TAG_restrict_type)
10195 string underlying_type_repr;
10196 if (has_underlying_type_die)
10197 underlying_type_repr =
10198 die_type_name(rdr, &underlying_type_die,
10199 qualified_name, where_offset,
10202 underlying_type_repr =
"void";
10204 if (underlying_type_repr.empty())
10208 if (has_underlying_type_die)
10211 die_peel_qualified(&underlying_type_die, peeled);
10212 if (die_is_pointer_or_reference_type(&peeled))
10213 repr = underlying_type_repr +
" " + repr;
10215 repr +=
" " + underlying_type_repr;
10218 repr +=
" " + underlying_type_repr;
10223 case DW_TAG_pointer_type:
10224 case DW_TAG_reference_type:
10225 case DW_TAG_rvalue_reference_type:
10227 Dwarf_Die pointed_to_type_die;
10228 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
10230 if (tag == DW_TAG_pointer_type)
10235 if (die_is_unspecified(&pointed_to_type_die))
10238 string pointed_type_repr =
10239 die_type_name(rdr, &pointed_to_type_die,
10240 qualified_name, where_offset,
10243 repr = pointed_type_repr;
10247 if (tag == DW_TAG_pointer_type)
10249 else if (tag == DW_TAG_reference_type)
10251 else if (tag == DW_TAG_rvalue_reference_type)
10258 case DW_TAG_subrange_type:
10271 build_subrange_type(const_cast<reader&>(rdr),
10274 repr += s->as_string();
10278 case DW_TAG_array_type:
10280 Dwarf_Die element_type_die;
10281 if (!die_die_attribute(die, DW_AT_type, element_type_die))
10283 string element_type_name =
10284 die_type_name(rdr, &element_type_die,
10285 qualified_name, where_offset,
10287 if (element_type_name.empty())
10291 build_subranges_from_array_type_die(const_cast<reader&>(rdr),
10292 die, subranges, where_offset,
10295 repr = element_type_name;
10296 repr += array_type_def::subrange_type::vector_as_string(subranges);
10300 case DW_TAG_subroutine_type:
10301 case DW_TAG_subprogram:
10303 string return_type_name;
10305 vector<string> parm_names;
10306 bool is_const =
false;
10307 bool is_static =
false;
10308 bool is_method_type =
false;
10309 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
10315 parm_names, is_const,
10317 if (return_type_name.empty())
10318 return_type_name =
"void";
10320 repr = return_type_name;
10322 if (is_method_type)
10325 repr +=
" (" + class_name +
"::*)";
10330 for (vector<string>::const_iterator i = parm_names.begin();
10331 i != parm_names.end();
10334 if (i != parm_names.begin())
10343 case DW_TAG_string_type:
10344 case DW_TAG_ptr_to_member_type:
10345 case DW_TAG_set_type:
10346 case DW_TAG_file_type:
10347 case DW_TAG_packed_type:
10348 case DW_TAG_thrown_type:
10349 case DW_TAG_interface_type:
10350 case DW_TAG_shared_type:
10371 die_type_name(
const reader& rdr,
10372 const Dwarf_Die* die,
10373 bool qualified_name,
10374 size_t where_offset)
10376 unordered_set<uint64_t> guard;
10377 return die_type_name(rdr, die, qualified_name, where_offset, guard);
10398 die_qualified_decl_name(
const reader& rdr,
10399 const Dwarf_Die* die,
10400 size_t where_offset,
10401 unordered_set<uint64_t>& guard)
10403 if (!die || !die_is_decl(die))
10406 string name = die_name(die);
10408 Dwarf_Die scope_die;
10409 if (!get_scope_die(rdr, die, where_offset, scope_die))
10412 string scope_name = die_qualified_name(rdr, &scope_die, where_offset, guard);
10413 string separator =
"::";
10417 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
10420 case DW_TAG_namespace:
10421 case DW_TAG_member:
10422 case DW_TAG_variable:
10423 repr = scope_name.empty() ? name : scope_name + separator + name;
10425 case DW_TAG_subprogram:
10426 repr = die_function_signature(rdr, die,
10428 where_offset, guard);
10431 case DW_TAG_unspecified_parameters:
10435 case DW_TAG_formal_parameter:
10436 case DW_TAG_imported_declaration:
10437 case DW_TAG_GNU_template_template_param:
10438 case DW_TAG_GNU_template_parameter_pack:
10439 case DW_TAG_GNU_formal_parameter_pack:
10467 die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
10468 size_t where, unordered_set<uint64_t>& guard)
10470 if (die_is_type(die))
10471 return die_qualified_type_name(rdr, die, where, guard);
10472 else if (die_is_decl(die))
10473 return die_qualified_decl_name(rdr, die, where, guard);
10494 die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
10496 unordered_set<uint64_t> guard;
10497 return die_qualified_name(rdr, die, where, guard);
10523 die_qualified_type_name_empty(
const reader& rdr,
10524 const Dwarf_Die* die,
10525 size_t where,
string &qualified_name,
10526 unordered_set<uint64_t>& guard)
10531 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
10534 if (tag == DW_TAG_typedef
10535 || tag == DW_TAG_pointer_type
10536 || tag == DW_TAG_reference_type
10537 || tag == DW_TAG_rvalue_reference_type
10538 || tag == DW_TAG_array_type
10539 || tag == DW_TAG_const_type
10540 || tag == DW_TAG_volatile_type
10541 || tag == DW_TAG_restrict_type)
10543 Dwarf_Die underlying_type_die;
10544 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
10547 die_qualified_type_name(rdr, &underlying_type_die, where, guard);
10554 string name = die_qualified_type_name(rdr, die, where, guard);
10559 qname = die_qualified_type_name(rdr, die, where, guard);
10563 qualified_name = qname;
10615 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
10616 const Dwarf_Die* die,
10617 size_t where_offset,
10619 bool qualified_name,
10620 bool &is_method_type,
10621 string &return_type_name,
10622 string &class_name,
10623 vector<string>& parm_names,
10626 unordered_set<uint64_t>& guard)
10628 uint64_t off = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
10629 if (guard.find(off) != guard.end())
10634 Dwarf_Die ret_type_die;
10635 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
10636 return_type_name =
"void";
10641 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset, guard)
10642 : die_type_name(rdr, &ret_type_die, qualified_name,
10643 where_offset, guard);
10646 if (return_type_name.empty())
10647 return_type_name =
"void";
10649 Dwarf_Die object_pointer_die, class_die;
10651 die_function_type_is_method_type(rdr, die, where_offset,
10652 object_pointer_die,
10653 class_die, is_static);
10656 if (is_method_type)
10659 class_name = die_type_name(rdr, &class_die, qualified_name,
10660 where_offset, guard);
10662 Dwarf_Die this_pointer_die;
10663 Dwarf_Die pointed_to_die;
10665 && die_die_attribute(&object_pointer_die, DW_AT_type,
10667 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
10668 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
10671 string fn_name = die_name(die);
10672 string non_qualified_class_name = die_name(&class_die);
10673 bool is_ctor = fn_name == non_qualified_class_name;
10674 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
10676 if (is_ctor || is_dtor)
10677 return_type_name.clear();
10680 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
10683 int child_tag = dwarf_tag(&child);
10684 bool first_parm =
true;
10685 if (child_tag == DW_TAG_formal_parameter)
10690 first_parm =
false;
10691 if (is_method_type)
10694 Dwarf_Die parm_type_die;
10695 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
10699 ? rdr.get_die_pretty_representation(&parm_type_die,
10700 where_offset, guard)
10701 : die_type_name(rdr, &parm_type_die,
10702 qualified_name, where_offset, guard);
10706 parm_names.push_back(qname);
10708 else if (child_tag == DW_TAG_unspecified_parameters)
10711 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
10721 while (dwarf_siblingof(&child, &child) == 0);
10723 if (class_name.empty())
10725 Dwarf_Die parent_die;
10726 if (get_parent_die(rdr, die, parent_die, where_offset))
10728 if (die_is_class_type(&parent_die)
10730 class_name = die_type_name(rdr, &parent_die,
10760 die_function_signature(
const reader& rdr,
10761 const Dwarf_Die *fn_die,
10762 bool qualified_name,
10763 size_t where_offset,
10764 unordered_set<uint64_t>& guard)
10768 bool has_lang =
false;
10769 if ((has_lang = get_die_language(fn_die, lang)))
10777 string fn_name = die_linkage_name(fn_die);
10778 if (fn_name.empty())
10779 fn_name = die_name(fn_die);
10789 string return_type_name;
10790 Dwarf_Die ret_type_die;
10791 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
10792 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
10796 if (return_type_name.empty())
10797 return_type_name =
"void";
10799 Dwarf_Die scope_die;
10801 if (qualified_name && get_scope_die(rdr, fn_die, where_offset, scope_die))
10802 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset, guard);
10803 string fn_name = die_name(fn_die);
10804 if (!scope_name.empty())
10805 fn_name = scope_name +
"::" + fn_name;
10808 vector<string> parm_names;
10809 bool is_const =
false;
10810 bool is_static =
false;
10811 bool is_method_type =
false;
10813 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
10815 qualified_name, is_method_type,
10816 return_type_name, class_name,
10817 parm_names, is_const, is_static,
10820 bool is_virtual = die_is_virtual(fn_die);
10822 string repr = is_method_type?
"method" :
"function";
10824 repr +=
" virtual";
10826 if (!return_type_name.empty())
10827 repr +=
" " + return_type_name;
10829 repr +=
" " + fn_name;
10833 bool some_parm_emitted =
false;
10834 for (vector<string>::const_iterator i = parm_names.begin();
10835 i != parm_names.end();
10838 if (i != parm_names.begin())
10840 if (some_parm_emitted)
10844 if (!is_static && is_method_type)
10849 some_parm_emitted =
true;
10894 die_class_flat_representation(
const reader& rdr,
10895 const Dwarf_Die* die,
10896 const string& indent,
10898 bool qualified_names,
10899 size_t where_offset,
10900 unordered_set<uint64_t>& guard)
10902 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
10904 string repr = indent;
10905 string local_indent =
" ";
10906 string real_indent;
10908 if (tag == DW_TAG_union_type)
10910 else if (tag == DW_TAG_structure_type)
10912 else if (tag == DW_TAG_class_type)
10919 if (die_is_anonymous(die))
10921 uint64_t off = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
10922 if (guard.find(off) != guard.end())
10930 if (!die_is_anonymous(die))
10931 repr += die_qualified_name(rdr, die, where_offset, guard);
10938 Dwarf_Die member_child_die;
10939 bool first_sibling =
true;
10940 for (
bool got_it = get_member_child_die(die, &member_child_die);
10942 got_it = get_next_member_sibling_die(&member_child_die,
10943 &member_child_die),
10944 first_sibling =
false)
10948 if (!die_is_decl(&member_child_die)
10949 && !(die_is_type(&member_child_die)
10950 && die_is_anonymous(&member_child_die)))
10954 real_indent = first_sibling ?
"" :
" " ;
10956 real_indent = (first_sibling ?
"":
"\n") + indent + local_indent;
10958 repr += real_indent;
10960 repr += die_pretty_print_decl(rdr, &member_child_die,
10971 repr += indent +
"}";
10973 if (die_is_anonymous(die))
10975 uint64_t off = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
11007 die_enum_flat_representation(
const reader& rdr,
11008 const Dwarf_Die* die,
11009 const string& indent,
11011 bool qualified_names,
11012 size_t where_offset)
11014 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
11016 std::ostringstream o;
11017 string local_indent =
" ";
11018 string real_indent;
11020 if (tag == DW_TAG_enumeration_type)
11027 if (!die_is_anonymous(die))
11028 o << (qualified_names
11029 ? die_qualified_name(rdr, die, where_offset)
11039 bool first_enumerator=
true;
11040 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
11044 if (dwarf_tag(&child) != DW_TAG_enumerator)
11049 die_loc_and_name(rdr, &child, l, name, m);
11051 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
11054 real_indent = first_enumerator ?
"" :
", ";
11056 real_indent = first_enumerator ?
"" :
",\n" + indent + local_indent;
11057 o << name +
" = " << val;
11058 first_enumerator =
false;
11060 while (dwarf_siblingof(&child, &child) == 0);
11104 die_class_or_enum_flat_representation(
const reader& rdr,
11105 const Dwarf_Die* die,
11106 const string& indent,
11108 bool qualified_names,
11109 size_t where_offset,
11110 unordered_set<uint64_t>& guard)
11116 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
11120 case DW_TAG_class_type:
11121 case DW_TAG_structure_type:
11122 case DW_TAG_union_type:
11123 result = die_class_flat_representation(rdr, die, indent,
11124 one_line, qualified_names,
11128 case DW_TAG_enumeration_type:
11129 result = die_enum_flat_representation(rdr, die, indent,
11130 one_line, qualified_names,
11167 die_class_or_enum_flat_representation(
const reader& rdr,
11168 const Dwarf_Die* die,
11169 const string& indent,
11171 bool qualified_names,
11172 size_t where_offset)
11174 unordered_set<uint64_t> guard;
11175 return die_class_or_enum_flat_representation(rdr, die, indent,
11176 one_line, qualified_names,
11177 where_offset, guard);
11203 die_pretty_print_type(
const reader& rdr,
11204 const Dwarf_Die* die,
11205 size_t where_offset,
11206 unordered_set<uint64_t>& guard)
11209 || (!die_is_type(die)
11210 && dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subprogram))
11215 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
11218 case DW_TAG_string_type:
11227 repr =
"string type";
11229 case DW_TAG_unspecified_type:
11230 case DW_TAG_ptr_to_member_type:
11233 case DW_TAG_namespace:
11234 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset,
11238 case DW_TAG_base_type:
11239 repr = rdr.get_die_qualified_type_name(die, where_offset, guard);
11242 case DW_TAG_typedef:
11244 string qualified_name;
11245 if (!die_qualified_type_name_empty(rdr, die,
11249 repr =
"typedef " + qualified_name;
11253 case DW_TAG_const_type:
11254 case DW_TAG_volatile_type:
11255 case DW_TAG_restrict_type:
11256 case DW_TAG_pointer_type:
11257 case DW_TAG_reference_type:
11258 case DW_TAG_rvalue_reference_type:
11259 repr = rdr.get_die_qualified_type_name(die, where_offset, guard);
11262 case DW_TAG_enumeration_type:
11264 string qualified_name =
11265 rdr.get_die_qualified_type_name(die, where_offset, guard);
11266 repr =
"enum " + qualified_name;
11270 case DW_TAG_structure_type:
11271 case DW_TAG_class_type:
11273 string qualified_name =
11274 rdr.get_die_qualified_type_name(die, where_offset, guard);
11275 repr =
"class " + qualified_name;
11279 case DW_TAG_union_type:
11281 string qualified_name =
11282 rdr.get_die_qualified_type_name(die, where_offset, guard);
11283 repr =
"union " + qualified_name;
11287 case DW_TAG_array_type:
11289 Dwarf_Die element_type_die;
11290 if (!die_die_attribute(die, DW_AT_type, element_type_die))
11292 string element_type_name =
11293 rdr.get_die_qualified_type_name(&element_type_die,
11294 where_offset, guard);
11295 if (element_type_name.empty())
11299 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
11302 repr = element_type_name;
11303 repr += array_type_def::subrange_type::vector_as_string(subranges);
11307 case DW_TAG_subrange_type:
11317 repr += die_qualified_type_name(rdr, die, where_offset, guard);
11321 case DW_TAG_subroutine_type:
11322 case DW_TAG_subprogram:
11324 string return_type_name;
11326 vector<string> parm_names;
11327 bool is_const =
false;
11328 bool is_static =
false;
11329 bool is_method_type =
false;
11330 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
11334 return_type_name, class_name,
11335 parm_names, is_const,
11337 if (!is_method_type)
11338 repr =
"function type";
11340 repr =
"method type";
11341 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset, guard);
11345 case DW_TAG_set_type:
11346 case DW_TAG_file_type:
11347 case DW_TAG_packed_type:
11348 case DW_TAG_thrown_type:
11349 case DW_TAG_interface_type:
11350 case DW_TAG_shared_type:
11383 die_pretty_print_decl(
const reader& rdr,
11384 const Dwarf_Die* die,
11385 bool qualified_name,
11387 size_t where_offset,
11388 unordered_set<uint64_t>& guard)
11390 if (!die || !die_is_decl(die))
11395 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
11398 case DW_TAG_namespace:
11399 repr =
"namespace " + die_qualified_name(rdr, die, where_offset, guard);
11402 case DW_TAG_member:
11403 case DW_TAG_variable:
11405 string type_repr =
"void";
11406 Dwarf_Die type_die;
11407 if (die_die_attribute(die, DW_AT_type, type_die))
11408 type_repr = die_type_name(rdr, &type_die,
11412 repr = (qualified_name
11413 ? die_qualified_name(rdr, die, where_offset, guard)
11419 repr = type_repr +
" " + repr;
11423 case DW_TAG_subprogram:
11425 repr = die_function_signature(rdr, die, qualified_name,
11426 where_offset, guard);
11457 die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset,
11458 unordered_set<uint64_t>& guard)
11460 if (die_is_type(die))
11461 return die_pretty_print_type(rdr, die, where_offset, guard);
11462 else if (die_is_decl(die))
11463 return die_pretty_print_decl(rdr, die,
11466 where_offset, guard);
11489 compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
11493 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
11494 int r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
11495 if (l_tag != r_tag)
11498 bool result =
false;
11500 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
11503 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
11505 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
11512 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
11522 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
11539 at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
11540 const Dwarf_Die *l,
11541 const Dwarf_Die *r)
11543 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
11546 if ((die_is_declaration_only(l) && die_has_no_child(l))
11547 || (die_is_declaration_only(r) && die_has_no_child(r)))
11574 compare_as_type_dies(
const reader& rdr,
11575 const Dwarf_Die *l,
11576 const Dwarf_Die *r)
11582 if (dwarf_tag(const_cast<Dwarf_Die*>(l)) == DW_TAG_string_type
11583 && dwarf_tag(const_cast<Dwarf_Die*>(r)) == DW_TAG_string_type
11584 && (dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
11585 != dwarf_dieoffset(const_cast<Dwarf_Die*>(r))))
11593 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11598 uint64_t l_size = 0, r_size = 0;
11599 die_size_in_bits(l, l_size);
11600 die_size_in_bits(r, r_size);
11602 return l_size == r_size;
11617 compare_as_decl_and_type_dies(
const reader &rdr,
11618 const Dwarf_Die *l,
11619 const Dwarf_Die *r)
11621 if (!compare_as_decl_dies(l, r)
11622 || !compare_as_type_dies(rdr, l, r))
11644 fn_die_equal_by_linkage_name(
const Dwarf_Die *l,
11645 const Dwarf_Die *r)
11653 int tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
11655 tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
11658 string lname = die_name(l), rname = die_name(r);
11659 string llinkage_name = die_linkage_name(l),
11660 rlinkage_name = die_linkage_name(r);
11662 if (die_is_in_c_or_cplusplus(l)
11663 && die_is_in_c_or_cplusplus(r))
11665 if (!llinkage_name.empty() && !rlinkage_name.empty())
11666 return llinkage_name == rlinkage_name;
11667 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
11670 return lname == rname;
11673 return (!llinkage_name.empty()
11674 && !rlinkage_name.empty()
11675 && llinkage_name == rlinkage_name);
11707 try_canonical_die_comparison(
const reader& rdr,
11708 Dwarf_Off l_offset, Dwarf_Off r_offset,
11710 bool& l_has_canonical_die_offset,
11711 bool& r_has_canonical_die_offset,
11712 Dwarf_Off& l_canonical_die_offset,
11713 Dwarf_Off& r_canonical_die_offset,
11716 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11717 if (rdr.debug_die_canonicalization_is_on_
11718 && !rdr.use_canonical_die_comparison_)
11723 l_has_canonical_die_offset =
11724 (l_canonical_die_offset =
11725 rdr.get_canonical_die_offset(l_offset, l_die_source,
11728 r_has_canonical_die_offset =
11729 (r_canonical_die_offset =
11730 rdr.get_canonical_die_offset(r_offset, r_die_source,
11733 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
11735 result = (l_canonical_die_offset == r_canonical_die_offset);
11742 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11755 notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
11759 #define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
11760 notify_die_comparison_failed(l, r)
11762 #define NOTIFY_DIE_COMPARISON_FAILED(l, r)
11775 #define ABG_RETURN(value) \
11778 if ((value) == COMPARISON_RESULT_DIFFERENT) \
11780 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11782 return return_comparison_result(l, r, dies_being_compared, \
11783 value, aggregates_being_compared, \
11784 update_canonical_dies_on_the_fly); \
11795 #define ABG_RETURN_FALSE \
11798 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11799 return return_comparison_result(l, r, dies_being_compared, \
11800 COMPARISON_RESULT_DIFFERENT, \
11801 aggregates_being_compared, \
11802 update_canonical_dies_on_the_fly); \
11817 #define SET_RESULT_TO_FALSE(result, l , r) \
11820 result = COMPARISON_RESULT_DIFFERENT; \
11821 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11837 #define SET_RESULT_TO(result, value, l , r) \
11840 result = (value); \
11841 if (result == COMPARISON_RESULT_DIFFERENT) \
11843 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11847 #define RETURN_IF_COMPARISON_CYCLE_DETECTED \
11850 if (aggregates_being_compared.contains(dies_being_compared)) \
11852 result = COMPARISON_RESULT_CYCLE_DETECTED; \
11853 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
11854 ABG_RETURN(result); \
11869 get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
11874 bool found_member =
false;
11875 for (found_member = (dwarf_siblingof(const_cast<Dwarf_Die*>(die),
11878 found_member = (dwarf_siblingof(member, member) == 0))
11880 int tag = dwarf_tag(member);
11881 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
11885 return found_member;
11902 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
11907 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
11909 || tag == DW_TAG_union_type
11910 || tag == DW_TAG_class_type);
11912 bool found_child = (dwarf_child(const_cast<Dwarf_Die*>(die), child) == 0);
11917 tag = dwarf_tag(child);
11919 if (!(tag == DW_TAG_member
11920 || tag == DW_TAG_inheritance
11921 || tag == DW_TAG_subprogram))
11922 found_child = get_next_member_sibling_die(child, child);
11924 return found_child;
11947 maybe_propagate_canonical_type(
const reader& rdr,
11948 const Dwarf_Die* l,
11949 const Dwarf_Die* r)
11951 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l)),
11952 r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
11954 if (l_tag != r_tag)
11957 if (is_canon_type_to_be_propagated_tag(l_tag))
11958 propagate_canonical_type(rdr, l, r);
11976 propagate_canonical_type(
const reader& rdr,
11977 const Dwarf_Die* l,
11978 const Dwarf_Die* r)
11987 const die_source l_source = rdr.get_die_source(l);
11988 const die_source r_source = rdr.get_die_source(r);
11990 Dwarf_Off l_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(l));
11991 Dwarf_Off r_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(r));
11992 bool l_has_canonical_die_offset =
false;
11993 bool r_has_canonical_die_offset =
false;
11994 Dwarf_Off l_canonical_die_offset = 0;
11995 Dwarf_Off r_canonical_die_offset = 0;
11997 l_has_canonical_die_offset =
11998 (l_canonical_die_offset =
11999 rdr.get_canonical_die_offset(l_offset, l_source,
12002 r_has_canonical_die_offset =
12003 (r_canonical_die_offset =
12004 rdr.get_canonical_die_offset(r_offset, r_source,
12008 if (!l_has_canonical_die_offset
12009 && r_has_canonical_die_offset
12012 && l_source == r_source)
12015 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
12017 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
12018 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
12019 rdr.canonical_propagated_count_++;
12057 return_comparison_result(
const Dwarf_Die* l,
12058 const Dwarf_Die* r,
12059 const offset_pair_type& cur_dies,
12061 offset_pairs_stack_type& comparison_stack,
12062 bool do_propagate_canonical_type =
true)
12064 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
12066 if (result == COMPARISON_RESULT_EQUAL)
12071 if (do_propagate_canonical_type)
12074 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12080 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
12093 else if (result == COMPARISON_RESULT_UNKNOWN)
12134 if (comparison_stack.is_redundant(cur_dies)
12135 && comparison_stack.vect_.back() == cur_dies)
12139 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12140 comparison_stack.confirm_canonical_propagated_type(cur_dies);
12142 result = COMPARISON_RESULT_EQUAL;
12144 else if (is_canon_type_to_be_propagated_tag(l_tag)
12145 && comparison_stack.vect_.back() == cur_dies)
12150 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
12151 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12155 else if (result == COMPARISON_RESULT_DIFFERENT)
12172 if (comparison_stack.is_redundant(cur_dies)
12173 && comparison_stack.vect_.back() == cur_dies)
12174 comparison_stack.cancel_canonical_propagated_type(cur_dies);
12182 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
12183 result = COMPARISON_RESULT_UNKNOWN;
12184 else if (is_canon_type_to_be_propagated_tag(l_tag)
12185 && !comparison_stack.vect_.empty()
12186 && comparison_stack.vect_.back() == cur_dies)
12191 comparison_stack.erase(cur_dies);
12193 maybe_cache_type_comparison_result(comparison_stack.rdr_,
12194 l_tag, cur_dies, result);
12223 compare_dies(
const reader& rdr,
12224 const Dwarf_Die *l,
const Dwarf_Die *r,
12225 offset_pairs_stack_type& aggregates_being_compared,
12226 bool update_canonical_dies_on_the_fly)
12231 const die_source l_die_source = rdr.get_die_source(l);
12232 const die_source r_die_source = rdr.get_die_source(r);
12234 offset_type l_offset =
12237 dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
12240 offset_type r_offset =
12243 dwarf_dieoffset(const_cast<Dwarf_Die*>(r))
12246 offset_pair_type dies_being_compared(l_offset, r_offset);
12248 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l)),
12249 r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
12251 if (l_tag != r_tag)
12254 if (l_offset == r_offset)
12255 return COMPARISON_RESULT_EQUAL;
12257 if (rdr.leverage_dwarf_factorization()
12258 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
12259 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
12260 if (l_offset != r_offset)
12261 return COMPARISON_RESULT_DIFFERENT;
12264 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
12265 dies_being_compared,
12269 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
12270 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
12274 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
12276 bool canonical_compare_result =
false;
12277 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
12278 l_die_source, r_die_source,
12279 l_has_canonical_die_offset,
12280 r_has_canonical_die_offset,
12281 l_canonical_die_offset,
12282 r_canonical_die_offset,
12283 canonical_compare_result))
12287 (canonical_compare_result
12288 ? COMPARISON_RESULT_EQUAL
12289 : COMPARISON_RESULT_DIFFERENT),
12299 case DW_TAG_base_type:
12300 case DW_TAG_string_type:
12301 case DW_TAG_unspecified_type:
12302 if (!compare_as_decl_and_type_dies(rdr, l, r))
12306 case DW_TAG_typedef:
12307 case DW_TAG_pointer_type:
12308 case DW_TAG_reference_type:
12309 case DW_TAG_rvalue_reference_type:
12310 case DW_TAG_const_type:
12311 case DW_TAG_volatile_type:
12312 case DW_TAG_restrict_type:
12314 if (!compare_as_type_dies(rdr, l, r))
12320 bool from_the_same_tu =
false;
12321 if (!pointer_or_qual_die_of_anonymous_class_type(l)
12322 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
12323 && from_the_same_tu)
12340 Dwarf_Die lu_type_die, ru_type_die;
12341 bool lu_is_void, ru_is_void;
12343 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
12344 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
12346 if (lu_is_void && ru_is_void)
12347 result = COMPARISON_RESULT_EQUAL;
12348 else if (lu_is_void != ru_is_void)
12351 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
12352 aggregates_being_compared,
12353 update_canonical_dies_on_the_fly);
12357 case DW_TAG_enumeration_type:
12358 if (!compare_as_decl_and_type_dies(rdr, l, r))
12363 Dwarf_Die l_enumtor, r_enumtor;
12364 bool found_l_enumtor =
true, found_r_enumtor =
true;
12366 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
12367 for (found_l_enumtor = dwarf_child(const_cast<Dwarf_Die*>(l),
12369 found_r_enumtor = dwarf_child(const_cast<Dwarf_Die*>(r),
12371 found_l_enumtor && found_r_enumtor;
12372 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
12373 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
12375 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
12376 if ( l_tag != r_tag)
12382 if (l_tag != DW_TAG_enumerator)
12385 uint64_t l_val = 0, r_val = 0;
12386 die_unsigned_constant_attribute(&l_enumtor,
12389 die_unsigned_constant_attribute(&r_enumtor,
12392 if (l_val != r_val)
12398 if (found_l_enumtor != found_r_enumtor )
12403 case DW_TAG_structure_type:
12404 case DW_TAG_union_type:
12405 case DW_TAG_class_type:
12407 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12409 rdr.compare_count_++;
12411 if (!compare_as_decl_and_type_dies(rdr, l, r))
12413 else if (rdr.options().assume_odr_for_cplusplus
12414 && rdr.odr_is_relevant(l)
12415 && rdr.odr_is_relevant(r)
12416 && !die_is_anonymous(l)
12417 && !die_is_anonymous(r))
12418 result = COMPARISON_RESULT_EQUAL;
12421 aggregates_being_compared.add(dies_being_compared);
12423 Dwarf_Die l_member, r_member;
12424 bool found_l_member =
true, found_r_member =
true;
12426 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
12427 for (found_l_member = get_member_child_die(l, &l_member),
12428 found_r_member = get_member_child_die(r, &r_member);
12429 found_l_member && found_r_member;
12430 found_l_member = get_next_member_sibling_die(&l_member,
12432 found_r_member = get_next_member_sibling_die(&r_member,
12435 int l_tag = dwarf_tag(&l_member),
12436 r_tag = dwarf_tag(&r_member);
12438 if (l_tag != r_tag)
12445 || l_tag == DW_TAG_variable
12446 || l_tag == DW_TAG_inheritance
12447 || l_tag == DW_TAG_subprogram);
12450 compare_dies(rdr, &l_member, &r_member,
12451 aggregates_being_compared,
12452 update_canonical_dies_on_the_fly);
12454 if (local_result == COMPARISON_RESULT_UNKNOWN)
12463 result = local_result;
12465 if (local_result == COMPARISON_RESULT_DIFFERENT)
12471 if (found_l_member != found_r_member)
12480 case DW_TAG_array_type:
12482 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12484 aggregates_being_compared.add(dies_being_compared);
12486 rdr.compare_count_++;
12488 Dwarf_Die l_child, r_child;
12489 bool found_l_child, found_r_child;
12490 for (found_l_child = dwarf_child(const_cast<Dwarf_Die*>(l),
12492 found_r_child = dwarf_child(const_cast<Dwarf_Die*>(r),
12494 found_l_child && found_r_child;
12495 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
12496 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
12498 int l_child_tag = dwarf_tag(&l_child),
12499 r_child_tag = dwarf_tag(&r_child);
12500 if (l_child_tag == DW_TAG_subrange_type
12501 || r_child_tag == DW_TAG_subrange_type)
12503 result = compare_dies(rdr, &l_child, &r_child,
12504 aggregates_being_compared,
12505 update_canonical_dies_on_the_fly);
12513 if (found_l_child != found_r_child)
12516 Dwarf_Die ltype_die, rtype_die;
12517 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
12518 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
12521 result = compare_dies(rdr, <ype_die, &rtype_die,
12522 aggregates_being_compared,
12523 update_canonical_dies_on_the_fly);
12529 case DW_TAG_subrange_type:
12531 uint64_t l_lower_bound = 0, r_lower_bound = 0,
12532 l_upper_bound = 0, r_upper_bound = 0;
12533 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
12534 l_upper_bound_set =
false, r_upper_bound_set =
false;
12536 l_lower_bound_set =
12537 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
12538 r_lower_bound_set =
12539 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
12541 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
12544 uint64_t l_count = 0;
12545 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
12547 l_upper_bound = l_lower_bound + l_count;
12548 l_upper_bound_set =
true;
12554 l_upper_bound_set =
true;
12556 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
12559 uint64_t r_count = 0;
12560 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
12562 r_upper_bound = r_lower_bound + r_count;
12563 r_upper_bound_set =
true;
12569 r_upper_bound_set =
true;
12571 if ((l_lower_bound_set != r_lower_bound_set)
12572 || (l_upper_bound_set != r_upper_bound_set)
12573 || (l_lower_bound != r_lower_bound)
12574 || (l_upper_bound != r_upper_bound))
12579 case DW_TAG_subroutine_type:
12580 case DW_TAG_subprogram:
12582 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12584 aggregates_being_compared.add(dies_being_compared);
12586 rdr.compare_count_++;
12588 if (l_tag == DW_TAG_subprogram
12589 && !fn_die_equal_by_linkage_name(l, r))
12594 else if (l_tag == DW_TAG_subprogram
12595 && die_is_in_c(l) && die_is_in_c(r))
12597 result = COMPARISON_RESULT_EQUAL;
12600 else if (!die_is_in_c(l) && !die_is_in_c(r))
12606 Dwarf_Die l_return_type, r_return_type;
12607 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
12609 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
12611 if (l_return_type_is_void != r_return_type_is_void
12612 || (!l_return_type_is_void
12613 && !compare_dies(rdr,
12614 &l_return_type, &r_return_type,
12615 aggregates_being_compared,
12616 update_canonical_dies_on_the_fly)))
12620 Dwarf_Die l_child, r_child;
12621 bool found_l_child, found_r_child;
12622 for (found_l_child = dwarf_child(const_cast<Dwarf_Die*>(l),
12624 found_r_child = dwarf_child(const_cast<Dwarf_Die*>(r),
12626 found_l_child && found_r_child;
12627 found_l_child = dwarf_siblingof(&l_child,
12629 found_r_child = dwarf_siblingof(&r_child,
12632 int l_child_tag = dwarf_tag(&l_child);
12633 int r_child_tag = dwarf_tag(&r_child);
12635 COMPARISON_RESULT_EQUAL;
12636 if (l_child_tag != r_child_tag)
12637 local_result = COMPARISON_RESULT_DIFFERENT;
12638 if (l_child_tag == DW_TAG_formal_parameter)
12640 compare_dies(rdr, &l_child, &r_child,
12641 aggregates_being_compared,
12642 update_canonical_dies_on_the_fly);
12643 if (local_result == COMPARISON_RESULT_DIFFERENT)
12645 result = local_result;
12649 if (local_result == COMPARISON_RESULT_UNKNOWN)
12660 result = local_result;
12662 if (found_l_child != found_r_child)
12672 case DW_TAG_formal_parameter:
12674 Dwarf_Die l_type, r_type;
12675 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
12676 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
12677 if (l_type_is_void != r_type_is_void)
12679 else if (!l_type_is_void)
12682 compare_dies(rdr, &l_type, &r_type,
12683 aggregates_being_compared,
12684 update_canonical_dies_on_the_fly);
12690 case DW_TAG_variable:
12691 case DW_TAG_member:
12692 if (compare_as_decl_dies(l, r))
12695 if (l_tag == DW_TAG_member)
12697 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
12698 die_member_offset(rdr, l, l_offset_in_bits);
12699 die_member_offset(rdr, r, r_offset_in_bits);
12700 if (l_offset_in_bits != r_offset_in_bits)
12706 Dwarf_Die l_type, r_type;
12707 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12708 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12710 compare_dies(rdr, &l_type, &r_type,
12711 aggregates_being_compared,
12712 update_canonical_dies_on_the_fly);
12720 case DW_TAG_inheritance:
12722 Dwarf_Die l_type, r_type;
12723 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12724 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12725 result = compare_dies(rdr, &l_type, &r_type,
12726 aggregates_being_compared,
12727 update_canonical_dies_on_the_fly);
12731 uint64_t l_a = 0, r_a = 0;
12732 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
12733 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
12737 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
12738 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
12742 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
12743 die_member_offset(rdr, l, l_offset_in_bits);
12744 die_member_offset(rdr, r, r_offset_in_bits);
12745 if (l_offset_in_bits != r_offset_in_bits)
12750 case DW_TAG_ptr_to_member_type:
12752 bool comp_result =
false;
12753 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
12757 Dwarf_Die l_type, r_type;
12758 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12759 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12760 result = compare_dies(rdr, &l_type, &r_type,
12761 aggregates_being_compared,
12762 update_canonical_dies_on_the_fly);
12766 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
12767 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
12768 result = compare_dies(rdr, &l_type, &r_type,
12769 aggregates_being_compared,
12770 update_canonical_dies_on_the_fly);
12776 case DW_TAG_enumerator:
12777 case DW_TAG_packed_type:
12778 case DW_TAG_set_type:
12779 case DW_TAG_file_type:
12780 case DW_TAG_thrown_type:
12781 case DW_TAG_interface_type:
12782 case DW_TAG_shared_type:
12783 case DW_TAG_compile_unit:
12784 case DW_TAG_namespace:
12785 case DW_TAG_module:
12786 case DW_TAG_constant:
12787 case DW_TAG_partial_unit:
12788 case DW_TAG_imported_unit:
12789 case DW_TAG_dwarf_procedure:
12790 case DW_TAG_imported_declaration:
12791 case DW_TAG_entry_point:
12793 case DW_TAG_lexical_block:
12794 case DW_TAG_unspecified_parameters:
12795 case DW_TAG_variant:
12796 case DW_TAG_common_block:
12797 case DW_TAG_common_inclusion:
12798 case DW_TAG_inlined_subroutine:
12799 case DW_TAG_with_stmt:
12800 case DW_TAG_access_declaration:
12801 case DW_TAG_catch_block:
12802 case DW_TAG_friend:
12803 case DW_TAG_namelist:
12804 case DW_TAG_namelist_item:
12805 case DW_TAG_template_type_parameter:
12806 case DW_TAG_template_value_parameter:
12807 case DW_TAG_try_block:
12808 case DW_TAG_variant_part:
12809 case DW_TAG_imported_module:
12810 case DW_TAG_condition:
12811 case DW_TAG_type_unit:
12812 case DW_TAG_template_alias:
12813 case DW_TAG_lo_user:
12814 case DW_TAG_MIPS_loop:
12815 case DW_TAG_format_label:
12816 case DW_TAG_function_template:
12817 case DW_TAG_class_template:
12818 case DW_TAG_GNU_BINCL:
12819 case DW_TAG_GNU_EINCL:
12820 case DW_TAG_GNU_template_template_param:
12821 case DW_TAG_GNU_template_parameter_pack:
12822 case DW_TAG_GNU_formal_parameter_pack:
12823 case DW_TAG_GNU_call_site:
12824 case DW_TAG_GNU_call_site_parameter:
12825 case DW_TAG_hi_user:
12826 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
12827 if (rdr.debug_die_canonicalization_is_on_)
12854 compare_dies(
const reader& rdr,
12855 const Dwarf_Die *l,
12856 const Dwarf_Die *r,
12857 bool update_canonical_dies_on_the_fly)
12859 offset_pairs_stack_type aggregates_being_compared(rdr);
12860 return compare_dies(rdr, l, r, aggregates_being_compared,
12861 update_canonical_dies_on_the_fly);
12883 compare_dies_during_canonicalization(reader& rdr,
12884 const Dwarf_Die *l,
12885 const Dwarf_Die *r,
12886 bool update_canonical_dies_on_the_fly)
12888 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
12889 if (rdr.debug_die_canonicalization_is_on_)
12891 bool canonical_equality =
false, structural_equality =
false;
12892 rdr.use_canonical_die_comparison_ =
false;
12893 structural_equality = compare_dies(rdr, l, r,
12895 rdr.use_canonical_die_comparison_ =
true;
12896 canonical_equality = compare_dies(rdr, l, r,
12897 update_canonical_dies_on_the_fly);
12898 if (canonical_equality != structural_equality)
12900 std::cerr <<
"structural & canonical equality different for DIEs: "
12902 <<
"l: " << dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
12903 <<
", r: " << dwarf_dieoffset(const_cast<Dwarf_Die*>(r))
12906 << rdr.get_die_pretty_type_representation(l, 0)
12911 return structural_equality;
12914 return compare_dies(rdr, l, r,
12915 update_canonical_dies_on_the_fly);
12957 find_import_unit_point_between_dies(
const reader& rdr,
12958 size_t partial_unit_offset,
12959 Dwarf_Off first_die_offset,
12960 Dwarf_Off first_die_cu_offset,
12962 size_t last_die_offset,
12963 size_t& imported_point_offset)
12966 rdr.tu_die_imported_unit_points_map(source);
12968 tu_die_imported_unit_points_map_type::const_iterator iter =
12969 tu_die_imported_unit_points_map.find(first_die_cu_offset);
12971 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
12973 const imported_unit_points_type& imported_unit_points = iter->second;
12974 if (imported_unit_points.empty())
12977 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
12978 imported_unit_points_type::const_iterator e = imported_unit_points.end();
12980 find_lower_bound_in_imported_unit_points(imported_unit_points,
12984 if (last_die_offset != static_cast<size_t>(-1))
12985 find_lower_bound_in_imported_unit_points(imported_unit_points,
12989 if (e != imported_unit_points.end())
12991 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
12992 if (i->imported_unit_die_off == partial_unit_offset)
12994 imported_point_offset = i->offset_of_import ;
12998 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
13000 if (find_import_unit_point_between_dies(rdr,
13001 partial_unit_offset,
13002 i->imported_unit_child_off,
13003 i->imported_unit_cu_off,
13004 i->imported_unit_die_source,
13006 imported_point_offset))
13012 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
13013 if (i->imported_unit_die_off == partial_unit_offset)
13015 imported_point_offset = i->offset_of_import ;
13019 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
13021 if (find_import_unit_point_between_dies(rdr,
13022 partial_unit_offset,
13023 i->imported_unit_child_off,
13024 i->imported_unit_cu_off,
13025 i->imported_unit_die_source,
13027 imported_point_offset))
13060 find_import_unit_point_before_die(
const reader& rdr,
13061 size_t partial_unit_offset,
13062 size_t where_offset,
13063 size_t& imported_point_offset)
13065 size_t import_point_offset = 0;
13066 Dwarf_Die first_die_of_tu;
13068 if (dwarf_child(const_cast<Dwarf_Die*>(rdr.cur_tu_die()),
13069 &first_die_of_tu) != 0)
13072 Dwarf_Die cu_die_memory;
13075 cu_die = dwarf_diecu(const_cast<Dwarf_Die*>(&first_die_of_tu),
13076 &cu_die_memory, 0, 0);
13078 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
13079 dwarf_dieoffset(&first_die_of_tu),
13080 dwarf_dieoffset(cu_die),
13081 PRIMARY_DEBUG_INFO_DIE_SOURCE,
13083 import_point_offset))
13085 imported_point_offset = import_point_offset;
13089 if (import_point_offset)
13091 imported_point_offset = import_point_offset;
13119 get_parent_die(
const reader& rdr,
13120 const Dwarf_Die* die,
13121 Dwarf_Die& parent_die,
13122 size_t where_offset)
13126 const die_source source = rdr.get_die_source(die);
13128 const offset_offset_map_type& m = rdr.die_parent_map(source);
13129 offset_offset_map_type::const_iterator i =
13130 m.find(dwarf_dieoffset(const_cast<Dwarf_Die*>(die)));
13137 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
13138 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(rdr.dwarf_debug_info()),
13139 i->second, &parent_die));
13141 case ALT_DEBUG_INFO_DIE_SOURCE:
13142 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(rdr.alternate_dwarf_debug_info()),
13143 i->second, &parent_die));
13145 case TYPE_UNIT_DIE_SOURCE:
13146 ABG_ASSERT(dwarf_offdie_types(const_cast<Dwarf*>(rdr.dwarf_debug_info()),
13147 i->second, &parent_die));
13149 case NO_DEBUG_INFO_DIE_SOURCE:
13150 case NUMBER_OF_DIE_SOURCES:
13154 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
13156 if (where_offset == 0)
13158 parent_die = *rdr.cur_tu_die();
13161 size_t import_point_offset = 0;
13163 find_import_unit_point_before_die(rdr,
13164 dwarf_dieoffset(&parent_die),
13166 import_point_offset);
13172 parent_die = *rdr.cur_tu_die();
13176 Dwarf_Die import_point_die;
13177 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(rdr.dwarf_debug_info()),
13178 import_point_offset,
13179 &import_point_die));
13180 return get_parent_die(rdr, &import_point_die,
13181 parent_die, where_offset);
13214 get_scope_die(
const reader& rdr,
13215 const Dwarf_Die* dye,
13216 size_t where_offset,
13217 Dwarf_Die& scope_die)
13219 Dwarf_Die origin_die_mem;
13220 Dwarf_Die *die = &origin_die_mem;
13221 if (!die_origin_die(dye, origin_die_mem))
13222 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
13225 get_die_language(die, die_lang);
13227 || rdr.die_parent_map(rdr.get_die_source(die)).empty())
13229 ABG_ASSERT(dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_member);
13230 return dwarf_diecu(const_cast<Dwarf_Die*>(die), &scope_die, 0, 0);
13233 if (!get_parent_die(rdr, die, scope_die, where_offset))
13236 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
13237 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
13238 || dwarf_tag(&scope_die) == DW_TAG_array_type)
13239 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
13269 get_scope_for_die(reader& rdr,
13271 bool called_for_public_decl,
13272 size_t where_offset)
13274 Dwarf_Die origin_die_mem;
13275 Dwarf_Die *die = &origin_die_mem;
13277 if (!die_origin_die(dye, origin_die_mem))
13280 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
13282 const die_source source_of_die = rdr.get_die_source(die);
13285 get_die_language(die, die_lang);
13287 || rdr.die_parent_map(source_of_die).empty())
13292 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
13293 return rdr.global_scope();
13296 Dwarf_Die parent_die;
13298 if (!get_parent_die(rdr, die, parent_die, where_offset))
13299 return rdr.nil_scope();
13301 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
13302 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
13303 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
13305 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
13306 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
13308 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
13309 || source_of_die == TYPE_UNIT_DIE_SOURCE);
13310 return rdr.cur_transl_unit()->get_global_scope();
13319 die_tu_map_type::const_iterator i =
13320 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
13321 if (i != rdr.die_tu_map().end())
13322 return i->second->get_global_scope();
13323 return rdr.cur_transl_unit()->get_global_scope();
13328 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
13329 || dwarf_tag(&parent_die) == DW_TAG_array_type
13330 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
13342 called_for_public_decl,
13351 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
13352 return rdr.nil_scope();
13353 s = get_scope_for_die(rdr, &parent_die,
13354 called_for_public_decl,
13360 d = build_ir_node_from_die(rdr, &parent_die,
13361 called_for_public_decl,
13363 s = dynamic_pointer_cast<scope_decl>(d);
13367 return rdr.nil_scope();
13370 if (cl && cl->get_is_declaration_only())
13373 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
13390 dwarf_language_to_tu_language(
size_t l)
13395 return translation_unit::LANG_C89;
13397 return translation_unit::LANG_C99;
13398 #ifdef HAVE_DW_LANG_C11_enumerator
13400 return translation_unit::LANG_C11;
13402 #ifdef HAVE_DW_LANG_C17
13404 return translation_unit::LANG_C17;
13406 #ifdef HAVE_DW_LANG_C23
13408 return translation_unit::LANG_C23;
13411 return translation_unit::LANG_C;
13412 #ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
13413 case DW_LANG_C_plus_plus_03:
13414 return translation_unit::LANG_C_plus_plus_03;
13417 #ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
13418 case DW_LANG_C_plus_plus_11:
13419 return translation_unit::LANG_C_plus_plus_11;
13422 #ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
13423 case DW_LANG_C_plus_plus_14:
13424 return translation_unit::LANG_C_plus_plus_14;
13426 #ifdef HAVE_DW_LANG_C_plus_plus_17
13427 case DW_LANG_C_plus_plus_17:
13428 return translation_unit::LANG_C_plus_plus_17;
13431 #ifdef HAVE_DW_LANG_C_plus_plus_20
13432 case DW_LANG_C_plus_plus_20:
13433 return translation_unit::LANG_C_plus_plus_20;
13435 #ifdef HAVE_DW_LANG_C_plus_plus_23
13436 case DW_LANG_C_plus_plus_23:
13437 return translation_unit::LANG_C_plus_plus_23;
13439 case DW_LANG_C_plus_plus:
13440 return translation_unit::LANG_C_plus_plus;
13441 #ifdef HAVE_DW_LANG_D_enumerator
13443 return translation_unit::LANG_D;
13445 #ifdef HAVE_DW_LANG_OCaml_enumerator
13446 case DW_LANG_OCaml:
13447 return translation_unit::LANG_OCaml;
13449 #ifdef HAVE_DW_LANG_Go_enumerator
13451 return translation_unit::LANG_Go;
13453 #ifdef HAVE_DW_LANG_Rust_enumerator
13455 return translation_unit::LANG_Rust;
13457 #ifdef HAVE_DW_LANG_Zig
13459 return translation_unit::LANG_Zig;
13461 #ifdef HAVE_DW_LANG_Metal
13462 case DW_LANG_Metal:
13463 return translation_unit::LANG_Metal;
13465 case DW_LANG_Ada83:
13466 return translation_unit::LANG_Ada83;
13467 case DW_LANG_Ada95:
13468 return translation_unit::LANG_Ada95;
13469 #ifdef HAVE_DW_LANG_Ada2005
13470 case DW_LANG_Ada2005:
13471 return translation_unit::LANG_Ada2005;
13474 #ifdef HAVE_DW_LANG_Ada2012
13475 case DW_LANG_Ada2012:
13476 return translation_unit::LANG_Ada2012;
13478 case DW_LANG_Cobol74:
13479 return translation_unit::LANG_Cobol74;
13480 case DW_LANG_Cobol85:
13481 return translation_unit::LANG_Cobol85;
13482 case DW_LANG_Fortran77:
13483 return translation_unit::LANG_Fortran77;
13484 case DW_LANG_Fortran90:
13485 return translation_unit::LANG_Fortran90;
13486 case DW_LANG_Fortran95:
13487 return translation_unit::LANG_Fortran95;
13488 #ifdef HAVE_DW_LANG_Fortran18
13489 case DW_LANG_Fortran18:
13490 return translation_unit::LANG_Fortran18;
13492 #ifdef HAVE_DW_LANG_Fortran23
13493 case DW_LANG_Fortran23:
13494 return translation_unit::LANG_Fortran23;
13496 case DW_LANG_Pascal83:
13497 return translation_unit::LANG_Pascal83;
13498 case DW_LANG_Modula2:
13499 return translation_unit::LANG_Modula2;
13501 return translation_unit::LANG_Java;
13502 #ifdef HAVE_DW_LANG_Kotlin
13503 case DW_LANG_Kotlin:
13504 return translation_unit::LANG_Kotlin;
13507 return translation_unit::LANG_PLI;
13509 return translation_unit::LANG_ObjC;
13510 case DW_LANG_ObjC_plus_plus:
13511 return translation_unit::LANG_ObjC_plus_plus;
13513 #ifdef HAVE_DW_LANG_UPC_enumerator
13515 return translation_unit::LANG_UPC;
13517 #ifdef HAVE_DW_LANG_Python_enumerator
13518 case DW_LANG_Python:
13519 return translation_unit::LANG_Python;
13521 #ifdef HAVE_DW_LANG_Ruby
13523 return translation_unit::LANG_Ruby;
13525 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
13526 case DW_LANG_Mips_Assembler:
13527 return translation_unit::LANG_Mips_Assembler;
13529 #ifdef HAVE_DW_LANG_Assembly
13530 case DW_LANG_Assembly:
13531 return translation_unit::LANG_Assembly;
13533 #ifdef HAVE_DW_LANG_Crystal
13534 case DW_LANG_Crystal:
13535 return translation_unit::LANG_Crystal;
13537 #ifdef HAVE_DW_LANG_HIP
13539 return translation_unit::LANG_HIP;
13541 #ifdef HAVE_DW_LANG_C_sharp
13542 case DW_LANG_C_sharp:
13543 return translation_unit::LANG_C_sharp;
13545 #ifdef HAVE_DW_LANG_Mojo
13547 return translation_unit::LANG_Mojo;
13549 #ifdef HAVE_DW_LANG_GLSL
13551 return translation_unit::LANG_GLSL;
13553 #ifdef HAVE_DW_LANG_GLSL_ES
13554 case DW_LANG_GLSL_ES:
13555 return translation_unit::LANG_GLSL_ES;
13557 #ifdef HAVE_DW_LANG_HLSL
13559 return translation_unit::LANG_HLSL;
13561 #ifdef HAVE_DW_LANG_OpenCL_CPP
13562 case DW_LANG_OpenCL_CPP:
13563 return translation_unit::LANG_OpenCL_CPP;
13565 #ifdef HAVE_DW_LANG_CPP_for_OpenCL
13566 case DW_LANG_CPP_for_OpenCL:
13567 return translation_unit::LANG_CPP_for_OpenCL;
13569 #ifdef HAVE_DW_LANG_SYCL
13571 return translation_unit::LANG_SYCL;
13573 #ifdef HAVE_DW_LANG_Odin
13575 return translation_unit::LANG_Odin;
13577 #ifdef HAVE_DW_LANG_P4
13579 return translation_unit::LANG_P4;
13581 #ifdef HAVE_DW_LANG_Move
13583 return translation_unit::LANG_Move;
13585 #ifdef HAVE_DW_LANG_Hylo
13587 return translation_unit::LANG_Hylo;
13591 return translation_unit::LANG_UNKNOWN;
13608 case translation_unit::LANG_UNKNOWN:
13609 case translation_unit::LANG_C89:
13610 case translation_unit::LANG_C99:
13611 case translation_unit::LANG_C11:
13612 case translation_unit::LANG_C17:
13613 case translation_unit::LANG_C23:
13614 case translation_unit::LANG_C:
13615 case translation_unit::LANG_C_plus_plus_03:
13616 case translation_unit::LANG_C_plus_plus_11:
13617 case translation_unit::LANG_C_plus_plus_14:
13618 case translation_unit::LANG_C_plus_plus_17:
13619 case translation_unit::LANG_C_plus_plus_20:
13620 case translation_unit::LANG_C_plus_plus_23:
13621 case translation_unit::LANG_C_plus_plus:
13622 case translation_unit::LANG_OCaml:
13623 case translation_unit::LANG_ObjC:
13624 case translation_unit::LANG_ObjC_plus_plus:
13625 case translation_unit::LANG_D:
13626 case translation_unit::LANG_Rust:
13627 case translation_unit::LANG_Go:
13628 case translation_unit::LANG_Zig:
13629 case translation_unit::LANG_Metal:
13630 case translation_unit::LANG_Java:
13631 case translation_unit::LANG_Kotlin:
13632 case translation_unit::LANG_Python:
13633 case translation_unit::LANG_Ruby:
13634 case translation_unit::LANG_UPC:
13635 case translation_unit::LANG_Mips_Assembler:
13636 case translation_unit::LANG_Assembly:
13637 case translation_unit::LANG_Crystal:
13638 case translation_unit::LANG_HIP:
13639 case translation_unit::LANG_C_sharp:
13640 case translation_unit::LANG_Mojo:
13641 case translation_unit::LANG_GLSL:
13642 case translation_unit::LANG_GLSL_ES:
13643 case translation_unit::LANG_HLSL:
13644 case translation_unit::LANG_Odin:
13645 case translation_unit::LANG_P4:
13646 case translation_unit::LANG_OpenCL_CPP:
13647 case translation_unit::LANG_CPP_for_OpenCL:
13648 case translation_unit::LANG_SYCL:
13649 case translation_unit::LANG_Move:
13650 case translation_unit::LANG_Hylo:
13653 case translation_unit::LANG_Cobol74:
13654 case translation_unit::LANG_Cobol85:
13655 case translation_unit::LANG_Fortran77:
13656 case translation_unit::LANG_Fortran90:
13657 case translation_unit::LANG_Fortran95:
13658 case translation_unit::LANG_Fortran18:
13659 case translation_unit::LANG_Fortran23:
13660 case translation_unit::LANG_Ada83:
13661 case translation_unit::LANG_Ada95:
13662 case translation_unit::LANG_Ada2005:
13663 case translation_unit::LANG_Ada2012:
13664 case translation_unit::LANG_Pascal83:
13665 case translation_unit::LANG_Modula2:
13666 case translation_unit::LANG_PLI:
13691 find_lower_bound_in_imported_unit_points(
const imported_unit_points_type& p,
13693 imported_unit_points_type::const_iterator& r)
13695 imported_unit_point v(val);
13696 imported_unit_points_type::const_iterator result =
13697 std::lower_bound(p.begin(), p.end(), v);
13699 bool is_ok = result != p.end();
13721 build_translation_unit_and_add_to_ir(reader& rdr,
13729 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
13733 rdr.clear_per_translation_unit_data();
13735 rdr.cur_tu_die(die);
13737 string path = die_string_attribute(die, DW_AT_name);
13738 if (path ==
"<artificial>")
13744 std::ostringstream o;
13745 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
13748 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
13758 const string& abs_path =
13759 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
13760 result = rdr.corpus()->find_translation_unit(abs_path);
13765 result.reset(
new translation_unit(rdr.env(),
13768 result->set_compilation_dir_path(compilation_dir);
13769 rdr.corpus()->add(result);
13771 die_unsigned_constant_attribute(die, DW_AT_language, l);
13772 result->set_language(dwarf_language_to_tu_language(l));
13775 rdr.cur_transl_unit(result);
13776 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
13779 if (dwarf_child(die, &child) != 0)
13782 result->set_is_constructed(
false);
13783 int tag = dwarf_tag(&child);
13785 if (rdr.load_undefined_interfaces()
13786 && (rdr.is_decl_die_with_undefined_symbol(&child)
13787 || tag == DW_TAG_class_type
13792 || ((tag == DW_TAG_union_type || tag == DW_TAG_structure_type)
13793 && die_is_in_cplus_plus(&child))))
13797 build_ir_node_from_die(rdr, &child,
13802 dwarf_dieoffset(&child));
13804 else if (!rdr.env().analyze_exported_interfaces_only()
13805 || rdr.is_decl_die_with_exported_symbol(&child))
13809 build_ir_node_from_die(rdr, &child,
13810 die_is_public_decl(&child),
13811 dwarf_dieoffset(&child));
13813 while (dwarf_siblingof(&child, &child) == 0);
13815 if (!rdr.var_decls_to_re_add_to_tree().empty())
13816 for (list<var_decl_sptr>::const_iterator v =
13817 rdr.var_decls_to_re_add_to_tree().begin();
13818 v != rdr.var_decls_to_re_add_to_tree().end();
13825 string demangled_name =
13827 if (!demangled_name.empty())
13829 std::list<string> fqn_comps;
13831 string mem_name = fqn_comps.back();
13832 fqn_comps.pop_back();
13835 if (!fqn_comps.empty())
13863 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
13869 rdr.var_decls_to_re_add_to_tree().clear();
13871 result->set_is_constructed(
true);
13896 build_namespace_decl_and_add_to_ir(reader& rdr,
13898 size_t where_offset)
13905 unsigned tag = dwarf_tag(die);
13906 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
13913 string name, linkage_name;
13915 die_loc_and_name(rdr, die, loc, name, linkage_name);
13917 result.reset(
new namespace_decl(rdr.env(), name, loc));
13919 rdr.associate_die_to_decl(die, result, where_offset);
13922 if (dwarf_child(die, &child) != 0)
13925 rdr.scope_stack().push(result.get());
13927 build_ir_node_from_die(rdr, &child,
13933 die_is_public_decl(die) && die_is_public_decl(&child),
13935 while (dwarf_siblingof(&child, &child) == 0);
13936 rdr.scope_stack().pop();
13951 build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
13957 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
13959 uint64_t byte_size = 0, bit_size = 0;
13960 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
13961 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
13964 if (bit_size == 0 && byte_size != 0)
13966 bit_size = byte_size * 8;
13968 string type_name, linkage_name;
13970 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
13972 if (byte_size == 0)
13976 if (type_name ==
"void")
13977 result =
is_type_decl(build_ir_node_for_void_type(rdr));
13984 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13986 string normalized_type_name = type_name;
13987 real_type real_type;
13989 normalized_type_name = real_type.
to_string();
13994 if (corpus_sptr corp = rdr.corpus())
13997 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
13998 0, loc, linkage_name));
13999 rdr.associate_die_to_type(die, result, where_offset);
14017 build_enum_underlying_type(reader& rdr,
14019 uint64_t enum_size,
14020 bool is_anonymous =
true)
14022 string underlying_type_name =
14026 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
14027 enum_size, enum_size, location()));
14028 result->set_is_anonymous(is_anonymous);
14029 result->set_is_artificial(
true);
14032 result = dynamic_pointer_cast<type_decl>(d);
14034 maybe_canonicalize_type(result, rdr);
14053 build_enum_type(reader& rdr,
14056 size_t where_offset,
14057 bool is_declaration_only)
14063 unsigned tag = dwarf_tag(die);
14064 if (tag != DW_TAG_enumeration_type)
14067 string name, linkage_name;
14069 die_loc_and_name(rdr, die, loc, name, linkage_name);
14071 bool is_anonymous =
false;
14075 name = get_internal_anonymous_die_prefix_name(die);
14078 is_anonymous =
true;
14080 scope_decl* sc = scope ? scope : rdr.global_scope().get();
14081 if (
size_t s = sc->get_num_anonymous_member_enums())
14082 name = build_internal_anonymous_die_name(name, s);
14085 bool use_odr = rdr.odr_is_relevant(die);
14097 result = pre_existing_enum;
14099 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14108 if (pre_existing_enum->get_location() == loc)
14109 result = pre_existing_enum;
14114 rdr.associate_die_to_type(die, result, where_offset);
14122 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14124 bool is_artificial = die_is_artificial(die);
14127 bool enum_underlying_type_is_anonymous=
true;
14131 if (dwarf_child(die, &child) == 0)
14135 if (dwarf_tag(&child) != DW_TAG_enumerator)
14140 die_loc_and_name(rdr, &child, l, n, m);
14142 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
14143 enms.push_back(enum_type_decl::enumerator(n, val));
14145 while (dwarf_siblingof(&child, &child) == 0);
14153 build_enum_underlying_type(rdr, name, size,
14154 enum_underlying_type_is_anonymous);
14155 t->set_is_declaration_only(is_declaration_only);
14157 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
14158 result->set_is_anonymous(is_anonymous);
14159 result->set_is_declaration_only(is_declaration_only);
14160 result->set_is_artificial(is_artificial);
14161 rdr.associate_die_to_type(die, result, where_offset);
14180 finish_member_function_reading(Dwarf_Die* die,
14182 const class_or_union_sptr klass,
14193 size_t is_inline = die_is_declared_inline(die);
14194 bool is_ctor = (f->get_name() == klass->get_name());
14195 bool is_dtor = (!f->get_name().empty()
14196 &&
static_cast<string>(f->get_name())[0] ==
'~');
14197 bool is_virtual = die_is_virtual(die);
14198 int64_t vindex = -1;
14200 die_virtual_function_index(die, vindex);
14203 if (!c->is_struct())
14204 access = private_access;
14205 die_access_specifier(die, access);
14207 m->is_declared_inline(is_inline);
14211 bool is_static = method_t->get_is_for_static_method();
14219 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol()
14239 Dwarf_Off die_offset = dwarf_dieoffset(die);
14240 die_function_decl_map_type &fns_with_no_symbol =
14241 rdr.die_function_decl_with_no_symbol_map();
14242 die_function_decl_map_type::const_iterator i =
14243 fns_with_no_symbol.find(die_offset);
14244 if (i == fns_with_no_symbol.end())
14245 fns_with_no_symbol[die_offset] = f;
14266 maybe_finish_function_decl_reading(reader& rdr,
14268 size_t where_offset,
14286 static type_base_sptr
14287 lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
14290 corpus* corp = scope->get_corpus();
14311 static type_base_sptr
14312 lookup_class_or_typedef_from_corpus(reader& rdr,
14314 bool called_for_public_decl,
14315 size_t where_offset)
14320 string class_name = die_string_attribute(die, DW_AT_name);
14321 if (class_name.empty())
14325 called_for_public_decl,
14328 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
14330 return type_base_sptr();
14347 static method_decl_sptr
14348 is_function_for_die_a_member_of_class(reader& rdr,
14349 Dwarf_Die* function_die,
14350 const class_or_union_sptr& class_type)
14355 return method_decl_sptr();
14361 method_type = method->get_type();
14366 class_or_union_sptr method_class = method_type->get_class_type();
14369 string method_class_name = method_class->get_qualified_name(),
14370 class_type_name = class_type->get_qualified_name();
14372 if (method_class_name == class_type_name)
14378 return method_decl_sptr();
14400 static method_decl_sptr
14401 add_or_update_member_function(reader& rdr,
14402 Dwarf_Die* function_die,
14403 const class_or_union_sptr& class_type,
14404 bool called_from_public_decl,
14405 size_t where_offset)
14407 method_decl_sptr method =
14408 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
14411 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
14413 called_from_public_decl,
14416 return method_decl_sptr();
14418 finish_member_function_reading(function_die,
14461 add_or_update_class_type(reader& rdr,
14466 bool called_from_public_decl,
14467 size_t where_offset,
14468 bool is_declaration_only)
14474 const die_source source = rdr.get_die_source(die);
14476 unsigned tag = dwarf_tag(die);
14478 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
14482 die_class_or_union_map_type::const_iterator i =
14483 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14484 if (i != rdr.die_wip_classes_map(source).end())
14492 string name, linkage_name;
14494 die_loc_and_name(rdr, die, loc, name, linkage_name);
14495 cleanup_decl_name(name);
14497 bool is_anonymous =
false;
14502 name = get_internal_anonymous_die_prefix_name(die);
14505 is_anonymous =
true;
14509 s = scope->get_num_anonymous_member_classes();
14511 s = rdr.global_scope()->get_num_anonymous_member_classes();
14512 name = build_internal_anonymous_die_name(name, s);
14517 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14533 && (result->get_is_declaration_only() == is_declaration_only
14534 || (!result->get_is_declaration_only()
14535 && is_declaration_only)))
14537 rdr.associate_die_to_type(die, result, where_offset);
14556 klass = pre_existing_class;
14559 die_size_in_bits(die, size);
14560 bool is_artificial = die_is_artificial(die);
14563 bool has_child = (dwarf_child(die, &child) == 0);
14565 decl_base_sptr res;
14568 res = result = klass;
14569 if (has_child && klass->get_is_declaration_only()
14570 && klass->get_definition_of_declaration())
14571 res = result =
is_class_type(klass->get_definition_of_declaration());
14573 result->set_location(loc);
14577 result.reset(
new class_decl(rdr.env(), name, size,
14579 decl_base::VISIBILITY_DEFAULT,
14582 result->set_is_declaration_only(is_declaration_only);
14585 result = dynamic_pointer_cast<class_decl>(res);
14589 if (!klass || klass->get_is_declaration_only())
14590 if (size != result->get_size_in_bits())
14591 result->set_size_in_bits(size);
14596 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
14609 result->set_is_declaration_only(is_declaration_only);
14613 if (!result->get_is_declaration_only() && has_child)
14614 if (result->get_size_in_bits() == 0 && size != 0)
14615 result->set_size_in_bits(size);
14617 result->set_is_artificial(is_artificial);
14619 rdr.associate_die_to_type(die, result, where_offset);
14626 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
14628 bool is_incomplete_type =
false;
14629 if (is_declaration_only && size == 0 && has_child)
14641 is_incomplete_type =
true;
14644 dynamic_pointer_cast<scope_decl>(res);
14646 rdr.scope_stack().push(scop.get());
14648 if (has_child && !is_incomplete_type)
14652 tag = dwarf_tag(&child);
14655 if (tag == DW_TAG_inheritance)
14657 result->set_is_declaration_only(
false);
14659 Dwarf_Die type_die;
14660 if (!die_die_attribute(&child, DW_AT_type, type_die))
14663 string type_name = die_type_name(rdr, &type_die,
14666 type_base_sptr base_type;
14667 if (!type_name.empty())
14669 base_type = result->find_base_class(type_name);
14675 lookup_class_or_typedef_from_corpus(rdr, &type_die,
14676 called_from_public_decl,
14680 is_type(build_ir_node_from_die(rdr, &type_die,
14681 called_from_public_decl,
14695 die_access_specifier(&child, access);
14697 bool is_virt= die_is_virtual(&child);
14698 int64_t offset = 0;
14699 bool is_offset_present =
14700 die_member_offset(rdr, &child, offset);
14704 is_offset_present ? offset : -1,
14706 if (b->get_is_declaration_only()
14713 && !b->get_qualified_name().empty())
14714 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
14715 if (result->find_base_class(b->get_qualified_name()))
14717 result->add_base_specifier(base);
14720 else if (tag == DW_TAG_member
14721 || tag == DW_TAG_variable)
14723 Dwarf_Die type_die;
14724 if (!die_die_attribute(&child, DW_AT_type, type_die))
14729 die_loc_and_name(rdr, &child, loc, n, m);
14734 if (n.substr(0, 5) ==
"_vptr"
14736 && !std::isalnum(n.at(5))
14746 int64_t offset_in_bits = 0;
14747 bool is_laid_out = die_member_offset(rdr, &child,
14752 bool is_static = !is_laid_out;
14768 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
14769 called_from_public_decl,
14771 type_base_sptr t =
is_type(ty);
14775 if (n.empty() && !die_is_anonymous_data_member(&child))
14781 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
14798 result->set_is_declaration_only(
false);
14804 die_access_specifier(&child, access);
14812 result->add_data_member(dm, access, is_laid_out,
14813 is_static, offset_in_bits);
14815 rdr.associate_die_to_decl(&child, dm, where_offset,
14819 else if (tag == DW_TAG_subprogram)
14822 add_or_update_member_function(rdr, &child, result,
14823 called_from_public_decl,
14826 rdr.associate_die_to_decl(&child, f, where_offset,
14830 else if (die_is_type(&child))
14835 && !result->find_member_type(die_name(&child)))
14836 build_ir_node_from_die(rdr, &child, result.get(),
14837 called_from_public_decl,
14844 string anonymous_type_name =
14845 die_class_or_enum_flat_representation(rdr, &child,
14850 if (type_base_sptr member_t =
14851 result->find_member_type(anonymous_type_name))
14852 rdr.associate_die_to_decl(&child,
is_decl(member_t),
14858 is_type(build_ir_node_from_die(rdr, &child,
14860 called_from_public_decl,
14865 maybe_set_member_type_access_specifier(result,
14871 }
while (dwarf_siblingof(&child, &child) == 0);
14874 rdr.scope_stack().pop();
14877 die_class_or_union_map_type::const_iterator i =
14878 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14879 if (i != rdr.die_wip_classes_map(source).end())
14884 rdr.die_wip_classes_map(source).erase(i);
14915 static union_decl_sptr
14916 add_or_update_union_type(reader& rdr,
14919 union_decl_sptr union_type,
14920 bool called_from_public_decl,
14921 size_t where_offset,
14922 bool is_declaration_only)
14924 union_decl_sptr result;
14928 unsigned tag = dwarf_tag(die);
14930 if (tag != DW_TAG_union_type)
14933 const die_source source = rdr.get_die_source(die);
14935 die_class_or_union_map_type::const_iterator i =
14936 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14937 if (i != rdr.die_wip_classes_map(source).end())
14945 string name, linkage_name;
14947 die_loc_and_name(rdr, die, loc, name, linkage_name);
14948 cleanup_decl_name(name);
14950 bool is_anonymous =
false;
14955 name = get_internal_anonymous_die_prefix_name(die);
14958 is_anonymous =
true;
14962 s = scope->get_num_anonymous_member_unions();
14964 s = rdr.global_scope()->get_num_anonymous_member_classes();
14965 name = build_internal_anonymous_die_name(name, s);
14975 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14984 rdr.associate_die_to_type(die, result, where_offset);
14996 if (union_decl_sptr pre_existing_union =
14998 union_type = pre_existing_union;
15001 die_size_in_bits(die, size);
15002 bool is_artificial = die_is_artificial(die);
15006 result = union_type;
15007 result->set_location(loc);
15011 result.reset(
new union_decl(rdr.env(), name, size, loc,
15012 decl_base::VISIBILITY_DEFAULT,
15014 if (is_declaration_only)
15015 result->set_is_declaration_only(
true);
15022 result->set_size_in_bits(size);
15023 result->set_is_declaration_only(
false);
15026 result->set_is_artificial(is_artificial);
15028 rdr.associate_die_to_type(die, result, where_offset);
15031 bool has_child = (dwarf_child(die, &child) == 0);
15035 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
15038 dynamic_pointer_cast<scope_decl>(result);
15040 rdr.scope_stack().push(scop.get());
15046 tag = dwarf_tag(&child);
15048 if (tag == DW_TAG_member || tag == DW_TAG_variable)
15050 Dwarf_Die type_die;
15051 if (!die_die_attribute(&child, DW_AT_type, type_die))
15056 die_loc_and_name(rdr, &child, loc, n, m);
15065 ssize_t offset_in_bits = 0;
15066 decl_base_sptr ty =
15067 is_decl(build_ir_node_from_die(rdr, &type_die,
15068 called_from_public_decl,
15070 type_base_sptr t =
is_type(ty);
15077 result->set_is_declaration_only(
false);
15080 die_access_specifier(&child, access);
15086 if (n.empty() && result->find_data_member(dm))
15092 result->add_data_member(dm, access,
true,
15096 rdr.associate_die_to_decl(&child, dm, where_offset,
15100 else if (tag == DW_TAG_subprogram)
15103 is_decl(build_ir_node_from_die(rdr, &child,
15105 called_from_public_decl,
15113 finish_member_function_reading(&child, f, result, rdr);
15115 rdr.associate_die_to_decl(&child, f, where_offset,
15119 else if (die_is_type(&child))
15121 string type_name = die_type_name(rdr, &child,
15124 if (type_base_sptr member_t = result->find_member_type(type_name))
15125 rdr.associate_die_to_decl(&child,
is_decl(member_t),
15129 decl_base_sptr td =
15130 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
15131 called_from_public_decl,
15134 }
while (dwarf_siblingof(&child, &child) == 0);
15137 rdr.scope_stack().pop();
15140 die_class_or_union_map_type::const_iterator i =
15141 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
15142 if (i != rdr.die_wip_classes_map(source).end())
15147 rdr.die_wip_classes_map(source).erase(i);
15171 static type_base_sptr
15172 build_qualified_type(reader& rdr,
15174 bool called_from_public_decl,
15175 size_t where_offset)
15177 type_base_sptr result;
15181 unsigned tag = dwarf_tag(die);
15183 if (tag != DW_TAG_const_type
15184 && tag != DW_TAG_volatile_type
15185 && tag != DW_TAG_restrict_type)
15188 Dwarf_Die underlying_type_die;
15189 decl_base_sptr utype_decl;
15190 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15194 utype_decl = build_ir_node_for_void_type(rdr);
15197 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
15198 called_from_public_decl,
15205 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15208 rdr.associate_die_to_type(die, result, where_offset);
15212 type_base_sptr utype =
is_type(utype_decl);
15216 if (tag == DW_TAG_const_type)
15217 qual |= qualified_type_def::CV_CONST;
15218 else if (tag == DW_TAG_volatile_type)
15219 qual |= qualified_type_def::CV_VOLATILE;
15220 else if (tag == DW_TAG_restrict_type)
15221 qual |= qualified_type_def::CV_RESTRICT;
15226 result.reset(
new qualified_type_def(utype, qual, location()));
15228 rdr.associate_die_to_type(die, result, where_offset);
15246 schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
15251 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
15253 rdr.schedule_type_for_late_canonicalization(t);
15257 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
15259 rdr.schedule_type_for_late_canonicalization(t);
15263 for (vector<array_type_def::subrange_sptr>::const_iterator i =
15264 type->get_subranges().begin();
15265 i != type->get_subranges().end();
15268 if (!(*i)->get_scope())
15270 rdr.schedule_type_for_late_canonicalization(*i);
15273 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
15275 rdr.schedule_type_for_late_canonicalization(type);
15294 static decl_base_sptr
15295 maybe_strip_qualification(
const qualified_type_def_sptr t,
15301 decl_base_sptr result = t;
15302 type_base_sptr u = t->get_underlying_type();
15306 if (result.get() != t.get())
15312 scope_decl * scope = 0;
15315 scope = array->get_scope();
15318 schedule_array_tree_for_late_canonicalization(array, rdr);
15320 t->set_underlying_type(array);
15321 u = t->get_underlying_type();
15329 schedule_array_tree_for_late_canonicalization(typdef, rdr);
15332 t->set_underlying_type(typdef);
15333 u = t->get_underlying_type();
15342 type_base_sptr element_type = array->get_element_type();
15347 ABG_ASSERT(!qualified->get_canonical_type());
15349 quals |= t->get_cv_quals();
15350 qualified->set_cv_quals(quals);
15356 qualified_type_def_sptr qual_type
15357 (
new qualified_type_def(element_type,
15359 t->get_location()));
15362 array->set_element_type(qual_type);
15363 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
15388 build_pointer_type_def(reader& rdr,
15390 bool called_from_public_decl,
15391 size_t where_offset)
15398 unsigned tag = dwarf_tag(die);
15399 if (tag != DW_TAG_pointer_type)
15403 Dwarf_Die underlying_type_die;
15404 bool has_underlying_type_die =
false;
15405 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15408 utype_decl = build_ir_node_for_void_type(rdr);
15410 has_underlying_type_die =
true;
15412 if (!utype_decl && has_underlying_type_die)
15413 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
15414 called_from_public_decl,
15421 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15428 type_base_sptr utype =
is_type(utype_decl);
15434 uint64_t size = rdr.cur_transl_unit()->get_address_size();
15435 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
15442 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
15444 result.reset(
new pointer_type_def(utype, size, 0, location()));
15450 rdr.associate_die_to_type(die, result, where_offset);
15472 build_reference_type(reader& rdr,
15474 bool called_from_public_decl,
15475 size_t where_offset)
15482 unsigned tag = dwarf_tag(die);
15483 if (tag != DW_TAG_reference_type
15484 && tag != DW_TAG_rvalue_reference_type)
15487 Dwarf_Die underlying_type_die;
15488 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15492 build_ir_node_from_die(rdr, &underlying_type_die,
15493 called_from_public_decl,
15500 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15507 type_base_sptr utype =
is_type(utype_decl);
15513 uint64_t size = rdr.cur_transl_unit()->get_address_size();
15514 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
15519 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
15521 bool is_lvalue = tag == DW_TAG_reference_type;
15523 result.reset(
new reference_type_def(utype, is_lvalue, size,
15526 if (corpus_sptr corp = rdr.corpus())
15529 rdr.associate_die_to_type(die, result, where_offset);
15552 build_ptr_to_mbr_type(reader& rdr,
15554 bool called_from_public_decl,
15555 size_t where_offset)
15562 unsigned tag = dwarf_tag(die);
15563 if (tag != DW_TAG_ptr_to_member_type)
15566 Dwarf_Die data_member_type_die, containing_type_die;
15568 if (!die_die_attribute(die, DW_AT_type, data_member_type_die)
15569 || !die_die_attribute(die, DW_AT_containing_type, containing_type_die))
15573 build_ir_node_from_die(rdr, &data_member_type_die,
15574 called_from_public_decl, where_offset);
15575 if (!data_member_type)
15579 build_ir_node_from_die(rdr, &containing_type_die,
15580 called_from_public_decl, where_offset);
15581 if (!containing_type)
15588 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15595 uint64_t size_in_bits = rdr.cur_transl_unit()->get_address_size();
15597 result.reset(
new ptr_to_mbr_type(data_member_type->get_environment(),
15604 rdr.associate_die_to_type(die, result, where_offset);
15624 static function_type_sptr
15625 build_function_type(reader& rdr,
15627 class_or_union_sptr is_method,
15628 size_t where_offset)
15630 function_type_sptr result;
15635 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
15636 || dwarf_tag(die) == DW_TAG_subprogram);
15638 const die_source source = rdr.get_die_source(die);
15641 size_t off = dwarf_dieoffset(die);
15642 auto i = rdr.die_wip_function_types_map(source).find(off);
15643 if (i != rdr.die_wip_function_types_map(source).end())
15651 decl_base_sptr type_decl;
15659 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
15663 rdr.associate_die_to_type(die, result, where_offset);
15668 if (odr_is_relevant)
15677 if (function_type_sptr fn_type =
15680 rdr.associate_die_to_type(die, fn_type, where_offset);
15688 bool is_const =
false;
15689 bool is_static =
false;
15690 Dwarf_Die object_pointer_die;
15691 Dwarf_Die class_type_die;
15692 bool has_this_parm_die =
15693 die_function_type_is_method_type(rdr, die, where_offset,
15694 object_pointer_die,
15697 if (has_this_parm_die)
15702 if (die_object_pointer_is_for_const_method(&object_pointer_die))
15710 class_or_union_sptr klass_type =
15721 is_method = klass_type;
15730 result.reset(is_method
15731 ?
new method_type(is_method, is_const,
15732 tu->get_address_size(),
15734 :
new function_type(rdr.env(), tu->get_address_size(),
15736 rdr.associate_die_to_type(die, result, where_offset);
15737 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
15739 type_base_sptr return_type;
15740 Dwarf_Die ret_type_die;
15741 if (die_die_attribute(die, DW_AT_type, ret_type_die))
15743 is_type(build_ir_node_from_die(rdr, &ret_type_die,
15747 return_type =
is_type(build_ir_node_for_void_type(rdr));
15748 result->set_return_type(return_type);
15753 if (dwarf_child(die, &child) == 0)
15756 int child_tag = dwarf_tag(&child);
15757 if (child_tag == DW_TAG_formal_parameter)
15760 string name, linkage_name;
15762 die_loc_and_name(rdr, &child, loc, name, linkage_name);
15767 bool is_artificial = die_is_artificial(&child);
15768 type_base_sptr parm_type;
15769 Dwarf_Die parm_type_die;
15770 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
15772 is_type(build_ir_node_from_die(rdr, &parm_type_die,
15779 && function_parms.empty())
15795 (
new function_decl::parameter(parm_type, name, loc,
15798 function_parms.push_back(p);
15800 else if (child_tag == DW_TAG_unspecified_parameters)
15803 bool is_artificial = die_is_artificial(&child);
15805 type_base_sptr parm_type =
15806 is_type(build_ir_node_for_variadic_parameter_type(rdr));
15808 (
new function_decl::parameter(parm_type,
15813 function_parms.push_back(p);
15823 while (dwarf_siblingof(&child, &child) == 0);
15825 result->set_parameters(function_parms);
15827 tu->bind_function_type_life_time(result);
15829 result->set_is_artificial(
true);
15831 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
15834 die_function_type_map_type::const_iterator i =
15835 rdr.die_wip_function_types_map(source).
15836 find(dwarf_dieoffset(die));
15837 if (i != rdr.die_wip_function_types_map(source).end())
15838 rdr.die_wip_function_types_map(source).erase(i);
15841 maybe_canonicalize_type(result, rdr);
15868 build_subrange_type(reader& rdr,
15869 const Dwarf_Die* die,
15870 size_t where_offset,
15871 bool associate_type_to_die)
15878 unsigned tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
15879 if (tag != DW_TAG_subrange_type)
15882 string name = die_name(die);
15885 Dwarf_Die underlying_type_die;
15886 type_base_sptr underlying_type;
15888 bool is_signed =
false;
15889 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
15891 is_type(build_ir_node_from_die(rdr,
15892 &underlying_type_die,
15896 if (underlying_type)
15899 if (die_unsigned_constant_attribute (&underlying_type_die,
15902 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
15908 bool has_size_info =
false;
15910 if ((has_size_info = die_unsigned_constant_attribute(die,
15911 DW_AT_byte_size, size)))
15914 has_size_info = die_unsigned_constant_attribute(die,
15915 DW_AT_bit_size, size);
15918 array_type_def::subrange_type::bound_value lower_bound =
15919 get_default_array_lower_bound(language);
15920 array_type_def::subrange_type::bound_value upper_bound;
15921 uint64_t count = 0;
15922 bool is_non_finite =
false;
15923 bool non_zero_count_present =
false;
15934 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
15936 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
15937 is_signed, upper_bound);
15938 if (!found_upper_bound)
15939 found_upper_bound = subrange_die_indirect_bound_value(die,
15944 if (!found_upper_bound)
15957 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
15965 non_zero_count_present =
true;
15970 int64_t u = lower_bound.get_signed_value() + count;
15972 upper_bound = u - 1;
15975 if (!non_zero_count_present)
15979 is_non_finite =
true;
15982 if (UINT64_MAX == upper_bound.get_unsigned_value())
15985 is_non_finite =
true;
15988 (
new array_type_def::subrange_type(rdr.env(),
15994 result->is_non_finite(is_non_finite);
15997 result->set_size_in_bits(size);
16004 if (!underlying_type)
16005 result->set_size_in_bits(rdr.cur_transl_unit()->get_address_size());
16010 || (result->get_length() ==
16011 (uint64_t) (result->get_upper_bound()
16012 - result->get_lower_bound() + 1)));
16014 if (associate_type_to_die)
16015 rdr.associate_die_to_type(die, result, where_offset);
16037 build_subranges_from_array_type_die(
const reader& rdr,
16038 const Dwarf_Die* die,
16040 size_t where_offset,
16041 bool associate_type_to_die)
16045 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
16049 int child_tag = dwarf_tag(&child);
16050 if (child_tag == DW_TAG_subrange_type)
16053 if (associate_type_to_die)
16059 build_ir_node_from_die(const_cast<reader&>(rdr), &child,
16068 s = build_subrange_type(const_cast<reader&>(rdr), &child,
16072 subranges.push_back(s);
16075 while (dwarf_siblingof(&child, &child) == 0);
16096 build_array_type(reader& rdr,
16098 bool called_from_public_decl,
16099 size_t where_offset)
16106 unsigned tag = dwarf_tag(die);
16107 if (tag != DW_TAG_array_type)
16110 decl_base_sptr type_decl;
16111 Dwarf_Die type_die;
16113 if (die_die_attribute(die, DW_AT_type, type_die))
16114 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
16115 called_from_public_decl,
16122 if (type_base_sptr t = rdr.lookup_type_from_die(die))
16129 type_base_sptr type =
is_type(type_decl);
16134 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
16136 result.reset(
new array_type_def(type, subranges, location()));
16137 rdr.associate_die_to_type(die, result, where_offset);
16158 build_typedef_type(reader& rdr,
16160 bool called_from_public_decl,
16161 size_t where_offset)
16168 unsigned tag = dwarf_tag(die);
16169 if (tag != DW_TAG_typedef)
16172 string name, linkage_name;
16174 die_loc_and_name(rdr, die, loc, name, linkage_name);
16176 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
16182 type_base_sptr utype;
16183 Dwarf_Die underlying_type_die;
16184 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
16187 utype = rdr.env().get_void_type();
16191 is_type(build_ir_node_from_die(rdr,
16192 &underlying_type_die,
16193 called_from_public_decl,
16199 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
16206 decl_base_sptr decl =
is_decl(utype);
16208 decl->set_naming_typedef(result);
16209 rdr.maybe_schedule_decl_only_type_for_resolution(utype);
16213 rdr.associate_die_to_type(die, result, where_offset);
16250 build_or_get_var_decl_if_not_suppressed(reader& rdr,
16253 size_t where_offset,
16254 bool is_declaration_only,
16256 bool is_required_decl_spec)
16259 if (variable_is_suppressed(rdr, scope, die,
16260 is_declaration_only,
16261 is_required_decl_spec))
16263 ++rdr.stats_.number_of_suppressed_variables;
16269 string var_name = die_name(die);
16270 if (!var_name.empty())
16271 if ((var = class_type->find_data_member(var_name)))
16276 ++rdr.stats_.number_of_suppressed_variables;
16278 var = build_var_decl(rdr, die, where_offset, result);
16301 build_var_decl(reader& rdr,
16303 size_t where_offset,
16309 int tag = dwarf_tag(die);
16310 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
16312 if (!die_is_public_decl(die))
16315 type_base_sptr type;
16316 Dwarf_Die type_die;
16317 if (die_die_attribute(die, DW_AT_type, type_die))
16319 decl_base_sptr ty =
16320 is_decl(build_ir_node_from_die(rdr, &type_die,
16329 if (!type && !result)
16332 string name, linkage_name;
16334 die_loc_and_name(rdr, die, loc, name, linkage_name);
16337 result.reset(
new var_decl(name, type, loc, linkage_name));
16343 if (!linkage_name.empty())
16344 result->set_linkage_name(linkage_name);
16347 result->set_type(type);
16353 if (!result->get_symbol())
16356 Dwarf_Addr var_addr;
16358 if (rdr.get_variable_address(die, var_addr))
16361 update_main_symbol(var_addr,
16362 result->get_linkage_name().empty()
16363 ? result->get_name()
16364 : result->get_linkage_name());
16365 var_sym = rdr.variable_symbol_is_exported(var_addr);
16370 result->set_symbol(var_sym);
16373 string linkage_name = result->get_linkage_name();
16374 if (linkage_name.empty()
16375 || !var_sym->get_alias_from_name(linkage_name))
16376 result->set_linkage_name(var_sym->get_name());
16377 result->set_is_in_public_symbol_table(
true);
16380 if (!var_sym && rdr.is_decl_die_with_undefined_symbol(die))
16384 string n = result->get_linkage_name();
16386 n = result->get_name();
16387 var_sym = rdr.symtab()->lookup_undefined_variable_symbol(n);
16390 result->set_symbol(var_sym);
16391 result->set_is_in_public_symbol_table(
false);
16418 function_is_suppressed(
const reader& rdr,
16419 const scope_decl* scope,
16420 Dwarf_Die *function_die,
16421 bool is_declaration_only)
16423 if (function_die == 0
16424 || dwarf_tag(function_die) != DW_TAG_subprogram)
16427 string fname = die_string_attribute(function_die, DW_AT_name);
16428 string flinkage_name = die_linkage_name(function_die);
16429 if (flinkage_name.empty() && die_is_in_c(function_die))
16430 flinkage_name = fname;
16440 && (!is_declaration_only || rdr.drop_undefined_syms()))
16442 Dwarf_Addr fn_addr;
16443 if (!rdr.get_function_address(function_die, fn_addr))
16447 rdr.function_symbol_is_exported(fn_addr);
16450 if (symbol->is_suppressed())
16457 if (symbol->has_aliases())
16459 !a->is_main_symbol(); a = a->get_next_alias())
16460 if (a->is_suppressed())
16509 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
16512 size_t where_offset,
16513 bool is_declaration_only,
16517 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
16519 ++rdr.stats_.number_of_suppressed_functions;
16523 string name = die_name(fn_die);
16524 string linkage_name = die_linkage_name(fn_die);
16525 bool is_dtor = !name.empty() && name[0]==
'~';
16526 bool is_virtual =
false;
16529 Dwarf_Attribute attr;
16530 if (dwarf_attr_integrate(const_cast<Dwarf_Die*>(fn_die),
16531 DW_AT_vtable_elem_location,
16543 if (!result && (!(is_dtor && is_virtual)))
16547 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
16548 rdr.associate_die_to_decl(fn_die, fn,
true);
16549 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
16555 ++rdr.stats_.number_of_allowed_functions;
16561 string linkage_name = die_linkage_name(fn_die);
16562 fn = klass->find_member_function_sptr(linkage_name);
16569 if (!fn || !fn->get_symbol())
16576 fn = build_function_decl(rdr, fn_die, where_offset, result);
16601 variable_is_suppressed(
const reader& rdr,
16602 const scope_decl* scope,
16603 Dwarf_Die *variable_die,
16604 bool is_declaration_only,
16605 bool is_required_decl_spec)
16607 if (variable_die == 0
16608 || (dwarf_tag(variable_die) != DW_TAG_variable
16609 && dwarf_tag(variable_die) != DW_TAG_member))
16612 string name = die_string_attribute(variable_die, DW_AT_name);
16613 string linkage_name = die_linkage_name(variable_die);
16614 if (linkage_name.empty() && die_is_in_c(variable_die))
16615 linkage_name = name;
16624 && !is_required_decl_spec
16628 && (!is_declaration_only || !rdr.load_undefined_interfaces()))
16630 Dwarf_Addr var_addr = 0;
16631 if (!rdr.get_variable_address(variable_die, var_addr))
16635 rdr.variable_symbol_is_exported(var_addr);
16638 if (symbol->is_suppressed())
16645 if (symbol->has_aliases())
16647 !a->is_main_symbol(); a = a->get_next_alias())
16648 if (a->is_suppressed())
16677 type_is_suppressed(
const reader& rdr,
16678 const scope_decl* scope,
16679 Dwarf_Die *type_die,
16680 bool &type_is_opaque)
16683 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
16684 && dwarf_tag(type_die) != DW_TAG_class_type
16685 && dwarf_tag(type_die) != DW_TAG_structure_type
16686 && dwarf_tag(type_die) != DW_TAG_union_type))
16689 string type_name, linkage_name;
16690 location type_location;
16691 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
16715 type_is_suppressed(
const reader& rdr,
16716 const scope_decl* scope,
16717 Dwarf_Die *type_die)
16719 bool type_is_opaque =
false;
16720 return type_is_suppressed(rdr, scope, type_die, type_is_opaque);
16744 get_opaque_version_of_type(reader &rdr,
16746 Dwarf_Die *type_die,
16747 size_t where_offset)
16754 unsigned tag = dwarf_tag(type_die);
16755 if (tag != DW_TAG_class_type
16756 && tag != DW_TAG_structure_type
16757 && tag != DW_TAG_union_type
16758 && tag != DW_TAG_enumeration_type)
16761 string type_name, linkage_name;
16762 location type_location;
16763 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
16772 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
16774 string_classes_or_unions_map::const_iterator i =
16775 rdr.declaration_only_classes().find(qualified_name);
16776 if (i != rdr.declaration_only_classes().end())
16777 result = i->second.back();
16788 tag == DW_TAG_structure_type,
16790 decl_base::VISIBILITY_DEFAULT));
16791 klass->set_is_declaration_only(
true);
16792 klass->set_is_artificial(die_is_artificial(type_die));
16794 rdr.associate_die_to_type(type_die, klass, where_offset);
16795 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
16800 if (tag == DW_TAG_enumeration_type)
16802 string_enums_map::const_iterator i =
16803 rdr.declaration_only_enums().find(qualified_name);
16804 if (i != rdr.declaration_only_enums().end())
16805 result = i->second.back();
16810 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
16813 build_enum_underlying_type(rdr, type_name, size,
16821 enum_type->set_is_artificial(die_is_artificial(type_die));
16823 result = enum_type;
16846 elf_symbol::FUNC_TYPE,
16847 elf_symbol::GLOBAL_BINDING,
16851 elf_symbol::DEFAULT_VISIBILITY);
16869 build_function_decl(reader& rdr,
16871 size_t where_offset,
16877 int tag = dwarf_tag(die);
16878 ABG_ASSERT(tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine);
16880 if (!die_is_public_decl(die))
16886 string fname, flinkage_name;
16888 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
16889 cleanup_decl_name(fname);
16891 size_t is_inline = die_is_declared_inline(die);
16892 class_or_union_sptr is_method =
16905 if (!flinkage_name.empty()
16906 && result->get_linkage_name() != flinkage_name)
16907 result->set_linkage_name(flinkage_name);
16909 if (!result->get_location())
16910 result->set_location(floc);
16911 result->is_declared_inline(is_inline);
16915 function_type_sptr fn_type(build_function_type(rdr, die, is_method,
16920 maybe_canonicalize_type(fn_type, rdr);
16922 result.reset(is_method
16923 ?
new method_decl(fname, fn_type,
16926 :
new function_decl(fname, fn_type,
16933 if (!result->get_symbol())
16936 Dwarf_Addr fn_addr;
16937 if (rdr.get_function_address(die, fn_addr))
16940 update_main_symbol(fn_addr,
16941 result->get_linkage_name().empty()
16942 ? result->get_name()
16943 : result->get_linkage_name());
16944 fn_sym = rdr.function_symbol_is_exported(fn_addr);
16947 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
16949 result->set_symbol(fn_sym);
16950 string linkage_name = result->get_linkage_name();
16951 if (linkage_name.empty())
16952 result->set_linkage_name(fn_sym->get_name());
16953 result->set_is_in_public_symbol_table(
true);
16956 if (!fn_sym && rdr.is_decl_die_with_undefined_symbol(die))
16960 string n = result->get_linkage_name();
16962 n = result->get_name();
16963 fn_sym = rdr.symtab()->lookup_undefined_function_symbol(n);
16966 result->set_symbol(fn_sym);
16967 result->set_is_in_public_symbol_table(
false);
16972 rdr.associate_die_to_type(die, result->get_type(), where_offset);
16974 size_t die_offset = dwarf_dieoffset(die);
16979 && !result->get_linkage_name().empty())
16985 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
17004 maybe_canonicalize_type(
const type_base_sptr& t,
17010 rdr.schedule_type_for_late_canonicalization(t);
17019 maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
17022 if (
is_type(member_type_declaration)
17025 class_or_union* scope =
17031 if (!cl->is_struct())
17032 access = private_access;
17034 die_access_specifier(die, access);
17047 cleanup_decl_name(
string& str)
17068 const Dwarf_Die *fn_die)
17070 if (!fn || fn->get_scope())
17074 !die_is_virtual(fn_die)
17076 && !fn->get_symbol())
17121 build_ir_node_from_die(reader& rdr,
17124 bool called_from_public_decl,
17125 size_t where_offset,
17126 bool is_declaration_only,
17127 bool is_required_decl_spec)
17131 if (!die || !scope)
17134 int tag = dwarf_tag(die);
17136 if (!called_from_public_decl)
17138 if (rdr.load_all_types() && die_is_type(die))
17142 else if (tag != DW_TAG_subprogram
17143 && tag != DW_TAG_variable
17144 && tag != DW_TAG_member
17145 && tag != DW_TAG_namespace)
17149 const die_source source_of_die = rdr.get_die_source(die);
17151 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
17154 if (rdr.load_all_types())
17155 if (called_from_public_decl)
17156 if (type_base_sptr t =
is_type(result))
17157 if (corpus *abi_corpus = rdr.corpus().get())
17158 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
17167 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
17172 case DW_TAG_base_type:
17177 maybe_canonicalize_type(t, rdr);
17181 case DW_TAG_typedef:
17184 called_from_public_decl,
17190 maybe_set_member_type_access_specifier(
is_decl(result), die);
17191 maybe_canonicalize_type(t, rdr);
17196 case DW_TAG_pointer_type:
17199 build_pointer_type_def(rdr, die,
17200 called_from_public_decl,
17207 maybe_canonicalize_type(p, rdr);
17212 case DW_TAG_reference_type:
17213 case DW_TAG_rvalue_reference_type:
17216 build_reference_type(rdr, die,
17217 called_from_public_decl,
17223 maybe_canonicalize_type(r, rdr);
17228 case DW_TAG_ptr_to_member_type:
17231 build_ptr_to_mbr_type(rdr, die, called_from_public_decl,
17237 rdr.cur_transl_unit()->get_global_scope());
17238 maybe_canonicalize_type(p, rdr);
17243 case DW_TAG_const_type:
17244 case DW_TAG_volatile_type:
17245 case DW_TAG_restrict_type:
17248 build_qualified_type(rdr, die,
17249 called_from_public_decl,
17260 type_base_sptr ty =
is_type(d);
17264 rdr.associate_die_to_type(die, ty, where_offset);
17267 maybe_canonicalize_type(
is_type(result), rdr);
17272 case DW_TAG_enumeration_type:
17274 bool type_is_opaque =
false;
17275 bool type_suppressed =
17276 type_is_suppressed(rdr, scope, die, type_is_opaque);
17277 if (type_suppressed && type_is_opaque)
17285 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
17286 maybe_canonicalize_type(
is_type(result), rdr);
17288 else if (!type_suppressed)
17292 is_declaration_only);
17296 maybe_set_member_type_access_specifier(
is_decl(result), die);
17297 maybe_canonicalize_type(
is_type(result), rdr);
17303 case DW_TAG_class_type:
17304 case DW_TAG_structure_type:
17306 bool type_is_opaque =
false;
17307 bool type_suppressed=
17308 type_is_suppressed(rdr, scope, die, type_is_opaque);
17310 if (type_suppressed && type_is_opaque)
17318 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
17319 maybe_canonicalize_type(
is_type(result), rdr);
17321 else if (!type_suppressed)
17324 Dwarf_Die spec_die;
17325 if (die_die_attribute(die, DW_AT_specification, spec_die))
17328 get_scope_for_die(rdr, &spec_die,
17329 called_from_public_decl,
17332 decl_base_sptr cl =
17333 is_decl(build_ir_node_from_die(rdr, &spec_die,
17335 called_from_public_decl,
17337 is_declaration_only,
17340 klass = dynamic_pointer_cast<class_decl>(cl);
17344 add_or_update_class_type(rdr, die,
17346 tag == DW_TAG_structure_type,
17348 called_from_public_decl,
17350 is_declaration_only);
17356 string type_name = die_type_name(rdr, die,
17364 add_or_update_class_type(rdr, die, scope,
17365 tag == DW_TAG_structure_type,
17367 called_from_public_decl,
17369 is_declaration_only);
17373 add_or_update_class_type(rdr, die, scope,
17374 tag == DW_TAG_structure_type,
17376 called_from_public_decl,
17378 is_declaration_only);
17382 maybe_set_member_type_access_specifier(klass, die);
17383 maybe_canonicalize_type(klass, rdr);
17389 case DW_TAG_union_type:
17390 if (!type_is_suppressed(rdr, scope, die))
17392 union_decl_sptr union_type;
17395 string type_name = die_type_name(rdr, die,
17398 if (union_decl_sptr u =
17405 add_or_update_union_type(rdr, die, scope,
17407 called_from_public_decl,
17409 is_declaration_only);
17413 maybe_set_member_type_access_specifier(union_type, die);
17414 maybe_canonicalize_type(union_type, rdr);
17415 result = union_type;
17419 case DW_TAG_string_type:
17421 case DW_TAG_subroutine_type:
17423 function_type_sptr f = build_function_type(rdr, die,
17429 result->set_is_artificial(
false);
17430 maybe_canonicalize_type(f, rdr);
17434 case DW_TAG_array_type:
17438 called_from_public_decl,
17444 maybe_canonicalize_type(a, rdr);
17448 case DW_TAG_subrange_type:
17454 build_subrange_type(rdr, die, where_offset,
17460 maybe_canonicalize_type(s, rdr);
17464 case DW_TAG_packed_type:
17466 case DW_TAG_set_type:
17468 case DW_TAG_file_type:
17470 case DW_TAG_thrown_type:
17472 case DW_TAG_interface_type:
17474 case DW_TAG_unspecified_type:
17476 case DW_TAG_shared_type:
17479 case DW_TAG_compile_unit:
17484 case DW_TAG_namespace:
17485 case DW_TAG_module:
17486 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
17489 case DW_TAG_variable:
17490 case DW_TAG_member:
17492 if (tag == DW_TAG_member)
17496 get_scope_for_die(rdr, die,
17498 die_is_effectively_public_decl(rdr, die),
17501 build_or_get_var_decl_if_not_suppressed(rdr, var_scope.get(), die,
17503 is_declaration_only,
17505 is_required_decl_spec);
17513 v = build_var_decl(rdr, die, where_offset, v);
17515 Dwarf_Addr addr = 0;
17516 bool has_data_location =
false;
17517 has_data_location = rdr.get_variable_address(die, addr);
17522 || (v && rdr.is_decl_die_with_undefined_symbol(die))
17523 || (v && rdr.is_decl_die_with_exported_symbol(die))
17537 rdr.var_decls_to_re_add_to_tree().push_back(v);
17538 rdr.add_var_to_exported_or_undefined_decls(v);
17539 rdr.associate_die_to_decl(die, v, where_offset,
17546 case DW_TAG_subprogram:
17547 case DW_TAG_inlined_subroutine:
17549 if (die_is_artificial(die))
17552 Dwarf_Die abstract_origin_die;
17553 bool has_abstract_origin = die_die_attribute(die, DW_AT_abstract_origin,
17554 abstract_origin_die,
17558 scope_decl_sptr s = get_scope_for_die(rdr, die, called_from_public_decl,
17560 scope_decl* interface_scope = scope ? scope : s.get();
17563 string linkage_name = die_linkage_name(die);
17564 string spec_linkage_name;
17571 if (!linkage_name.empty())
17574 class_scope->find_member_function_sptr(linkage_name)))
17579 spec_linkage_name = existing_fn->get_linkage_name();
17580 if (has_abstract_origin
17581 && !spec_linkage_name.empty()
17582 && linkage_name != spec_linkage_name)
17589 existing_fn = existing_fn->clone();
17594 else if (has_abstract_origin)
17598 existing_fn = build_function_decl(rdr, &abstract_origin_die, where_offset,
17601 rdr.scope_stack().push(interface_scope);
17608 build_or_get_fn_decl_if_not_suppressed(rdr, interface_scope,
17610 is_declaration_only,
17613 if (result && !existing_fn)
17619 && !is_required_decl_spec)
17636 sptr_utils::noop_deleter());
17638 finish_member_function_reading(die, fn, klass, rdr);
17649 rdr.add_fn_to_exported_or_undefined_decls(fn.get());
17650 rdr.associate_die_to_decl(die, fn, where_offset,
17652 maybe_canonicalize_type(fn->get_type(), rdr);
17655 rdr.scope_stack().pop();
17659 case DW_TAG_formal_parameter:
17664 case DW_TAG_constant:
17666 case DW_TAG_enumerator:
17669 case DW_TAG_partial_unit:
17670 case DW_TAG_imported_unit:
17677 case DW_TAG_dwarf_procedure:
17678 case DW_TAG_imported_declaration:
17679 case DW_TAG_entry_point:
17681 case DW_TAG_lexical_block:
17682 case DW_TAG_unspecified_parameters:
17683 case DW_TAG_variant:
17684 case DW_TAG_common_block:
17685 case DW_TAG_common_inclusion:
17686 case DW_TAG_inheritance:
17687 case DW_TAG_with_stmt:
17688 case DW_TAG_access_declaration:
17689 case DW_TAG_catch_block:
17690 case DW_TAG_friend:
17691 case DW_TAG_namelist:
17692 case DW_TAG_namelist_item:
17693 case DW_TAG_template_type_parameter:
17694 case DW_TAG_template_value_parameter:
17695 case DW_TAG_try_block:
17696 case DW_TAG_variant_part:
17697 case DW_TAG_imported_module:
17698 case DW_TAG_condition:
17699 case DW_TAG_type_unit:
17700 case DW_TAG_template_alias:
17701 case DW_TAG_lo_user:
17702 case DW_TAG_MIPS_loop:
17703 case DW_TAG_format_label:
17704 case DW_TAG_function_template:
17705 case DW_TAG_class_template:
17706 case DW_TAG_GNU_BINCL:
17707 case DW_TAG_GNU_EINCL:
17708 case DW_TAG_GNU_template_template_param:
17709 case DW_TAG_GNU_template_parameter_pack:
17710 case DW_TAG_GNU_formal_parameter_pack:
17711 case DW_TAG_GNU_call_site:
17712 case DW_TAG_GNU_call_site_parameter:
17713 case DW_TAG_hi_user:
17718 if (result && tag != DW_TAG_subroutine_type)
17719 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
17723 if (rdr.load_all_types())
17724 if (called_from_public_decl)
17725 if (type_base_sptr t =
is_type(result))
17726 if (corpus *abi_corpus = scope->get_corpus())
17727 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
17729 rdr.maybe_schedule_decl_only_type_for_resolution(result);
17739 static decl_base_sptr
17740 build_ir_node_for_void_type(reader& rdr)
17742 const environment& env = rdr.env();
17744 type_base_sptr t = env.get_void_type();
17749 rdr.schedule_type_for_late_canonicalization(t);
17751 return type_declaration;
17766 build_ir_node_for_void_pointer_type(reader& rdr)
17768 const environment& env = rdr.env();
17769 type_base_sptr t = env.get_void_pointer_type();
17774 rdr.schedule_type_for_late_canonicalization(t);
17776 return type_declaration;
17784 static decl_base_sptr
17785 build_ir_node_for_variadic_parameter_type(reader &rdr)
17788 const environment& env = rdr.env();
17789 type_base_sptr t = env.get_variadic_parameter_type();
17794 rdr.schedule_type_for_late_canonicalization(t);
17796 return type_declaration;
17822 build_ir_node_from_die(reader& rdr,
17824 bool called_from_public_decl,
17825 size_t where_offset)
17828 return decl_base_sptr();
17838 bool consider_as_called_from_public_decl =
17839 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
17841 consider_as_called_from_public_decl,
17844 scope = rdr.global_scope();
17846 return build_ir_node_from_die(rdr, die, scope.get(),
17847 called_from_public_decl,
17848 where_offset,
true);
17882 elf_based_reader_sptr
17884 const vector<string>& debug_info_root_paths,
17885 environment& environment,
17886 bool load_all_types,
17887 bool linux_kernel_mode)
17890 reader_sptr r = reader::create(elf_path,
17891 debug_info_root_paths,
17894 linux_kernel_mode);
17934 const std::string& elf_path,
17935 const vector<string>&debug_info_root_path,
17936 bool read_all_types,
17937 bool linux_kernel_mode)
17939 reader& r =
dynamic_cast<reader&
>(rdr);
17940 r.initialize(elf_path, debug_info_root_path,
17941 read_all_types, linux_kernel_mode);
17978 const vector<string>& debug_info_root_paths,
17979 environment& environment,
17980 bool load_all_types,
17983 elf_based_reader_sptr rdr =
17984 dwarf::reader::create(elf_path, debug_info_root_paths,
17985 environment, load_all_types,
17988 return rdr->read_corpus(status);
18008 lookup_symbol_from_elf(
const environment& env,
18009 const string& elf_path,
18010 const string& symbol_name,
18012 vector<elf_symbol_sptr>& syms)
18015 if (elf_version(EV_CURRENT) == EV_NONE)
18018 int fd = open(elf_path.c_str(), O_RDONLY);
18026 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
18054 const string& path,
18055 const string& symname,
18056 vector<elf_symbol_sptr>& syms)
18058 if (elf_version(EV_CURRENT) == EV_NONE)
18061 int fd = open(path.c_str(), O_RDONLY);
18069 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
unordered_map< Dwarf_Off, function_type_sptr > die_function_type_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
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...
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
method_decl_sptr copy_member_function(class_or_union_sptr t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
shared_ptr< addr_elf_symbol_sptr_map_type > addr_elf_symbol_sptr_map_sptr
Convenience typedef for a shared pointer to an addr_elf_symbol_sptr_map_type.
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
visibility
The visibility of the symbol.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
unordered_map< interned_string, dwarf_offsets_type, hash_interned_string > istring_dwarf_offsets_map_type
Convenience typedef for a map which is an interned_string and which value is a vector of offsets...
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
unordered_set< std::pair< offset_type, offset_type >, offset_pair_hash > offset_pair_set_type
A convenience typedef for an unordered set of pairs of offset_type.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
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.
bool lookup_public_function_symbol_from_elf(environment &env, const string &path, const string &symname, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of an elf file to see if a public function of a given name is found...
bool parse_real_type(const string &type_name, real_type &type)
Parse a real type from a string.
Utilities to ease the wrapping of C types into std::shared_ptr.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
unordered_map< Dwarf_Off, interned_string > die_istring_map_type
Convenience typedef for a map which key is the offset of a DIE and the value is the corresponding qua...
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
unordered_map< Dwarf_Off, function_decl_sptr > die_function_decl_map_type
Convenience typedef for a map which key the offset of a dwarf die and which value is the correspondin...
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
A functor to hash instances of interned_string.
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.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
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.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< string > &debug_info_root_path, bool read_all_types, bool linux_kernel_mode)
Re-initialize a reader so that it can re-used to read another binary.
unordered_map< string, enums_type > string_enums_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
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.
This contains the declarations for the symtab reader.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
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...
void hash_and_canonicalize_types(IteratorType begin, IteratorType end, deref_lambda deref, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
unordered_map< string, classes_or_unions_type > string_classes_or_unions_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
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...
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
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.
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::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
scope_decl * get_scope() const
Return the type containing the current decl, if any.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This contains the private implementation of the suppression engine of libabigail. ...
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section, the alternate debug info section or from the type unit section.
bool lookup_symbol_from_elf(const environment &env, const string &elf_path, const string &symbol_name, bool demangle, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of a given elf file and see if we find a given symbol.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name...
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
type
The type of a symbol.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
The source location of a token.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one...
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.
unordered_map< interned_string, type_base_wptrs_type, hash_interned_string > istring_type_base_wptrs_map_type
A convenience typedef for a map which key is an interned_string and which value is a vector of type_b...
unordered_map< Dwarf_Off, translation_unit_sptr > die_tu_map_type
Convenience typedef for a map which key is the offset of a DW_TAG_compile_unit and the value is the c...
unordered_map< Dwarf_Off, class_or_union_sptr > die_class_or_union_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
This contains the private implementation of the suppression engine of libabigail. ...
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
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.
The common interface of readers based on ELF.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
unordered_map< string, classes_type > string_classes_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum...
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.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
var_decl_sptr copy_member_variable(class_or_union_sptr t, const var_decl *variable)
Copy a data member of a class_or_union into a new class_or_union.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
binding
The binding of a symbol.
virtual void initialize(const std::string &elf_path, const vector< string > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void initialize()
The initialization function of libxml2 abstraction layer. This function must be called prior to using...
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
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...
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
language
The language of the translation unit.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
unordered_map< Dwarf_Off, Dwarf_Off > offset_offset_map_type
Convenience typedef for a map which key is a dwarf offset. The value is also a dwarf offset...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_set_type, offset_pair_hash > offset_pair_set_map_type
A convenience typedef for an unordered_map that associates a pair of offset_type to a set of pairs of...
corpus_sptr read_corpus_from_elf(const std::string &elf_path, const vector< string > &debug_info_root_paths, environment &environment, bool load_all_types, fe_iface::status &status)
Read all abigail::translation_unit possible from the debug info accessible from an elf file...
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.
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
This contains a set of ELF utilities used by the dwarf reader.
The abstraction of an interned string.
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
The abstraction of the version of an ELF symbol.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
unordered_map< interned_string, function_type_sptr, hash_interned_string > istring_fn_type_map_type
Convenience typedef for a map that associates an interned_string to a function_type_sptr.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
const class_decl * is_compatible_with_class_type(const type_base *t)
Test if a type is a class. This function looks through typedefs.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_vector_type, offset_pair_hash > offset_pair_vect_map_type
A convenience typedef for an unordered map that associates a pair of offset_type to a vector of pairs...
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
access_specifier
Access specifier for class members.
The private data and functions of the abigail::ir::corpus type.
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
unordered_map< Dwarf_Off, type_or_decl_base_sptr > die_artefact_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
The internal representation of an integral type.
unordered_map< Dwarf_Off, class_decl_sptr > die_class_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< string > &debug_info_root_paths, environment &environment, bool load_all_types, bool linux_kernel_mode)
Create a dwarf::reader.
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.
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
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.
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
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.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
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...