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
51 ABG_END_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
142 {
return abigail::hashing::combine_hashes(p.first, p.second);}
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
186 {
return abigail::hashing::combine_hashes(p.source_, p.offset_);}
191 struct offset_pair_hash
194 operator()(
const std::pair<offset_type, offset_type>& p)
const
196 size_t h1 = abigail::hashing::combine_hashes(p.first.source_,
198 size_t h2 = abigail::hashing::combine_hashes(p.second.source_,
200 return abigail::hashing::combine_hashes(h1, h2);
208 typedef unordered_set<std::pair<offset_type,
217 typedef unordered_map<std::pair<offset_type, offset_type>,
223 typedef unordered_map<std::pair<offset_type, offset_type>,
233 build_translation_unit_and_add_to_ir(reader& rdr,
238 maybe_propagate_canonical_type(
const reader& rdr,
243 propagate_canonical_type(
const reader& rdr,
285 struct imported_unit_point
287 Dwarf_Off offset_of_import;
291 Dwarf_Off imported_unit_die_off;
292 Dwarf_Off imported_unit_cu_off;
293 Dwarf_Off imported_unit_child_off;
296 imported_unit_point()
297 : offset_of_import(),
298 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
299 imported_unit_die_off(),
300 imported_unit_cu_off(),
301 imported_unit_child_off()
308 imported_unit_point(Dwarf_Off import_off)
309 : offset_of_import(import_off),
310 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
311 imported_unit_die_off(),
312 imported_unit_cu_off(),
313 imported_unit_child_off()
324 imported_unit_point(Dwarf_Off import_off,
325 const Dwarf_Die& imported_die,
327 : offset_of_import(import_off),
328 imported_unit_die_source(from),
329 imported_unit_die_off(dwarf_dieoffset
330 (
const_cast<Dwarf_Die*
>(&imported_die))),
331 imported_unit_cu_off(),
332 imported_unit_child_off()
334 Dwarf_Die imported_unit_child;
336 ABG_ASSERT(dwarf_child(
const_cast<Dwarf_Die*
>(&imported_die),
337 &imported_unit_child) == 0);
339 imported_unit_child_off =
340 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(&imported_unit_child));
342 Dwarf_Die cu_die_memory;
345 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&imported_unit_child),
346 &cu_die_memory, 0, 0);
347 imported_unit_cu_off = dwarf_dieoffset(cu_die);
355 typedef unordered_map<Dwarf_Off, imported_unit_points_type>
367 operator<(
const imported_unit_point& l,
const imported_unit_point& r)
368 {
return l.offset_of_import < r.offset_of_import;}
371 get_parent_die(
const reader& rdr,
372 const Dwarf_Die* die,
373 Dwarf_Die& parent_die,
374 size_t where_offset);
377 get_scope_die(
const reader& rdr,
378 const Dwarf_Die* die,
380 Dwarf_Die& scope_die);
383 die_is_anonymous(
const Dwarf_Die* die);
386 die_is_anonymous_data_member(
const Dwarf_Die* die);
389 die_is_type(
const Dwarf_Die* die);
392 die_is_decl(
const Dwarf_Die* die);
395 die_is_declaration_only(Dwarf_Die* die);
398 die_is_variable_decl(
const Dwarf_Die *die);
401 die_is_function_decl(
const Dwarf_Die *die);
404 die_has_size_attribute(
const Dwarf_Die *die);
407 die_has_no_child(
const Dwarf_Die *die);
410 die_is_namespace(
const Dwarf_Die* die);
413 die_is_unspecified(Dwarf_Die* die);
416 die_is_void_type(Dwarf_Die* die);
419 die_is_pointer_type(
const Dwarf_Die* die);
422 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
425 die_is_reference_type(
const Dwarf_Die* die);
428 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
431 die_is_pointer_or_reference_type(
const Dwarf_Die* die);
434 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
437 die_is_class_type(
const Dwarf_Die* die);
440 die_is_qualified_type(
const Dwarf_Die* die);
443 die_is_function_type(
const Dwarf_Die *die);
446 die_has_object_pointer(
const Dwarf_Die* die,
447 Dwarf_Die& object_pointer);
450 die_has_children(
const Dwarf_Die* die);
453 die_this_pointer_from_object_pointer(Dwarf_Die* die,
454 Dwarf_Die& this_pointer);
457 die_this_pointer_is_const(Dwarf_Die* die);
460 die_object_pointer_is_for_const_method(Dwarf_Die* die);
463 is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
466 die_is_at_class_scope(
const reader& rdr,
467 const Dwarf_Die* die,
469 Dwarf_Die& class_scope_die);
471 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
474 bool& is_tls_address);
477 dwarf_language_to_tu_language(
size_t l);
480 die_unsigned_constant_attribute(
const Dwarf_Die* die,
485 die_signed_constant_attribute(
const Dwarf_Die*die,
490 die_constant_attribute(
const Dwarf_Die *die,
493 array_type_def::subrange_type::bound_value &value);
496 die_member_offset(
const reader& rdr,
497 const Dwarf_Die* die,
501 form_is_DW_FORM_strx(
unsigned form);
504 form_is_DW_FORM_line_strp(
unsigned form);
507 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
510 die_name(
const Dwarf_Die* die);
513 die_location(
const reader& rdr,
const Dwarf_Die* die);
516 die_location_address(Dwarf_Die* die,
518 bool& is_tls_address);
521 die_die_attribute(
const Dwarf_Die* die,
524 bool recursively =
true);
527 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
529 array_type_def::subrange_type::bound_value& v,
533 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
535 Dwarf_Die& referenced_subrange);
537 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
540 build_internal_anonymous_die_name(
const string &
base_name,
541 size_t anonymous_type_index);
544 get_internal_anonymous_die_name(Dwarf_Die *die,
545 size_t anonymous_type_index);
548 die_qualified_type_name(
const reader& rdr,
549 const Dwarf_Die* die,
553 die_qualified_decl_name(
const reader& rdr,
554 const Dwarf_Die* die,
558 die_qualified_name(
const reader& rdr,
559 const Dwarf_Die* die,
563 die_qualified_type_name_empty(
const reader& rdr,
564 const Dwarf_Die* die,
size_t where,
565 string &qualified_name);
568 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
569 const Dwarf_Die* die,
572 string &return_type_name,
574 vector<string>& parm_names,
579 die_function_signature(
const reader& rdr,
580 const Dwarf_Die *die,
581 size_t where_offset);
584 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
587 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
590 die_function_type_is_method_type(
const reader& rdr,
591 const Dwarf_Die *die,
593 Dwarf_Die& object_pointer_die,
594 Dwarf_Die& class_die,
598 die_pretty_print_type(reader& rdr,
599 const Dwarf_Die* die,
600 size_t where_offset);
603 die_pretty_print_decl(reader& rdr,
604 const Dwarf_Die* die,
605 size_t where_offset);
608 die_pretty_print(reader& rdr,
609 const Dwarf_Die* die,
610 size_t where_offset);
613 maybe_canonicalize_type(
const type_base_sptr& t,
622 imported_unit_points_type::const_iterator&);
625 build_subrange_type(reader& rdr,
626 const Dwarf_Die* die,
628 bool associate_type_to_die =
true);
631 build_subranges_from_array_type_die(reader& rdr,
632 const Dwarf_Die* die,
635 bool associate_type_to_die =
true);
638 compare_dies(
const reader& rdr,
639 const Dwarf_Die *l,
const Dwarf_Die *r,
640 bool update_canonical_dies_on_the_fly);
643 compare_dies_during_canonicalization(reader& rdr,
644 const Dwarf_Die *l,
const Dwarf_Die *r,
645 bool update_canonical_dies_on_the_fly);
648 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
662 compare_symbol_name(
const string& symbol_name,
671 return symbol_name == name;
700 lookup_symbol_from_sysv_hash_tab(
const environment& env,
702 const string& sym_name,
704 size_t sym_tab_index,
706 vector<elf_symbol_sptr>& syms_found)
708 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
711 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
714 GElf_Shdr sheader_mem;
715 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
717 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
722 unsigned long hash = elf_hash(sym_name.c_str());
723 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
724 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
725 size_t nb_buckets = ht_data[0];
726 size_t nb_chains = ht_data[1];
734 Elf32_Word* ht_buckets = &ht_data[2];
735 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
738 size_t bucket = hash % nb_buckets;
739 size_t symbol_index = ht_buckets[bucket];
742 const char* sym_name_str;
751 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
752 sym_name_str = elf_strptr(elf_handle,
753 sym_tab_section_header->sh_link,
756 && compare_symbol_name(sym_name_str, sym_name, demangle))
762 sym_size = symbol.st_size;
763 elf_symbol::version ver;
774 symbol.st_shndx != SHN_UNDEF,
775 symbol.st_shndx == SHN_COMMON,
776 ver, sym_visibility);
777 syms_found.push_back(symbol_found);
780 symbol_index = ht_chains[symbol_index];
781 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
792 get_elf_class_size_in_bytes(Elf* elf_handle)
798 int c = hdr.e_ident[EI_CLASS];
832 bloom_word_at(Elf* elf_handle,
833 Elf32_Word* bloom_filter,
836 Elf64_Xword result = 0;
840 c = h.e_ident[EI_CLASS];
845 result = bloom_filter[index];
849 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
870 size_t first_sym_index;
873 Elf32_Word* bloom_filter;
876 Elf_Scn* sym_tab_section;
877 GElf_Shdr sym_tab_section_header;
907 setup_gnu_ht(Elf* elf_handle,
909 size_t sym_tab_index,
912 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
914 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
916 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
917 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
922 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
923 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
925 ht.nb_buckets = ht_data[0];
926 if (ht.nb_buckets == 0)
930 ht.first_sym_index = ht_data[1];
933 ht.bf_nwords = ht_data[2];
935 ht.shift = ht_data[3];
937 ht.bloom_filter = &ht_data[4];
942 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
944 ht.buckets = ht.bloom_filter + ht.bf_size;
946 ht.chain = ht.buckets + ht.nb_buckets;
977 lookup_symbol_from_gnu_hash_tab(
const environment& env,
979 const string& sym_name,
981 size_t sym_tab_index,
983 vector<elf_symbol_sptr>& syms_found)
986 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
992 size_t h1 = elf_gnu_hash(sym_name.c_str());
993 size_t h2 = h1 >> ht.shift;
996 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
997 int n = (h1 / c) % ht.bf_nwords;
1003 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1006 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1009 size_t i = ht.buckets[h1 % ht.nb_buckets];
1013 Elf32_Word stop_word, *stop_wordp;
1014 elf_symbol::version ver;
1016 const char* sym_name_str;
1025 for (i = ht.buckets[h1 % ht.nb_buckets],
1026 stop_wordp = &ht.chain[i - ht.first_sym_index];
1029 < ht.chain + (ht.sym_count - ht.first_sym_index));
1032 stop_word = *stop_wordp;
1033 if ((stop_word & ~ 1)!= (h1 & ~1))
1039 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1041 sym_name_str = elf_strptr(elf_handle,
1042 ht.sym_tab_section_header.sh_link,
1045 && compare_symbol_name(sym_name_str, sym_name, demangle))
1063 sym_type, sym_binding,
1064 symbol.st_shndx != SHN_UNDEF,
1065 symbol.st_shndx == SHN_COMMON,
1066 ver, sym_visibility);
1067 syms_found.push_back(symbol_found);
1109 lookup_symbol_from_elf_hash_tab(
const environment& env,
1111 hash_table_kind ht_kind,
1113 size_t symtab_index,
1114 const string& symbol_name,
1116 vector<elf_symbol_sptr>& syms_found)
1118 if (elf_handle == 0 || symbol_name.empty())
1121 if (ht_kind == NO_HASH_TABLE_KIND)
1124 if (ht_kind == SYSV_HASH_TABLE_KIND)
1125 return lookup_symbol_from_sysv_hash_tab(env,
1126 elf_handle, symbol_name,
1131 else if (ht_kind == GNU_HASH_TABLE_KIND)
1132 return lookup_symbol_from_gnu_hash_tab(env,
1133 elf_handle, symbol_name,
1166 lookup_symbol_from_symtab(
const environment& env,
1168 const string& sym_name,
1169 size_t sym_tab_index,
1171 vector<elf_symbol_sptr>& syms_found)
1176 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1179 GElf_Shdr header_mem;
1180 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1183 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1184 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1187 elf_symbol::version ver;
1190 for (
size_t i = 0; i < symcount; ++i)
1193 sym = gelf_getsym(symtab, i, &sym_mem);
1194 name_str = elf_strptr(elf_handle,
1195 sym_tab_header->sh_link,
1198 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1206 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1207 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1216 sym_binding, sym_is_defined,
1217 sym_is_common, ver, sym_visibility);
1218 syms_found.push_back(symbol_found);
1257 lookup_symbol_from_elf(
const environment& env,
1259 const string& symbol_name,
1261 vector<elf_symbol_sptr>& syms_found)
1263 size_t hash_table_index = 0, symbol_table_index = 0;
1264 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1269 symbol_table_index);
1271 if (ht_kind == NO_HASH_TABLE_KIND)
1276 return lookup_symbol_from_symtab(env,
1284 return lookup_symbol_from_elf_hash_tab(env,
1308 lookup_public_function_symbol_from_elf(environment& env,
1310 const string& symbol_name,
1311 vector<elf_symbol_sptr>& func_syms)
1313 vector<elf_symbol_sptr> syms_found;
1316 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1319 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1320 i != syms_found.end();
1326 if ((type == elf_symbol::FUNC_TYPE
1327 || type == elf_symbol::GNU_IFUNC_TYPE
1328 || type == elf_symbol::COMMON_TYPE)
1329 && (binding == elf_symbol::GLOBAL_BINDING
1330 || binding == elf_symbol::WEAK_BINDING))
1332 func_syms.push_back(*i);
1353 int64_t const_value_;
1361 expr_result(
bool is_const)
1362 : is_const_(is_const),
1366 explicit expr_result(int64_t v)
1392 const_value(int64_t& value)
1396 value = const_value_;
1412 return const_value_;
1415 operator int64_t()
const
1416 {
return const_value();}
1419 operator=(
const int64_t v)
1427 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1430 operator>=(
const expr_result& o)
const
1431 {
return const_value_ >= o.const_value_;}
1434 operator<=(
const expr_result& o)
const
1435 {
return const_value_ <= o.const_value_;}
1438 operator>(
const expr_result& o)
const
1439 {
return const_value_ > o.const_value_;}
1442 operator<(
const expr_result& o)
const
1443 {
return const_value_ < o.const_value_;}
1448 expr_result r(*
this);
1449 r.const_value_ += v.const_value_;
1450 r.is_const_ = r.is_const_ && v.is_const_;
1455 operator+=(int64_t v)
1462 operator-(
const expr_result& v)
const
1464 expr_result r(*
this);
1465 r.const_value_ -= v.const_value_;
1466 r.is_const_ = r.is_const_ && v.is_const_;
1471 operator%(
const expr_result& v)
const
1473 expr_result r(*
this);
1474 r.const_value_ %= v.const_value_;
1475 r.is_const_ = r.is_const_ && v.is_const();
1480 operator*(
const expr_result& v)
const
1482 expr_result r(*
this);
1483 r.const_value_ *= v.const_value_;
1484 r.is_const_ = r.is_const_ && v.is_const();
1491 expr_result r(*
this);
1492 r.const_value_ |= v.const_value_;
1493 r.is_const_ = r.is_const_ && v.is_const_;
1498 operator^(
const expr_result& v)
const
1500 expr_result r(*
this);
1501 r.const_value_ ^= v.const_value_;
1502 r.is_const_ = r.is_const_ && v.is_const_;
1507 operator>>(
const expr_result& v)
const
1509 expr_result r(*
this);
1510 r.const_value_ = r.const_value_ >> v.const_value_;
1511 r.is_const_ = r.is_const_ && v.is_const_;
1518 expr_result r(*
this);
1519 r.const_value_ = r.const_value_ << v.const_value_;
1520 r.is_const_ = r.is_const_ && v.is_const_;
1527 expr_result r(*
this);
1528 r.const_value_ = ~r.const_value_;
1535 expr_result r(*
this);
1536 r.const_value_ = -r.const_value_;
1543 expr_result r = *
this;
1544 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1551 expr_result r(*
this);
1552 r.const_value_ &= o.const_value_;
1553 r.is_const_ = r.is_const_ && o.is_const_;
1558 operator/(
const expr_result& o)
1560 expr_result r(*
this);
1561 r.is_const_ = r.is_const_ && o.is_const_;
1562 return r.const_value() / o.const_value();
1568 class expr_result_stack_type
1570 vector<expr_result> elems_;
1574 expr_result_stack_type()
1575 {elems_.reserve(4);}
1578 operator[](
unsigned i)
1580 unsigned s = elems_.size();
1582 return elems_[s - 1 -i];
1586 operator[](
unsigned i)
const
1587 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1591 {
return elems_.size();}
1593 vector<expr_result>::reverse_iterator
1595 {
return elems_.rbegin();}
1597 const vector<expr_result>::reverse_iterator
1599 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1601 vector<expr_result>::reverse_iterator
1603 {
return elems_.rend();}
1605 const vector<expr_result>::reverse_iterator
1607 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1611 {
return elems_.back();}
1615 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1618 push_front(expr_result e)
1619 {elems_.push_back(e);}
1624 expr_result r = front();
1630 erase(vector<expr_result>::reverse_iterator i)
1631 {elems_.erase(--i.base());}
1639 struct dwarf_expr_eval_context
1642 expr_result_stack_type stack;
1647 dwarf_expr_eval_context()
1651 stack.push_front(expr_result(
true));
1658 stack.push_front(expr_result(
true));
1659 accum = expr_result(
false);
1660 set_tls_addr =
false;
1669 set_tls_address(
bool f)
1678 set_tls_address()
const
1679 {
return set_tls_addr;}
1684 expr_result r = stack.front();
1690 push(
const expr_result& v)
1691 {stack.push_front(v);}
1700 typedef shared_ptr<reader> reader_sptr;
1707 class reader :
public elf_based_reader
1714 template <
typename ContainerType>
1715 class die_source_dependant_container_set
1717 ContainerType primary_debug_info_container_;
1718 ContainerType alt_debug_info_container_;
1719 ContainerType type_unit_container_;
1733 ContainerType *result = 0;
1736 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1737 result = &primary_debug_info_container_;
1739 case ALT_DEBUG_INFO_DIE_SOURCE:
1740 result = &alt_debug_info_container_;
1742 case TYPE_UNIT_DIE_SOURCE:
1743 result = &type_unit_container_;
1745 case NO_DEBUG_INFO_DIE_SOURCE:
1746 case NUMBER_OF_DIE_SOURCES:
1759 const ContainerType&
1762 return const_cast<die_source_dependant_container_set*
>(
this)->
1763 get_container(source);
1777 get_container(
const reader& rdr,
const Dwarf_Die *die)
1779 const die_source source = rdr.get_die_source(die);
1780 return get_container(source);
1793 const ContainerType&
1794 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1796 return const_cast<die_source_dependant_container_set*
>(
this)->
1797 get_container(rdr, die);
1804 primary_debug_info_container_.clear();
1805 alt_debug_info_container_.clear();
1806 type_unit_container_.clear();
1810 unsigned short dwarf_version_;
1811 Dwarf_Die* cur_tu_die_;
1812 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1816 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1817 decl_die_repr_die_offsets_maps_;
1821 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1822 type_die_repr_die_offsets_maps_;
1823 mutable die_source_dependant_container_set<die_istring_map_type>
1824 die_qualified_name_maps_;
1825 mutable die_source_dependant_container_set<die_istring_map_type>
1826 die_pretty_repr_maps_;
1827 mutable die_source_dependant_container_set<die_istring_map_type>
1828 die_pretty_type_repr_maps_;
1831 mutable die_source_dependant_container_set<die_artefact_map_type>
1832 decl_die_artefact_maps_;
1835 mutable die_source_dependant_container_set<die_artefact_map_type>
1836 type_die_artefact_maps_;
1839 mutable die_source_dependant_container_set<offset_offset_map_type>
1840 canonical_type_die_offsets_;
1843 mutable die_source_dependant_container_set<offset_offset_map_type>
1844 canonical_decl_die_offsets_;
1850 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1852 dwarf_offset_pair_hash> die_comparison_results_;
1862 vector<type_base_sptr> types_to_canonicalize_;
1881 list<var_decl_sptr> var_decls_to_add_;
1882 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1883 bool debug_die_canonicalization_is_on_;
1884 bool use_canonical_die_comparison_;
1886 mutable size_t compare_count_;
1887 mutable size_t canonical_propagated_count_;
1888 mutable size_t cancelled_propagation_count_;
1889 mutable optional<bool> leverage_dwarf_factorization_;
1924 reader(
const string& elf_path,
1925 const vector<char**>& debug_info_root_paths,
1926 environment& environment,
1927 bool load_all_types,
1928 bool linux_kernel_mode)
1929 : elf_based_reader(elf_path,
1930 debug_info_root_paths,
1933 initialize(load_all_types, linux_kernel_mode);
1951 initialize(
bool load_all_types,
bool linux_kernel_mode)
1955 decl_die_repr_die_offsets_maps_.clear();
1956 type_die_repr_die_offsets_maps_.clear();
1957 die_qualified_name_maps_.clear();
1958 die_pretty_repr_maps_.clear();
1959 die_pretty_type_repr_maps_.clear();
1960 decl_die_artefact_maps_.clear();
1961 type_die_artefact_maps_.clear();
1962 canonical_type_die_offsets_.clear();
1963 canonical_decl_die_offsets_.clear();
1964 die_wip_classes_map_.clear();
1965 alternate_die_wip_classes_map_.clear();
1966 type_unit_die_wip_classes_map_.clear();
1967 die_wip_function_types_map_.clear();
1968 alternate_die_wip_function_types_map_.clear();
1969 type_unit_die_wip_function_types_map_.clear();
1970 die_function_with_no_symbol_map_.clear();
1971 types_to_canonicalize_.clear();
1972 decl_only_classes_map_.clear();
1973 die_tu_map_.clear();
1975 corpus_group().reset();
1977 primary_die_parent_map_.clear();
1978 tu_die_imported_unit_points_map_.clear();
1979 alt_tu_die_imported_unit_points_map_.clear();
1980 type_units_tu_die_imported_unit_points_map_.clear();
1981 alternate_die_parent_map_.clear();
1982 type_section_die_parent_map_.clear();
1983 var_decls_to_add_.clear();
1984 clear_per_translation_unit_data();
1985 options().load_in_linux_kernel_mode = linux_kernel_mode;
1986 options().load_all_types = load_all_types;
1987 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1988 debug_die_canonicalization_is_on_ =
1989 env().debug_die_canonicalization_is_on();
1990 use_canonical_die_comparison_ =
true;
1993 canonical_propagated_count_ = 0;
1994 cancelled_propagation_count_ = 0;
1995 load_in_linux_kernel_mode(linux_kernel_mode);
2016 initialize(
const string& elf_path,
2017 const vector<char**>& debug_info_root_paths,
2018 bool load_all_types,
2019 bool linux_kernel_mode)
2021 reset(elf_path, debug_info_root_paths);
2022 initialize(load_all_types, linux_kernel_mode);
2042 static dwarf::reader_sptr
2043 create(
const std::string& elf_path,
2044 const vector<char**>& debug_info_root_paths,
2045 environment& environment,
2046 bool load_all_types,
2047 bool linux_kernel_mode)
2049 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2050 environment, load_all_types,
2051 linux_kernel_mode));
2068 read_corpus(status& status)
2070 status = STATUS_UNKNOWN;
2075 if ((status & STATUS_NO_SYMBOLS_FOUND)
2076 || !(status & STATUS_OK))
2080 return corpus_sptr();
2083 if (dwarf_debug_info() ==
nullptr)
2084 status |= STATUS_DEBUG_INFO_NOT_FOUND;
2088 if (refers_to_alt_debug_info(alt_di_path)
2089 && !alternate_dwarf_debug_info())
2090 status |= STATUS_ALT_DEBUG_INFO_NOT_FOUND;
2095 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2096 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2098 return corpus_sptr();
2102 corpus_sptr corp = read_debug_info_into_corpus();
2104 status |= STATUS_OK;
2117 read_debug_info_into_corpus()
2119 clear_per_corpus_data();
2124 origin |= corpus::DWARF_ORIGIN;
2125 corpus()->set_origin(origin);
2127 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2128 && !env().user_set_analyze_exported_interfaces_only())
2135 env().analyze_exported_interfaces_only(
true);
2137 corpus()->set_soname(dt_soname());
2138 corpus()->set_needed(dt_needed());
2139 corpus()->set_architecture_name(elf_architecture());
2141 corpus()->set_symtab(symtab());
2145 if (!dwarf_debug_info()
2146 || !corpus()->get_symtab()->has_symbols())
2149 uint8_t address_size = 0;
2150 size_t header_size = 0;
2152 #ifdef WITH_DEBUG_SELF_COMPARISON
2153 if (env().self_comparison_debug_is_on())
2154 env().set_self_comparison_debug_input(corpus());
2160 tools_utils::timer t;
2163 cerr <<
"building die -> parent maps ...";
2167 build_die_parent_maps();
2172 cerr <<
" DONE@" << corpus()->get_path()
2179 env().canonicalization_is_done(
false);
2182 tools_utils::timer t;
2185 cerr <<
"building the libabigail internal representation ...";
2189 Dwarf_Half dwarf_vers = 0;
2190 for (Dwarf_Off offset = 0, next_offset = 0;
2191 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
2192 offset, &next_offset, &header_size,
2193 &dwarf_vers, NULL, &address_size, NULL,
2195 offset = next_offset)
2197 Dwarf_Off die_offset = offset + header_size;
2199 if (!dwarf_offdie(
const_cast<Dwarf*
>(dwarf_debug_info()),
2201 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2204 dwarf_version(dwarf_vers);
2211 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2217 cerr <<
" DONE@" << corpus()->get_path()
2222 cerr <<
"Number of aggregate types compared: "
2223 << compare_count_ <<
"\n"
2224 <<
"Number of canonical types propagated: "
2225 << canonical_propagated_count_ <<
"\n"
2226 <<
"Number of cancelled propagated canonical types:"
2227 << cancelled_propagation_count_ <<
"\n";
2232 tools_utils::timer t;
2235 cerr <<
"resolving declaration only classes ...";
2238 resolve_declaration_only_classes();
2242 cerr <<
" DONE@" << corpus()->get_path()
2250 tools_utils::timer t;
2253 cerr <<
"resolving declaration only enums ...";
2256 resolve_declaration_only_enums();
2260 cerr <<
" DONE@" << corpus()->get_path()
2268 tools_utils::timer t;
2271 cerr <<
"fixing up functions with linkage name but "
2272 <<
"no advertised underlying symbols ....";
2275 fixup_functions_with_no_symbols();
2279 cerr <<
" DONE@" << corpus()->get_path()
2298 tools_utils::timer t;
2301 cerr <<
"perform late type canonicalizing ...\n";
2305 perform_late_type_canonicalizing();
2309 cerr <<
"late type canonicalizing DONE@"
2310 << corpus()->get_path()
2317 env().canonicalization_is_done(
true);
2320 tools_utils::timer t;
2323 cerr <<
"sort functions and variables ...";
2326 corpus()->sort_functions();
2327 corpus()->sort_variables();
2331 cerr <<
" DONE@" << corpus()->get_path()
2345 clear_per_translation_unit_data()
2347 while (!scope_stack().empty())
2348 scope_stack().pop();
2349 var_decls_to_re_add_to_tree().clear();
2350 per_tu_repr_to_fn_type_maps().clear();
2356 clear_per_corpus_data()
2358 die_qualified_name_maps_.clear();
2359 die_pretty_repr_maps_.clear();
2360 die_pretty_type_repr_maps_.clear();
2361 clear_types_to_canonicalize();
2369 {
return options().env;}
2376 {
return const_cast<reader*
>(
this)->env();}
2384 drop_undefined_syms()
const
2385 {
return options().drop_undefined_syms;}
2392 drop_undefined_syms(
bool f)
2393 {options().drop_undefined_syms = f;}
2397 dwarf_version()
const
2398 {
return dwarf_version_;}
2401 dwarf_version(
unsigned short v)
2402 {dwarf_version_ = v;}
2414 dwarf_elf_handle()
const
2415 {
return dwarf_getelf(
const_cast<Dwarf*
>(dwarf_debug_info()));}
2425 dwarf_is_splitted()
const
2426 {
return dwarf_elf_handle() != elf_handle();}
2435 dwarf_per_die_source(
die_source source)
const
2437 const Dwarf *result = 0;
2440 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2441 case TYPE_UNIT_DIE_SOURCE:
2442 result = dwarf_debug_info();
2444 case ALT_DEBUG_INFO_DIE_SOURCE:
2445 result = alternate_dwarf_debug_info();
2447 case NO_DEBUG_INFO_DIE_SOURCE:
2448 case NUMBER_OF_DIE_SOURCES:
2459 {
return corpus_path();}
2463 {
return cur_tu_die_;}
2466 cur_tu_die(Dwarf_Die* cur_tu_die)
2467 {cur_tu_die_ = cur_tu_die;}
2469 dwarf_expr_eval_context&
2470 dwarf_expr_eval_ctxt()
const
2471 {
return dwarf_expr_eval_context_;}
2478 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2479 decl_die_repr_die_offsets_maps()
const
2480 {
return decl_die_repr_die_offsets_maps_;}
2487 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2488 decl_die_repr_die_offsets_maps()
2489 {
return decl_die_repr_die_offsets_maps_;}
2496 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2497 type_die_repr_die_offsets_maps()
const
2498 {
return type_die_repr_die_offsets_maps_;}
2505 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2506 type_die_repr_die_offsets_maps()
2507 {
return type_die_repr_die_offsets_maps_;}
2520 compute_canonical_die_offset(
const Dwarf_Die *die,
2521 Dwarf_Off &canonical_die_offset,
2522 bool die_as_type)
const
2526 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2527 get_container(*
this, die)
2528 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2529 get_container(*
this, die);
2531 Dwarf_Die canonical_die;
2532 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2534 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2552 compute_canonical_die(
const Dwarf_Die *die,
2554 Dwarf_Die &canonical_die,
2555 bool die_as_type)
const
2557 const die_source source = get_die_source(die);
2559 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2561 compute_canonical_die(die_offset, source,
2563 canonical_die, die_as_type);
2583 compute_canonical_die(Dwarf_Off die_offset,
2586 Dwarf_Die &canonical_die,
2587 bool die_as_type)
const
2593 ? (
const_cast<reader*
>(
this)->
2594 type_die_repr_die_offsets_maps().get_container(source))
2595 : (
const_cast<reader*
>(
this)->
2596 decl_die_repr_die_offsets_maps().get_container(source));
2599 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2608 interned_string name =
2610 ? get_die_pretty_type_representation(&die, 0)
2611 : get_die_pretty_representation(&die, 0);
2613 Dwarf_Off canonical_die_offset = 0;
2614 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2618 offsets.push_back(die_offset);
2619 map[name] = offsets;
2620 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2621 get_die_from_offset(source, die_offset, &canonical_die);
2625 Dwarf_Off cur_die_offset;
2626 Dwarf_Die potential_canonical_die;
2627 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2628 o != i->second.end();
2631 cur_die_offset = *o;
2632 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2633 if (compare_dies(*
this, &die, &potential_canonical_die,
2636 canonical_die_offset = cur_die_offset;
2637 set_canonical_die_offset(canonical_dies, die_offset,
2638 canonical_die_offset);
2639 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2644 canonical_die_offset = die_offset;
2645 i->second.push_back(die_offset);
2646 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2647 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2666 get_canonical_die(
const Dwarf_Die *die,
2667 Dwarf_Die &canonical_die,
2671 const die_source source = get_die_source(die);
2675 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2676 get_container(source)
2677 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2678 get_container(source);
2680 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2681 if (Dwarf_Off canonical_die_offset =
2682 get_canonical_die_offset(canonical_dies, die_offset))
2684 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2692 ? (
const_cast<reader*
>(
this)->
2693 type_die_repr_die_offsets_maps().get_container(*
this, die))
2694 : (
const_cast<reader*
>(
this)->
2695 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2703 interned_string name =
2705 ? get_die_pretty_type_representation(die, where)
2706 : get_die_pretty_representation(die, where);
2708 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2712 Dwarf_Off cur_die_offset;
2713 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2714 o != i->second.end();
2717 cur_die_offset = *o;
2718 get_die_from_offset(source, cur_die_offset, &canonical_die);
2720 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2721 die, &canonical_die,
2724 set_canonical_die_offset(canonical_dies,
2758 get_or_compute_canonical_die(
const Dwarf_Die* die,
2759 Dwarf_Die& canonical_die,
2761 bool die_as_type)
const
2763 const die_source source = get_die_source(die);
2767 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2768 get_container(source)
2769 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2770 get_container(source);
2772 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2774 if (Dwarf_Off canonical_die_offset =
2775 get_canonical_die_offset(canonical_dies,
2776 initial_die_offset))
2778 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2782 if (!is_type_die_to_be_canonicalized(die))
2789 ? (
const_cast<reader*
>(
this)->
2790 type_die_repr_die_offsets_maps().get_container(*
this, die))
2791 : (
const_cast<reader*
>(
this)->
2792 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2800 interned_string name =
2802 ? get_die_pretty_type_representation(die, where)
2803 : get_die_pretty_representation(die, where);
2805 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2809 offsets.push_back(initial_die_offset);
2810 map[name] = offsets;
2811 get_die_from_offset(source, initial_die_offset, &canonical_die);
2812 set_canonical_die_offset(canonical_dies,
2814 initial_die_offset);
2821 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2824 Dwarf_Off die_offset = i->second[n];
2825 get_die_from_offset(source, die_offset, &canonical_die);
2827 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2828 die, &canonical_die,
2831 set_canonical_die_offset(canonical_dies,
2841 get_die_from_offset(source, initial_die_offset, &canonical_die);
2842 i->second.push_back(initial_die_offset);
2843 set_canonical_die_offset(canonical_dies,
2845 initial_die_offset);
2862 get_die_source(
const Dwarf_Die *die)
const
2864 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2885 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2889 uint8_t address_size = 0, offset_size = 0;
2890 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
2891 &cu_die, &address_size,
2895 Dwarf_Half version = 0;
2896 Dwarf_Off abbrev_offset = 0;
2897 uint64_t type_signature = 0;
2898 Dwarf_Off type_offset = 0;
2899 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2900 &version, &abbrev_offset,
2901 &address_size, &offset_size,
2902 &type_signature, &type_offset))
2905 int tag = dwarf_tag(&cu_kind);
2907 if (tag == DW_TAG_compile_unit
2908 || tag == DW_TAG_partial_unit)
2910 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
2911 if (dwarf_debug_info() == die_dwarf)
2912 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
2913 else if (alternate_dwarf_debug_info() == die_dwarf)
2914 source = ALT_DEBUG_INFO_DIE_SOURCE;
2918 else if (tag == DW_TAG_type_unit)
2919 source = TYPE_UNIT_DIE_SOURCE;
2935 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
2937 if (source == TYPE_UNIT_DIE_SOURCE)
2938 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2941 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2968 associate_die_to_decl(Dwarf_Die* die,
2969 decl_base_sptr decl,
2970 size_t where_offset,
2971 bool do_associate_by_repr =
false)
2973 const die_source source = get_die_source(die);
2976 decl_die_artefact_maps().get_container(source);
2979 if (do_associate_by_repr)
2981 Dwarf_Die equiv_die;
2982 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
2985 die_offset = dwarf_dieoffset(&equiv_die);
2988 die_offset = dwarf_dieoffset(die);
2990 m[die_offset] = decl;
3012 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3014 decl_base_sptr result =
3015 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3034 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3038 die_qualified_name_maps_.get_container(*
this, die);
3040 size_t die_offset = dwarf_dieoffset(die);
3041 die_istring_map_type::const_iterator i = map.find(die_offset);
3045 reader& rdr = *
const_cast<reader*
>(
this);
3046 string qualified_name = die_qualified_name(rdr, die, where_offset);
3047 interned_string istr = env().intern(qualified_name);
3048 map[die_offset] = istr;
3068 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3070 return const_cast<reader*
>(
this)->
3071 get_die_qualified_name(die, where_offset);
3092 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3097 if (die == cur_tu_die())
3098 return env().intern(
"");
3101 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3104 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3105 die_istring_map_type::const_iterator i =
3106 map.find(die_offset);
3110 reader& rdr = *
const_cast<reader*
>(
this);
3111 string qualified_name;
3112 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3113 if ((tag == DW_TAG_structure_type
3114 || tag == DW_TAG_class_type
3115 || tag == DW_TAG_union_type)
3116 && die_is_anonymous(die))
3118 location l = die_location(*
this, die);
3119 qualified_name = l ? l.expand() :
"noloc";
3120 qualified_name =
"unnamed-at-" + qualified_name;
3124 die_qualified_type_name(rdr, die, where_offset);
3126 interned_string istr = env().intern(qualified_name);
3127 map[die_offset] = istr;
3151 get_die_pretty_type_representation(
const Dwarf_Die *die,
3152 size_t where_offset)
const
3156 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3159 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3160 die_istring_map_type::const_iterator i = map.find(die_offset);
3164 reader& rdr = *
const_cast<reader*
>(
this);
3165 string pretty_representation =
3166 die_pretty_print_type(rdr, die, where_offset);
3167 interned_string istr = env().intern(pretty_representation);
3168 map[die_offset] = istr;
3188 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3193 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3196 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3197 die_istring_map_type::const_iterator i = map.find(die_offset);
3201 reader& rdr = *
const_cast<reader*
>(
this);
3202 string pretty_representation =
3203 die_pretty_print(rdr, die, where_offset);
3204 interned_string istr = env().intern(pretty_representation);
3205 map[die_offset] = istr;
3229 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3232 lookup_artifact_from_die(die,
true);
3234 return fn->get_type();
3258 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3260 Dwarf_Die equiv_die;
3261 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3266 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3267 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3269 size_t die_offset = dwarf_dieoffset(&equiv_die);
3270 die_artefact_map_type::const_iterator i = m.find(die_offset);
3297 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3299 bool die_as_type =
false)
const
3303 ? type_die_artefact_maps().get_container(source)
3304 : decl_die_artefact_maps().get_container(source);
3306 die_artefact_map_type::const_iterator i = m.find(die_offset);
3323 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
3326 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
3329 lang = dwarf_language_to_tu_language(l);
3341 die_is_in_c(
const Dwarf_Die *die)
const
3344 if (!get_die_language(die, l))
3357 die_is_in_cplus_plus(
const Dwarf_Die *die)
const
3360 if (!get_die_language(die, l))
3373 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
const
3376 if (!get_die_language(die, l))
3418 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3433 if (!get_die_language(die, lang))
3444 die_source_dependant_container_set<die_artefact_map_type>&
3445 decl_die_artefact_maps()
3446 {
return decl_die_artefact_maps_;}
3453 const die_source_dependant_container_set<die_artefact_map_type>&
3454 decl_die_artefact_maps()
const
3455 {
return decl_die_artefact_maps_;}
3462 die_source_dependant_container_set<die_artefact_map_type>&
3463 type_die_artefact_maps()
3464 {
return type_die_artefact_maps_;}
3471 const die_source_dependant_container_set<die_artefact_map_type>&
3472 type_die_artefact_maps()
const
3473 {
return type_die_artefact_maps_;}
3481 per_tu_repr_to_fn_type_maps()
3482 {
return per_tu_repr_to_fn_type_maps_;}
3490 per_tu_repr_to_fn_type_maps()
const
3491 {
return per_tu_repr_to_fn_type_maps_;}
3501 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3504 if (!die_is_function_type(die))
3507 interned_string repr =
3508 get_die_pretty_type_representation(die, 0);
3511 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3522 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3524 if (!die_is_function_type(die))
3527 interned_string repr = die_name(die).empty() ?
3528 get_die_pretty_type_representation(die, 0)
3529 : get_die_pretty_representation(die, 0);
3532 istring_fn_type_map_type::const_iterator i =
3533 per_tu_repr_to_fn_type_maps().find(repr);
3535 if (i == per_tu_repr_to_fn_type_maps().end())
3552 Dwarf_Off die_offset,
3553 Dwarf_Off canonical_die_offset)
const
3555 canonical_dies[die_offset] = canonical_die_offset;}
3571 set_canonical_die_offset(Dwarf_Off die_offset,
3573 Dwarf_Off canonical_die_offset,
3574 bool die_as_type)
const
3578 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3579 get_container(source)
3580 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3581 get_container(source);
3583 set_canonical_die_offset(canonical_dies,
3585 canonical_die_offset);
3599 set_canonical_die_offset(
const Dwarf_Die *die,
3600 Dwarf_Off canonical_die_offset,
3601 bool die_as_type)
const
3603 const die_source source = get_die_source(die);
3605 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3607 set_canonical_die_offset(die_offset, source,
3608 canonical_die_offset,
3622 Dwarf_Off die_offset)
const
3624 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3625 if (it == canonical_dies.end())
3642 get_canonical_die_offset(Dwarf_Off die_offset,
3644 bool die_as_type)
const
3648 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3649 get_container(source)
3650 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3651 get_container(source);
3653 return get_canonical_die_offset(canonical_dies, die_offset);
3668 erase_canonical_die_offset(Dwarf_Off die_offset,
3670 bool die_as_type)
const
3674 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3675 get_container(source)
3676 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3677 get_container(source);
3679 return canonical_dies.erase(die_offset);
3692 associate_die_to_type(
const Dwarf_Die *die,
3693 type_base_sptr type,
3699 Dwarf_Die equiv_die;
3700 if (!get_or_compute_canonical_die(die, equiv_die, where,
3705 type_die_artefact_maps().get_container(*
this, &equiv_die);
3707 size_t die_offset = dwarf_dieoffset(&equiv_die);
3708 m[die_offset] = type;
3722 lookup_type_from_die(
const Dwarf_Die* die)
const
3725 lookup_artifact_from_die(die,
true);
3727 return fn->get_type();
3745 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3747 type_base_sptr result;
3749 type_die_artefact_maps().get_container(source);
3750 die_artefact_map_type::const_iterator i = m.find(die_offset);
3754 return fn->get_type();
3762 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3772 die_wip_function_types_map(source);
3773 die_function_type_map_type::const_iterator i = m.find(die_offset);
3792 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3807 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3809 case ALT_DEBUG_INFO_DIE_SOURCE:
3810 return alternate_die_wip_classes_map_;
3811 case TYPE_UNIT_DIE_SOURCE:
3812 return type_unit_die_wip_classes_map_;
3813 case NO_DEBUG_INFO_DIE_SOURCE:
3814 case NUMBER_OF_DIE_SOURCES:
3817 return die_wip_classes_map_;
3828 die_wip_function_types_map(
die_source source)
const
3829 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3839 die_wip_function_types_map(
die_source source)
3843 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3845 case ALT_DEBUG_INFO_DIE_SOURCE:
3846 return alternate_die_wip_function_types_map_;
3847 case TYPE_UNIT_DIE_SOURCE:
3848 return type_unit_die_wip_function_types_map_;
3849 case NO_DEBUG_INFO_DIE_SOURCE:
3850 case NUMBER_OF_DIE_SOURCES:
3853 return die_wip_function_types_map_;
3864 die_function_decl_with_no_symbol_map()
3865 {
return die_function_with_no_symbol_map_;}
3878 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3880 die_class_or_union_map_type::const_iterator i =
3881 die_wip_classes_map(source).find(offset);
3882 return (i != die_wip_classes_map(source).end());
3896 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3898 die_function_type_map_type::const_iterator i =
3899 die_wip_function_types_map(source).find(offset);
3900 return (i != die_wip_function_types_map(source).end());
3919 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3925 || dwarf_tag(die) != DW_TAG_member
3926 || !die_name(die).empty())
3932 if (die_is_anonymous_data_member(die))
3938 int64_t offset_in_bits = 0;
3939 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3943 loc = die_location(*
this, die);
3948 std::ostringstream o;
3949 o <<
"unnamed-dm-@-";
3951 o <<
"offset-" << offset_in_bits <<
"bits";
3953 o <<
"loc-" << loc.expand();
3966 declaration_only_classes()
const
3967 {
return decl_only_classes_map_;}
3977 declaration_only_classes()
3978 {
return decl_only_classes_map_;}
3986 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
3988 if (cou->get_is_declaration_only()
3989 && cou->get_definition_of_declaration() == 0)
3991 string qn = cou->get_qualified_name();
3992 string_classes_or_unions_map::iterator record =
3993 declaration_only_classes().find(qn);
3994 if (record == declaration_only_classes().end())
3995 declaration_only_classes()[qn].push_back(cou);
3997 record->second.push_back(cou);
4009 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4011 if (cou->get_is_declaration_only())
4012 return (declaration_only_classes().find(cou->get_qualified_name())
4013 != declaration_only_classes().end());
4033 const environment& e = l->get_environment();
4036 e.priv_->allow_type_comparison_results_caching(
true);
4037 bool s0 = e.decl_only_class_equals_definition();
4038 e.decl_only_class_equals_definition(
true);
4039 bool equal = l == r;
4040 e.decl_only_class_equals_definition(s0);
4041 e.priv_->clear_type_comparison_results_cache();
4042 e.priv_->allow_type_comparison_results_caching(
false);
4049 resolve_declaration_only_classes()
4051 vector<string> resolved_classes;
4053 for (string_classes_or_unions_map::iterator i =
4054 declaration_only_classes().begin();
4055 i != declaration_only_classes().end();
4058 bool to_resolve =
false;
4059 for (classes_or_unions_type::iterator j = i->second.begin();
4060 j != i->second.end();
4062 if ((*j)->get_is_declaration_only()
4063 && ((*j)->get_definition_of_declaration() == 0))
4068 resolved_classes.push_back(i->first);
4113 map<string, class_or_union_sptr> per_tu_class_map;
4114 for (type_base_wptrs_type::const_iterator c = classes->begin();
4115 c != classes->end();
4122 if (klass->get_is_declaration_only())
4125 string tu_path = klass->get_translation_unit()->get_absolute_path();
4126 if (tu_path.empty())
4132 per_tu_class_map[tu_path] = klass;
4135 if (!per_tu_class_map.empty())
4141 for (classes_or_unions_type::iterator j = i->second.begin();
4142 j != i->second.end();
4145 if ((*j)->get_is_declaration_only()
4146 && ((*j)->get_definition_of_declaration() == 0))
4149 (*j)->get_translation_unit()->get_absolute_path();
4150 map<string, class_or_union_sptr>::const_iterator e =
4151 per_tu_class_map.find(tu_path);
4152 if (e != per_tu_class_map.end())
4153 (*j)->set_definition_of_declaration(e->second);
4154 else if (per_tu_class_map.size() == 1)
4155 (*j)->set_definition_of_declaration
4156 (per_tu_class_map.begin()->second);
4166 class_or_union_sptr>::const_iterator it;
4167 class_or_union_sptr first_class =
4168 per_tu_class_map.begin()->second;
4169 bool all_class_definitions_are_equal =
true;
4170 for (it = per_tu_class_map.begin();
4171 it != per_tu_class_map.end();
4174 if (it == per_tu_class_map.begin())
4178 if (!compare_before_canonicalisation(it->second,
4181 all_class_definitions_are_equal =
false;
4186 if (all_class_definitions_are_equal)
4187 (*j)->set_definition_of_declaration(first_class);
4191 resolved_classes.push_back(i->first);
4195 size_t num_decl_only_classes = declaration_only_classes().size(),
4196 num_resolved = resolved_classes.size();
4198 cerr <<
"resolved " << num_resolved
4199 <<
" class declarations out of "
4200 << num_decl_only_classes
4203 for (vector<string>::const_iterator i = resolved_classes.begin();
4204 i != resolved_classes.end();
4206 declaration_only_classes().erase(*i);
4208 if (show_stats() && !declaration_only_classes().empty())
4210 cerr <<
"Here are the "
4211 << num_decl_only_classes - num_resolved
4212 <<
" unresolved class declarations:\n";
4213 for (string_classes_or_unions_map::iterator i =
4214 declaration_only_classes().begin();
4215 i != declaration_only_classes().end();
4217 cerr <<
" " << i->first <<
"\n";
4229 declaration_only_enums()
const
4230 {
return decl_only_enums_map_;}
4240 declaration_only_enums()
4241 {
return decl_only_enums_map_;}
4251 if (enom->get_is_declaration_only()
4252 && enom->get_definition_of_declaration() == 0)
4254 string qn = enom->get_qualified_name();
4255 string_enums_map::iterator record =
4256 declaration_only_enums().find(qn);
4257 if (record == declaration_only_enums().end())
4258 declaration_only_enums()[qn].push_back(enom);
4260 record->second.push_back(enom);
4274 if (enom->get_is_declaration_only())
4275 return (declaration_only_enums().find(enom->get_qualified_name())
4276 != declaration_only_enums().end());
4289 resolve_declaration_only_enums()
4291 vector<string> resolved_enums;
4293 for (string_enums_map::iterator i =
4294 declaration_only_enums().begin();
4295 i != declaration_only_enums().end();
4298 bool to_resolve =
false;
4299 for (enums_type::iterator j = i->second.begin();
4300 j != i->second.end();
4302 if ((*j)->get_is_declaration_only()
4303 && ((*j)->get_definition_of_declaration() == 0))
4308 resolved_enums.push_back(i->first);
4350 map<string, enum_type_decl_sptr> per_tu_enum_map;
4351 for (type_base_wptrs_type::const_iterator c = enums->begin();
4359 if (enom->get_is_declaration_only())
4362 string tu_path = enom->get_translation_unit()->get_absolute_path();
4363 if (tu_path.empty())
4369 per_tu_enum_map[tu_path] = enom;
4372 if (!per_tu_enum_map.empty())
4378 for (enums_type::iterator j = i->second.begin();
4379 j != i->second.end();
4382 if ((*j)->get_is_declaration_only()
4383 && ((*j)->get_definition_of_declaration() == 0))
4386 (*j)->get_translation_unit()->get_absolute_path();
4387 map<string, enum_type_decl_sptr>::const_iterator e =
4388 per_tu_enum_map.find(tu_path);
4389 if (e != per_tu_enum_map.end())
4390 (*j)->set_definition_of_declaration(e->second);
4391 else if (per_tu_enum_map.size() == 1)
4392 (*j)->set_definition_of_declaration
4393 (per_tu_enum_map.begin()->second);
4405 per_tu_enum_map.begin()->second;
4406 bool all_enum_definitions_are_equal =
true;
4407 for (it = per_tu_enum_map.begin();
4408 it != per_tu_enum_map.end();
4411 if (it == per_tu_enum_map.begin())
4415 if (!compare_before_canonicalisation(it->second,
4418 all_enum_definitions_are_equal =
false;
4423 if (all_enum_definitions_are_equal)
4424 (*j)->set_definition_of_declaration(first_enum);
4428 resolved_enums.push_back(i->first);
4432 size_t num_decl_only_enums = declaration_only_enums().size(),
4433 num_resolved = resolved_enums.size();
4435 cerr <<
"resolved " << num_resolved
4436 <<
" enum declarations out of "
4437 << num_decl_only_enums
4440 for (vector<string>::const_iterator i = resolved_enums.begin();
4441 i != resolved_enums.end();
4443 declaration_only_enums().erase(*i);
4445 if (show_stats() && !declaration_only_enums().empty())
4447 cerr <<
"Here are the "
4448 << num_decl_only_enums - num_resolved
4449 <<
" unresolved enum declarations:\n";
4450 for (string_enums_map::iterator i = declaration_only_enums().begin();
4451 i != declaration_only_enums().end();
4453 cerr <<
" " << i->first <<
"\n";
4469 corpus_sptr corp = corpus();
4473 string id = fn->get_id_string();
4475 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4480 if (f->get_symbol())
4500 fixup_functions_with_no_symbols()
4502 corpus_sptr corp = corpus();
4507 die_function_decl_with_no_symbol_map();
4510 cerr << fns_with_no_symbol.size()
4511 <<
" functions to fixup, potentially\n";
4513 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4514 i != fns_with_no_symbol.end();
4517 corp->lookup_function_symbol(i->second->get_linkage_name()))
4532 if (i->second->get_symbol()
4533 || symbol_already_belongs_to_a_function(sym))
4538 i->second->set_symbol(sym);
4541 i->second->set_is_in_public_symbol_table(
true);
4544 maybe_add_fn_to_exported_decls(i->second.get());
4546 cerr <<
"fixed up '"
4547 << i->second->get_pretty_representation()
4548 <<
"' with symbol '"
4549 << sym->get_id_string()
4553 fns_with_no_symbol.clear();
4563 const vector<type_base_sptr>&
4564 types_to_canonicalize()
const
4565 {
return types_to_canonicalize_;}
4569 clear_types_to_canonicalize()
4571 types_to_canonicalize_.clear();
4579 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4581 types_to_canonicalize_.push_back(t);
4591 canonicalize_types_scheduled()
4593 tools_utils::timer cn_timer;
4596 cerr <<
"going to canonicalize types";
4597 corpus_sptr c = corpus();
4599 cerr <<
" of corpus " << corpus()->get_path();
4603 if (!types_to_canonicalize().empty())
4605 types_to_canonicalize().end(),
4606 [](
const vector<type_base_sptr>::const_iterator& i)
4612 cerr <<
"finished canonicalizing types";
4613 corpus_sptr c = corpus();
4615 cerr <<
" of corpus " << corpus()->get_path();
4616 cerr <<
": (" << cn_timer <<
")\n";
4633 add_late_canonicalized_types_stats(
size_t& canonicalized,
4634 size_t& missed)
const
4636 for (
auto t : types_to_canonicalize())
4638 if (t->get_canonical_type())
4648 perform_late_type_canonicalizing()
4650 canonicalize_types_scheduled();
4654 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4655 add_late_canonicalized_types_stats(num_canonicalized,
4657 total = num_canonicalized + num_missed;
4661 cerr <<
" # late canonicalized types: "
4662 << num_canonicalized;
4664 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4666 <<
" # missed canonicalization opportunities: "
4669 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4677 {
return die_tu_map_;}
4681 {
return die_tu_map_;}
4690 tu_die_imported_unit_points_map(
die_source source)
const
4691 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4700 tu_die_imported_unit_points_map(
die_source source)
4704 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4706 case ALT_DEBUG_INFO_DIE_SOURCE:
4707 return alt_tu_die_imported_unit_points_map_;
4708 case TYPE_UNIT_DIE_SOURCE:
4709 return type_units_tu_die_imported_unit_points_map_;
4710 case NO_DEBUG_INFO_DIE_SOURCE:
4711 case NUMBER_OF_DIE_SOURCES:
4715 return tu_die_imported_unit_points_map_;
4733 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4746 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4748 case ALT_DEBUG_INFO_DIE_SOURCE:
4749 return alternate_die_parent_map_;
4750 case TYPE_UNIT_DIE_SOURCE:
4751 return type_section_die_parent_map();
4752 case NO_DEBUG_INFO_DIE_SOURCE:
4753 case NUMBER_OF_DIE_SOURCES:
4756 return primary_die_parent_map_;
4760 type_section_die_parent_map()
const
4761 {
return type_section_die_parent_map_;}
4764 type_section_die_parent_map()
4765 {
return type_section_die_parent_map_;}
4771 cur_transl_unit()
const
4795 global_scope()
const
4796 {
return cur_transl_unit()->get_global_scope();}
4803 {
return nil_scope_;}
4807 {
return scope_stack_;}
4811 {
return scope_stack_;}
4816 if (scope_stack().empty())
4818 if (cur_transl_unit())
4821 return scope_stack().top();
4824 list<var_decl_sptr>&
4825 var_decls_to_re_add_to_tree()
4826 {
return var_decls_to_add_;}
4839 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
4841 if (!die || !die_is_decl(die))
4844 bool result =
false, address_found =
false, symbol_is_exported =
false;;
4845 Dwarf_Addr decl_symbol_address = 0;
4847 if (die_is_variable_decl(die))
4849 if ((address_found = get_variable_address(die, decl_symbol_address)))
4850 symbol_is_exported =
4851 !!variable_symbol_is_exported(decl_symbol_address);
4853 else if (die_is_function_decl(die))
4855 if ((address_found = get_function_address(die, decl_symbol_address)))
4856 symbol_is_exported =
4857 !!function_symbol_is_exported(decl_symbol_address);
4861 result = symbol_is_exported;
4880 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
4886 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
4888 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4890 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4892 dwarf_elf_load_address));
4895 if (dwarf_is_splitted()
4896 && (dwarf_elf_load_address != elf_load_address))
4907 addr = addr - dwarf_elf_load_address + elf_load_address;
4933 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
4938 Elf* elf = elf_handle();
4940 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4942 if (elf_header->e_type == ET_REL)
4955 addr = maybe_adjust_address_for_exec_or_dyn(addr);
4980 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
4982 Elf* elf = elf_handle();
4984 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4986 if (elf_header->e_type == ET_REL)
4999 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5018 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5019 Dwarf_Addr& address)
const
5022 Dwarf_Addr end_addr;
5023 ptrdiff_t offset = 0;
5027 Dwarf_Addr addr = 0, fn_addr = 0;
5028 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5030 fn_addr = maybe_adjust_fn_sym_address(addr);
5031 if (function_symbol_is_exported(fn_addr))
5037 }
while (offset > 0);
5055 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5057 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5058 DW_AT_low_pc, address))
5064 if (!get_first_exported_fn_address_from_DW_AT_ranges
5065 (
const_cast<Dwarf_Die*
>(function_die),
5069 address = maybe_adjust_fn_sym_address(address);
5088 get_variable_address(
const Dwarf_Die* variable_die,
5089 Dwarf_Addr& address)
const
5091 bool is_tls_address =
false;
5092 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5093 address, is_tls_address))
5095 if (!is_tls_address)
5096 address = maybe_adjust_var_sym_address(address);
5103 corpus::exported_decls_builder*
5104 exported_decls_builder()
5105 {
return corpus()->get_exported_decls_builder().get();}
5113 load_all_types()
const
5114 {
return options().load_all_types;}
5122 load_all_types(
bool f)
5123 {options().load_all_types = f;}
5126 load_in_linux_kernel_mode()
const
5127 {
return options().load_in_linux_kernel_mode;}
5130 load_in_linux_kernel_mode(
bool f)
5131 {options().load_in_linux_kernel_mode = f;}
5141 leverage_dwarf_factorization()
const
5143 if (!leverage_dwarf_factorization_.has_value())
5145 if (options().leverage_dwarf_factorization
5146 && elf_helpers::find_section_by_name(elf_handle(),
5147 ".gnu_debugaltlink"))
5148 leverage_dwarf_factorization_ =
true;
5150 leverage_dwarf_factorization_ =
false;
5152 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5154 return *leverage_dwarf_factorization_;
5164 {
return options().show_stats;}
5174 {options().show_stats = f;}
5184 {
return options().do_log;}
5193 {options().do_log = f;}
5213 build_die_parent_relations_under(Dwarf_Die* die,
5223 if (dwarf_child(die, &child) != 0)
5228 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5229 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5231 Dwarf_Die imported_unit;
5232 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5243 && die_has_children(&imported_unit))
5245 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5246 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5247 imported_units.push_back
5248 (imported_unit_point(dwarf_dieoffset(&child),
5250 imported_unit_die_source));
5253 build_die_parent_relations_under(&child, source, imported_units);
5255 while (dwarf_siblingof(&child, &child) == 0);
5287 case translation_unit::LANG_UNKNOWN:
5288 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5289 case translation_unit::LANG_Mips_Assembler:
5316 build_die_parent_maps()
5318 bool we_do_have_to_build_die_parent_map =
false;
5319 uint8_t address_size = 0;
5320 size_t header_size = 0;
5325 for (Dwarf_Off offset = 0, next_offset = 0;
5326 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
5327 offset, &next_offset, &header_size,
5328 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5329 offset = next_offset)
5331 Dwarf_Off die_offset = offset + header_size;
5333 if (!dwarf_offdie(
const_cast<Dwarf*
>(dwarf_debug_info()),
5338 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5340 if (do_we_build_die_parent_maps(lang))
5341 we_do_have_to_build_die_parent_map =
true;
5344 if (!we_do_have_to_build_die_parent_map)
5349 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5350 for (Dwarf_Off offset = 0, next_offset = 0;
5351 (dwarf_next_unit(
const_cast<Dwarf*
>(alternate_dwarf_debug_info()),
5352 offset, &next_offset, &header_size,
5353 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5354 offset = next_offset)
5356 Dwarf_Off die_offset = offset + header_size;
5358 if (!dwarf_offdie(
const_cast<Dwarf*
>(alternate_dwarf_debug_info()),
5364 tu_die_imported_unit_points_map(source)[die_offset] =
5366 build_die_parent_relations_under(&cu, source, imported_units);
5371 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5374 for (Dwarf_Off offset = 0, next_offset = 0;
5375 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
5376 offset, &next_offset, &header_size,
5377 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5378 offset = next_offset)
5380 Dwarf_Off die_offset = offset + header_size;
5382 if (!dwarf_offdie(
const_cast<Dwarf*
>(dwarf_debug_info()),
5387 tu_die_imported_unit_points_map(source)[die_offset] =
5389 build_die_parent_relations_under(&cu, source, imported_units);
5394 source = TYPE_UNIT_DIE_SOURCE;
5397 uint64_t type_signature = 0;
5398 Dwarf_Off type_offset;
5399 for (Dwarf_Off offset = 0, next_offset = 0;
5400 (dwarf_next_unit(
const_cast<Dwarf*
>(dwarf_debug_info()),
5401 offset, &next_offset, &header_size,
5402 NULL, NULL, &address_size, NULL,
5403 &type_signature, &type_offset) == 0);
5404 offset = next_offset)
5406 Dwarf_Off die_offset = offset + header_size;
5409 if (!dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_debug_info()),
5414 tu_die_imported_unit_points_map(source)[die_offset] =
5416 build_die_parent_relations_under(&cu, source, imported_units);
5431 struct offset_pairs_stack_type
5448 offset_pairs_stack_type(
const reader& rdr)
5474 offset_pair_vector_type::iterator i;
5476 for (i = vect_.begin();i < vect_.end(); ++i)
5480 if (i != vect_.end())
5499 if (set_.find(p) == set_.end())
5526 bool result =
false;
5531 offset_pair_vector_type::const_iterator i;
5532 for (i = vect_.begin(); i != vect_.end(); ++i)
5536 if (i == vect_.end())
5541 for (++i; i != vect_.end(); ++i)
5543 pairs.push_back(*i);
5563 for (
auto type_pair : dependant_types)
5564 dependant_types_[type_pair].push_back(p);
5575 get_pairs_that_depend_on(p, dependant_types);
5578 auto it = redundant_types_.find(p);
5579 if (it == redundant_types_.end())
5581 auto entry = std::make_pair(p, dependant_types);
5582 redundant_types_.insert(entry);
5585 it->second.insert(it->second.end(),
5586 dependant_types.begin(),
5587 dependant_types.end());
5591 record_dependant_types(p, dependant_types);
5602 auto i = redundant_types_.find(p);
5603 if (i != redundant_types_.end())
5616 auto i = dependant_types_.find(p);
5617 if (i == dependant_types_.end())
5635 bool erase_cached_results =
false)
5639 auto redundant_type = redundant_types_.find(p);
5640 if (redundant_type != redundant_types_.end())
5642 for (
auto dependant_type : redundant_type->second)
5646 auto dependant_types_it = dependant_types_.find(dependant_type);
5647 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5651 auto i = dependant_types_it->second.begin();
5652 for (; i!= dependant_types_it->second.end();++i)
5655 if (i != dependant_types_it->second.end())
5656 dependant_types_it->second.erase(i);
5661 if (dependant_types_it->second.empty())
5663 if (erase_cached_results)
5664 rdr_.die_comparison_results_.erase(dependant_type);
5665 dependant_types_.erase(dependant_types_it);
5669 if (erase_cached_results)
5670 rdr_.die_comparison_results_.erase(p);
5671 redundant_types_.erase(p);
5683 {erase_redundant_type_pair_entry(p,
true);}
5696 get_dependant_types(p, dependant_types,
true);
5697 for (
auto dependant_type : dependant_types)
5701 if (rdr_.propagated_types_.find(dependant_type)
5702 != rdr_.propagated_types_.end())
5704 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5705 dependant_type.first.source_,
5707 rdr_.propagated_types_.erase(dependant_type);
5708 rdr_.cancelled_propagation_count_++;
5712 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5713 if (comp_result_it != rdr_.die_comparison_results_.end())
5714 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5718 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5719 if (comp_result_it != rdr_.die_comparison_results_.end())
5726 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5727 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5728 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5731 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5733 rdr_.erase_canonical_die_offset(p.first.offset_,
5736 rdr_.propagated_types_.erase(p);
5737 rdr_.cancelled_propagation_count_++;
5756 bool transitive_closure =
false)
5758 auto i = redundant_types_.find(p);
5759 if (i != redundant_types_.end())
5761 for (
auto dependant_type : i->second)
5762 if (result.find(dependant_type) == result.end())
5764 result.insert(dependant_type);
5765 if (transitive_closure)
5766 get_dependant_types(p, result,
true);
5775 build_ir_node_from_die(reader& rdr,
5778 bool called_from_public_decl,
5779 size_t where_offset,
5780 bool is_declaration_only =
true,
5781 bool is_required_decl_spec =
false);
5784 build_ir_node_from_die(reader& rdr,
5786 bool called_from_public_decl,
5787 size_t where_offset);
5790 add_or_update_class_type(reader& rdr,
5795 bool called_from_public_decl,
5796 size_t where_offset,
5797 bool is_declaration_only);
5799 static union_decl_sptr
5800 add_or_update_union_type(reader& rdr,
5803 union_decl_sptr union_type,
5804 bool called_from_public_decl,
5805 size_t where_offset,
5806 bool is_declaration_only);
5808 static decl_base_sptr
5809 build_ir_node_for_void_type(reader& rdr);
5811 static decl_base_sptr
5812 build_ir_node_for_variadic_parameter_type(reader &rdr);
5815 build_function_decl(reader& rdr,
5817 size_t where_offset,
5821 function_is_suppressed(
const reader& rdr,
5822 const scope_decl* scope,
5823 Dwarf_Die *function_die,
5824 bool is_declaration_only);
5827 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5830 size_t where_offset,
5831 bool is_declaration_only,
5835 build_var_decl(reader& rdr,
5837 size_t where_offset,
5841 build_or_get_var_decl_if_not_suppressed(reader& rdr,
5844 size_t where_offset,
5846 bool is_required_decl_spec =
false);
5848 variable_is_suppressed(
const reader& rdr,
5849 const scope_decl* scope,
5850 Dwarf_Die *variable_die,
5851 bool is_required_decl_spec =
false);
5854 finish_member_function_reading(Dwarf_Die* die,
5856 const class_or_union_sptr klass,
5865 die_is_anonymous(
const Dwarf_Die* die)
5867 Dwarf_Attribute attr;
5868 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
5882 die_is_anonymous_data_member(
const Dwarf_Die* die)
5885 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
5886 || !die_name(die).empty())
5890 if (!die_die_attribute(die, DW_AT_type, type_die))
5893 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5894 && dwarf_tag(&type_die) != DW_TAG_union_type)
5911 die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5916 Dwarf_Attribute attr;
5917 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5920 const char* str = dwarf_formstring(&attr);
5921 return str ? str :
"";
5935 die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5940 Dwarf_Attribute attr;
5941 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5944 const char* str = dwarf_formstring(&attr);
5964 die_unsigned_constant_attribute(
const Dwarf_Die* die,
5971 Dwarf_Attribute attr;
5972 Dwarf_Word result = 0;
5973 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
5974 || dwarf_formudata(&attr, &result))
5994 die_signed_constant_attribute(
const Dwarf_Die *die,
6001 Dwarf_Attribute attr;
6002 Dwarf_Sword result = 0;
6003 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6004 || dwarf_formsdata(&attr, &result))
6030 die_constant_attribute(
const Dwarf_Die *die,
6033 array_type_def::subrange_type::bound_value &value)
6038 if (!die_unsigned_constant_attribute(die, attr_name, l))
6040 value.set_unsigned(l);
6045 if (!die_signed_constant_attribute(die, attr_name, l))
6047 value.set_signed(l);
6062 form_is_DW_FORM_strx(
unsigned form)
6066 #if defined HAVE_DW_FORM_strx1 \
6067 && defined HAVE_DW_FORM_strx2 \
6068 && defined HAVE_DW_FORM_strx3 \
6069 && defined HAVE_DW_FORM_strx4
6070 if (form == DW_FORM_strx1
6071 || form == DW_FORM_strx2
6072 || form == DW_FORM_strx3
6073 ||form == DW_FORM_strx4)
6090 form_is_DW_FORM_line_strp(
unsigned form)
6094 #if defined HAVE_DW_FORM_line_strp
6095 if (form == DW_FORM_line_strp)
6122 die_flag_attribute(
const Dwarf_Die* die,
6125 bool recursively =
true)
6127 Dwarf_Attribute attr;
6129 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6130 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6134 if (dwarf_formflag(&attr, &f))
6148 die_linkage_name(
const Dwarf_Die* die)
6153 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6154 if (linkage_name.empty())
6155 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6156 return linkage_name;
6170 die_decl_file_attribute(
const Dwarf_Die* die)
6175 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6177 return str ? str :
"";
6198 die_die_attribute(
const Dwarf_Die* die,
6203 Dwarf_Attribute attr;
6205 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6206 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6209 return dwarf_formref_die(&attr, &result);
6239 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6241 Dwarf_Die& referenced_subrange)
6243 bool result =
false;
6245 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6248 Dwarf_Die referenced_die;
6249 if (die_die_attribute(die, attr_name, referenced_die))
6251 unsigned tag = dwarf_tag(&referenced_die);
6252 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6255 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6257 tag = dwarf_tag(&type_die);
6258 if (tag == DW_TAG_subrange_type)
6260 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6296 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6298 array_type_def::subrange_type::bound_value& v,
6301 bool result =
false;
6303 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6306 Dwarf_Die subrange_die;
6307 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6310 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6328 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6330 Dwarf_Attribute attr;
6331 if (!dwarf_attr_integrate(die, attr_name, &attr))
6333 return dwarf_formaddr(&attr, &result) == 0;
6344 die_location(
const reader& rdr,
const Dwarf_Die* die)
6349 string file = die_decl_file_attribute(die);
6351 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6353 if (!file.empty() && line != 0)
6356 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6368 die_name(
const Dwarf_Die* die)
6370 string name = die_string_attribute(die, DW_AT_name);
6386 die_loc_and_name(
const reader& rdr,
6390 string& linkage_name)
6392 loc = die_location(rdr, die);
6393 name = die_name(die);
6394 linkage_name = die_linkage_name(die);
6407 die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6412 uint64_t byte_size = 0, bit_size = 0;
6414 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6416 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6420 bit_size = byte_size * 8;
6443 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6450 case private_access:
6451 result = private_access;
6454 case protected_access:
6455 result = protected_access;
6459 result = public_access;
6478 die_is_public_decl(
const Dwarf_Die* die)
6482 bool is_public =
false;
6488 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6489 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6490 die_flag_attribute(die, DW_AT_external, is_public);
6491 else if (tag == DW_TAG_namespace)
6493 string name = die_name(die);
6494 is_public = !name.empty();
6508 die_is_effectively_public_decl(
const reader& rdr,
6509 const Dwarf_Die* die)
6511 if (die_is_public_decl(die))
6514 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6515 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6518 Dwarf_Die parent_die;
6519 size_t where_offset = 0;
6520 if (!get_parent_die(rdr, die, parent_die, where_offset))
6523 tag = dwarf_tag(&parent_die);
6524 if (tag == DW_TAG_compile_unit
6525 || tag == DW_TAG_partial_unit
6526 || tag == DW_TAG_type_unit)
6530 if (tag == DW_TAG_namespace)
6532 string name = die_name(&parent_die);
6551 die_is_declaration_only(Dwarf_Die* die)
6553 bool is_declaration =
false;
6554 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6555 if (is_declaration && !die_has_size_attribute(die))
6566 die_is_function_decl(
const Dwarf_Die *die)
6571 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6572 if (tag == DW_TAG_subprogram)
6583 die_is_variable_decl(
const Dwarf_Die *die)
6588 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6589 if (tag == DW_TAG_variable)
6600 die_has_size_attribute(
const Dwarf_Die *die)
6603 if (die_size_in_bits(die, s))
6614 die_has_no_child(
const Dwarf_Die *die)
6620 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
6633 die_is_declaration_only(
const Dwarf_Die* die)
6634 {
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
6642 die_is_artificial(Dwarf_Die* die)
6645 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6652 is_type_tag(
unsigned tag)
6654 bool result =
false;
6658 case DW_TAG_array_type:
6659 case DW_TAG_class_type:
6660 case DW_TAG_enumeration_type:
6661 case DW_TAG_pointer_type:
6662 case DW_TAG_reference_type:
6663 case DW_TAG_string_type:
6664 case DW_TAG_structure_type:
6665 case DW_TAG_subroutine_type:
6666 case DW_TAG_typedef:
6667 case DW_TAG_union_type:
6668 case DW_TAG_ptr_to_member_type:
6669 case DW_TAG_set_type:
6670 case DW_TAG_subrange_type:
6671 case DW_TAG_base_type:
6672 case DW_TAG_const_type:
6673 case DW_TAG_file_type:
6674 case DW_TAG_packed_type:
6675 case DW_TAG_thrown_type:
6676 case DW_TAG_volatile_type:
6677 case DW_TAG_restrict_type:
6678 case DW_TAG_interface_type:
6679 case DW_TAG_unspecified_type:
6680 case DW_TAG_shared_type:
6681 case DW_TAG_rvalue_reference_type:
6682 case DW_TAG_coarray_type:
6683 case DW_TAG_atomic_type:
6684 case DW_TAG_immutable_type:
6707 is_canon_type_to_be_propagated_tag(
unsigned tag)
6709 bool result =
false;
6713 case DW_TAG_class_type:
6714 case DW_TAG_structure_type:
6715 case DW_TAG_union_type:
6716 case DW_TAG_subroutine_type:
6717 case DW_TAG_subprogram:
6738 type_comparison_result_to_be_cached(
unsigned tag)
6743 case DW_TAG_class_type:
6744 case DW_TAG_structure_type:
6745 case DW_TAG_union_type:
6746 case DW_TAG_subroutine_type:
6747 case DW_TAG_subprogram:
6768 maybe_cache_type_comparison_result(
const reader& rdr,
6773 if (!type_comparison_result_to_be_cached(tag)
6774 || (result != COMPARISON_RESULT_EQUAL
6775 && result != COMPARISON_RESULT_DIFFERENT))
6778 rdr.die_comparison_results_[p] = result;
6798 get_cached_type_comparison_result(
const reader& rdr,
6802 auto i = rdr.die_comparison_results_.find(p);
6803 if (i != rdr.die_comparison_results_.end())
6826 maybe_get_cached_type_comparison_result(
const reader& rdr,
6831 if (type_comparison_result_to_be_cached(tag))
6836 if (get_cached_type_comparison_result(rdr, p, result))
6848 is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
6850 bool result =
false;
6851 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6853 if (!is_type_tag(tag))
6858 case DW_TAG_class_type:
6859 case DW_TAG_structure_type:
6860 case DW_TAG_union_type:
6861 result = !die_is_declaration_only(die);
6864 case DW_TAG_subroutine_type:
6865 case DW_TAG_subprogram:
6866 case DW_TAG_array_type:
6882 is_decl_tag(
unsigned tag)
6886 case DW_TAG_formal_parameter:
6887 case DW_TAG_imported_declaration:
6889 case DW_TAG_unspecified_parameters:
6890 case DW_TAG_subprogram:
6891 case DW_TAG_variable:
6892 case DW_TAG_namespace:
6893 case DW_TAG_GNU_template_template_param:
6894 case DW_TAG_GNU_template_parameter_pack:
6895 case DW_TAG_GNU_formal_parameter_pack:
6907 die_is_type(
const Dwarf_Die* die)
6911 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
6920 die_is_decl(
const Dwarf_Die* die)
6924 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
6933 die_is_namespace(
const Dwarf_Die* die)
6937 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
6946 die_is_unspecified(Dwarf_Die* die)
6950 return (dwarf_tag(die) == DW_TAG_unspecified_type);
6959 die_is_void_type(Dwarf_Die* die)
6961 if (!die || dwarf_tag(die) != DW_TAG_base_type)
6964 string name = die_name(die);
6977 die_is_pointer_type(
const Dwarf_Die* die)
6982 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6983 if (tag == DW_TAG_pointer_type)
6997 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
6999 if (!die_is_pointer_array_or_reference_type(die)
7000 && !die_is_qualified_type(die))
7003 Dwarf_Die underlying_type_die;
7004 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7007 if (!die_is_class_type(&underlying_type_die))
7010 string name = die_name(&underlying_type_die);
7012 return name.empty();
7021 die_is_reference_type(
const Dwarf_Die* die)
7026 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7027 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7039 die_is_array_type(
const Dwarf_Die* die)
7044 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7045 if (tag == DW_TAG_array_type)
7057 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7058 {
return (die_is_pointer_type(die)
7059 || die_is_reference_type(die)
7060 || die_is_array_type(die));}
7068 die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7069 {
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7078 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7079 {
return (die_is_pointer_array_or_reference_type(die)
7080 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7088 die_is_class_type(
const Dwarf_Die* die)
7090 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7092 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7104 die_is_qualified_type(
const Dwarf_Die* die)
7106 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7107 if (tag == DW_TAG_const_type
7108 || tag == DW_TAG_volatile_type
7109 || tag == DW_TAG_restrict_type)
7121 die_is_function_type(
const Dwarf_Die *die)
7123 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7124 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7142 die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7147 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7159 die_has_children(
const Dwarf_Die* die)
7165 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7185 die_this_pointer_from_object_pointer(Dwarf_Die* die,
7186 Dwarf_Die& this_pointer_die)
7189 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7191 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7206 die_this_pointer_is_const(Dwarf_Die* die)
7210 if (dwarf_tag(die) == DW_TAG_pointer_type)
7212 Dwarf_Die pointed_to_type_die;
7213 if (die_die_attribute(die, DW_AT_type, pointed_to_type_die))
7214 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7230 die_object_pointer_is_for_const_method(Dwarf_Die* die)
7233 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7235 Dwarf_Die this_pointer_die;
7236 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7237 if (die_this_pointer_is_const(&this_pointer_die))
7259 die_is_at_class_scope(
const reader& rdr,
7260 const Dwarf_Die* die,
7261 size_t where_offset,
7262 Dwarf_Die& class_scope_die)
7264 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7267 int tag = dwarf_tag(&class_scope_die);
7269 return (tag == DW_TAG_structure_type
7270 || tag == DW_TAG_class_type
7271 || tag == DW_TAG_union_type);
7284 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7289 int tag = dwarf_tag(die);
7291 if (tag == DW_TAG_const_type
7292 || tag == DW_TAG_volatile_type
7293 || tag == DW_TAG_restrict_type
7294 || tag == DW_TAG_pointer_type
7295 || tag == DW_TAG_reference_type
7296 || tag == DW_TAG_rvalue_reference_type)
7298 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7304 memcpy(&peeled_die, die,
sizeof(peeled_die));
7306 while (tag == DW_TAG_const_type
7307 || tag == DW_TAG_volatile_type
7308 || tag == DW_TAG_restrict_type
7309 || tag == DW_TAG_pointer_type
7310 || tag == DW_TAG_reference_type
7311 || tag == DW_TAG_rvalue_reference_type)
7313 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7315 tag = dwarf_tag(&peeled_die);
7330 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7335 memcpy(&peeled_die, die,
sizeof(peeled_die));
7337 int tag = dwarf_tag(&peeled_die);
7339 bool result =
false;
7340 while (tag == DW_TAG_const_type
7341 || tag == DW_TAG_volatile_type
7342 || tag == DW_TAG_restrict_type)
7344 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7346 tag = dwarf_tag(&peeled_die);
7362 die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
7367 int tag = dwarf_tag(die);
7369 memcpy(&peeled_die, die,
sizeof(peeled_die));
7371 if (tag == DW_TAG_typedef)
7373 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7379 while (tag == DW_TAG_typedef)
7381 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7383 tag = dwarf_tag(&peeled_die);
7399 die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
7404 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7406 if (tag == DW_TAG_pointer_type
7407 || tag == DW_TAG_reference_type
7408 || tag == DW_TAG_rvalue_reference_type
7409 || tag == DW_TAG_typedef)
7411 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7417 while (tag == DW_TAG_pointer_type
7418 || tag == DW_TAG_reference_type
7419 || tag == DW_TAG_rvalue_reference_type
7420 || tag == DW_TAG_typedef)
7422 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7424 tag = dwarf_tag(&peeled_die);
7452 die_function_type_is_method_type(
const reader& rdr,
7453 const Dwarf_Die *die,
7454 size_t where_offset,
7455 Dwarf_Die& object_pointer_die,
7456 Dwarf_Die& class_die,
7462 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7463 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7465 bool has_object_pointer =
false;
7467 if (tag == DW_TAG_subprogram)
7469 Dwarf_Die spec_or_origin_die;
7470 if (die_die_attribute(die, DW_AT_specification,
7472 || die_die_attribute(die, DW_AT_abstract_origin,
7473 spec_or_origin_die))
7475 if (die_has_object_pointer(&spec_or_origin_die,
7476 object_pointer_die))
7477 has_object_pointer =
true;
7480 if (die_is_at_class_scope(rdr, &spec_or_origin_die,
7481 where_offset, class_die))
7489 if (die_has_object_pointer(die, object_pointer_die))
7490 has_object_pointer =
true;
7493 if (die_is_at_class_scope(rdr, die, where_offset, class_die))
7502 if (die_has_object_pointer(die, object_pointer_die))
7503 has_object_pointer =
true;
7514 Dwarf_Die this_type_die;
7515 if (!die_die_attribute(&object_pointer_die, DW_AT_type, this_type_die))
7520 if (!die_peel_qual_ptr(&this_type_die, class_die))
7525 die_peel_typedef(&class_die, class_die);
7533 VIRTUALITY_NOT_VIRTUAL,
7535 VIRTUALITY_PURE_VIRTUAL
7548 die_virtuality(
const Dwarf_Die* die, virtuality& virt)
7554 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
7556 if (v == DW_VIRTUALITY_virtual)
7557 virt = VIRTUALITY_VIRTUAL;
7558 else if (v == DW_VIRTUALITY_pure_virtual)
7559 virt = VIRTUALITY_PURE_VIRTUAL;
7561 virt = VIRTUALITY_NOT_VIRTUAL;
7573 die_is_virtual(
const Dwarf_Die* die)
7576 if (!die_virtuality(die, v))
7579 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
7589 die_is_declared_inline(Dwarf_Die* die)
7591 uint64_t inline_value = 0;
7592 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
7594 return inline_value == DW_INL_declared_inlined;
7609 slowly_compare_strings(
const Dwarf_Die *l,
7613 const char *l_str = die_char_str_attribute(l, attr_name),
7614 *r_str = die_char_str_attribute(r, attr_name);
7615 if (!l_str && !r_str)
7617 return l_str && r_str && !strcmp(l_str, r_str);
7643 compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
7647 Dwarf_Attribute l_attr, r_attr;
7648 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
7649 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
7653 || l_attr.form == DW_FORM_string
7654 || l_attr.form == DW_FORM_GNU_strp_alt
7655 || form_is_DW_FORM_strx(l_attr.form)
7656 || form_is_DW_FORM_line_strp(l_attr.form));
7659 || r_attr.form == DW_FORM_string
7660 || r_attr.form == DW_FORM_GNU_strp_alt
7661 || form_is_DW_FORM_strx(r_attr.form)
7662 || form_is_DW_FORM_line_strp(r_attr.form));
7664 if ((l_attr.form == DW_FORM_strp
7665 && r_attr.form == DW_FORM_strp)
7666 || (l_attr.form == DW_FORM_GNU_strp_alt
7667 && r_attr.form == DW_FORM_GNU_strp_alt)
7668 || (form_is_DW_FORM_strx(l_attr.form)
7669 && form_is_DW_FORM_strx(r_attr.form))
7670 || (form_is_DW_FORM_line_strp(l_attr.form)
7671 && form_is_DW_FORM_line_strp(r_attr.form)))
7678 if (l_attr.valp == r_attr.valp)
7680 #if WITH_DEBUG_TYPE_CANONICALIZATION
7681 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
7692 result = slowly_compare_strings(l, r, attr_name);
7710 compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
7712 Dwarf_Die l_cu, r_cu;
7713 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
7714 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
7718 compare_dies_string_attribute_value(&l_cu, &r_cu,
7721 if (compared && result)
7723 Dwarf_Die peeled_l, peeled_r;
7724 if (die_is_pointer_reference_or_typedef_type(l)
7725 && die_is_pointer_reference_or_typedef_type(r)
7726 && die_peel_pointer_and_typedef(l, peeled_l)
7727 && die_peel_pointer_and_typedef(r, peeled_r))
7729 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
7730 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
7733 compare_dies_string_attribute_value(&l_cu, &r_cu,
7764 die_location_expr(
const Dwarf_Die* die,
7772 Dwarf_Attribute attr;
7773 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
7777 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
7812 op_pushes_constant_value(Dwarf_Op* ops,
7816 dwarf_expr_eval_context& ctxt)
7820 Dwarf_Op& op = ops[index];
7826 value = ops[index].number;
7839 value = ops[index].number;
7943 expr_result r(value);
7946 next_index = index + 1;
7976 op_pushes_non_constant_value(Dwarf_Op* ops,
7980 dwarf_expr_eval_context& ctxt)
7983 Dwarf_Op& op = ops[index];
8019 next_index = index + 1;
8054 next_index = index + 1;
8058 next_index = index + 2;
8062 next_index = index + 1;
8066 next_index = index + 1;
8069 case DW_OP_GNU_variable_value:
8070 next_index = index + 1;
8077 expr_result r(
false);
8106 op_manipulates_stack(Dwarf_Op* expr,
8110 dwarf_expr_eval_context& ctxt)
8112 Dwarf_Op& op = expr[index];
8118 v = ctxt.stack.front();
8123 v = ctxt.stack.front();
8142 ctxt.stack.erase(ctxt.stack.begin() + 1);
8149 ctxt.stack.erase(ctxt.stack.begin() + 2);
8154 case DW_OP_deref_size:
8162 case DW_OP_xderef_size:
8170 case DW_OP_push_object_address:
8175 case DW_OP_form_tls_address:
8176 case DW_OP_GNU_push_tls_address:
8179 if (op.atom == DW_OP_form_tls_address)
8184 case DW_OP_call_frame_cfa:
8196 if (op.atom == DW_OP_form_tls_address
8197 || op.atom == DW_OP_GNU_push_tls_address)
8198 ctxt.set_tls_address(
true);
8200 ctxt.set_tls_address(
false);
8202 next_index = index + 1;
8230 op_is_arith_logic(Dwarf_Op* expr,
8234 dwarf_expr_eval_context& ctxt)
8238 Dwarf_Op& op = expr[index];
8239 expr_result val1, val2;
8240 bool result =
false;
8256 ctxt.push(val1 & val2);
8263 if (!val1.is_const())
8265 ctxt.push(val2 / val1);
8273 ctxt.push(val2 - val1);
8281 ctxt.push(val2 % val1);
8289 ctxt.push(val2 * val1);
8311 ctxt.push(val1 | val2);
8319 ctxt.push(val2 + val1);
8323 case DW_OP_plus_uconst:
8335 ctxt.push(val2 << val1);
8344 ctxt.push(val2 >> val1);
8352 ctxt.push(val2 ^ val1);
8362 if (ctxt.stack.front().is_const())
8363 ctxt.accum = ctxt.stack.front();
8365 next_index = index + 1;
8393 op_is_control_flow(Dwarf_Op* expr,
8397 dwarf_expr_eval_context& ctxt)
8401 Dwarf_Op& op = expr[index];
8402 expr_result val1, val2;
8416 if (op.atom == DW_OP_eq)
8417 value = val2 == val1;
8418 else if (op.atom == DW_OP_ge)
8419 value = val2 >= val1;
8420 else if (op.atom == DW_OP_gt)
8421 value = val2 > val1;
8422 else if (op.atom == DW_OP_le)
8423 value = val2 <= val1;
8424 else if (op.atom == DW_OP_lt)
8425 value = val2 < val1;
8426 else if (op.atom == DW_OP_ne)
8427 value = val2 != val1;
8429 val1 = value ? 1 : 0;
8436 index += op.number - 1;
8441 if (val1.const_value() != 0)
8442 index += val1.const_value() - 1;
8447 case DW_OP_call_ref:
8455 if (ctxt.stack.front().is_const())
8456 ctxt.accum = ctxt.stack.front();
8458 next_index = index + 1;
8479 eval_quickly(Dwarf_Op* expr,
8483 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
8485 value = expr[0].number;
8512 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8515 bool& is_tls_address,
8516 dwarf_expr_eval_context &eval_ctxt)
8522 size_t index = 0, next_index = 0;
8525 if (op_is_arith_logic(expr, expr_len, index,
8526 next_index, eval_ctxt)
8527 || op_pushes_constant_value(expr, expr_len, index,
8528 next_index, eval_ctxt)
8529 || op_manipulates_stack(expr, expr_len, index,
8530 next_index, eval_ctxt)
8531 || op_pushes_non_constant_value(expr, expr_len, index,
8532 next_index, eval_ctxt)
8533 || op_is_control_flow(expr, expr_len, index,
8534 next_index, eval_ctxt))
8537 next_index = index + 1;
8541 }
while (index < expr_len);
8543 is_tls_address = eval_ctxt.set_tls_address();
8544 if (eval_ctxt.accum.is_const())
8546 value = eval_ctxt.accum;
8566 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8569 bool& is_tls_address)
8571 dwarf_expr_eval_context eval_ctxt;
8572 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
8573 is_tls_address, eval_ctxt);
8765 read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
8770 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
8783 uint64_t containing_anonymous_object_size = 0;
8784 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
8785 containing_anonymous_object_size));
8786 containing_anonymous_object_size *= 8;
8788 uint64_t bitfield_size = 0;
8789 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
8800 offset = containing_anonymous_object_size - off - bitfield_size;
8816 die_constant_data_member_location(
const Dwarf_Die *die,
8822 Dwarf_Attribute attr;
8823 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
8824 DW_AT_data_member_location,
8829 if (dwarf_formudata(&attr, &val) != 0)
8885 die_member_offset(
const reader& rdr,
8886 const Dwarf_Die* die,
8889 Dwarf_Op* expr = NULL;
8890 size_t expr_len = 0;
8891 uint64_t bit_offset = 0;
8895 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
8897 offset = bit_offset;
8909 if (!die_constant_data_member_location(die, offset))
8914 if (!die_location_expr(die, DW_AT_data_member_location,
8921 if (!eval_quickly(expr, expr_len, offset))
8923 bool is_tls_address =
false;
8924 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
8925 offset, is_tls_address,
8926 rdr.dwarf_expr_eval_ctxt()))
8944 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
8945 offset += bit_offset;
8962 die_location_address(Dwarf_Die* die,
8963 Dwarf_Addr& address,
8964 bool& is_tls_address)
8966 Dwarf_Op* expr = NULL;
8967 size_t expr_len = 0;
8969 is_tls_address =
false;
8974 Dwarf_Attribute attr;
8975 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
8978 if (dwarf_getlocation(&attr, &expr, &expr_len))
8985 Dwarf_Attribute result;
8986 if (!dwarf_getlocation_attr(&attr, expr, &result))
8988 return !dwarf_formaddr(&result, &address);
8991 address = expr->number;
9006 die_virtual_function_index(Dwarf_Die* die,
9012 Dwarf_Op* expr = NULL;
9013 size_t expr_len = 0;
9014 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9019 bool is_tls_addr =
false;
9020 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9038 int tag = dwarf_tag(die);
9040 if (tag == DW_TAG_class_type
9041 || tag == DW_TAG_structure_type
9042 || tag == DW_TAG_union_type
9043 || tag == DW_TAG_enumeration_type)
9044 return die_is_anonymous(die);
9066 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9069 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9071 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9073 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9075 else if (tag == DW_TAG_union_type)
9077 else if (tag == DW_TAG_enumeration_type)
9096 build_internal_anonymous_die_name(
const string &
base_name,
9097 size_t anonymous_type_index)
9100 if (anonymous_type_index && !
base_name.empty())
9102 std::ostringstream o;
9122 get_internal_anonymous_die_name(Dwarf_Die *die,
9123 size_t anonymous_type_index)
9125 string name = get_internal_anonymous_die_prefix_name(die);
9126 name = build_internal_anonymous_die_name(name, anonymous_type_index);
9148 die_qualified_type_name(
const reader& rdr,
9149 const Dwarf_Die* die,
9150 size_t where_offset)
9155 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9156 if (tag == DW_TAG_compile_unit
9157 || tag == DW_TAG_partial_unit
9158 || tag == DW_TAG_type_unit)
9161 string name = die_name(die);
9163 Dwarf_Die scope_die;
9164 if (!get_scope_die(rdr, die, where_offset, scope_die))
9167 string parent_name = die_qualified_name(rdr, &scope_die, where_offset);
9168 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9169 string separator = colon_colon ?
"::" :
".";
9175 case DW_TAG_unspecified_type:
9178 case DW_TAG_base_type:
9188 case DW_TAG_typedef:
9189 case DW_TAG_enumeration_type:
9190 case DW_TAG_structure_type:
9191 case DW_TAG_class_type:
9192 case DW_TAG_union_type:
9200 name = get_internal_anonymous_die_prefix_name(die);
9203 repr = parent_name.empty() ? name : parent_name + separator + name;
9207 case DW_TAG_const_type:
9208 case DW_TAG_volatile_type:
9209 case DW_TAG_restrict_type:
9211 Dwarf_Die underlying_type_die;
9212 bool has_underlying_type_die =
9213 die_die_attribute(die, DW_AT_type, underlying_type_die);
9215 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9218 if (tag == DW_TAG_const_type)
9220 if (has_underlying_type_die
9221 && die_is_reference_type(&underlying_type_die))
9231 else if (!has_underlying_type_die
9232 || die_is_void_type(&underlying_type_die))
9240 else if (tag == DW_TAG_volatile_type)
9242 else if (tag == DW_TAG_restrict_type)
9247 string underlying_type_repr;
9248 if (has_underlying_type_die)
9249 underlying_type_repr =
9250 die_qualified_type_name(rdr, &underlying_type_die, where_offset);
9252 underlying_type_repr =
"void";
9254 if (underlying_type_repr.empty())
9258 if (has_underlying_type_die)
9261 die_peel_qualified(&underlying_type_die, peeled);
9262 if (die_is_pointer_or_reference_type(&peeled))
9263 repr = underlying_type_repr +
" " + repr;
9265 repr +=
" " + underlying_type_repr;
9268 repr +=
" " + underlying_type_repr;
9273 case DW_TAG_pointer_type:
9274 case DW_TAG_reference_type:
9275 case DW_TAG_rvalue_reference_type:
9277 Dwarf_Die pointed_to_type_die;
9278 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9280 if (tag == DW_TAG_pointer_type)
9285 if (die_is_unspecified(&pointed_to_type_die))
9288 string pointed_type_repr =
9289 die_qualified_type_name(rdr, &pointed_to_type_die, where_offset);
9291 repr = pointed_type_repr;
9295 if (tag == DW_TAG_pointer_type)
9297 else if (tag == DW_TAG_reference_type)
9299 else if (tag == DW_TAG_rvalue_reference_type)
9306 case DW_TAG_subrange_type:
9319 build_subrange_type(
const_cast<reader&
>(rdr),
9322 repr += s->as_string();
9326 case DW_TAG_array_type:
9328 Dwarf_Die element_type_die;
9329 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9331 string element_type_name =
9332 die_qualified_type_name(rdr, &element_type_die, where_offset);
9333 if (element_type_name.empty())
9337 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9338 die, subranges, where_offset,
9341 repr = element_type_name;
9342 repr += array_type_def::subrange_type::vector_as_string(subranges);
9346 case DW_TAG_subroutine_type:
9347 case DW_TAG_subprogram:
9349 string return_type_name;
9351 vector<string> parm_names;
9352 bool is_const =
false;
9353 bool is_static =
false;
9355 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9357 return_type_name, class_name,
9358 parm_names, is_const,
9360 if (return_type_name.empty())
9361 return_type_name =
"void";
9363 repr = return_type_name;
9365 if (!class_name.empty())
9368 repr +=
" (" + class_name +
"::*)";
9373 for (vector<string>::const_iterator i = parm_names.begin();
9374 i != parm_names.end();
9377 if (i != parm_names.begin())
9386 case DW_TAG_string_type:
9387 case DW_TAG_ptr_to_member_type:
9388 case DW_TAG_set_type:
9389 case DW_TAG_file_type:
9390 case DW_TAG_packed_type:
9391 case DW_TAG_thrown_type:
9392 case DW_TAG_interface_type:
9393 case DW_TAG_shared_type:
9413 die_qualified_decl_name(
const reader& rdr,
9414 const Dwarf_Die* die,
9415 size_t where_offset)
9417 if (!die || !die_is_decl(die))
9420 string name = die_name(die);
9422 Dwarf_Die scope_die;
9423 if (!get_scope_die(rdr, die, where_offset, scope_die))
9426 string scope_name = die_qualified_name(rdr, &scope_die, where_offset);
9427 string separator =
"::";
9431 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9434 case DW_TAG_namespace:
9436 case DW_TAG_variable:
9437 repr = scope_name.empty() ? name : scope_name + separator + name;
9439 case DW_TAG_subprogram:
9440 repr = die_function_signature(rdr, die, where_offset);
9443 case DW_TAG_unspecified_parameters:
9447 case DW_TAG_formal_parameter:
9448 case DW_TAG_imported_declaration:
9449 case DW_TAG_GNU_template_template_param:
9450 case DW_TAG_GNU_template_parameter_pack:
9451 case DW_TAG_GNU_formal_parameter_pack:
9474 die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
9476 if (die_is_type(die))
9477 return die_qualified_type_name(rdr, die, where);
9478 else if (die_is_decl(die))
9479 return die_qualified_decl_name(rdr, die, where);
9501 die_qualified_type_name_empty(
const reader& rdr,
9502 const Dwarf_Die* die,
9503 size_t where,
string &qualified_name)
9508 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9511 if (tag == DW_TAG_typedef
9512 || tag == DW_TAG_pointer_type
9513 || tag == DW_TAG_reference_type
9514 || tag == DW_TAG_rvalue_reference_type
9515 || tag == DW_TAG_array_type
9516 || tag == DW_TAG_const_type
9517 || tag == DW_TAG_volatile_type
9518 || tag == DW_TAG_restrict_type)
9520 Dwarf_Die underlying_type_die;
9521 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
9524 die_qualified_type_name(rdr, &underlying_type_die, where);
9531 string name = die_qualified_type_name(rdr, die, where);
9536 qname = die_qualified_type_name(rdr, die, where);
9540 qualified_name = qname;
9580 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
9581 const Dwarf_Die* die,
9582 size_t where_offset,
9584 string &return_type_name,
9586 vector<string>& parm_names,
9591 Dwarf_Die ret_type_die;
9592 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
9593 return_type_name =
"void";
9597 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset)
9598 : rdr.get_die_qualified_type_name(&ret_type_die, where_offset);
9600 if (return_type_name.empty())
9601 return_type_name =
"void";
9603 Dwarf_Die object_pointer_die, class_die;
9605 die_function_type_is_method_type(rdr, die, where_offset,
9607 class_die, is_static);
9612 class_name = rdr.get_die_qualified_type_name(&class_die, where_offset);
9614 Dwarf_Die this_pointer_die;
9615 Dwarf_Die pointed_to_die;
9617 && die_die_attribute(&object_pointer_die, DW_AT_type,
9619 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
9620 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
9623 string fn_name = die_name(die);
9624 string non_qualified_class_name = die_name(&class_die);
9625 bool is_ctor = fn_name == non_qualified_class_name;
9626 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
9628 if (is_ctor || is_dtor)
9629 return_type_name.clear();
9632 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
9635 int child_tag = dwarf_tag(&child);
9636 if (child_tag == DW_TAG_formal_parameter)
9638 Dwarf_Die parm_type_die;
9639 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
9641 string qualified_name =
9643 ? rdr.get_die_pretty_representation(&parm_type_die, where_offset)
9644 : rdr.get_die_qualified_type_name(&parm_type_die, where_offset);
9646 if (qualified_name.empty())
9648 parm_names.push_back(qualified_name);
9650 else if (child_tag == DW_TAG_unspecified_parameters)
9653 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
9663 while (dwarf_siblingof(&child, &child) == 0);
9665 if (class_name.empty())
9667 Dwarf_Die parent_die;
9668 if (get_parent_die(rdr, die, parent_die, where_offset))
9670 if (die_is_class_type(&parent_die))
9672 rdr.get_die_qualified_type_name(&parent_die, where_offset);
9689 die_function_signature(
const reader& rdr,
9690 const Dwarf_Die *fn_die,
9691 size_t where_offset)
9695 bool has_lang =
false;
9696 if ((has_lang = rdr.get_die_language(fn_die, lang)))
9704 string fn_name = die_linkage_name(fn_die);
9705 if (fn_name.empty())
9706 fn_name = die_name(fn_die);
9716 string return_type_name;
9717 Dwarf_Die ret_type_die;
9718 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
9719 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
9722 if (return_type_name.empty())
9723 return_type_name =
"void";
9725 Dwarf_Die scope_die;
9727 if (get_scope_die(rdr, fn_die, where_offset, scope_die))
9728 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset);
9729 string fn_name = die_name(fn_die);
9730 if (!scope_name.empty())
9731 fn_name = scope_name +
"::" + fn_name;
9734 vector<string> parm_names;
9735 bool is_const =
false;
9736 bool is_static =
false;
9738 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
9740 return_type_name, class_name,
9741 parm_names, is_const, is_static);
9743 bool is_virtual = die_is_virtual(fn_die);
9745 string repr = class_name.empty() ?
"function" :
"method";
9749 if (!return_type_name.empty())
9750 repr +=
" " + return_type_name;
9752 repr +=
" " + fn_name;
9756 bool some_parm_emitted =
false;
9757 for (vector<string>::const_iterator i = parm_names.begin();
9758 i != parm_names.end();
9761 if (i != parm_names.begin())
9763 if (some_parm_emitted)
9767 if (!is_static && !class_name.empty())
9772 some_parm_emitted =
true;
9803 die_pretty_print_type(reader& rdr,
9804 const Dwarf_Die* die,
9805 size_t where_offset)
9808 || (!die_is_type(die)
9809 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
9814 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9817 case DW_TAG_string_type:
9826 repr =
"string type";
9828 case DW_TAG_unspecified_type:
9829 case DW_TAG_ptr_to_member_type:
9832 case DW_TAG_namespace:
9833 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset);
9836 case DW_TAG_base_type:
9837 repr = rdr.get_die_qualified_type_name(die, where_offset);
9840 case DW_TAG_typedef:
9842 string qualified_name;
9843 if (!die_qualified_type_name_empty(rdr, die,
9846 repr =
"typedef " + qualified_name;
9850 case DW_TAG_const_type:
9851 case DW_TAG_volatile_type:
9852 case DW_TAG_restrict_type:
9853 case DW_TAG_pointer_type:
9854 case DW_TAG_reference_type:
9855 case DW_TAG_rvalue_reference_type:
9856 repr = rdr.get_die_qualified_type_name(die, where_offset);
9859 case DW_TAG_enumeration_type:
9861 string qualified_name =
9862 rdr.get_die_qualified_type_name(die, where_offset);
9863 repr =
"enum " + qualified_name;
9867 case DW_TAG_structure_type:
9868 case DW_TAG_class_type:
9870 string qualified_name =
9871 rdr.get_die_qualified_type_name(die, where_offset);
9872 repr =
"class " + qualified_name;
9876 case DW_TAG_union_type:
9878 string qualified_name =
9879 rdr.get_die_qualified_type_name(die, where_offset);
9880 repr =
"union " + qualified_name;
9884 case DW_TAG_array_type:
9886 Dwarf_Die element_type_die;
9887 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9889 string element_type_name =
9890 rdr.get_die_qualified_type_name(&element_type_die, where_offset);
9891 if (element_type_name.empty())
9895 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
9898 repr = element_type_name;
9899 repr += array_type_def::subrange_type::vector_as_string(subranges);
9903 case DW_TAG_subrange_type:
9913 repr += die_qualified_type_name(rdr, die, where_offset);
9917 case DW_TAG_subroutine_type:
9918 case DW_TAG_subprogram:
9920 string return_type_name;
9922 vector<string> parm_names;
9923 bool is_const =
false;
9924 bool is_static =
false;
9926 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9928 return_type_name, class_name,
9929 parm_names, is_const,
9931 if (class_name.empty())
9932 repr =
"function type";
9934 repr =
"method type";
9935 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset);
9939 case DW_TAG_set_type:
9940 case DW_TAG_file_type:
9941 case DW_TAG_packed_type:
9942 case DW_TAG_thrown_type:
9943 case DW_TAG_interface_type:
9944 case DW_TAG_shared_type:
9970 die_pretty_print_decl(reader& rdr,
9971 const Dwarf_Die* die,
9972 size_t where_offset)
9974 if (!die || !die_is_decl(die))
9979 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9982 case DW_TAG_namespace:
9983 repr =
"namespace " + die_qualified_name(rdr, die, where_offset);
9987 case DW_TAG_variable:
9989 string type_repr =
"void";
9991 if (die_die_attribute(die, DW_AT_type, type_die))
9992 type_repr = die_qualified_type_name(rdr, &type_die, where_offset);
9993 repr = die_qualified_name(rdr, die, where_offset);
9995 repr = type_repr +
" " + repr;
9999 case DW_TAG_subprogram:
10000 repr = die_function_signature(rdr, die, where_offset);
10026 die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset)
10028 if (die_is_type(die))
10029 return die_pretty_print_type(rdr, die, where_offset);
10030 else if (die_is_decl(die))
10031 return die_pretty_print_decl(rdr, die, where_offset);
10054 compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
10058 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10059 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10060 if (l_tag != r_tag)
10063 bool result =
false;
10065 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
10068 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
10070 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
10077 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10087 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10104 at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
10105 const Dwarf_Die *l,
10106 const Dwarf_Die *r)
10108 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
10111 if ((die_is_declaration_only(l) && die_has_no_child(l))
10112 || (die_is_declaration_only(r) && die_has_no_child(r)))
10139 compare_as_type_dies(
const reader& rdr,
10140 const Dwarf_Die *l,
10141 const Dwarf_Die *r)
10147 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
10148 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
10149 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10150 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
10158 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10163 uint64_t l_size = 0, r_size = 0;
10164 die_size_in_bits(l, l_size);
10165 die_size_in_bits(r, r_size);
10167 return l_size == r_size;
10182 compare_as_decl_and_type_dies(
const reader &rdr,
10183 const Dwarf_Die *l,
10184 const Dwarf_Die *r)
10186 if (!compare_as_decl_dies(l, r)
10187 || !compare_as_type_dies(rdr, l, r))
10211 fn_die_equal_by_linkage_name(
const reader &rdr,
10212 const Dwarf_Die *l,
10213 const Dwarf_Die *r)
10221 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10223 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10226 string lname = die_name(l), rname = die_name(r);
10227 string llinkage_name = die_linkage_name(l),
10228 rlinkage_name = die_linkage_name(r);
10230 if (rdr.die_is_in_c_or_cplusplus(l)
10231 && rdr.die_is_in_c_or_cplusplus(r))
10233 if (!llinkage_name.empty() && !rlinkage_name.empty())
10234 return llinkage_name == rlinkage_name;
10235 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
10238 return lname == rname;
10241 return (!llinkage_name.empty()
10242 && !rlinkage_name.empty()
10243 && llinkage_name == rlinkage_name);
10275 try_canonical_die_comparison(
const reader& rdr,
10276 Dwarf_Off l_offset, Dwarf_Off r_offset,
10278 bool& l_has_canonical_die_offset,
10279 bool& r_has_canonical_die_offset,
10280 Dwarf_Off& l_canonical_die_offset,
10281 Dwarf_Off& r_canonical_die_offset,
10284 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10285 if (rdr.debug_die_canonicalization_is_on_
10286 && !rdr.use_canonical_die_comparison_)
10291 l_has_canonical_die_offset =
10292 (l_canonical_die_offset =
10293 rdr.get_canonical_die_offset(l_offset, l_die_source,
10296 r_has_canonical_die_offset =
10297 (r_canonical_die_offset =
10298 rdr.get_canonical_die_offset(r_offset, r_die_source,
10301 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
10303 result = (l_canonical_die_offset == r_canonical_die_offset);
10310 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10323 notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
10327 #define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
10328 notify_die_comparison_failed(l, r)
10330 #define NOTIFY_DIE_COMPARISON_FAILED(l, r)
10343 #define ABG_RETURN(value) \
10346 if ((value) == COMPARISON_RESULT_DIFFERENT) \
10348 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10350 return return_comparison_result(l, r, dies_being_compared, \
10351 value, aggregates_being_compared, \
10352 update_canonical_dies_on_the_fly); \
10363 #define ABG_RETURN_FALSE \
10366 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10367 return return_comparison_result(l, r, dies_being_compared, \
10368 COMPARISON_RESULT_DIFFERENT, \
10369 aggregates_being_compared, \
10370 update_canonical_dies_on_the_fly); \
10385 #define SET_RESULT_TO_FALSE(result, l , r) \
10388 result = COMPARISON_RESULT_DIFFERENT; \
10389 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10405 #define SET_RESULT_TO(result, value, l , r) \
10408 result = (value); \
10409 if (result == COMPARISON_RESULT_DIFFERENT) \
10411 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10415 #define RETURN_IF_COMPARISON_CYCLE_DETECTED \
10418 if (aggregates_being_compared.contains(dies_being_compared)) \
10420 result = COMPARISON_RESULT_CYCLE_DETECTED; \
10421 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
10422 ABG_RETURN(result); \
10437 get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
10442 bool found_member =
false;
10443 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
10446 found_member = (dwarf_siblingof(member, member) == 0))
10448 int tag = dwarf_tag(member);
10449 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
10453 return found_member;
10467 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
10472 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10474 || tag == DW_TAG_union_type
10475 || tag == DW_TAG_class_type);
10477 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die),
10483 tag = dwarf_tag(child);
10485 if (!(tag == DW_TAG_member
10486 || tag == DW_TAG_inheritance
10487 || tag == DW_TAG_subprogram))
10488 found_child = get_next_member_sibling_die(child, child);
10490 return found_child;
10513 maybe_propagate_canonical_type(
const reader& rdr,
10514 const Dwarf_Die* l,
10515 const Dwarf_Die* r)
10517 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10518 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10520 if (l_tag != r_tag)
10523 if (is_canon_type_to_be_propagated_tag(l_tag))
10524 propagate_canonical_type(rdr, l, r);
10542 propagate_canonical_type(
const reader& rdr,
10543 const Dwarf_Die* l,
10544 const Dwarf_Die* r)
10553 const die_source l_source = rdr.get_die_source(l);
10554 const die_source r_source = rdr.get_die_source(r);
10556 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
10557 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
10558 bool l_has_canonical_die_offset =
false;
10559 bool r_has_canonical_die_offset =
false;
10560 Dwarf_Off l_canonical_die_offset = 0;
10561 Dwarf_Off r_canonical_die_offset = 0;
10563 l_has_canonical_die_offset =
10564 (l_canonical_die_offset =
10565 rdr.get_canonical_die_offset(l_offset, l_source,
10568 r_has_canonical_die_offset =
10569 (r_canonical_die_offset =
10570 rdr.get_canonical_die_offset(r_offset, r_source,
10574 if (!l_has_canonical_die_offset
10577 && l_source == r_source)
10579 if (!r_has_canonical_die_offset)
10580 rdr.compute_canonical_die_offset(r, r_canonical_die_offset,
10583 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
10585 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
10586 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
10587 rdr.canonical_propagated_count_++;
10625 return_comparison_result(
const Dwarf_Die* l,
10626 const Dwarf_Die* r,
10629 offset_pairs_stack_type& comparison_stack,
10630 bool do_propagate_canonical_type =
true)
10632 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10634 if (result == COMPARISON_RESULT_EQUAL)
10639 if (do_propagate_canonical_type)
10642 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10648 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10661 else if (result == COMPARISON_RESULT_UNKNOWN)
10702 if (comparison_stack.is_redundant(cur_dies)
10703 && comparison_stack.vect_.back() == cur_dies)
10707 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10708 comparison_stack.confirm_canonical_propagated_type(cur_dies);
10710 result = COMPARISON_RESULT_EQUAL;
10712 else if (is_canon_type_to_be_propagated_tag(l_tag)
10713 && comparison_stack.vect_.back() == cur_dies)
10718 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
10719 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10723 else if (result == COMPARISON_RESULT_DIFFERENT)
10740 if (comparison_stack.is_redundant(cur_dies)
10741 && comparison_stack.vect_.back() == cur_dies)
10742 comparison_stack.cancel_canonical_propagated_type(cur_dies);
10750 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10751 result = COMPARISON_RESULT_UNKNOWN;
10752 else if (is_canon_type_to_be_propagated_tag(l_tag)
10753 && !comparison_stack.vect_.empty()
10754 && comparison_stack.vect_.back() == cur_dies)
10759 comparison_stack.erase(cur_dies);
10761 maybe_cache_type_comparison_result(comparison_stack.rdr_,
10762 l_tag, cur_dies, result);
10791 compare_dies(
const reader& rdr,
10792 const Dwarf_Die *l,
const Dwarf_Die *r,
10793 offset_pairs_stack_type& aggregates_being_compared,
10794 bool update_canonical_dies_on_the_fly)
10799 const die_source l_die_source = rdr.get_die_source(l);
10800 const die_source r_die_source = rdr.get_die_source(r);
10802 offset_type l_offset =
10805 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10808 offset_type r_offset =
10811 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
10816 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10817 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10819 if (l_tag != r_tag)
10822 if (l_offset == r_offset)
10823 return COMPARISON_RESULT_EQUAL;
10825 if (rdr.leverage_dwarf_factorization()
10826 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
10827 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
10828 if (l_offset != r_offset)
10829 return COMPARISON_RESULT_DIFFERENT;
10832 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
10833 dies_being_compared,
10837 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
10838 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
10842 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
10844 bool canonical_compare_result =
false;
10845 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
10846 l_die_source, r_die_source,
10847 l_has_canonical_die_offset,
10848 r_has_canonical_die_offset,
10849 l_canonical_die_offset,
10850 r_canonical_die_offset,
10851 canonical_compare_result))
10855 (canonical_compare_result
10856 ? COMPARISON_RESULT_EQUAL
10857 : COMPARISON_RESULT_DIFFERENT),
10867 case DW_TAG_base_type:
10868 case DW_TAG_string_type:
10869 case DW_TAG_unspecified_type:
10870 if (!compare_as_decl_and_type_dies(rdr, l, r))
10874 case DW_TAG_typedef:
10875 case DW_TAG_pointer_type:
10876 case DW_TAG_reference_type:
10877 case DW_TAG_rvalue_reference_type:
10878 case DW_TAG_const_type:
10879 case DW_TAG_volatile_type:
10880 case DW_TAG_restrict_type:
10882 if (!compare_as_type_dies(rdr, l, r))
10888 bool from_the_same_tu =
false;
10889 if (!pointer_or_qual_die_of_anonymous_class_type(l)
10890 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
10891 && from_the_same_tu)
10908 Dwarf_Die lu_type_die, ru_type_die;
10909 bool lu_is_void, ru_is_void;
10911 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
10912 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
10914 if (lu_is_void && ru_is_void)
10915 result = COMPARISON_RESULT_EQUAL;
10916 else if (lu_is_void != ru_is_void)
10919 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
10920 aggregates_being_compared,
10921 update_canonical_dies_on_the_fly);
10925 case DW_TAG_enumeration_type:
10926 if (!compare_as_decl_and_type_dies(rdr, l, r))
10931 Dwarf_Die l_enumtor, r_enumtor;
10932 bool found_l_enumtor =
true, found_r_enumtor =
true;
10934 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10935 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
10937 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
10939 found_l_enumtor && found_r_enumtor;
10940 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
10941 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
10943 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
10944 if ( l_tag != r_tag)
10950 if (l_tag != DW_TAG_enumerator)
10953 uint64_t l_val = 0, r_val = 0;
10954 die_unsigned_constant_attribute(&l_enumtor,
10957 die_unsigned_constant_attribute(&r_enumtor,
10960 if (l_val != r_val)
10966 if (found_l_enumtor != found_r_enumtor )
10971 case DW_TAG_structure_type:
10972 case DW_TAG_union_type:
10973 case DW_TAG_class_type:
10975 RETURN_IF_COMPARISON_CYCLE_DETECTED;
10977 rdr.compare_count_++;
10979 if (!compare_as_decl_and_type_dies(rdr, l, r))
10981 else if (rdr.options().assume_odr_for_cplusplus
10982 && rdr.odr_is_relevant(l)
10983 && rdr.odr_is_relevant(r)
10984 && !die_is_anonymous(l)
10985 && !die_is_anonymous(r))
10986 result = COMPARISON_RESULT_EQUAL;
10989 aggregates_being_compared.add(dies_being_compared);
10991 Dwarf_Die l_member, r_member;
10992 bool found_l_member =
true, found_r_member =
true;
10994 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10995 for (found_l_member = get_member_child_die(l, &l_member),
10996 found_r_member = get_member_child_die(r, &r_member);
10997 found_l_member && found_r_member;
10998 found_l_member = get_next_member_sibling_die(&l_member,
11000 found_r_member = get_next_member_sibling_die(&r_member,
11003 int l_tag = dwarf_tag(&l_member),
11004 r_tag = dwarf_tag(&r_member);
11006 if (l_tag != r_tag)
11013 || l_tag == DW_TAG_variable
11014 || l_tag == DW_TAG_inheritance
11015 || l_tag == DW_TAG_subprogram);
11018 compare_dies(rdr, &l_member, &r_member,
11019 aggregates_being_compared,
11020 update_canonical_dies_on_the_fly);
11022 if (local_result == COMPARISON_RESULT_UNKNOWN)
11031 result = local_result;
11033 if (local_result == COMPARISON_RESULT_DIFFERENT)
11039 if (found_l_member != found_r_member)
11048 case DW_TAG_array_type:
11050 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11052 aggregates_being_compared.add(dies_being_compared);
11054 rdr.compare_count_++;
11056 Dwarf_Die l_child, r_child;
11057 bool found_l_child, found_r_child;
11058 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11060 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11062 found_l_child && found_r_child;
11063 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
11064 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
11066 int l_child_tag = dwarf_tag(&l_child),
11067 r_child_tag = dwarf_tag(&r_child);
11068 if (l_child_tag == DW_TAG_subrange_type
11069 || r_child_tag == DW_TAG_subrange_type)
11071 result = compare_dies(rdr, &l_child, &r_child,
11072 aggregates_being_compared,
11073 update_canonical_dies_on_the_fly);
11081 if (found_l_child != found_r_child)
11084 Dwarf_Die ltype_die, rtype_die;
11085 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
11086 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
11089 result = compare_dies(rdr, <ype_die, &rtype_die,
11090 aggregates_being_compared,
11091 update_canonical_dies_on_the_fly);
11097 case DW_TAG_subrange_type:
11099 uint64_t l_lower_bound = 0, r_lower_bound = 0,
11100 l_upper_bound = 0, r_upper_bound = 0;
11101 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
11102 l_upper_bound_set =
false, r_upper_bound_set =
false;
11104 l_lower_bound_set =
11105 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
11106 r_lower_bound_set =
11107 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
11109 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
11112 uint64_t l_count = 0;
11113 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
11115 l_upper_bound = l_lower_bound + l_count;
11116 l_upper_bound_set =
true;
11122 l_upper_bound_set =
true;
11124 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
11127 uint64_t r_count = 0;
11128 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
11130 r_upper_bound = r_lower_bound + r_count;
11131 r_upper_bound_set =
true;
11137 r_upper_bound_set =
true;
11139 if ((l_lower_bound_set != r_lower_bound_set)
11140 || (l_upper_bound_set != r_upper_bound_set)
11141 || (l_lower_bound != r_lower_bound)
11142 || (l_upper_bound != r_upper_bound))
11147 case DW_TAG_subroutine_type:
11148 case DW_TAG_subprogram:
11150 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11152 aggregates_being_compared.add(dies_being_compared);
11154 rdr.compare_count_++;
11156 if (l_tag == DW_TAG_subprogram
11157 && !fn_die_equal_by_linkage_name(rdr, l, r))
11162 else if (l_tag == DW_TAG_subprogram
11163 && rdr.die_is_in_c(l) && rdr.die_is_in_c(r)
11166 result = COMPARISON_RESULT_EQUAL;
11169 else if (!rdr.die_is_in_c(l) && !rdr.die_is_in_c(r))
11175 Dwarf_Die l_return_type, r_return_type;
11176 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
11178 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
11180 if (l_return_type_is_void != r_return_type_is_void
11181 || (!l_return_type_is_void
11182 && !compare_dies(rdr,
11183 &l_return_type, &r_return_type,
11184 aggregates_being_compared,
11185 update_canonical_dies_on_the_fly)))
11189 Dwarf_Die l_child, r_child;
11190 bool found_l_child, found_r_child;
11191 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11193 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11195 found_l_child && found_r_child;
11196 found_l_child = dwarf_siblingof(&l_child,
11198 found_r_child = dwarf_siblingof(&r_child,
11201 int l_child_tag = dwarf_tag(&l_child);
11202 int r_child_tag = dwarf_tag(&r_child);
11204 COMPARISON_RESULT_EQUAL;
11205 if (l_child_tag != r_child_tag)
11206 local_result = COMPARISON_RESULT_DIFFERENT;
11207 if (l_child_tag == DW_TAG_formal_parameter)
11209 compare_dies(rdr, &l_child, &r_child,
11210 aggregates_being_compared,
11211 update_canonical_dies_on_the_fly);
11212 if (local_result == COMPARISON_RESULT_DIFFERENT)
11214 result = local_result;
11218 if (local_result == COMPARISON_RESULT_UNKNOWN)
11229 result = local_result;
11231 if (found_l_child != found_r_child)
11241 case DW_TAG_formal_parameter:
11243 Dwarf_Die l_type, r_type;
11244 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
11245 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
11246 if (l_type_is_void != r_type_is_void)
11248 else if (!l_type_is_void)
11251 compare_dies(rdr, &l_type, &r_type,
11252 aggregates_being_compared,
11253 update_canonical_dies_on_the_fly);
11259 case DW_TAG_variable:
11260 case DW_TAG_member:
11261 if (compare_as_decl_dies(l, r))
11264 if (l_tag == DW_TAG_member)
11266 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11267 die_member_offset(rdr, l, l_offset_in_bits);
11268 die_member_offset(rdr, r, r_offset_in_bits);
11269 if (l_offset_in_bits != r_offset_in_bits)
11275 Dwarf_Die l_type, r_type;
11276 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11277 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11279 compare_dies(rdr, &l_type, &r_type,
11280 aggregates_being_compared,
11281 update_canonical_dies_on_the_fly);
11289 case DW_TAG_inheritance:
11291 Dwarf_Die l_type, r_type;
11292 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11293 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11294 result = compare_dies(rdr, &l_type, &r_type,
11295 aggregates_being_compared,
11296 update_canonical_dies_on_the_fly);
11300 uint64_t l_a = 0, r_a = 0;
11301 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
11302 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
11306 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
11307 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
11311 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11312 die_member_offset(rdr, l, l_offset_in_bits);
11313 die_member_offset(rdr, r, r_offset_in_bits);
11314 if (l_offset_in_bits != r_offset_in_bits)
11319 case DW_TAG_ptr_to_member_type:
11321 bool comp_result =
false;
11322 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
11326 Dwarf_Die l_type, r_type;
11327 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11328 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11329 result = compare_dies(rdr, &l_type, &r_type,
11330 aggregates_being_compared,
11331 update_canonical_dies_on_the_fly);
11335 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
11336 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
11337 result = compare_dies(rdr, &l_type, &r_type,
11338 aggregates_being_compared,
11339 update_canonical_dies_on_the_fly);
11345 case DW_TAG_enumerator:
11346 case DW_TAG_packed_type:
11347 case DW_TAG_set_type:
11348 case DW_TAG_file_type:
11349 case DW_TAG_thrown_type:
11350 case DW_TAG_interface_type:
11351 case DW_TAG_shared_type:
11352 case DW_TAG_compile_unit:
11353 case DW_TAG_namespace:
11354 case DW_TAG_module:
11355 case DW_TAG_constant:
11356 case DW_TAG_partial_unit:
11357 case DW_TAG_imported_unit:
11358 case DW_TAG_dwarf_procedure:
11359 case DW_TAG_imported_declaration:
11360 case DW_TAG_entry_point:
11362 case DW_TAG_lexical_block:
11363 case DW_TAG_unspecified_parameters:
11364 case DW_TAG_variant:
11365 case DW_TAG_common_block:
11366 case DW_TAG_common_inclusion:
11367 case DW_TAG_inlined_subroutine:
11368 case DW_TAG_with_stmt:
11369 case DW_TAG_access_declaration:
11370 case DW_TAG_catch_block:
11371 case DW_TAG_friend:
11372 case DW_TAG_namelist:
11373 case DW_TAG_namelist_item:
11374 case DW_TAG_template_type_parameter:
11375 case DW_TAG_template_value_parameter:
11376 case DW_TAG_try_block:
11377 case DW_TAG_variant_part:
11378 case DW_TAG_imported_module:
11379 case DW_TAG_condition:
11380 case DW_TAG_type_unit:
11381 case DW_TAG_template_alias:
11382 case DW_TAG_lo_user:
11383 case DW_TAG_MIPS_loop:
11384 case DW_TAG_format_label:
11385 case DW_TAG_function_template:
11386 case DW_TAG_class_template:
11387 case DW_TAG_GNU_BINCL:
11388 case DW_TAG_GNU_EINCL:
11389 case DW_TAG_GNU_template_template_param:
11390 case DW_TAG_GNU_template_parameter_pack:
11391 case DW_TAG_GNU_formal_parameter_pack:
11392 case DW_TAG_GNU_call_site:
11393 case DW_TAG_GNU_call_site_parameter:
11394 case DW_TAG_hi_user:
11395 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11396 if (rdr.debug_die_canonicalization_is_on_)
11423 compare_dies(
const reader& rdr,
11424 const Dwarf_Die *l,
11425 const Dwarf_Die *r,
11426 bool update_canonical_dies_on_the_fly)
11428 offset_pairs_stack_type aggregates_being_compared(rdr);
11429 return compare_dies(rdr, l, r, aggregates_being_compared,
11430 update_canonical_dies_on_the_fly);
11452 compare_dies_during_canonicalization(reader& rdr,
11453 const Dwarf_Die *l,
11454 const Dwarf_Die *r,
11455 bool update_canonical_dies_on_the_fly)
11457 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11458 if (rdr.debug_die_canonicalization_is_on_)
11460 bool canonical_equality =
false, structural_equality =
false;
11461 rdr.use_canonical_die_comparison_ =
false;
11462 structural_equality = compare_dies(rdr, l, r,
11464 rdr.use_canonical_die_comparison_ =
true;
11465 canonical_equality = compare_dies(rdr, l, r,
11466 update_canonical_dies_on_the_fly);
11467 if (canonical_equality != structural_equality)
11469 std::cerr <<
"structural & canonical equality different for DIEs: "
11471 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11472 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
11475 << rdr.get_die_pretty_type_representation(l, 0)
11480 return structural_equality;
11483 return compare_dies(rdr, l, r,
11484 update_canonical_dies_on_the_fly);
11526 find_import_unit_point_between_dies(
const reader& rdr,
11527 size_t partial_unit_offset,
11528 Dwarf_Off first_die_offset,
11529 Dwarf_Off first_die_cu_offset,
11531 size_t last_die_offset,
11532 size_t& imported_point_offset)
11535 rdr.tu_die_imported_unit_points_map(source);
11537 tu_die_imported_unit_points_map_type::const_iterator iter =
11538 tu_die_imported_unit_points_map.find(first_die_cu_offset);
11540 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
11543 if (imported_unit_points.empty())
11546 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
11547 imported_unit_points_type::const_iterator e = imported_unit_points.end();
11549 find_lower_bound_in_imported_unit_points(imported_unit_points,
11553 if (last_die_offset !=
static_cast<size_t>(-1))
11554 find_lower_bound_in_imported_unit_points(imported_unit_points,
11558 if (e != imported_unit_points.end())
11560 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11561 if (i->imported_unit_die_off == partial_unit_offset)
11563 imported_point_offset = i->offset_of_import ;
11567 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11569 if (find_import_unit_point_between_dies(rdr,
11570 partial_unit_offset,
11571 i->imported_unit_child_off,
11572 i->imported_unit_cu_off,
11573 i->imported_unit_die_source,
11575 imported_point_offset))
11581 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11582 if (i->imported_unit_die_off == partial_unit_offset)
11584 imported_point_offset = i->offset_of_import ;
11588 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11590 if (find_import_unit_point_between_dies(rdr,
11591 partial_unit_offset,
11592 i->imported_unit_child_off,
11593 i->imported_unit_cu_off,
11594 i->imported_unit_die_source,
11596 imported_point_offset))
11629 find_import_unit_point_before_die(
const reader& rdr,
11630 size_t partial_unit_offset,
11631 size_t where_offset,
11632 size_t& imported_point_offset)
11634 size_t import_point_offset = 0;
11635 Dwarf_Die first_die_of_tu;
11637 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
11638 &first_die_of_tu) != 0)
11641 Dwarf_Die cu_die_memory;
11644 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
11645 &cu_die_memory, 0, 0);
11647 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
11648 dwarf_dieoffset(&first_die_of_tu),
11649 dwarf_dieoffset(cu_die),
11650 PRIMARY_DEBUG_INFO_DIE_SOURCE,
11652 import_point_offset))
11654 imported_point_offset = import_point_offset;
11658 if (import_point_offset)
11660 imported_point_offset = import_point_offset;
11688 get_parent_die(
const reader& rdr,
11689 const Dwarf_Die* die,
11690 Dwarf_Die& parent_die,
11691 size_t where_offset)
11695 const die_source source = rdr.get_die_source(die);
11698 offset_offset_map_type::const_iterator i =
11699 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
11706 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
11707 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11708 i->second, &parent_die));
11710 case ALT_DEBUG_INFO_DIE_SOURCE:
11711 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
11712 i->second, &parent_die));
11714 case TYPE_UNIT_DIE_SOURCE:
11715 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11716 i->second, &parent_die));
11718 case NO_DEBUG_INFO_DIE_SOURCE:
11719 case NUMBER_OF_DIE_SOURCES:
11723 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
11725 if (where_offset == 0)
11727 parent_die = *rdr.cur_tu_die();
11730 size_t import_point_offset = 0;
11732 find_import_unit_point_before_die(rdr,
11733 dwarf_dieoffset(&parent_die),
11735 import_point_offset);
11741 parent_die = *rdr.cur_tu_die();
11745 Dwarf_Die import_point_die;
11746 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11747 import_point_offset,
11748 &import_point_die));
11749 return get_parent_die(rdr, &import_point_die,
11750 parent_die, where_offset);
11777 get_scope_die(
const reader& rdr,
11778 const Dwarf_Die* die,
11779 size_t where_offset,
11780 Dwarf_Die& scope_die)
11784 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
11785 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
11788 Dwarf_Die logical_parent_die;
11789 if (die_die_attribute(die, DW_AT_specification,
11790 logical_parent_die,
false)
11791 || die_die_attribute(die, DW_AT_abstract_origin,
11792 logical_parent_die,
false))
11793 return get_scope_die(rdr, &logical_parent_die, where_offset, scope_die);
11795 if (!get_parent_die(rdr, die, scope_die, where_offset))
11798 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
11799 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
11800 || dwarf_tag(&scope_die) == DW_TAG_array_type)
11801 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
11828 get_scope_for_die(reader& rdr,
11830 bool called_for_public_decl,
11831 size_t where_offset)
11833 const die_source source_of_die = rdr.get_die_source(die);
11836 rdr.get_die_language(die, die_lang);
11838 || rdr.die_parent_map(source_of_die).empty())
11843 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
11844 return rdr.global_scope();
11847 Dwarf_Die cloned_die;
11848 if (die_die_attribute(die, DW_AT_specification, cloned_die,
false)
11849 || die_die_attribute(die, DW_AT_abstract_origin, cloned_die,
false))
11850 return get_scope_for_die(rdr, &cloned_die,
11851 called_for_public_decl,
11854 Dwarf_Die parent_die;
11856 if (!get_parent_die(rdr, die, parent_die, where_offset))
11857 return rdr.nil_scope();
11859 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
11860 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
11861 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11863 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
11864 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11866 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
11867 || source_of_die == TYPE_UNIT_DIE_SOURCE);
11868 return rdr.cur_transl_unit()->get_global_scope();
11877 die_tu_map_type::const_iterator i =
11878 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
11879 if (i != rdr.die_tu_map().end())
11880 return i->second->get_global_scope();
11881 return rdr.cur_transl_unit()->get_global_scope();
11886 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
11887 || dwarf_tag(&parent_die) == DW_TAG_array_type
11888 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
11900 called_for_public_decl,
11909 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
11910 return rdr.nil_scope();
11911 s = get_scope_for_die(rdr, &parent_die,
11912 called_for_public_decl,
11918 d = build_ir_node_from_die(rdr, &parent_die,
11919 called_for_public_decl,
11921 s = dynamic_pointer_cast<scope_decl>(d);
11925 return rdr.nil_scope();
11928 if (cl && cl->get_is_declaration_only())
11931 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
11948 dwarf_language_to_tu_language(
size_t l)
11953 return translation_unit::LANG_C89;
11955 return translation_unit::LANG_C;
11956 case DW_LANG_Ada83:
11957 return translation_unit::LANG_Ada83;
11958 case DW_LANG_C_plus_plus:
11959 return translation_unit::LANG_C_plus_plus;
11960 case DW_LANG_Cobol74:
11961 return translation_unit::LANG_Cobol74;
11962 case DW_LANG_Cobol85:
11963 return translation_unit::LANG_Cobol85;
11964 case DW_LANG_Fortran77:
11965 return translation_unit::LANG_Fortran77;
11966 case DW_LANG_Fortran90:
11967 return translation_unit::LANG_Fortran90;
11968 case DW_LANG_Pascal83:
11969 return translation_unit::LANG_Pascal83;
11970 case DW_LANG_Modula2:
11971 return translation_unit::LANG_Modula2;
11973 return translation_unit::LANG_Java;
11975 return translation_unit::LANG_C99;
11976 case DW_LANG_Ada95:
11977 return translation_unit::LANG_Ada95;
11978 case DW_LANG_Fortran95:
11979 return translation_unit::LANG_Fortran95;
11981 return translation_unit::LANG_PLI;
11983 return translation_unit::LANG_ObjC;
11984 case DW_LANG_ObjC_plus_plus:
11985 return translation_unit::LANG_ObjC_plus_plus;
11987 #ifdef HAVE_DW_LANG_Rust_enumerator
11989 return translation_unit::LANG_Rust;
11992 #ifdef HAVE_DW_LANG_UPC_enumerator
11994 return translation_unit::LANG_UPC;
11997 #ifdef HAVE_DW_LANG_D_enumerator
11999 return translation_unit::LANG_D;
12002 #ifdef HAVE_DW_LANG_Python_enumerator
12003 case DW_LANG_Python:
12004 return translation_unit::LANG_Python;
12007 #ifdef HAVE_DW_LANG_Go_enumerator
12009 return translation_unit::LANG_Go;
12012 #ifdef HAVE_DW_LANG_C11_enumerator
12014 return translation_unit::LANG_C11;
12017 #ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
12018 case DW_LANG_C_plus_plus_03:
12019 return translation_unit::LANG_C_plus_plus_03;
12022 #ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
12023 case DW_LANG_C_plus_plus_11:
12024 return translation_unit::LANG_C_plus_plus_11;
12027 #ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
12028 case DW_LANG_C_plus_plus_14:
12029 return translation_unit::LANG_C_plus_plus_14;
12032 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
12033 case DW_LANG_Mips_Assembler:
12034 return translation_unit::LANG_Mips_Assembler;
12038 return translation_unit::LANG_UNKNOWN;
12055 case translation_unit::LANG_UNKNOWN:
12058 case translation_unit::LANG_Cobol74:
12059 case translation_unit::LANG_Cobol85:
12062 case translation_unit::LANG_C89:
12063 case translation_unit::LANG_C99:
12064 case translation_unit::LANG_C11:
12065 case translation_unit::LANG_C:
12066 case translation_unit::LANG_C_plus_plus_03:
12067 case translation_unit::LANG_C_plus_plus_11:
12068 case translation_unit::LANG_C_plus_plus_14:
12069 case translation_unit::LANG_C_plus_plus:
12070 case translation_unit::LANG_ObjC:
12071 case translation_unit::LANG_ObjC_plus_plus:
12072 case translation_unit::LANG_Rust:
12075 case translation_unit::LANG_Fortran77:
12076 case translation_unit::LANG_Fortran90:
12077 case translation_unit::LANG_Fortran95:
12078 case translation_unit::LANG_Ada83:
12079 case translation_unit::LANG_Ada95:
12080 case translation_unit::LANG_Pascal83:
12081 case translation_unit::LANG_Modula2:
12084 case translation_unit::LANG_Java:
12087 case translation_unit::LANG_PLI:
12090 case translation_unit::LANG_UPC:
12091 case translation_unit::LANG_D:
12092 case translation_unit::LANG_Python:
12093 case translation_unit::LANG_Go:
12094 case translation_unit::LANG_Mips_Assembler:
12121 imported_unit_points_type::const_iterator& r)
12123 imported_unit_point v(val);
12124 imported_unit_points_type::const_iterator result =
12125 std::lower_bound(p.begin(), p.end(), v);
12127 bool is_ok = result != p.end();
12149 build_translation_unit_and_add_to_ir(reader& rdr,
12157 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
12161 rdr.clear_per_translation_unit_data();
12163 rdr.cur_tu_die(die);
12165 string path = die_string_attribute(die, DW_AT_name);
12166 if (path ==
"<artificial>")
12172 std::ostringstream o;
12173 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
12176 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
12186 const string& abs_path =
12187 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
12188 result = rdr.corpus()->find_translation_unit(abs_path);
12193 result.reset(
new translation_unit(rdr.env(),
12196 result->set_compilation_dir_path(compilation_dir);
12197 rdr.corpus()->add(result);
12199 die_unsigned_constant_attribute(die, DW_AT_language, l);
12200 result->set_language(dwarf_language_to_tu_language(l));
12203 rdr.cur_transl_unit(result);
12204 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
12207 if (dwarf_child(die, &child) != 0)
12210 result->set_is_constructed(
false);
12215 if (!rdr.env().analyze_exported_interfaces_only()
12216 || rdr.is_decl_die_with_exported_symbol(&child))
12217 build_ir_node_from_die(rdr, &child,
12218 die_is_public_decl(&child),
12219 dwarf_dieoffset(&child));
12220 while (dwarf_siblingof(&child, &child) == 0);
12222 if (!rdr.var_decls_to_re_add_to_tree().empty())
12223 for (list<var_decl_sptr>::const_iterator v =
12224 rdr.var_decls_to_re_add_to_tree().begin();
12225 v != rdr.var_decls_to_re_add_to_tree().end();
12232 string demangled_name =
12234 if (!demangled_name.empty())
12236 std::list<string> fqn_comps;
12238 string mem_name = fqn_comps.back();
12239 fqn_comps.pop_back();
12242 if (!fqn_comps.empty())
12270 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
12276 rdr.var_decls_to_re_add_to_tree().clear();
12278 result->set_is_constructed(
true);
12303 build_namespace_decl_and_add_to_ir(reader& rdr,
12305 size_t where_offset)
12312 unsigned tag = dwarf_tag(die);
12313 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
12320 string name, linkage_name;
12322 die_loc_and_name(rdr, die, loc, name, linkage_name);
12324 result.reset(
new namespace_decl(rdr.env(), name, loc));
12326 rdr.associate_die_to_decl(die, result, where_offset);
12329 if (dwarf_child(die, &child) != 0)
12332 rdr.scope_stack().push(result.get());
12334 build_ir_node_from_die(rdr, &child,
12340 die_is_public_decl(die) && die_is_public_decl(&child),
12342 while (dwarf_siblingof(&child, &child) == 0);
12343 rdr.scope_stack().pop();
12358 build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
12364 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
12366 uint64_t byte_size = 0, bit_size = 0;
12367 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
12368 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
12371 if (bit_size == 0 && byte_size != 0)
12373 bit_size = byte_size * 8;
12375 string type_name, linkage_name;
12377 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
12379 if (byte_size == 0)
12383 if (type_name ==
"void")
12384 result =
is_type_decl(build_ir_node_for_void_type(rdr));
12391 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12393 string normalized_type_name = type_name;
12394 integral_type int_type;
12396 normalized_type_name = int_type.
to_string();
12401 if (corpus_sptr corp = rdr.corpus())
12404 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
12405 0, loc, linkage_name));
12406 rdr.associate_die_to_type(die, result, where_offset);
12424 build_enum_underlying_type(reader& rdr,
12426 uint64_t enum_size,
12427 bool is_anonymous =
true)
12429 string underlying_type_name =
12433 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
12434 enum_size, enum_size, location()));
12435 result->set_is_anonymous(is_anonymous);
12436 result->set_is_artificial(
true);
12439 result = dynamic_pointer_cast<type_decl>(d);
12460 build_enum_type(reader& rdr,
12463 size_t where_offset,
12464 bool is_declaration_only)
12470 unsigned tag = dwarf_tag(die);
12471 if (tag != DW_TAG_enumeration_type)
12474 string name, linkage_name;
12476 die_loc_and_name(rdr, die, loc, name, linkage_name);
12478 bool is_anonymous =
false;
12482 name = get_internal_anonymous_die_prefix_name(die);
12485 is_anonymous =
true;
12487 if (
size_t s = scope->get_num_anonymous_member_enums())
12488 name = build_internal_anonymous_die_name(name, s);
12491 bool use_odr = rdr.odr_is_relevant(die);
12503 result = pre_existing_enum;
12505 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12514 if (pre_existing_enum->get_location() == loc)
12515 result = pre_existing_enum;
12520 rdr.associate_die_to_type(die, result, where_offset);
12528 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
12530 bool is_artificial = die_is_artificial(die);
12533 bool enum_underlying_type_is_anonymous=
true;
12537 if (dwarf_child(die, &child) == 0)
12541 if (dwarf_tag(&child) != DW_TAG_enumerator)
12546 die_loc_and_name(rdr, &child, l, n, m);
12548 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
12549 enms.push_back(enum_type_decl::enumerator(n, val));
12551 while (dwarf_siblingof(&child, &child) == 0);
12559 build_enum_underlying_type(rdr, name, size,
12560 enum_underlying_type_is_anonymous);
12561 t->set_is_declaration_only(is_declaration_only);
12563 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
12564 result->set_is_anonymous(is_anonymous);
12565 result->set_is_declaration_only(is_declaration_only);
12566 result->set_is_artificial(is_artificial);
12567 rdr.associate_die_to_type(die, result, where_offset);
12569 rdr.maybe_schedule_declaration_only_enum_for_resolution(result);
12588 finish_member_function_reading(Dwarf_Die* die,
12590 const class_or_union_sptr klass,
12601 bool is_ctor = (f->get_name() == klass->get_name());
12602 bool is_dtor = (!f->get_name().empty()
12603 &&
static_cast<string>(f->get_name())[0] ==
'~');
12604 bool is_virtual = die_is_virtual(die);
12605 int64_t vindex = -1;
12607 die_virtual_function_index(die, vindex);
12610 if (!c->is_struct())
12611 access = private_access;
12612 die_access_specifier(die, access);
12614 bool is_static =
false;
12622 if (!f->get_parameters().empty())
12623 first_parm = f->get_parameters()[0];
12625 bool is_artificial = first_parm && first_parm->get_is_artificial();
12626 type_base_sptr this_ptr_type, other_klass;
12629 this_ptr_type = first_parm->get_type();
12636 this_ptr_type = q->get_underlying_type();
12640 other_klass = p->get_pointed_to_type();
12645 other_klass = q->get_underlying_type();
12648 &&
get_type_name(other_klass) == klass->get_qualified_name())
12659 Dwarf_Die object_pointer_die;
12660 if (die_has_object_pointer(die, object_pointer_die))
12676 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol())
12695 Dwarf_Off die_offset = dwarf_dieoffset(die);
12697 rdr.die_function_decl_with_no_symbol_map();
12698 die_function_decl_map_type::const_iterator i =
12699 fns_with_no_symbol.find(die_offset);
12700 if (i == fns_with_no_symbol.end())
12701 fns_with_no_symbol[die_offset] = f;
12722 maybe_finish_function_decl_reading(reader& rdr,
12724 size_t where_offset,
12742 static type_base_sptr
12743 lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
12746 corpus* corp = scope->get_corpus();
12767 static type_base_sptr
12768 lookup_class_or_typedef_from_corpus(reader& rdr,
12770 bool called_for_public_decl,
12771 size_t where_offset)
12776 string class_name = die_string_attribute(die, DW_AT_name);
12777 if (class_name.empty())
12781 called_for_public_decl,
12784 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
12786 return type_base_sptr();
12797 static type_base_sptr
12798 lookup_class_typedef_or_enum_type_from_corpus(scope_decl* scope,
12799 const string& type_name)
12802 corpus* corp = scope->get_corpus();
12820 static type_base_sptr
12821 lookup_class_typedef_or_enum_type_from_corpus(Dwarf_Die* die,
12822 size_t anonymous_member_type_idx,
12828 string type_name = die_string_attribute(die, DW_AT_name);
12831 get_internal_anonymous_die_name(die, anonymous_member_type_idx);
12833 if (type_name.empty())
12836 return lookup_class_typedef_or_enum_type_from_corpus(scope, type_name);
12854 static method_decl_sptr
12855 is_function_for_die_a_member_of_class(reader& rdr,
12856 Dwarf_Die* function_die,
12857 const class_or_union_sptr& class_type)
12862 return method_decl_sptr();
12868 method_type = method->get_type();
12873 class_or_union_sptr method_class = method_type->get_class_type();
12876 string method_class_name = method_class->get_qualified_name(),
12877 class_type_name = class_type->get_qualified_name();
12879 if (method_class_name == class_type_name)
12885 return method_decl_sptr();
12907 static method_decl_sptr
12908 add_or_update_member_function(reader& rdr,
12909 Dwarf_Die* function_die,
12910 const class_or_union_sptr& class_type,
12911 bool called_from_public_decl,
12912 size_t where_offset)
12914 method_decl_sptr method =
12915 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
12918 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
12920 called_from_public_decl,
12923 return method_decl_sptr();
12925 finish_member_function_reading(function_die,
12968 add_or_update_class_type(reader& rdr,
12973 bool called_from_public_decl,
12974 size_t where_offset,
12975 bool is_declaration_only)
12981 const die_source source = rdr.get_die_source(die);
12983 unsigned tag = dwarf_tag(die);
12985 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
12989 die_class_or_union_map_type::const_iterator i =
12990 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
12991 if (i != rdr.die_wip_classes_map(source).end())
12999 string name, linkage_name;
13001 die_loc_and_name(rdr, die, loc, name, linkage_name);
13003 bool is_anonymous =
false;
13008 name = get_internal_anonymous_die_prefix_name(die);
13011 is_anonymous =
true;
13013 if (
size_t s = scope->get_num_anonymous_member_classes())
13014 name = build_internal_anonymous_die_name(name, s);
13019 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13035 && (result->get_is_declaration_only() == is_declaration_only
13036 || (!result->get_is_declaration_only()
13037 && is_declaration_only)))
13039 rdr.associate_die_to_type(die, result, where_offset);
13058 klass = pre_existing_class;
13061 die_size_in_bits(die, size);
13062 bool is_artificial = die_is_artificial(die);
13065 bool has_child = (dwarf_child(die, &child) == 0);
13067 decl_base_sptr res;
13070 res = result = klass;
13071 if (has_child && klass->get_is_declaration_only()
13072 && klass->get_definition_of_declaration())
13073 res = result =
is_class_type(klass->get_definition_of_declaration());
13075 result->set_location(loc);
13079 result.reset(
new class_decl(rdr.env(), name, size,
13081 decl_base::VISIBILITY_DEFAULT,
13084 result->set_is_declaration_only(is_declaration_only);
13087 result = dynamic_pointer_cast<class_decl>(res);
13091 if (!klass || klass->get_is_declaration_only())
13092 if (size != result->get_size_in_bits())
13093 result->set_size_in_bits(size);
13098 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
13111 result->set_is_declaration_only(is_declaration_only);
13115 if (!result->get_is_declaration_only() && has_child)
13116 if (result->get_size_in_bits() == 0 && size != 0)
13117 result->set_size_in_bits(size);
13119 result->set_is_artificial(is_artificial);
13121 rdr.associate_die_to_type(die, result, where_offset);
13123 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13130 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13132 bool is_incomplete_type =
false;
13133 if (is_declaration_only && size == 0 && has_child)
13145 is_incomplete_type =
true;
13148 dynamic_pointer_cast<scope_decl>(res);
13150 rdr.scope_stack().push(scop.get());
13152 if (has_child && !is_incomplete_type)
13154 int anonymous_member_class_index = -1;
13155 int anonymous_member_union_index = -1;
13156 int anonymous_member_enum_index = -1;
13160 tag = dwarf_tag(&child);
13163 if (tag == DW_TAG_inheritance)
13165 result->set_is_declaration_only(
false);
13167 Dwarf_Die type_die;
13168 if (!die_die_attribute(&child, DW_AT_type, type_die))
13171 type_base_sptr base_type;
13173 lookup_class_or_typedef_from_corpus(rdr, &type_die,
13174 called_from_public_decl,
13178 is_type(build_ir_node_from_die(rdr, &type_die,
13179 called_from_public_decl,
13193 die_access_specifier(&child, access);
13195 bool is_virt= die_is_virtual(&child);
13196 int64_t offset = 0;
13197 bool is_offset_present =
13198 die_member_offset(rdr, &child, offset);
13202 is_offset_present ? offset : -1,
13204 if (b->get_is_declaration_only())
13205 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
13206 if (result->find_base_class(b->get_qualified_name()))
13208 result->add_base_specifier(base);
13211 else if (tag == DW_TAG_member
13212 || tag == DW_TAG_variable)
13214 Dwarf_Die type_die;
13215 if (!die_die_attribute(&child, DW_AT_type, type_die))
13220 die_loc_and_name(rdr, &child, loc, n, m);
13225 if (n.substr(0, 5) ==
"_vptr"
13227 && !std::isalnum(n.at(5))
13237 int64_t offset_in_bits = 0;
13238 bool is_laid_out = die_member_offset(rdr, &child,
13243 bool is_static = !is_laid_out;
13245 if (is_static && variable_is_suppressed(rdr,
13250 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
13251 called_from_public_decl,
13253 type_base_sptr t =
is_type(ty);
13257 if (n.empty() && !die_is_anonymous_data_member(&child))
13263 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
13280 result->set_is_declaration_only(
false);
13286 die_access_specifier(&child, access);
13294 result->add_data_member(dm, access, is_laid_out,
13295 is_static, offset_in_bits);
13297 rdr.associate_die_to_decl(&child, dm, where_offset,
13301 else if (tag == DW_TAG_subprogram)
13304 add_or_update_member_function(rdr, &child, result,
13305 called_from_public_decl,
13308 rdr.associate_die_to_decl(&child, f, where_offset,
13312 else if (die_is_type(&child))
13318 int anonymous_member_type_index = 0;
13322 if (die_is_class_type(&child))
13323 anonymous_member_type_index =
13324 ++anonymous_member_class_index;
13325 else if (dwarf_tag(&child) == DW_TAG_union_type)
13326 anonymous_member_type_index =
13327 ++anonymous_member_union_index;
13328 else if (dwarf_tag(&child) == DW_TAG_enumeration_type)
13329 anonymous_member_type_index =
13330 ++anonymous_member_enum_index;
13335 && !lookup_class_typedef_or_enum_type_from_corpus
13336 (&child, anonymous_member_type_index, result.get()))
13337 || !result->find_member_type(die_name(&child)))
13338 build_ir_node_from_die(rdr, &child, result.get(),
13339 called_from_public_decl,
13342 }
while (dwarf_siblingof(&child, &child) == 0);
13345 rdr.scope_stack().pop();
13348 die_class_or_union_map_type::const_iterator i =
13349 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13350 if (i != rdr.die_wip_classes_map(source).end())
13355 rdr.die_wip_classes_map(source).erase(i);
13359 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13387 static union_decl_sptr
13388 add_or_update_union_type(reader& rdr,
13391 union_decl_sptr union_type,
13392 bool called_from_public_decl,
13393 size_t where_offset,
13394 bool is_declaration_only)
13396 union_decl_sptr result;
13400 unsigned tag = dwarf_tag(die);
13402 if (tag != DW_TAG_union_type)
13405 const die_source source = rdr.get_die_source(die);
13407 die_class_or_union_map_type::const_iterator i =
13408 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13409 if (i != rdr.die_wip_classes_map(source).end())
13417 string name, linkage_name;
13419 die_loc_and_name(rdr, die, loc, name, linkage_name);
13421 bool is_anonymous =
false;
13426 name = get_internal_anonymous_die_prefix_name(die);
13429 is_anonymous =
true;
13431 if (
size_t s = scope->get_num_anonymous_member_unions())
13432 name = build_internal_anonymous_die_name(name, s);
13442 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13451 rdr.associate_die_to_type(die, result, where_offset);
13463 if (union_decl_sptr pre_existing_union =
13465 union_type = pre_existing_union;
13468 die_size_in_bits(die, size);
13469 bool is_artificial = die_is_artificial(die);
13473 result = union_type;
13474 result->set_location(loc);
13478 result.reset(
new union_decl(rdr.env(), name, size, loc,
13479 decl_base::VISIBILITY_DEFAULT,
13481 if (is_declaration_only)
13482 result->set_is_declaration_only(
true);
13489 result->set_size_in_bits(size);
13490 result->set_is_declaration_only(
false);
13493 result->set_is_artificial(is_artificial);
13495 rdr.associate_die_to_type(die, result, where_offset);
13497 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13500 bool has_child = (dwarf_child(die, &child) == 0);
13504 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13507 dynamic_pointer_cast<scope_decl>(result);
13509 rdr.scope_stack().push(scop.get());
13515 tag = dwarf_tag(&child);
13517 if (tag == DW_TAG_member || tag == DW_TAG_variable)
13519 Dwarf_Die type_die;
13520 if (!die_die_attribute(&child, DW_AT_type, type_die))
13525 die_loc_and_name(rdr, &child, loc, n, m);
13534 ssize_t offset_in_bits = 0;
13535 decl_base_sptr ty =
13536 is_decl(build_ir_node_from_die(rdr, &type_die,
13537 called_from_public_decl,
13539 type_base_sptr t =
is_type(ty);
13546 result->set_is_declaration_only(
false);
13549 die_access_specifier(&child, access);
13555 if (n.empty() && result->find_data_member(dm))
13558 result->add_data_member(dm, access,
true,
13562 rdr.associate_die_to_decl(&child, dm, where_offset,
13566 else if (tag == DW_TAG_subprogram)
13569 is_decl(build_ir_node_from_die(rdr, &child,
13571 called_from_public_decl,
13579 finish_member_function_reading(&child, f, result, rdr);
13581 rdr.associate_die_to_decl(&child, f, where_offset,
13585 else if (die_is_type(&child))
13586 decl_base_sptr td =
13587 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
13588 called_from_public_decl,
13590 }
while (dwarf_siblingof(&child, &child) == 0);
13593 rdr.scope_stack().pop();
13596 die_class_or_union_map_type::const_iterator i =
13597 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13598 if (i != rdr.die_wip_classes_map(source).end())
13603 rdr.die_wip_classes_map(source).erase(i);
13627 static type_base_sptr
13628 build_qualified_type(reader& rdr,
13630 bool called_from_public_decl,
13631 size_t where_offset)
13633 type_base_sptr result;
13637 unsigned tag = dwarf_tag(die);
13639 if (tag != DW_TAG_const_type
13640 && tag != DW_TAG_volatile_type
13641 && tag != DW_TAG_restrict_type)
13644 Dwarf_Die underlying_type_die;
13645 decl_base_sptr utype_decl;
13646 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13650 utype_decl = build_ir_node_for_void_type(rdr);
13653 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
13654 called_from_public_decl,
13661 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13664 rdr.associate_die_to_type(die, result, where_offset);
13668 type_base_sptr utype =
is_type(utype_decl);
13672 if (tag == DW_TAG_const_type)
13673 qual |= qualified_type_def::CV_CONST;
13674 else if (tag == DW_TAG_volatile_type)
13675 qual |= qualified_type_def::CV_VOLATILE;
13676 else if (tag == DW_TAG_restrict_type)
13677 qual |= qualified_type_def::CV_RESTRICT;
13682 result.reset(
new qualified_type_def(utype, qual, location()));
13684 rdr.associate_die_to_type(die, result, where_offset);
13702 schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
13707 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13709 rdr.schedule_type_for_late_canonicalization(t);
13713 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13715 rdr.schedule_type_for_late_canonicalization(t);
13719 for (vector<array_type_def::subrange_sptr>::const_iterator i =
13720 type->get_subranges().begin();
13721 i != type->get_subranges().end();
13724 if (!(*i)->get_scope())
13726 rdr.schedule_type_for_late_canonicalization(*i);
13729 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
13731 rdr.schedule_type_for_late_canonicalization(type);
13750 static decl_base_sptr
13751 maybe_strip_qualification(
const qualified_type_def_sptr t,
13757 decl_base_sptr result = t;
13758 type_base_sptr u = t->get_underlying_type();
13762 if (result.get() != t.get())
13768 scope_decl * scope = 0;
13771 scope = array->get_scope();
13774 schedule_array_tree_for_late_canonicalization(array, rdr);
13776 t->set_underlying_type(array);
13777 u = t->get_underlying_type();
13785 schedule_array_tree_for_late_canonicalization(typdef, rdr);
13788 t->set_underlying_type(typdef);
13789 u = t->get_underlying_type();
13798 type_base_sptr element_type = array->get_element_type();
13803 ABG_ASSERT(!qualified->get_canonical_type());
13805 quals |= t->get_cv_quals();
13806 qualified->set_cv_quals(quals);
13812 qualified_type_def_sptr qual_type
13813 (
new qualified_type_def(element_type,
13815 t->get_location()));
13818 array->set_element_type(qual_type);
13819 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
13844 build_pointer_type_def(reader& rdr,
13846 bool called_from_public_decl,
13847 size_t where_offset)
13854 unsigned tag = dwarf_tag(die);
13855 if (tag != DW_TAG_pointer_type)
13859 Dwarf_Die underlying_type_die;
13860 bool has_underlying_type_die =
false;
13861 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13864 utype_decl = build_ir_node_for_void_type(rdr);
13866 has_underlying_type_die =
true;
13868 if (!utype_decl && has_underlying_type_die)
13869 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
13870 called_from_public_decl,
13877 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13884 type_base_sptr utype =
is_type(utype_decl);
13890 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13891 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13898 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
13900 result.reset(
new pointer_type_def(utype, size, 0, location()));
13903 rdr.associate_die_to_type(die, result, where_offset);
13925 build_reference_type(reader& rdr,
13927 bool called_from_public_decl,
13928 size_t where_offset)
13935 unsigned tag = dwarf_tag(die);
13936 if (tag != DW_TAG_reference_type
13937 && tag != DW_TAG_rvalue_reference_type)
13940 Dwarf_Die underlying_type_die;
13941 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13945 build_ir_node_from_die(rdr, &underlying_type_die,
13946 called_from_public_decl,
13953 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13960 type_base_sptr utype =
is_type(utype_decl);
13966 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13967 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13972 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
13974 bool is_lvalue = tag == DW_TAG_reference_type;
13976 result.reset(
new reference_type_def(utype, is_lvalue, size,
13979 if (corpus_sptr corp = rdr.corpus())
13982 rdr.associate_die_to_type(die, result, where_offset);
14003 build_function_type(reader& rdr,
14005 class_or_union_sptr is_method,
14006 size_t where_offset)
14013 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
14014 || dwarf_tag(die) == DW_TAG_subprogram);
14016 const die_source source = rdr.get_die_source(die);
14019 size_t off = dwarf_dieoffset(die);
14020 auto i = rdr.die_wip_function_types_map(source).find(off);
14021 if (i != rdr.die_wip_function_types_map(source).end())
14029 decl_base_sptr type_decl;
14037 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
14041 rdr.associate_die_to_type(die, result, where_offset);
14058 rdr.associate_die_to_type(die, fn_type, where_offset);
14066 bool is_const =
false;
14067 bool is_static =
false;
14068 Dwarf_Die object_pointer_die;
14069 Dwarf_Die class_type_die;
14070 bool has_this_parm_die =
14071 die_function_type_is_method_type(rdr, die, where_offset,
14072 object_pointer_die,
14075 if (has_this_parm_die)
14080 if (die_object_pointer_is_for_const_method(&object_pointer_die))
14088 class_or_union_sptr klass_type =
14093 is_method = klass_type;
14102 result.reset(is_method
14103 ?
new method_type(is_method, is_const,
14104 tu->get_address_size(),
14106 :
new function_type(rdr.env(), tu->get_address_size(),
14108 rdr.associate_die_to_type(die, result, where_offset);
14109 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
14111 type_base_sptr return_type;
14112 Dwarf_Die ret_type_die;
14113 if (die_die_attribute(die, DW_AT_type, ret_type_die))
14115 is_type(build_ir_node_from_die(rdr, &ret_type_die,
14119 return_type =
is_type(build_ir_node_for_void_type(rdr));
14120 result->set_return_type(return_type);
14125 if (dwarf_child(die, &child) == 0)
14128 int child_tag = dwarf_tag(&child);
14129 if (child_tag == DW_TAG_formal_parameter)
14132 string name, linkage_name;
14134 die_loc_and_name(rdr, &child, loc, name, linkage_name);
14139 bool is_artificial = die_is_artificial(&child);
14140 type_base_sptr parm_type;
14141 Dwarf_Die parm_type_die;
14142 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
14144 is_type(build_ir_node_from_die(rdr, &parm_type_die,
14150 (
new function_decl::parameter(parm_type, name, loc,
14153 function_parms.push_back(p);
14155 else if (child_tag == DW_TAG_unspecified_parameters)
14158 bool is_artificial = die_is_artificial(&child);
14160 type_base_sptr parm_type =
14161 is_type(build_ir_node_for_variadic_parameter_type(rdr));
14163 (
new function_decl::parameter(parm_type,
14168 function_parms.push_back(p);
14178 while (dwarf_siblingof(&child, &child) == 0);
14180 result->set_parameters(function_parms);
14182 tu->bind_function_type_life_time(result);
14184 result->set_is_artificial(
true);
14186 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
14189 die_function_type_map_type::const_iterator i =
14190 rdr.die_wip_function_types_map(source).
14191 find(dwarf_dieoffset(die));
14192 if (i != rdr.die_wip_function_types_map(source).end())
14193 rdr.die_wip_function_types_map(source).erase(i);
14196 maybe_canonicalize_type(result, rdr);
14223 build_subrange_type(reader& rdr,
14224 const Dwarf_Die* die,
14225 size_t where_offset,
14226 bool associate_type_to_die)
14233 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
14234 if (tag != DW_TAG_subrange_type)
14237 string name = die_name(die);
14240 Dwarf_Die underlying_type_die;
14241 type_base_sptr underlying_type;
14243 bool is_signed =
false;
14244 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
14246 is_type(build_ir_node_from_die(rdr,
14247 &underlying_type_die,
14251 if (underlying_type)
14254 if (die_unsigned_constant_attribute (&underlying_type_die,
14257 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
14261 array_type_def::subrange_type::bound_value lower_bound =
14262 get_default_array_lower_bound(language);
14263 array_type_def::subrange_type::bound_value upper_bound;
14264 uint64_t count = 0;
14265 bool is_infinite =
false;
14266 bool count_present =
false;
14277 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
14279 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
14280 is_signed, upper_bound);
14281 if (!found_upper_bound)
14282 found_upper_bound = subrange_die_indirect_bound_value(die,
14287 if (!found_upper_bound)
14300 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
14302 count_present =
true;
14306 int64_t u = lower_bound.get_signed_value() + count;
14307 upper_bound = u - 1;
14310 if (!count_present)
14314 is_infinite =
true;
14317 if (UINT64_MAX == upper_bound.get_unsigned_value())
14320 is_infinite =
true;
14323 (
new array_type_def::subrange_type(rdr.env(),
14328 result->is_infinite(is_infinite);
14330 if (underlying_type)
14331 result->set_underlying_type(underlying_type);
14335 || (result->get_length() ==
14336 (uint64_t) (result->get_upper_bound()
14337 - result->get_lower_bound() + 1)));
14339 if (associate_type_to_die)
14340 rdr.associate_die_to_type(die, result, where_offset);
14362 build_subranges_from_array_type_die(reader& rdr,
14363 const Dwarf_Die* die,
14365 size_t where_offset,
14366 bool associate_type_to_die)
14370 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
14374 int child_tag = dwarf_tag(&child);
14375 if (child_tag == DW_TAG_subrange_type)
14378 if (associate_type_to_die)
14384 build_ir_node_from_die(rdr, &child,
14393 s = build_subrange_type(rdr, &child,
14397 subranges.push_back(s);
14400 while (dwarf_siblingof(&child, &child) == 0);
14421 build_array_type(reader& rdr,
14423 bool called_from_public_decl,
14424 size_t where_offset)
14431 unsigned tag = dwarf_tag(die);
14432 if (tag != DW_TAG_array_type)
14435 decl_base_sptr type_decl;
14436 Dwarf_Die type_die;
14438 if (die_die_attribute(die, DW_AT_type, type_die))
14439 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
14440 called_from_public_decl,
14447 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14454 type_base_sptr type =
is_type(type_decl);
14459 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
14461 result.reset(
new array_type_def(type, subranges, location()));
14483 build_typedef_type(reader& rdr,
14485 bool called_from_public_decl,
14486 size_t where_offset)
14493 unsigned tag = dwarf_tag(die);
14494 if (tag != DW_TAG_typedef)
14497 string name, linkage_name;
14499 die_loc_and_name(rdr, die, loc, name, linkage_name);
14501 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14507 type_base_sptr utype;
14508 Dwarf_Die underlying_type_die;
14509 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14512 utype = rdr.env().get_void_type();
14516 is_type(build_ir_node_from_die(rdr,
14517 &underlying_type_die,
14518 called_from_public_decl,
14524 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
14531 decl_base_sptr decl =
is_decl(utype);
14533 decl->set_naming_typedef(result);
14537 rdr.associate_die_to_type(die, result, where_offset);
14571 build_or_get_var_decl_if_not_suppressed(reader& rdr,
14574 size_t where_offset,
14576 bool is_required_decl_spec)
14579 if (variable_is_suppressed(rdr, scope, die, is_required_decl_spec))
14584 string var_name = die_name(die);
14585 if (!var_name.empty())
14586 if ((var = class_type->find_data_member(var_name)))
14589 var = build_var_decl(rdr, die, where_offset, result);
14612 build_var_decl(reader& rdr,
14614 size_t where_offset,
14620 int tag = dwarf_tag(die);
14621 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
14623 if (!die_is_public_decl(die))
14626 type_base_sptr type;
14627 Dwarf_Die type_die;
14628 if (die_die_attribute(die, DW_AT_type, type_die))
14630 decl_base_sptr ty =
14631 is_decl(build_ir_node_from_die(rdr, &type_die,
14640 if (!type && !result)
14643 string name, linkage_name;
14645 die_loc_and_name(rdr, die, loc, name, linkage_name);
14648 result.reset(
new var_decl(name, type, loc, linkage_name));
14654 if (!linkage_name.empty())
14655 result->set_linkage_name(linkage_name);
14658 result->set_type(type);
14664 if (!result->get_symbol())
14667 Dwarf_Addr var_addr;
14669 if (rdr.get_variable_address(die, var_addr))
14672 update_main_symbol(var_addr,
14673 result->get_linkage_name().empty()
14674 ? result->get_name()
14675 : result->get_linkage_name());
14676 var_sym = rdr.variable_symbol_is_exported(var_addr);
14681 result->set_symbol(var_sym);
14684 string linkage_name = result->get_linkage_name();
14685 if (linkage_name.empty()
14686 || !var_sym->get_alias_from_name(linkage_name))
14687 result->set_linkage_name(var_sym->get_name());
14688 result->set_is_in_public_symbol_table(
true);
14714 function_is_suppressed(
const reader& rdr,
14715 const scope_decl* scope,
14716 Dwarf_Die *function_die,
14717 bool is_declaration_only)
14719 if (function_die == 0
14720 || dwarf_tag(function_die) != DW_TAG_subprogram)
14723 string fname = die_string_attribute(function_die, DW_AT_name);
14724 string flinkage_name = die_linkage_name(function_die);
14725 if (flinkage_name.empty() && rdr.die_is_in_c(function_die))
14726 flinkage_name = fname;
14736 && (!is_declaration_only || rdr.drop_undefined_syms()))
14738 Dwarf_Addr fn_addr;
14739 if (!rdr.get_function_address(function_die, fn_addr))
14743 rdr.function_symbol_is_exported(fn_addr);
14746 if (!symbol->is_suppressed())
14753 if (symbol->has_aliases())
14755 !a->is_main_symbol(); a = a->get_next_alias())
14756 if (!a->is_suppressed())
14805 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
14808 size_t where_offset,
14809 bool is_declaration_only,
14813 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
14816 string name = die_name(fn_die);
14817 string linkage_name = die_linkage_name(fn_die);
14818 bool is_dtor = !name.empty() && name[0]==
'~';
14819 bool is_virtual =
false;
14822 Dwarf_Attribute attr;
14823 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
14824 DW_AT_vtable_elem_location,
14836 if (!result && (!(is_dtor && is_virtual)))
14839 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
14840 rdr.associate_die_to_decl(fn_die, fn,
true);
14841 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
14849 string linkage_name = die_linkage_name(fn_die);
14850 fn = klass->find_member_function_sptr(linkage_name);
14857 if (!fn || !fn->get_symbol())
14864 fn = build_function_decl(rdr, fn_die, where_offset, result);
14886 variable_is_suppressed(
const reader& rdr,
14887 const scope_decl* scope,
14888 Dwarf_Die *variable_die,
14889 bool is_required_decl_spec)
14891 if (variable_die == 0
14892 || (dwarf_tag(variable_die) != DW_TAG_variable
14893 && dwarf_tag(variable_die) != DW_TAG_member))
14896 string name = die_string_attribute(variable_die, DW_AT_name);
14897 string linkage_name = die_linkage_name(variable_die);
14898 if (linkage_name.empty() && rdr.die_is_in_c(variable_die))
14899 linkage_name = name;
14909 Dwarf_Addr var_addr = 0;
14910 if (!rdr.get_variable_address(variable_die, var_addr))
14914 rdr.variable_symbol_is_exported(var_addr);
14917 if (!symbol->is_suppressed())
14924 if (symbol->has_aliases())
14926 !a->is_main_symbol(); a = a->get_next_alias())
14927 if (!a->is_suppressed())
14956 type_is_suppressed(
const reader& rdr,
14957 const scope_decl* scope,
14958 Dwarf_Die *type_die,
14959 bool &type_is_private)
14962 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
14963 && dwarf_tag(type_die) != DW_TAG_class_type
14964 && dwarf_tag(type_die) != DW_TAG_structure_type
14965 && dwarf_tag(type_die) != DW_TAG_union_type))
14968 string type_name, linkage_name;
14969 location type_location;
14970 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
14994 type_is_suppressed(
const reader& rdr,
14995 const scope_decl* scope,
14996 Dwarf_Die *type_die)
14998 bool type_is_private =
false;
14999 return type_is_suppressed(rdr, scope, type_die, type_is_private);
15023 get_opaque_version_of_type(reader &rdr,
15025 Dwarf_Die *type_die,
15026 size_t where_offset)
15033 unsigned tag = dwarf_tag(type_die);
15034 if (tag != DW_TAG_class_type
15035 && tag != DW_TAG_structure_type
15036 && tag != DW_TAG_union_type
15037 && tag != DW_TAG_enumeration_type)
15040 string type_name, linkage_name;
15041 location type_location;
15042 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15043 if (!type_location)
15053 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
15055 string_classes_or_unions_map::const_iterator i =
15056 rdr.declaration_only_classes().find(qualified_name);
15057 if (i != rdr.declaration_only_classes().end())
15058 result = i->second.back();
15069 tag == DW_TAG_structure_type,
15071 decl_base::VISIBILITY_DEFAULT));
15072 klass->set_is_declaration_only(
true);
15073 klass->set_is_artificial(die_is_artificial(type_die));
15075 rdr.associate_die_to_type(type_die, klass, where_offset);
15076 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
15081 if (tag == DW_TAG_enumeration_type)
15083 string_enums_map::const_iterator i =
15084 rdr.declaration_only_enums().find(qualified_name);
15085 if (i != rdr.declaration_only_enums().end())
15086 result = i->second.back();
15091 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
15094 build_enum_underlying_type(rdr, type_name, size,
15102 enum_type->set_is_artificial(die_is_artificial(type_die));
15104 result = enum_type;
15127 elf_symbol::FUNC_TYPE,
15128 elf_symbol::GLOBAL_BINDING,
15132 elf_symbol::DEFAULT_VISIBILITY);
15150 build_function_decl(reader& rdr,
15152 size_t where_offset,
15158 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subprogram);
15160 if (!die_is_public_decl(die))
15166 string fname, flinkage_name;
15168 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
15170 size_t is_inline = die_is_declared_inline(die);
15171 class_or_union_sptr is_method =
15184 if (!flinkage_name.empty()
15185 && result->get_linkage_name() != flinkage_name)
15186 result->set_linkage_name(flinkage_name);
15188 if (!result->get_location())
15189 result->set_location(floc);
15198 maybe_canonicalize_type(fn_type, rdr);
15200 result.reset(is_method
15201 ?
new method_decl(fname, fn_type,
15204 :
new function_decl(fname, fn_type,
15211 if (!result->get_symbol())
15214 Dwarf_Addr fn_addr;
15215 if (rdr.get_function_address(die, fn_addr))
15218 update_main_symbol(fn_addr,
15219 result->get_linkage_name().empty()
15220 ? result->get_name()
15221 : result->get_linkage_name());
15222 fn_sym = rdr.function_symbol_is_exported(fn_addr);
15225 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
15227 result->set_symbol(fn_sym);
15228 string linkage_name = result->get_linkage_name();
15229 if (linkage_name.empty())
15230 result->set_linkage_name(fn_sym->get_name());
15231 result->set_is_in_public_symbol_table(
true);
15235 rdr.associate_die_to_type(die, result->get_type(), where_offset);
15237 size_t die_offset = dwarf_dieoffset(die);
15242 && !result->get_linkage_name().empty())
15248 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
15267 maybe_canonicalize_type(
const type_base_sptr& t,
15280 ||(
is_decl(peeled_type) &&
is_decl(peeled_type)->get_is_anonymous()))
15290 rdr.schedule_type_for_late_canonicalization(t);
15292 rdr.schedule_type_for_late_canonicalization(t);
15303 maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
15306 if (
is_type(member_type_declaration)
15309 class_or_union* scope =
15315 if (!cl->is_struct())
15316 access = private_access;
15318 die_access_specifier(die, access);
15341 if (!fn || fn->get_scope())
15345 !die_is_virtual(fn_die)
15347 && !fn->get_linkage_name().empty()
15349 && !fn->get_symbol())
15394 build_ir_node_from_die(reader& rdr,
15397 bool called_from_public_decl,
15398 size_t where_offset,
15399 bool is_declaration_only,
15400 bool is_required_decl_spec)
15404 if (!die || !scope)
15407 int tag = dwarf_tag(die);
15409 if (!called_from_public_decl)
15411 if (rdr.load_all_types() && die_is_type(die))
15415 else if (tag != DW_TAG_subprogram
15416 && tag != DW_TAG_variable
15417 && tag != DW_TAG_member
15418 && tag != DW_TAG_namespace)
15422 const die_source source_of_die = rdr.get_die_source(die);
15424 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
15427 if (rdr.load_all_types())
15428 if (called_from_public_decl)
15429 if (type_base_sptr t =
is_type(result))
15430 if (corpus *abi_corpus = scope->get_corpus())
15431 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15440 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
15445 case DW_TAG_base_type:
15454 case DW_TAG_typedef:
15457 t =
is_typedef(scope->find_member_type(die_name(die)));
15460 t = build_typedef_type(rdr, die,
15461 called_from_public_decl,
15467 maybe_set_member_type_access_specifier(
is_decl(result), die);
15468 maybe_canonicalize_type(t, rdr);
15473 case DW_TAG_pointer_type:
15476 build_pointer_type_def(rdr, die,
15477 called_from_public_decl,
15484 maybe_canonicalize_type(p, rdr);
15489 case DW_TAG_reference_type:
15490 case DW_TAG_rvalue_reference_type:
15493 build_reference_type(rdr, die,
15494 called_from_public_decl,
15501 rdr.associate_die_to_type(die, r, where_offset);
15502 maybe_canonicalize_type(r, rdr);
15507 case DW_TAG_const_type:
15508 case DW_TAG_volatile_type:
15509 case DW_TAG_restrict_type:
15512 build_qualified_type(rdr, die,
15513 called_from_public_decl,
15524 type_base_sptr ty =
is_type(d);
15528 rdr.associate_die_to_type(die, ty, where_offset);
15531 maybe_canonicalize_type(
is_type(result), rdr);
15536 case DW_TAG_enumeration_type:
15538 bool type_is_private =
false;
15539 bool type_suppressed =
15540 type_is_suppressed(rdr, scope, die, type_is_private);
15541 if (type_suppressed && type_is_private)
15549 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15550 maybe_canonicalize_type(
is_type(result), rdr);
15552 else if (!type_suppressed)
15556 is_declaration_only);
15560 maybe_set_member_type_access_specifier(
is_decl(result), die);
15561 maybe_canonicalize_type(
is_type(result), rdr);
15567 case DW_TAG_class_type:
15568 case DW_TAG_structure_type:
15570 bool type_is_private =
false;
15571 bool type_suppressed=
15572 type_is_suppressed(rdr, scope, die, type_is_private);
15574 if (type_suppressed && type_is_private)
15582 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15583 maybe_canonicalize_type(
is_type(result), rdr);
15585 else if (!type_suppressed)
15587 Dwarf_Die spec_die;
15590 if (die_die_attribute(die, DW_AT_specification, spec_die))
15593 get_scope_for_die(rdr, &spec_die,
15594 called_from_public_decl,
15597 decl_base_sptr cl =
15598 is_decl(build_ir_node_from_die(rdr, &spec_die,
15600 called_from_public_decl,
15602 is_declaration_only,
15605 klass = dynamic_pointer_cast<class_decl>(cl);
15609 add_or_update_class_type(rdr, die,
15611 tag == DW_TAG_structure_type,
15613 called_from_public_decl,
15615 is_declaration_only);
15619 add_or_update_class_type(rdr, die, scope,
15620 tag == DW_TAG_structure_type,
15622 called_from_public_decl,
15624 is_declaration_only);
15628 maybe_set_member_type_access_specifier(klass, die);
15629 maybe_canonicalize_type(klass, rdr);
15634 case DW_TAG_union_type:
15635 if (!type_is_suppressed(rdr, scope, die))
15637 union_decl_sptr union_type =
15638 add_or_update_union_type(rdr, die, scope,
15640 called_from_public_decl,
15642 is_declaration_only);
15645 maybe_set_member_type_access_specifier(union_type, die);
15646 maybe_canonicalize_type(union_type, rdr);
15648 result = union_type;
15651 case DW_TAG_string_type:
15653 case DW_TAG_subroutine_type:
15661 result->set_is_artificial(
false);
15662 maybe_canonicalize_type(f, rdr);
15666 case DW_TAG_array_type:
15670 called_from_public_decl,
15676 rdr.associate_die_to_type(die, a, where_offset);
15677 maybe_canonicalize_type(a, rdr);
15681 case DW_TAG_subrange_type:
15687 build_subrange_type(rdr, die, where_offset);
15692 rdr.associate_die_to_type(die, s, where_offset);
15693 maybe_canonicalize_type(s, rdr);
15697 case DW_TAG_packed_type:
15699 case DW_TAG_set_type:
15701 case DW_TAG_file_type:
15703 case DW_TAG_ptr_to_member_type:
15705 case DW_TAG_thrown_type:
15707 case DW_TAG_interface_type:
15709 case DW_TAG_unspecified_type:
15711 case DW_TAG_shared_type:
15714 case DW_TAG_compile_unit:
15719 case DW_TAG_namespace:
15720 case DW_TAG_module:
15721 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
15724 case DW_TAG_variable:
15725 case DW_TAG_member:
15727 Dwarf_Die spec_die;
15728 bool var_is_cloned =
false;
15730 if (tag == DW_TAG_member)
15733 if (die_die_attribute(die, DW_AT_specification, spec_die,
false)
15734 || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin,
15738 get_scope_for_die(rdr, &spec_die,
15740 die_is_effectively_public_decl(rdr, die),
15745 is_decl(build_ir_node_from_die(rdr, &spec_die,
15747 called_from_public_decl,
15749 is_declaration_only,
15754 dynamic_pointer_cast<var_decl>(d);
15757 m = build_var_decl(rdr, die, where_offset, m);
15761 rdr.associate_die_to_decl(die, m, where_offset,
15767 rdr.var_decls_to_re_add_to_tree().push_back(m);
15770 rdr.maybe_add_var_to_exported_decls(m.get());
15776 build_or_get_var_decl_if_not_suppressed(rdr, scope, die,
15779 is_required_decl_spec))
15783 v = dynamic_pointer_cast<var_decl>(result);
15786 rdr.var_decls_to_re_add_to_tree().push_back(v);
15787 rdr.maybe_add_var_to_exported_decls(v.get());
15792 case DW_TAG_subprogram:
15794 Dwarf_Die spec_die;
15795 Dwarf_Die abstract_origin_die;
15796 Dwarf_Die *interface_die = 0, *origin_die = 0;
15798 if (die_is_artificial(die))
15802 bool has_spec = die_die_attribute(die, DW_AT_specification,
15804 bool has_abstract_origin =
15805 die_die_attribute(die, DW_AT_abstract_origin,
15806 abstract_origin_die,
true);
15807 if (has_spec || has_abstract_origin)
15812 : &abstract_origin_die;
15814 has_abstract_origin
15815 ? &abstract_origin_die
15818 string linkage_name = die_linkage_name(die);
15819 string spec_linkage_name = die_linkage_name(interface_die);
15821 interface_scope = get_scope_for_die(rdr, interface_die,
15822 called_from_public_decl,
15824 if (interface_scope)
15828 if (c && !linkage_name.empty())
15829 d = c->find_member_function_sptr(linkage_name);
15832 d =
is_decl(build_ir_node_from_die(rdr,
15834 interface_scope.get(),
15835 called_from_public_decl,
15837 is_declaration_only,
15841 fn = dynamic_pointer_cast<function_decl>(d);
15842 if (has_abstract_origin
15843 && (linkage_name != spec_linkage_name))
15853 rdr.scope_stack().push(scope);
15855 scope_decl* logical_scope =
15857 ? interface_scope.get()
15860 result = build_or_get_fn_decl_if_not_suppressed(rdr, logical_scope,
15862 is_declaration_only,
15869 && !is_required_decl_spec)
15881 sptr_utils::noop_deleter());
15883 finish_member_function_reading(die, fn, klass, rdr);
15888 rdr.maybe_add_fn_to_exported_decls(fn.get());
15889 rdr.associate_die_to_decl(die, fn, where_offset,
15891 maybe_canonicalize_type(fn->get_type(), rdr);
15894 rdr.scope_stack().pop();
15898 case DW_TAG_formal_parameter:
15903 case DW_TAG_constant:
15905 case DW_TAG_enumerator:
15908 case DW_TAG_partial_unit:
15909 case DW_TAG_imported_unit:
15916 case DW_TAG_dwarf_procedure:
15917 case DW_TAG_imported_declaration:
15918 case DW_TAG_entry_point:
15920 case DW_TAG_lexical_block:
15921 case DW_TAG_unspecified_parameters:
15922 case DW_TAG_variant:
15923 case DW_TAG_common_block:
15924 case DW_TAG_common_inclusion:
15925 case DW_TAG_inheritance:
15926 case DW_TAG_inlined_subroutine:
15927 case DW_TAG_with_stmt:
15928 case DW_TAG_access_declaration:
15929 case DW_TAG_catch_block:
15930 case DW_TAG_friend:
15931 case DW_TAG_namelist:
15932 case DW_TAG_namelist_item:
15933 case DW_TAG_template_type_parameter:
15934 case DW_TAG_template_value_parameter:
15935 case DW_TAG_try_block:
15936 case DW_TAG_variant_part:
15937 case DW_TAG_imported_module:
15938 case DW_TAG_condition:
15939 case DW_TAG_type_unit:
15940 case DW_TAG_template_alias:
15941 case DW_TAG_lo_user:
15942 case DW_TAG_MIPS_loop:
15943 case DW_TAG_format_label:
15944 case DW_TAG_function_template:
15945 case DW_TAG_class_template:
15946 case DW_TAG_GNU_BINCL:
15947 case DW_TAG_GNU_EINCL:
15948 case DW_TAG_GNU_template_template_param:
15949 case DW_TAG_GNU_template_parameter_pack:
15950 case DW_TAG_GNU_formal_parameter_pack:
15951 case DW_TAG_GNU_call_site:
15952 case DW_TAG_GNU_call_site_parameter:
15953 case DW_TAG_hi_user:
15958 if (result && tag != DW_TAG_subroutine_type)
15959 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
15963 if (rdr.load_all_types())
15964 if (called_from_public_decl)
15965 if (type_base_sptr t =
is_type(result))
15966 if (corpus *abi_corpus = scope->get_corpus())
15967 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15977 static decl_base_sptr
15978 build_ir_node_for_void_type(reader& rdr)
15980 const environment& env = rdr.env();
15982 type_base_sptr t = env.get_void_type();
15986 rdr.cur_transl_unit()->get_global_scope());
15988 return type_declaration;
15996 static decl_base_sptr
15997 build_ir_node_for_variadic_parameter_type(reader &rdr)
16000 const environment& env = rdr.env();
16002 type_base_sptr t = env.get_variadic_parameter_type();
16006 rdr.cur_transl_unit()->get_global_scope());
16008 return type_declaration;
16034 build_ir_node_from_die(reader& rdr,
16036 bool called_from_public_decl,
16037 size_t where_offset)
16040 return decl_base_sptr();
16045 return build_ir_node_from_die(rdr, die, scop.get(),
16046 called_from_public_decl,
16059 bool consider_as_called_from_public_decl =
16060 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
16062 consider_as_called_from_public_decl,
16064 return build_ir_node_from_die(rdr, die, scope.get(),
16065 called_from_public_decl,
16101 elf_based_reader_sptr
16103 const vector<char**>& debug_info_root_paths,
16105 bool load_all_types,
16106 bool linux_kernel_mode)
16109 reader_sptr r = reader::create(elf_path,
16110 debug_info_root_paths,
16113 linux_kernel_mode);
16114 return static_pointer_cast<elf_based_reader>(r);
16153 const std::string& elf_path,
16154 const vector<char**>&debug_info_root_path,
16155 bool read_all_types,
16156 bool linux_kernel_mode)
16158 reader& r =
dynamic_cast<reader&
>(rdr);
16159 r.initialize(elf_path, debug_info_root_path,
16160 read_all_types, linux_kernel_mode);
16197 const vector<char**>& debug_info_root_paths,
16199 bool load_all_types,
16202 elf_based_reader_sptr rdr =
16203 dwarf::reader::create(elf_path, debug_info_root_paths,
16207 return rdr->read_corpus(status);
16228 const string& elf_path,
16229 const string& symbol_name,
16231 vector<elf_symbol_sptr>& syms)
16234 if (elf_version(EV_CURRENT) == EV_NONE)
16237 int fd = open(elf_path.c_str(), O_RDONLY);
16245 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
16273 const string& path,
16274 const string& symname,
16275 vector<elf_symbol_sptr>& syms)
16277 if (elf_version(EV_CURRENT) == EV_NONE)
16280 int fd = open(path.c_str(), O_RDONLY);
16288 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
The private data and functions of the abigail::ir::corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one.
bool architecture_is_big_endian(Elf *elf_handle)
Test if the endianness of the current binary is Big Endian.
bool get_binary_load_address(Elf *elf_handle, GElf_Addr &load_address)
Get the address at which a given binary is loaded in memory.
bool get_version_for_symbol(Elf *elf_handle, size_t symbol_index, bool get_def_version, elf_symbol::version &version)
Return the version for a symbol that is at a given index in its SHT_SYMTAB section.
elf_symbol::binding stb_to_elf_symbol_binding(unsigned char stb)
Convert an elf symbol binding (given by the ELF{32,64}_ST_BIND macros) into an elf_symbol::binding va...
elf_symbol::visibility stv_to_elf_symbol_visibility(unsigned char stv)
Convert an ELF symbol visiblity given by the symbols ->st_other data member as returned by the GELF_S...
bool find_symbol_table_section_index(Elf *elf_handle, size_t &symtab_index)
Find the index (in the section headers table) of the symbol table section.
elf_symbol::type stt_to_elf_symbol_type(unsigned char stt)
Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE macros) into an elf_symbol::type value.
hash_table_kind find_hash_table_section_index(Elf *elf_handle, size_t &ht_section_index, size_t &symtab_section_index)
Get the offset offset of the hash table section.
This contains a set of ELF utilities used by the dwarf reader.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
The common interface of readers based on ELF.
status
The status of the fe_iface::read_corpus call.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
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.
The abstraction of the version of an ELF symbol.
binding
The binding of a symbol.
type
The type of a symbol.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
visibility
The visibility of the symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
The internal representation of an integral type.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
The source location of a token.
CV
Bit field values representing the cv qualifiers of the underlying type.
language
The language of the translation unit.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
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...
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...
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.
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< char ** > &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, 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...
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
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.
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...
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
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...
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...
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...
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
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...
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...
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.
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...
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...
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
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_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.
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...
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
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.
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, bool linux_kernel_mode)
Create a dwarf::reader.
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section,...
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.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
corpus_sptr read_corpus_from_elf(const std::string &elf_path, const vector< char ** > &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,...
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
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.
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.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
class_decl_sptr is_compatible_with_class_type(const type_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
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...
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
array_type_def * is_array_type(const type_or_decl_base *type)
Test if a type is an array_type_def.
reference_type_def * is_reference_type(type_or_decl_base *t)
Test whether a type is a reference_type_def.
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.
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.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void canonicalize_types(const input_iterator &begin, const input_iterator &end, deref_lambda deref)
Compute the canonical type for all the IR types of the system.
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
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.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
pointer_type_def * is_pointer_type(type_or_decl_base *t)
Test whether a type is a pointer_type_def.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one.
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.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
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...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_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.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
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.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
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.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
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.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
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.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
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_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_private, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_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...
Toplevel namespace for libabigail.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
A functor to hash instances of interned_string.