14#include "abg-internal.h"
22#include <elfutils/libdwfl.h>
33#include <unordered_map>
34#include <unordered_set>
43ABG_BEGIN_EXPORT_DECLARATIONS
51ABG_END_EXPORT_DECLARATIONS
55#define UINT64_MAX 0xffffffffffffffff
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71using std::unordered_map;
72using std::unordered_set;
79using 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,
138struct dwarf_offset_pair_hash
141 operator()(
const std::pair<Dwarf_Off, Dwarf_Off>& p)
const
145typedef 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
194struct offset_pair_hash
197 operator()(
const std::pair<offset_type, offset_type>& p)
const
202 hash_t(p.second.offset_));
211typedef unordered_set<std::pair<offset_type,
220typedef unordered_map<std::pair<offset_type, offset_type>,
226typedef unordered_map<std::pair<offset_type, offset_type>,
236build_translation_unit_and_add_to_ir(reader& rdr,
241maybe_propagate_canonical_type(
const reader& rdr,
246propagate_canonical_type(
const reader& rdr,
251maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
292struct imported_unit_point
294 Dwarf_Off offset_of_import;
298 Dwarf_Off imported_unit_die_off;
299 Dwarf_Off imported_unit_cu_off;
300 Dwarf_Off imported_unit_child_off;
303 imported_unit_point()
304 : offset_of_import(),
305 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
306 imported_unit_die_off(),
307 imported_unit_cu_off(),
308 imported_unit_child_off()
315 imported_unit_point(Dwarf_Off import_off)
316 : offset_of_import(import_off),
317 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
318 imported_unit_die_off(),
319 imported_unit_cu_off(),
320 imported_unit_child_off()
331 imported_unit_point(Dwarf_Off import_off,
332 const Dwarf_Die& imported_die,
334 : offset_of_import(import_off),
335 imported_unit_die_source(from),
336 imported_unit_die_off(dwarf_dieoffset
337 (
const_cast<Dwarf_Die*
>(&imported_die))),
338 imported_unit_cu_off(),
339 imported_unit_child_off()
341 Dwarf_Die imported_unit_child;
343 ABG_ASSERT(dwarf_child(
const_cast<Dwarf_Die*
>(&imported_die),
344 &imported_unit_child) == 0);
346 imported_unit_child_off =
347 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(&imported_unit_child));
349 Dwarf_Die cu_die_memory;
352 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&imported_unit_child),
353 &cu_die_memory, 0, 0);
354 imported_unit_cu_off = dwarf_dieoffset(cu_die);
362typedef unordered_map<Dwarf_Off, imported_unit_points_type>
374operator<(
const imported_unit_point& l,
const imported_unit_point& r)
375{
return l.offset_of_import < r.offset_of_import;}
378get_parent_die(
const reader& rdr,
379 const Dwarf_Die* die,
380 Dwarf_Die& parent_die,
381 size_t where_offset);
384get_scope_die(
const reader& rdr,
385 const Dwarf_Die* die,
387 Dwarf_Die& scope_die);
393die_is_in_c(
const Dwarf_Die *die);
396die_is_in_cplus_plus(
const Dwarf_Die *die);
399die_is_in_c_or_cplusplus(
const Dwarf_Die *die);
402die_is_anonymous(
const Dwarf_Die* die);
405die_is_anonymous_data_member(
const Dwarf_Die* die);
408die_is_type(
const Dwarf_Die* die);
411die_is_decl(
const Dwarf_Die* die);
414die_is_declaration_only(Dwarf_Die* die);
417die_is_variable_decl(
const Dwarf_Die *die);
420die_is_function_decl(
const Dwarf_Die *die);
423die_has_size_attribute(
const Dwarf_Die *die);
426die_has_no_child(
const Dwarf_Die *die);
429die_is_namespace(
const Dwarf_Die* die);
432die_is_unspecified(Dwarf_Die* die);
435die_is_void_type(Dwarf_Die* die);
438die_is_pointer_type(
const Dwarf_Die* die);
441pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
444die_is_reference_type(
const Dwarf_Die* die);
447die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
450die_is_pointer_or_reference_type(
const Dwarf_Die* die);
453die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
456die_is_class_type(
const Dwarf_Die* die);
459die_is_qualified_type(
const Dwarf_Die* die);
462die_is_function_type(
const Dwarf_Die *die);
465die_has_object_pointer(
const Dwarf_Die* die,
466 Dwarf_Die& object_pointer);
469die_has_children(
const Dwarf_Die* die);
472fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die);
475member_fn_die_has_this_pointer(
const reader& rdr,
476 const Dwarf_Die* die,
478 Dwarf_Die& class_die,
479 Dwarf_Die& object_pointer_die);
482die_this_pointer_from_object_pointer(Dwarf_Die* die,
483 Dwarf_Die& this_pointer);
486die_this_pointer_is_const(Dwarf_Die* die);
489die_object_pointer_is_for_const_method(Dwarf_Die* die);
492is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
495die_is_at_class_scope(
const reader& rdr,
496 const Dwarf_Die* die,
498 Dwarf_Die& class_scope_die);
500eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
503 bool& is_tls_address);
506dwarf_language_to_tu_language(
size_t l);
509die_unsigned_constant_attribute(
const Dwarf_Die* die,
514die_signed_constant_attribute(
const Dwarf_Die*die,
519die_constant_attribute(
const Dwarf_Die *die,
525die_member_offset(
const reader& rdr,
526 const Dwarf_Die* die,
530form_is_DW_FORM_strx(
unsigned form);
533form_is_DW_FORM_line_strp(
unsigned form);
536die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
539die_name(
const Dwarf_Die* die);
542die_name_and_linkage_name(
const Dwarf_Die* die,
544 string& linkage_name);
546die_location(
const reader& rdr,
const Dwarf_Die* die);
549die_location_address(Dwarf_Die* die,
551 bool& is_tls_address);
554die_die_attribute(
const Dwarf_Die* die,
557 bool recursively =
true);
560die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die);
563subrange_die_indirect_bound_value(
const Dwarf_Die *die,
569subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
571 Dwarf_Die& referenced_subrange);
573get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
576build_internal_anonymous_die_name(
const string &
base_name,
577 size_t anonymous_type_index);
580die_qualified_type_name(
const reader& rdr,
581 const Dwarf_Die* die,
583 unordered_set<uint64_t>& guard);
586die_qualified_decl_name(
const reader& rdr,
587 const Dwarf_Die* die,
589 unordered_set<uint64_t>& guard);
592die_qualified_name(
const reader& rdr,
593 const Dwarf_Die* die,
595 unordered_set<uint64_t>& guard);
598die_qualified_name(
const reader& rdr,
599 const Dwarf_Die* die,
603die_type_name(
const reader& rdr,
const Dwarf_Die* die,
604 bool qualified_name,
size_t where_offset,
605 unordered_set<uint64_t>& infinite_loop_guard);
608die_type_name(
const reader& rdr,
const Dwarf_Die* die,
609 bool qualified_name,
size_t where_offset);
612die_qualified_type_name_empty(
const reader& rdr,
613 const Dwarf_Die* die,
size_t where,
614 string &qualified_name,
615 unordered_set<uint64_t>& infinite_loop_guard);
618die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
619 const Dwarf_Die* die,
624 string &return_type_name,
626 vector<string>& parm_names,
629 unordered_set<uint64_t>& infinite_loop_guard);
632die_function_signature(
const reader& rdr,
633 const Dwarf_Die *die,
636 unordered_set<uint64_t>& infinite_loop_guard);
639die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
642die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
645die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die);
648die_function_type_is_method_type(
const reader& rdr,
649 const Dwarf_Die *die,
651 Dwarf_Die& object_pointer_die,
652 Dwarf_Die& class_die,
656die_enum_flat_representation(
const reader& rdr,
657 const Dwarf_Die* die,
658 const string& indent,
660 bool qualified_names,
661 size_t where_offset);
664die_class_flat_representation(
const reader& rdr,
665 const Dwarf_Die* die,
666 const string& indent,
668 bool qualified_names,
670 unordered_set<uint64_t>& infinite_loop_guard);
673die_class_or_enum_flat_representation(
const reader& rdr,
674 const Dwarf_Die* die,
675 const string& indent,
677 bool qualified_names,
679 unordered_set<uint64_t>& infinite_loop_guard);
682die_class_or_enum_flat_representation(
const reader& rdr,
683 const Dwarf_Die* die,
684 const string& indent,
686 bool qualified_names,
687 size_t where_offset);
690die_pretty_print_type(
const reader& rdr,
691 const Dwarf_Die* die,
693 unordered_set<uint64_t>& guard);
696die_pretty_print_decl(
const reader& rdr,
697 const Dwarf_Die* die,
701 unordered_set<uint64_t>& infinite_loop_guard);
704die_pretty_print(reader& rdr,
705 const Dwarf_Die* die,
707 unordered_set<uint64_t>& infinite_loop_guard);
710maybe_canonicalize_type(
const type_base_sptr& t,
719 imported_unit_points_type::const_iterator&);
722build_subrange_type(reader& rdr,
723 const Dwarf_Die* die,
725 bool associate_type_to_die =
true);
728build_subranges_from_array_type_die(
const reader& rdr,
729 const Dwarf_Die* die,
732 bool associate_type_to_die =
true);
735compare_dies(
const reader& rdr,
736 const Dwarf_Die *l,
const Dwarf_Die *r,
737 bool update_canonical_dies_on_the_fly);
740compare_dies_during_canonicalization(reader& rdr,
741 const Dwarf_Die *l,
const Dwarf_Die *r,
742 bool update_canonical_dies_on_the_fly);
745get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
748get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member);
761 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
764 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
767 lang = dwarf_language_to_tu_language(l);
779die_is_in_c(
const Dwarf_Die *die)
782 if (!get_die_language(die, l))
795die_is_in_cplus_plus(
const Dwarf_Die *die)
798 if (!get_die_language(die, l))
811die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
814 if (!get_die_language(die, l))
831compare_symbol_name(
const string& symbol_name,
840 return symbol_name == name;
869lookup_symbol_from_sysv_hash_tab(
const environment& env,
871 const string& sym_name,
873 size_t sym_tab_index,
875 vector<elf_symbol_sptr>& syms_found)
877 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
880 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
883 GElf_Shdr sheader_mem;
884 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
886 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
891 unsigned long hash = elf_hash(sym_name.c_str());
892 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
893 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
894 size_t nb_buckets = ht_data[0];
895 size_t nb_chains = ht_data[1];
903 Elf32_Word* ht_buckets = &ht_data[2];
904 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
907 size_t bucket =
hash % nb_buckets;
908 size_t symbol_index = ht_buckets[bucket];
911 const char* sym_name_str;
920 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
921 sym_name_str = elf_strptr(elf_handle,
922 sym_tab_section_header->sh_link,
925 && compare_symbol_name(sym_name_str, sym_name, demangle))
931 sym_size = symbol.st_size;
932 elf_symbol::version ver;
943 symbol.st_shndx != SHN_UNDEF,
944 symbol.st_shndx == SHN_COMMON,
945 ver, sym_visibility);
946 syms_found.push_back(symbol_found);
949 symbol_index = ht_chains[symbol_index];
950 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
961get_elf_class_size_in_bytes(Elf* elf_handle)
967 int c = hdr.e_ident[EI_CLASS];
1001bloom_word_at(Elf* elf_handle,
1002 Elf32_Word* bloom_filter,
1005 Elf64_Xword result = 0;
1009 c = h.e_ident[EI_CLASS];
1014 result = bloom_filter[index];
1018 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
1037 Elf32_Word* buckets;
1039 size_t first_sym_index;
1042 Elf32_Word* bloom_filter;
1045 Elf_Scn* sym_tab_section;
1046 GElf_Shdr sym_tab_section_header;
1076setup_gnu_ht(Elf* elf_handle,
1078 size_t sym_tab_index,
1081 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1083 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
1085 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
1086 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
1091 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
1092 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
1094 ht.nb_buckets = ht_data[0];
1095 if (ht.nb_buckets == 0)
1099 ht.first_sym_index = ht_data[1];
1102 ht.bf_nwords = ht_data[2];
1104 ht.shift = ht_data[3];
1106 ht.bloom_filter = &ht_data[4];
1111 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
1113 ht.buckets = ht.bloom_filter + ht.bf_size;
1115 ht.chain = ht.buckets + ht.nb_buckets;
1146lookup_symbol_from_gnu_hash_tab(
const environment& env,
1148 const string& sym_name,
1150 size_t sym_tab_index,
1152 vector<elf_symbol_sptr>& syms_found)
1155 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
1161 size_t h1 = elf_gnu_hash(sym_name.c_str());
1162 size_t h2 = h1 >> ht.shift;
1165 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
1166 int n = (h1 / c) % ht.bf_nwords;
1172 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1175 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1178 size_t i = ht.buckets[h1 % ht.nb_buckets];
1182 Elf32_Word stop_word, *stop_wordp;
1183 elf_symbol::version ver;
1185 const char* sym_name_str;
1194 for (i = ht.buckets[h1 % ht.nb_buckets],
1195 stop_wordp = &ht.chain[i - ht.first_sym_index];
1198 < ht.chain + (ht.sym_count - ht.first_sym_index));
1201 stop_word = *stop_wordp;
1202 if ((stop_word & ~ 1)!= (h1 & ~1))
1208 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1210 sym_name_str = elf_strptr(elf_handle,
1211 ht.sym_tab_section_header.sh_link,
1214 && compare_symbol_name(sym_name_str, sym_name, demangle))
1232 sym_type, sym_binding,
1233 symbol.st_shndx != SHN_UNDEF,
1234 symbol.st_shndx == SHN_COMMON,
1235 ver, sym_visibility);
1236 syms_found.push_back(symbol_found);
1278lookup_symbol_from_elf_hash_tab(
const environment& env,
1280 hash_table_kind ht_kind,
1282 size_t symtab_index,
1283 const string& symbol_name,
1285 vector<elf_symbol_sptr>& syms_found)
1287 if (elf_handle == 0 || symbol_name.empty())
1290 if (ht_kind == NO_HASH_TABLE_KIND)
1293 if (ht_kind == SYSV_HASH_TABLE_KIND)
1294 return lookup_symbol_from_sysv_hash_tab(env,
1295 elf_handle, symbol_name,
1300 else if (ht_kind == GNU_HASH_TABLE_KIND)
1301 return lookup_symbol_from_gnu_hash_tab(env,
1302 elf_handle, symbol_name,
1335lookup_symbol_from_symtab(
const environment& env,
1337 const string& sym_name,
1338 size_t sym_tab_index,
1340 vector<elf_symbol_sptr>& syms_found)
1345 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1348 GElf_Shdr header_mem;
1349 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1352 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1353 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1356 elf_symbol::version ver;
1359 for (
size_t i = 0; i < symcount; ++i)
1362 sym = gelf_getsym(symtab, i, &sym_mem);
1363 name_str = elf_strptr(elf_handle,
1364 sym_tab_header->sh_link,
1367 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1375 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1376 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1385 sym_binding, sym_is_defined,
1386 sym_is_common, ver, sym_visibility);
1387 syms_found.push_back(symbol_found);
1426lookup_symbol_from_elf(
const environment& env,
1428 const string& symbol_name,
1430 vector<elf_symbol_sptr>& syms_found)
1432 size_t hash_table_index = 0, symbol_table_index = 0;
1433 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1438 symbol_table_index);
1440 if (ht_kind == NO_HASH_TABLE_KIND)
1445 return lookup_symbol_from_symtab(env,
1453 return lookup_symbol_from_elf_hash_tab(env,
1477lookup_public_function_symbol_from_elf(environment& env,
1479 const string& symbol_name,
1480 vector<elf_symbol_sptr>& func_syms)
1482 vector<elf_symbol_sptr> syms_found;
1485 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1488 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1489 i != syms_found.end();
1495 if ((type == elf_symbol::FUNC_TYPE
1496 || type == elf_symbol::GNU_IFUNC_TYPE
1497 || type == elf_symbol::COMMON_TYPE)
1498 && (binding == elf_symbol::GLOBAL_BINDING
1499 || binding == elf_symbol::WEAK_BINDING))
1501 func_syms.push_back(*i);
1522 int64_t const_value_;
1530 expr_result(
bool is_const)
1531 : is_const_(is_const),
1535 explicit expr_result(int64_t v)
1561 const_value(int64_t& value)
1565 value = const_value_;
1581 return const_value_;
1584 operator int64_t()
const
1585 {
return const_value();}
1588 operator=(
const int64_t v)
1596 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1599 operator>=(
const expr_result& o)
const
1600 {
return const_value_ >= o.const_value_;}
1603 operator<=(
const expr_result& o)
const
1604 {
return const_value_ <= o.const_value_;}
1607 operator>(
const expr_result& o)
const
1608 {
return const_value_ > o.const_value_;}
1611 operator<(
const expr_result& o)
const
1612 {
return const_value_ < o.const_value_;}
1617 expr_result r(*
this);
1618 r.const_value_ += v.const_value_;
1619 r.is_const_ = r.is_const_ && v.is_const_;
1624 operator+=(int64_t v)
1631 operator-(
const expr_result& v)
const
1633 expr_result r(*
this);
1634 r.const_value_ -= v.const_value_;
1635 r.is_const_ = r.is_const_ && v.is_const_;
1640 operator%(
const expr_result& v)
const
1642 expr_result r(*
this);
1643 r.const_value_ %= v.const_value_;
1644 r.is_const_ = r.is_const_ && v.is_const();
1649 operator*(
const expr_result& v)
const
1651 expr_result r(*
this);
1652 r.const_value_ *= v.const_value_;
1653 r.is_const_ = r.is_const_ && v.is_const();
1660 expr_result r(*
this);
1661 r.const_value_ |= v.const_value_;
1662 r.is_const_ = r.is_const_ && v.is_const_;
1667 operator^(
const expr_result& v)
const
1669 expr_result r(*
this);
1670 r.const_value_ ^= v.const_value_;
1671 r.is_const_ = r.is_const_ && v.is_const_;
1676 operator>>(
const expr_result& v)
const
1678 expr_result r(*
this);
1679 r.const_value_ = r.const_value_ >> v.const_value_;
1680 r.is_const_ = r.is_const_ && v.is_const_;
1687 expr_result r(*
this);
1688 r.const_value_ = r.const_value_ << v.const_value_;
1689 r.is_const_ = r.is_const_ && v.is_const_;
1696 expr_result r(*
this);
1697 r.const_value_ = ~r.const_value_;
1704 expr_result r(*
this);
1705 r.const_value_ = -r.const_value_;
1712 expr_result r = *
this;
1713 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1720 expr_result r(*
this);
1721 r.const_value_ &= o.const_value_;
1722 r.is_const_ = r.is_const_ && o.is_const_;
1727 operator/(
const expr_result& o)
1729 expr_result r(*
this);
1730 r.is_const_ = r.is_const_ && o.is_const_;
1731 return r.const_value() / o.const_value();
1737class expr_result_stack_type
1739 vector<expr_result> elems_;
1743 expr_result_stack_type()
1744 {elems_.reserve(4);}
1747 operator[](
unsigned i)
1749 unsigned s = elems_.size();
1751 return elems_[s - 1 -i];
1755 operator[](
unsigned i)
const
1756 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1760 {
return elems_.size();}
1762 vector<expr_result>::reverse_iterator
1764 {
return elems_.rbegin();}
1766 const vector<expr_result>::reverse_iterator
1768 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1770 vector<expr_result>::reverse_iterator
1772 {
return elems_.rend();}
1774 const vector<expr_result>::reverse_iterator
1776 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1780 {
return elems_.back();}
1784 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1787 push_front(expr_result e)
1788 {elems_.push_back(e);}
1793 expr_result r = front();
1799 erase(vector<expr_result>::reverse_iterator i)
1800 {elems_.erase(--i.base());}
1808struct dwarf_expr_eval_context
1811 expr_result_stack_type stack;
1816 dwarf_expr_eval_context()
1820 stack.push_front(expr_result(
true));
1827 stack.push_front(expr_result(
true));
1828 accum = expr_result(
false);
1829 set_tls_addr =
false;
1838 set_tls_address(
bool f)
1847 set_tls_address()
const
1848 {
return set_tls_addr;}
1853 expr_result r = stack.front();
1859 push(
const expr_result& v)
1860 {stack.push_front(v);}
1869typedef shared_ptr<reader> reader_sptr;
1876class reader :
public elf_based_reader
1883 template <
typename ContainerType>
1884 class die_source_dependant_container_set
1886 ContainerType primary_debug_info_container_;
1887 ContainerType alt_debug_info_container_;
1888 ContainerType type_unit_container_;
1902 ContainerType *result = 0;
1905 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1906 result = &primary_debug_info_container_;
1908 case ALT_DEBUG_INFO_DIE_SOURCE:
1909 result = &alt_debug_info_container_;
1911 case TYPE_UNIT_DIE_SOURCE:
1912 result = &type_unit_container_;
1914 case NO_DEBUG_INFO_DIE_SOURCE:
1915 case NUMBER_OF_DIE_SOURCES:
1928 const ContainerType&
1931 return const_cast<die_source_dependant_container_set*
>(
this)->
1932 get_container(source);
1946 get_container(
const reader& rdr,
const Dwarf_Die *die)
1948 const die_source source = rdr.get_die_source(die);
1949 return get_container(source);
1962 const ContainerType&
1963 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1965 return const_cast<die_source_dependant_container_set*
>(
this)->
1966 get_container(rdr, die);
1973 primary_debug_info_container_.clear();
1974 alt_debug_info_container_.clear();
1975 type_unit_container_.clear();
1982 unsigned number_of_suppressed_functions = 0;
1983 unsigned number_of_suppressed_variables = 0;
1984 unsigned number_of_allowed_functions = 0;
1985 unsigned number_of_allowed_variables = 0;
1991 number_of_suppressed_functions = 0;
1992 number_of_suppressed_variables = 0;
1993 number_of_allowed_functions = 0;
1994 number_of_allowed_variables = 0;
1998 unsigned short dwarf_version_;
1999 Dwarf_Die* cur_tu_die_;
2000 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
2004 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
2005 decl_die_repr_die_offsets_maps_;
2009 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
2010 type_die_repr_die_offsets_maps_;
2011 mutable die_source_dependant_container_set<die_istring_map_type>
2012 die_qualified_name_maps_;
2013 mutable die_source_dependant_container_set<die_istring_map_type>
2014 die_pretty_repr_maps_;
2015 mutable die_source_dependant_container_set<die_istring_map_type>
2016 die_pretty_type_repr_maps_;
2019 mutable die_source_dependant_container_set<die_artefact_map_type>
2020 decl_die_artefact_maps_;
2023 mutable die_source_dependant_container_set<die_artefact_map_type>
2024 type_die_artefact_maps_;
2027 mutable die_source_dependant_container_set<offset_offset_map_type>
2028 canonical_type_die_offsets_;
2031 mutable die_source_dependant_container_set<offset_offset_map_type>
2032 canonical_decl_die_offsets_;
2038 mutable std::unordered_map<std::pair<offset_type,offset_type>,
2040 dwarf_offset_pair_hash> die_comparison_results_;
2050 vector<type_base_sptr> types_to_canonicalize_;
2069 list<var_decl_sptr> var_decls_to_add_;
2070#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2071 bool debug_die_canonicalization_is_on_;
2072 bool use_canonical_die_comparison_;
2074 mutable size_t compare_count_;
2075 mutable size_t canonical_propagated_count_;
2076 mutable size_t cancelled_propagation_count_;
2077 mutable optional<bool> leverage_dwarf_factorization_;
2078 mutable stats stats_;
2113 reader(
const string& elf_path,
2114 const vector<char**>& debug_info_root_paths,
2115 environment& environment,
2116 bool load_all_types,
2117 bool linux_kernel_mode)
2119 debug_info_root_paths,
2122 initialize(load_all_types, linux_kernel_mode);
2147 initialize(
bool load_all_types,
bool linux_kernel_mode)
2151 decl_die_repr_die_offsets_maps_.clear();
2152 type_die_repr_die_offsets_maps_.clear();
2153 die_qualified_name_maps_.clear();
2154 die_pretty_repr_maps_.clear();
2155 die_pretty_type_repr_maps_.clear();
2156 decl_die_artefact_maps_.clear();
2157 type_die_artefact_maps_.clear();
2158 canonical_type_die_offsets_.clear();
2159 canonical_decl_die_offsets_.clear();
2160 die_wip_classes_map_.clear();
2161 alternate_die_wip_classes_map_.clear();
2162 type_unit_die_wip_classes_map_.clear();
2163 die_wip_function_types_map_.clear();
2164 alternate_die_wip_function_types_map_.clear();
2165 type_unit_die_wip_function_types_map_.clear();
2166 die_function_with_no_symbol_map_.clear();
2167 types_to_canonicalize_.clear();
2168 decl_only_classes_map_.clear();
2169 die_tu_map_.clear();
2173 primary_die_parent_map_.clear();
2174 tu_die_imported_unit_points_map_.clear();
2175 alt_tu_die_imported_unit_points_map_.clear();
2176 type_units_tu_die_imported_unit_points_map_.clear();
2177 alternate_die_parent_map_.clear();
2178 type_section_die_parent_map_.clear();
2179 var_decls_to_add_.clear();
2180 clear_per_translation_unit_data();
2181 clear_per_corpus_data();
2182 options().load_in_linux_kernel_mode = linux_kernel_mode;
2183 options().load_all_types = load_all_types;
2184#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2185 debug_die_canonicalization_is_on_ =
2186 env().debug_die_canonicalization_is_on();
2187 use_canonical_die_comparison_ =
true;
2190 canonical_propagated_count_ = 0;
2191 cancelled_propagation_count_ = 0;
2192 load_in_linux_kernel_mode(linux_kernel_mode);
2215 const vector<char**>& debug_info_root_paths,
2216 bool load_all_types,
2217 bool linux_kernel_mode)
2220 initialize(load_all_types, linux_kernel_mode);
2240 static dwarf::reader_sptr
2241 create(
const std::string& elf_path,
2242 const vector<char**>& debug_info_root_paths,
2243 environment& environment,
2244 bool load_all_types,
2245 bool linux_kernel_mode)
2247 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2248 environment, load_all_types,
2249 linux_kernel_mode));
2266 read_corpus(status& status)
2273 if (!(status & STATUS_OK))
2277 return corpus_sptr();
2293 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2294 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2296 return corpus_sptr();
2300 corpus_sptr corp = read_debug_info_into_corpus();
2302 status |= STATUS_OK;
2315 read_debug_info_into_corpus()
2320 origin |= corpus::DWARF_ORIGIN;
2321 corpus()->set_origin(origin);
2328 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2329 && !env().user_set_analyze_exported_interfaces_only())
2336 env().analyze_exported_interfaces_only(
true);
2342 corpus()->set_symtab(symtab());
2347 || !
corpus()->get_symtab()
2348 || !
corpus()->get_symtab()->has_symbols())
2351 uint8_t address_size = 0;
2352 size_t header_size = 0;
2354#ifdef WITH_DEBUG_SELF_COMPARISON
2355 if (env().self_comparison_debug_is_on())
2359 env().set_self_comparison_debug_input(g);
2361 env().set_self_comparison_debug_input(
corpus());
2365 env().priv_->do_log(do_log());
2370 tools_utils::timer t;
2373 cerr <<
"building die -> parent maps ...";
2377 build_die_parent_maps();
2382 cerr <<
" DONE@" <<
corpus()->get_path()
2389 env().canonicalization_is_done(
false);
2392 tools_utils::timer t;
2395 cerr <<
"DWARF Reader: building the "
2396 "libabigail internal representation ...\n";
2400 Dwarf_Half dwarf_vers = 0;
2401 for (Dwarf_Off offset = 0, next_offset = 0;
2403 offset, &next_offset, &header_size,
2404 &dwarf_vers, NULL, &address_size, NULL,
2406 offset = next_offset)
2408 Dwarf_Off die_offset = offset + header_size;
2412 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2415 dwarf_version(dwarf_vers);
2422 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2428 cerr <<
"DWARF Reader: building "
2429 <<
"the libabigail internal representation "
2430 <<
"DONE for corpus " <<
corpus()->get_path()
2435 cerr <<
"DWARF Reader: Number of aggregate types compared: "
2436 << compare_count_ <<
"\n"
2437 <<
"Number of canonical types propagated: "
2438 << canonical_propagated_count_ <<
"\n"
2439 <<
"Number of cancelled propagated canonical types:"
2440 << cancelled_propagation_count_ <<
"\n"
2441 <<
"Number of suppressed functions: "
2442 << stats_.number_of_suppressed_functions <<
"\n"
2443 <<
"Number of allowed functions: "
2444 << stats_.number_of_allowed_functions <<
"\n"
2445 <<
"Total number of fns in the corpus: "
2446 <<
corpus()->get_functions().size() <<
"\n"
2447 <<
"Total number of variables in the corpus: "
2448 <<
corpus()->get_variables().size() <<
"\n";
2453 tools_utils::timer t;
2456 cerr <<
"DWARF Reader: resolving declaration only classes ...";
2459 resolve_declaration_only_classes();
2463 cerr <<
" DONE@" <<
corpus()->get_path()
2471 tools_utils::timer t;
2474 cerr <<
"resolving declaration only enums ...";
2477 resolve_declaration_only_enums();
2481 cerr <<
" DONE@" <<
corpus()->get_path()
2489 tools_utils::timer t;
2492 cerr <<
"DWARF Reader: fixing up functions with linkage name but "
2493 <<
"no advertised underlying symbols ....";
2496 fixup_functions_with_no_symbols();
2500 cerr <<
" DONE@" <<
corpus()->get_path()
2507 merge_member_functions_in_classes_of_same_names();
2521 tools_utils::timer t;
2524 cerr <<
"DWARF Reader: perform late type canonicalizing ...\n";
2528 perform_late_type_canonicalizing();
2532 cerr <<
"DWARF Reader: late type canonicalizing DONE for "
2540 env().canonicalization_is_done(
true);
2543 tools_utils::timer t;
2546 cerr <<
"DWARF Reader: sort functions and variables ...";
2549 corpus()->sort_functions();
2550 corpus()->sort_variables();
2554 cerr <<
" DONE@" <<
corpus()->get_path()
2568 clear_per_translation_unit_data()
2570 while (!scope_stack().empty())
2571 scope_stack().pop();
2572 var_decls_to_re_add_to_tree().clear();
2573 per_tu_repr_to_fn_type_maps().clear();
2579 clear_per_corpus_data()
2581 die_qualified_name_maps_.clear();
2582 die_pretty_repr_maps_.clear();
2583 die_pretty_type_repr_maps_.clear();
2584 clear_types_to_canonicalize();
2599 {
return const_cast<reader*
>(
this)->env();}
2607 drop_undefined_syms()
const
2608 {
return options().drop_undefined_syms;}
2615 drop_undefined_syms(
bool f)
2616 {
options().drop_undefined_syms = f;}
2620 dwarf_version()
const
2621 {
return dwarf_version_;}
2624 dwarf_version(
unsigned short v)
2625 {dwarf_version_ = v;}
2637 dwarf_elf_handle()
const
2648 dwarf_is_splitted()
const
2649 {
return dwarf_elf_handle() != elf_handle();}
2658 dwarf_per_die_source(
die_source source)
const
2660 const Dwarf *result = 0;
2663 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2664 case TYPE_UNIT_DIE_SOURCE:
2667 case ALT_DEBUG_INFO_DIE_SOURCE:
2670 case NO_DEBUG_INFO_DIE_SOURCE:
2671 case NUMBER_OF_DIE_SOURCES:
2686 {
return cur_tu_die_;}
2689 cur_tu_die(Dwarf_Die* cur_tu_die)
2690 {cur_tu_die_ = cur_tu_die;}
2692 dwarf_expr_eval_context&
2693 dwarf_expr_eval_ctxt()
const
2694 {
return dwarf_expr_eval_context_;}
2701 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2702 decl_die_repr_die_offsets_maps()
const
2703 {
return decl_die_repr_die_offsets_maps_;}
2710 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2711 decl_die_repr_die_offsets_maps()
2712 {
return decl_die_repr_die_offsets_maps_;}
2719 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2720 type_die_repr_die_offsets_maps()
const
2721 {
return type_die_repr_die_offsets_maps_;}
2728 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2729 type_die_repr_die_offsets_maps()
2730 {
return type_die_repr_die_offsets_maps_;}
2743 compute_canonical_die_offset(
const Dwarf_Die *die,
2744 Dwarf_Off &canonical_die_offset,
2745 bool die_as_type)
const
2749 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2750 get_container(*
this, die)
2751 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2752 get_container(*
this, die);
2754 Dwarf_Die canonical_die;
2755 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2757 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2775 compute_canonical_die(
const Dwarf_Die *die,
2777 Dwarf_Die &canonical_die,
2778 bool die_as_type)
const
2780 const die_source source = get_die_source(die);
2782 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2784 compute_canonical_die(die_offset, source,
2786 canonical_die, die_as_type);
2806 compute_canonical_die(Dwarf_Off die_offset,
2809 Dwarf_Die &canonical_die,
2810 bool die_as_type)
const
2816 ? (
const_cast<reader*
>(
this)->
2817 type_die_repr_die_offsets_maps().get_container(source))
2818 : (
const_cast<reader*
>(
this)->
2819 decl_die_repr_die_offsets_maps().get_container(source));
2822 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2831 interned_string name =
2833 ? get_die_pretty_type_representation(&die, 0)
2834 : get_die_pretty_representation(&die, 0);
2836 Dwarf_Off canonical_die_offset = 0;
2837 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2841 offsets.push_back(die_offset);
2842 map[name] = offsets;
2843 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2844 get_die_from_offset(source, die_offset, &canonical_die);
2848 Dwarf_Off cur_die_offset;
2849 Dwarf_Die potential_canonical_die;
2850 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2851 o != i->second.end();
2854 cur_die_offset = *o;
2855 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2856 if (compare_dies(*
this, &die, &potential_canonical_die,
2859 canonical_die_offset = cur_die_offset;
2860 set_canonical_die_offset(canonical_dies, die_offset,
2861 canonical_die_offset);
2862 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2867 canonical_die_offset = die_offset;
2868 i->second.push_back(die_offset);
2869 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2870 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2889 get_canonical_die(
const Dwarf_Die *die,
2890 Dwarf_Die &canonical_die,
2894 const die_source source = get_die_source(die);
2898 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2899 get_container(source)
2900 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2901 get_container(source);
2903 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2904 if (Dwarf_Off canonical_die_offset =
2905 get_canonical_die_offset(canonical_dies, die_offset))
2907 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2915 ? (
const_cast<reader*
>(
this)->
2916 type_die_repr_die_offsets_maps().get_container(*
this, die))
2917 : (
const_cast<reader*
>(
this)->
2918 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2926 interned_string name =
2928 ? get_die_pretty_type_representation(die, where)
2929 : get_die_pretty_representation(die, where);
2931 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2935 Dwarf_Off cur_die_offset;
2936 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2937 o != i->second.end();
2940 cur_die_offset = *o;
2941 get_die_from_offset(source, cur_die_offset, &canonical_die);
2943 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2944 die, &canonical_die,
2947 set_canonical_die_offset(canonical_dies,
2981 get_or_compute_canonical_die(
const Dwarf_Die* die,
2982 Dwarf_Die& canonical_die,
2984 bool die_as_type)
const
2986 const die_source source = get_die_source(die);
2990 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2991 get_container(source)
2992 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2993 get_container(source);
2995 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2997 if (Dwarf_Off canonical_die_offset =
2998 get_canonical_die_offset(canonical_dies,
2999 initial_die_offset))
3001 get_die_from_offset(source, canonical_die_offset, &canonical_die);
3005 if (!is_type_die_to_be_canonicalized(die))
3012 ? (
const_cast<reader*
>(
this)->
3013 type_die_repr_die_offsets_maps().get_container(*
this, die))
3014 : (
const_cast<reader*
>(
this)->
3015 decl_die_repr_die_offsets_maps().get_container(*
this, die));
3023 interned_string name =
3025 ? get_die_pretty_type_representation(die, where)
3026 : get_die_pretty_representation(die, where);
3028 istring_dwarf_offsets_map_type::iterator i = map.find(name);
3032 offsets.push_back(initial_die_offset);
3033 map[name] = offsets;
3034 get_die_from_offset(source, initial_die_offset, &canonical_die);
3035 set_canonical_die_offset(canonical_dies,
3037 initial_die_offset);
3044 dwarf_offsets_type::size_type n = 0, s = i->second.size();
3047 Dwarf_Off die_offset = i->second[n];
3048 get_die_from_offset(source, die_offset, &canonical_die);
3050 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
3051 die, &canonical_die,
3054 set_canonical_die_offset(canonical_dies,
3064 get_die_from_offset(source, initial_die_offset, &canonical_die);
3065 i->second.push_back(initial_die_offset);
3066 set_canonical_die_offset(canonical_dies,
3068 initial_die_offset);
3085 get_die_source(
const Dwarf_Die *die)
const
3087 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
3108 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
3112 uint8_t address_size = 0, offset_size = 0;
3113 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
3114 &cu_die, &address_size,
3118 Dwarf_Half version = 0;
3119 Dwarf_Off abbrev_offset = 0;
3120 uint64_t type_signature = 0;
3121 Dwarf_Off type_offset = 0;
3122 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
3123 &version, &abbrev_offset,
3124 &address_size, &offset_size,
3125 &type_signature, &type_offset))
3128 int tag = dwarf_tag(&cu_kind);
3130 if (tag == DW_TAG_compile_unit
3131 || tag == DW_TAG_partial_unit)
3133 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
3135 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
3137 source = ALT_DEBUG_INFO_DIE_SOURCE;
3141 else if (tag == DW_TAG_type_unit)
3142 source = TYPE_UNIT_DIE_SOURCE;
3158 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
3160 if (source == TYPE_UNIT_DIE_SOURCE)
3161 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3164 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3191 associate_die_to_decl(Dwarf_Die* die,
3192 decl_base_sptr decl,
3193 size_t where_offset,
3194 bool do_associate_by_repr =
false)
3196 const die_source source = get_die_source(die);
3199 decl_die_artefact_maps().get_container(source);
3202 if (do_associate_by_repr)
3204 Dwarf_Die equiv_die;
3205 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
3208 die_offset = dwarf_dieoffset(&equiv_die);
3211 die_offset = dwarf_dieoffset(die);
3213 m[die_offset] = decl;
3235 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3237 decl_base_sptr result =
3238 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3263 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset,
3264 unordered_set<uint64_t>& guard)
const
3268 die_qualified_name_maps_.get_container(*
this, die);
3270 size_t die_offset = dwarf_dieoffset(die);
3271 die_istring_map_type::const_iterator i = map.find(die_offset);
3275 reader& rdr = *
const_cast<reader*
>(
this);
3276 string qualified_name = die_qualified_name(rdr, die,
3279 interned_string istr = env().intern(qualified_name);
3280 map[die_offset] = istr;
3300 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3302 return const_cast<reader*
>(
this)->
3303 get_die_qualified_name(die, where_offset);
3330 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset,
3331 unordered_set<uint64_t>& guard)
const
3336 if (die == cur_tu_die())
3337 return env().intern(
"");
3340 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3343 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3344 die_istring_map_type::const_iterator i =
3345 map.find(die_offset);
3349 reader& rdr = *
const_cast<reader*
>(
this);
3350 string qualified_name;
3351 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3352 if ((tag == DW_TAG_structure_type
3353 || tag == DW_TAG_class_type
3354 || tag == DW_TAG_union_type)
3355 && die_is_anonymous(die))
3357 die_class_or_enum_flat_representation(*
this, die,
"",
3363 qualified_name = die_qualified_type_name(rdr, die,
3367 interned_string istr = env().intern(qualified_name);
3368 map[die_offset] = istr;
3398 get_die_pretty_type_representation(
const Dwarf_Die *die,
3399 size_t where_offset,
3400 unordered_set<uint64_t>& guard)
const
3404 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3407 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3408 die_istring_map_type::const_iterator i = map.find(die_offset);
3412 reader& rdr = *
const_cast<reader*
>(
this);
3413 string pretty_representation =
3414 die_pretty_print_type(rdr, die, where_offset, guard);
3415 interned_string istr = env().intern(pretty_representation);
3416 map[die_offset] = istr;
3441 get_die_pretty_type_representation(
const Dwarf_Die *die,
3442 size_t where_offset)
const
3444 unordered_set<uint64_t> guard;
3445 return get_die_pretty_type_representation(die, where_offset, guard);
3467 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset,
3468 unordered_set<uint64_t>& guard)
const
3473 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3476 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3477 die_istring_map_type::const_iterator i = map.find(die_offset);
3481 reader& rdr = *
const_cast<reader*
>(
this);
3482 string pretty_representation =
3483 die_pretty_print(rdr, die, where_offset, guard);
3484 interned_string istr = env().intern(pretty_representation);
3485 map[die_offset] = istr;
3505 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3507 unordered_set<uint64_t> guard;
3508 return get_die_pretty_representation(die, where_offset, guard);
3528 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3531 lookup_artifact_from_die(die,
true);
3533 return fn->get_type();
3557 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3559 Dwarf_Die equiv_die;
3560 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3565 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3566 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3568 size_t die_offset = dwarf_dieoffset(&equiv_die);
3569 die_artefact_map_type::const_iterator i = m.find(die_offset);
3596 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3598 bool die_as_type =
false)
const
3602 ? type_die_artefact_maps().get_container(source)
3603 : decl_die_artefact_maps().get_container(source);
3605 die_artefact_map_type::const_iterator i = m.find(die_offset);
3648 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3663 if (!get_die_language(die, lang))
3674 die_source_dependant_container_set<die_artefact_map_type>&
3675 decl_die_artefact_maps()
3676 {
return decl_die_artefact_maps_;}
3683 const die_source_dependant_container_set<die_artefact_map_type>&
3684 decl_die_artefact_maps()
const
3685 {
return decl_die_artefact_maps_;}
3692 die_source_dependant_container_set<die_artefact_map_type>&
3693 type_die_artefact_maps()
3694 {
return type_die_artefact_maps_;}
3701 const die_source_dependant_container_set<die_artefact_map_type>&
3702 type_die_artefact_maps()
const
3703 {
return type_die_artefact_maps_;}
3711 per_tu_repr_to_fn_type_maps()
3712 {
return per_tu_repr_to_fn_type_maps_;}
3720 per_tu_repr_to_fn_type_maps()
const
3721 {
return per_tu_repr_to_fn_type_maps_;}
3731 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3734 if (!die_is_function_type(die))
3737 interned_string repr =
3738 get_die_pretty_type_representation(die, 0);
3741 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3752 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3754 if (!die_is_function_type(die))
3757 interned_string repr = die_name(die).empty() ?
3758 get_die_pretty_type_representation(die, 0)
3759 : get_die_pretty_representation(die, 0);
3762 istring_fn_type_map_type::const_iterator i =
3763 per_tu_repr_to_fn_type_maps().find(repr);
3765 if (i == per_tu_repr_to_fn_type_maps().end())
3782 Dwarf_Off die_offset,
3783 Dwarf_Off canonical_die_offset)
const
3785 canonical_dies[die_offset] = canonical_die_offset;}
3801 set_canonical_die_offset(Dwarf_Off die_offset,
3803 Dwarf_Off canonical_die_offset,
3804 bool die_as_type)
const
3808 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3809 get_container(source)
3810 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3811 get_container(source);
3813 set_canonical_die_offset(canonical_dies,
3815 canonical_die_offset);
3829 set_canonical_die_offset(
const Dwarf_Die *die,
3830 Dwarf_Off canonical_die_offset,
3831 bool die_as_type)
const
3833 const die_source source = get_die_source(die);
3835 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3837 set_canonical_die_offset(die_offset, source,
3838 canonical_die_offset,
3852 Dwarf_Off die_offset)
const
3854 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3855 if (it == canonical_dies.end())
3872 get_canonical_die_offset(Dwarf_Off die_offset,
3874 bool die_as_type)
const
3878 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3879 get_container(source)
3880 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3881 get_container(source);
3883 return get_canonical_die_offset(canonical_dies, die_offset);
3898 erase_canonical_die_offset(Dwarf_Off die_offset,
3900 bool die_as_type)
const
3904 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3905 get_container(source)
3906 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3907 get_container(source);
3909 return canonical_dies.erase(die_offset);
3922 associate_die_to_type(
const Dwarf_Die *die,
3923 type_base_sptr type,
3929 Dwarf_Die equiv_die;
3930 if (!get_or_compute_canonical_die(die, equiv_die, where,
3935 type_die_artefact_maps().get_container(*
this, &equiv_die);
3937 size_t die_offset = dwarf_dieoffset(&equiv_die);
3938 m[die_offset] = type;
3952 lookup_type_from_die(
const Dwarf_Die* die)
const
3955 lookup_artifact_from_die(die,
true);
3957 return fn->get_type();
3975 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3977 type_base_sptr result;
3979 type_die_artefact_maps().get_container(source);
3980 die_artefact_map_type::const_iterator i = m.find(die_offset);
3984 return fn->get_type();
3992 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
4002 die_wip_function_types_map(source);
4003 die_function_type_map_type::const_iterator i = m.find(die_offset);
4022 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
4037 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4039 case ALT_DEBUG_INFO_DIE_SOURCE:
4040 return alternate_die_wip_classes_map_;
4041 case TYPE_UNIT_DIE_SOURCE:
4042 return type_unit_die_wip_classes_map_;
4043 case NO_DEBUG_INFO_DIE_SOURCE:
4044 case NUMBER_OF_DIE_SOURCES:
4047 return die_wip_classes_map_;
4058 die_wip_function_types_map(
die_source source)
const
4059 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
4069 die_wip_function_types_map(
die_source source)
4073 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4075 case ALT_DEBUG_INFO_DIE_SOURCE:
4076 return alternate_die_wip_function_types_map_;
4077 case TYPE_UNIT_DIE_SOURCE:
4078 return type_unit_die_wip_function_types_map_;
4079 case NO_DEBUG_INFO_DIE_SOURCE:
4080 case NUMBER_OF_DIE_SOURCES:
4083 return die_wip_function_types_map_;
4094 die_function_decl_with_no_symbol_map()
4095 {
return die_function_with_no_symbol_map_;}
4108 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
4110 die_class_or_union_map_type::const_iterator i =
4111 die_wip_classes_map(source).find(offset);
4112 return (i != die_wip_classes_map(source).end());
4126 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
4128 die_function_type_map_type::const_iterator i =
4129 die_wip_function_types_map(source).find(offset);
4130 return (i != die_wip_function_types_map(source).end());
4149 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
4155 || dwarf_tag(die) != DW_TAG_member
4156 || !die_name(die).empty())
4162 if (die_is_anonymous_data_member(die))
4168 int64_t offset_in_bits = 0;
4169 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
4173 loc = die_location(*
this, die);
4178 std::ostringstream o;
4179 o <<
"unnamed-dm-@-";
4181 o <<
"offset-" << offset_in_bits <<
"bits";
4183 o <<
"loc-" << loc.expand();
4196 declaration_only_classes()
const
4197 {
return decl_only_classes_map_;}
4207 declaration_only_classes()
4208 {
return decl_only_classes_map_;}
4220 maybe_schedule_declaration_only_class_for_resolution(cou);
4222 maybe_schedule_declaration_only_enum_for_resolution(e);
4231 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
4233 if (cou->get_is_declaration_only()
4234 && cou->get_definition_of_declaration() == 0
4239 && !cou->get_qualified_name().empty())
4241 string qn = cou->get_qualified_name();
4242 string_classes_or_unions_map::iterator record =
4243 declaration_only_classes().find(qn);
4244 if (record == declaration_only_classes().end())
4245 declaration_only_classes()[qn].push_back(cou);
4247 record->second.push_back(cou);
4259 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4261 if (cou->get_is_declaration_only())
4262 return ((declaration_only_classes().find(cou->get_qualified_name())
4263 != declaration_only_classes().end())
4264 || (declaration_only_classes().find(cou->get_name())
4265 != declaration_only_classes().end()));
4288 const environment& e = l->get_environment();
4292 && l->
kind() == r->kind()
4293 && ((l->get_corpus() && r->get_corpus()
4294 && (l->get_corpus() == r->get_corpus()))
4295 ||(l->get_translation_unit()
4296 && r->get_translation_unit()
4297 && l->get_translation_unit() == r->get_translation_unit())))
4306 decl_base *ld =
is_decl(l.get());
4307 decl_base *rd =
is_decl(r.get());
4309 if (ld->get_qualified_name() != rd->get_qualified_name())
4312 location ll = ld->get_location(), rl = rd->get_location();
4315 string l1 = ll.expand();
4316 string l2 = rl.expand();
4322 e.priv_->allow_type_comparison_results_caching(
true);
4323 bool s0 = e.decl_only_class_equals_definition();
4324 e.decl_only_class_equals_definition(
true);
4325 bool equal = l == r;
4326 e.decl_only_class_equals_definition(s0);
4327 e.priv_->clear_type_comparison_results_cache();
4328 e.priv_->allow_type_comparison_results_caching(
false);
4335 resolve_declaration_only_classes()
4337 vector<string> resolved_classes;
4339 for (string_classes_or_unions_map::iterator i =
4340 declaration_only_classes().begin();
4341 i != declaration_only_classes().end();
4344 bool to_resolve =
false;
4345 for (classes_or_unions_type::iterator j = i->second.begin();
4346 j != i->second.end();
4348 if ((*j)->get_is_declaration_only()
4349 && ((*j)->get_definition_of_declaration() == 0))
4354 resolved_classes.push_back(i->first);
4399 map<string, class_or_union_sptr> per_tu_class_map;
4400 for (type_base_wptrs_type::const_iterator c = classes->begin();
4401 c != classes->end();
4408 if (klass->get_is_declaration_only())
4411 string tu_path = klass->get_translation_unit()->get_absolute_path();
4412 if (tu_path.empty())
4418 per_tu_class_map[tu_path] = klass;
4421 if (!per_tu_class_map.empty())
4427 for (classes_or_unions_type::iterator j = i->second.begin();
4428 j != i->second.end();
4431 if ((*j)->get_is_declaration_only()
4432 && ((*j)->get_definition_of_declaration() == 0))
4435 (*j)->get_translation_unit()->get_absolute_path();
4436 map<string, class_or_union_sptr>::const_iterator e =
4437 per_tu_class_map.find(tu_path);
4438 if (e != per_tu_class_map.end())
4439 (*j)->set_definition_of_declaration(e->second);
4440 else if (per_tu_class_map.size() == 1)
4441 (*j)->set_definition_of_declaration
4442 (per_tu_class_map.begin()->second);
4452 class_or_union_sptr>::const_iterator it;
4453 class_or_union_sptr first_class =
4454 per_tu_class_map.begin()->second;
4455 bool all_class_definitions_are_equal =
true;
4456 for (it = per_tu_class_map.begin();
4457 it != per_tu_class_map.end();
4460 if (it == per_tu_class_map.begin())
4464 if (!compare_before_canonicalisation(it->second,
4467 all_class_definitions_are_equal =
false;
4472 if (all_class_definitions_are_equal)
4473 (*j)->set_definition_of_declaration(first_class);
4477 resolved_classes.push_back(i->first);
4481 size_t num_decl_only_classes = declaration_only_classes().size(),
4482 num_resolved = resolved_classes.size();
4484 cerr <<
"resolved " << num_resolved
4485 <<
" class declarations out of "
4486 << num_decl_only_classes
4489 for (vector<string>::const_iterator i = resolved_classes.begin();
4490 i != resolved_classes.end();
4492 declaration_only_classes().erase(*i);
4494 if (show_stats() && !declaration_only_classes().empty())
4496 cerr <<
"Here are the "
4497 << num_decl_only_classes - num_resolved
4498 <<
" unresolved class declarations:\n";
4499 for (string_classes_or_unions_map::iterator i =
4500 declaration_only_classes().begin();
4501 i != declaration_only_classes().end();
4503 cerr <<
" " << i->first <<
"\n";
4515 declaration_only_enums()
const
4516 {
return decl_only_enums_map_;}
4526 declaration_only_enums()
4527 {
return decl_only_enums_map_;}
4537 if (enom->get_is_declaration_only()
4538 && enom->get_definition_of_declaration() == 0
4543 && !enom->get_qualified_name().empty())
4545 string qn = enom->get_qualified_name();
4546 string_enums_map::iterator record =
4547 declaration_only_enums().find(qn);
4548 if (record == declaration_only_enums().end())
4549 declaration_only_enums()[qn].push_back(enom);
4551 record->second.push_back(enom);
4565 if (enom->get_is_declaration_only())
4566 return (declaration_only_enums().find(enom->get_qualified_name())
4567 != declaration_only_enums().end());
4580 resolve_declaration_only_enums()
4582 vector<string> resolved_enums;
4584 for (string_enums_map::iterator i =
4585 declaration_only_enums().begin();
4586 i != declaration_only_enums().end();
4589 bool to_resolve =
false;
4590 for (enums_type::iterator j = i->second.begin();
4591 j != i->second.end();
4593 if ((*j)->get_is_declaration_only()
4594 && ((*j)->get_definition_of_declaration() == 0))
4599 resolved_enums.push_back(i->first);
4641 map<string, enum_type_decl_sptr> per_tu_enum_map;
4642 for (type_base_wptrs_type::const_iterator c = enums->begin();
4650 if (enom->get_is_declaration_only())
4653 string tu_path = enom->get_translation_unit()->get_absolute_path();
4654 if (tu_path.empty())
4660 per_tu_enum_map[tu_path] = enom;
4663 if (!per_tu_enum_map.empty())
4669 for (enums_type::iterator j = i->second.begin();
4670 j != i->second.end();
4673 if ((*j)->get_is_declaration_only()
4674 && ((*j)->get_definition_of_declaration() == 0))
4677 (*j)->get_translation_unit()->get_absolute_path();
4678 map<string, enum_type_decl_sptr>::const_iterator e =
4679 per_tu_enum_map.find(tu_path);
4680 if (e != per_tu_enum_map.end())
4681 (*j)->set_definition_of_declaration(e->second);
4682 else if (per_tu_enum_map.size() == 1)
4683 (*j)->set_definition_of_declaration
4684 (per_tu_enum_map.begin()->second);
4696 per_tu_enum_map.begin()->second;
4697 bool all_enum_definitions_are_equal =
true;
4698 for (it = per_tu_enum_map.begin();
4699 it != per_tu_enum_map.end();
4702 if (it == per_tu_enum_map.begin())
4706 if (!compare_before_canonicalisation(it->second,
4709 all_enum_definitions_are_equal =
false;
4714 if (all_enum_definitions_are_equal)
4715 (*j)->set_definition_of_declaration(first_enum);
4719 resolved_enums.push_back(i->first);
4723 size_t num_decl_only_enums = declaration_only_enums().size(),
4724 num_resolved = resolved_enums.size();
4726 cerr <<
"resolved " << num_resolved
4727 <<
" enum declarations out of "
4728 << num_decl_only_enums
4731 for (vector<string>::const_iterator i = resolved_enums.begin();
4732 i != resolved_enums.end();
4734 declaration_only_enums().erase(*i);
4736 if (show_stats() && !declaration_only_enums().empty())
4738 cerr <<
"Here are the "
4739 << num_decl_only_enums - num_resolved
4740 <<
" unresolved enum declarations:\n";
4741 for (string_enums_map::iterator i = declaration_only_enums().begin();
4742 i != declaration_only_enums().end();
4744 cerr <<
" " << i->first <<
"\n";
4760 corpus_sptr corp =
corpus();
4764 interned_string
id = corp->get_environment().intern(fn->get_id_string());
4766 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4771 if (f->get_symbol())
4791 fixup_functions_with_no_symbols()
4793 corpus_sptr corp =
corpus();
4798 die_function_decl_with_no_symbol_map();
4801 cerr << fns_with_no_symbol.size()
4802 <<
" functions to fixup, potentially\n";
4804 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4805 i != fns_with_no_symbol.end();
4808 corp->lookup_function_symbol(i->second->get_linkage_name()))
4823 if (i->second->get_symbol()
4824 || symbol_already_belongs_to_a_function(sym))
4829 i->second->set_symbol(sym);
4832 cerr <<
"fixed up '"
4833 << i->second->get_pretty_representation()
4834 <<
"' with symbol '"
4835 << sym->get_id_string()
4839 fns_with_no_symbol.clear();
4852 for (
auto method : src_class->get_member_functions())
4853 if (!method->get_linkage_name().empty())
4854 if (!dest_class->find_member_function(method->get_linkage_name()))
4856 method_decl_sptr copied_method =
4859 schedule_type_for_late_canonicalization(copied_method->get_type());
4870 template <
typename iterator_type>
4872 contains_anonymous_class(
const iterator_type& begin,
4873 const iterator_type& end)
4875 for (
auto i = begin; i < end; ++i)
4877 type_base_sptr t(*i);
4879 if (c && c->get_is_anonymous())
4895 template <
typename iterator_type>
4897 merge_member_functions_of_classes(
const iterator_type& begin,
4898 const iterator_type& end)
4900 if (contains_anonymous_class(begin, end))
4903 for (
auto i = begin; i < end; ++i)
4905 type_base_sptr t(*i);
4907 if (!reference_class)
4910 string n1 = reference_class->get_pretty_representation(
true,
true);
4912 for (
auto j = begin; j < end; ++j)
4917 type_base_sptr type(*j);
4922 n2 = klass->get_pretty_representation(
true,
true);
4925 copy_missing_member_functions(reference_class, klass);
4926 copy_missing_member_functions(klass, reference_class);
4935 merge_member_functions_in_classes_of_same_names()
4937 corpus_sptr abi =
corpus();
4942 abi->get_types().class_types();
4944 for (
auto entry : class_types)
4946 auto& classes = entry.second;
4947 if (classes.size() > 1)
4949 bool a_class_has_member_fns =
false;
4950 for (
auto& c : classes)
4952 type_base_sptr t(c);
4954 if (!klass->get_member_functions().empty())
4956 a_class_has_member_fns =
true;
4960 if (a_class_has_member_fns)
4961 merge_member_functions_of_classes(classes.begin(),
4969 const vector<type_base_sptr>&
4970 types_to_canonicalize()
const
4971 {
return types_to_canonicalize_;}
4975 vector<type_base_sptr>&
4976 types_to_canonicalize()
4977 {
return types_to_canonicalize_;}
4981 clear_types_to_canonicalize()
4983 types_to_canonicalize_.clear();
4991 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4993 types_to_canonicalize_.push_back(t);
5003 canonicalize_types_scheduled()
5005 tools_utils::timer cn_timer;
5008 cerr <<
"DWARF Reader is going to canonicalize "
5010 << types_to_canonicalize().size()
5012 corpus_sptr c =
corpus();
5014 cerr <<
" from corpus " <<
corpus()->get_path() <<
"\n";
5019 (types_to_canonicalize().begin(),
5020 types_to_canonicalize().end(),
5021 [](
const vector<type_base_sptr>::const_iterator& i)
5022 {
return *i;}, do_log(), show_stats());
5027 cerr <<
"DWARF Reader finished types "
5028 <<
"sorting, hashing & canonicalizing in: "
5029 << cn_timer <<
"\n";
5046 add_late_canonicalized_types_stats(
size_t& canonicalized,
5047 size_t& missed)
const
5049 for (
auto t : types_to_canonicalize())
5051 if (t->get_canonical_type())
5061 perform_late_type_canonicalizing()
5063 canonicalize_types_scheduled();
5067 size_t num_canonicalized = 0, num_missed = 0, total = 0;
5068 add_late_canonicalized_types_stats(num_canonicalized,
5070 total = num_canonicalized + num_missed;
5074 cerr <<
" # late canonicalized types: "
5075 << num_canonicalized;
5077 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
5079 <<
" # missed canonicalization opportunities: "
5082 cerr <<
" (" << num_missed * 100 / total <<
"%)";
5090 {
return die_tu_map_;}
5094 {
return die_tu_map_;}
5103 tu_die_imported_unit_points_map(
die_source source)
const
5104 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
5113 tu_die_imported_unit_points_map(
die_source source)
5117 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
5119 case ALT_DEBUG_INFO_DIE_SOURCE:
5120 return alt_tu_die_imported_unit_points_map_;
5121 case TYPE_UNIT_DIE_SOURCE:
5122 return type_units_tu_die_imported_unit_points_map_;
5123 case NO_DEBUG_INFO_DIE_SOURCE:
5124 case NUMBER_OF_DIE_SOURCES:
5128 return tu_die_imported_unit_points_map_;
5146 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
5159 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
5161 case ALT_DEBUG_INFO_DIE_SOURCE:
5162 return alternate_die_parent_map_;
5163 case TYPE_UNIT_DIE_SOURCE:
5164 return type_section_die_parent_map();
5165 case NO_DEBUG_INFO_DIE_SOURCE:
5166 case NUMBER_OF_DIE_SOURCES:
5169 return primary_die_parent_map_;
5173 type_section_die_parent_map()
const
5174 {
return type_section_die_parent_map_;}
5177 type_section_die_parent_map()
5178 {
return type_section_die_parent_map_;}
5184 cur_transl_unit()
const
5208 global_scope()
const
5209 {
return cur_transl_unit()->get_global_scope();}
5216 {
return nil_scope_;}
5220 {
return scope_stack_;}
5224 {
return scope_stack_;}
5229 if (scope_stack().empty())
5231 if (cur_transl_unit())
5234 return scope_stack().top();
5237 list<var_decl_sptr>&
5238 var_decls_to_re_add_to_tree()
5239 {
return var_decls_to_add_;}
5252 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
const
5254 if (!die || !die_is_decl(die))
5257 bool result =
false, address_found =
false, symbol_is_exported =
false;;
5258 Dwarf_Addr decl_symbol_address = 0;
5260 if (die_is_variable_decl(die))
5262 if ((address_found = get_variable_address(die, decl_symbol_address)))
5263 symbol_is_exported =
5266 else if (die_is_function_decl(die))
5268 if ((address_found = get_function_address(die, decl_symbol_address)))
5269 symbol_is_exported =
5274 result = symbol_is_exported;
5285 is_decl_die_with_undefined_symbol(
const Dwarf_Die *die)
const
5287 if (is_decl_die_with_exported_symbol(die))
5290 string name, linkage_name;
5291 die_name_and_linkage_name(die, name, linkage_name);
5292 if (linkage_name.empty())
5293 linkage_name = name;
5295 bool result =
false;
5296 if ((die_is_variable_decl(die)
5299 (die_is_function_decl(die)
5320 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
5326 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
5328 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
5330 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
5332 dwarf_elf_load_address));
5335 if (dwarf_is_splitted()
5336 && (dwarf_elf_load_address != elf_load_address))
5347 addr = addr - dwarf_elf_load_address + elf_load_address;
5373 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
5378 Elf* elf = elf_handle();
5380 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5382 if (elf_header->e_type == ET_REL)
5395 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5420 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
5422 Elf* elf = elf_handle();
5424 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5426 if (elf_header->e_type == ET_REL)
5439 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5458 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5459 Dwarf_Addr& address)
const
5462 Dwarf_Addr end_addr;
5463 ptrdiff_t offset = 0;
5467 Dwarf_Addr addr = 0, fn_addr = 0;
5468 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5470 fn_addr = maybe_adjust_fn_sym_address(addr);
5477 }
while (offset > 0);
5495 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5497 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5498 DW_AT_low_pc, address))
5504 if (!get_first_exported_fn_address_from_DW_AT_ranges
5505 (
const_cast<Dwarf_Die*
>(function_die),
5509 address = maybe_adjust_fn_sym_address(address);
5528 get_variable_address(
const Dwarf_Die* variable_die,
5529 Dwarf_Addr& address)
const
5531 bool is_tls_address =
false;
5532 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5533 address, is_tls_address))
5535 if (!is_tls_address)
5536 address = maybe_adjust_var_sym_address(address);
5543 corpus::exported_decls_builder*
5544 exported_decls_builder()
5545 {
return corpus()->get_exported_decls_builder().get();}
5553 load_all_types()
const
5554 {
return options().load_all_types;}
5562 load_all_types(
bool f)
5563 {
options().load_all_types = f;}
5566 load_in_linux_kernel_mode()
const
5567 {
return options().load_in_linux_kernel_mode;}
5570 load_in_linux_kernel_mode(
bool f)
5571 {
options().load_in_linux_kernel_mode = f;}
5583 load_undefined_interfaces()
const
5594 leverage_dwarf_factorization()
const
5596 if (!leverage_dwarf_factorization_.has_value())
5598 if (
options().leverage_dwarf_factorization
5599 && elf_helpers::find_section_by_name(elf_handle(),
5600 ".gnu_debugaltlink"))
5601 leverage_dwarf_factorization_ =
true;
5603 leverage_dwarf_factorization_ =
false;
5605 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5607 return *leverage_dwarf_factorization_;
5618 {
return options().show_stats;}
5667 build_die_parent_relations_under(Dwarf_Die* die,
5677 if (dwarf_child(die, &child) != 0)
5682 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5683 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5685 Dwarf_Die imported_unit;
5686 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5697 && die_has_children(&imported_unit))
5699 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5700 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5701 imported_units.push_back
5702 (imported_unit_point(dwarf_dieoffset(&child),
5704 imported_unit_die_source));
5707 build_die_parent_relations_under(&child, source, imported_units);
5709 while (dwarf_siblingof(&child, &child) == 0);
5741 case translation_unit::LANG_UNKNOWN:
5742#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5743 case translation_unit::LANG_Mips_Assembler:
5770 build_die_parent_maps()
5772 bool we_do_have_to_build_die_parent_map =
false;
5773 uint8_t address_size = 0;
5774 size_t header_size = 0;
5779 for (Dwarf_Off offset = 0, next_offset = 0;
5781 offset, &next_offset, &header_size,
5782 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5783 offset = next_offset)
5785 Dwarf_Off die_offset = offset + header_size;
5792 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5794 if (do_we_build_die_parent_maps(lang))
5795 we_do_have_to_build_die_parent_map =
true;
5798 if (!we_do_have_to_build_die_parent_map)
5803 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5804 for (Dwarf_Off offset = 0, next_offset = 0;
5806 offset, &next_offset, &header_size,
5807 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5808 offset = next_offset)
5810 Dwarf_Off die_offset = offset + header_size;
5818 tu_die_imported_unit_points_map(source)[die_offset] =
5820 build_die_parent_relations_under(&cu, source, imported_units);
5825 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5828 for (Dwarf_Off offset = 0, next_offset = 0;
5830 offset, &next_offset, &header_size,
5831 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5832 offset = next_offset)
5834 Dwarf_Off die_offset = offset + header_size;
5841 tu_die_imported_unit_points_map(source)[die_offset] =
5843 build_die_parent_relations_under(&cu, source, imported_units);
5848 source = TYPE_UNIT_DIE_SOURCE;
5851 uint64_t type_signature = 0;
5852 Dwarf_Off type_offset;
5853 for (Dwarf_Off offset = 0, next_offset = 0;
5855 offset, &next_offset, &header_size,
5856 NULL, NULL, &address_size, NULL,
5857 &type_signature, &type_offset) == 0);
5858 offset = next_offset)
5860 Dwarf_Off die_offset = offset + header_size;
5868 tu_die_imported_unit_points_map(source)[die_offset] =
5870 build_die_parent_relations_under(&cu, source, imported_units);
5885struct offset_pairs_stack_type
5902 offset_pairs_stack_type(
const reader& rdr)
5928 offset_pair_vector_type::iterator i;
5930 for (i = vect_.begin();i < vect_.end(); ++i)
5934 if (i != vect_.end())
5953 if (set_.find(p) == set_.end())
5980 bool result =
false;
5985 offset_pair_vector_type::const_iterator i;
5986 for (i = vect_.begin(); i != vect_.end(); ++i)
5990 if (i == vect_.end())
5995 for (++i; i != vect_.end(); ++i)
5997 pairs.push_back(*i);
6017 for (
auto type_pair : dependant_types)
6018 dependant_types_[type_pair].push_back(p);
6029 get_pairs_that_depend_on(p, dependant_types);
6032 auto it = redundant_types_.find(p);
6033 if (it == redundant_types_.end())
6035 auto entry = std::make_pair(p, dependant_types);
6036 redundant_types_.insert(entry);
6039 it->second.insert(it->second.end(),
6040 dependant_types.begin(),
6041 dependant_types.end());
6045 record_dependant_types(p, dependant_types);
6056 auto i = redundant_types_.find(p);
6057 if (i != redundant_types_.end())
6070 auto i = dependant_types_.find(p);
6071 if (i == dependant_types_.end())
6089 bool erase_cached_results =
false)
6093 auto redundant_type = redundant_types_.find(p);
6094 if (redundant_type != redundant_types_.end())
6096 for (
auto dependant_type : redundant_type->second)
6100 auto dependant_types_it = dependant_types_.find(dependant_type);
6101 ABG_ASSERT(dependant_types_it != dependant_types_.end());
6105 auto i = dependant_types_it->second.begin();
6106 for (; i!= dependant_types_it->second.end();++i)
6109 if (i != dependant_types_it->second.end())
6110 dependant_types_it->second.erase(i);
6115 if (dependant_types_it->second.empty())
6117 if (erase_cached_results)
6118 rdr_.die_comparison_results_.erase(dependant_type);
6119 dependant_types_.erase(dependant_types_it);
6123 if (erase_cached_results)
6124 rdr_.die_comparison_results_.erase(p);
6125 redundant_types_.erase(p);
6137 {erase_redundant_type_pair_entry(p,
true);}
6150 get_dependant_types(p, dependant_types,
true);
6151 for (
auto dependant_type : dependant_types)
6155 if (rdr_.propagated_types_.find(dependant_type)
6156 != rdr_.propagated_types_.end())
6158 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
6159 dependant_type.first.source_,
6161 rdr_.propagated_types_.erase(dependant_type);
6162 rdr_.cancelled_propagation_count_++;
6166 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
6167 if (comp_result_it != rdr_.die_comparison_results_.end())
6168 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
6172 auto comp_result_it = rdr_.die_comparison_results_.find(p);
6173 if (comp_result_it != rdr_.die_comparison_results_.end())
6180 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
6181 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
6182 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
6185 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
6187 rdr_.erase_canonical_die_offset(p.first.offset_,
6190 rdr_.propagated_types_.erase(p);
6191 rdr_.cancelled_propagation_count_++;
6210 bool transitive_closure =
false)
6212 auto i = redundant_types_.find(p);
6213 if (i != redundant_types_.end())
6215 for (
auto dependant_type : i->second)
6216 if (result.find(dependant_type) == result.end())
6218 result.insert(dependant_type);
6219 if (transitive_closure)
6220 get_dependant_types(p, result,
true);
6229build_ir_node_from_die(reader& rdr,
6232 bool called_from_public_decl,
6233 size_t where_offset,
6234 bool is_declaration_only =
true,
6235 bool is_required_decl_spec =
false);
6238build_ir_node_from_die(reader& rdr,
6240 bool called_from_public_decl,
6241 size_t where_offset);
6243static decl_base_sptr
6244build_ir_node_for_void_type(reader& rdr);
6247build_ir_node_for_void_pointer_type(reader& rdr);
6250add_or_update_class_type(reader& rdr,
6255 bool called_from_public_decl,
6256 size_t where_offset,
6257 bool is_declaration_only);
6259static union_decl_sptr
6260add_or_update_union_type(reader& rdr,
6263 union_decl_sptr union_type,
6264 bool called_from_public_decl,
6265 size_t where_offset,
6266 bool is_declaration_only);
6268static decl_base_sptr
6269build_ir_node_for_void_type(reader& rdr);
6271static decl_base_sptr
6272build_ir_node_for_variadic_parameter_type(reader &rdr);
6275build_function_decl(reader& rdr,
6277 size_t where_offset,
6281function_is_suppressed(
const reader& rdr,
6282 const scope_decl* scope,
6283 Dwarf_Die *function_die,
6284 bool is_declaration_only);
6287build_or_get_fn_decl_if_not_suppressed(reader& rdr,
6290 size_t where_offset,
6291 bool is_declaration_only,
6295build_var_decl(reader& rdr,
6297 size_t where_offset,
6301build_or_get_var_decl_if_not_suppressed(reader& rdr,
6304 size_t where_offset,
6305 bool is_declaration_only,
6307 bool is_required_decl_spec =
false);
6309variable_is_suppressed(
const reader& rdr,
6310 const scope_decl* scope,
6311 Dwarf_Die *variable_die,
6312 bool is_declaration_only,
6313 bool is_required_decl_spec =
false);
6316finish_member_function_reading(Dwarf_Die* die,
6318 const class_or_union_sptr klass,
6327die_is_anonymous(
const Dwarf_Die* die)
6329 Dwarf_Attribute attr;
6330 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
6344die_is_anonymous_data_member(
const Dwarf_Die* die)
6347 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
6348 || !die_name(die).empty())
6352 if (!die_die_attribute(die, DW_AT_type, type_die))
6355 if (dwarf_tag(&type_die) != DW_TAG_structure_type
6356 && dwarf_tag(&type_die) != DW_TAG_union_type)
6373die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6378 Dwarf_Attribute attr;
6379 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6382 const char* str = dwarf_formstring(&attr);
6383 return str ? str :
"";
6397die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6402 Dwarf_Attribute attr;
6403 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6406 const char* str = dwarf_formstring(&attr);
6426die_unsigned_constant_attribute(
const Dwarf_Die* die,
6433 Dwarf_Attribute attr;
6434 Dwarf_Word result = 0;
6435 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6436 || dwarf_formudata(&attr, &result))
6456die_signed_constant_attribute(
const Dwarf_Die *die,
6463 Dwarf_Attribute attr;
6464 Dwarf_Sword result = 0;
6465 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6466 || dwarf_formsdata(&attr, &result))
6492die_constant_attribute(
const Dwarf_Die *die,
6495 array_type_def::subrange_type::bound_value &value)
6500 if (!die_unsigned_constant_attribute(die, attr_name, l))
6502 value.set_unsigned(l);
6507 if (!die_signed_constant_attribute(die, attr_name, l))
6509 value.set_signed(l);
6524form_is_DW_FORM_strx(
unsigned form)
6528#if defined HAVE_DW_FORM_strx1 \
6529 && defined HAVE_DW_FORM_strx2 \
6530 && defined HAVE_DW_FORM_strx3 \
6531 && defined HAVE_DW_FORM_strx4
6532 if (form == DW_FORM_strx1
6533 || form == DW_FORM_strx2
6534 || form == DW_FORM_strx3
6535 ||form == DW_FORM_strx4)
6552form_is_DW_FORM_line_strp(
unsigned form)
6556#if defined HAVE_DW_FORM_line_strp
6557 if (form == DW_FORM_line_strp)
6584die_flag_attribute(
const Dwarf_Die* die,
6587 bool recursively =
true)
6589 Dwarf_Attribute attr;
6591 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6592 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6596 if (dwarf_formflag(&attr, &f))
6610die_linkage_name(
const Dwarf_Die* die)
6615 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6616 if (linkage_name.empty())
6617 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6618 return linkage_name;
6632die_decl_file_attribute(
const Dwarf_Die* die)
6637 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6639 return str ? str :
"";
6660die_die_attribute(
const Dwarf_Die* die,
6665 Dwarf_Attribute attr;
6667 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6668 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6671 return dwarf_formref_die(&attr, &result);
6696die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die)
6698 if (die_die_attribute(die, DW_AT_specification, origin_die,
true)
6699 || die_die_attribute(die, DW_AT_abstract_origin, origin_die,
true))
6701 while (die_die_attribute(&origin_die,
6702 DW_AT_specification,
6704 || die_die_attribute(&origin_die,
6705 DW_AT_abstract_origin,
6743subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6745 Dwarf_Die& referenced_subrange)
6747 bool result =
false;
6749 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6752 Dwarf_Die referenced_die;
6753 if (die_die_attribute(die, attr_name, referenced_die))
6755 unsigned tag = dwarf_tag(&referenced_die);
6756 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6759 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6761 tag = dwarf_tag(&type_die);
6762 if (tag == DW_TAG_subrange_type)
6764 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6800subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6802 array_type_def::subrange_type::bound_value& v,
6805 bool result =
false;
6807 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6810 Dwarf_Die subrange_die;
6811 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6814 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6832die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6834 Dwarf_Attribute attr;
6835 if (!dwarf_attr_integrate(die, attr_name, &attr))
6837 return dwarf_formaddr(&attr, &result) == 0;
6848die_location(
const reader& rdr,
const Dwarf_Die* die)
6853 string file = die_decl_file_attribute(die);
6855 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6857 if (!file.empty() && line != 0)
6860 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6872die_name(
const Dwarf_Die* die)
6874 string name = die_string_attribute(die, DW_AT_name);
6890die_loc_and_name(
const reader& rdr,
6894 string& linkage_name)
6896 loc = die_location(rdr, die);
6897 name = die_name(die);
6898 linkage_name = die_linkage_name(die);
6909die_name_and_linkage_name(
const Dwarf_Die* die,
6911 string& linkage_name)
6913 name = die_name(die);
6914 linkage_name = die_linkage_name(die);
6927die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6932 uint64_t byte_size = 0, bit_size = 0;
6934 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6936 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6940 bit_size = byte_size * 8;
6963 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6970 case private_access:
6971 result = private_access;
6974 case protected_access:
6975 result = protected_access;
6979 result = public_access;
6998die_is_public_decl(
const Dwarf_Die* die)
7002 bool is_public =
false;
7008 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7009 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
7010 die_flag_attribute(die, DW_AT_external, is_public);
7011 else if (tag == DW_TAG_namespace)
7013 string name = die_name(die);
7014 is_public = !name.empty();
7028die_is_effectively_public_decl(
const reader& rdr,
7029 const Dwarf_Die* die)
7031 if (die_is_public_decl(die))
7034 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7035 if (tag == DW_TAG_variable || tag == DW_TAG_member)
7038 Dwarf_Die parent_die;
7039 size_t where_offset = 0;
7040 if (!get_parent_die(rdr, die, parent_die, where_offset))
7043 tag = dwarf_tag(&parent_die);
7044 if (tag == DW_TAG_compile_unit
7045 || tag == DW_TAG_partial_unit
7046 || tag == DW_TAG_type_unit)
7050 if (tag == DW_TAG_namespace)
7052 string name = die_name(&parent_die);
7071die_is_declaration_only(Dwarf_Die* die)
7073 bool is_declaration =
false;
7074 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
7075 if (is_declaration && (!die_has_size_attribute(die)
7076 || !die_has_children(die)))
7087die_is_function_decl(
const Dwarf_Die *die)
7092 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7093 if (tag == DW_TAG_subprogram)
7104die_is_variable_decl(
const Dwarf_Die *die)
7109 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7110 if (tag == DW_TAG_variable)
7121die_has_size_attribute(
const Dwarf_Die *die)
7124 if (die_size_in_bits(die, s))
7135die_has_no_child(
const Dwarf_Die *die)
7141 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7154die_is_declaration_only(
const Dwarf_Die* die)
7155{
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
7163die_is_artificial(Dwarf_Die* die)
7166 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
7173is_type_tag(
unsigned tag)
7175 bool result =
false;
7179 case DW_TAG_array_type:
7180 case DW_TAG_class_type:
7181 case DW_TAG_enumeration_type:
7182 case DW_TAG_pointer_type:
7183 case DW_TAG_reference_type:
7184 case DW_TAG_string_type:
7185 case DW_TAG_structure_type:
7186 case DW_TAG_subroutine_type:
7187 case DW_TAG_typedef:
7188 case DW_TAG_union_type:
7189 case DW_TAG_ptr_to_member_type:
7190 case DW_TAG_set_type:
7191 case DW_TAG_subrange_type:
7192 case DW_TAG_base_type:
7193 case DW_TAG_const_type:
7194 case DW_TAG_file_type:
7195 case DW_TAG_packed_type:
7196 case DW_TAG_thrown_type:
7197 case DW_TAG_volatile_type:
7198 case DW_TAG_restrict_type:
7199 case DW_TAG_interface_type:
7200 case DW_TAG_unspecified_type:
7201 case DW_TAG_shared_type:
7202 case DW_TAG_rvalue_reference_type:
7203 case DW_TAG_coarray_type:
7204 case DW_TAG_atomic_type:
7205 case DW_TAG_immutable_type:
7228is_canon_type_to_be_propagated_tag(
unsigned tag)
7230 bool result =
false;
7234 case DW_TAG_class_type:
7235 case DW_TAG_structure_type:
7236 case DW_TAG_union_type:
7237 case DW_TAG_subroutine_type:
7238 case DW_TAG_subprogram:
7259type_comparison_result_to_be_cached(
unsigned tag)
7264 case DW_TAG_class_type:
7265 case DW_TAG_structure_type:
7266 case DW_TAG_union_type:
7267 case DW_TAG_subroutine_type:
7268 case DW_TAG_subprogram:
7289maybe_cache_type_comparison_result(
const reader& rdr,
7294 if (!type_comparison_result_to_be_cached(tag)
7295 || (result != COMPARISON_RESULT_EQUAL
7296 && result != COMPARISON_RESULT_DIFFERENT))
7299 rdr.die_comparison_results_[p] = result;
7319get_cached_type_comparison_result(
const reader& rdr,
7323 auto i = rdr.die_comparison_results_.find(p);
7324 if (i != rdr.die_comparison_results_.end())
7347maybe_get_cached_type_comparison_result(
const reader& rdr,
7352 if (type_comparison_result_to_be_cached(tag))
7357 if (get_cached_type_comparison_result(rdr, p, result))
7369is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
7371 bool result =
false;
7372 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7374 if (!is_type_tag(tag))
7379 case DW_TAG_class_type:
7380 case DW_TAG_structure_type:
7381 case DW_TAG_union_type:
7382 result = !die_is_declaration_only(die);
7385 case DW_TAG_subroutine_type:
7386 case DW_TAG_subprogram:
7387 case DW_TAG_array_type:
7403is_decl_tag(
unsigned tag)
7407 case DW_TAG_formal_parameter:
7408 case DW_TAG_imported_declaration:
7410 case DW_TAG_unspecified_parameters:
7411 case DW_TAG_subprogram:
7412 case DW_TAG_variable:
7413 case DW_TAG_namespace:
7414 case DW_TAG_GNU_template_template_param:
7415 case DW_TAG_GNU_template_parameter_pack:
7416 case DW_TAG_GNU_formal_parameter_pack:
7428die_is_type(
const Dwarf_Die* die)
7432 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7441die_is_decl(
const Dwarf_Die* die)
7445 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7454die_is_namespace(
const Dwarf_Die* die)
7458 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
7467die_is_unspecified(Dwarf_Die* die)
7471 return (dwarf_tag(die) == DW_TAG_unspecified_type);
7480die_is_void_type(Dwarf_Die* die)
7482 if (!die || dwarf_tag(die) != DW_TAG_base_type)
7485 string name = die_name(die);
7498die_is_pointer_type(
const Dwarf_Die* die)
7503 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7504 if (tag == DW_TAG_pointer_type)
7518pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7520 if (!die_is_pointer_array_or_reference_type(die)
7521 && !die_is_qualified_type(die))
7524 Dwarf_Die underlying_type_die;
7525 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7528 if (!die_is_class_type(&underlying_type_die))
7531 string name = die_name(&underlying_type_die);
7533 return name.empty();
7542die_is_reference_type(
const Dwarf_Die* die)
7547 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7548 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7560die_is_array_type(
const Dwarf_Die* die)
7565 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7566 if (tag == DW_TAG_array_type)
7578die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7579{
return (die_is_pointer_type(die)
7580 || die_is_reference_type(die)
7581 || die_is_array_type(die));}
7589die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7590{
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7599die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7600{
return (die_is_pointer_array_or_reference_type(die)
7601 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7609die_is_class_type(
const Dwarf_Die* die)
7611 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7613 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7625die_is_qualified_type(
const Dwarf_Die* die)
7627 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7628 if (tag == DW_TAG_const_type
7629 || tag == DW_TAG_volatile_type
7630 || tag == DW_TAG_restrict_type)
7642die_is_function_type(
const Dwarf_Die *die)
7644 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7645 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7663die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7668 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7680die_has_children(
const Dwarf_Die* die)
7686 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7706fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die)
7711 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7712 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7715 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7717 int child_tag = dwarf_tag(&child);
7718 if (child_tag == DW_TAG_formal_parameter)
7720 memcpy(&first_parm_die, &child,
sizeof(Dwarf_Die));
7755member_fn_die_has_this_pointer(
const reader& rdr,
7756 const Dwarf_Die* die,
7757 size_t where_offset,
7758 Dwarf_Die& class_die,
7759 Dwarf_Die& object_pointer_die)
7764 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7765 if (tag != DW_TAG_subprogram && tag != DW_TAG_subroutine_type)
7768 if (tag == DW_TAG_subprogram
7769 && !die_is_at_class_scope(rdr, die, where_offset, class_die))
7772 Dwarf_Die first_parm_die;
7773 Dwarf_Die parm_type_die;
7774 if (die_has_object_pointer(die, object_pointer_die))
7780 memcpy(&first_parm_die, &object_pointer_die,
sizeof(Dwarf_Die));
7781 if (!die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7783 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7784 die_peel_typedef(&parm_type_die, parm_type_die);
7786 else if (fn_die_first_parameter_die(die, first_parm_die))
7788 memcpy(&object_pointer_die, &first_parm_die,
sizeof(Dwarf_Die));
7789 bool is_artificial =
false;
7790 if (die_flag_attribute(&first_parm_die, DW_AT_artificial, is_artificial))
7792 if (die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7794 tag = dwarf_tag(&parm_type_die);
7795 if (tag == DW_TAG_pointer_type)
7797 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7798 die_peel_typedef(&parm_type_die, parm_type_die);
7812 tag = dwarf_tag(&parm_type_die);
7813 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7815 memcpy(&class_die, &parm_type_die,
sizeof(Dwarf_Die));
7835die_this_pointer_from_object_pointer(Dwarf_Die* die,
7836 Dwarf_Die& this_pointer_die)
7839 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7841 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7856die_this_pointer_is_const(Dwarf_Die* dye)
7861 memcpy(&die, dye,
sizeof(Dwarf_Die));
7862 if (dwarf_tag(&die) == DW_TAG_const_type)
7865 if (dwarf_tag(&die) == DW_TAG_pointer_type)
7867 Dwarf_Die pointed_to_type_die;
7868 if (die_die_attribute(&die, DW_AT_type, pointed_to_type_die))
7869 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7885die_object_pointer_is_for_const_method(Dwarf_Die* die)
7888 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7890 Dwarf_Die this_pointer_die;
7891 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7892 if (die_this_pointer_is_const(&this_pointer_die))
7914die_is_at_class_scope(
const reader& rdr,
7915 const Dwarf_Die* die,
7916 size_t where_offset,
7917 Dwarf_Die& class_scope_die)
7919 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7922 int tag = dwarf_tag(&class_scope_die);
7924 return (tag == DW_TAG_structure_type
7925 || tag == DW_TAG_class_type
7926 || tag == DW_TAG_union_type);
7939die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7944 int tag = dwarf_tag(die);
7946 if (tag == DW_TAG_const_type
7947 || tag == DW_TAG_volatile_type
7948 || tag == DW_TAG_restrict_type
7949 || tag == DW_TAG_pointer_type
7950 || tag == DW_TAG_reference_type
7951 || tag == DW_TAG_rvalue_reference_type)
7953 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7959 memcpy(&peeled_die, die,
sizeof(peeled_die));
7961 while (tag == DW_TAG_const_type
7962 || tag == DW_TAG_volatile_type
7963 || tag == DW_TAG_restrict_type
7964 || tag == DW_TAG_pointer_type
7965 || tag == DW_TAG_reference_type
7966 || tag == DW_TAG_rvalue_reference_type)
7968 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7970 tag = dwarf_tag(&peeled_die);
7985die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7990 memcpy(&peeled_die, die,
sizeof(peeled_die));
7992 int tag = dwarf_tag(&peeled_die);
7994 bool result =
false;
7995 while (tag == DW_TAG_const_type
7996 || tag == DW_TAG_volatile_type
7997 || tag == DW_TAG_restrict_type)
7999 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8001 tag = dwarf_tag(&peeled_die);
8017die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
8022 int tag = dwarf_tag(die);
8024 memcpy(&peeled_die, die,
sizeof(peeled_die));
8026 if (tag == DW_TAG_typedef)
8028 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8034 while (tag == DW_TAG_typedef)
8036 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8038 tag = dwarf_tag(&peeled_die);
8054die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
8059 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
8061 if (tag == DW_TAG_pointer_type
8062 || tag == DW_TAG_reference_type
8063 || tag == DW_TAG_rvalue_reference_type
8064 || tag == DW_TAG_typedef)
8066 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8072 while (tag == DW_TAG_pointer_type
8073 || tag == DW_TAG_reference_type
8074 || tag == DW_TAG_rvalue_reference_type
8075 || tag == DW_TAG_typedef)
8077 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8079 tag = dwarf_tag(&peeled_die);
8110die_function_type_is_method_type(
const reader& rdr,
8111 const Dwarf_Die *die,
8112 size_t where_offset,
8113 Dwarf_Die& object_pointer_die,
8114 Dwarf_Die& class_die,
8120 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
8121 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
8123 if (member_fn_die_has_this_pointer(rdr, die, where_offset, class_die, object_pointer_die))
8128 else if (die_is_at_class_scope(rdr, die, where_offset, class_die))
8139 VIRTUALITY_NOT_VIRTUAL,
8141 VIRTUALITY_PURE_VIRTUAL
8154die_virtuality(
const Dwarf_Die* die, virtuality& virt)
8160 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
8162 if (v == DW_VIRTUALITY_virtual)
8163 virt = VIRTUALITY_VIRTUAL;
8164 else if (v == DW_VIRTUALITY_pure_virtual)
8165 virt = VIRTUALITY_PURE_VIRTUAL;
8167 virt = VIRTUALITY_NOT_VIRTUAL;
8179die_is_virtual(
const Dwarf_Die* die)
8182 if (!die_virtuality(die, v))
8185 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
8195die_is_declared_inline(Dwarf_Die* die)
8197 uint64_t inline_value = 0;
8198 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
8200 return (inline_value == DW_INL_declared_inlined
8201 || inline_value == DW_INL_declared_not_inlined);
8216slowly_compare_strings(
const Dwarf_Die *l,
8220 const char *l_str = die_char_str_attribute(l, attr_name),
8221 *r_str = die_char_str_attribute(r, attr_name);
8222 if (!l_str && !r_str)
8224 return l_str && r_str && !strcmp(l_str, r_str);
8250compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
8254 Dwarf_Attribute l_attr, r_attr;
8255 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
8256 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
8260 || l_attr.form == DW_FORM_string
8261 || l_attr.form == DW_FORM_GNU_strp_alt
8262 || form_is_DW_FORM_strx(l_attr.form)
8263 || form_is_DW_FORM_line_strp(l_attr.form));
8266 || r_attr.form == DW_FORM_string
8267 || r_attr.form == DW_FORM_GNU_strp_alt
8268 || form_is_DW_FORM_strx(r_attr.form)
8269 || form_is_DW_FORM_line_strp(r_attr.form));
8271 if ((l_attr.form == DW_FORM_strp
8272 && r_attr.form == DW_FORM_strp)
8273 || (l_attr.form == DW_FORM_GNU_strp_alt
8274 && r_attr.form == DW_FORM_GNU_strp_alt)
8275 || (form_is_DW_FORM_strx(l_attr.form)
8276 && form_is_DW_FORM_strx(r_attr.form))
8277 || (form_is_DW_FORM_line_strp(l_attr.form)
8278 && form_is_DW_FORM_line_strp(r_attr.form)))
8285 if (l_attr.valp == r_attr.valp)
8287#if WITH_DEBUG_TYPE_CANONICALIZATION
8288 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
8299 result = slowly_compare_strings(l, r, attr_name);
8317compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
8319 Dwarf_Die l_cu, r_cu;
8320 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
8321 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
8325 compare_dies_string_attribute_value(&l_cu, &r_cu,
8328 if (compared && result)
8330 Dwarf_Die peeled_l, peeled_r;
8331 if (die_is_pointer_reference_or_typedef_type(l)
8332 && die_is_pointer_reference_or_typedef_type(r)
8333 && die_peel_pointer_and_typedef(l, peeled_l)
8334 && die_peel_pointer_and_typedef(r, peeled_r))
8336 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
8337 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
8340 compare_dies_string_attribute_value(&l_cu, &r_cu,
8371die_location_expr(
const Dwarf_Die* die,
8379 Dwarf_Attribute attr;
8380 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
8384 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
8419op_pushes_constant_value(Dwarf_Op* ops,
8423 dwarf_expr_eval_context& ctxt)
8427 Dwarf_Op& op = ops[index];
8433 value = ops[index].number;
8446 value = ops[index].number;
8550 expr_result r(value);
8553 next_index = index + 1;
8583op_pushes_non_constant_value(Dwarf_Op* ops,
8587 dwarf_expr_eval_context& ctxt)
8590 Dwarf_Op& op = ops[index];
8626 next_index = index + 1;
8661 next_index = index + 1;
8665 next_index = index + 2;
8669 next_index = index + 1;
8673 next_index = index + 1;
8676 case DW_OP_GNU_variable_value:
8677 next_index = index + 1;
8684 expr_result r(
false);
8713op_manipulates_stack(Dwarf_Op* expr,
8717 dwarf_expr_eval_context& ctxt)
8719 Dwarf_Op& op = expr[index];
8725 v = ctxt.stack.front();
8730 v = ctxt.stack.front();
8749 ctxt.stack.erase(ctxt.stack.begin() + 1);
8756 ctxt.stack.erase(ctxt.stack.begin() + 2);
8761 case DW_OP_deref_size:
8769 case DW_OP_xderef_size:
8777 case DW_OP_push_object_address:
8782 case DW_OP_form_tls_address:
8783 case DW_OP_GNU_push_tls_address:
8786 if (op.atom == DW_OP_form_tls_address)
8791 case DW_OP_call_frame_cfa:
8803 if (op.atom == DW_OP_form_tls_address
8804 || op.atom == DW_OP_GNU_push_tls_address)
8805 ctxt.set_tls_address(
true);
8807 ctxt.set_tls_address(
false);
8809 next_index = index + 1;
8837op_is_arith_logic(Dwarf_Op* expr,
8841 dwarf_expr_eval_context& ctxt)
8845 Dwarf_Op& op = expr[index];
8846 expr_result val1, val2;
8847 bool result =
false;
8863 ctxt.push(val1 & val2);
8870 if (!val1.is_const())
8872 ctxt.push(val2 / val1);
8880 ctxt.push(val2 - val1);
8888 ctxt.push(val2 % val1);
8896 ctxt.push(val2 * val1);
8918 ctxt.push(val1 | val2);
8926 ctxt.push(val2 + val1);
8930 case DW_OP_plus_uconst:
8942 ctxt.push(val2 << val1);
8951 ctxt.push(val2 >> val1);
8959 ctxt.push(val2 ^ val1);
8969 if (ctxt.stack.front().is_const())
8970 ctxt.accum = ctxt.stack.front();
8972 next_index = index + 1;
9000op_is_control_flow(Dwarf_Op* expr,
9004 dwarf_expr_eval_context& ctxt)
9008 Dwarf_Op& op = expr[index];
9009 expr_result val1, val2;
9023 if (op.atom == DW_OP_eq)
9024 value = val2 == val1;
9025 else if (op.atom == DW_OP_ge)
9026 value = val2 >= val1;
9027 else if (op.atom == DW_OP_gt)
9028 value = val2 > val1;
9029 else if (op.atom == DW_OP_le)
9030 value = val2 <= val1;
9031 else if (op.atom == DW_OP_lt)
9032 value = val2 < val1;
9033 else if (op.atom == DW_OP_ne)
9034 value = val2 != val1;
9036 val1 = value ? 1 : 0;
9043 index += op.number - 1;
9048 if (val1.const_value() != 0)
9049 index += val1.const_value() - 1;
9054 case DW_OP_call_ref:
9062 if (ctxt.stack.front().is_const())
9063 ctxt.accum = ctxt.stack.front();
9065 next_index = index + 1;
9086eval_quickly(Dwarf_Op* expr,
9090 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
9092 value = expr[0].number;
9119eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
9122 bool& is_tls_address,
9123 dwarf_expr_eval_context &eval_ctxt)
9129 size_t index = 0, next_index = 0;
9132 if (op_is_arith_logic(expr, expr_len, index,
9133 next_index, eval_ctxt)
9134 || op_pushes_constant_value(expr, expr_len, index,
9135 next_index, eval_ctxt)
9136 || op_manipulates_stack(expr, expr_len, index,
9137 next_index, eval_ctxt)
9138 || op_pushes_non_constant_value(expr, expr_len, index,
9139 next_index, eval_ctxt)
9140 || op_is_control_flow(expr, expr_len, index,
9141 next_index, eval_ctxt))
9144 next_index = index + 1;
9148 }
while (index < expr_len);
9150 is_tls_address = eval_ctxt.set_tls_address();
9151 if (eval_ctxt.accum.is_const())
9153 value = eval_ctxt.accum;
9173eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
9176 bool& is_tls_address)
9178 dwarf_expr_eval_context eval_ctxt;
9179 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
9180 is_tls_address, eval_ctxt);
9372read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
9377 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
9390 uint64_t containing_anonymous_object_size = 0;
9391 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
9392 containing_anonymous_object_size));
9393 containing_anonymous_object_size *= 8;
9395 uint64_t bitfield_size = 0;
9396 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
9407 offset = containing_anonymous_object_size - off - bitfield_size;
9423die_constant_data_member_location(
const Dwarf_Die *die,
9429 Dwarf_Attribute attr;
9430 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
9431 DW_AT_data_member_location,
9436 if (dwarf_formudata(&attr, &val) != 0)
9492die_member_offset(
const reader& rdr,
9493 const Dwarf_Die* die,
9496 Dwarf_Op* expr = NULL;
9497 size_t expr_len = 0;
9498 uint64_t bit_offset = 0;
9502 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
9504 offset = bit_offset;
9516 if (!die_constant_data_member_location(die, offset))
9521 if (!die_location_expr(die, DW_AT_data_member_location,
9528 if (!eval_quickly(expr, expr_len, offset))
9530 bool is_tls_address =
false;
9531 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
9532 offset, is_tls_address,
9533 rdr.dwarf_expr_eval_ctxt()))
9551 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
9552 offset += bit_offset;
9569die_location_address(Dwarf_Die* die,
9570 Dwarf_Addr& address,
9571 bool& is_tls_address)
9573 Dwarf_Op* expr = NULL;
9574 size_t expr_len = 0;
9576 is_tls_address =
false;
9581 Dwarf_Attribute attr;
9582 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
9585 if (dwarf_getlocation(&attr, &expr, &expr_len))
9592 Dwarf_Attribute result;
9593 if (!dwarf_getlocation_attr(&attr, expr, &result))
9595 return !dwarf_formaddr(&result, &address);
9598 address = expr->number;
9613die_virtual_function_index(Dwarf_Die* die,
9619 Dwarf_Op* expr = NULL;
9620 size_t expr_len = 0;
9621 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9626 bool is_tls_addr =
false;
9627 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9645 int tag = dwarf_tag(die);
9647 if (tag == DW_TAG_class_type
9648 || tag == DW_TAG_structure_type
9649 || tag == DW_TAG_union_type
9650 || tag == DW_TAG_enumeration_type)
9651 return die_is_anonymous(die);
9673get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9676 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9678 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9680 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9682 else if (tag == DW_TAG_union_type)
9684 else if (tag == DW_TAG_enumeration_type)
9703build_internal_anonymous_die_name(
const string &
base_name,
9704 size_t anonymous_type_index)
9707 if (anonymous_type_index && !
base_name.empty())
9709 std::ostringstream o;
9739die_qualified_type_name(
const reader& rdr,
9740 const Dwarf_Die* die,
9741 size_t where_offset,
9742 unordered_set<uint64_t>& guard)
9747 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9748 if (tag == DW_TAG_compile_unit
9749 || tag == DW_TAG_partial_unit
9750 || tag == DW_TAG_type_unit)
9753 string name = die_name(die);
9755 Dwarf_Die scope_die;
9756 if (!get_scope_die(rdr, die, where_offset, scope_die))
9759 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9760 string separator = colon_colon ?
"::" :
".";
9766 case DW_TAG_unspecified_type:
9769 case DW_TAG_base_type:
9779 case DW_TAG_typedef:
9783 case DW_TAG_enumeration_type:
9784 case DW_TAG_structure_type:
9785 case DW_TAG_class_type:
9786 case DW_TAG_union_type:
9788 if (die_is_anonymous(die))
9789 repr = die_class_or_enum_flat_representation(rdr, die,
"",
9792 where_offset, guard);
9795 string parent_name = die_qualified_name(rdr, &scope_die,
9796 where_offset, guard);
9797 repr = parent_name.empty() ? name : parent_name + separator + name;
9802 case DW_TAG_const_type:
9803 case DW_TAG_volatile_type:
9804 case DW_TAG_restrict_type:
9806 Dwarf_Die underlying_type_die;
9807 bool has_underlying_type_die =
9808 die_die_attribute(die, DW_AT_type, underlying_type_die);
9810 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9813 if (tag == DW_TAG_const_type)
9815 if (has_underlying_type_die
9816 && die_is_reference_type(&underlying_type_die))
9826 else if (!has_underlying_type_die
9827 || die_is_void_type(&underlying_type_die))
9835 else if (tag == DW_TAG_volatile_type)
9837 else if (tag == DW_TAG_restrict_type)
9842 string underlying_type_repr;
9843 if (has_underlying_type_die)
9844 underlying_type_repr =
9845 die_qualified_type_name(rdr, &underlying_type_die,
9846 where_offset, guard);
9848 underlying_type_repr =
"void";
9850 if (underlying_type_repr.empty())
9854 if (has_underlying_type_die)
9857 die_peel_qualified(&underlying_type_die, peeled);
9858 if (die_is_pointer_or_reference_type(&peeled))
9859 repr = underlying_type_repr +
" " + repr;
9861 repr +=
" " + underlying_type_repr;
9864 repr +=
" " + underlying_type_repr;
9869 case DW_TAG_pointer_type:
9870 case DW_TAG_reference_type:
9871 case DW_TAG_rvalue_reference_type:
9873 Dwarf_Die pointed_to_type_die;
9874 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9876 if (tag == DW_TAG_pointer_type)
9881 if (die_is_unspecified(&pointed_to_type_die))
9884 string pointed_type_repr =
9885 die_qualified_type_name(rdr, &pointed_to_type_die,
9886 where_offset, guard);
9888 repr = pointed_type_repr;
9892 if (tag == DW_TAG_pointer_type)
9894 else if (tag == DW_TAG_reference_type)
9896 else if (tag == DW_TAG_rvalue_reference_type)
9903 case DW_TAG_subrange_type:
9916 build_subrange_type(
const_cast<reader&
>(rdr),
9919 repr += s->as_string();
9923 case DW_TAG_array_type:
9925 Dwarf_Die element_type_die;
9926 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9928 string element_type_name =
9929 die_qualified_type_name(rdr, &element_type_die, where_offset, guard);
9930 if (element_type_name.empty())
9934 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9935 die, subranges, where_offset,
9938 repr = element_type_name;
9939 repr += array_type_def::subrange_type::vector_as_string(subranges);
9943 case DW_TAG_subroutine_type:
9944 case DW_TAG_subprogram:
9946 string return_type_name;
9948 vector<string> parm_names;
9949 bool is_const =
false;
9950 bool is_static =
false;
9952 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9956 return_type_name, class_name,
9957 parm_names, is_const,
9959 if (return_type_name.empty())
9960 return_type_name =
"void";
9962 repr = return_type_name;
9966 repr +=
" (" + class_name +
"::*)";
9970 for (vector<string>::const_iterator i = parm_names.begin();
9971 i != parm_names.end();
9974 if (i != parm_names.begin())
9983 case DW_TAG_string_type:
9984 case DW_TAG_ptr_to_member_type:
9985 case DW_TAG_set_type:
9986 case DW_TAG_file_type:
9987 case DW_TAG_packed_type:
9988 case DW_TAG_thrown_type:
9989 case DW_TAG_interface_type:
9990 case DW_TAG_shared_type:
10016die_type_name(
const reader& rdr,
10017 const Dwarf_Die* die,
10018 bool qualified_name,
10019 size_t where_offset,
10020 unordered_set<uint64_t>& guard)
10025 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
10026 if (tag == DW_TAG_compile_unit
10027 || tag == DW_TAG_partial_unit
10028 || tag == DW_TAG_type_unit)
10031 string name = die_name(die);
10033 Dwarf_Die scope_die;
10034 if (!get_scope_die(rdr, die, where_offset, scope_die))
10037 bool colon_colon = die_is_type(die) || die_is_namespace(die);
10038 string separator = colon_colon ?
"::" :
".";
10044 case DW_TAG_unspecified_type:
10047 case DW_TAG_base_type:
10057 case DW_TAG_typedef:
10061 case DW_TAG_enumeration_type:
10062 case DW_TAG_structure_type:
10063 case DW_TAG_class_type:
10064 case DW_TAG_union_type:
10066 if (die_is_anonymous(die))
10067 repr = die_class_or_enum_flat_representation(rdr, die,
"",
10074 string parent_name;
10075 if (qualified_name)
10078 parent_name = die_qualified_name(rdr, &scope_die,
10079 where_offset, guard);
10081 repr = parent_name.empty() ? name : parent_name + separator + name;
10086 case DW_TAG_const_type:
10087 case DW_TAG_volatile_type:
10088 case DW_TAG_restrict_type:
10090 Dwarf_Die underlying_type_die;
10091 bool has_underlying_type_die =
10092 die_die_attribute(die, DW_AT_type, underlying_type_die);
10094 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
10097 if (tag == DW_TAG_const_type)
10099 if (has_underlying_type_die
10100 && die_is_reference_type(&underlying_type_die))
10110 else if (!has_underlying_type_die
10111 || die_is_void_type(&underlying_type_die))
10119 else if (tag == DW_TAG_volatile_type)
10121 else if (tag == DW_TAG_restrict_type)
10126 string underlying_type_repr;
10127 if (has_underlying_type_die)
10128 underlying_type_repr =
10129 die_type_name(rdr, &underlying_type_die,
10130 qualified_name, where_offset,
10133 underlying_type_repr =
"void";
10135 if (underlying_type_repr.empty())
10139 if (has_underlying_type_die)
10142 die_peel_qualified(&underlying_type_die, peeled);
10143 if (die_is_pointer_or_reference_type(&peeled))
10144 repr = underlying_type_repr +
" " + repr;
10146 repr +=
" " + underlying_type_repr;
10149 repr +=
" " + underlying_type_repr;
10154 case DW_TAG_pointer_type:
10155 case DW_TAG_reference_type:
10156 case DW_TAG_rvalue_reference_type:
10158 Dwarf_Die pointed_to_type_die;
10159 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
10161 if (tag == DW_TAG_pointer_type)
10166 if (die_is_unspecified(&pointed_to_type_die))
10169 string pointed_type_repr =
10170 die_type_name(rdr, &pointed_to_type_die,
10171 qualified_name, where_offset,
10174 repr = pointed_type_repr;
10178 if (tag == DW_TAG_pointer_type)
10180 else if (tag == DW_TAG_reference_type)
10182 else if (tag == DW_TAG_rvalue_reference_type)
10189 case DW_TAG_subrange_type:
10202 build_subrange_type(
const_cast<reader&
>(rdr),
10205 repr += s->as_string();
10209 case DW_TAG_array_type:
10211 Dwarf_Die element_type_die;
10212 if (!die_die_attribute(die, DW_AT_type, element_type_die))
10214 string element_type_name =
10215 die_type_name(rdr, &element_type_die,
10216 qualified_name, where_offset,
10218 if (element_type_name.empty())
10222 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
10223 die, subranges, where_offset,
10226 repr = element_type_name;
10227 repr += array_type_def::subrange_type::vector_as_string(subranges);
10231 case DW_TAG_subroutine_type:
10232 case DW_TAG_subprogram:
10234 string return_type_name;
10236 vector<string> parm_names;
10237 bool is_const =
false;
10238 bool is_static =
false;
10240 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
10246 parm_names, is_const,
10248 if (return_type_name.empty())
10249 return_type_name =
"void";
10251 repr = return_type_name;
10256 repr +=
" (" + class_name +
"::*)";
10261 for (vector<string>::const_iterator i = parm_names.begin();
10262 i != parm_names.end();
10265 if (i != parm_names.begin())
10274 case DW_TAG_string_type:
10275 case DW_TAG_ptr_to_member_type:
10276 case DW_TAG_set_type:
10277 case DW_TAG_file_type:
10278 case DW_TAG_packed_type:
10279 case DW_TAG_thrown_type:
10280 case DW_TAG_interface_type:
10281 case DW_TAG_shared_type:
10302die_type_name(
const reader& rdr,
10303 const Dwarf_Die* die,
10304 bool qualified_name,
10305 size_t where_offset)
10307 unordered_set<uint64_t> guard;
10308 return die_type_name(rdr, die, qualified_name, where_offset, guard);
10329die_qualified_decl_name(
const reader& rdr,
10330 const Dwarf_Die* die,
10331 size_t where_offset,
10332 unordered_set<uint64_t>& guard)
10334 if (!die || !die_is_decl(die))
10337 string name = die_name(die);
10339 Dwarf_Die scope_die;
10340 if (!get_scope_die(rdr, die, where_offset, scope_die))
10343 string scope_name = die_qualified_name(rdr, &scope_die, where_offset, guard);
10344 string separator =
"::";
10348 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10351 case DW_TAG_namespace:
10352 case DW_TAG_member:
10353 case DW_TAG_variable:
10354 repr = scope_name.empty() ? name : scope_name + separator + name;
10356 case DW_TAG_subprogram:
10357 repr = die_function_signature(rdr, die,
10359 where_offset, guard);
10362 case DW_TAG_unspecified_parameters:
10366 case DW_TAG_formal_parameter:
10367 case DW_TAG_imported_declaration:
10368 case DW_TAG_GNU_template_template_param:
10369 case DW_TAG_GNU_template_parameter_pack:
10370 case DW_TAG_GNU_formal_parameter_pack:
10398die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
10399 size_t where, unordered_set<uint64_t>& guard)
10401 if (die_is_type(die))
10402 return die_qualified_type_name(rdr, die, where, guard);
10403 else if (die_is_decl(die))
10404 return die_qualified_decl_name(rdr, die, where, guard);
10425die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
10427 unordered_set<uint64_t> guard;
10428 return die_qualified_name(rdr, die, where, guard);
10454die_qualified_type_name_empty(
const reader& rdr,
10455 const Dwarf_Die* die,
10456 size_t where,
string &qualified_name,
10457 unordered_set<uint64_t>& guard)
10462 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10465 if (tag == DW_TAG_typedef
10466 || tag == DW_TAG_pointer_type
10467 || tag == DW_TAG_reference_type
10468 || tag == DW_TAG_rvalue_reference_type
10469 || tag == DW_TAG_array_type
10470 || tag == DW_TAG_const_type
10471 || tag == DW_TAG_volatile_type
10472 || tag == DW_TAG_restrict_type)
10474 Dwarf_Die underlying_type_die;
10475 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
10478 die_qualified_type_name(rdr, &underlying_type_die, where, guard);
10485 string name = die_qualified_type_name(rdr, die, where, guard);
10490 qname = die_qualified_type_name(rdr, die, where, guard);
10494 qualified_name = qname;
10546die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
10547 const Dwarf_Die* die,
10548 size_t where_offset,
10550 bool qualified_name,
10552 string &return_type_name,
10553 string &class_name,
10554 vector<string>& parm_names,
10557 unordered_set<uint64_t>& guard)
10559 uint64_t off = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
10560 if (guard.find(off) != guard.end())
10565 Dwarf_Die ret_type_die;
10566 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
10567 return_type_name =
"void";
10572 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset, guard)
10573 : die_type_name(rdr, &ret_type_die, qualified_name,
10574 where_offset, guard);
10577 if (return_type_name.empty())
10578 return_type_name =
"void";
10580 Dwarf_Die object_pointer_die, class_die;
10582 die_function_type_is_method_type(rdr, die, where_offset,
10583 object_pointer_die,
10584 class_die, is_static);
10590 class_name = die_type_name(rdr, &class_die, qualified_name,
10591 where_offset, guard);
10593 Dwarf_Die this_pointer_die;
10594 Dwarf_Die pointed_to_die;
10596 && die_die_attribute(&object_pointer_die, DW_AT_type,
10598 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
10599 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
10602 string fn_name = die_name(die);
10603 string non_qualified_class_name = die_name(&class_die);
10604 bool is_ctor = fn_name == non_qualified_class_name;
10605 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
10607 if (is_ctor || is_dtor)
10608 return_type_name.clear();
10611 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
10614 int child_tag = dwarf_tag(&child);
10615 bool first_parm =
true;
10616 if (child_tag == DW_TAG_formal_parameter)
10621 first_parm =
false;
10625 Dwarf_Die parm_type_die;
10626 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
10630 ? rdr.get_die_pretty_representation(&parm_type_die,
10631 where_offset, guard)
10632 : die_type_name(rdr, &parm_type_die,
10633 qualified_name, where_offset, guard);
10637 parm_names.push_back(qname);
10639 else if (child_tag == DW_TAG_unspecified_parameters)
10642 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
10652 while (dwarf_siblingof(&child, &child) == 0);
10654 if (class_name.empty())
10656 Dwarf_Die parent_die;
10657 if (get_parent_die(rdr, die, parent_die, where_offset))
10659 if (die_is_class_type(&parent_die)
10661 class_name = die_type_name(rdr, &parent_die,
10691die_function_signature(
const reader& rdr,
10692 const Dwarf_Die *fn_die,
10693 bool qualified_name,
10694 size_t where_offset,
10695 unordered_set<uint64_t>& guard)
10699 bool has_lang =
false;
10700 if ((has_lang = get_die_language(fn_die, lang)))
10708 string fn_name = die_linkage_name(fn_die);
10709 if (fn_name.empty())
10710 fn_name = die_name(fn_die);
10720 string return_type_name;
10721 Dwarf_Die ret_type_die;
10722 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
10723 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
10727 if (return_type_name.empty())
10728 return_type_name =
"void";
10730 Dwarf_Die scope_die;
10732 if (qualified_name && get_scope_die(rdr, fn_die, where_offset, scope_die))
10733 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset, guard);
10734 string fn_name = die_name(fn_die);
10735 if (!scope_name.empty())
10736 fn_name = scope_name +
"::" + fn_name;
10739 vector<string> parm_names;
10740 bool is_const =
false;
10741 bool is_static =
false;
10744 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
10747 return_type_name, class_name,
10748 parm_names, is_const, is_static,
10751 bool is_virtual = die_is_virtual(fn_die);
10755 repr +=
" virtual";
10757 if (!return_type_name.empty())
10758 repr +=
" " + return_type_name;
10760 repr +=
" " + fn_name;
10764 bool some_parm_emitted =
false;
10765 for (vector<string>::const_iterator i = parm_names.begin();
10766 i != parm_names.end();
10769 if (i != parm_names.begin())
10771 if (some_parm_emitted)
10780 some_parm_emitted =
true;
10825die_class_flat_representation(
const reader& rdr,
10826 const Dwarf_Die* die,
10827 const string& indent,
10829 bool qualified_names,
10830 size_t where_offset,
10831 unordered_set<uint64_t>& guard)
10833 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10835 string repr = indent;
10836 string local_indent =
" ";
10837 string real_indent;
10839 if (tag == DW_TAG_union_type)
10841 else if (tag == DW_TAG_structure_type)
10843 else if (tag == DW_TAG_class_type)
10850 if (die_is_anonymous(die))
10852 uint64_t off = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
10853 if (guard.find(off) != guard.end())
10861 if (!die_is_anonymous(die))
10862 repr += die_qualified_name(rdr, die, where_offset, guard);
10869 Dwarf_Die member_child_die;
10870 bool first_sibling =
true;
10871 for (
bool got_it = get_member_child_die(die, &member_child_die);
10873 got_it = get_next_member_sibling_die(&member_child_die,
10874 &member_child_die),
10875 first_sibling =
false)
10879 if (!die_is_decl(&member_child_die)
10880 && !(die_is_type(&member_child_die)
10881 && die_is_anonymous(&member_child_die)))
10885 real_indent = first_sibling ?
"" :
" " ;
10887 real_indent = (first_sibling ?
"":
"\n") + indent + local_indent;
10889 repr += real_indent;
10891 repr += die_pretty_print_decl(rdr, &member_child_die,
10902 repr += indent +
"}";
10904 if (die_is_anonymous(die))
10906 uint64_t off = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
10938die_enum_flat_representation(
const reader& rdr,
10939 const Dwarf_Die* die,
10940 const string& indent,
10942 bool qualified_names,
10943 size_t where_offset)
10945 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10947 std::ostringstream o;
10948 string local_indent =
" ";
10949 string real_indent;
10951 if (tag == DW_TAG_enumeration_type)
10958 if (!die_is_anonymous(die))
10959 o << (qualified_names
10960 ? die_qualified_name(rdr, die, where_offset)
10970 bool first_enumerator=
true;
10971 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
10975 if (dwarf_tag(&child) != DW_TAG_enumerator)
10980 die_loc_and_name(rdr, &child, l, name, m);
10982 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
10985 real_indent = first_enumerator ?
"" :
", ";
10987 real_indent = first_enumerator ?
"" :
",\n" + indent + local_indent;
10988 o << name +
" = " << val;
10989 first_enumerator =
false;
10991 while (dwarf_siblingof(&child, &child) == 0);
10994 o << one_line ? string(
"}") :
"\n" + indent;
11032die_class_or_enum_flat_representation(
const reader& rdr,
11033 const Dwarf_Die* die,
11034 const string& indent,
11036 bool qualified_names,
11037 size_t where_offset,
11038 unordered_set<uint64_t>& guard)
11044 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11048 case DW_TAG_class_type:
11049 case DW_TAG_structure_type:
11050 case DW_TAG_union_type:
11051 result = die_class_flat_representation(rdr, die, indent,
11052 one_line, qualified_names,
11056 case DW_TAG_enumeration_type:
11057 result = die_enum_flat_representation(rdr, die, indent,
11058 one_line, qualified_names,
11095die_class_or_enum_flat_representation(
const reader& rdr,
11096 const Dwarf_Die* die,
11097 const string& indent,
11099 bool qualified_names,
11100 size_t where_offset)
11102 unordered_set<uint64_t> guard;
11103 return die_class_or_enum_flat_representation(rdr, die, indent,
11104 one_line, qualified_names,
11105 where_offset, guard);
11131die_pretty_print_type(
const reader& rdr,
11132 const Dwarf_Die* die,
11133 size_t where_offset,
11134 unordered_set<uint64_t>& guard)
11137 || (!die_is_type(die)
11138 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
11143 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11146 case DW_TAG_string_type:
11155 repr =
"string type";
11157 case DW_TAG_unspecified_type:
11158 case DW_TAG_ptr_to_member_type:
11161 case DW_TAG_namespace:
11162 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset,
11166 case DW_TAG_base_type:
11167 repr = rdr.get_die_qualified_type_name(die, where_offset, guard);
11170 case DW_TAG_typedef:
11172 string qualified_name;
11173 if (!die_qualified_type_name_empty(rdr, die,
11177 repr =
"typedef " + qualified_name;
11181 case DW_TAG_const_type:
11182 case DW_TAG_volatile_type:
11183 case DW_TAG_restrict_type:
11184 case DW_TAG_pointer_type:
11185 case DW_TAG_reference_type:
11186 case DW_TAG_rvalue_reference_type:
11187 repr = rdr.get_die_qualified_type_name(die, where_offset, guard);
11190 case DW_TAG_enumeration_type:
11192 string qualified_name =
11193 rdr.get_die_qualified_type_name(die, where_offset, guard);
11194 repr =
"enum " + qualified_name;
11198 case DW_TAG_structure_type:
11199 case DW_TAG_class_type:
11201 string qualified_name =
11202 rdr.get_die_qualified_type_name(die, where_offset, guard);
11203 repr =
"class " + qualified_name;
11207 case DW_TAG_union_type:
11209 string qualified_name =
11210 rdr.get_die_qualified_type_name(die, where_offset, guard);
11211 repr =
"union " + qualified_name;
11215 case DW_TAG_array_type:
11217 Dwarf_Die element_type_die;
11218 if (!die_die_attribute(die, DW_AT_type, element_type_die))
11220 string element_type_name =
11221 rdr.get_die_qualified_type_name(&element_type_die,
11222 where_offset, guard);
11223 if (element_type_name.empty())
11227 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
11230 repr = element_type_name;
11231 repr += array_type_def::subrange_type::vector_as_string(subranges);
11235 case DW_TAG_subrange_type:
11245 repr += die_qualified_type_name(rdr, die, where_offset, guard);
11249 case DW_TAG_subroutine_type:
11250 case DW_TAG_subprogram:
11252 string return_type_name;
11254 vector<string> parm_names;
11255 bool is_const =
false;
11256 bool is_static =
false;
11258 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
11262 return_type_name, class_name,
11263 parm_names, is_const,
11266 repr =
"function type";
11268 repr =
"method type";
11269 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset, guard);
11273 case DW_TAG_set_type:
11274 case DW_TAG_file_type:
11275 case DW_TAG_packed_type:
11276 case DW_TAG_thrown_type:
11277 case DW_TAG_interface_type:
11278 case DW_TAG_shared_type:
11311die_pretty_print_decl(
const reader& rdr,
11312 const Dwarf_Die* die,
11313 bool qualified_name,
11315 size_t where_offset,
11316 unordered_set<uint64_t>& guard)
11318 if (!die || !die_is_decl(die))
11323 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11326 case DW_TAG_namespace:
11327 repr =
"namespace " + die_qualified_name(rdr, die, where_offset, guard);
11330 case DW_TAG_member:
11331 case DW_TAG_variable:
11333 string type_repr =
"void";
11334 Dwarf_Die type_die;
11335 if (die_die_attribute(die, DW_AT_type, type_die))
11336 type_repr = die_type_name(rdr, &type_die,
11340 repr = (qualified_name
11341 ? die_qualified_name(rdr, die, where_offset, guard)
11347 repr = type_repr +
" " + repr;
11351 case DW_TAG_subprogram:
11353 repr = die_function_signature(rdr, die, qualified_name,
11354 where_offset, guard);
11385die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset,
11386 unordered_set<uint64_t>& guard)
11388 if (die_is_type(die))
11389 return die_pretty_print_type(rdr, die, where_offset, guard);
11390 else if (die_is_decl(die))
11391 return die_pretty_print_decl(rdr, die,
11394 where_offset, guard);
11417compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
11421 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
11422 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11423 if (l_tag != r_tag)
11426 bool result =
false;
11428 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
11431 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
11433 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
11440 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
11450 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
11467at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
11468 const Dwarf_Die *l,
11469 const Dwarf_Die *r)
11471 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
11474 if ((die_is_declaration_only(l) && die_has_no_child(l))
11475 || (die_is_declaration_only(r) && die_has_no_child(r)))
11502compare_as_type_dies(
const reader& rdr,
11503 const Dwarf_Die *l,
11504 const Dwarf_Die *r)
11510 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
11511 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
11512 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11513 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
11521 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11526 uint64_t l_size = 0, r_size = 0;
11527 die_size_in_bits(l, l_size);
11528 die_size_in_bits(r, r_size);
11530 return l_size == r_size;
11545compare_as_decl_and_type_dies(
const reader &rdr,
11546 const Dwarf_Die *l,
11547 const Dwarf_Die *r)
11549 if (!compare_as_decl_dies(l, r)
11550 || !compare_as_type_dies(rdr, l, r))
11572fn_die_equal_by_linkage_name(
const Dwarf_Die *l,
11573 const Dwarf_Die *r)
11581 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
11583 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11586 string lname = die_name(l), rname = die_name(r);
11587 string llinkage_name = die_linkage_name(l),
11588 rlinkage_name = die_linkage_name(r);
11590 if (die_is_in_c_or_cplusplus(l)
11591 && die_is_in_c_or_cplusplus(r))
11593 if (!llinkage_name.empty() && !rlinkage_name.empty())
11594 return llinkage_name == rlinkage_name;
11595 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
11598 return lname == rname;
11601 return (!llinkage_name.empty()
11602 && !rlinkage_name.empty()
11603 && llinkage_name == rlinkage_name);
11635try_canonical_die_comparison(
const reader& rdr,
11636 Dwarf_Off l_offset, Dwarf_Off r_offset,
11638 bool& l_has_canonical_die_offset,
11639 bool& r_has_canonical_die_offset,
11640 Dwarf_Off& l_canonical_die_offset,
11641 Dwarf_Off& r_canonical_die_offset,
11644#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11645 if (rdr.debug_die_canonicalization_is_on_
11646 && !rdr.use_canonical_die_comparison_)
11651 l_has_canonical_die_offset =
11652 (l_canonical_die_offset =
11653 rdr.get_canonical_die_offset(l_offset, l_die_source,
11656 r_has_canonical_die_offset =
11657 (r_canonical_die_offset =
11658 rdr.get_canonical_die_offset(r_offset, r_die_source,
11661 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
11663 result = (l_canonical_die_offset == r_canonical_die_offset);
11670#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11683notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
11687#define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
11688 notify_die_comparison_failed(l, r)
11690#define NOTIFY_DIE_COMPARISON_FAILED(l, r)
11703#define ABG_RETURN(value) \
11706 if ((value) == COMPARISON_RESULT_DIFFERENT) \
11708 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11710 return return_comparison_result(l, r, dies_being_compared, \
11711 value, aggregates_being_compared, \
11712 update_canonical_dies_on_the_fly); \
11723#define ABG_RETURN_FALSE \
11726 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11727 return return_comparison_result(l, r, dies_being_compared, \
11728 COMPARISON_RESULT_DIFFERENT, \
11729 aggregates_being_compared, \
11730 update_canonical_dies_on_the_fly); \
11745#define SET_RESULT_TO_FALSE(result, l , r) \
11748 result = COMPARISON_RESULT_DIFFERENT; \
11749 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11765#define SET_RESULT_TO(result, value, l , r) \
11768 result = (value); \
11769 if (result == COMPARISON_RESULT_DIFFERENT) \
11771 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11775#define RETURN_IF_COMPARISON_CYCLE_DETECTED \
11778 if (aggregates_being_compared.contains(dies_being_compared)) \
11780 result = COMPARISON_RESULT_CYCLE_DETECTED; \
11781 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
11782 ABG_RETURN(result); \
11797get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
11802 bool found_member =
false;
11803 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
11806 found_member = (dwarf_siblingof(member, member) == 0))
11808 int tag = dwarf_tag(member);
11809 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
11813 return found_member;
11830get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
11835 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11837 || tag == DW_TAG_union_type
11838 || tag == DW_TAG_class_type);
11840 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die), child) == 0);
11845 tag = dwarf_tag(child);
11847 if (!(tag == DW_TAG_member
11848 || tag == DW_TAG_inheritance
11849 || tag == DW_TAG_subprogram))
11850 found_child = get_next_member_sibling_die(child, child);
11852 return found_child;
11875maybe_propagate_canonical_type(
const reader& rdr,
11876 const Dwarf_Die* l,
11877 const Dwarf_Die* r)
11879 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
11880 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11882 if (l_tag != r_tag)
11885 if (is_canon_type_to_be_propagated_tag(l_tag))
11886 propagate_canonical_type(rdr, l, r);
11904propagate_canonical_type(
const reader& rdr,
11905 const Dwarf_Die* l,
11906 const Dwarf_Die* r)
11915 const die_source l_source = rdr.get_die_source(l);
11916 const die_source r_source = rdr.get_die_source(r);
11918 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
11919 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
11920 bool l_has_canonical_die_offset =
false;
11921 bool r_has_canonical_die_offset =
false;
11922 Dwarf_Off l_canonical_die_offset = 0;
11923 Dwarf_Off r_canonical_die_offset = 0;
11925 l_has_canonical_die_offset =
11926 (l_canonical_die_offset =
11927 rdr.get_canonical_die_offset(l_offset, l_source,
11930 r_has_canonical_die_offset =
11931 (r_canonical_die_offset =
11932 rdr.get_canonical_die_offset(r_offset, r_source,
11936 if (!l_has_canonical_die_offset
11937 && r_has_canonical_die_offset
11940 && l_source == r_source)
11943 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
11945 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
11946 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
11947 rdr.canonical_propagated_count_++;
11985return_comparison_result(
const Dwarf_Die* l,
11986 const Dwarf_Die* r,
11989 offset_pairs_stack_type& comparison_stack,
11990 bool do_propagate_canonical_type =
true)
11992 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
11994 if (result == COMPARISON_RESULT_EQUAL)
11999 if (do_propagate_canonical_type)
12002 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12008 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
12021 else if (result == COMPARISON_RESULT_UNKNOWN)
12062 if (comparison_stack.is_redundant(cur_dies)
12063 && comparison_stack.vect_.back() == cur_dies)
12067 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12068 comparison_stack.confirm_canonical_propagated_type(cur_dies);
12070 result = COMPARISON_RESULT_EQUAL;
12072 else if (is_canon_type_to_be_propagated_tag(l_tag)
12073 && comparison_stack.vect_.back() == cur_dies)
12078 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
12079 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12083 else if (result == COMPARISON_RESULT_DIFFERENT)
12100 if (comparison_stack.is_redundant(cur_dies)
12101 && comparison_stack.vect_.back() == cur_dies)
12102 comparison_stack.cancel_canonical_propagated_type(cur_dies);
12110 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
12111 result = COMPARISON_RESULT_UNKNOWN;
12112 else if (is_canon_type_to_be_propagated_tag(l_tag)
12113 && !comparison_stack.vect_.empty()
12114 && comparison_stack.vect_.back() == cur_dies)
12119 comparison_stack.erase(cur_dies);
12121 maybe_cache_type_comparison_result(comparison_stack.rdr_,
12122 l_tag, cur_dies, result);
12151compare_dies(
const reader& rdr,
12152 const Dwarf_Die *l,
const Dwarf_Die *r,
12153 offset_pairs_stack_type& aggregates_being_compared,
12154 bool update_canonical_dies_on_the_fly)
12159 const die_source l_die_source = rdr.get_die_source(l);
12160 const die_source r_die_source = rdr.get_die_source(r);
12162 offset_type l_offset =
12165 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
12168 offset_type r_offset =
12171 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
12176 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
12177 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
12179 if (l_tag != r_tag)
12182 if (l_offset == r_offset)
12183 return COMPARISON_RESULT_EQUAL;
12185 if (rdr.leverage_dwarf_factorization()
12186 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
12187 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
12188 if (l_offset != r_offset)
12189 return COMPARISON_RESULT_DIFFERENT;
12192 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
12193 dies_being_compared,
12197 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
12198 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
12202 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
12204 bool canonical_compare_result =
false;
12205 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
12206 l_die_source, r_die_source,
12207 l_has_canonical_die_offset,
12208 r_has_canonical_die_offset,
12209 l_canonical_die_offset,
12210 r_canonical_die_offset,
12211 canonical_compare_result))
12215 (canonical_compare_result
12216 ? COMPARISON_RESULT_EQUAL
12217 : COMPARISON_RESULT_DIFFERENT),
12227 case DW_TAG_base_type:
12228 case DW_TAG_string_type:
12229 case DW_TAG_unspecified_type:
12230 if (!compare_as_decl_and_type_dies(rdr, l, r))
12234 case DW_TAG_typedef:
12235 case DW_TAG_pointer_type:
12236 case DW_TAG_reference_type:
12237 case DW_TAG_rvalue_reference_type:
12238 case DW_TAG_const_type:
12239 case DW_TAG_volatile_type:
12240 case DW_TAG_restrict_type:
12242 if (!compare_as_type_dies(rdr, l, r))
12248 bool from_the_same_tu =
false;
12249 if (!pointer_or_qual_die_of_anonymous_class_type(l)
12250 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
12251 && from_the_same_tu)
12268 Dwarf_Die lu_type_die, ru_type_die;
12269 bool lu_is_void, ru_is_void;
12271 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
12272 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
12274 if (lu_is_void && ru_is_void)
12275 result = COMPARISON_RESULT_EQUAL;
12276 else if (lu_is_void != ru_is_void)
12279 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
12280 aggregates_being_compared,
12281 update_canonical_dies_on_the_fly);
12285 case DW_TAG_enumeration_type:
12286 if (!compare_as_decl_and_type_dies(rdr, l, r))
12291 Dwarf_Die l_enumtor, r_enumtor;
12292 bool found_l_enumtor =
true, found_r_enumtor =
true;
12294 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
12295 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
12297 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
12299 found_l_enumtor && found_r_enumtor;
12300 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
12301 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
12303 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
12304 if ( l_tag != r_tag)
12310 if (l_tag != DW_TAG_enumerator)
12313 uint64_t l_val = 0, r_val = 0;
12314 die_unsigned_constant_attribute(&l_enumtor,
12317 die_unsigned_constant_attribute(&r_enumtor,
12320 if (l_val != r_val)
12326 if (found_l_enumtor != found_r_enumtor )
12331 case DW_TAG_structure_type:
12332 case DW_TAG_union_type:
12333 case DW_TAG_class_type:
12335 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12337 rdr.compare_count_++;
12339 if (!compare_as_decl_and_type_dies(rdr, l, r))
12341 else if (rdr.options().assume_odr_for_cplusplus
12342 && rdr.odr_is_relevant(l)
12343 && rdr.odr_is_relevant(r)
12344 && !die_is_anonymous(l)
12345 && !die_is_anonymous(r))
12346 result = COMPARISON_RESULT_EQUAL;
12349 aggregates_being_compared.add(dies_being_compared);
12351 Dwarf_Die l_member, r_member;
12352 bool found_l_member =
true, found_r_member =
true;
12354 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
12355 for (found_l_member = get_member_child_die(l, &l_member),
12356 found_r_member = get_member_child_die(r, &r_member);
12357 found_l_member && found_r_member;
12358 found_l_member = get_next_member_sibling_die(&l_member,
12360 found_r_member = get_next_member_sibling_die(&r_member,
12363 int l_tag = dwarf_tag(&l_member),
12364 r_tag = dwarf_tag(&r_member);
12366 if (l_tag != r_tag)
12373 || l_tag == DW_TAG_variable
12374 || l_tag == DW_TAG_inheritance
12375 || l_tag == DW_TAG_subprogram);
12378 compare_dies(rdr, &l_member, &r_member,
12379 aggregates_being_compared,
12380 update_canonical_dies_on_the_fly);
12382 if (local_result == COMPARISON_RESULT_UNKNOWN)
12391 result = local_result;
12393 if (local_result == COMPARISON_RESULT_DIFFERENT)
12399 if (found_l_member != found_r_member)
12408 case DW_TAG_array_type:
12410 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12412 aggregates_being_compared.add(dies_being_compared);
12414 rdr.compare_count_++;
12416 Dwarf_Die l_child, r_child;
12417 bool found_l_child, found_r_child;
12418 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
12420 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
12422 found_l_child && found_r_child;
12423 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
12424 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
12426 int l_child_tag = dwarf_tag(&l_child),
12427 r_child_tag = dwarf_tag(&r_child);
12428 if (l_child_tag == DW_TAG_subrange_type
12429 || r_child_tag == DW_TAG_subrange_type)
12431 result = compare_dies(rdr, &l_child, &r_child,
12432 aggregates_being_compared,
12433 update_canonical_dies_on_the_fly);
12441 if (found_l_child != found_r_child)
12444 Dwarf_Die ltype_die, rtype_die;
12445 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
12446 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
12449 result = compare_dies(rdr, <ype_die, &rtype_die,
12450 aggregates_being_compared,
12451 update_canonical_dies_on_the_fly);
12457 case DW_TAG_subrange_type:
12459 uint64_t l_lower_bound = 0, r_lower_bound = 0,
12460 l_upper_bound = 0, r_upper_bound = 0;
12461 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
12462 l_upper_bound_set =
false, r_upper_bound_set =
false;
12464 l_lower_bound_set =
12465 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
12466 r_lower_bound_set =
12467 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
12469 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
12472 uint64_t l_count = 0;
12473 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
12475 l_upper_bound = l_lower_bound + l_count;
12476 l_upper_bound_set =
true;
12482 l_upper_bound_set =
true;
12484 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
12487 uint64_t r_count = 0;
12488 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
12490 r_upper_bound = r_lower_bound + r_count;
12491 r_upper_bound_set =
true;
12497 r_upper_bound_set =
true;
12499 if ((l_lower_bound_set != r_lower_bound_set)
12500 || (l_upper_bound_set != r_upper_bound_set)
12501 || (l_lower_bound != r_lower_bound)
12502 || (l_upper_bound != r_upper_bound))
12507 case DW_TAG_subroutine_type:
12508 case DW_TAG_subprogram:
12510 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12512 aggregates_being_compared.add(dies_being_compared);
12514 rdr.compare_count_++;
12516 if (l_tag == DW_TAG_subprogram
12517 && !fn_die_equal_by_linkage_name(l, r))
12522 else if (l_tag == DW_TAG_subprogram
12523 && die_is_in_c(l) && die_is_in_c(r))
12525 result = COMPARISON_RESULT_EQUAL;
12528 else if (!die_is_in_c(l) && !die_is_in_c(r))
12534 Dwarf_Die l_return_type, r_return_type;
12535 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
12537 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
12539 if (l_return_type_is_void != r_return_type_is_void
12540 || (!l_return_type_is_void
12541 && !compare_dies(rdr,
12542 &l_return_type, &r_return_type,
12543 aggregates_being_compared,
12544 update_canonical_dies_on_the_fly)))
12548 Dwarf_Die l_child, r_child;
12549 bool found_l_child, found_r_child;
12550 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
12552 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
12554 found_l_child && found_r_child;
12555 found_l_child = dwarf_siblingof(&l_child,
12557 found_r_child = dwarf_siblingof(&r_child,
12560 int l_child_tag = dwarf_tag(&l_child);
12561 int r_child_tag = dwarf_tag(&r_child);
12563 COMPARISON_RESULT_EQUAL;
12564 if (l_child_tag != r_child_tag)
12565 local_result = COMPARISON_RESULT_DIFFERENT;
12566 if (l_child_tag == DW_TAG_formal_parameter)
12568 compare_dies(rdr, &l_child, &r_child,
12569 aggregates_being_compared,
12570 update_canonical_dies_on_the_fly);
12571 if (local_result == COMPARISON_RESULT_DIFFERENT)
12573 result = local_result;
12577 if (local_result == COMPARISON_RESULT_UNKNOWN)
12588 result = local_result;
12590 if (found_l_child != found_r_child)
12600 case DW_TAG_formal_parameter:
12602 Dwarf_Die l_type, r_type;
12603 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
12604 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
12605 if (l_type_is_void != r_type_is_void)
12607 else if (!l_type_is_void)
12610 compare_dies(rdr, &l_type, &r_type,
12611 aggregates_being_compared,
12612 update_canonical_dies_on_the_fly);
12618 case DW_TAG_variable:
12619 case DW_TAG_member:
12620 if (compare_as_decl_dies(l, r))
12623 if (l_tag == DW_TAG_member)
12625 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
12626 die_member_offset(rdr, l, l_offset_in_bits);
12627 die_member_offset(rdr, r, r_offset_in_bits);
12628 if (l_offset_in_bits != r_offset_in_bits)
12634 Dwarf_Die l_type, r_type;
12635 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12636 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12638 compare_dies(rdr, &l_type, &r_type,
12639 aggregates_being_compared,
12640 update_canonical_dies_on_the_fly);
12648 case DW_TAG_inheritance:
12650 Dwarf_Die l_type, r_type;
12651 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12652 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12653 result = compare_dies(rdr, &l_type, &r_type,
12654 aggregates_being_compared,
12655 update_canonical_dies_on_the_fly);
12659 uint64_t l_a = 0, r_a = 0;
12660 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
12661 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
12665 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
12666 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
12670 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
12671 die_member_offset(rdr, l, l_offset_in_bits);
12672 die_member_offset(rdr, r, r_offset_in_bits);
12673 if (l_offset_in_bits != r_offset_in_bits)
12678 case DW_TAG_ptr_to_member_type:
12680 bool comp_result =
false;
12681 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
12685 Dwarf_Die l_type, r_type;
12686 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12687 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12688 result = compare_dies(rdr, &l_type, &r_type,
12689 aggregates_being_compared,
12690 update_canonical_dies_on_the_fly);
12694 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
12695 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
12696 result = compare_dies(rdr, &l_type, &r_type,
12697 aggregates_being_compared,
12698 update_canonical_dies_on_the_fly);
12704 case DW_TAG_enumerator:
12705 case DW_TAG_packed_type:
12706 case DW_TAG_set_type:
12707 case DW_TAG_file_type:
12708 case DW_TAG_thrown_type:
12709 case DW_TAG_interface_type:
12710 case DW_TAG_shared_type:
12711 case DW_TAG_compile_unit:
12712 case DW_TAG_namespace:
12713 case DW_TAG_module:
12714 case DW_TAG_constant:
12715 case DW_TAG_partial_unit:
12716 case DW_TAG_imported_unit:
12717 case DW_TAG_dwarf_procedure:
12718 case DW_TAG_imported_declaration:
12719 case DW_TAG_entry_point:
12721 case DW_TAG_lexical_block:
12722 case DW_TAG_unspecified_parameters:
12723 case DW_TAG_variant:
12724 case DW_TAG_common_block:
12725 case DW_TAG_common_inclusion:
12726 case DW_TAG_inlined_subroutine:
12727 case DW_TAG_with_stmt:
12728 case DW_TAG_access_declaration:
12729 case DW_TAG_catch_block:
12730 case DW_TAG_friend:
12731 case DW_TAG_namelist:
12732 case DW_TAG_namelist_item:
12733 case DW_TAG_template_type_parameter:
12734 case DW_TAG_template_value_parameter:
12735 case DW_TAG_try_block:
12736 case DW_TAG_variant_part:
12737 case DW_TAG_imported_module:
12738 case DW_TAG_condition:
12739 case DW_TAG_type_unit:
12740 case DW_TAG_template_alias:
12741 case DW_TAG_lo_user:
12742 case DW_TAG_MIPS_loop:
12743 case DW_TAG_format_label:
12744 case DW_TAG_function_template:
12745 case DW_TAG_class_template:
12746 case DW_TAG_GNU_BINCL:
12747 case DW_TAG_GNU_EINCL:
12748 case DW_TAG_GNU_template_template_param:
12749 case DW_TAG_GNU_template_parameter_pack:
12750 case DW_TAG_GNU_formal_parameter_pack:
12751 case DW_TAG_GNU_call_site:
12752 case DW_TAG_GNU_call_site_parameter:
12753 case DW_TAG_hi_user:
12754#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
12755 if (rdr.debug_die_canonicalization_is_on_)
12782compare_dies(
const reader& rdr,
12783 const Dwarf_Die *l,
12784 const Dwarf_Die *r,
12785 bool update_canonical_dies_on_the_fly)
12787 offset_pairs_stack_type aggregates_being_compared(rdr);
12788 return compare_dies(rdr, l, r, aggregates_being_compared,
12789 update_canonical_dies_on_the_fly);
12811compare_dies_during_canonicalization(reader& rdr,
12812 const Dwarf_Die *l,
12813 const Dwarf_Die *r,
12814 bool update_canonical_dies_on_the_fly)
12816#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
12817 if (rdr.debug_die_canonicalization_is_on_)
12819 bool canonical_equality =
false, structural_equality =
false;
12820 rdr.use_canonical_die_comparison_ =
false;
12821 structural_equality = compare_dies(rdr, l, r,
12823 rdr.use_canonical_die_comparison_ =
true;
12824 canonical_equality = compare_dies(rdr, l, r,
12825 update_canonical_dies_on_the_fly);
12826 if (canonical_equality != structural_equality)
12828 std::cerr <<
"structural & canonical equality different for DIEs: "
12830 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
12831 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
12834 << rdr.get_die_pretty_type_representation(l, 0)
12839 return structural_equality;
12842 return compare_dies(rdr, l, r,
12843 update_canonical_dies_on_the_fly);
12885find_import_unit_point_between_dies(
const reader& rdr,
12886 size_t partial_unit_offset,
12887 Dwarf_Off first_die_offset,
12888 Dwarf_Off first_die_cu_offset,
12890 size_t last_die_offset,
12891 size_t& imported_point_offset)
12894 rdr.tu_die_imported_unit_points_map(source);
12896 tu_die_imported_unit_points_map_type::const_iterator iter =
12897 tu_die_imported_unit_points_map.find(first_die_cu_offset);
12899 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
12902 if (imported_unit_points.empty())
12905 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
12906 imported_unit_points_type::const_iterator e = imported_unit_points.end();
12908 find_lower_bound_in_imported_unit_points(imported_unit_points,
12912 if (last_die_offset !=
static_cast<size_t>(-1))
12913 find_lower_bound_in_imported_unit_points(imported_unit_points,
12917 if (e != imported_unit_points.end())
12919 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
12920 if (i->imported_unit_die_off == partial_unit_offset)
12922 imported_point_offset = i->offset_of_import ;
12926 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
12928 if (find_import_unit_point_between_dies(rdr,
12929 partial_unit_offset,
12930 i->imported_unit_child_off,
12931 i->imported_unit_cu_off,
12932 i->imported_unit_die_source,
12934 imported_point_offset))
12940 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
12941 if (i->imported_unit_die_off == partial_unit_offset)
12943 imported_point_offset = i->offset_of_import ;
12947 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
12949 if (find_import_unit_point_between_dies(rdr,
12950 partial_unit_offset,
12951 i->imported_unit_child_off,
12952 i->imported_unit_cu_off,
12953 i->imported_unit_die_source,
12955 imported_point_offset))
12988find_import_unit_point_before_die(
const reader& rdr,
12989 size_t partial_unit_offset,
12990 size_t where_offset,
12991 size_t& imported_point_offset)
12993 size_t import_point_offset = 0;
12994 Dwarf_Die first_die_of_tu;
12996 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
12997 &first_die_of_tu) != 0)
13000 Dwarf_Die cu_die_memory;
13003 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
13004 &cu_die_memory, 0, 0);
13006 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
13007 dwarf_dieoffset(&first_die_of_tu),
13008 dwarf_dieoffset(cu_die),
13009 PRIMARY_DEBUG_INFO_DIE_SOURCE,
13011 import_point_offset))
13013 imported_point_offset = import_point_offset;
13017 if (import_point_offset)
13019 imported_point_offset = import_point_offset;
13047get_parent_die(
const reader& rdr,
13048 const Dwarf_Die* die,
13049 Dwarf_Die& parent_die,
13050 size_t where_offset)
13054 const die_source source = rdr.get_die_source(die);
13057 offset_offset_map_type::const_iterator i =
13058 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
13065 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
13066 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
13067 i->second, &parent_die));
13069 case ALT_DEBUG_INFO_DIE_SOURCE:
13070 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
13071 i->second, &parent_die));
13073 case TYPE_UNIT_DIE_SOURCE:
13074 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
13075 i->second, &parent_die));
13077 case NO_DEBUG_INFO_DIE_SOURCE:
13078 case NUMBER_OF_DIE_SOURCES:
13082 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
13084 if (where_offset == 0)
13086 parent_die = *rdr.cur_tu_die();
13089 size_t import_point_offset = 0;
13091 find_import_unit_point_before_die(rdr,
13092 dwarf_dieoffset(&parent_die),
13094 import_point_offset);
13100 parent_die = *rdr.cur_tu_die();
13104 Dwarf_Die import_point_die;
13105 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
13106 import_point_offset,
13107 &import_point_die));
13108 return get_parent_die(rdr, &import_point_die,
13109 parent_die, where_offset);
13142get_scope_die(
const reader& rdr,
13143 const Dwarf_Die* dye,
13144 size_t where_offset,
13145 Dwarf_Die& scope_die)
13147 Dwarf_Die origin_die_mem;
13148 Dwarf_Die *die = &origin_die_mem;
13149 if (!die_origin_die(dye, origin_die_mem))
13150 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
13153 get_die_language(die, die_lang);
13155 || rdr.die_parent_map(rdr.get_die_source(die)).empty())
13157 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
13158 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
13161 if (!get_parent_die(rdr, die, scope_die, where_offset))
13164 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
13165 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
13166 || dwarf_tag(&scope_die) == DW_TAG_array_type)
13167 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
13197get_scope_for_die(reader& rdr,
13199 bool called_for_public_decl,
13200 size_t where_offset)
13202 Dwarf_Die origin_die_mem;
13203 Dwarf_Die *die = &origin_die_mem;
13205 if (!die_origin_die(dye, origin_die_mem))
13208 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
13210 const die_source source_of_die = rdr.get_die_source(die);
13213 get_die_language(die, die_lang);
13215 || rdr.die_parent_map(source_of_die).empty())
13220 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
13221 return rdr.global_scope();
13224 Dwarf_Die parent_die;
13226 if (!get_parent_die(rdr, die, parent_die, where_offset))
13227 return rdr.nil_scope();
13229 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
13230 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
13231 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
13233 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
13234 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
13236 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
13237 || source_of_die == TYPE_UNIT_DIE_SOURCE);
13238 return rdr.cur_transl_unit()->get_global_scope();
13247 die_tu_map_type::const_iterator i =
13248 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
13249 if (i != rdr.die_tu_map().end())
13250 return i->second->get_global_scope();
13251 return rdr.cur_transl_unit()->get_global_scope();
13256 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
13257 || dwarf_tag(&parent_die) == DW_TAG_array_type
13258 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
13270 called_for_public_decl,
13279 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
13280 return rdr.nil_scope();
13281 s = get_scope_for_die(rdr, &parent_die,
13282 called_for_public_decl,
13288 d = build_ir_node_from_die(rdr, &parent_die,
13289 called_for_public_decl,
13291 s = dynamic_pointer_cast<scope_decl>(d);
13295 return rdr.nil_scope();
13298 if (cl && cl->get_is_declaration_only())
13301 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
13318dwarf_language_to_tu_language(
size_t l)
13323 return translation_unit::LANG_C89;
13325 return translation_unit::LANG_C;
13326 case DW_LANG_Ada83:
13327 return translation_unit::LANG_Ada83;
13328 case DW_LANG_C_plus_plus:
13329 return translation_unit::LANG_C_plus_plus;
13330 case DW_LANG_Cobol74:
13331 return translation_unit::LANG_Cobol74;
13332 case DW_LANG_Cobol85:
13333 return translation_unit::LANG_Cobol85;
13334 case DW_LANG_Fortran77:
13335 return translation_unit::LANG_Fortran77;
13336 case DW_LANG_Fortran90:
13337 return translation_unit::LANG_Fortran90;
13338 case DW_LANG_Pascal83:
13339 return translation_unit::LANG_Pascal83;
13340 case DW_LANG_Modula2:
13341 return translation_unit::LANG_Modula2;
13343 return translation_unit::LANG_Java;
13345 return translation_unit::LANG_C99;
13346 case DW_LANG_Ada95:
13347 return translation_unit::LANG_Ada95;
13348 case DW_LANG_Fortran95:
13349 return translation_unit::LANG_Fortran95;
13351 return translation_unit::LANG_PLI;
13353 return translation_unit::LANG_ObjC;
13354 case DW_LANG_ObjC_plus_plus:
13355 return translation_unit::LANG_ObjC_plus_plus;
13357#ifdef HAVE_DW_LANG_Rust_enumerator
13359 return translation_unit::LANG_Rust;
13362#ifdef HAVE_DW_LANG_UPC_enumerator
13364 return translation_unit::LANG_UPC;
13367#ifdef HAVE_DW_LANG_D_enumerator
13369 return translation_unit::LANG_D;
13372#ifdef HAVE_DW_LANG_Python_enumerator
13373 case DW_LANG_Python:
13374 return translation_unit::LANG_Python;
13377#ifdef HAVE_DW_LANG_Go_enumerator
13379 return translation_unit::LANG_Go;
13382#ifdef HAVE_DW_LANG_C11_enumerator
13384 return translation_unit::LANG_C11;
13387#ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
13388 case DW_LANG_C_plus_plus_03:
13389 return translation_unit::LANG_C_plus_plus_03;
13392#ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
13393 case DW_LANG_C_plus_plus_11:
13394 return translation_unit::LANG_C_plus_plus_11;
13397#ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
13398 case DW_LANG_C_plus_plus_14:
13399 return translation_unit::LANG_C_plus_plus_14;
13402#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
13403 case DW_LANG_Mips_Assembler:
13404 return translation_unit::LANG_Mips_Assembler;
13408 return translation_unit::LANG_UNKNOWN;
13425 case translation_unit::LANG_UNKNOWN:
13428 case translation_unit::LANG_Cobol74:
13429 case translation_unit::LANG_Cobol85:
13432 case translation_unit::LANG_C89:
13433 case translation_unit::LANG_C99:
13434 case translation_unit::LANG_C11:
13435 case translation_unit::LANG_C:
13436 case translation_unit::LANG_C_plus_plus_03:
13437 case translation_unit::LANG_C_plus_plus_11:
13438 case translation_unit::LANG_C_plus_plus_14:
13439 case translation_unit::LANG_C_plus_plus:
13440 case translation_unit::LANG_ObjC:
13441 case translation_unit::LANG_ObjC_plus_plus:
13442 case translation_unit::LANG_Rust:
13445 case translation_unit::LANG_Fortran77:
13446 case translation_unit::LANG_Fortran90:
13447 case translation_unit::LANG_Fortran95:
13448 case translation_unit::LANG_Ada83:
13449 case translation_unit::LANG_Ada95:
13450 case translation_unit::LANG_Pascal83:
13451 case translation_unit::LANG_Modula2:
13454 case translation_unit::LANG_Java:
13457 case translation_unit::LANG_PLI:
13460 case translation_unit::LANG_UPC:
13461 case translation_unit::LANG_D:
13462 case translation_unit::LANG_Python:
13463 case translation_unit::LANG_Go:
13464 case translation_unit::LANG_Mips_Assembler:
13491 imported_unit_points_type::const_iterator& r)
13493 imported_unit_point v(val);
13494 imported_unit_points_type::const_iterator result =
13495 std::lower_bound(p.begin(), p.end(), v);
13497 bool is_ok = result != p.end();
13519build_translation_unit_and_add_to_ir(reader& rdr,
13527 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
13531 rdr.clear_per_translation_unit_data();
13533 rdr.cur_tu_die(die);
13535 string path = die_string_attribute(die, DW_AT_name);
13536 if (path ==
"<artificial>")
13542 std::ostringstream o;
13543 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
13546 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
13556 const string& abs_path =
13557 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
13558 result = rdr.corpus()->find_translation_unit(abs_path);
13563 result.reset(
new translation_unit(rdr.env(),
13566 result->set_compilation_dir_path(compilation_dir);
13567 rdr.corpus()->add(result);
13569 die_unsigned_constant_attribute(die, DW_AT_language, l);
13570 result->set_language(dwarf_language_to_tu_language(l));
13573 rdr.cur_transl_unit(result);
13574 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
13577 if (dwarf_child(die, &child) != 0)
13580 result->set_is_constructed(
false);
13581 int tag = dwarf_tag(&child);
13583 if (rdr.load_undefined_interfaces()
13584 && (rdr.is_decl_die_with_undefined_symbol(&child)
13585 || tag == DW_TAG_class_type
13590 || ((tag == DW_TAG_union_type || tag == DW_TAG_structure_type)
13591 && die_is_in_cplus_plus(&child))))
13595 build_ir_node_from_die(rdr, &child,
13600 dwarf_dieoffset(&child));
13602 else if (!rdr.env().analyze_exported_interfaces_only()
13603 || rdr.is_decl_die_with_exported_symbol(&child))
13607 build_ir_node_from_die(rdr, &child,
13608 die_is_public_decl(&child),
13609 dwarf_dieoffset(&child));
13611 while (dwarf_siblingof(&child, &child) == 0);
13613 if (!rdr.var_decls_to_re_add_to_tree().empty())
13614 for (list<var_decl_sptr>::const_iterator v =
13615 rdr.var_decls_to_re_add_to_tree().begin();
13616 v != rdr.var_decls_to_re_add_to_tree().end();
13623 string demangled_name =
13625 if (!demangled_name.empty())
13627 std::list<string> fqn_comps;
13629 string mem_name = fqn_comps.back();
13630 fqn_comps.pop_back();
13633 if (!fqn_comps.empty())
13661 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
13667 rdr.var_decls_to_re_add_to_tree().clear();
13669 result->set_is_constructed(
true);
13694build_namespace_decl_and_add_to_ir(reader& rdr,
13696 size_t where_offset)
13703 unsigned tag = dwarf_tag(die);
13704 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
13711 string name, linkage_name;
13713 die_loc_and_name(rdr, die, loc, name, linkage_name);
13715 result.reset(
new namespace_decl(rdr.env(), name, loc));
13717 rdr.associate_die_to_decl(die, result, where_offset);
13720 if (dwarf_child(die, &child) != 0)
13723 rdr.scope_stack().push(result.get());
13725 build_ir_node_from_die(rdr, &child,
13731 die_is_public_decl(die) && die_is_public_decl(&child),
13733 while (dwarf_siblingof(&child, &child) == 0);
13734 rdr.scope_stack().pop();
13749build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
13755 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
13757 uint64_t byte_size = 0, bit_size = 0;
13758 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
13759 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
13762 if (bit_size == 0 && byte_size != 0)
13764 bit_size = byte_size * 8;
13766 string type_name, linkage_name;
13768 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
13770 if (byte_size == 0)
13774 if (type_name ==
"void")
13775 result =
is_type_decl(build_ir_node_for_void_type(rdr));
13782 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13784 string normalized_type_name = type_name;
13785 real_type real_type;
13787 normalized_type_name = real_type.
to_string();
13792 if (corpus_sptr corp = rdr.corpus())
13795 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
13796 0, loc, linkage_name));
13797 rdr.associate_die_to_type(die, result, where_offset);
13815build_enum_underlying_type(reader& rdr,
13817 uint64_t enum_size,
13818 bool is_anonymous =
true)
13820 string underlying_type_name =
13824 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
13825 enum_size, enum_size, location()));
13826 result->set_is_anonymous(is_anonymous);
13827 result->set_is_artificial(
true);
13830 result = dynamic_pointer_cast<type_decl>(d);
13832 maybe_canonicalize_type(result, rdr);
13851build_enum_type(reader& rdr,
13854 size_t where_offset,
13855 bool is_declaration_only)
13861 unsigned tag = dwarf_tag(die);
13862 if (tag != DW_TAG_enumeration_type)
13865 string name, linkage_name;
13867 die_loc_and_name(rdr, die, loc, name, linkage_name);
13869 bool is_anonymous =
false;
13873 name = get_internal_anonymous_die_prefix_name(die);
13876 is_anonymous =
true;
13878 scope_decl* sc = scope ? scope : rdr.global_scope().get();
13879 if (
size_t s = sc->get_num_anonymous_member_enums())
13880 name = build_internal_anonymous_die_name(name, s);
13883 bool use_odr = rdr.odr_is_relevant(die);
13895 result = pre_existing_enum;
13897 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13906 if (pre_existing_enum->get_location() == loc)
13907 result = pre_existing_enum;
13912 rdr.associate_die_to_type(die, result, where_offset);
13920 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13922 bool is_artificial = die_is_artificial(die);
13925 bool enum_underlying_type_is_anonymous=
true;
13929 if (dwarf_child(die, &child) == 0)
13933 if (dwarf_tag(&child) != DW_TAG_enumerator)
13938 die_loc_and_name(rdr, &child, l, n, m);
13940 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
13941 enms.push_back(enum_type_decl::enumerator(n, val));
13943 while (dwarf_siblingof(&child, &child) == 0);
13951 build_enum_underlying_type(rdr, name, size,
13952 enum_underlying_type_is_anonymous);
13953 t->set_is_declaration_only(is_declaration_only);
13955 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
13956 result->set_is_anonymous(is_anonymous);
13957 result->set_is_declaration_only(is_declaration_only);
13958 result->set_is_artificial(is_artificial);
13959 rdr.associate_die_to_type(die, result, where_offset);
13978finish_member_function_reading(Dwarf_Die* die,
13980 const class_or_union_sptr klass,
13991 size_t is_inline = die_is_declared_inline(die);
13992 bool is_ctor = (f->get_name() == klass->get_name());
13993 bool is_dtor = (!f->get_name().empty()
13994 &&
static_cast<string>(f->get_name())[0] ==
'~');
13995 bool is_virtual = die_is_virtual(die);
13996 int64_t vindex = -1;
13998 die_virtual_function_index(die, vindex);
14001 if (!c->is_struct())
14002 access = private_access;
14003 die_access_specifier(die, access);
14005 m->is_declared_inline(is_inline);
14009 bool is_static = method_t->get_is_for_static_method();
14017 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol()
14037 Dwarf_Off die_offset = dwarf_dieoffset(die);
14039 rdr.die_function_decl_with_no_symbol_map();
14040 die_function_decl_map_type::const_iterator i =
14041 fns_with_no_symbol.find(die_offset);
14042 if (i == fns_with_no_symbol.end())
14043 fns_with_no_symbol[die_offset] = f;
14064maybe_finish_function_decl_reading(reader& rdr,
14066 size_t where_offset,
14084static type_base_sptr
14085lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
14088 corpus* corp = scope->get_corpus();
14109static type_base_sptr
14110lookup_class_or_typedef_from_corpus(reader& rdr,
14112 bool called_for_public_decl,
14113 size_t where_offset)
14118 string class_name = die_string_attribute(die, DW_AT_name);
14119 if (class_name.empty())
14123 called_for_public_decl,
14126 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
14128 return type_base_sptr();
14145static method_decl_sptr
14146is_function_for_die_a_member_of_class(reader& rdr,
14147 Dwarf_Die* function_die,
14148 const class_or_union_sptr& class_type)
14153 return method_decl_sptr();
14159 method_type = method->get_type();
14164 class_or_union_sptr method_class = method_type->get_class_type();
14167 string method_class_name = method_class->get_qualified_name(),
14168 class_type_name = class_type->get_qualified_name();
14170 if (method_class_name == class_type_name)
14176 return method_decl_sptr();
14198static method_decl_sptr
14199add_or_update_member_function(reader& rdr,
14200 Dwarf_Die* function_die,
14201 const class_or_union_sptr& class_type,
14202 bool called_from_public_decl,
14203 size_t where_offset)
14205 method_decl_sptr method =
14206 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
14209 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
14211 called_from_public_decl,
14214 return method_decl_sptr();
14216 finish_member_function_reading(function_die,
14259add_or_update_class_type(reader& rdr,
14264 bool called_from_public_decl,
14265 size_t where_offset,
14266 bool is_declaration_only)
14272 const die_source source = rdr.get_die_source(die);
14274 unsigned tag = dwarf_tag(die);
14276 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
14280 die_class_or_union_map_type::const_iterator i =
14281 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14282 if (i != rdr.die_wip_classes_map(source).end())
14290 string name, linkage_name;
14292 die_loc_and_name(rdr, die, loc, name, linkage_name);
14294 bool is_anonymous =
false;
14299 name = get_internal_anonymous_die_prefix_name(die);
14302 is_anonymous =
true;
14306 s = scope->get_num_anonymous_member_classes();
14308 s = rdr.global_scope()->get_num_anonymous_member_classes();
14309 name = build_internal_anonymous_die_name(name, s);
14314 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14330 && (result->get_is_declaration_only() == is_declaration_only
14331 || (!result->get_is_declaration_only()
14332 && is_declaration_only)))
14334 rdr.associate_die_to_type(die, result, where_offset);
14353 klass = pre_existing_class;
14356 die_size_in_bits(die, size);
14357 bool is_artificial = die_is_artificial(die);
14360 bool has_child = (dwarf_child(die, &child) == 0);
14362 decl_base_sptr res;
14365 res = result = klass;
14366 if (has_child && klass->get_is_declaration_only()
14367 && klass->get_definition_of_declaration())
14368 res = result =
is_class_type(klass->get_definition_of_declaration());
14370 result->set_location(loc);
14374 result.reset(
new class_decl(rdr.env(), name, size,
14376 decl_base::VISIBILITY_DEFAULT,
14379 result->set_is_declaration_only(is_declaration_only);
14382 result = dynamic_pointer_cast<class_decl>(res);
14386 if (!klass || klass->get_is_declaration_only())
14387 if (size != result->get_size_in_bits())
14388 result->set_size_in_bits(size);
14393 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
14406 result->set_is_declaration_only(is_declaration_only);
14410 if (!result->get_is_declaration_only() && has_child)
14411 if (result->get_size_in_bits() == 0 && size != 0)
14412 result->set_size_in_bits(size);
14414 result->set_is_artificial(is_artificial);
14416 rdr.associate_die_to_type(die, result, where_offset);
14423 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
14425 bool is_incomplete_type =
false;
14426 if (is_declaration_only && size == 0 && has_child)
14438 is_incomplete_type =
true;
14441 dynamic_pointer_cast<scope_decl>(res);
14443 rdr.scope_stack().push(scop.get());
14445 if (has_child && !is_incomplete_type)
14449 tag = dwarf_tag(&child);
14452 if (tag == DW_TAG_inheritance)
14454 result->set_is_declaration_only(
false);
14456 Dwarf_Die type_die;
14457 if (!die_die_attribute(&child, DW_AT_type, type_die))
14460 string type_name = die_type_name(rdr, &type_die,
14463 type_base_sptr base_type;
14464 if (!type_name.empty())
14466 base_type = result->find_base_class(type_name);
14472 lookup_class_or_typedef_from_corpus(rdr, &type_die,
14473 called_from_public_decl,
14477 is_type(build_ir_node_from_die(rdr, &type_die,
14478 called_from_public_decl,
14492 die_access_specifier(&child, access);
14494 bool is_virt= die_is_virtual(&child);
14495 int64_t offset = 0;
14496 bool is_offset_present =
14497 die_member_offset(rdr, &child, offset);
14501 is_offset_present ? offset : -1,
14503 if (b->get_is_declaration_only()
14510 && !b->get_qualified_name().empty())
14511 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
14512 if (result->find_base_class(b->get_qualified_name()))
14514 result->add_base_specifier(base);
14517 else if (tag == DW_TAG_member
14518 || tag == DW_TAG_variable)
14520 Dwarf_Die type_die;
14521 if (!die_die_attribute(&child, DW_AT_type, type_die))
14526 die_loc_and_name(rdr, &child, loc, n, m);
14531 if (n.substr(0, 5) ==
"_vptr"
14533 && !std::isalnum(n.at(5))
14543 int64_t offset_in_bits = 0;
14544 bool is_laid_out = die_member_offset(rdr, &child,
14549 bool is_static = !is_laid_out;
14565 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
14566 called_from_public_decl,
14568 type_base_sptr t =
is_type(ty);
14572 if (n.empty() && !die_is_anonymous_data_member(&child))
14578 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
14595 result->set_is_declaration_only(
false);
14601 die_access_specifier(&child, access);
14609 result->add_data_member(dm, access, is_laid_out,
14610 is_static, offset_in_bits);
14612 rdr.associate_die_to_decl(&child, dm, where_offset,
14616 else if (tag == DW_TAG_subprogram)
14619 add_or_update_member_function(rdr, &child, result,
14620 called_from_public_decl,
14623 rdr.associate_die_to_decl(&child, f, where_offset,
14627 else if (die_is_type(&child))
14632 && !result->find_member_type(die_name(&child)))
14633 build_ir_node_from_die(rdr, &child, result.get(),
14634 called_from_public_decl,
14641 string anonymous_type_name =
14642 die_class_or_enum_flat_representation(rdr, &child,
14647 if (type_base_sptr member_t =
14648 result->find_member_type(anonymous_type_name))
14649 rdr.associate_die_to_decl(&child,
is_decl(member_t),
14655 is_type(build_ir_node_from_die(rdr, &child,
14657 called_from_public_decl,
14662 maybe_set_member_type_access_specifier(result,
14668 }
while (dwarf_siblingof(&child, &child) == 0);
14671 rdr.scope_stack().pop();
14674 die_class_or_union_map_type::const_iterator i =
14675 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14676 if (i != rdr.die_wip_classes_map(source).end())
14681 rdr.die_wip_classes_map(source).erase(i);
14712static union_decl_sptr
14713add_or_update_union_type(reader& rdr,
14716 union_decl_sptr union_type,
14717 bool called_from_public_decl,
14718 size_t where_offset,
14719 bool is_declaration_only)
14721 union_decl_sptr result;
14725 unsigned tag = dwarf_tag(die);
14727 if (tag != DW_TAG_union_type)
14730 const die_source source = rdr.get_die_source(die);
14732 die_class_or_union_map_type::const_iterator i =
14733 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14734 if (i != rdr.die_wip_classes_map(source).end())
14742 string name, linkage_name;
14744 die_loc_and_name(rdr, die, loc, name, linkage_name);
14746 bool is_anonymous =
false;
14751 name = get_internal_anonymous_die_prefix_name(die);
14754 is_anonymous =
true;
14758 s = scope->get_num_anonymous_member_unions();
14760 s = rdr.global_scope()->get_num_anonymous_member_classes();
14761 name = build_internal_anonymous_die_name(name, s);
14771 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14780 rdr.associate_die_to_type(die, result, where_offset);
14792 if (union_decl_sptr pre_existing_union =
14794 union_type = pre_existing_union;
14797 die_size_in_bits(die, size);
14798 bool is_artificial = die_is_artificial(die);
14802 result = union_type;
14803 result->set_location(loc);
14807 result.reset(
new union_decl(rdr.env(), name, size, loc,
14808 decl_base::VISIBILITY_DEFAULT,
14810 if (is_declaration_only)
14811 result->set_is_declaration_only(
true);
14818 result->set_size_in_bits(size);
14819 result->set_is_declaration_only(
false);
14822 result->set_is_artificial(is_artificial);
14824 rdr.associate_die_to_type(die, result, where_offset);
14827 bool has_child = (dwarf_child(die, &child) == 0);
14831 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
14834 dynamic_pointer_cast<scope_decl>(result);
14836 rdr.scope_stack().push(scop.get());
14842 tag = dwarf_tag(&child);
14844 if (tag == DW_TAG_member || tag == DW_TAG_variable)
14846 Dwarf_Die type_die;
14847 if (!die_die_attribute(&child, DW_AT_type, type_die))
14852 die_loc_and_name(rdr, &child, loc, n, m);
14861 ssize_t offset_in_bits = 0;
14862 decl_base_sptr ty =
14863 is_decl(build_ir_node_from_die(rdr, &type_die,
14864 called_from_public_decl,
14866 type_base_sptr t =
is_type(ty);
14873 result->set_is_declaration_only(
false);
14876 die_access_specifier(&child, access);
14882 if (n.empty() && result->find_data_member(dm))
14888 result->add_data_member(dm, access,
true,
14892 rdr.associate_die_to_decl(&child, dm, where_offset,
14896 else if (tag == DW_TAG_subprogram)
14899 is_decl(build_ir_node_from_die(rdr, &child,
14901 called_from_public_decl,
14909 finish_member_function_reading(&child, f, result, rdr);
14911 rdr.associate_die_to_decl(&child, f, where_offset,
14915 else if (die_is_type(&child))
14917 string type_name = die_type_name(rdr, &child,
14920 if (type_base_sptr member_t = result->find_member_type(type_name))
14921 rdr.associate_die_to_decl(&child,
is_decl(member_t),
14925 decl_base_sptr td =
14926 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
14927 called_from_public_decl,
14930 }
while (dwarf_siblingof(&child, &child) == 0);
14933 rdr.scope_stack().pop();
14936 die_class_or_union_map_type::const_iterator i =
14937 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14938 if (i != rdr.die_wip_classes_map(source).end())
14943 rdr.die_wip_classes_map(source).erase(i);
14967static type_base_sptr
14968build_qualified_type(reader& rdr,
14970 bool called_from_public_decl,
14971 size_t where_offset)
14973 type_base_sptr result;
14977 unsigned tag = dwarf_tag(die);
14979 if (tag != DW_TAG_const_type
14980 && tag != DW_TAG_volatile_type
14981 && tag != DW_TAG_restrict_type)
14984 Dwarf_Die underlying_type_die;
14985 decl_base_sptr utype_decl;
14986 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14990 utype_decl = build_ir_node_for_void_type(rdr);
14993 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
14994 called_from_public_decl,
15001 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15004 rdr.associate_die_to_type(die, result, where_offset);
15008 type_base_sptr utype =
is_type(utype_decl);
15012 if (tag == DW_TAG_const_type)
15013 qual |= qualified_type_def::CV_CONST;
15014 else if (tag == DW_TAG_volatile_type)
15015 qual |= qualified_type_def::CV_VOLATILE;
15016 else if (tag == DW_TAG_restrict_type)
15017 qual |= qualified_type_def::CV_RESTRICT;
15022 result.reset(
new qualified_type_def(utype, qual, location()));
15024 rdr.associate_die_to_type(die, result, where_offset);
15042schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
15047 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
15049 rdr.schedule_type_for_late_canonicalization(t);
15053 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
15055 rdr.schedule_type_for_late_canonicalization(t);
15059 for (vector<array_type_def::subrange_sptr>::const_iterator i =
15060 type->get_subranges().begin();
15061 i != type->get_subranges().end();
15064 if (!(*i)->get_scope())
15066 rdr.schedule_type_for_late_canonicalization(*i);
15069 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
15071 rdr.schedule_type_for_late_canonicalization(type);
15090static decl_base_sptr
15091maybe_strip_qualification(
const qualified_type_def_sptr t,
15097 decl_base_sptr result = t;
15098 type_base_sptr u = t->get_underlying_type();
15102 if (result.get() != t.get())
15108 scope_decl * scope = 0;
15111 scope = array->get_scope();
15114 schedule_array_tree_for_late_canonicalization(array, rdr);
15116 t->set_underlying_type(array);
15117 u = t->get_underlying_type();
15125 schedule_array_tree_for_late_canonicalization(typdef, rdr);
15128 t->set_underlying_type(typdef);
15129 u = t->get_underlying_type();
15138 type_base_sptr element_type = array->get_element_type();
15143 ABG_ASSERT(!qualified->get_canonical_type());
15145 quals |= t->get_cv_quals();
15146 qualified->set_cv_quals(quals);
15152 qualified_type_def_sptr qual_type
15153 (
new qualified_type_def(element_type,
15155 t->get_location()));
15158 array->set_element_type(qual_type);
15159 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
15184build_pointer_type_def(reader& rdr,
15186 bool called_from_public_decl,
15187 size_t where_offset)
15194 unsigned tag = dwarf_tag(die);
15195 if (tag != DW_TAG_pointer_type)
15199 Dwarf_Die underlying_type_die;
15200 bool has_underlying_type_die =
false;
15201 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15204 utype_decl = build_ir_node_for_void_type(rdr);
15206 has_underlying_type_die =
true;
15208 if (!utype_decl && has_underlying_type_die)
15209 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
15210 called_from_public_decl,
15217 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15224 type_base_sptr utype =
is_type(utype_decl);
15230 uint64_t size = rdr.cur_transl_unit()->get_address_size();
15231 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
15238 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
15240 result.reset(
new pointer_type_def(utype, size, 0, location()));
15246 rdr.associate_die_to_type(die, result, where_offset);
15268build_reference_type(reader& rdr,
15270 bool called_from_public_decl,
15271 size_t where_offset)
15278 unsigned tag = dwarf_tag(die);
15279 if (tag != DW_TAG_reference_type
15280 && tag != DW_TAG_rvalue_reference_type)
15283 Dwarf_Die underlying_type_die;
15284 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15288 build_ir_node_from_die(rdr, &underlying_type_die,
15289 called_from_public_decl,
15296 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15303 type_base_sptr utype =
is_type(utype_decl);
15309 uint64_t size = rdr.cur_transl_unit()->get_address_size();
15310 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
15315 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
15317 bool is_lvalue = tag == DW_TAG_reference_type;
15319 result.reset(
new reference_type_def(utype, is_lvalue, size,
15322 if (corpus_sptr corp = rdr.corpus())
15325 rdr.associate_die_to_type(die, result, where_offset);
15348build_ptr_to_mbr_type(reader& rdr,
15350 bool called_from_public_decl,
15351 size_t where_offset)
15358 unsigned tag = dwarf_tag(die);
15359 if (tag != DW_TAG_ptr_to_member_type)
15362 Dwarf_Die data_member_type_die, containing_type_die;
15364 if (!die_die_attribute(die, DW_AT_type, data_member_type_die)
15365 || !die_die_attribute(die, DW_AT_containing_type, containing_type_die))
15369 build_ir_node_from_die(rdr, &data_member_type_die,
15370 called_from_public_decl, where_offset);
15371 if (!data_member_type)
15375 build_ir_node_from_die(rdr, &containing_type_die,
15376 called_from_public_decl, where_offset);
15377 if (!containing_type)
15384 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15391 uint64_t size_in_bits = rdr.cur_transl_unit()->get_address_size();
15393 result.reset(
new ptr_to_mbr_type(data_member_type->get_environment(),
15400 rdr.associate_die_to_type(die, result, where_offset);
15421build_function_type(reader& rdr,
15423 class_or_union_sptr is_method,
15424 size_t where_offset)
15431 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
15432 || dwarf_tag(die) == DW_TAG_subprogram);
15434 const die_source source = rdr.get_die_source(die);
15437 size_t off = dwarf_dieoffset(die);
15438 auto i = rdr.die_wip_function_types_map(source).find(off);
15439 if (i != rdr.die_wip_function_types_map(source).end())
15447 decl_base_sptr type_decl;
15455 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
15459 rdr.associate_die_to_type(die, result, where_offset);
15476 rdr.associate_die_to_type(die, fn_type, where_offset);
15484 bool is_const =
false;
15485 bool is_static =
false;
15486 Dwarf_Die object_pointer_die;
15487 Dwarf_Die class_type_die;
15488 bool has_this_parm_die =
15489 die_function_type_is_method_type(rdr, die, where_offset,
15490 object_pointer_die,
15493 if (has_this_parm_die)
15498 if (die_object_pointer_is_for_const_method(&object_pointer_die))
15506 class_or_union_sptr klass_type =
15517 is_method = klass_type;
15526 result.reset(is_method
15527 ?
new method_type(is_method, is_const,
15528 tu->get_address_size(),
15530 :
new function_type(rdr.env(), tu->get_address_size(),
15532 rdr.associate_die_to_type(die, result, where_offset);
15533 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
15535 type_base_sptr return_type;
15536 Dwarf_Die ret_type_die;
15537 if (die_die_attribute(die, DW_AT_type, ret_type_die))
15539 is_type(build_ir_node_from_die(rdr, &ret_type_die,
15543 return_type =
is_type(build_ir_node_for_void_type(rdr));
15544 result->set_return_type(return_type);
15549 if (dwarf_child(die, &child) == 0)
15552 int child_tag = dwarf_tag(&child);
15553 if (child_tag == DW_TAG_formal_parameter)
15556 string name, linkage_name;
15558 die_loc_and_name(rdr, &child, loc, name, linkage_name);
15563 bool is_artificial = die_is_artificial(&child);
15564 type_base_sptr parm_type;
15565 Dwarf_Die parm_type_die;
15566 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
15568 is_type(build_ir_node_from_die(rdr, &parm_type_die,
15575 && function_parms.empty())
15591 (
new function_decl::parameter(parm_type, name, loc,
15594 function_parms.push_back(p);
15596 else if (child_tag == DW_TAG_unspecified_parameters)
15599 bool is_artificial = die_is_artificial(&child);
15601 type_base_sptr parm_type =
15602 is_type(build_ir_node_for_variadic_parameter_type(rdr));
15604 (
new function_decl::parameter(parm_type,
15609 function_parms.push_back(p);
15619 while (dwarf_siblingof(&child, &child) == 0);
15621 result->set_parameters(function_parms);
15623 tu->bind_function_type_life_time(result);
15625 result->set_is_artificial(
true);
15627 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
15630 die_function_type_map_type::const_iterator i =
15631 rdr.die_wip_function_types_map(source).
15632 find(dwarf_dieoffset(die));
15633 if (i != rdr.die_wip_function_types_map(source).end())
15634 rdr.die_wip_function_types_map(source).erase(i);
15637 maybe_canonicalize_type(result, rdr);
15664build_subrange_type(reader& rdr,
15665 const Dwarf_Die* die,
15666 size_t where_offset,
15667 bool associate_type_to_die)
15674 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
15675 if (tag != DW_TAG_subrange_type)
15678 string name = die_name(die);
15681 Dwarf_Die underlying_type_die;
15682 type_base_sptr underlying_type;
15684 bool is_signed =
false;
15685 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
15687 is_type(build_ir_node_from_die(rdr,
15688 &underlying_type_die,
15692 if (underlying_type)
15695 if (die_unsigned_constant_attribute (&underlying_type_die,
15698 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
15704 bool has_size_info =
false;
15706 if ((has_size_info = die_unsigned_constant_attribute(die,
15707 DW_AT_byte_size, size)))
15710 has_size_info = die_unsigned_constant_attribute(die,
15711 DW_AT_bit_size, size);
15714 array_type_def::subrange_type::bound_value lower_bound =
15715 get_default_array_lower_bound(language);
15716 array_type_def::subrange_type::bound_value upper_bound;
15717 uint64_t count = 0;
15718 bool is_non_finite =
false;
15719 bool non_zero_count_present =
false;
15730 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
15732 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
15733 is_signed, upper_bound);
15734 if (!found_upper_bound)
15735 found_upper_bound = subrange_die_indirect_bound_value(die,
15740 if (!found_upper_bound)
15753 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
15761 non_zero_count_present =
true;
15766 int64_t u = lower_bound.get_signed_value() + count;
15768 upper_bound = u - 1;
15771 if (!non_zero_count_present)
15775 is_non_finite =
true;
15778 if (UINT64_MAX == upper_bound.get_unsigned_value())
15781 is_non_finite =
true;
15784 (
new array_type_def::subrange_type(rdr.env(),
15790 result->is_non_finite(is_non_finite);
15793 result->set_size_in_bits(size);
15800 if (!underlying_type)
15801 result->set_size_in_bits(rdr.cur_transl_unit()->get_address_size());
15806 || (result->get_length() ==
15807 (uint64_t) (result->get_upper_bound()
15808 - result->get_lower_bound() + 1)));
15810 if (associate_type_to_die)
15811 rdr.associate_die_to_type(die, result, where_offset);
15833build_subranges_from_array_type_die(
const reader& rdr,
15834 const Dwarf_Die* die,
15836 size_t where_offset,
15837 bool associate_type_to_die)
15841 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
15845 int child_tag = dwarf_tag(&child);
15846 if (child_tag == DW_TAG_subrange_type)
15849 if (associate_type_to_die)
15855 build_ir_node_from_die(
const_cast<reader&
>(rdr), &child,
15864 s = build_subrange_type(
const_cast<reader&
>(rdr), &child,
15868 subranges.push_back(s);
15871 while (dwarf_siblingof(&child, &child) == 0);
15892build_array_type(reader& rdr,
15894 bool called_from_public_decl,
15895 size_t where_offset)
15902 unsigned tag = dwarf_tag(die);
15903 if (tag != DW_TAG_array_type)
15906 decl_base_sptr type_decl;
15907 Dwarf_Die type_die;
15909 if (die_die_attribute(die, DW_AT_type, type_die))
15910 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
15911 called_from_public_decl,
15918 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15925 type_base_sptr type =
is_type(type_decl);
15930 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
15932 result.reset(
new array_type_def(type, subranges, location()));
15933 rdr.associate_die_to_type(die, result, where_offset);
15954build_typedef_type(reader& rdr,
15956 bool called_from_public_decl,
15957 size_t where_offset)
15964 unsigned tag = dwarf_tag(die);
15965 if (tag != DW_TAG_typedef)
15968 string name, linkage_name;
15970 die_loc_and_name(rdr, die, loc, name, linkage_name);
15972 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
15978 type_base_sptr utype;
15979 Dwarf_Die underlying_type_die;
15980 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15983 utype = rdr.env().get_void_type();
15987 is_type(build_ir_node_from_die(rdr,
15988 &underlying_type_die,
15989 called_from_public_decl,
15995 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
16002 decl_base_sptr decl =
is_decl(utype);
16004 decl->set_naming_typedef(result);
16005 rdr.maybe_schedule_decl_only_type_for_resolution(utype);
16009 rdr.associate_die_to_type(die, result, where_offset);
16046build_or_get_var_decl_if_not_suppressed(reader& rdr,
16049 size_t where_offset,
16050 bool is_declaration_only,
16052 bool is_required_decl_spec)
16055 if (variable_is_suppressed(rdr, scope, die,
16056 is_declaration_only,
16057 is_required_decl_spec))
16059 ++rdr.stats_.number_of_suppressed_variables;
16065 string var_name = die_name(die);
16066 if (!var_name.empty())
16067 if ((var = class_type->find_data_member(var_name)))
16072 ++rdr.stats_.number_of_suppressed_variables;
16074 var = build_var_decl(rdr, die, where_offset, result);
16097build_var_decl(reader& rdr,
16099 size_t where_offset,
16105 int tag = dwarf_tag(die);
16106 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
16108 if (!die_is_public_decl(die))
16111 type_base_sptr type;
16112 Dwarf_Die type_die;
16113 if (die_die_attribute(die, DW_AT_type, type_die))
16115 decl_base_sptr ty =
16116 is_decl(build_ir_node_from_die(rdr, &type_die,
16125 if (!type && !result)
16128 string name, linkage_name;
16130 die_loc_and_name(rdr, die, loc, name, linkage_name);
16133 result.reset(
new var_decl(name, type, loc, linkage_name));
16139 if (!linkage_name.empty())
16140 result->set_linkage_name(linkage_name);
16143 result->set_type(type);
16149 if (!result->get_symbol())
16152 Dwarf_Addr var_addr;
16154 if (rdr.get_variable_address(die, var_addr))
16157 update_main_symbol(var_addr,
16158 result->get_linkage_name().empty()
16159 ? result->get_name()
16160 : result->get_linkage_name());
16161 var_sym = rdr.variable_symbol_is_exported(var_addr);
16166 result->set_symbol(var_sym);
16169 string linkage_name = result->get_linkage_name();
16170 if (linkage_name.empty()
16171 || !var_sym->get_alias_from_name(linkage_name))
16172 result->set_linkage_name(var_sym->get_name());
16173 result->set_is_in_public_symbol_table(
true);
16176 if (!var_sym && rdr.is_decl_die_with_undefined_symbol(die))
16180 string n = result->get_linkage_name();
16182 n = result->get_name();
16183 var_sym = rdr.symtab()->lookup_undefined_variable_symbol(n);
16186 result->set_symbol(var_sym);
16187 result->set_is_in_public_symbol_table(
false);
16214function_is_suppressed(
const reader& rdr,
16215 const scope_decl* scope,
16216 Dwarf_Die *function_die,
16217 bool is_declaration_only)
16219 if (function_die == 0
16220 || dwarf_tag(function_die) != DW_TAG_subprogram)
16223 string fname = die_string_attribute(function_die, DW_AT_name);
16224 string flinkage_name = die_linkage_name(function_die);
16225 if (flinkage_name.empty() && die_is_in_c(function_die))
16226 flinkage_name = fname;
16236 && (!is_declaration_only || rdr.drop_undefined_syms()))
16238 Dwarf_Addr fn_addr;
16239 if (!rdr.get_function_address(function_die, fn_addr))
16243 rdr.function_symbol_is_exported(fn_addr);
16246 if (symbol->is_suppressed())
16253 if (symbol->has_aliases())
16255 !a->is_main_symbol(); a = a->get_next_alias())
16256 if (a->is_suppressed())
16305build_or_get_fn_decl_if_not_suppressed(reader& rdr,
16308 size_t where_offset,
16309 bool is_declaration_only,
16313 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
16315 ++rdr.stats_.number_of_suppressed_functions;
16319 string name = die_name(fn_die);
16320 string linkage_name = die_linkage_name(fn_die);
16321 bool is_dtor = !name.empty() && name[0]==
'~';
16322 bool is_virtual =
false;
16325 Dwarf_Attribute attr;
16326 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
16327 DW_AT_vtable_elem_location,
16339 if (!result && (!(is_dtor && is_virtual)))
16343 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
16344 rdr.associate_die_to_decl(fn_die, fn,
true);
16345 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
16351 ++rdr.stats_.number_of_allowed_functions;
16357 string linkage_name = die_linkage_name(fn_die);
16358 fn = klass->find_member_function_sptr(linkage_name);
16365 if (!fn || !fn->get_symbol())
16372 fn = build_function_decl(rdr, fn_die, where_offset, result);
16397variable_is_suppressed(
const reader& rdr,
16398 const scope_decl* scope,
16399 Dwarf_Die *variable_die,
16400 bool is_declaration_only,
16401 bool is_required_decl_spec)
16403 if (variable_die == 0
16404 || (dwarf_tag(variable_die) != DW_TAG_variable
16405 && dwarf_tag(variable_die) != DW_TAG_member))
16408 string name = die_string_attribute(variable_die, DW_AT_name);
16409 string linkage_name = die_linkage_name(variable_die);
16410 if (linkage_name.empty() && die_is_in_c(variable_die))
16411 linkage_name = name;
16420 && !is_required_decl_spec
16424 && (!is_declaration_only || !rdr.load_undefined_interfaces()))
16426 Dwarf_Addr var_addr = 0;
16427 if (!rdr.get_variable_address(variable_die, var_addr))
16431 rdr.variable_symbol_is_exported(var_addr);
16434 if (symbol->is_suppressed())
16441 if (symbol->has_aliases())
16443 !a->is_main_symbol(); a = a->get_next_alias())
16444 if (a->is_suppressed())
16473type_is_suppressed(
const reader& rdr,
16474 const scope_decl* scope,
16475 Dwarf_Die *type_die,
16476 bool &type_is_opaque)
16479 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
16480 && dwarf_tag(type_die) != DW_TAG_class_type
16481 && dwarf_tag(type_die) != DW_TAG_structure_type
16482 && dwarf_tag(type_die) != DW_TAG_union_type))
16485 string type_name, linkage_name;
16486 location type_location;
16487 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
16511type_is_suppressed(
const reader& rdr,
16512 const scope_decl* scope,
16513 Dwarf_Die *type_die)
16515 bool type_is_opaque =
false;
16516 return type_is_suppressed(rdr, scope, type_die, type_is_opaque);
16540get_opaque_version_of_type(reader &rdr,
16542 Dwarf_Die *type_die,
16543 size_t where_offset)
16550 unsigned tag = dwarf_tag(type_die);
16551 if (tag != DW_TAG_class_type
16552 && tag != DW_TAG_structure_type
16553 && tag != DW_TAG_union_type
16554 && tag != DW_TAG_enumeration_type)
16557 string type_name, linkage_name;
16558 location type_location;
16559 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
16568 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
16570 string_classes_or_unions_map::const_iterator i =
16571 rdr.declaration_only_classes().find(qualified_name);
16572 if (i != rdr.declaration_only_classes().end())
16573 result = i->second.back();
16584 tag == DW_TAG_structure_type,
16586 decl_base::VISIBILITY_DEFAULT));
16587 klass->set_is_declaration_only(
true);
16588 klass->set_is_artificial(die_is_artificial(type_die));
16590 rdr.associate_die_to_type(type_die, klass, where_offset);
16591 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
16596 if (tag == DW_TAG_enumeration_type)
16598 string_enums_map::const_iterator i =
16599 rdr.declaration_only_enums().find(qualified_name);
16600 if (i != rdr.declaration_only_enums().end())
16601 result = i->second.back();
16606 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
16609 build_enum_underlying_type(rdr, type_name, size,
16617 enum_type->set_is_artificial(die_is_artificial(type_die));
16619 result = enum_type;
16642 elf_symbol::FUNC_TYPE,
16643 elf_symbol::GLOBAL_BINDING,
16647 elf_symbol::DEFAULT_VISIBILITY);
16665build_function_decl(reader& rdr,
16667 size_t where_offset,
16673 int tag = dwarf_tag(die);
16674 ABG_ASSERT(tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine);
16676 if (!die_is_public_decl(die))
16682 string fname, flinkage_name;
16684 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
16686 size_t is_inline = die_is_declared_inline(die);
16687 class_or_union_sptr is_method =
16700 if (!flinkage_name.empty()
16701 && result->get_linkage_name() != flinkage_name)
16702 result->set_linkage_name(flinkage_name);
16704 if (!result->get_location())
16705 result->set_location(floc);
16706 result->is_declared_inline(is_inline);
16715 maybe_canonicalize_type(fn_type, rdr);
16717 result.reset(is_method
16718 ?
new method_decl(fname, fn_type,
16721 :
new function_decl(fname, fn_type,
16728 if (!result->get_symbol())
16731 Dwarf_Addr fn_addr;
16732 if (rdr.get_function_address(die, fn_addr))
16735 update_main_symbol(fn_addr,
16736 result->get_linkage_name().empty()
16737 ? result->get_name()
16738 : result->get_linkage_name());
16739 fn_sym = rdr.function_symbol_is_exported(fn_addr);
16742 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
16744 result->set_symbol(fn_sym);
16745 string linkage_name = result->get_linkage_name();
16746 if (linkage_name.empty())
16747 result->set_linkage_name(fn_sym->get_name());
16748 result->set_is_in_public_symbol_table(
true);
16751 if (!fn_sym && rdr.is_decl_die_with_undefined_symbol(die))
16755 string n = result->get_linkage_name();
16757 n = result->get_name();
16758 fn_sym = rdr.symtab()->lookup_undefined_function_symbol(n);
16761 result->set_symbol(fn_sym);
16762 result->set_is_in_public_symbol_table(
false);
16767 rdr.associate_die_to_type(die, result->get_type(), where_offset);
16769 size_t die_offset = dwarf_dieoffset(die);
16774 && !result->get_linkage_name().empty())
16780 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
16799maybe_canonicalize_type(
const type_base_sptr& t,
16805 rdr.schedule_type_for_late_canonicalization(t);
16814maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
16817 if (
is_type(member_type_declaration)
16820 class_or_union* scope =
16826 if (!cl->is_struct())
16827 access = private_access;
16829 die_access_specifier(die, access);
16849 const Dwarf_Die *fn_die)
16851 if (!fn || fn->get_scope())
16855 !die_is_virtual(fn_die)
16857 && !fn->get_symbol())
16902build_ir_node_from_die(reader& rdr,
16905 bool called_from_public_decl,
16906 size_t where_offset,
16907 bool is_declaration_only,
16908 bool is_required_decl_spec)
16912 if (!die || !scope)
16915 int tag = dwarf_tag(die);
16917 if (!called_from_public_decl)
16919 if (rdr.load_all_types() && die_is_type(die))
16923 else if (tag != DW_TAG_subprogram
16924 && tag != DW_TAG_variable
16925 && tag != DW_TAG_member
16926 && tag != DW_TAG_namespace)
16930 const die_source source_of_die = rdr.get_die_source(die);
16932 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
16935 if (rdr.load_all_types())
16936 if (called_from_public_decl)
16937 if (type_base_sptr t =
is_type(result))
16938 if (corpus *abi_corpus = rdr.corpus().get())
16939 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
16948 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
16953 case DW_TAG_base_type:
16958 maybe_canonicalize_type(t, rdr);
16962 case DW_TAG_typedef:
16965 called_from_public_decl,
16971 maybe_set_member_type_access_specifier(
is_decl(result), die);
16972 maybe_canonicalize_type(t, rdr);
16977 case DW_TAG_pointer_type:
16980 build_pointer_type_def(rdr, die,
16981 called_from_public_decl,
16988 maybe_canonicalize_type(p, rdr);
16993 case DW_TAG_reference_type:
16994 case DW_TAG_rvalue_reference_type:
16997 build_reference_type(rdr, die,
16998 called_from_public_decl,
17004 maybe_canonicalize_type(r, rdr);
17009 case DW_TAG_ptr_to_member_type:
17012 build_ptr_to_mbr_type(rdr, die, called_from_public_decl,
17018 rdr.cur_transl_unit()->get_global_scope());
17019 maybe_canonicalize_type(p, rdr);
17024 case DW_TAG_const_type:
17025 case DW_TAG_volatile_type:
17026 case DW_TAG_restrict_type:
17029 build_qualified_type(rdr, die,
17030 called_from_public_decl,
17041 type_base_sptr ty =
is_type(d);
17045 rdr.associate_die_to_type(die, ty, where_offset);
17048 maybe_canonicalize_type(
is_type(result), rdr);
17053 case DW_TAG_enumeration_type:
17055 bool type_is_opaque =
false;
17056 bool type_suppressed =
17057 type_is_suppressed(rdr, scope, die, type_is_opaque);
17058 if (type_suppressed && type_is_opaque)
17066 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
17067 maybe_canonicalize_type(
is_type(result), rdr);
17069 else if (!type_suppressed)
17073 is_declaration_only);
17077 maybe_set_member_type_access_specifier(
is_decl(result), die);
17078 maybe_canonicalize_type(
is_type(result), rdr);
17084 case DW_TAG_class_type:
17085 case DW_TAG_structure_type:
17087 bool type_is_opaque =
false;
17088 bool type_suppressed=
17089 type_is_suppressed(rdr, scope, die, type_is_opaque);
17091 if (type_suppressed && type_is_opaque)
17099 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
17100 maybe_canonicalize_type(
is_type(result), rdr);
17102 else if (!type_suppressed)
17105 Dwarf_Die spec_die;
17106 if (die_die_attribute(die, DW_AT_specification, spec_die))
17109 get_scope_for_die(rdr, &spec_die,
17110 called_from_public_decl,
17113 decl_base_sptr cl =
17114 is_decl(build_ir_node_from_die(rdr, &spec_die,
17116 called_from_public_decl,
17118 is_declaration_only,
17121 klass = dynamic_pointer_cast<class_decl>(cl);
17125 add_or_update_class_type(rdr, die,
17127 tag == DW_TAG_structure_type,
17129 called_from_public_decl,
17131 is_declaration_only);
17137 string type_name = die_type_name(rdr, die,
17145 add_or_update_class_type(rdr, die, scope,
17146 tag == DW_TAG_structure_type,
17148 called_from_public_decl,
17150 is_declaration_only);
17154 add_or_update_class_type(rdr, die, scope,
17155 tag == DW_TAG_structure_type,
17157 called_from_public_decl,
17159 is_declaration_only);
17163 maybe_set_member_type_access_specifier(klass, die);
17164 maybe_canonicalize_type(klass, rdr);
17170 case DW_TAG_union_type:
17171 if (!type_is_suppressed(rdr, scope, die))
17173 union_decl_sptr union_type;
17176 string type_name = die_type_name(rdr, die,
17179 if (union_decl_sptr u =
17186 add_or_update_union_type(rdr, die, scope,
17188 called_from_public_decl,
17190 is_declaration_only);
17194 maybe_set_member_type_access_specifier(union_type, die);
17195 maybe_canonicalize_type(union_type, rdr);
17196 result = union_type;
17200 case DW_TAG_string_type:
17202 case DW_TAG_subroutine_type:
17210 result->set_is_artificial(
false);
17211 maybe_canonicalize_type(f, rdr);
17215 case DW_TAG_array_type:
17219 called_from_public_decl,
17225 maybe_canonicalize_type(a, rdr);
17229 case DW_TAG_subrange_type:
17235 build_subrange_type(rdr, die, where_offset,
17241 maybe_canonicalize_type(s, rdr);
17245 case DW_TAG_packed_type:
17247 case DW_TAG_set_type:
17249 case DW_TAG_file_type:
17251 case DW_TAG_thrown_type:
17253 case DW_TAG_interface_type:
17255 case DW_TAG_unspecified_type:
17257 case DW_TAG_shared_type:
17260 case DW_TAG_compile_unit:
17265 case DW_TAG_namespace:
17266 case DW_TAG_module:
17267 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
17270 case DW_TAG_variable:
17271 case DW_TAG_member:
17273 if (tag == DW_TAG_member)
17277 get_scope_for_die(rdr, die,
17279 die_is_effectively_public_decl(rdr, die),
17282 build_or_get_var_decl_if_not_suppressed(rdr, var_scope.get(), die,
17284 is_declaration_only,
17286 is_required_decl_spec);
17294 v = build_var_decl(rdr, die, where_offset, v);
17307 rdr.var_decls_to_re_add_to_tree().push_back(v);
17308 rdr.add_var_to_exported_or_undefined_decls(v);
17309 rdr.associate_die_to_decl(die, v, where_offset,
17316 case DW_TAG_subprogram:
17317 case DW_TAG_inlined_subroutine:
17319 if (die_is_artificial(die))
17322 Dwarf_Die abstract_origin_die;
17323 bool has_abstract_origin = die_die_attribute(die, DW_AT_abstract_origin,
17324 abstract_origin_die,
17328 scope_decl_sptr s = get_scope_for_die(rdr, die, called_from_public_decl,
17330 scope_decl* interface_scope = scope ? scope : s.get();
17333 string linkage_name = die_linkage_name(die);
17334 string spec_linkage_name;
17341 if (!linkage_name.empty())
17344 class_scope->find_member_function_sptr(linkage_name)))
17349 spec_linkage_name = existing_fn->get_linkage_name();
17350 if (has_abstract_origin
17351 && !spec_linkage_name.empty()
17352 && linkage_name != spec_linkage_name)
17359 existing_fn = existing_fn->clone();
17364 else if (has_abstract_origin)
17368 existing_fn = build_function_decl(rdr, &abstract_origin_die, where_offset,
17371 rdr.scope_stack().push(interface_scope);
17378 build_or_get_fn_decl_if_not_suppressed(rdr, interface_scope,
17380 is_declaration_only,
17383 if (result && !existing_fn)
17389 && !is_required_decl_spec)
17406 sptr_utils::noop_deleter());
17408 finish_member_function_reading(die, fn, klass, rdr);
17419 rdr.add_fn_to_exported_or_undefined_decls(fn.get());
17420 rdr.associate_die_to_decl(die, fn, where_offset,
17422 maybe_canonicalize_type(fn->get_type(), rdr);
17425 rdr.scope_stack().pop();
17429 case DW_TAG_formal_parameter:
17434 case DW_TAG_constant:
17436 case DW_TAG_enumerator:
17439 case DW_TAG_partial_unit:
17440 case DW_TAG_imported_unit:
17447 case DW_TAG_dwarf_procedure:
17448 case DW_TAG_imported_declaration:
17449 case DW_TAG_entry_point:
17451 case DW_TAG_lexical_block:
17452 case DW_TAG_unspecified_parameters:
17453 case DW_TAG_variant:
17454 case DW_TAG_common_block:
17455 case DW_TAG_common_inclusion:
17456 case DW_TAG_inheritance:
17457 case DW_TAG_with_stmt:
17458 case DW_TAG_access_declaration:
17459 case DW_TAG_catch_block:
17460 case DW_TAG_friend:
17461 case DW_TAG_namelist:
17462 case DW_TAG_namelist_item:
17463 case DW_TAG_template_type_parameter:
17464 case DW_TAG_template_value_parameter:
17465 case DW_TAG_try_block:
17466 case DW_TAG_variant_part:
17467 case DW_TAG_imported_module:
17468 case DW_TAG_condition:
17469 case DW_TAG_type_unit:
17470 case DW_TAG_template_alias:
17471 case DW_TAG_lo_user:
17472 case DW_TAG_MIPS_loop:
17473 case DW_TAG_format_label:
17474 case DW_TAG_function_template:
17475 case DW_TAG_class_template:
17476 case DW_TAG_GNU_BINCL:
17477 case DW_TAG_GNU_EINCL:
17478 case DW_TAG_GNU_template_template_param:
17479 case DW_TAG_GNU_template_parameter_pack:
17480 case DW_TAG_GNU_formal_parameter_pack:
17481 case DW_TAG_GNU_call_site:
17482 case DW_TAG_GNU_call_site_parameter:
17483 case DW_TAG_hi_user:
17488 if (result && tag != DW_TAG_subroutine_type)
17489 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
17493 if (rdr.load_all_types())
17494 if (called_from_public_decl)
17495 if (type_base_sptr t =
is_type(result))
17496 if (corpus *abi_corpus = scope->get_corpus())
17497 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
17499 rdr.maybe_schedule_decl_only_type_for_resolution(result);
17509static decl_base_sptr
17510build_ir_node_for_void_type(reader& rdr)
17512 const environment& env = rdr.env();
17514 type_base_sptr t = env.get_void_type();
17519 rdr.schedule_type_for_late_canonicalization(t);
17521 return type_declaration;
17536build_ir_node_for_void_pointer_type(reader& rdr)
17538 const environment& env = rdr.env();
17539 type_base_sptr t = env.get_void_pointer_type();
17544 rdr.schedule_type_for_late_canonicalization(t);
17546 return type_declaration;
17554static decl_base_sptr
17555build_ir_node_for_variadic_parameter_type(reader &rdr)
17558 const environment& env = rdr.env();
17559 type_base_sptr t = env.get_variadic_parameter_type();
17564 rdr.schedule_type_for_late_canonicalization(t);
17566 return type_declaration;
17592build_ir_node_from_die(reader& rdr,
17594 bool called_from_public_decl,
17595 size_t where_offset)
17598 return decl_base_sptr();
17608 bool consider_as_called_from_public_decl =
17609 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
17611 consider_as_called_from_public_decl,
17614 scope = rdr.global_scope();
17616 return build_ir_node_from_die(rdr, die, scope.get(),
17617 called_from_public_decl,
17618 where_offset,
true);
17652elf_based_reader_sptr
17654 const vector<char**>& debug_info_root_paths,
17656 bool load_all_types,
17657 bool linux_kernel_mode)
17660 reader_sptr r = reader::create(elf_path,
17661 debug_info_root_paths,
17664 linux_kernel_mode);
17665 return static_pointer_cast<elf_based_reader>(r);
17704 const std::string& elf_path,
17705 const vector<char**>&debug_info_root_path,
17706 bool read_all_types,
17707 bool linux_kernel_mode)
17709 reader& r =
dynamic_cast<reader&
>(rdr);
17710 r.initialize(elf_path, debug_info_root_path,
17711 read_all_types, linux_kernel_mode);
17748 const vector<char**>& debug_info_root_paths,
17750 bool load_all_types,
17753 elf_based_reader_sptr rdr =
17754 dwarf::reader::create(elf_path, debug_info_root_paths,
17758 return rdr->read_corpus(status);
17779 const string& elf_path,
17780 const string& symbol_name,
17782 vector<elf_symbol_sptr>& syms)
17785 if (elf_version(EV_CURRENT) == EV_NONE)
17788 int fd = open(elf_path.c_str(), O_RDONLY);
17796 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
17824 const string& path,
17825 const string& symname,
17826 vector<elf_symbol_sptr>& syms)
17828 if (elf_version(EV_CURRENT) == EV_NONE)
17831 int fd = open(path.c_str(), O_RDONLY);
17839 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...
elf_symbol_sptr function_symbol_is_undefined(const string &name) const
Test if a name is the name of an undefined function symbol.
const string & elf_architecture() const
Get the value of the 'ARCHITECTURE' property of the current ELF file.
const Dwarf * dwarf_debug_info() const
Getter of the handle used to access DWARF information from the current ELF file.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
const Dwarf * alternate_dwarf_debug_info() const
Getter of the handle use to access DWARF information from the alternate split DWARF information.
bool refers_to_alt_debug_info(string &alt_di_path) const
Check if the underlying elf file refers to an alternate debug info file associated to it.
elf_symbol_sptr variable_symbol_is_undefined(const string &name) const
Test if a name is the name of an undefined variable symbol.
elf_symbol_sptr variable_symbol_is_exported(GElf_Addr symbol_address) const
Test if a given variable symbol has been exported.
elf_symbol_sptr function_symbol_is_exported(GElf_Addr symbol_address) const
Test if a given function symbol has been exported.
const vector< string > & dt_needed() const
Get the value of the DT_NEEDED property of the current ELF file.
The common interface of readers based on ELF.
elf_based_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &env)
Readers that implement this interface must provide a factory method to create a reader instance as th...
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
status
The status of the fe_iface::read_corpus call.
@ STATUS_DEBUG_INFO_NOT_FOUND
This status is for when the debug info could not be read.
@ STATUS_ALT_DEBUG_INFO_NOT_FOUND
This status is for when the alternate debug info could not be found.
@ STATUS_UNKNOWN
The status is in an unknown state.
const options_type & options() const
Getter of the the options of the current Front End Interface.
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
corpus_group_sptr & corpus_group()
Getter for the ABI corpus group being built by the current front-end.
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
The abstraction of an interned string.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
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 source location of a token.
CV
Bit field values representing the cv qualifiers of the underlying type.
The internal representation of an integral type.
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
language
The language of the translation unit.
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
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.
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.
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous 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...
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...
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.
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...
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
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.
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,...
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
hash_t hash(uint64_t v, uint64_t seed)
Hash an integer value and combine it with a hash previously computed.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
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.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
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.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
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.
bool parse_real_type(const string &type_name, real_type &type)
Parse a real type from a string.
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...
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
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.
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.
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
bool 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.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
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.
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
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_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
unordered_map< interned_string, type_base_wptrs_type, hash_interned_string > istring_type_base_wptrs_map_type
A convenience typedef for a map which key is an interned_string and which value is a vector of type_b...
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
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.
void hash_and_canonicalize_types(IteratorType begin, IteratorType end, deref_lambda deref, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
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.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
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 and if the d...
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.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
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.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
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.
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.
method_decl_sptr copy_member_function(const class_or_union_sptr &t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
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 set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_opaque, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
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 OR operator for the fe_iface::status type.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
bool load_undefined_interfaces
If this option is set to true, then the functions and variables that have an undefined symbol are goi...
A functor to hash instances of interned_string.