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,
255cleanup_decl_name(
string&);
295struct imported_unit_point
297 Dwarf_Off offset_of_import;
301 Dwarf_Off imported_unit_die_off;
302 Dwarf_Off imported_unit_cu_off;
303 Dwarf_Off imported_unit_child_off;
306 imported_unit_point()
307 : offset_of_import(),
308 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
309 imported_unit_die_off(),
310 imported_unit_cu_off(),
311 imported_unit_child_off()
318 imported_unit_point(Dwarf_Off import_off)
319 : offset_of_import(import_off),
320 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
321 imported_unit_die_off(),
322 imported_unit_cu_off(),
323 imported_unit_child_off()
334 imported_unit_point(Dwarf_Off import_off,
335 const Dwarf_Die& imported_die,
337 : offset_of_import(import_off),
338 imported_unit_die_source(from),
339 imported_unit_die_off(dwarf_dieoffset
340 (
const_cast<Dwarf_Die*
>(&imported_die))),
341 imported_unit_cu_off(),
342 imported_unit_child_off()
344 Dwarf_Die imported_unit_child;
346 ABG_ASSERT(dwarf_child(
const_cast<Dwarf_Die*
>(&imported_die),
347 &imported_unit_child) == 0);
349 imported_unit_child_off =
350 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(&imported_unit_child));
352 Dwarf_Die cu_die_memory;
355 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&imported_unit_child),
356 &cu_die_memory, 0, 0);
357 imported_unit_cu_off = dwarf_dieoffset(cu_die);
365typedef unordered_map<Dwarf_Off, imported_unit_points_type>
377operator<(
const imported_unit_point& l,
const imported_unit_point& r)
378{
return l.offset_of_import < r.offset_of_import;}
381get_parent_die(
const reader& rdr,
382 const Dwarf_Die* die,
383 Dwarf_Die& parent_die,
384 size_t where_offset);
387get_scope_die(
const reader& rdr,
388 const Dwarf_Die* die,
390 Dwarf_Die& scope_die);
396die_is_in_c(
const Dwarf_Die *die);
399die_is_in_cplus_plus(
const Dwarf_Die *die);
402die_is_in_c_or_cplusplus(
const Dwarf_Die *die);
405die_is_anonymous(
const Dwarf_Die* die);
408die_is_anonymous_data_member(
const Dwarf_Die* die);
411die_is_type(
const Dwarf_Die* die);
414die_is_decl(
const Dwarf_Die* die);
417die_is_declaration_only(Dwarf_Die* die);
420die_is_variable_decl(
const Dwarf_Die *die);
423die_is_function_decl(
const Dwarf_Die *die);
426die_has_size_attribute(
const Dwarf_Die *die);
429die_has_no_child(
const Dwarf_Die *die);
432die_is_namespace(
const Dwarf_Die* die);
435die_is_unspecified(Dwarf_Die* die);
438die_is_void_type(Dwarf_Die* die);
441die_is_pointer_type(
const Dwarf_Die* die);
444pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
447die_is_reference_type(
const Dwarf_Die* die);
450die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
453die_is_pointer_or_reference_type(
const Dwarf_Die* die);
456die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
459die_is_class_type(
const Dwarf_Die* die);
462die_is_qualified_type(
const Dwarf_Die* die);
465die_is_function_type(
const Dwarf_Die *die);
468die_has_object_pointer(
const Dwarf_Die* die,
469 Dwarf_Die& object_pointer);
472die_has_children(
const Dwarf_Die* die);
475fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die);
478member_fn_die_has_this_pointer(
const reader& rdr,
479 const Dwarf_Die* die,
481 Dwarf_Die& class_die,
482 Dwarf_Die& object_pointer_die);
485die_this_pointer_from_object_pointer(Dwarf_Die* die,
486 Dwarf_Die& this_pointer);
489die_this_pointer_is_const(Dwarf_Die* die);
492die_object_pointer_is_for_const_method(Dwarf_Die* die);
495is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
498die_is_at_class_scope(
const reader& rdr,
499 const Dwarf_Die* die,
501 Dwarf_Die& class_scope_die);
503eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
506 bool& is_tls_address);
509dwarf_language_to_tu_language(
size_t l);
512die_unsigned_constant_attribute(
const Dwarf_Die* die,
517die_signed_constant_attribute(
const Dwarf_Die*die,
522die_constant_attribute(
const Dwarf_Die *die,
528die_member_offset(
const reader& rdr,
529 const Dwarf_Die* die,
533form_is_DW_FORM_strx(
unsigned form);
536form_is_DW_FORM_line_strp(
unsigned form);
539die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
542die_name(
const Dwarf_Die* die);
545die_name_and_linkage_name(
const Dwarf_Die* die,
547 string& linkage_name);
549die_location(
const reader& rdr,
const Dwarf_Die* die);
552die_location_address(Dwarf_Die* die,
554 bool& is_tls_address);
557die_die_attribute(
const Dwarf_Die* die,
560 bool recursively =
true);
563die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die);
566subrange_die_indirect_bound_value(
const Dwarf_Die *die,
572subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
574 Dwarf_Die& referenced_subrange);
576get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
579build_internal_anonymous_die_name(
const string &
base_name,
580 size_t anonymous_type_index);
583die_qualified_type_name(
const reader& rdr,
584 const Dwarf_Die* die,
586 unordered_set<uint64_t>& guard);
589die_qualified_decl_name(
const reader& rdr,
590 const Dwarf_Die* die,
592 unordered_set<uint64_t>& guard);
595die_qualified_name(
const reader& rdr,
596 const Dwarf_Die* die,
598 unordered_set<uint64_t>& guard);
601die_qualified_name(
const reader& rdr,
602 const Dwarf_Die* die,
606die_type_name(
const reader& rdr,
const Dwarf_Die* die,
607 bool qualified_name,
size_t where_offset,
608 unordered_set<uint64_t>& infinite_loop_guard);
611die_type_name(
const reader& rdr,
const Dwarf_Die* die,
612 bool qualified_name,
size_t where_offset);
615die_qualified_type_name_empty(
const reader& rdr,
616 const Dwarf_Die* die,
size_t where,
617 string &qualified_name,
618 unordered_set<uint64_t>& infinite_loop_guard);
621die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
622 const Dwarf_Die* die,
627 string &return_type_name,
629 vector<string>& parm_names,
632 unordered_set<uint64_t>& infinite_loop_guard);
635die_function_signature(
const reader& rdr,
636 const Dwarf_Die *die,
639 unordered_set<uint64_t>& infinite_loop_guard);
642die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
645die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
648die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die);
651die_function_type_is_method_type(
const reader& rdr,
652 const Dwarf_Die *die,
654 Dwarf_Die& object_pointer_die,
655 Dwarf_Die& class_die,
659die_enum_flat_representation(
const reader& rdr,
660 const Dwarf_Die* die,
661 const string& indent,
663 bool qualified_names,
664 size_t where_offset);
667die_class_flat_representation(
const reader& rdr,
668 const Dwarf_Die* die,
669 const string& indent,
671 bool qualified_names,
673 unordered_set<uint64_t>& infinite_loop_guard);
676die_class_or_enum_flat_representation(
const reader& rdr,
677 const Dwarf_Die* die,
678 const string& indent,
680 bool qualified_names,
682 unordered_set<uint64_t>& infinite_loop_guard);
685die_class_or_enum_flat_representation(
const reader& rdr,
686 const Dwarf_Die* die,
687 const string& indent,
689 bool qualified_names,
690 size_t where_offset);
693die_pretty_print_type(
const reader& rdr,
694 const Dwarf_Die* die,
696 unordered_set<uint64_t>& guard);
699die_pretty_print_decl(
const reader& rdr,
700 const Dwarf_Die* die,
704 unordered_set<uint64_t>& infinite_loop_guard);
707die_pretty_print(reader& rdr,
708 const Dwarf_Die* die,
710 unordered_set<uint64_t>& infinite_loop_guard);
713maybe_canonicalize_type(
const type_base_sptr& t,
722 imported_unit_points_type::const_iterator&);
725build_subrange_type(reader& rdr,
726 const Dwarf_Die* die,
728 bool associate_type_to_die =
true);
731build_subranges_from_array_type_die(
const reader& rdr,
732 const Dwarf_Die* die,
735 bool associate_type_to_die =
true);
738compare_dies(
const reader& rdr,
739 const Dwarf_Die *l,
const Dwarf_Die *r,
740 bool update_canonical_dies_on_the_fly);
743compare_dies_during_canonicalization(reader& rdr,
744 const Dwarf_Die *l,
const Dwarf_Die *r,
745 bool update_canonical_dies_on_the_fly);
748get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
751get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member);
764 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
767 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
770 lang = dwarf_language_to_tu_language(l);
782die_is_in_c(
const Dwarf_Die *die)
785 if (!get_die_language(die, l))
798die_is_in_cplus_plus(
const Dwarf_Die *die)
801 if (!get_die_language(die, l))
814die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
817 if (!get_die_language(die, l))
834compare_symbol_name(
const string& symbol_name,
843 return symbol_name == name;
872lookup_symbol_from_sysv_hash_tab(
const environment& env,
874 const string& sym_name,
876 size_t sym_tab_index,
878 vector<elf_symbol_sptr>& syms_found)
880 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
883 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
886 GElf_Shdr sheader_mem;
887 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
889 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
894 unsigned long hash = elf_hash(sym_name.c_str());
895 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
896 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
897 size_t nb_buckets = ht_data[0];
898 size_t nb_chains = ht_data[1];
906 Elf32_Word* ht_buckets = &ht_data[2];
907 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
910 size_t bucket =
hash % nb_buckets;
911 size_t symbol_index = ht_buckets[bucket];
914 const char* sym_name_str;
923 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
924 sym_name_str = elf_strptr(elf_handle,
925 sym_tab_section_header->sh_link,
928 && compare_symbol_name(sym_name_str, sym_name, demangle))
934 sym_size = symbol.st_size;
935 elf_symbol::version ver;
946 symbol.st_shndx != SHN_UNDEF,
947 symbol.st_shndx == SHN_COMMON,
948 ver, sym_visibility);
949 syms_found.push_back(symbol_found);
952 symbol_index = ht_chains[symbol_index];
953 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
964get_elf_class_size_in_bytes(Elf* elf_handle)
970 int c = hdr.e_ident[EI_CLASS];
1004bloom_word_at(Elf* elf_handle,
1005 Elf32_Word* bloom_filter,
1008 Elf64_Xword result = 0;
1012 c = h.e_ident[EI_CLASS];
1017 result = bloom_filter[index];
1021 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
1040 Elf32_Word* buckets;
1042 size_t first_sym_index;
1045 Elf32_Word* bloom_filter;
1048 Elf_Scn* sym_tab_section;
1049 GElf_Shdr sym_tab_section_header;
1079setup_gnu_ht(Elf* elf_handle,
1081 size_t sym_tab_index,
1084 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1086 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
1088 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
1089 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
1094 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
1095 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
1097 ht.nb_buckets = ht_data[0];
1098 if (ht.nb_buckets == 0)
1102 ht.first_sym_index = ht_data[1];
1105 ht.bf_nwords = ht_data[2];
1107 ht.shift = ht_data[3];
1109 ht.bloom_filter = &ht_data[4];
1114 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
1116 ht.buckets = ht.bloom_filter + ht.bf_size;
1118 ht.chain = ht.buckets + ht.nb_buckets;
1149lookup_symbol_from_gnu_hash_tab(
const environment& env,
1151 const string& sym_name,
1153 size_t sym_tab_index,
1155 vector<elf_symbol_sptr>& syms_found)
1158 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
1164 size_t h1 = elf_gnu_hash(sym_name.c_str());
1165 size_t h2 = h1 >> ht.shift;
1168 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
1169 int n = (h1 / c) % ht.bf_nwords;
1175 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1178 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1181 size_t i = ht.buckets[h1 % ht.nb_buckets];
1185 Elf32_Word stop_word, *stop_wordp;
1186 elf_symbol::version ver;
1188 const char* sym_name_str;
1197 for (i = ht.buckets[h1 % ht.nb_buckets],
1198 stop_wordp = &ht.chain[i - ht.first_sym_index];
1201 < ht.chain + (ht.sym_count - ht.first_sym_index));
1204 stop_word = *stop_wordp;
1205 if ((stop_word & ~ 1)!= (h1 & ~1))
1211 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1213 sym_name_str = elf_strptr(elf_handle,
1214 ht.sym_tab_section_header.sh_link,
1217 && compare_symbol_name(sym_name_str, sym_name, demangle))
1235 sym_type, sym_binding,
1236 symbol.st_shndx != SHN_UNDEF,
1237 symbol.st_shndx == SHN_COMMON,
1238 ver, sym_visibility);
1239 syms_found.push_back(symbol_found);
1281lookup_symbol_from_elf_hash_tab(
const environment& env,
1283 hash_table_kind ht_kind,
1285 size_t symtab_index,
1286 const string& symbol_name,
1288 vector<elf_symbol_sptr>& syms_found)
1290 if (elf_handle == 0 || symbol_name.empty())
1293 if (ht_kind == NO_HASH_TABLE_KIND)
1296 if (ht_kind == SYSV_HASH_TABLE_KIND)
1297 return lookup_symbol_from_sysv_hash_tab(env,
1298 elf_handle, symbol_name,
1303 else if (ht_kind == GNU_HASH_TABLE_KIND)
1304 return lookup_symbol_from_gnu_hash_tab(env,
1305 elf_handle, symbol_name,
1338lookup_symbol_from_symtab(
const environment& env,
1340 const string& sym_name,
1341 size_t sym_tab_index,
1343 vector<elf_symbol_sptr>& syms_found)
1348 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1351 GElf_Shdr header_mem;
1352 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1355 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1356 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1359 elf_symbol::version ver;
1362 for (
size_t i = 0; i < symcount; ++i)
1365 sym = gelf_getsym(symtab, i, &sym_mem);
1366 name_str = elf_strptr(elf_handle,
1367 sym_tab_header->sh_link,
1370 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1378 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1379 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1388 sym_binding, sym_is_defined,
1389 sym_is_common, ver, sym_visibility);
1390 syms_found.push_back(symbol_found);
1429lookup_symbol_from_elf(
const environment& env,
1431 const string& symbol_name,
1433 vector<elf_symbol_sptr>& syms_found)
1435 size_t hash_table_index = 0, symbol_table_index = 0;
1436 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1441 symbol_table_index);
1443 if (ht_kind == NO_HASH_TABLE_KIND)
1448 return lookup_symbol_from_symtab(env,
1456 return lookup_symbol_from_elf_hash_tab(env,
1480lookup_public_function_symbol_from_elf(environment& env,
1482 const string& symbol_name,
1483 vector<elf_symbol_sptr>& func_syms)
1485 vector<elf_symbol_sptr> syms_found;
1488 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1491 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1492 i != syms_found.end();
1498 if ((type == elf_symbol::FUNC_TYPE
1499 || type == elf_symbol::GNU_IFUNC_TYPE
1500 || type == elf_symbol::COMMON_TYPE)
1501 && (binding == elf_symbol::GLOBAL_BINDING
1502 || binding == elf_symbol::WEAK_BINDING))
1504 func_syms.push_back(*i);
1525 int64_t const_value_;
1533 expr_result(
bool is_const)
1534 : is_const_(is_const),
1538 explicit expr_result(int64_t v)
1564 const_value(int64_t& value)
1568 value = const_value_;
1584 return const_value_;
1587 operator int64_t()
const
1588 {
return const_value();}
1591 operator=(
const int64_t v)
1599 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1602 operator>=(
const expr_result& o)
const
1603 {
return const_value_ >= o.const_value_;}
1606 operator<=(
const expr_result& o)
const
1607 {
return const_value_ <= o.const_value_;}
1610 operator>(
const expr_result& o)
const
1611 {
return const_value_ > o.const_value_;}
1614 operator<(
const expr_result& o)
const
1615 {
return const_value_ < o.const_value_;}
1620 expr_result r(*
this);
1621 r.const_value_ += v.const_value_;
1622 r.is_const_ = r.is_const_ && v.is_const_;
1627 operator+=(int64_t v)
1634 operator-(
const expr_result& v)
const
1636 expr_result r(*
this);
1637 r.const_value_ -= v.const_value_;
1638 r.is_const_ = r.is_const_ && v.is_const_;
1643 operator%(
const expr_result& v)
const
1645 expr_result r(*
this);
1646 r.const_value_ %= v.const_value_;
1647 r.is_const_ = r.is_const_ && v.is_const();
1652 operator*(
const expr_result& v)
const
1654 expr_result r(*
this);
1655 r.const_value_ *= v.const_value_;
1656 r.is_const_ = r.is_const_ && v.is_const();
1663 expr_result r(*
this);
1664 r.const_value_ |= v.const_value_;
1665 r.is_const_ = r.is_const_ && v.is_const_;
1670 operator^(
const expr_result& v)
const
1672 expr_result r(*
this);
1673 r.const_value_ ^= v.const_value_;
1674 r.is_const_ = r.is_const_ && v.is_const_;
1679 operator>>(
const expr_result& v)
const
1681 expr_result r(*
this);
1682 r.const_value_ = r.const_value_ >> v.const_value_;
1683 r.is_const_ = r.is_const_ && v.is_const_;
1690 expr_result r(*
this);
1691 r.const_value_ = r.const_value_ << v.const_value_;
1692 r.is_const_ = r.is_const_ && v.is_const_;
1699 expr_result r(*
this);
1700 r.const_value_ = ~r.const_value_;
1707 expr_result r(*
this);
1708 r.const_value_ = -r.const_value_;
1715 expr_result r = *
this;
1716 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1723 expr_result r(*
this);
1724 r.const_value_ &= o.const_value_;
1725 r.is_const_ = r.is_const_ && o.is_const_;
1730 operator/(
const expr_result& o)
1732 expr_result r(*
this);
1733 r.is_const_ = r.is_const_ && o.is_const_;
1734 return r.const_value() / o.const_value();
1740class expr_result_stack_type
1742 vector<expr_result> elems_;
1746 expr_result_stack_type()
1747 {elems_.reserve(4);}
1750 operator[](
unsigned i)
1752 unsigned s = elems_.size();
1754 return elems_[s - 1 -i];
1758 operator[](
unsigned i)
const
1759 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1763 {
return elems_.size();}
1765 vector<expr_result>::reverse_iterator
1767 {
return elems_.rbegin();}
1769 const vector<expr_result>::reverse_iterator
1771 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1773 vector<expr_result>::reverse_iterator
1775 {
return elems_.rend();}
1777 const vector<expr_result>::reverse_iterator
1779 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1783 {
return elems_.back();}
1787 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1790 push_front(expr_result e)
1791 {elems_.push_back(e);}
1796 expr_result r = front();
1802 erase(vector<expr_result>::reverse_iterator i)
1803 {elems_.erase(--i.base());}
1811struct dwarf_expr_eval_context
1814 expr_result_stack_type stack;
1819 dwarf_expr_eval_context()
1823 stack.push_front(expr_result(
true));
1830 stack.push_front(expr_result(
true));
1831 accum = expr_result(
false);
1832 set_tls_addr =
false;
1841 set_tls_address(
bool f)
1850 set_tls_address()
const
1851 {
return set_tls_addr;}
1856 expr_result r = stack.front();
1862 push(
const expr_result& v)
1863 {stack.push_front(v);}
1872typedef shared_ptr<reader> reader_sptr;
1879class reader :
public elf_based_reader
1886 template <
typename ContainerType>
1887 class die_source_dependant_container_set
1889 ContainerType primary_debug_info_container_;
1890 ContainerType alt_debug_info_container_;
1891 ContainerType type_unit_container_;
1905 ContainerType *result = 0;
1908 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1909 result = &primary_debug_info_container_;
1911 case ALT_DEBUG_INFO_DIE_SOURCE:
1912 result = &alt_debug_info_container_;
1914 case TYPE_UNIT_DIE_SOURCE:
1915 result = &type_unit_container_;
1917 case NO_DEBUG_INFO_DIE_SOURCE:
1918 case NUMBER_OF_DIE_SOURCES:
1931 const ContainerType&
1934 return const_cast<die_source_dependant_container_set*
>(
this)->
1935 get_container(source);
1949 get_container(
const reader& rdr,
const Dwarf_Die *die)
1951 const die_source source = rdr.get_die_source(die);
1952 return get_container(source);
1965 const ContainerType&
1966 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1968 return const_cast<die_source_dependant_container_set*
>(
this)->
1969 get_container(rdr, die);
1976 primary_debug_info_container_.clear();
1977 alt_debug_info_container_.clear();
1978 type_unit_container_.clear();
1985 unsigned number_of_suppressed_functions = 0;
1986 unsigned number_of_suppressed_variables = 0;
1987 unsigned number_of_allowed_functions = 0;
1988 unsigned number_of_allowed_variables = 0;
1994 number_of_suppressed_functions = 0;
1995 number_of_suppressed_variables = 0;
1996 number_of_allowed_functions = 0;
1997 number_of_allowed_variables = 0;
2001 unsigned short dwarf_version_;
2002 Dwarf_Die* cur_tu_die_;
2003 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
2007 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
2008 decl_die_repr_die_offsets_maps_;
2012 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
2013 type_die_repr_die_offsets_maps_;
2014 mutable die_source_dependant_container_set<die_istring_map_type>
2015 die_qualified_name_maps_;
2016 mutable die_source_dependant_container_set<die_istring_map_type>
2017 die_pretty_repr_maps_;
2018 mutable die_source_dependant_container_set<die_istring_map_type>
2019 die_pretty_type_repr_maps_;
2022 mutable die_source_dependant_container_set<die_artefact_map_type>
2023 decl_die_artefact_maps_;
2026 mutable die_source_dependant_container_set<die_artefact_map_type>
2027 type_die_artefact_maps_;
2030 mutable die_source_dependant_container_set<offset_offset_map_type>
2031 canonical_type_die_offsets_;
2034 mutable die_source_dependant_container_set<offset_offset_map_type>
2035 canonical_decl_die_offsets_;
2041 mutable std::unordered_map<std::pair<offset_type,offset_type>,
2043 dwarf_offset_pair_hash> die_comparison_results_;
2053 vector<type_base_sptr> types_to_canonicalize_;
2072 list<var_decl_sptr> var_decls_to_add_;
2073#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2074 bool debug_die_canonicalization_is_on_;
2075 bool use_canonical_die_comparison_;
2077 mutable size_t compare_count_;
2078 mutable size_t canonical_propagated_count_;
2079 mutable size_t cancelled_propagation_count_;
2080 mutable optional<bool> leverage_dwarf_factorization_;
2081 mutable stats stats_;
2116 reader(
const string& elf_path,
2117 const vector<char**>& debug_info_root_paths,
2118 environment& environment,
2119 bool load_all_types,
2120 bool linux_kernel_mode)
2122 debug_info_root_paths,
2125 reset(load_all_types, linux_kernel_mode);
2150 reset(
bool load_all_types,
bool linux_kernel_mode)
2154 decl_die_repr_die_offsets_maps_.clear();
2155 type_die_repr_die_offsets_maps_.clear();
2156 die_qualified_name_maps_.clear();
2157 die_pretty_repr_maps_.clear();
2158 die_pretty_type_repr_maps_.clear();
2159 decl_die_artefact_maps_.clear();
2160 type_die_artefact_maps_.clear();
2161 canonical_type_die_offsets_.clear();
2162 canonical_decl_die_offsets_.clear();
2163 die_wip_classes_map_.clear();
2164 alternate_die_wip_classes_map_.clear();
2165 type_unit_die_wip_classes_map_.clear();
2166 die_wip_function_types_map_.clear();
2167 alternate_die_wip_function_types_map_.clear();
2168 type_unit_die_wip_function_types_map_.clear();
2169 die_function_with_no_symbol_map_.clear();
2170 types_to_canonicalize_.clear();
2171 decl_only_classes_map_.clear();
2172 die_tu_map_.clear();
2176 primary_die_parent_map_.clear();
2177 tu_die_imported_unit_points_map_.clear();
2178 alt_tu_die_imported_unit_points_map_.clear();
2179 type_units_tu_die_imported_unit_points_map_.clear();
2180 alternate_die_parent_map_.clear();
2181 type_section_die_parent_map_.clear();
2182 var_decls_to_add_.clear();
2183 clear_per_translation_unit_data();
2184 clear_per_corpus_data();
2185 options().load_in_linux_kernel_mode = linux_kernel_mode;
2186 options().load_all_types = load_all_types;
2187#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
2188 debug_die_canonicalization_is_on_ =
2189 env().debug_die_canonicalization_is_on();
2190 use_canonical_die_comparison_ =
true;
2193 canonical_propagated_count_ = 0;
2194 cancelled_propagation_count_ = 0;
2195 load_in_linux_kernel_mode(linux_kernel_mode);
2218 const vector<char**>& debug_info_root_paths,
2219 bool load_all_types,
2220 bool linux_kernel_mode)
2223 reset(load_all_types, linux_kernel_mode);
2243 static dwarf::reader_sptr
2244 create(
const std::string& elf_path,
2245 const vector<char**>& debug_info_root_paths,
2246 environment& environment,
2247 bool load_all_types,
2248 bool linux_kernel_mode)
2250 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2251 environment, load_all_types,
2252 linux_kernel_mode));
2269 read_corpus(status& status)
2276 if (!(status & STATUS_OK))
2280 return corpus_sptr();
2296 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2297 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2299 return corpus_sptr();
2303 corpus_sptr corp = read_debug_info_into_corpus();
2305 status |= STATUS_OK;
2318 read_debug_info_into_corpus()
2323 origin |= corpus::DWARF_ORIGIN;
2324 corpus()->set_origin(origin);
2331 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2332 && !env().user_set_analyze_exported_interfaces_only())
2339 env().analyze_exported_interfaces_only(
true);
2345 corpus()->set_symtab(symtab());
2350 || !
corpus()->get_symtab()
2351 || !
corpus()->get_symtab()->has_symbols())
2354 uint8_t address_size = 0;
2355 size_t header_size = 0;
2357#ifdef WITH_DEBUG_SELF_COMPARISON
2358 if (env().self_comparison_debug_is_on())
2362 env().set_self_comparison_debug_input(g);
2364 env().set_self_comparison_debug_input(
corpus());
2368 env().priv_->do_log(do_log());
2373 tools_utils::timer t;
2376 cerr <<
"building die -> parent maps ...";
2380 build_die_parent_maps();
2385 cerr <<
" DONE@" <<
corpus()->get_path()
2392 env().canonicalization_is_done(
false);
2395 tools_utils::timer t;
2398 cerr <<
"DWARF Reader: building the "
2399 "libabigail internal representation ...\n";
2403 Dwarf_Half dwarf_vers = 0;
2404 for (Dwarf_Off offset = 0, next_offset = 0;
2406 offset, &next_offset, &header_size,
2407 &dwarf_vers, NULL, &address_size, NULL,
2409 offset = next_offset)
2411 Dwarf_Off die_offset = offset + header_size;
2415 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2418 dwarf_version(dwarf_vers);
2425 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2431 cerr <<
"DWARF Reader: building "
2432 <<
"the libabigail internal representation "
2433 <<
"DONE for corpus " <<
corpus()->get_path()
2438 cerr <<
"DWARF Reader: Number of aggregate types compared: "
2439 << compare_count_ <<
"\n"
2440 <<
"Number of canonical types propagated: "
2441 << canonical_propagated_count_ <<
"\n"
2442 <<
"Number of cancelled propagated canonical types:"
2443 << cancelled_propagation_count_ <<
"\n"
2444 <<
"Number of suppressed functions: "
2445 << stats_.number_of_suppressed_functions <<
"\n"
2446 <<
"Number of allowed functions: "
2447 << stats_.number_of_allowed_functions <<
"\n"
2448 <<
"Total number of fns in the corpus: "
2449 <<
corpus()->get_functions().size() <<
"\n"
2450 <<
"Total number of variables in the corpus: "
2451 <<
corpus()->get_variables().size() <<
"\n";
2456 tools_utils::timer t;
2459 cerr <<
"DWARF Reader: resolving declaration only classes ...";
2462 resolve_declaration_only_classes();
2466 cerr <<
" DONE@" <<
corpus()->get_path()
2474 tools_utils::timer t;
2477 cerr <<
"resolving declaration only enums ...";
2480 resolve_declaration_only_enums();
2484 cerr <<
" DONE@" <<
corpus()->get_path()
2492 tools_utils::timer t;
2495 cerr <<
"DWARF Reader: fixing up functions with linkage name but "
2496 <<
"no advertised underlying symbols ....";
2499 fixup_functions_with_no_symbols();
2503 cerr <<
" DONE@" <<
corpus()->get_path()
2510 merge_member_functions_in_classes_of_same_names();
2524 tools_utils::timer t;
2527 cerr <<
"DWARF Reader: perform late type canonicalizing ...\n";
2531 perform_late_type_canonicalizing();
2535 cerr <<
"DWARF Reader: late type canonicalizing DONE for "
2543 env().canonicalization_is_done(
true);
2546 tools_utils::timer t;
2549 cerr <<
"DWARF Reader: sort functions and variables ...";
2552 corpus()->sort_functions();
2553 corpus()->sort_variables();
2557 cerr <<
" DONE@" <<
corpus()->get_path()
2571 clear_per_translation_unit_data()
2573 while (!scope_stack().empty())
2574 scope_stack().pop();
2575 var_decls_to_re_add_to_tree().clear();
2576 per_tu_repr_to_fn_type_maps().clear();
2582 clear_per_corpus_data()
2584 die_qualified_name_maps_.clear();
2585 die_pretty_repr_maps_.clear();
2586 die_pretty_type_repr_maps_.clear();
2587 clear_types_to_canonicalize();
2602 {
return const_cast<reader*
>(
this)->env();}
2610 drop_undefined_syms()
const
2611 {
return options().drop_undefined_syms;}
2618 drop_undefined_syms(
bool f)
2619 {
options().drop_undefined_syms = f;}
2623 dwarf_version()
const
2624 {
return dwarf_version_;}
2627 dwarf_version(
unsigned short v)
2628 {dwarf_version_ = v;}
2640 dwarf_elf_handle()
const
2651 dwarf_is_splitted()
const
2652 {
return dwarf_elf_handle() != elf_handle();}
2661 dwarf_per_die_source(
die_source source)
const
2663 const Dwarf *result = 0;
2666 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2667 case TYPE_UNIT_DIE_SOURCE:
2670 case ALT_DEBUG_INFO_DIE_SOURCE:
2673 case NO_DEBUG_INFO_DIE_SOURCE:
2674 case NUMBER_OF_DIE_SOURCES:
2689 {
return cur_tu_die_;}
2692 cur_tu_die(Dwarf_Die* cur_tu_die)
2693 {cur_tu_die_ = cur_tu_die;}
2695 dwarf_expr_eval_context&
2696 dwarf_expr_eval_ctxt()
const
2697 {
return dwarf_expr_eval_context_;}
2704 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2705 decl_die_repr_die_offsets_maps()
const
2706 {
return decl_die_repr_die_offsets_maps_;}
2713 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2714 decl_die_repr_die_offsets_maps()
2715 {
return decl_die_repr_die_offsets_maps_;}
2722 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2723 type_die_repr_die_offsets_maps()
const
2724 {
return type_die_repr_die_offsets_maps_;}
2731 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2732 type_die_repr_die_offsets_maps()
2733 {
return type_die_repr_die_offsets_maps_;}
2746 compute_canonical_die_offset(
const Dwarf_Die *die,
2747 Dwarf_Off &canonical_die_offset,
2748 bool die_as_type)
const
2752 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2753 get_container(*
this, die)
2754 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2755 get_container(*
this, die);
2757 Dwarf_Die canonical_die;
2758 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2760 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2778 compute_canonical_die(
const Dwarf_Die *die,
2780 Dwarf_Die &canonical_die,
2781 bool die_as_type)
const
2783 const die_source source = get_die_source(die);
2785 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2787 compute_canonical_die(die_offset, source,
2789 canonical_die, die_as_type);
2809 compute_canonical_die(Dwarf_Off die_offset,
2812 Dwarf_Die &canonical_die,
2813 bool die_as_type)
const
2819 ? (
const_cast<reader*
>(
this)->
2820 type_die_repr_die_offsets_maps().get_container(source))
2821 : (
const_cast<reader*
>(
this)->
2822 decl_die_repr_die_offsets_maps().get_container(source));
2825 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2834 interned_string name =
2836 ? get_die_pretty_type_representation(&die, 0)
2837 : get_die_pretty_representation(&die, 0);
2839 Dwarf_Off canonical_die_offset = 0;
2840 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2844 offsets.push_back(die_offset);
2845 map[name] = offsets;
2846 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2847 get_die_from_offset(source, die_offset, &canonical_die);
2851 Dwarf_Off cur_die_offset;
2852 Dwarf_Die potential_canonical_die;
2853 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2854 o != i->second.end();
2857 cur_die_offset = *o;
2858 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2859 if (compare_dies(*
this, &die, &potential_canonical_die,
2862 canonical_die_offset = cur_die_offset;
2863 set_canonical_die_offset(canonical_dies, die_offset,
2864 canonical_die_offset);
2865 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2870 canonical_die_offset = die_offset;
2871 i->second.push_back(die_offset);
2872 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2873 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2892 get_canonical_die(
const Dwarf_Die *die,
2893 Dwarf_Die &canonical_die,
2897 const die_source source = get_die_source(die);
2901 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2902 get_container(source)
2903 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2904 get_container(source);
2906 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2907 if (Dwarf_Off canonical_die_offset =
2908 get_canonical_die_offset(canonical_dies, die_offset))
2910 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2918 ? (
const_cast<reader*
>(
this)->
2919 type_die_repr_die_offsets_maps().get_container(*
this, die))
2920 : (
const_cast<reader*
>(
this)->
2921 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2929 interned_string name =
2931 ? get_die_pretty_type_representation(die, where)
2932 : get_die_pretty_representation(die, where);
2934 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2938 Dwarf_Off cur_die_offset;
2939 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2940 o != i->second.end();
2943 cur_die_offset = *o;
2944 get_die_from_offset(source, cur_die_offset, &canonical_die);
2946 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2947 die, &canonical_die,
2950 set_canonical_die_offset(canonical_dies,
2984 get_or_compute_canonical_die(
const Dwarf_Die* die,
2985 Dwarf_Die& canonical_die,
2987 bool die_as_type)
const
2989 const die_source source = get_die_source(die);
2993 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2994 get_container(source)
2995 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2996 get_container(source);
2998 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3000 if (Dwarf_Off canonical_die_offset =
3001 get_canonical_die_offset(canonical_dies,
3002 initial_die_offset))
3004 get_die_from_offset(source, canonical_die_offset, &canonical_die);
3008 if (!is_type_die_to_be_canonicalized(die))
3015 ? (
const_cast<reader*
>(
this)->
3016 type_die_repr_die_offsets_maps().get_container(*
this, die))
3017 : (
const_cast<reader*
>(
this)->
3018 decl_die_repr_die_offsets_maps().get_container(*
this, die));
3026 interned_string name =
3028 ? get_die_pretty_type_representation(die, where)
3029 : get_die_pretty_representation(die, where);
3031 istring_dwarf_offsets_map_type::iterator i = map.find(name);
3035 offsets.push_back(initial_die_offset);
3036 map[name] = offsets;
3037 get_die_from_offset(source, initial_die_offset, &canonical_die);
3038 set_canonical_die_offset(canonical_dies,
3040 initial_die_offset);
3047 dwarf_offsets_type::size_type n = 0, s = i->second.size();
3050 Dwarf_Off die_offset = i->second[n];
3051 get_die_from_offset(source, die_offset, &canonical_die);
3053 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
3054 die, &canonical_die,
3057 set_canonical_die_offset(canonical_dies,
3067 get_die_from_offset(source, initial_die_offset, &canonical_die);
3068 i->second.push_back(initial_die_offset);
3069 set_canonical_die_offset(canonical_dies,
3071 initial_die_offset);
3088 get_die_source(
const Dwarf_Die *die)
const
3090 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
3111 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
3115 uint8_t address_size = 0, offset_size = 0;
3116 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
3117 &cu_die, &address_size,
3121 Dwarf_Half version = 0;
3122 Dwarf_Off abbrev_offset = 0;
3123 uint64_t type_signature = 0;
3124 Dwarf_Off type_offset = 0;
3125 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
3126 &version, &abbrev_offset,
3127 &address_size, &offset_size,
3128 &type_signature, &type_offset))
3131 int tag = dwarf_tag(&cu_kind);
3133 if (tag == DW_TAG_compile_unit
3134 || tag == DW_TAG_partial_unit)
3136 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
3138 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
3140 source = ALT_DEBUG_INFO_DIE_SOURCE;
3144 else if (tag == DW_TAG_type_unit)
3145 source = TYPE_UNIT_DIE_SOURCE;
3161 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
3163 if (source == TYPE_UNIT_DIE_SOURCE)
3164 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3167 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3194 associate_die_to_decl(Dwarf_Die* die,
3195 decl_base_sptr decl,
3196 size_t where_offset,
3197 bool do_associate_by_repr =
false)
3199 const die_source source = get_die_source(die);
3202 decl_die_artefact_maps().get_container(source);
3205 if (do_associate_by_repr)
3207 Dwarf_Die equiv_die;
3208 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
3211 die_offset = dwarf_dieoffset(&equiv_die);
3214 die_offset = dwarf_dieoffset(die);
3216 m[die_offset] = decl;
3238 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3240 decl_base_sptr result =
3241 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3266 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset,
3267 unordered_set<uint64_t>& guard)
const
3271 die_qualified_name_maps_.get_container(*
this, die);
3273 size_t die_offset = dwarf_dieoffset(die);
3274 die_istring_map_type::const_iterator i = map.find(die_offset);
3278 reader& rdr = *
const_cast<reader*
>(
this);
3279 string qualified_name = die_qualified_name(rdr, die,
3282 interned_string istr = env().intern(qualified_name);
3283 map[die_offset] = istr;
3303 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3305 return const_cast<reader*
>(
this)->
3306 get_die_qualified_name(die, where_offset);
3333 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset,
3334 unordered_set<uint64_t>& guard)
const
3339 if (die == cur_tu_die())
3340 return env().intern(
"");
3343 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3346 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3347 die_istring_map_type::const_iterator i =
3348 map.find(die_offset);
3352 reader& rdr = *
const_cast<reader*
>(
this);
3353 string qualified_name;
3354 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3355 if ((tag == DW_TAG_structure_type
3356 || tag == DW_TAG_class_type
3357 || tag == DW_TAG_union_type)
3358 && die_is_anonymous(die))
3360 die_class_or_enum_flat_representation(*
this, die,
"",
3366 qualified_name = die_qualified_type_name(rdr, die,
3370 interned_string istr = env().intern(qualified_name);
3371 map[die_offset] = istr;
3401 get_die_pretty_type_representation(
const Dwarf_Die *die,
3402 size_t where_offset,
3403 unordered_set<uint64_t>& guard)
const
3407 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3410 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3411 die_istring_map_type::const_iterator i = map.find(die_offset);
3415 reader& rdr = *
const_cast<reader*
>(
this);
3416 string pretty_representation =
3417 die_pretty_print_type(rdr, die, where_offset, guard);
3418 interned_string istr = env().intern(pretty_representation);
3419 map[die_offset] = istr;
3444 get_die_pretty_type_representation(
const Dwarf_Die *die,
3445 size_t where_offset)
const
3447 unordered_set<uint64_t> guard;
3448 return get_die_pretty_type_representation(die, where_offset, guard);
3470 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset,
3471 unordered_set<uint64_t>& guard)
const
3476 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3479 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3480 die_istring_map_type::const_iterator i = map.find(die_offset);
3484 reader& rdr = *
const_cast<reader*
>(
this);
3485 string pretty_representation =
3486 die_pretty_print(rdr, die, where_offset, guard);
3487 interned_string istr = env().intern(pretty_representation);
3488 map[die_offset] = istr;
3508 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3510 unordered_set<uint64_t> guard;
3511 return get_die_pretty_representation(die, where_offset, guard);
3531 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3534 lookup_artifact_from_die(die,
true);
3536 return fn->get_type();
3560 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3562 Dwarf_Die equiv_die;
3563 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3568 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3569 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3571 size_t die_offset = dwarf_dieoffset(&equiv_die);
3572 die_artefact_map_type::const_iterator i = m.find(die_offset);
3599 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3601 bool die_as_type =
false)
const
3605 ? type_die_artefact_maps().get_container(source)
3606 : decl_die_artefact_maps().get_container(source);
3608 die_artefact_map_type::const_iterator i = m.find(die_offset);
3651 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3666 if (!get_die_language(die, lang))
3677 die_source_dependant_container_set<die_artefact_map_type>&
3678 decl_die_artefact_maps()
3679 {
return decl_die_artefact_maps_;}
3686 const die_source_dependant_container_set<die_artefact_map_type>&
3687 decl_die_artefact_maps()
const
3688 {
return decl_die_artefact_maps_;}
3695 die_source_dependant_container_set<die_artefact_map_type>&
3696 type_die_artefact_maps()
3697 {
return type_die_artefact_maps_;}
3704 const die_source_dependant_container_set<die_artefact_map_type>&
3705 type_die_artefact_maps()
const
3706 {
return type_die_artefact_maps_;}
3714 per_tu_repr_to_fn_type_maps()
3715 {
return per_tu_repr_to_fn_type_maps_;}
3723 per_tu_repr_to_fn_type_maps()
const
3724 {
return per_tu_repr_to_fn_type_maps_;}
3734 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3737 if (!die_is_function_type(die))
3740 interned_string repr =
3741 get_die_pretty_type_representation(die, 0);
3744 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3755 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3757 if (!die_is_function_type(die))
3760 interned_string repr = die_name(die).empty() ?
3761 get_die_pretty_type_representation(die, 0)
3762 : get_die_pretty_representation(die, 0);
3765 istring_fn_type_map_type::const_iterator i =
3766 per_tu_repr_to_fn_type_maps().find(repr);
3768 if (i == per_tu_repr_to_fn_type_maps().end())
3785 Dwarf_Off die_offset,
3786 Dwarf_Off canonical_die_offset)
const
3788 canonical_dies[die_offset] = canonical_die_offset;}
3804 set_canonical_die_offset(Dwarf_Off die_offset,
3806 Dwarf_Off canonical_die_offset,
3807 bool die_as_type)
const
3811 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3812 get_container(source)
3813 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3814 get_container(source);
3816 set_canonical_die_offset(canonical_dies,
3818 canonical_die_offset);
3832 set_canonical_die_offset(
const Dwarf_Die *die,
3833 Dwarf_Off canonical_die_offset,
3834 bool die_as_type)
const
3836 const die_source source = get_die_source(die);
3838 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3840 set_canonical_die_offset(die_offset, source,
3841 canonical_die_offset,
3855 Dwarf_Off die_offset)
const
3857 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3858 if (it == canonical_dies.end())
3875 get_canonical_die_offset(Dwarf_Off die_offset,
3877 bool die_as_type)
const
3881 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3882 get_container(source)
3883 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3884 get_container(source);
3886 return get_canonical_die_offset(canonical_dies, die_offset);
3901 erase_canonical_die_offset(Dwarf_Off die_offset,
3903 bool die_as_type)
const
3907 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3908 get_container(source)
3909 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3910 get_container(source);
3912 return canonical_dies.erase(die_offset);
3925 associate_die_to_type(
const Dwarf_Die *die,
3926 type_base_sptr type,
3932 Dwarf_Die equiv_die;
3933 if (!get_or_compute_canonical_die(die, equiv_die, where,
3938 type_die_artefact_maps().get_container(*
this, &equiv_die);
3940 size_t die_offset = dwarf_dieoffset(&equiv_die);
3941 m[die_offset] = type;
3955 lookup_type_from_die(
const Dwarf_Die* die)
const
3958 lookup_artifact_from_die(die,
true);
3960 return fn->get_type();
3978 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3980 type_base_sptr result;
3982 type_die_artefact_maps().get_container(source);
3983 die_artefact_map_type::const_iterator i = m.find(die_offset);
3987 return fn->get_type();
3995 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
4005 die_wip_function_types_map(source);
4006 die_function_type_map_type::const_iterator i = m.find(die_offset);
4025 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
4040 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4042 case ALT_DEBUG_INFO_DIE_SOURCE:
4043 return alternate_die_wip_classes_map_;
4044 case TYPE_UNIT_DIE_SOURCE:
4045 return type_unit_die_wip_classes_map_;
4046 case NO_DEBUG_INFO_DIE_SOURCE:
4047 case NUMBER_OF_DIE_SOURCES:
4050 return die_wip_classes_map_;
4061 die_wip_function_types_map(
die_source source)
const
4062 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
4072 die_wip_function_types_map(
die_source source)
4076 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4078 case ALT_DEBUG_INFO_DIE_SOURCE:
4079 return alternate_die_wip_function_types_map_;
4080 case TYPE_UNIT_DIE_SOURCE:
4081 return type_unit_die_wip_function_types_map_;
4082 case NO_DEBUG_INFO_DIE_SOURCE:
4083 case NUMBER_OF_DIE_SOURCES:
4086 return die_wip_function_types_map_;
4097 die_function_decl_with_no_symbol_map()
4098 {
return die_function_with_no_symbol_map_;}
4111 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
4113 die_class_or_union_map_type::const_iterator i =
4114 die_wip_classes_map(source).find(offset);
4115 return (i != die_wip_classes_map(source).end());
4129 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
4131 die_function_type_map_type::const_iterator i =
4132 die_wip_function_types_map(source).find(offset);
4133 return (i != die_wip_function_types_map(source).end());
4152 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
4158 || dwarf_tag(die) != DW_TAG_member
4159 || !die_name(die).empty())
4165 if (die_is_anonymous_data_member(die))
4171 int64_t offset_in_bits = 0;
4172 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
4176 loc = die_location(*
this, die);
4181 std::ostringstream o;
4182 o <<
"unnamed-dm-@-";
4184 o <<
"offset-" << offset_in_bits <<
"bits";
4186 o <<
"loc-" << loc.expand();
4199 declaration_only_classes()
const
4200 {
return decl_only_classes_map_;}
4210 declaration_only_classes()
4211 {
return decl_only_classes_map_;}
4223 maybe_schedule_declaration_only_class_for_resolution(cou);
4225 maybe_schedule_declaration_only_enum_for_resolution(e);
4234 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
4236 if (cou->get_is_declaration_only()
4237 && cou->get_definition_of_declaration() == 0
4242 && !cou->get_qualified_name().empty())
4244 string qn = cou->get_qualified_name();
4245 string_classes_or_unions_map::iterator record =
4246 declaration_only_classes().find(qn);
4247 if (record == declaration_only_classes().end())
4248 declaration_only_classes()[qn].push_back(cou);
4250 record->second.push_back(cou);
4262 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4264 if (cou->get_is_declaration_only())
4265 return ((declaration_only_classes().find(cou->get_qualified_name())
4266 != declaration_only_classes().end())
4267 || (declaration_only_classes().find(cou->get_name())
4268 != declaration_only_classes().end()));
4291 const environment& e = l->get_environment();
4295 && l->
kind() == r->kind()
4296 && ((l->get_corpus() && r->get_corpus()
4297 && (l->get_corpus() == r->get_corpus()))
4298 ||(l->get_translation_unit()
4299 && r->get_translation_unit()
4300 && l->get_translation_unit() == r->get_translation_unit())))
4309 decl_base *ld =
is_decl(l.get());
4310 decl_base *rd =
is_decl(r.get());
4312 if (ld->get_qualified_name() != rd->get_qualified_name())
4315 location ll = ld->get_location(), rl = rd->get_location();
4318 string l1 = ll.expand();
4319 string l2 = rl.expand();
4325 e.priv_->allow_type_comparison_results_caching(
true);
4326 bool s0 = e.decl_only_class_equals_definition();
4327 e.decl_only_class_equals_definition(
true);
4328 bool equal = l == r;
4329 e.decl_only_class_equals_definition(s0);
4330 e.priv_->clear_type_comparison_results_cache();
4331 e.priv_->allow_type_comparison_results_caching(
false);
4338 resolve_declaration_only_classes()
4340 vector<string> resolved_classes;
4342 for (string_classes_or_unions_map::iterator i =
4343 declaration_only_classes().begin();
4344 i != declaration_only_classes().end();
4347 bool to_resolve =
false;
4348 for (classes_or_unions_type::iterator j = i->second.begin();
4349 j != i->second.end();
4351 if ((*j)->get_is_declaration_only()
4352 && ((*j)->get_definition_of_declaration() == 0))
4357 resolved_classes.push_back(i->first);
4402 map<string, class_or_union_sptr> per_tu_class_map;
4403 for (type_base_wptrs_type::const_iterator c = classes->begin();
4404 c != classes->end();
4411 if (klass->get_is_declaration_only())
4414 string tu_path = klass->get_translation_unit()->get_absolute_path();
4415 if (tu_path.empty())
4421 per_tu_class_map[tu_path] = klass;
4424 if (!per_tu_class_map.empty())
4430 for (classes_or_unions_type::iterator j = i->second.begin();
4431 j != i->second.end();
4434 if ((*j)->get_is_declaration_only()
4435 && ((*j)->get_definition_of_declaration() == 0))
4438 (*j)->get_translation_unit()->get_absolute_path();
4439 map<string, class_or_union_sptr>::const_iterator e =
4440 per_tu_class_map.find(tu_path);
4441 if (e != per_tu_class_map.end())
4442 (*j)->set_definition_of_declaration(e->second);
4443 else if (per_tu_class_map.size() == 1)
4444 (*j)->set_definition_of_declaration
4445 (per_tu_class_map.begin()->second);
4455 class_or_union_sptr>::const_iterator it;
4456 class_or_union_sptr first_class =
4457 per_tu_class_map.begin()->second;
4458 bool all_class_definitions_are_equal =
true;
4459 for (it = per_tu_class_map.begin();
4460 it != per_tu_class_map.end();
4463 if (it == per_tu_class_map.begin())
4467 if (!compare_before_canonicalisation(it->second,
4470 all_class_definitions_are_equal =
false;
4475 if (all_class_definitions_are_equal)
4476 (*j)->set_definition_of_declaration(first_class);
4480 resolved_classes.push_back(i->first);
4484 size_t num_decl_only_classes = declaration_only_classes().size(),
4485 num_resolved = resolved_classes.size();
4487 cerr <<
"resolved " << num_resolved
4488 <<
" class declarations out of "
4489 << num_decl_only_classes
4492 for (vector<string>::const_iterator i = resolved_classes.begin();
4493 i != resolved_classes.end();
4495 declaration_only_classes().erase(*i);
4497 if (show_stats() && !declaration_only_classes().empty())
4499 cerr <<
"Here are the "
4500 << num_decl_only_classes - num_resolved
4501 <<
" unresolved class declarations:\n";
4502 for (string_classes_or_unions_map::iterator i =
4503 declaration_only_classes().begin();
4504 i != declaration_only_classes().end();
4506 cerr <<
" " << i->first <<
"\n";
4518 declaration_only_enums()
const
4519 {
return decl_only_enums_map_;}
4529 declaration_only_enums()
4530 {
return decl_only_enums_map_;}
4540 if (enom->get_is_declaration_only()
4541 && enom->get_definition_of_declaration() == 0
4546 && !enom->get_qualified_name().empty())
4548 string qn = enom->get_qualified_name();
4549 string_enums_map::iterator record =
4550 declaration_only_enums().find(qn);
4551 if (record == declaration_only_enums().end())
4552 declaration_only_enums()[qn].push_back(enom);
4554 record->second.push_back(enom);
4568 if (enom->get_is_declaration_only())
4569 return (declaration_only_enums().find(enom->get_qualified_name())
4570 != declaration_only_enums().end());
4583 resolve_declaration_only_enums()
4585 vector<string> resolved_enums;
4587 for (string_enums_map::iterator i =
4588 declaration_only_enums().begin();
4589 i != declaration_only_enums().end();
4592 bool to_resolve =
false;
4593 for (enums_type::iterator j = i->second.begin();
4594 j != i->second.end();
4596 if ((*j)->get_is_declaration_only()
4597 && ((*j)->get_definition_of_declaration() == 0))
4602 resolved_enums.push_back(i->first);
4644 map<string, enum_type_decl_sptr> per_tu_enum_map;
4645 for (type_base_wptrs_type::const_iterator c = enums->begin();
4653 if (enom->get_is_declaration_only())
4656 string tu_path = enom->get_translation_unit()->get_absolute_path();
4657 if (tu_path.empty())
4663 per_tu_enum_map[tu_path] = enom;
4666 if (!per_tu_enum_map.empty())
4672 for (enums_type::iterator j = i->second.begin();
4673 j != i->second.end();
4676 if ((*j)->get_is_declaration_only()
4677 && ((*j)->get_definition_of_declaration() == 0))
4680 (*j)->get_translation_unit()->get_absolute_path();
4681 map<string, enum_type_decl_sptr>::const_iterator e =
4682 per_tu_enum_map.find(tu_path);
4683 if (e != per_tu_enum_map.end())
4684 (*j)->set_definition_of_declaration(e->second);
4685 else if (per_tu_enum_map.size() == 1)
4686 (*j)->set_definition_of_declaration
4687 (per_tu_enum_map.begin()->second);
4699 per_tu_enum_map.begin()->second;
4700 bool all_enum_definitions_are_equal =
true;
4701 for (it = per_tu_enum_map.begin();
4702 it != per_tu_enum_map.end();
4705 if (it == per_tu_enum_map.begin())
4709 if (!compare_before_canonicalisation(it->second,
4712 all_enum_definitions_are_equal =
false;
4717 if (all_enum_definitions_are_equal)
4718 (*j)->set_definition_of_declaration(first_enum);
4722 resolved_enums.push_back(i->first);
4726 size_t num_decl_only_enums = declaration_only_enums().size(),
4727 num_resolved = resolved_enums.size();
4729 cerr <<
"resolved " << num_resolved
4730 <<
" enum declarations out of "
4731 << num_decl_only_enums
4734 for (vector<string>::const_iterator i = resolved_enums.begin();
4735 i != resolved_enums.end();
4737 declaration_only_enums().erase(*i);
4739 if (show_stats() && !declaration_only_enums().empty())
4741 cerr <<
"Here are the "
4742 << num_decl_only_enums - num_resolved
4743 <<
" unresolved enum declarations:\n";
4744 for (string_enums_map::iterator i = declaration_only_enums().begin();
4745 i != declaration_only_enums().end();
4747 cerr <<
" " << i->first <<
"\n";
4763 corpus_sptr corp =
corpus();
4767 interned_string
id = corp->get_environment().intern(fn->get_id_string());
4769 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4774 if (f->get_symbol())
4794 fixup_functions_with_no_symbols()
4796 corpus_sptr corp =
corpus();
4801 die_function_decl_with_no_symbol_map();
4804 cerr << fns_with_no_symbol.size()
4805 <<
" functions to fixup, potentially\n";
4807 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4808 i != fns_with_no_symbol.end();
4811 corp->lookup_function_symbol(i->second->get_linkage_name()))
4826 if (i->second->get_symbol()
4827 || symbol_already_belongs_to_a_function(sym))
4832 i->second->set_symbol(sym);
4835 cerr <<
"fixed up '"
4836 << i->second->get_pretty_representation()
4837 <<
"' with symbol '"
4838 << sym->get_id_string()
4842 fns_with_no_symbol.clear();
4855 for (
auto method : src_class->get_member_functions())
4856 if (!method->get_linkage_name().empty())
4857 if (!dest_class->find_member_function(method->get_linkage_name()))
4859 method_decl_sptr copied_method =
4862 schedule_type_for_late_canonicalization(copied_method->get_type());
4873 template <
typename iterator_type>
4875 contains_anonymous_class(
const iterator_type& begin,
4876 const iterator_type& end)
4878 for (
auto i = begin; i < end; ++i)
4880 type_base_sptr t(*i);
4882 if (c && c->get_is_anonymous())
4898 template <
typename iterator_type>
4900 merge_member_functions_of_classes(
const iterator_type& begin,
4901 const iterator_type& end)
4903 if (contains_anonymous_class(begin, end))
4906 for (
auto i = begin; i < end; ++i)
4908 type_base_sptr t(*i);
4910 if (!reference_class)
4913 string n1 = reference_class->get_pretty_representation(
true,
true);
4915 for (
auto j = begin; j < end; ++j)
4920 type_base_sptr type(*j);
4925 n2 = klass->get_pretty_representation(
true,
true);
4928 copy_missing_member_functions(reference_class, klass);
4929 copy_missing_member_functions(klass, reference_class);
4938 merge_member_functions_in_classes_of_same_names()
4940 corpus_sptr abi =
corpus();
4945 abi->get_types().class_types();
4947 for (
auto entry : class_types)
4949 auto& classes = entry.second;
4950 if (classes.size() > 1)
4952 bool a_class_has_member_fns =
false;
4953 for (
auto& c : classes)
4955 type_base_sptr t(c);
4957 if (!klass->get_member_functions().empty())
4959 a_class_has_member_fns =
true;
4963 if (a_class_has_member_fns)
4964 merge_member_functions_of_classes(classes.begin(),
4972 const vector<type_base_sptr>&
4973 types_to_canonicalize()
const
4974 {
return types_to_canonicalize_;}
4978 vector<type_base_sptr>&
4979 types_to_canonicalize()
4980 {
return types_to_canonicalize_;}
4984 clear_types_to_canonicalize()
4986 types_to_canonicalize_.clear();
4994 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4996 types_to_canonicalize_.push_back(t);
5006 canonicalize_types_scheduled()
5008 tools_utils::timer cn_timer;
5011 cerr <<
"DWARF Reader is going to canonicalize "
5013 << types_to_canonicalize().size()
5015 corpus_sptr c =
corpus();
5017 cerr <<
" from corpus " <<
corpus()->get_path() <<
"\n";
5022 (types_to_canonicalize().begin(),
5023 types_to_canonicalize().end(),
5024 [](
const vector<type_base_sptr>::const_iterator& i)
5025 {
return *i;}, do_log(), show_stats());
5030 cerr <<
"DWARF Reader finished types "
5031 <<
"sorting, hashing & canonicalizing in: "
5032 << cn_timer <<
"\n";
5049 add_late_canonicalized_types_stats(
size_t& canonicalized,
5050 size_t& missed)
const
5052 for (
auto t : types_to_canonicalize())
5054 if (t->get_canonical_type())
5064 perform_late_type_canonicalizing()
5066 canonicalize_types_scheduled();
5070 size_t num_canonicalized = 0, num_missed = 0, total = 0;
5071 add_late_canonicalized_types_stats(num_canonicalized,
5073 total = num_canonicalized + num_missed;
5077 cerr <<
" # late canonicalized types: "
5078 << num_canonicalized;
5080 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
5082 <<
" # missed canonicalization opportunities: "
5085 cerr <<
" (" << num_missed * 100 / total <<
"%)";
5093 {
return die_tu_map_;}
5097 {
return die_tu_map_;}
5106 tu_die_imported_unit_points_map(
die_source source)
const
5107 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
5116 tu_die_imported_unit_points_map(
die_source source)
5120 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
5122 case ALT_DEBUG_INFO_DIE_SOURCE:
5123 return alt_tu_die_imported_unit_points_map_;
5124 case TYPE_UNIT_DIE_SOURCE:
5125 return type_units_tu_die_imported_unit_points_map_;
5126 case NO_DEBUG_INFO_DIE_SOURCE:
5127 case NUMBER_OF_DIE_SOURCES:
5131 return tu_die_imported_unit_points_map_;
5149 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
5162 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
5164 case ALT_DEBUG_INFO_DIE_SOURCE:
5165 return alternate_die_parent_map_;
5166 case TYPE_UNIT_DIE_SOURCE:
5167 return type_section_die_parent_map();
5168 case NO_DEBUG_INFO_DIE_SOURCE:
5169 case NUMBER_OF_DIE_SOURCES:
5172 return primary_die_parent_map_;
5176 type_section_die_parent_map()
const
5177 {
return type_section_die_parent_map_;}
5180 type_section_die_parent_map()
5181 {
return type_section_die_parent_map_;}
5187 cur_transl_unit()
const
5211 global_scope()
const
5212 {
return cur_transl_unit()->get_global_scope();}
5219 {
return nil_scope_;}
5223 {
return scope_stack_;}
5227 {
return scope_stack_;}
5232 if (scope_stack().empty())
5234 if (cur_transl_unit())
5237 return scope_stack().top();
5240 list<var_decl_sptr>&
5241 var_decls_to_re_add_to_tree()
5242 {
return var_decls_to_add_;}
5255 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
const
5257 if (!die || !die_is_decl(die))
5260 bool result =
false, address_found =
false, symbol_is_exported =
false;;
5261 Dwarf_Addr decl_symbol_address = 0;
5263 if (die_is_variable_decl(die))
5265 if ((address_found = get_variable_address(die, decl_symbol_address)))
5266 symbol_is_exported =
5269 else if (die_is_function_decl(die))
5271 if ((address_found = get_function_address(die, decl_symbol_address)))
5272 symbol_is_exported =
5277 result = symbol_is_exported;
5288 is_decl_die_with_undefined_symbol(
const Dwarf_Die *die)
const
5290 if (is_decl_die_with_exported_symbol(die))
5293 string name, linkage_name;
5294 die_name_and_linkage_name(die, name, linkage_name);
5295 if (linkage_name.empty())
5296 linkage_name = name;
5298 bool result =
false;
5299 if ((die_is_variable_decl(die)
5302 (die_is_function_decl(die)
5323 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
5329 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
5331 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
5333 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
5335 dwarf_elf_load_address));
5338 if (dwarf_is_splitted()
5339 && (dwarf_elf_load_address != elf_load_address))
5350 addr = addr - dwarf_elf_load_address + elf_load_address;
5376 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
5381 Elf* elf = elf_handle();
5383 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5385 if (elf_header->e_type == ET_REL)
5398 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5423 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
5425 Elf* elf = elf_handle();
5427 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5429 if (elf_header->e_type == ET_REL)
5442 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5461 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5462 Dwarf_Addr& address)
const
5465 Dwarf_Addr end_addr;
5466 ptrdiff_t offset = 0;
5470 Dwarf_Addr addr = 0, fn_addr = 0;
5471 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5473 fn_addr = maybe_adjust_fn_sym_address(addr);
5480 }
while (offset > 0);
5498 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5500 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5501 DW_AT_low_pc, address))
5507 if (!get_first_exported_fn_address_from_DW_AT_ranges
5508 (
const_cast<Dwarf_Die*
>(function_die),
5512 address = maybe_adjust_fn_sym_address(address);
5531 get_variable_address(
const Dwarf_Die* variable_die,
5532 Dwarf_Addr& address)
const
5534 bool is_tls_address =
false;
5535 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5536 address, is_tls_address))
5538 if (!is_tls_address)
5539 address = maybe_adjust_var_sym_address(address);
5546 corpus::exported_decls_builder*
5547 exported_decls_builder()
5548 {
return corpus()->get_exported_decls_builder().get();}
5556 load_all_types()
const
5557 {
return options().load_all_types;}
5565 load_all_types(
bool f)
5566 {
options().load_all_types = f;}
5569 load_in_linux_kernel_mode()
const
5570 {
return options().load_in_linux_kernel_mode;}
5573 load_in_linux_kernel_mode(
bool f)
5574 {
options().load_in_linux_kernel_mode = f;}
5586 load_undefined_interfaces()
const
5597 leverage_dwarf_factorization()
const
5599 if (!leverage_dwarf_factorization_.has_value())
5601 if (
options().leverage_dwarf_factorization
5602 && elf_helpers::find_section_by_name(elf_handle(),
5603 ".gnu_debugaltlink"))
5604 leverage_dwarf_factorization_ =
true;
5606 leverage_dwarf_factorization_ =
false;
5608 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5610 return *leverage_dwarf_factorization_;
5621 {
return options().show_stats;}
5670 build_die_parent_relations_under(Dwarf_Die* die,
5680 if (dwarf_child(die, &child) != 0)
5685 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5686 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5688 Dwarf_Die imported_unit;
5689 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5700 && die_has_children(&imported_unit))
5702 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5703 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5704 imported_units.push_back
5705 (imported_unit_point(dwarf_dieoffset(&child),
5707 imported_unit_die_source));
5710 build_die_parent_relations_under(&child, source, imported_units);
5712 while (dwarf_siblingof(&child, &child) == 0);
5744 case translation_unit::LANG_UNKNOWN:
5745#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5746 case translation_unit::LANG_Mips_Assembler:
5773 build_die_parent_maps()
5775 bool we_do_have_to_build_die_parent_map =
false;
5776 uint8_t address_size = 0;
5777 size_t header_size = 0;
5782 for (Dwarf_Off offset = 0, next_offset = 0;
5784 offset, &next_offset, &header_size,
5785 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5786 offset = next_offset)
5788 Dwarf_Off die_offset = offset + header_size;
5795 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5797 if (do_we_build_die_parent_maps(lang))
5798 we_do_have_to_build_die_parent_map =
true;
5801 if (!we_do_have_to_build_die_parent_map)
5806 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5807 for (Dwarf_Off offset = 0, next_offset = 0;
5809 offset, &next_offset, &header_size,
5810 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5811 offset = next_offset)
5813 Dwarf_Off die_offset = offset + header_size;
5821 tu_die_imported_unit_points_map(source)[die_offset] =
5823 build_die_parent_relations_under(&cu, source, imported_units);
5828 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5831 for (Dwarf_Off offset = 0, next_offset = 0;
5833 offset, &next_offset, &header_size,
5834 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5835 offset = next_offset)
5837 Dwarf_Off die_offset = offset + header_size;
5844 tu_die_imported_unit_points_map(source)[die_offset] =
5846 build_die_parent_relations_under(&cu, source, imported_units);
5851 source = TYPE_UNIT_DIE_SOURCE;
5854 uint64_t type_signature = 0;
5855 Dwarf_Off type_offset;
5856 for (Dwarf_Off offset = 0, next_offset = 0;
5858 offset, &next_offset, &header_size,
5859 NULL, NULL, &address_size, NULL,
5860 &type_signature, &type_offset) == 0);
5861 offset = next_offset)
5863 Dwarf_Off die_offset = offset + header_size;
5871 tu_die_imported_unit_points_map(source)[die_offset] =
5873 build_die_parent_relations_under(&cu, source, imported_units);
5888struct offset_pairs_stack_type
5905 offset_pairs_stack_type(
const reader& rdr)
5931 offset_pair_vector_type::iterator i;
5933 for (i = vect_.begin();i < vect_.end(); ++i)
5937 if (i != vect_.end())
5956 if (set_.find(p) == set_.end())
5983 bool result =
false;
5988 offset_pair_vector_type::const_iterator i;
5989 for (i = vect_.begin(); i != vect_.end(); ++i)
5993 if (i == vect_.end())
5998 for (++i; i != vect_.end(); ++i)
6000 pairs.push_back(*i);
6020 for (
auto type_pair : dependant_types)
6021 dependant_types_[type_pair].push_back(p);
6032 get_pairs_that_depend_on(p, dependant_types);
6035 auto it = redundant_types_.find(p);
6036 if (it == redundant_types_.end())
6038 auto entry = std::make_pair(p, dependant_types);
6039 redundant_types_.insert(entry);
6042 it->second.insert(it->second.end(),
6043 dependant_types.begin(),
6044 dependant_types.end());
6048 record_dependant_types(p, dependant_types);
6059 auto i = redundant_types_.find(p);
6060 if (i != redundant_types_.end())
6073 auto i = dependant_types_.find(p);
6074 if (i == dependant_types_.end())
6092 bool erase_cached_results =
false)
6096 auto redundant_type = redundant_types_.find(p);
6097 if (redundant_type != redundant_types_.end())
6099 for (
auto dependant_type : redundant_type->second)
6103 auto dependant_types_it = dependant_types_.find(dependant_type);
6104 ABG_ASSERT(dependant_types_it != dependant_types_.end());
6108 auto i = dependant_types_it->second.begin();
6109 for (; i!= dependant_types_it->second.end();++i)
6112 if (i != dependant_types_it->second.end())
6113 dependant_types_it->second.erase(i);
6118 if (dependant_types_it->second.empty())
6120 if (erase_cached_results)
6121 rdr_.die_comparison_results_.erase(dependant_type);
6122 dependant_types_.erase(dependant_types_it);
6126 if (erase_cached_results)
6127 rdr_.die_comparison_results_.erase(p);
6128 redundant_types_.erase(p);
6140 {erase_redundant_type_pair_entry(p,
true);}
6153 get_dependant_types(p, dependant_types,
true);
6154 for (
auto dependant_type : dependant_types)
6158 if (rdr_.propagated_types_.find(dependant_type)
6159 != rdr_.propagated_types_.end())
6161 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
6162 dependant_type.first.source_,
6164 rdr_.propagated_types_.erase(dependant_type);
6165 rdr_.cancelled_propagation_count_++;
6169 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
6170 if (comp_result_it != rdr_.die_comparison_results_.end())
6171 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
6175 auto comp_result_it = rdr_.die_comparison_results_.find(p);
6176 if (comp_result_it != rdr_.die_comparison_results_.end())
6183 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
6184 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
6185 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
6188 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
6190 rdr_.erase_canonical_die_offset(p.first.offset_,
6193 rdr_.propagated_types_.erase(p);
6194 rdr_.cancelled_propagation_count_++;
6213 bool transitive_closure =
false)
6215 auto i = redundant_types_.find(p);
6216 if (i != redundant_types_.end())
6218 for (
auto dependant_type : i->second)
6219 if (result.find(dependant_type) == result.end())
6221 result.insert(dependant_type);
6222 if (transitive_closure)
6223 get_dependant_types(p, result,
true);
6232build_ir_node_from_die(reader& rdr,
6235 bool called_from_public_decl,
6236 size_t where_offset,
6237 bool is_declaration_only =
true,
6238 bool is_required_decl_spec =
false);
6241build_ir_node_from_die(reader& rdr,
6243 bool called_from_public_decl,
6244 size_t where_offset);
6246static decl_base_sptr
6247build_ir_node_for_void_type(reader& rdr);
6250build_ir_node_for_void_pointer_type(reader& rdr);
6253add_or_update_class_type(reader& rdr,
6258 bool called_from_public_decl,
6259 size_t where_offset,
6260 bool is_declaration_only);
6262static union_decl_sptr
6263add_or_update_union_type(reader& rdr,
6266 union_decl_sptr union_type,
6267 bool called_from_public_decl,
6268 size_t where_offset,
6269 bool is_declaration_only);
6271static decl_base_sptr
6272build_ir_node_for_void_type(reader& rdr);
6274static decl_base_sptr
6275build_ir_node_for_variadic_parameter_type(reader &rdr);
6278build_function_decl(reader& rdr,
6280 size_t where_offset,
6284function_is_suppressed(
const reader& rdr,
6285 const scope_decl* scope,
6286 Dwarf_Die *function_die,
6287 bool is_declaration_only);
6290build_or_get_fn_decl_if_not_suppressed(reader& rdr,
6293 size_t where_offset,
6294 bool is_declaration_only,
6298build_var_decl(reader& rdr,
6300 size_t where_offset,
6304build_or_get_var_decl_if_not_suppressed(reader& rdr,
6307 size_t where_offset,
6308 bool is_declaration_only,
6310 bool is_required_decl_spec =
false);
6312variable_is_suppressed(
const reader& rdr,
6313 const scope_decl* scope,
6314 Dwarf_Die *variable_die,
6315 bool is_declaration_only,
6316 bool is_required_decl_spec =
false);
6319finish_member_function_reading(Dwarf_Die* die,
6321 const class_or_union_sptr klass,
6330die_is_anonymous(
const Dwarf_Die* die)
6332 Dwarf_Attribute attr;
6333 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
6347die_is_anonymous_data_member(
const Dwarf_Die* die)
6350 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
6351 || !die_name(die).empty())
6355 if (!die_die_attribute(die, DW_AT_type, type_die))
6358 if (dwarf_tag(&type_die) != DW_TAG_structure_type
6359 && dwarf_tag(&type_die) != DW_TAG_union_type)
6376die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6381 Dwarf_Attribute attr;
6382 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6385 const char* str = dwarf_formstring(&attr);
6386 return str ? str :
"";
6400die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
6405 Dwarf_Attribute attr;
6406 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6409 const char* str = dwarf_formstring(&attr);
6429die_unsigned_constant_attribute(
const Dwarf_Die* die,
6436 Dwarf_Attribute attr;
6437 Dwarf_Word result = 0;
6438 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6439 || dwarf_formudata(&attr, &result))
6459die_signed_constant_attribute(
const Dwarf_Die *die,
6466 Dwarf_Attribute attr;
6467 Dwarf_Sword result = 0;
6468 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6469 || dwarf_formsdata(&attr, &result))
6495die_constant_attribute(
const Dwarf_Die *die,
6498 array_type_def::subrange_type::bound_value &value)
6503 if (!die_unsigned_constant_attribute(die, attr_name, l))
6505 value.set_unsigned(l);
6510 if (!die_signed_constant_attribute(die, attr_name, l))
6512 value.set_signed(l);
6527form_is_DW_FORM_strx(
unsigned form)
6531#if defined HAVE_DW_FORM_strx1 \
6532 && defined HAVE_DW_FORM_strx2 \
6533 && defined HAVE_DW_FORM_strx3 \
6534 && defined HAVE_DW_FORM_strx4
6535 if (form == DW_FORM_strx1
6536 || form == DW_FORM_strx2
6537 || form == DW_FORM_strx3
6538 ||form == DW_FORM_strx4)
6555form_is_DW_FORM_line_strp(
unsigned form)
6559#if defined HAVE_DW_FORM_line_strp
6560 if (form == DW_FORM_line_strp)
6587die_flag_attribute(
const Dwarf_Die* die,
6590 bool recursively =
true)
6592 Dwarf_Attribute attr;
6594 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6595 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6599 if (dwarf_formflag(&attr, &f))
6613die_linkage_name(
const Dwarf_Die* die)
6618 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6619 if (linkage_name.empty())
6620 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6621 return linkage_name;
6635die_decl_file_attribute(
const Dwarf_Die* die)
6640 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6642 return str ? str :
"";
6663die_die_attribute(
const Dwarf_Die* die,
6668 Dwarf_Attribute attr;
6670 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6671 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6674 return dwarf_formref_die(&attr, &result);
6699die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die)
6701 if (die_die_attribute(die, DW_AT_specification, origin_die,
true)
6702 || die_die_attribute(die, DW_AT_abstract_origin, origin_die,
true))
6704 while (die_die_attribute(&origin_die,
6705 DW_AT_specification,
6707 || die_die_attribute(&origin_die,
6708 DW_AT_abstract_origin,
6746subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6748 Dwarf_Die& referenced_subrange)
6750 bool result =
false;
6752 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6755 Dwarf_Die referenced_die;
6756 if (die_die_attribute(die, attr_name, referenced_die))
6758 unsigned tag = dwarf_tag(&referenced_die);
6759 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6762 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6764 tag = dwarf_tag(&type_die);
6765 if (tag == DW_TAG_subrange_type)
6767 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6803subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6805 array_type_def::subrange_type::bound_value& v,
6808 bool result =
false;
6810 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6813 Dwarf_Die subrange_die;
6814 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6817 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6835die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6837 Dwarf_Attribute attr;
6838 if (!dwarf_attr_integrate(die, attr_name, &attr))
6840 return dwarf_formaddr(&attr, &result) == 0;
6851die_location(
const reader& rdr,
const Dwarf_Die* die)
6856 string file = die_decl_file_attribute(die);
6858 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6860 if (!file.empty() && line != 0)
6863 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6875die_name(
const Dwarf_Die* die)
6877 string name = die_string_attribute(die, DW_AT_name);
6893die_loc_and_name(
const reader& rdr,
6897 string& linkage_name)
6899 loc = die_location(rdr, die);
6900 name = die_name(die);
6901 linkage_name = die_linkage_name(die);
6912die_name_and_linkage_name(
const Dwarf_Die* die,
6914 string& linkage_name)
6916 name = die_name(die);
6917 linkage_name = die_linkage_name(die);
6930die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6935 uint64_t byte_size = 0, bit_size = 0;
6937 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6939 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6943 bit_size = byte_size * 8;
6966 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6973 case private_access:
6974 result = private_access;
6977 case protected_access:
6978 result = protected_access;
6982 result = public_access;
7001die_is_public_decl(
const Dwarf_Die* die)
7005 bool is_public =
false;
7011 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7012 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
7013 die_flag_attribute(die, DW_AT_external, is_public);
7014 else if (tag == DW_TAG_namespace)
7016 string name = die_name(die);
7017 is_public = !name.empty();
7031die_is_effectively_public_decl(
const reader& rdr,
7032 const Dwarf_Die* die)
7034 if (die_is_public_decl(die))
7037 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7038 if (tag == DW_TAG_variable || tag == DW_TAG_member)
7041 Dwarf_Die parent_die;
7042 size_t where_offset = 0;
7043 if (!get_parent_die(rdr, die, parent_die, where_offset))
7046 tag = dwarf_tag(&parent_die);
7047 if (tag == DW_TAG_compile_unit
7048 || tag == DW_TAG_partial_unit
7049 || tag == DW_TAG_type_unit)
7053 if (tag == DW_TAG_namespace)
7055 string name = die_name(&parent_die);
7074die_is_declaration_only(Dwarf_Die* die)
7076 bool is_declaration =
false;
7077 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
7078 if (is_declaration && (!die_has_size_attribute(die)
7079 || !die_has_children(die)))
7090die_is_function_decl(
const Dwarf_Die *die)
7095 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7096 if (tag == DW_TAG_subprogram)
7107die_is_variable_decl(
const Dwarf_Die *die)
7112 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7113 if (tag == DW_TAG_variable)
7124die_has_size_attribute(
const Dwarf_Die *die)
7127 if (die_size_in_bits(die, s))
7138die_has_no_child(
const Dwarf_Die *die)
7144 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7157die_is_declaration_only(
const Dwarf_Die* die)
7158{
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
7166die_is_artificial(Dwarf_Die* die)
7169 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
7176is_type_tag(
unsigned tag)
7178 bool result =
false;
7182 case DW_TAG_array_type:
7183 case DW_TAG_class_type:
7184 case DW_TAG_enumeration_type:
7185 case DW_TAG_pointer_type:
7186 case DW_TAG_reference_type:
7187 case DW_TAG_string_type:
7188 case DW_TAG_structure_type:
7189 case DW_TAG_subroutine_type:
7190 case DW_TAG_typedef:
7191 case DW_TAG_union_type:
7192 case DW_TAG_ptr_to_member_type:
7193 case DW_TAG_set_type:
7194 case DW_TAG_subrange_type:
7195 case DW_TAG_base_type:
7196 case DW_TAG_const_type:
7197 case DW_TAG_file_type:
7198 case DW_TAG_packed_type:
7199 case DW_TAG_thrown_type:
7200 case DW_TAG_volatile_type:
7201 case DW_TAG_restrict_type:
7202 case DW_TAG_interface_type:
7203 case DW_TAG_unspecified_type:
7204 case DW_TAG_shared_type:
7205 case DW_TAG_rvalue_reference_type:
7206 case DW_TAG_coarray_type:
7207 case DW_TAG_atomic_type:
7208 case DW_TAG_immutable_type:
7231is_canon_type_to_be_propagated_tag(
unsigned tag)
7233 bool result =
false;
7237 case DW_TAG_class_type:
7238 case DW_TAG_structure_type:
7239 case DW_TAG_union_type:
7240 case DW_TAG_subroutine_type:
7241 case DW_TAG_subprogram:
7262type_comparison_result_to_be_cached(
unsigned tag)
7267 case DW_TAG_class_type:
7268 case DW_TAG_structure_type:
7269 case DW_TAG_union_type:
7270 case DW_TAG_subroutine_type:
7271 case DW_TAG_subprogram:
7292maybe_cache_type_comparison_result(
const reader& rdr,
7297 if (!type_comparison_result_to_be_cached(tag)
7298 || (result != COMPARISON_RESULT_EQUAL
7299 && result != COMPARISON_RESULT_DIFFERENT))
7302 rdr.die_comparison_results_[p] = result;
7322get_cached_type_comparison_result(
const reader& rdr,
7326 auto i = rdr.die_comparison_results_.find(p);
7327 if (i != rdr.die_comparison_results_.end())
7350maybe_get_cached_type_comparison_result(
const reader& rdr,
7355 if (type_comparison_result_to_be_cached(tag))
7360 if (get_cached_type_comparison_result(rdr, p, result))
7372is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
7374 bool result =
false;
7375 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7377 if (!is_type_tag(tag))
7382 case DW_TAG_class_type:
7383 case DW_TAG_structure_type:
7384 case DW_TAG_union_type:
7385 result = !die_is_declaration_only(die);
7388 case DW_TAG_subroutine_type:
7389 case DW_TAG_subprogram:
7390 case DW_TAG_array_type:
7406is_decl_tag(
unsigned tag)
7410 case DW_TAG_formal_parameter:
7411 case DW_TAG_imported_declaration:
7413 case DW_TAG_unspecified_parameters:
7414 case DW_TAG_subprogram:
7415 case DW_TAG_variable:
7416 case DW_TAG_namespace:
7417 case DW_TAG_GNU_template_template_param:
7418 case DW_TAG_GNU_template_parameter_pack:
7419 case DW_TAG_GNU_formal_parameter_pack:
7431die_is_type(
const Dwarf_Die* die)
7435 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7444die_is_decl(
const Dwarf_Die* die)
7448 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
7457die_is_namespace(
const Dwarf_Die* die)
7461 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
7470die_is_unspecified(Dwarf_Die* die)
7474 return (dwarf_tag(die) == DW_TAG_unspecified_type);
7483die_is_void_type(Dwarf_Die* die)
7485 if (!die || dwarf_tag(die) != DW_TAG_base_type)
7488 string name = die_name(die);
7501die_is_pointer_type(
const Dwarf_Die* die)
7506 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7507 if (tag == DW_TAG_pointer_type)
7521pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7523 if (!die_is_pointer_array_or_reference_type(die)
7524 && !die_is_qualified_type(die))
7527 Dwarf_Die underlying_type_die;
7528 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7531 if (!die_is_class_type(&underlying_type_die))
7534 string name = die_name(&underlying_type_die);
7536 return name.empty();
7545die_is_reference_type(
const Dwarf_Die* die)
7550 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7551 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7563die_is_array_type(
const Dwarf_Die* die)
7568 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7569 if (tag == DW_TAG_array_type)
7581die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7582{
return (die_is_pointer_type(die)
7583 || die_is_reference_type(die)
7584 || die_is_array_type(die));}
7592die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7593{
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7602die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7603{
return (die_is_pointer_array_or_reference_type(die)
7604 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7612die_is_class_type(
const Dwarf_Die* die)
7614 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7616 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7628die_is_qualified_type(
const Dwarf_Die* die)
7630 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7631 if (tag == DW_TAG_const_type
7632 || tag == DW_TAG_volatile_type
7633 || tag == DW_TAG_restrict_type)
7645die_is_function_type(
const Dwarf_Die *die)
7647 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7648 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7666die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7671 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7683die_has_children(
const Dwarf_Die* die)
7689 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7709fn_die_first_parameter_die(
const Dwarf_Die* die, Dwarf_Die& first_parm_die)
7714 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7715 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7718 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7720 int child_tag = dwarf_tag(&child);
7721 if (child_tag == DW_TAG_formal_parameter)
7723 memcpy(&first_parm_die, &child,
sizeof(Dwarf_Die));
7758member_fn_die_has_this_pointer(
const reader& rdr,
7759 const Dwarf_Die* die,
7760 size_t where_offset,
7761 Dwarf_Die& class_die,
7762 Dwarf_Die& object_pointer_die)
7767 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7768 if (tag != DW_TAG_subprogram && tag != DW_TAG_subroutine_type)
7771 if (tag == DW_TAG_subprogram
7772 && !die_is_at_class_scope(rdr, die, where_offset, class_die))
7775 Dwarf_Die first_parm_die;
7776 Dwarf_Die parm_type_die;
7777 if (die_has_object_pointer(die, object_pointer_die))
7783 memcpy(&first_parm_die, &object_pointer_die,
sizeof(Dwarf_Die));
7784 if (!die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7786 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7787 die_peel_typedef(&parm_type_die, parm_type_die);
7789 else if (fn_die_first_parameter_die(die, first_parm_die))
7791 memcpy(&object_pointer_die, &first_parm_die,
sizeof(Dwarf_Die));
7792 bool is_artificial =
false;
7793 if (die_flag_attribute(&first_parm_die, DW_AT_artificial, is_artificial))
7795 if (die_die_attribute(&first_parm_die, DW_AT_type, parm_type_die))
7797 tag = dwarf_tag(&parm_type_die);
7798 if (tag == DW_TAG_pointer_type)
7800 die_peel_qual_ptr(&parm_type_die, parm_type_die);
7801 die_peel_typedef(&parm_type_die, parm_type_die);
7815 tag = dwarf_tag(&parm_type_die);
7816 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7818 memcpy(&class_die, &parm_type_die,
sizeof(Dwarf_Die));
7838die_this_pointer_from_object_pointer(Dwarf_Die* die,
7839 Dwarf_Die& this_pointer_die)
7842 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7844 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7859die_this_pointer_is_const(Dwarf_Die* dye)
7864 memcpy(&die, dye,
sizeof(Dwarf_Die));
7865 if (dwarf_tag(&die) == DW_TAG_const_type)
7868 if (dwarf_tag(&die) == DW_TAG_pointer_type)
7870 Dwarf_Die pointed_to_type_die;
7871 if (die_die_attribute(&die, DW_AT_type, pointed_to_type_die))
7872 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7888die_object_pointer_is_for_const_method(Dwarf_Die* die)
7891 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7893 Dwarf_Die this_pointer_die;
7894 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7895 if (die_this_pointer_is_const(&this_pointer_die))
7917die_is_at_class_scope(
const reader& rdr,
7918 const Dwarf_Die* die,
7919 size_t where_offset,
7920 Dwarf_Die& class_scope_die)
7922 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7925 int tag = dwarf_tag(&class_scope_die);
7927 return (tag == DW_TAG_structure_type
7928 || tag == DW_TAG_class_type
7929 || tag == DW_TAG_union_type);
7942die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7947 int tag = dwarf_tag(die);
7949 if (tag == DW_TAG_const_type
7950 || tag == DW_TAG_volatile_type
7951 || tag == DW_TAG_restrict_type
7952 || tag == DW_TAG_pointer_type
7953 || tag == DW_TAG_reference_type
7954 || tag == DW_TAG_rvalue_reference_type)
7956 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7962 memcpy(&peeled_die, die,
sizeof(peeled_die));
7964 while (tag == DW_TAG_const_type
7965 || tag == DW_TAG_volatile_type
7966 || tag == DW_TAG_restrict_type
7967 || tag == DW_TAG_pointer_type
7968 || tag == DW_TAG_reference_type
7969 || tag == DW_TAG_rvalue_reference_type)
7971 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7973 tag = dwarf_tag(&peeled_die);
7988die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7993 memcpy(&peeled_die, die,
sizeof(peeled_die));
7995 int tag = dwarf_tag(&peeled_die);
7997 bool result =
false;
7998 while (tag == DW_TAG_const_type
7999 || tag == DW_TAG_volatile_type
8000 || tag == DW_TAG_restrict_type)
8002 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8004 tag = dwarf_tag(&peeled_die);
8020die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
8025 int tag = dwarf_tag(die);
8027 memcpy(&peeled_die, die,
sizeof(peeled_die));
8029 if (tag == DW_TAG_typedef)
8031 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8037 while (tag == DW_TAG_typedef)
8039 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8041 tag = dwarf_tag(&peeled_die);
8057die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
8062 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
8064 if (tag == DW_TAG_pointer_type
8065 || tag == DW_TAG_reference_type
8066 || tag == DW_TAG_rvalue_reference_type
8067 || tag == DW_TAG_typedef)
8069 if (!die_die_attribute(die, DW_AT_type, peeled_die))
8075 while (tag == DW_TAG_pointer_type
8076 || tag == DW_TAG_reference_type
8077 || tag == DW_TAG_rvalue_reference_type
8078 || tag == DW_TAG_typedef)
8080 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
8082 tag = dwarf_tag(&peeled_die);
8113die_function_type_is_method_type(
const reader& rdr,
8114 const Dwarf_Die *die,
8115 size_t where_offset,
8116 Dwarf_Die& object_pointer_die,
8117 Dwarf_Die& class_die,
8123 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
8124 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
8126 if (member_fn_die_has_this_pointer(rdr, die, where_offset, class_die, object_pointer_die))
8131 else if (die_is_at_class_scope(rdr, die, where_offset, class_die))
8142 VIRTUALITY_NOT_VIRTUAL,
8144 VIRTUALITY_PURE_VIRTUAL
8157die_virtuality(
const Dwarf_Die* die, virtuality& virt)
8163 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
8165 if (v == DW_VIRTUALITY_virtual)
8166 virt = VIRTUALITY_VIRTUAL;
8167 else if (v == DW_VIRTUALITY_pure_virtual)
8168 virt = VIRTUALITY_PURE_VIRTUAL;
8170 virt = VIRTUALITY_NOT_VIRTUAL;
8182die_is_virtual(
const Dwarf_Die* die)
8185 if (!die_virtuality(die, v))
8188 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
8198die_is_declared_inline(Dwarf_Die* die)
8200 uint64_t inline_value = 0;
8201 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
8203 return (inline_value == DW_INL_declared_inlined
8204 || inline_value == DW_INL_declared_not_inlined);
8219slowly_compare_strings(
const Dwarf_Die *l,
8223 const char *l_str = die_char_str_attribute(l, attr_name),
8224 *r_str = die_char_str_attribute(r, attr_name);
8225 if (!l_str && !r_str)
8227 return l_str && r_str && !strcmp(l_str, r_str);
8253compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
8257 Dwarf_Attribute l_attr, r_attr;
8258 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
8259 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
8263 || l_attr.form == DW_FORM_string
8264 || l_attr.form == DW_FORM_GNU_strp_alt
8265 || form_is_DW_FORM_strx(l_attr.form)
8266 || form_is_DW_FORM_line_strp(l_attr.form));
8269 || r_attr.form == DW_FORM_string
8270 || r_attr.form == DW_FORM_GNU_strp_alt
8271 || form_is_DW_FORM_strx(r_attr.form)
8272 || form_is_DW_FORM_line_strp(r_attr.form));
8274 if ((l_attr.form == DW_FORM_strp
8275 && r_attr.form == DW_FORM_strp)
8276 || (l_attr.form == DW_FORM_GNU_strp_alt
8277 && r_attr.form == DW_FORM_GNU_strp_alt)
8278 || (form_is_DW_FORM_strx(l_attr.form)
8279 && form_is_DW_FORM_strx(r_attr.form))
8280 || (form_is_DW_FORM_line_strp(l_attr.form)
8281 && form_is_DW_FORM_line_strp(r_attr.form)))
8288 if (l_attr.valp == r_attr.valp)
8290#if WITH_DEBUG_TYPE_CANONICALIZATION
8291 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
8302 result = slowly_compare_strings(l, r, attr_name);
8320compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
8322 Dwarf_Die l_cu, r_cu;
8323 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
8324 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
8328 compare_dies_string_attribute_value(&l_cu, &r_cu,
8331 if (compared && result)
8333 Dwarf_Die peeled_l, peeled_r;
8334 if (die_is_pointer_reference_or_typedef_type(l)
8335 && die_is_pointer_reference_or_typedef_type(r)
8336 && die_peel_pointer_and_typedef(l, peeled_l)
8337 && die_peel_pointer_and_typedef(r, peeled_r))
8339 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
8340 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
8343 compare_dies_string_attribute_value(&l_cu, &r_cu,
8374die_location_expr(
const Dwarf_Die* die,
8382 Dwarf_Attribute attr;
8383 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
8387 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
8422op_pushes_constant_value(Dwarf_Op* ops,
8426 dwarf_expr_eval_context& ctxt)
8430 Dwarf_Op& op = ops[index];
8436 value = ops[index].number;
8449 value = ops[index].number;
8553 expr_result r(value);
8556 next_index = index + 1;
8586op_pushes_non_constant_value(Dwarf_Op* ops,
8590 dwarf_expr_eval_context& ctxt)
8593 Dwarf_Op& op = ops[index];
8629 next_index = index + 1;
8664 next_index = index + 1;
8668 next_index = index + 2;
8672 next_index = index + 1;
8676 next_index = index + 1;
8679 case DW_OP_GNU_variable_value:
8680 next_index = index + 1;
8687 expr_result r(
false);
8716op_manipulates_stack(Dwarf_Op* expr,
8720 dwarf_expr_eval_context& ctxt)
8722 Dwarf_Op& op = expr[index];
8728 v = ctxt.stack.front();
8733 v = ctxt.stack.front();
8752 ctxt.stack.erase(ctxt.stack.begin() + 1);
8759 ctxt.stack.erase(ctxt.stack.begin() + 2);
8764 case DW_OP_deref_size:
8772 case DW_OP_xderef_size:
8780 case DW_OP_push_object_address:
8785 case DW_OP_form_tls_address:
8786 case DW_OP_GNU_push_tls_address:
8789 if (op.atom == DW_OP_form_tls_address)
8794 case DW_OP_call_frame_cfa:
8806 if (op.atom == DW_OP_form_tls_address
8807 || op.atom == DW_OP_GNU_push_tls_address)
8808 ctxt.set_tls_address(
true);
8810 ctxt.set_tls_address(
false);
8812 next_index = index + 1;
8840op_is_arith_logic(Dwarf_Op* expr,
8844 dwarf_expr_eval_context& ctxt)
8848 Dwarf_Op& op = expr[index];
8849 expr_result val1, val2;
8850 bool result =
false;
8866 ctxt.push(val1 & val2);
8873 if (!val1.is_const())
8875 ctxt.push(val2 / val1);
8883 ctxt.push(val2 - val1);
8891 ctxt.push(val2 % val1);
8899 ctxt.push(val2 * val1);
8921 ctxt.push(val1 | val2);
8929 ctxt.push(val2 + val1);
8933 case DW_OP_plus_uconst:
8945 ctxt.push(val2 << val1);
8954 ctxt.push(val2 >> val1);
8962 ctxt.push(val2 ^ val1);
8972 if (ctxt.stack.front().is_const())
8973 ctxt.accum = ctxt.stack.front();
8975 next_index = index + 1;
9003op_is_control_flow(Dwarf_Op* expr,
9007 dwarf_expr_eval_context& ctxt)
9011 Dwarf_Op& op = expr[index];
9012 expr_result val1, val2;
9026 if (op.atom == DW_OP_eq)
9027 value = val2 == val1;
9028 else if (op.atom == DW_OP_ge)
9029 value = val2 >= val1;
9030 else if (op.atom == DW_OP_gt)
9031 value = val2 > val1;
9032 else if (op.atom == DW_OP_le)
9033 value = val2 <= val1;
9034 else if (op.atom == DW_OP_lt)
9035 value = val2 < val1;
9036 else if (op.atom == DW_OP_ne)
9037 value = val2 != val1;
9039 val1 = value ? 1 : 0;
9046 index += op.number - 1;
9051 if (val1.const_value() != 0)
9052 index += val1.const_value() - 1;
9057 case DW_OP_call_ref:
9065 if (ctxt.stack.front().is_const())
9066 ctxt.accum = ctxt.stack.front();
9068 next_index = index + 1;
9089eval_quickly(Dwarf_Op* expr,
9093 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
9095 value = expr[0].number;
9122eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
9125 bool& is_tls_address,
9126 dwarf_expr_eval_context &eval_ctxt)
9132 size_t index = 0, next_index = 0;
9135 if (op_is_arith_logic(expr, expr_len, index,
9136 next_index, eval_ctxt)
9137 || op_pushes_constant_value(expr, expr_len, index,
9138 next_index, eval_ctxt)
9139 || op_manipulates_stack(expr, expr_len, index,
9140 next_index, eval_ctxt)
9141 || op_pushes_non_constant_value(expr, expr_len, index,
9142 next_index, eval_ctxt)
9143 || op_is_control_flow(expr, expr_len, index,
9144 next_index, eval_ctxt))
9147 next_index = index + 1;
9151 }
while (index < expr_len);
9153 is_tls_address = eval_ctxt.set_tls_address();
9154 if (eval_ctxt.accum.is_const())
9156 value = eval_ctxt.accum;
9176eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
9179 bool& is_tls_address)
9181 dwarf_expr_eval_context eval_ctxt;
9182 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
9183 is_tls_address, eval_ctxt);
9375read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
9380 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
9393 uint64_t containing_anonymous_object_size = 0;
9394 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
9395 containing_anonymous_object_size));
9396 containing_anonymous_object_size *= 8;
9398 uint64_t bitfield_size = 0;
9399 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
9410 offset = containing_anonymous_object_size - off - bitfield_size;
9426die_constant_data_member_location(
const Dwarf_Die *die,
9432 Dwarf_Attribute attr;
9433 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
9434 DW_AT_data_member_location,
9439 if (dwarf_formudata(&attr, &val) != 0)
9495die_member_offset(
const reader& rdr,
9496 const Dwarf_Die* die,
9499 Dwarf_Op* expr = NULL;
9500 size_t expr_len = 0;
9501 uint64_t bit_offset = 0;
9505 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
9507 offset = bit_offset;
9519 if (!die_constant_data_member_location(die, offset))
9524 if (!die_location_expr(die, DW_AT_data_member_location,
9531 if (!eval_quickly(expr, expr_len, offset))
9533 bool is_tls_address =
false;
9534 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
9535 offset, is_tls_address,
9536 rdr.dwarf_expr_eval_ctxt()))
9554 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
9555 offset += bit_offset;
9572die_location_address(Dwarf_Die* die,
9573 Dwarf_Addr& address,
9574 bool& is_tls_address)
9576 Dwarf_Op* expr = NULL;
9577 size_t expr_len = 0;
9579 is_tls_address =
false;
9584 Dwarf_Attribute attr;
9585 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
9588 if (dwarf_getlocation(&attr, &expr, &expr_len))
9595 Dwarf_Attribute result;
9596 if (!dwarf_getlocation_attr(&attr, expr, &result))
9598 return !dwarf_formaddr(&result, &address);
9601 address = expr->number;
9616die_virtual_function_index(Dwarf_Die* die,
9622 Dwarf_Op* expr = NULL;
9623 size_t expr_len = 0;
9624 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9629 bool is_tls_addr =
false;
9630 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9648 int tag = dwarf_tag(die);
9650 if (tag == DW_TAG_class_type
9651 || tag == DW_TAG_structure_type
9652 || tag == DW_TAG_union_type
9653 || tag == DW_TAG_enumeration_type)
9654 return die_is_anonymous(die);
9676get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9679 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9681 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9683 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9685 else if (tag == DW_TAG_union_type)
9687 else if (tag == DW_TAG_enumeration_type)
9706build_internal_anonymous_die_name(
const string &
base_name,
9707 size_t anonymous_type_index)
9710 if (anonymous_type_index && !
base_name.empty())
9712 std::ostringstream o;
9742die_qualified_type_name(
const reader& rdr,
9743 const Dwarf_Die* die,
9744 size_t where_offset,
9745 unordered_set<uint64_t>& guard)
9750 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9751 if (tag == DW_TAG_compile_unit
9752 || tag == DW_TAG_partial_unit
9753 || tag == DW_TAG_type_unit)
9756 string name = die_name(die);
9758 Dwarf_Die scope_die;
9759 if (!get_scope_die(rdr, die, where_offset, scope_die))
9762 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9763 string separator = colon_colon ?
"::" :
".";
9769 case DW_TAG_unspecified_type:
9772 case DW_TAG_base_type:
9782 case DW_TAG_typedef:
9786 case DW_TAG_enumeration_type:
9787 case DW_TAG_structure_type:
9788 case DW_TAG_class_type:
9789 case DW_TAG_union_type:
9791 if (die_is_anonymous(die))
9792 repr = die_class_or_enum_flat_representation(rdr, die,
"",
9795 where_offset, guard);
9798 string parent_name = die_qualified_name(rdr, &scope_die,
9799 where_offset, guard);
9800 repr = parent_name.empty() ? name : parent_name + separator + name;
9805 case DW_TAG_const_type:
9806 case DW_TAG_volatile_type:
9807 case DW_TAG_restrict_type:
9809 Dwarf_Die underlying_type_die;
9810 bool has_underlying_type_die =
9811 die_die_attribute(die, DW_AT_type, underlying_type_die);
9813 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9816 if (tag == DW_TAG_const_type)
9818 if (has_underlying_type_die
9819 && die_is_reference_type(&underlying_type_die))
9829 else if (!has_underlying_type_die
9830 || die_is_void_type(&underlying_type_die))
9838 else if (tag == DW_TAG_volatile_type)
9840 else if (tag == DW_TAG_restrict_type)
9845 string underlying_type_repr;
9846 if (has_underlying_type_die)
9847 underlying_type_repr =
9848 die_qualified_type_name(rdr, &underlying_type_die,
9849 where_offset, guard);
9851 underlying_type_repr =
"void";
9853 if (underlying_type_repr.empty())
9857 if (has_underlying_type_die)
9860 die_peel_qualified(&underlying_type_die, peeled);
9861 if (die_is_pointer_or_reference_type(&peeled))
9862 repr = underlying_type_repr +
" " + repr;
9864 repr +=
" " + underlying_type_repr;
9867 repr +=
" " + underlying_type_repr;
9872 case DW_TAG_pointer_type:
9873 case DW_TAG_reference_type:
9874 case DW_TAG_rvalue_reference_type:
9876 Dwarf_Die pointed_to_type_die;
9877 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9879 if (tag == DW_TAG_pointer_type)
9884 if (die_is_unspecified(&pointed_to_type_die))
9887 string pointed_type_repr =
9888 die_qualified_type_name(rdr, &pointed_to_type_die,
9889 where_offset, guard);
9891 repr = pointed_type_repr;
9895 if (tag == DW_TAG_pointer_type)
9897 else if (tag == DW_TAG_reference_type)
9899 else if (tag == DW_TAG_rvalue_reference_type)
9906 case DW_TAG_subrange_type:
9919 build_subrange_type(
const_cast<reader&
>(rdr),
9922 repr += s->as_string();
9926 case DW_TAG_array_type:
9928 Dwarf_Die element_type_die;
9929 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9931 string element_type_name =
9932 die_qualified_type_name(rdr, &element_type_die, where_offset, guard);
9933 if (element_type_name.empty())
9937 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9938 die, subranges, where_offset,
9941 repr = element_type_name;
9942 repr += array_type_def::subrange_type::vector_as_string(subranges);
9946 case DW_TAG_subroutine_type:
9947 case DW_TAG_subprogram:
9949 string return_type_name;
9951 vector<string> parm_names;
9952 bool is_const =
false;
9953 bool is_static =
false;
9955 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9959 return_type_name, class_name,
9960 parm_names, is_const,
9962 if (return_type_name.empty())
9963 return_type_name =
"void";
9965 repr = return_type_name;
9969 repr +=
" (" + class_name +
"::*)";
9973 for (vector<string>::const_iterator i = parm_names.begin();
9974 i != parm_names.end();
9977 if (i != parm_names.begin())
9986 case DW_TAG_string_type:
9987 case DW_TAG_ptr_to_member_type:
9988 case DW_TAG_set_type:
9989 case DW_TAG_file_type:
9990 case DW_TAG_packed_type:
9991 case DW_TAG_thrown_type:
9992 case DW_TAG_interface_type:
9993 case DW_TAG_shared_type:
10019die_type_name(
const reader& rdr,
10020 const Dwarf_Die* die,
10021 bool qualified_name,
10022 size_t where_offset,
10023 unordered_set<uint64_t>& guard)
10028 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
10029 if (tag == DW_TAG_compile_unit
10030 || tag == DW_TAG_partial_unit
10031 || tag == DW_TAG_type_unit)
10034 string name = die_name(die);
10036 Dwarf_Die scope_die;
10037 if (!get_scope_die(rdr, die, where_offset, scope_die))
10040 bool colon_colon = die_is_type(die) || die_is_namespace(die);
10041 string separator = colon_colon ?
"::" :
".";
10047 case DW_TAG_unspecified_type:
10050 case DW_TAG_base_type:
10060 case DW_TAG_typedef:
10064 case DW_TAG_enumeration_type:
10065 case DW_TAG_structure_type:
10066 case DW_TAG_class_type:
10067 case DW_TAG_union_type:
10069 if (die_is_anonymous(die))
10070 repr = die_class_or_enum_flat_representation(rdr, die,
"",
10077 string parent_name;
10078 if (qualified_name)
10081 parent_name = die_qualified_name(rdr, &scope_die,
10082 where_offset, guard);
10084 repr = parent_name.empty() ? name : parent_name + separator + name;
10089 case DW_TAG_const_type:
10090 case DW_TAG_volatile_type:
10091 case DW_TAG_restrict_type:
10093 Dwarf_Die underlying_type_die;
10094 bool has_underlying_type_die =
10095 die_die_attribute(die, DW_AT_type, underlying_type_die);
10097 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
10100 if (tag == DW_TAG_const_type)
10102 if (has_underlying_type_die
10103 && die_is_reference_type(&underlying_type_die))
10113 else if (!has_underlying_type_die
10114 || die_is_void_type(&underlying_type_die))
10122 else if (tag == DW_TAG_volatile_type)
10124 else if (tag == DW_TAG_restrict_type)
10129 string underlying_type_repr;
10130 if (has_underlying_type_die)
10131 underlying_type_repr =
10132 die_type_name(rdr, &underlying_type_die,
10133 qualified_name, where_offset,
10136 underlying_type_repr =
"void";
10138 if (underlying_type_repr.empty())
10142 if (has_underlying_type_die)
10145 die_peel_qualified(&underlying_type_die, peeled);
10146 if (die_is_pointer_or_reference_type(&peeled))
10147 repr = underlying_type_repr +
" " + repr;
10149 repr +=
" " + underlying_type_repr;
10152 repr +=
" " + underlying_type_repr;
10157 case DW_TAG_pointer_type:
10158 case DW_TAG_reference_type:
10159 case DW_TAG_rvalue_reference_type:
10161 Dwarf_Die pointed_to_type_die;
10162 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
10164 if (tag == DW_TAG_pointer_type)
10169 if (die_is_unspecified(&pointed_to_type_die))
10172 string pointed_type_repr =
10173 die_type_name(rdr, &pointed_to_type_die,
10174 qualified_name, where_offset,
10177 repr = pointed_type_repr;
10181 if (tag == DW_TAG_pointer_type)
10183 else if (tag == DW_TAG_reference_type)
10185 else if (tag == DW_TAG_rvalue_reference_type)
10192 case DW_TAG_subrange_type:
10205 build_subrange_type(
const_cast<reader&
>(rdr),
10208 repr += s->as_string();
10212 case DW_TAG_array_type:
10214 Dwarf_Die element_type_die;
10215 if (!die_die_attribute(die, DW_AT_type, element_type_die))
10217 string element_type_name =
10218 die_type_name(rdr, &element_type_die,
10219 qualified_name, where_offset,
10221 if (element_type_name.empty())
10225 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
10226 die, subranges, where_offset,
10229 repr = element_type_name;
10230 repr += array_type_def::subrange_type::vector_as_string(subranges);
10234 case DW_TAG_subroutine_type:
10235 case DW_TAG_subprogram:
10237 string return_type_name;
10239 vector<string> parm_names;
10240 bool is_const =
false;
10241 bool is_static =
false;
10243 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
10249 parm_names, is_const,
10251 if (return_type_name.empty())
10252 return_type_name =
"void";
10254 repr = return_type_name;
10259 repr +=
" (" + class_name +
"::*)";
10264 for (vector<string>::const_iterator i = parm_names.begin();
10265 i != parm_names.end();
10268 if (i != parm_names.begin())
10277 case DW_TAG_string_type:
10278 case DW_TAG_ptr_to_member_type:
10279 case DW_TAG_set_type:
10280 case DW_TAG_file_type:
10281 case DW_TAG_packed_type:
10282 case DW_TAG_thrown_type:
10283 case DW_TAG_interface_type:
10284 case DW_TAG_shared_type:
10305die_type_name(
const reader& rdr,
10306 const Dwarf_Die* die,
10307 bool qualified_name,
10308 size_t where_offset)
10310 unordered_set<uint64_t> guard;
10311 return die_type_name(rdr, die, qualified_name, where_offset, guard);
10332die_qualified_decl_name(
const reader& rdr,
10333 const Dwarf_Die* die,
10334 size_t where_offset,
10335 unordered_set<uint64_t>& guard)
10337 if (!die || !die_is_decl(die))
10340 string name = die_name(die);
10342 Dwarf_Die scope_die;
10343 if (!get_scope_die(rdr, die, where_offset, scope_die))
10346 string scope_name = die_qualified_name(rdr, &scope_die, where_offset, guard);
10347 string separator =
"::";
10351 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10354 case DW_TAG_namespace:
10355 case DW_TAG_member:
10356 case DW_TAG_variable:
10357 repr = scope_name.empty() ? name : scope_name + separator + name;
10359 case DW_TAG_subprogram:
10360 repr = die_function_signature(rdr, die,
10362 where_offset, guard);
10365 case DW_TAG_unspecified_parameters:
10369 case DW_TAG_formal_parameter:
10370 case DW_TAG_imported_declaration:
10371 case DW_TAG_GNU_template_template_param:
10372 case DW_TAG_GNU_template_parameter_pack:
10373 case DW_TAG_GNU_formal_parameter_pack:
10401die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
10402 size_t where, unordered_set<uint64_t>& guard)
10404 if (die_is_type(die))
10405 return die_qualified_type_name(rdr, die, where, guard);
10406 else if (die_is_decl(die))
10407 return die_qualified_decl_name(rdr, die, where, guard);
10428die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
10430 unordered_set<uint64_t> guard;
10431 return die_qualified_name(rdr, die, where, guard);
10457die_qualified_type_name_empty(
const reader& rdr,
10458 const Dwarf_Die* die,
10459 size_t where,
string &qualified_name,
10460 unordered_set<uint64_t>& guard)
10465 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10468 if (tag == DW_TAG_typedef
10469 || tag == DW_TAG_pointer_type
10470 || tag == DW_TAG_reference_type
10471 || tag == DW_TAG_rvalue_reference_type
10472 || tag == DW_TAG_array_type
10473 || tag == DW_TAG_const_type
10474 || tag == DW_TAG_volatile_type
10475 || tag == DW_TAG_restrict_type)
10477 Dwarf_Die underlying_type_die;
10478 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
10481 die_qualified_type_name(rdr, &underlying_type_die, where, guard);
10488 string name = die_qualified_type_name(rdr, die, where, guard);
10493 qname = die_qualified_type_name(rdr, die, where, guard);
10497 qualified_name = qname;
10549die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
10550 const Dwarf_Die* die,
10551 size_t where_offset,
10553 bool qualified_name,
10555 string &return_type_name,
10556 string &class_name,
10557 vector<string>& parm_names,
10560 unordered_set<uint64_t>& guard)
10562 uint64_t off = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
10563 if (guard.find(off) != guard.end())
10568 Dwarf_Die ret_type_die;
10569 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
10570 return_type_name =
"void";
10575 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset, guard)
10576 : die_type_name(rdr, &ret_type_die, qualified_name,
10577 where_offset, guard);
10580 if (return_type_name.empty())
10581 return_type_name =
"void";
10583 Dwarf_Die object_pointer_die, class_die;
10585 die_function_type_is_method_type(rdr, die, where_offset,
10586 object_pointer_die,
10587 class_die, is_static);
10593 class_name = die_type_name(rdr, &class_die, qualified_name,
10594 where_offset, guard);
10596 Dwarf_Die this_pointer_die;
10597 Dwarf_Die pointed_to_die;
10599 && die_die_attribute(&object_pointer_die, DW_AT_type,
10601 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
10602 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
10605 string fn_name = die_name(die);
10606 string non_qualified_class_name = die_name(&class_die);
10607 bool is_ctor = fn_name == non_qualified_class_name;
10608 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
10610 if (is_ctor || is_dtor)
10611 return_type_name.clear();
10614 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
10617 int child_tag = dwarf_tag(&child);
10618 bool first_parm =
true;
10619 if (child_tag == DW_TAG_formal_parameter)
10624 first_parm =
false;
10628 Dwarf_Die parm_type_die;
10629 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
10633 ? rdr.get_die_pretty_representation(&parm_type_die,
10634 where_offset, guard)
10635 : die_type_name(rdr, &parm_type_die,
10636 qualified_name, where_offset, guard);
10640 parm_names.push_back(qname);
10642 else if (child_tag == DW_TAG_unspecified_parameters)
10645 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
10655 while (dwarf_siblingof(&child, &child) == 0);
10657 if (class_name.empty())
10659 Dwarf_Die parent_die;
10660 if (get_parent_die(rdr, die, parent_die, where_offset))
10662 if (die_is_class_type(&parent_die)
10664 class_name = die_type_name(rdr, &parent_die,
10694die_function_signature(
const reader& rdr,
10695 const Dwarf_Die *fn_die,
10696 bool qualified_name,
10697 size_t where_offset,
10698 unordered_set<uint64_t>& guard)
10702 bool has_lang =
false;
10703 if ((has_lang = get_die_language(fn_die, lang)))
10711 string fn_name = die_linkage_name(fn_die);
10712 if (fn_name.empty())
10713 fn_name = die_name(fn_die);
10723 string return_type_name;
10724 Dwarf_Die ret_type_die;
10725 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
10726 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
10730 if (return_type_name.empty())
10731 return_type_name =
"void";
10733 Dwarf_Die scope_die;
10735 if (qualified_name && get_scope_die(rdr, fn_die, where_offset, scope_die))
10736 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset, guard);
10737 string fn_name = die_name(fn_die);
10738 if (!scope_name.empty())
10739 fn_name = scope_name +
"::" + fn_name;
10742 vector<string> parm_names;
10743 bool is_const =
false;
10744 bool is_static =
false;
10747 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
10750 return_type_name, class_name,
10751 parm_names, is_const, is_static,
10754 bool is_virtual = die_is_virtual(fn_die);
10758 repr +=
" virtual";
10760 if (!return_type_name.empty())
10761 repr +=
" " + return_type_name;
10763 repr +=
" " + fn_name;
10767 bool some_parm_emitted =
false;
10768 for (vector<string>::const_iterator i = parm_names.begin();
10769 i != parm_names.end();
10772 if (i != parm_names.begin())
10774 if (some_parm_emitted)
10783 some_parm_emitted =
true;
10828die_class_flat_representation(
const reader& rdr,
10829 const Dwarf_Die* die,
10830 const string& indent,
10832 bool qualified_names,
10833 size_t where_offset,
10834 unordered_set<uint64_t>& guard)
10836 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10838 string repr = indent;
10839 string local_indent =
" ";
10840 string real_indent;
10842 if (tag == DW_TAG_union_type)
10844 else if (tag == DW_TAG_structure_type)
10846 else if (tag == DW_TAG_class_type)
10853 if (die_is_anonymous(die))
10855 uint64_t off = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
10856 if (guard.find(off) != guard.end())
10864 if (!die_is_anonymous(die))
10865 repr += die_qualified_name(rdr, die, where_offset, guard);
10872 Dwarf_Die member_child_die;
10873 bool first_sibling =
true;
10874 for (
bool got_it = get_member_child_die(die, &member_child_die);
10876 got_it = get_next_member_sibling_die(&member_child_die,
10877 &member_child_die),
10878 first_sibling =
false)
10882 if (!die_is_decl(&member_child_die)
10883 && !(die_is_type(&member_child_die)
10884 && die_is_anonymous(&member_child_die)))
10888 real_indent = first_sibling ?
"" :
" " ;
10890 real_indent = (first_sibling ?
"":
"\n") + indent + local_indent;
10892 repr += real_indent;
10894 repr += die_pretty_print_decl(rdr, &member_child_die,
10905 repr += indent +
"}";
10907 if (die_is_anonymous(die))
10909 uint64_t off = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
10941die_enum_flat_representation(
const reader& rdr,
10942 const Dwarf_Die* die,
10943 const string& indent,
10945 bool qualified_names,
10946 size_t where_offset)
10948 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10950 std::ostringstream o;
10951 string local_indent =
" ";
10952 string real_indent;
10954 if (tag == DW_TAG_enumeration_type)
10961 if (!die_is_anonymous(die))
10962 o << (qualified_names
10963 ? die_qualified_name(rdr, die, where_offset)
10973 bool first_enumerator=
true;
10974 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
10978 if (dwarf_tag(&child) != DW_TAG_enumerator)
10983 die_loc_and_name(rdr, &child, l, name, m);
10985 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
10988 real_indent = first_enumerator ?
"" :
", ";
10990 real_indent = first_enumerator ?
"" :
",\n" + indent + local_indent;
10991 o << name +
" = " << val;
10992 first_enumerator =
false;
10994 while (dwarf_siblingof(&child, &child) == 0);
10997 o << one_line ? string(
"}") :
"\n" + indent;
11035die_class_or_enum_flat_representation(
const reader& rdr,
11036 const Dwarf_Die* die,
11037 const string& indent,
11039 bool qualified_names,
11040 size_t where_offset,
11041 unordered_set<uint64_t>& guard)
11047 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11051 case DW_TAG_class_type:
11052 case DW_TAG_structure_type:
11053 case DW_TAG_union_type:
11054 result = die_class_flat_representation(rdr, die, indent,
11055 one_line, qualified_names,
11059 case DW_TAG_enumeration_type:
11060 result = die_enum_flat_representation(rdr, die, indent,
11061 one_line, qualified_names,
11098die_class_or_enum_flat_representation(
const reader& rdr,
11099 const Dwarf_Die* die,
11100 const string& indent,
11102 bool qualified_names,
11103 size_t where_offset)
11105 unordered_set<uint64_t> guard;
11106 return die_class_or_enum_flat_representation(rdr, die, indent,
11107 one_line, qualified_names,
11108 where_offset, guard);
11134die_pretty_print_type(
const reader& rdr,
11135 const Dwarf_Die* die,
11136 size_t where_offset,
11137 unordered_set<uint64_t>& guard)
11140 || (!die_is_type(die)
11141 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
11146 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11149 case DW_TAG_string_type:
11158 repr =
"string type";
11160 case DW_TAG_unspecified_type:
11161 case DW_TAG_ptr_to_member_type:
11164 case DW_TAG_namespace:
11165 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset,
11169 case DW_TAG_base_type:
11170 repr = rdr.get_die_qualified_type_name(die, where_offset, guard);
11173 case DW_TAG_typedef:
11175 string qualified_name;
11176 if (!die_qualified_type_name_empty(rdr, die,
11180 repr =
"typedef " + qualified_name;
11184 case DW_TAG_const_type:
11185 case DW_TAG_volatile_type:
11186 case DW_TAG_restrict_type:
11187 case DW_TAG_pointer_type:
11188 case DW_TAG_reference_type:
11189 case DW_TAG_rvalue_reference_type:
11190 repr = rdr.get_die_qualified_type_name(die, where_offset, guard);
11193 case DW_TAG_enumeration_type:
11195 string qualified_name =
11196 rdr.get_die_qualified_type_name(die, where_offset, guard);
11197 repr =
"enum " + qualified_name;
11201 case DW_TAG_structure_type:
11202 case DW_TAG_class_type:
11204 string qualified_name =
11205 rdr.get_die_qualified_type_name(die, where_offset, guard);
11206 repr =
"class " + qualified_name;
11210 case DW_TAG_union_type:
11212 string qualified_name =
11213 rdr.get_die_qualified_type_name(die, where_offset, guard);
11214 repr =
"union " + qualified_name;
11218 case DW_TAG_array_type:
11220 Dwarf_Die element_type_die;
11221 if (!die_die_attribute(die, DW_AT_type, element_type_die))
11223 string element_type_name =
11224 rdr.get_die_qualified_type_name(&element_type_die,
11225 where_offset, guard);
11226 if (element_type_name.empty())
11230 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
11233 repr = element_type_name;
11234 repr += array_type_def::subrange_type::vector_as_string(subranges);
11238 case DW_TAG_subrange_type:
11248 repr += die_qualified_type_name(rdr, die, where_offset, guard);
11252 case DW_TAG_subroutine_type:
11253 case DW_TAG_subprogram:
11255 string return_type_name;
11257 vector<string> parm_names;
11258 bool is_const =
false;
11259 bool is_static =
false;
11261 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
11265 return_type_name, class_name,
11266 parm_names, is_const,
11269 repr =
"function type";
11271 repr =
"method type";
11272 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset, guard);
11276 case DW_TAG_set_type:
11277 case DW_TAG_file_type:
11278 case DW_TAG_packed_type:
11279 case DW_TAG_thrown_type:
11280 case DW_TAG_interface_type:
11281 case DW_TAG_shared_type:
11314die_pretty_print_decl(
const reader& rdr,
11315 const Dwarf_Die* die,
11316 bool qualified_name,
11318 size_t where_offset,
11319 unordered_set<uint64_t>& guard)
11321 if (!die || !die_is_decl(die))
11326 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11329 case DW_TAG_namespace:
11330 repr =
"namespace " + die_qualified_name(rdr, die, where_offset, guard);
11333 case DW_TAG_member:
11334 case DW_TAG_variable:
11336 string type_repr =
"void";
11337 Dwarf_Die type_die;
11338 if (die_die_attribute(die, DW_AT_type, type_die))
11339 type_repr = die_type_name(rdr, &type_die,
11343 repr = (qualified_name
11344 ? die_qualified_name(rdr, die, where_offset, guard)
11350 repr = type_repr +
" " + repr;
11354 case DW_TAG_subprogram:
11356 repr = die_function_signature(rdr, die, qualified_name,
11357 where_offset, guard);
11388die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset,
11389 unordered_set<uint64_t>& guard)
11391 if (die_is_type(die))
11392 return die_pretty_print_type(rdr, die, where_offset, guard);
11393 else if (die_is_decl(die))
11394 return die_pretty_print_decl(rdr, die,
11397 where_offset, guard);
11420compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
11424 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
11425 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11426 if (l_tag != r_tag)
11429 bool result =
false;
11431 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
11434 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
11436 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
11443 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
11453 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
11470at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
11471 const Dwarf_Die *l,
11472 const Dwarf_Die *r)
11474 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
11477 if ((die_is_declaration_only(l) && die_has_no_child(l))
11478 || (die_is_declaration_only(r) && die_has_no_child(r)))
11505compare_as_type_dies(
const reader& rdr,
11506 const Dwarf_Die *l,
11507 const Dwarf_Die *r)
11513 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
11514 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
11515 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11516 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
11524 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11529 uint64_t l_size = 0, r_size = 0;
11530 die_size_in_bits(l, l_size);
11531 die_size_in_bits(r, r_size);
11533 return l_size == r_size;
11548compare_as_decl_and_type_dies(
const reader &rdr,
11549 const Dwarf_Die *l,
11550 const Dwarf_Die *r)
11552 if (!compare_as_decl_dies(l, r)
11553 || !compare_as_type_dies(rdr, l, r))
11575fn_die_equal_by_linkage_name(
const Dwarf_Die *l,
11576 const Dwarf_Die *r)
11584 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
11586 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11589 string lname = die_name(l), rname = die_name(r);
11590 string llinkage_name = die_linkage_name(l),
11591 rlinkage_name = die_linkage_name(r);
11593 if (die_is_in_c_or_cplusplus(l)
11594 && die_is_in_c_or_cplusplus(r))
11596 if (!llinkage_name.empty() && !rlinkage_name.empty())
11597 return llinkage_name == rlinkage_name;
11598 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
11601 return lname == rname;
11604 return (!llinkage_name.empty()
11605 && !rlinkage_name.empty()
11606 && llinkage_name == rlinkage_name);
11638try_canonical_die_comparison(
const reader& rdr,
11639 Dwarf_Off l_offset, Dwarf_Off r_offset,
11641 bool& l_has_canonical_die_offset,
11642 bool& r_has_canonical_die_offset,
11643 Dwarf_Off& l_canonical_die_offset,
11644 Dwarf_Off& r_canonical_die_offset,
11647#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11648 if (rdr.debug_die_canonicalization_is_on_
11649 && !rdr.use_canonical_die_comparison_)
11654 l_has_canonical_die_offset =
11655 (l_canonical_die_offset =
11656 rdr.get_canonical_die_offset(l_offset, l_die_source,
11659 r_has_canonical_die_offset =
11660 (r_canonical_die_offset =
11661 rdr.get_canonical_die_offset(r_offset, r_die_source,
11664 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
11666 result = (l_canonical_die_offset == r_canonical_die_offset);
11673#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11686notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
11690#define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
11691 notify_die_comparison_failed(l, r)
11693#define NOTIFY_DIE_COMPARISON_FAILED(l, r)
11706#define ABG_RETURN(value) \
11709 if ((value) == COMPARISON_RESULT_DIFFERENT) \
11711 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11713 return return_comparison_result(l, r, dies_being_compared, \
11714 value, aggregates_being_compared, \
11715 update_canonical_dies_on_the_fly); \
11726#define ABG_RETURN_FALSE \
11729 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11730 return return_comparison_result(l, r, dies_being_compared, \
11731 COMPARISON_RESULT_DIFFERENT, \
11732 aggregates_being_compared, \
11733 update_canonical_dies_on_the_fly); \
11748#define SET_RESULT_TO_FALSE(result, l , r) \
11751 result = COMPARISON_RESULT_DIFFERENT; \
11752 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11768#define SET_RESULT_TO(result, value, l , r) \
11771 result = (value); \
11772 if (result == COMPARISON_RESULT_DIFFERENT) \
11774 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
11778#define RETURN_IF_COMPARISON_CYCLE_DETECTED \
11781 if (aggregates_being_compared.contains(dies_being_compared)) \
11783 result = COMPARISON_RESULT_CYCLE_DETECTED; \
11784 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
11785 ABG_RETURN(result); \
11800get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
11805 bool found_member =
false;
11806 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
11809 found_member = (dwarf_siblingof(member, member) == 0))
11811 int tag = dwarf_tag(member);
11812 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
11816 return found_member;
11833get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
11838 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
11840 || tag == DW_TAG_union_type
11841 || tag == DW_TAG_class_type);
11843 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die), child) == 0);
11848 tag = dwarf_tag(child);
11850 if (!(tag == DW_TAG_member
11851 || tag == DW_TAG_inheritance
11852 || tag == DW_TAG_subprogram))
11853 found_child = get_next_member_sibling_die(child, child);
11855 return found_child;
11878maybe_propagate_canonical_type(
const reader& rdr,
11879 const Dwarf_Die* l,
11880 const Dwarf_Die* r)
11882 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
11883 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
11885 if (l_tag != r_tag)
11888 if (is_canon_type_to_be_propagated_tag(l_tag))
11889 propagate_canonical_type(rdr, l, r);
11907propagate_canonical_type(
const reader& rdr,
11908 const Dwarf_Die* l,
11909 const Dwarf_Die* r)
11918 const die_source l_source = rdr.get_die_source(l);
11919 const die_source r_source = rdr.get_die_source(r);
11921 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
11922 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
11923 bool l_has_canonical_die_offset =
false;
11924 bool r_has_canonical_die_offset =
false;
11925 Dwarf_Off l_canonical_die_offset = 0;
11926 Dwarf_Off r_canonical_die_offset = 0;
11928 l_has_canonical_die_offset =
11929 (l_canonical_die_offset =
11930 rdr.get_canonical_die_offset(l_offset, l_source,
11933 r_has_canonical_die_offset =
11934 (r_canonical_die_offset =
11935 rdr.get_canonical_die_offset(r_offset, r_source,
11939 if (!l_has_canonical_die_offset
11940 && r_has_canonical_die_offset
11943 && l_source == r_source)
11946 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
11948 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
11949 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
11950 rdr.canonical_propagated_count_++;
11988return_comparison_result(
const Dwarf_Die* l,
11989 const Dwarf_Die* r,
11992 offset_pairs_stack_type& comparison_stack,
11993 bool do_propagate_canonical_type =
true)
11995 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
11997 if (result == COMPARISON_RESULT_EQUAL)
12002 if (do_propagate_canonical_type)
12005 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12011 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
12024 else if (result == COMPARISON_RESULT_UNKNOWN)
12065 if (comparison_stack.is_redundant(cur_dies)
12066 && comparison_stack.vect_.back() == cur_dies)
12070 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12071 comparison_stack.confirm_canonical_propagated_type(cur_dies);
12073 result = COMPARISON_RESULT_EQUAL;
12075 else if (is_canon_type_to_be_propagated_tag(l_tag)
12076 && comparison_stack.vect_.back() == cur_dies)
12081 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
12082 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
12086 else if (result == COMPARISON_RESULT_DIFFERENT)
12103 if (comparison_stack.is_redundant(cur_dies)
12104 && comparison_stack.vect_.back() == cur_dies)
12105 comparison_stack.cancel_canonical_propagated_type(cur_dies);
12113 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
12114 result = COMPARISON_RESULT_UNKNOWN;
12115 else if (is_canon_type_to_be_propagated_tag(l_tag)
12116 && !comparison_stack.vect_.empty()
12117 && comparison_stack.vect_.back() == cur_dies)
12122 comparison_stack.erase(cur_dies);
12124 maybe_cache_type_comparison_result(comparison_stack.rdr_,
12125 l_tag, cur_dies, result);
12154compare_dies(
const reader& rdr,
12155 const Dwarf_Die *l,
const Dwarf_Die *r,
12156 offset_pairs_stack_type& aggregates_being_compared,
12157 bool update_canonical_dies_on_the_fly)
12162 const die_source l_die_source = rdr.get_die_source(l);
12163 const die_source r_die_source = rdr.get_die_source(r);
12165 offset_type l_offset =
12168 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
12171 offset_type r_offset =
12174 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
12179 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
12180 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
12182 if (l_tag != r_tag)
12185 if (l_offset == r_offset)
12186 return COMPARISON_RESULT_EQUAL;
12188 if (rdr.leverage_dwarf_factorization()
12189 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
12190 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
12191 if (l_offset != r_offset)
12192 return COMPARISON_RESULT_DIFFERENT;
12195 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
12196 dies_being_compared,
12200 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
12201 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
12205 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
12207 bool canonical_compare_result =
false;
12208 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
12209 l_die_source, r_die_source,
12210 l_has_canonical_die_offset,
12211 r_has_canonical_die_offset,
12212 l_canonical_die_offset,
12213 r_canonical_die_offset,
12214 canonical_compare_result))
12218 (canonical_compare_result
12219 ? COMPARISON_RESULT_EQUAL
12220 : COMPARISON_RESULT_DIFFERENT),
12230 case DW_TAG_base_type:
12231 case DW_TAG_string_type:
12232 case DW_TAG_unspecified_type:
12233 if (!compare_as_decl_and_type_dies(rdr, l, r))
12237 case DW_TAG_typedef:
12238 case DW_TAG_pointer_type:
12239 case DW_TAG_reference_type:
12240 case DW_TAG_rvalue_reference_type:
12241 case DW_TAG_const_type:
12242 case DW_TAG_volatile_type:
12243 case DW_TAG_restrict_type:
12245 if (!compare_as_type_dies(rdr, l, r))
12251 bool from_the_same_tu =
false;
12252 if (!pointer_or_qual_die_of_anonymous_class_type(l)
12253 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
12254 && from_the_same_tu)
12271 Dwarf_Die lu_type_die, ru_type_die;
12272 bool lu_is_void, ru_is_void;
12274 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
12275 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
12277 if (lu_is_void && ru_is_void)
12278 result = COMPARISON_RESULT_EQUAL;
12279 else if (lu_is_void != ru_is_void)
12282 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
12283 aggregates_being_compared,
12284 update_canonical_dies_on_the_fly);
12288 case DW_TAG_enumeration_type:
12289 if (!compare_as_decl_and_type_dies(rdr, l, r))
12294 Dwarf_Die l_enumtor, r_enumtor;
12295 bool found_l_enumtor =
true, found_r_enumtor =
true;
12297 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
12298 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
12300 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
12302 found_l_enumtor && found_r_enumtor;
12303 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
12304 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
12306 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
12307 if ( l_tag != r_tag)
12313 if (l_tag != DW_TAG_enumerator)
12316 uint64_t l_val = 0, r_val = 0;
12317 die_unsigned_constant_attribute(&l_enumtor,
12320 die_unsigned_constant_attribute(&r_enumtor,
12323 if (l_val != r_val)
12329 if (found_l_enumtor != found_r_enumtor )
12334 case DW_TAG_structure_type:
12335 case DW_TAG_union_type:
12336 case DW_TAG_class_type:
12338 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12340 rdr.compare_count_++;
12342 if (!compare_as_decl_and_type_dies(rdr, l, r))
12344 else if (rdr.options().assume_odr_for_cplusplus
12345 && rdr.odr_is_relevant(l)
12346 && rdr.odr_is_relevant(r)
12347 && !die_is_anonymous(l)
12348 && !die_is_anonymous(r))
12349 result = COMPARISON_RESULT_EQUAL;
12352 aggregates_being_compared.add(dies_being_compared);
12354 Dwarf_Die l_member, r_member;
12355 bool found_l_member =
true, found_r_member =
true;
12357 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
12358 for (found_l_member = get_member_child_die(l, &l_member),
12359 found_r_member = get_member_child_die(r, &r_member);
12360 found_l_member && found_r_member;
12361 found_l_member = get_next_member_sibling_die(&l_member,
12363 found_r_member = get_next_member_sibling_die(&r_member,
12366 int l_tag = dwarf_tag(&l_member),
12367 r_tag = dwarf_tag(&r_member);
12369 if (l_tag != r_tag)
12376 || l_tag == DW_TAG_variable
12377 || l_tag == DW_TAG_inheritance
12378 || l_tag == DW_TAG_subprogram);
12381 compare_dies(rdr, &l_member, &r_member,
12382 aggregates_being_compared,
12383 update_canonical_dies_on_the_fly);
12385 if (local_result == COMPARISON_RESULT_UNKNOWN)
12394 result = local_result;
12396 if (local_result == COMPARISON_RESULT_DIFFERENT)
12402 if (found_l_member != found_r_member)
12411 case DW_TAG_array_type:
12413 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12415 aggregates_being_compared.add(dies_being_compared);
12417 rdr.compare_count_++;
12419 Dwarf_Die l_child, r_child;
12420 bool found_l_child, found_r_child;
12421 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
12423 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
12425 found_l_child && found_r_child;
12426 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
12427 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
12429 int l_child_tag = dwarf_tag(&l_child),
12430 r_child_tag = dwarf_tag(&r_child);
12431 if (l_child_tag == DW_TAG_subrange_type
12432 || r_child_tag == DW_TAG_subrange_type)
12434 result = compare_dies(rdr, &l_child, &r_child,
12435 aggregates_being_compared,
12436 update_canonical_dies_on_the_fly);
12444 if (found_l_child != found_r_child)
12447 Dwarf_Die ltype_die, rtype_die;
12448 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
12449 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
12452 result = compare_dies(rdr, <ype_die, &rtype_die,
12453 aggregates_being_compared,
12454 update_canonical_dies_on_the_fly);
12460 case DW_TAG_subrange_type:
12462 uint64_t l_lower_bound = 0, r_lower_bound = 0,
12463 l_upper_bound = 0, r_upper_bound = 0;
12464 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
12465 l_upper_bound_set =
false, r_upper_bound_set =
false;
12467 l_lower_bound_set =
12468 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
12469 r_lower_bound_set =
12470 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
12472 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
12475 uint64_t l_count = 0;
12476 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
12478 l_upper_bound = l_lower_bound + l_count;
12479 l_upper_bound_set =
true;
12485 l_upper_bound_set =
true;
12487 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
12490 uint64_t r_count = 0;
12491 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
12493 r_upper_bound = r_lower_bound + r_count;
12494 r_upper_bound_set =
true;
12500 r_upper_bound_set =
true;
12502 if ((l_lower_bound_set != r_lower_bound_set)
12503 || (l_upper_bound_set != r_upper_bound_set)
12504 || (l_lower_bound != r_lower_bound)
12505 || (l_upper_bound != r_upper_bound))
12510 case DW_TAG_subroutine_type:
12511 case DW_TAG_subprogram:
12513 RETURN_IF_COMPARISON_CYCLE_DETECTED;
12515 aggregates_being_compared.add(dies_being_compared);
12517 rdr.compare_count_++;
12519 if (l_tag == DW_TAG_subprogram
12520 && !fn_die_equal_by_linkage_name(l, r))
12525 else if (l_tag == DW_TAG_subprogram
12526 && die_is_in_c(l) && die_is_in_c(r))
12528 result = COMPARISON_RESULT_EQUAL;
12531 else if (!die_is_in_c(l) && !die_is_in_c(r))
12537 Dwarf_Die l_return_type, r_return_type;
12538 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
12540 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
12542 if (l_return_type_is_void != r_return_type_is_void
12543 || (!l_return_type_is_void
12544 && !compare_dies(rdr,
12545 &l_return_type, &r_return_type,
12546 aggregates_being_compared,
12547 update_canonical_dies_on_the_fly)))
12551 Dwarf_Die l_child, r_child;
12552 bool found_l_child, found_r_child;
12553 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
12555 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
12557 found_l_child && found_r_child;
12558 found_l_child = dwarf_siblingof(&l_child,
12560 found_r_child = dwarf_siblingof(&r_child,
12563 int l_child_tag = dwarf_tag(&l_child);
12564 int r_child_tag = dwarf_tag(&r_child);
12566 COMPARISON_RESULT_EQUAL;
12567 if (l_child_tag != r_child_tag)
12568 local_result = COMPARISON_RESULT_DIFFERENT;
12569 if (l_child_tag == DW_TAG_formal_parameter)
12571 compare_dies(rdr, &l_child, &r_child,
12572 aggregates_being_compared,
12573 update_canonical_dies_on_the_fly);
12574 if (local_result == COMPARISON_RESULT_DIFFERENT)
12576 result = local_result;
12580 if (local_result == COMPARISON_RESULT_UNKNOWN)
12591 result = local_result;
12593 if (found_l_child != found_r_child)
12603 case DW_TAG_formal_parameter:
12605 Dwarf_Die l_type, r_type;
12606 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
12607 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
12608 if (l_type_is_void != r_type_is_void)
12610 else if (!l_type_is_void)
12613 compare_dies(rdr, &l_type, &r_type,
12614 aggregates_being_compared,
12615 update_canonical_dies_on_the_fly);
12621 case DW_TAG_variable:
12622 case DW_TAG_member:
12623 if (compare_as_decl_dies(l, r))
12626 if (l_tag == DW_TAG_member)
12628 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
12629 die_member_offset(rdr, l, l_offset_in_bits);
12630 die_member_offset(rdr, r, r_offset_in_bits);
12631 if (l_offset_in_bits != r_offset_in_bits)
12637 Dwarf_Die l_type, r_type;
12638 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12639 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12641 compare_dies(rdr, &l_type, &r_type,
12642 aggregates_being_compared,
12643 update_canonical_dies_on_the_fly);
12651 case DW_TAG_inheritance:
12653 Dwarf_Die l_type, r_type;
12654 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12655 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12656 result = compare_dies(rdr, &l_type, &r_type,
12657 aggregates_being_compared,
12658 update_canonical_dies_on_the_fly);
12662 uint64_t l_a = 0, r_a = 0;
12663 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
12664 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
12668 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
12669 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
12673 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
12674 die_member_offset(rdr, l, l_offset_in_bits);
12675 die_member_offset(rdr, r, r_offset_in_bits);
12676 if (l_offset_in_bits != r_offset_in_bits)
12681 case DW_TAG_ptr_to_member_type:
12683 bool comp_result =
false;
12684 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
12688 Dwarf_Die l_type, r_type;
12689 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
12690 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
12691 result = compare_dies(rdr, &l_type, &r_type,
12692 aggregates_being_compared,
12693 update_canonical_dies_on_the_fly);
12697 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
12698 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
12699 result = compare_dies(rdr, &l_type, &r_type,
12700 aggregates_being_compared,
12701 update_canonical_dies_on_the_fly);
12707 case DW_TAG_enumerator:
12708 case DW_TAG_packed_type:
12709 case DW_TAG_set_type:
12710 case DW_TAG_file_type:
12711 case DW_TAG_thrown_type:
12712 case DW_TAG_interface_type:
12713 case DW_TAG_shared_type:
12714 case DW_TAG_compile_unit:
12715 case DW_TAG_namespace:
12716 case DW_TAG_module:
12717 case DW_TAG_constant:
12718 case DW_TAG_partial_unit:
12719 case DW_TAG_imported_unit:
12720 case DW_TAG_dwarf_procedure:
12721 case DW_TAG_imported_declaration:
12722 case DW_TAG_entry_point:
12724 case DW_TAG_lexical_block:
12725 case DW_TAG_unspecified_parameters:
12726 case DW_TAG_variant:
12727 case DW_TAG_common_block:
12728 case DW_TAG_common_inclusion:
12729 case DW_TAG_inlined_subroutine:
12730 case DW_TAG_with_stmt:
12731 case DW_TAG_access_declaration:
12732 case DW_TAG_catch_block:
12733 case DW_TAG_friend:
12734 case DW_TAG_namelist:
12735 case DW_TAG_namelist_item:
12736 case DW_TAG_template_type_parameter:
12737 case DW_TAG_template_value_parameter:
12738 case DW_TAG_try_block:
12739 case DW_TAG_variant_part:
12740 case DW_TAG_imported_module:
12741 case DW_TAG_condition:
12742 case DW_TAG_type_unit:
12743 case DW_TAG_template_alias:
12744 case DW_TAG_lo_user:
12745 case DW_TAG_MIPS_loop:
12746 case DW_TAG_format_label:
12747 case DW_TAG_function_template:
12748 case DW_TAG_class_template:
12749 case DW_TAG_GNU_BINCL:
12750 case DW_TAG_GNU_EINCL:
12751 case DW_TAG_GNU_template_template_param:
12752 case DW_TAG_GNU_template_parameter_pack:
12753 case DW_TAG_GNU_formal_parameter_pack:
12754 case DW_TAG_GNU_call_site:
12755 case DW_TAG_GNU_call_site_parameter:
12756 case DW_TAG_hi_user:
12757#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
12758 if (rdr.debug_die_canonicalization_is_on_)
12785compare_dies(
const reader& rdr,
12786 const Dwarf_Die *l,
12787 const Dwarf_Die *r,
12788 bool update_canonical_dies_on_the_fly)
12790 offset_pairs_stack_type aggregates_being_compared(rdr);
12791 return compare_dies(rdr, l, r, aggregates_being_compared,
12792 update_canonical_dies_on_the_fly);
12814compare_dies_during_canonicalization(reader& rdr,
12815 const Dwarf_Die *l,
12816 const Dwarf_Die *r,
12817 bool update_canonical_dies_on_the_fly)
12819#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
12820 if (rdr.debug_die_canonicalization_is_on_)
12822 bool canonical_equality =
false, structural_equality =
false;
12823 rdr.use_canonical_die_comparison_ =
false;
12824 structural_equality = compare_dies(rdr, l, r,
12826 rdr.use_canonical_die_comparison_ =
true;
12827 canonical_equality = compare_dies(rdr, l, r,
12828 update_canonical_dies_on_the_fly);
12829 if (canonical_equality != structural_equality)
12831 std::cerr <<
"structural & canonical equality different for DIEs: "
12833 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
12834 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
12837 << rdr.get_die_pretty_type_representation(l, 0)
12842 return structural_equality;
12845 return compare_dies(rdr, l, r,
12846 update_canonical_dies_on_the_fly);
12888find_import_unit_point_between_dies(
const reader& rdr,
12889 size_t partial_unit_offset,
12890 Dwarf_Off first_die_offset,
12891 Dwarf_Off first_die_cu_offset,
12893 size_t last_die_offset,
12894 size_t& imported_point_offset)
12897 rdr.tu_die_imported_unit_points_map(source);
12899 tu_die_imported_unit_points_map_type::const_iterator iter =
12900 tu_die_imported_unit_points_map.find(first_die_cu_offset);
12902 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
12905 if (imported_unit_points.empty())
12908 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
12909 imported_unit_points_type::const_iterator e = imported_unit_points.end();
12911 find_lower_bound_in_imported_unit_points(imported_unit_points,
12915 if (last_die_offset !=
static_cast<size_t>(-1))
12916 find_lower_bound_in_imported_unit_points(imported_unit_points,
12920 if (e != imported_unit_points.end())
12922 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
12923 if (i->imported_unit_die_off == partial_unit_offset)
12925 imported_point_offset = i->offset_of_import ;
12929 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
12931 if (find_import_unit_point_between_dies(rdr,
12932 partial_unit_offset,
12933 i->imported_unit_child_off,
12934 i->imported_unit_cu_off,
12935 i->imported_unit_die_source,
12937 imported_point_offset))
12943 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
12944 if (i->imported_unit_die_off == partial_unit_offset)
12946 imported_point_offset = i->offset_of_import ;
12950 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
12952 if (find_import_unit_point_between_dies(rdr,
12953 partial_unit_offset,
12954 i->imported_unit_child_off,
12955 i->imported_unit_cu_off,
12956 i->imported_unit_die_source,
12958 imported_point_offset))
12991find_import_unit_point_before_die(
const reader& rdr,
12992 size_t partial_unit_offset,
12993 size_t where_offset,
12994 size_t& imported_point_offset)
12996 size_t import_point_offset = 0;
12997 Dwarf_Die first_die_of_tu;
12999 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
13000 &first_die_of_tu) != 0)
13003 Dwarf_Die cu_die_memory;
13006 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
13007 &cu_die_memory, 0, 0);
13009 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
13010 dwarf_dieoffset(&first_die_of_tu),
13011 dwarf_dieoffset(cu_die),
13012 PRIMARY_DEBUG_INFO_DIE_SOURCE,
13014 import_point_offset))
13016 imported_point_offset = import_point_offset;
13020 if (import_point_offset)
13022 imported_point_offset = import_point_offset;
13050get_parent_die(
const reader& rdr,
13051 const Dwarf_Die* die,
13052 Dwarf_Die& parent_die,
13053 size_t where_offset)
13057 const die_source source = rdr.get_die_source(die);
13060 offset_offset_map_type::const_iterator i =
13061 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
13068 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
13069 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
13070 i->second, &parent_die));
13072 case ALT_DEBUG_INFO_DIE_SOURCE:
13073 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
13074 i->second, &parent_die));
13076 case TYPE_UNIT_DIE_SOURCE:
13077 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
13078 i->second, &parent_die));
13080 case NO_DEBUG_INFO_DIE_SOURCE:
13081 case NUMBER_OF_DIE_SOURCES:
13085 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
13087 if (where_offset == 0)
13089 parent_die = *rdr.cur_tu_die();
13092 size_t import_point_offset = 0;
13094 find_import_unit_point_before_die(rdr,
13095 dwarf_dieoffset(&parent_die),
13097 import_point_offset);
13103 parent_die = *rdr.cur_tu_die();
13107 Dwarf_Die import_point_die;
13108 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
13109 import_point_offset,
13110 &import_point_die));
13111 return get_parent_die(rdr, &import_point_die,
13112 parent_die, where_offset);
13145get_scope_die(
const reader& rdr,
13146 const Dwarf_Die* dye,
13147 size_t where_offset,
13148 Dwarf_Die& scope_die)
13150 Dwarf_Die origin_die_mem;
13151 Dwarf_Die *die = &origin_die_mem;
13152 if (!die_origin_die(dye, origin_die_mem))
13153 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
13156 get_die_language(die, die_lang);
13158 || rdr.die_parent_map(rdr.get_die_source(die)).empty())
13160 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
13161 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
13164 if (!get_parent_die(rdr, die, scope_die, where_offset))
13167 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
13168 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
13169 || dwarf_tag(&scope_die) == DW_TAG_array_type)
13170 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
13200get_scope_for_die(reader& rdr,
13202 bool called_for_public_decl,
13203 size_t where_offset)
13205 Dwarf_Die origin_die_mem;
13206 Dwarf_Die *die = &origin_die_mem;
13208 if (!die_origin_die(dye, origin_die_mem))
13211 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
13213 const die_source source_of_die = rdr.get_die_source(die);
13216 get_die_language(die, die_lang);
13218 || rdr.die_parent_map(source_of_die).empty())
13223 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
13224 return rdr.global_scope();
13227 Dwarf_Die parent_die;
13229 if (!get_parent_die(rdr, die, parent_die, where_offset))
13230 return rdr.nil_scope();
13232 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
13233 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
13234 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
13236 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
13237 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
13239 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
13240 || source_of_die == TYPE_UNIT_DIE_SOURCE);
13241 return rdr.cur_transl_unit()->get_global_scope();
13250 die_tu_map_type::const_iterator i =
13251 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
13252 if (i != rdr.die_tu_map().end())
13253 return i->second->get_global_scope();
13254 return rdr.cur_transl_unit()->get_global_scope();
13259 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
13260 || dwarf_tag(&parent_die) == DW_TAG_array_type
13261 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
13273 called_for_public_decl,
13282 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
13283 return rdr.nil_scope();
13284 s = get_scope_for_die(rdr, &parent_die,
13285 called_for_public_decl,
13291 d = build_ir_node_from_die(rdr, &parent_die,
13292 called_for_public_decl,
13294 s = dynamic_pointer_cast<scope_decl>(d);
13298 return rdr.nil_scope();
13301 if (cl && cl->get_is_declaration_only())
13304 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
13321dwarf_language_to_tu_language(
size_t l)
13326 return translation_unit::LANG_C89;
13328 return translation_unit::LANG_C99;
13329#ifdef HAVE_DW_LANG_C11_enumerator
13331 return translation_unit::LANG_C11;
13333#ifdef HAVE_DW_LANG_C17
13335 return translation_unit::LANG_C17;
13337#ifdef HAVE_DW_LANG_C23
13339 return translation_unit::LANG_C23;
13342 return translation_unit::LANG_C;
13343#ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
13344 case DW_LANG_C_plus_plus_03:
13345 return translation_unit::LANG_C_plus_plus_03;
13348#ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
13349 case DW_LANG_C_plus_plus_11:
13350 return translation_unit::LANG_C_plus_plus_11;
13353#ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
13354 case DW_LANG_C_plus_plus_14:
13355 return translation_unit::LANG_C_plus_plus_14;
13357#ifdef HAVE_DW_LANG_C_plus_plus_17
13358 case DW_LANG_C_plus_plus_17:
13359 return translation_unit::LANG_C_plus_plus_17;
13362#ifdef HAVE_DW_LANG_C_plus_plus_20
13363 case DW_LANG_C_plus_plus_20:
13364 return translation_unit::LANG_C_plus_plus_20;
13366#ifdef HAVE_DW_LANG_C_plus_plus_23
13367 case DW_LANG_C_plus_plus_23:
13368 return translation_unit::LANG_C_plus_plus_23;
13370 case DW_LANG_C_plus_plus:
13371 return translation_unit::LANG_C_plus_plus;
13372#ifdef HAVE_DW_LANG_D_enumerator
13374 return translation_unit::LANG_D;
13376#ifdef HAVE_DW_LANG_OCaml_enumerator
13377 case DW_LANG_OCaml:
13378 return translation_unit::LANG_OCaml;
13380#ifdef HAVE_DW_LANG_Go_enumerator
13382 return translation_unit::LANG_Go;
13384#ifdef HAVE_DW_LANG_Rust_enumerator
13386 return translation_unit::LANG_Rust;
13388#ifdef HAVE_DW_LANG_Zig
13390 return translation_unit::LANG_Zig;
13392#ifdef HAVE_DW_LANG_Metal
13393 case DW_LANG_Metal:
13394 return translation_unit::LANG_Metal;
13396 case DW_LANG_Ada83:
13397 return translation_unit::LANG_Ada83;
13398 case DW_LANG_Ada95:
13399 return translation_unit::LANG_Ada95;
13400#ifdef HAVE_DW_LANG_Ada2005
13401 case DW_LANG_Ada2005:
13402 return translation_unit::LANG_Ada2005;
13405#ifdef HAVE_DW_LANG_Ada2012
13406 case DW_LANG_Ada2012:
13407 return translation_unit::LANG_Ada2012;
13409 case DW_LANG_Cobol74:
13410 return translation_unit::LANG_Cobol74;
13411 case DW_LANG_Cobol85:
13412 return translation_unit::LANG_Cobol85;
13413 case DW_LANG_Fortran77:
13414 return translation_unit::LANG_Fortran77;
13415 case DW_LANG_Fortran90:
13416 return translation_unit::LANG_Fortran90;
13417 case DW_LANG_Fortran95:
13418 return translation_unit::LANG_Fortran95;
13419#ifdef HAVE_DW_LANG_Fortran18
13420 case DW_LANG_Fortran18:
13421 return translation_unit::LANG_Fortran18;
13423#ifdef HAVE_DW_LANG_Fortran23
13424 case DW_LANG_Fortran23:
13425 return translation_unit::LANG_Fortran23;
13427 case DW_LANG_Pascal83:
13428 return translation_unit::LANG_Pascal83;
13429 case DW_LANG_Modula2:
13430 return translation_unit::LANG_Modula2;
13432 return translation_unit::LANG_Java;
13433#ifdef HAVE_DW_LANG_Kotlin
13434 case DW_LANG_Kotlin:
13435 return translation_unit::LANG_Kotlin;
13438 return translation_unit::LANG_PLI;
13440 return translation_unit::LANG_ObjC;
13441 case DW_LANG_ObjC_plus_plus:
13442 return translation_unit::LANG_ObjC_plus_plus;
13444#ifdef HAVE_DW_LANG_UPC_enumerator
13446 return translation_unit::LANG_UPC;
13448#ifdef HAVE_DW_LANG_Python_enumerator
13449 case DW_LANG_Python:
13450 return translation_unit::LANG_Python;
13452#ifdef HAVE_DW_LANG_Ruby
13454 return translation_unit::LANG_Ruby;
13456#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
13457 case DW_LANG_Mips_Assembler:
13458 return translation_unit::LANG_Mips_Assembler;
13460#ifdef HAVE_DW_LANG_Assembly
13461 case DW_LANG_Assembly:
13462 return translation_unit::LANG_Assembly;
13464#ifdef HAVE_DW_LANG_Crystal
13465 case DW_LANG_Crystal:
13466 return translation_unit::LANG_Crystal;
13468#ifdef HAVE_DW_LANG_HIP
13470 return translation_unit::LANG_HIP;
13472#ifdef HAVE_DW_LANG_C_sharp
13473 case DW_LANG_C_sharp:
13474 return translation_unit::LANG_C_sharp;
13476#ifdef HAVE_DW_LANG_Mojo
13478 return translation_unit::LANG_Mojo;
13480#ifdef HAVE_DW_LANG_GLSL
13482 return translation_unit::LANG_GLSL;
13484#ifdef HAVE_DW_LANG_GLSL_ES
13485 case DW_LANG_GLSL_ES:
13486 return translation_unit::LANG_GLSL_ES;
13488#ifdef HAVE_DW_LANG_HLSL
13490 return translation_unit::LANG_HLSL;
13492#ifdef HAVE_DW_LANG_OpenCL_CPP
13493 case DW_LANG_OpenCL_CPP:
13494 return translation_unit::LANG_OpenCL_CPP;
13496#ifdef HAVE_DW_LANG_CPP_for_OpenCL
13497 case DW_LANG_CPP_for_OpenCL:
13498 return translation_unit::LANG_CPP_for_OpenCL;
13500#ifdef HAVE_DW_LANG_SYCL
13502 return translation_unit::LANG_SYCL;
13504#ifdef HAVE_DW_LANG_Odin
13506 return translation_unit::LANG_Odin;
13508#ifdef HAVE_DW_LANG_P4
13510 return translation_unit::LANG_P4;
13512#ifdef HAVE_DW_LANG_Move
13514 return translation_unit::LANG_Move;
13516#ifdef HAVE_DW_LANG_Hylo
13518 return translation_unit::LANG_Hylo;
13522 return translation_unit::LANG_UNKNOWN;
13539 case translation_unit::LANG_UNKNOWN:
13540 case translation_unit::LANG_C89:
13541 case translation_unit::LANG_C99:
13542 case translation_unit::LANG_C11:
13543 case translation_unit::LANG_C17:
13544 case translation_unit::LANG_C23:
13545 case translation_unit::LANG_C:
13546 case translation_unit::LANG_C_plus_plus_03:
13547 case translation_unit::LANG_C_plus_plus_11:
13548 case translation_unit::LANG_C_plus_plus_14:
13549 case translation_unit::LANG_C_plus_plus_17:
13550 case translation_unit::LANG_C_plus_plus_20:
13551 case translation_unit::LANG_C_plus_plus_23:
13552 case translation_unit::LANG_C_plus_plus:
13553 case translation_unit::LANG_OCaml:
13554 case translation_unit::LANG_ObjC:
13555 case translation_unit::LANG_ObjC_plus_plus:
13556 case translation_unit::LANG_D:
13557 case translation_unit::LANG_Rust:
13558 case translation_unit::LANG_Go:
13559 case translation_unit::LANG_Zig:
13560 case translation_unit::LANG_Metal:
13561 case translation_unit::LANG_Java:
13562 case translation_unit::LANG_Kotlin:
13563 case translation_unit::LANG_Python:
13564 case translation_unit::LANG_Ruby:
13565 case translation_unit::LANG_UPC:
13566 case translation_unit::LANG_Mips_Assembler:
13567 case translation_unit::LANG_Assembly:
13568 case translation_unit::LANG_Crystal:
13569 case translation_unit::LANG_HIP:
13570 case translation_unit::LANG_C_sharp:
13571 case translation_unit::LANG_Mojo:
13572 case translation_unit::LANG_GLSL:
13573 case translation_unit::LANG_GLSL_ES:
13574 case translation_unit::LANG_HLSL:
13575 case translation_unit::LANG_Odin:
13576 case translation_unit::LANG_P4:
13577 case translation_unit::LANG_OpenCL_CPP:
13578 case translation_unit::LANG_CPP_for_OpenCL:
13579 case translation_unit::LANG_SYCL:
13580 case translation_unit::LANG_Move:
13581 case translation_unit::LANG_Hylo:
13584 case translation_unit::LANG_Cobol74:
13585 case translation_unit::LANG_Cobol85:
13586 case translation_unit::LANG_Fortran77:
13587 case translation_unit::LANG_Fortran90:
13588 case translation_unit::LANG_Fortran95:
13589 case translation_unit::LANG_Fortran18:
13590 case translation_unit::LANG_Fortran23:
13591 case translation_unit::LANG_Ada83:
13592 case translation_unit::LANG_Ada95:
13593 case translation_unit::LANG_Ada2005:
13594 case translation_unit::LANG_Ada2012:
13595 case translation_unit::LANG_Pascal83:
13596 case translation_unit::LANG_Modula2:
13597 case translation_unit::LANG_PLI:
13624 imported_unit_points_type::const_iterator& r)
13626 imported_unit_point v(val);
13627 imported_unit_points_type::const_iterator result =
13628 std::lower_bound(p.begin(), p.end(), v);
13630 bool is_ok = result != p.end();
13652build_translation_unit_and_add_to_ir(reader& rdr,
13660 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
13664 rdr.clear_per_translation_unit_data();
13666 rdr.cur_tu_die(die);
13668 string path = die_string_attribute(die, DW_AT_name);
13669 if (path ==
"<artificial>")
13675 std::ostringstream o;
13676 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
13679 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
13689 const string& abs_path =
13690 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
13691 result = rdr.corpus()->find_translation_unit(abs_path);
13696 result.reset(
new translation_unit(rdr.env(),
13699 result->set_compilation_dir_path(compilation_dir);
13700 rdr.corpus()->add(result);
13702 die_unsigned_constant_attribute(die, DW_AT_language, l);
13703 result->set_language(dwarf_language_to_tu_language(l));
13706 rdr.cur_transl_unit(result);
13707 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
13710 if (dwarf_child(die, &child) != 0)
13713 result->set_is_constructed(
false);
13714 int tag = dwarf_tag(&child);
13716 if (rdr.load_undefined_interfaces()
13717 && (rdr.is_decl_die_with_undefined_symbol(&child)
13718 || tag == DW_TAG_class_type
13723 || ((tag == DW_TAG_union_type || tag == DW_TAG_structure_type)
13724 && die_is_in_cplus_plus(&child))))
13728 build_ir_node_from_die(rdr, &child,
13733 dwarf_dieoffset(&child));
13735 else if (!rdr.env().analyze_exported_interfaces_only()
13736 || rdr.is_decl_die_with_exported_symbol(&child))
13740 build_ir_node_from_die(rdr, &child,
13741 die_is_public_decl(&child),
13742 dwarf_dieoffset(&child));
13744 while (dwarf_siblingof(&child, &child) == 0);
13746 if (!rdr.var_decls_to_re_add_to_tree().empty())
13747 for (list<var_decl_sptr>::const_iterator v =
13748 rdr.var_decls_to_re_add_to_tree().begin();
13749 v != rdr.var_decls_to_re_add_to_tree().end();
13756 string demangled_name =
13758 if (!demangled_name.empty())
13760 std::list<string> fqn_comps;
13762 string mem_name = fqn_comps.back();
13763 fqn_comps.pop_back();
13766 if (!fqn_comps.empty())
13794 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
13800 rdr.var_decls_to_re_add_to_tree().clear();
13802 result->set_is_constructed(
true);
13827build_namespace_decl_and_add_to_ir(reader& rdr,
13829 size_t where_offset)
13836 unsigned tag = dwarf_tag(die);
13837 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
13844 string name, linkage_name;
13846 die_loc_and_name(rdr, die, loc, name, linkage_name);
13848 result.reset(
new namespace_decl(rdr.env(), name, loc));
13850 rdr.associate_die_to_decl(die, result, where_offset);
13853 if (dwarf_child(die, &child) != 0)
13856 rdr.scope_stack().push(result.get());
13858 build_ir_node_from_die(rdr, &child,
13864 die_is_public_decl(die) && die_is_public_decl(&child),
13866 while (dwarf_siblingof(&child, &child) == 0);
13867 rdr.scope_stack().pop();
13882build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
13888 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
13890 uint64_t byte_size = 0, bit_size = 0;
13891 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
13892 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
13895 if (bit_size == 0 && byte_size != 0)
13897 bit_size = byte_size * 8;
13899 string type_name, linkage_name;
13901 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
13903 if (byte_size == 0)
13907 if (type_name ==
"void")
13908 result =
is_type_decl(build_ir_node_for_void_type(rdr));
13915 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13917 string normalized_type_name = type_name;
13918 real_type real_type;
13920 normalized_type_name = real_type.
to_string();
13925 if (corpus_sptr corp = rdr.corpus())
13928 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
13929 0, loc, linkage_name));
13930 rdr.associate_die_to_type(die, result, where_offset);
13948build_enum_underlying_type(reader& rdr,
13950 uint64_t enum_size,
13951 bool is_anonymous =
true)
13953 string underlying_type_name =
13957 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
13958 enum_size, enum_size, location()));
13959 result->set_is_anonymous(is_anonymous);
13960 result->set_is_artificial(
true);
13963 result = dynamic_pointer_cast<type_decl>(d);
13965 maybe_canonicalize_type(result, rdr);
13984build_enum_type(reader& rdr,
13987 size_t where_offset,
13988 bool is_declaration_only)
13994 unsigned tag = dwarf_tag(die);
13995 if (tag != DW_TAG_enumeration_type)
13998 string name, linkage_name;
14000 die_loc_and_name(rdr, die, loc, name, linkage_name);
14002 bool is_anonymous =
false;
14006 name = get_internal_anonymous_die_prefix_name(die);
14009 is_anonymous =
true;
14011 scope_decl* sc = scope ? scope : rdr.global_scope().get();
14012 if (
size_t s = sc->get_num_anonymous_member_enums())
14013 name = build_internal_anonymous_die_name(name, s);
14016 bool use_odr = rdr.odr_is_relevant(die);
14028 result = pre_existing_enum;
14030 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14039 if (pre_existing_enum->get_location() == loc)
14040 result = pre_existing_enum;
14045 rdr.associate_die_to_type(die, result, where_offset);
14053 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14055 bool is_artificial = die_is_artificial(die);
14058 bool enum_underlying_type_is_anonymous=
true;
14062 if (dwarf_child(die, &child) == 0)
14066 if (dwarf_tag(&child) != DW_TAG_enumerator)
14071 die_loc_and_name(rdr, &child, l, n, m);
14073 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
14074 enms.push_back(enum_type_decl::enumerator(n, val));
14076 while (dwarf_siblingof(&child, &child) == 0);
14084 build_enum_underlying_type(rdr, name, size,
14085 enum_underlying_type_is_anonymous);
14086 t->set_is_declaration_only(is_declaration_only);
14088 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
14089 result->set_is_anonymous(is_anonymous);
14090 result->set_is_declaration_only(is_declaration_only);
14091 result->set_is_artificial(is_artificial);
14092 rdr.associate_die_to_type(die, result, where_offset);
14111finish_member_function_reading(Dwarf_Die* die,
14113 const class_or_union_sptr klass,
14124 size_t is_inline = die_is_declared_inline(die);
14125 bool is_ctor = (f->get_name() == klass->get_name());
14126 bool is_dtor = (!f->get_name().empty()
14127 &&
static_cast<string>(f->get_name())[0] ==
'~');
14128 bool is_virtual = die_is_virtual(die);
14129 int64_t vindex = -1;
14131 die_virtual_function_index(die, vindex);
14134 if (!c->is_struct())
14135 access = private_access;
14136 die_access_specifier(die, access);
14138 m->is_declared_inline(is_inline);
14142 bool is_static = method_t->get_is_for_static_method();
14150 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol()
14170 Dwarf_Off die_offset = dwarf_dieoffset(die);
14172 rdr.die_function_decl_with_no_symbol_map();
14173 die_function_decl_map_type::const_iterator i =
14174 fns_with_no_symbol.find(die_offset);
14175 if (i == fns_with_no_symbol.end())
14176 fns_with_no_symbol[die_offset] = f;
14197maybe_finish_function_decl_reading(reader& rdr,
14199 size_t where_offset,
14217static type_base_sptr
14218lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
14221 corpus* corp = scope->get_corpus();
14242static type_base_sptr
14243lookup_class_or_typedef_from_corpus(reader& rdr,
14245 bool called_for_public_decl,
14246 size_t where_offset)
14251 string class_name = die_string_attribute(die, DW_AT_name);
14252 if (class_name.empty())
14256 called_for_public_decl,
14259 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
14261 return type_base_sptr();
14278static method_decl_sptr
14279is_function_for_die_a_member_of_class(reader& rdr,
14280 Dwarf_Die* function_die,
14281 const class_or_union_sptr& class_type)
14286 return method_decl_sptr();
14292 method_type = method->get_type();
14297 class_or_union_sptr method_class = method_type->get_class_type();
14300 string method_class_name = method_class->get_qualified_name(),
14301 class_type_name = class_type->get_qualified_name();
14303 if (method_class_name == class_type_name)
14309 return method_decl_sptr();
14331static method_decl_sptr
14332add_or_update_member_function(reader& rdr,
14333 Dwarf_Die* function_die,
14334 const class_or_union_sptr& class_type,
14335 bool called_from_public_decl,
14336 size_t where_offset)
14338 method_decl_sptr method =
14339 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
14342 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
14344 called_from_public_decl,
14347 return method_decl_sptr();
14349 finish_member_function_reading(function_die,
14392add_or_update_class_type(reader& rdr,
14397 bool called_from_public_decl,
14398 size_t where_offset,
14399 bool is_declaration_only)
14405 const die_source source = rdr.get_die_source(die);
14407 unsigned tag = dwarf_tag(die);
14409 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
14413 die_class_or_union_map_type::const_iterator i =
14414 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14415 if (i != rdr.die_wip_classes_map(source).end())
14423 string name, linkage_name;
14425 die_loc_and_name(rdr, die, loc, name, linkage_name);
14426 cleanup_decl_name(name);
14428 bool is_anonymous =
false;
14433 name = get_internal_anonymous_die_prefix_name(die);
14436 is_anonymous =
true;
14440 s = scope->get_num_anonymous_member_classes();
14442 s = rdr.global_scope()->get_num_anonymous_member_classes();
14443 name = build_internal_anonymous_die_name(name, s);
14448 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14464 && (result->get_is_declaration_only() == is_declaration_only
14465 || (!result->get_is_declaration_only()
14466 && is_declaration_only)))
14468 rdr.associate_die_to_type(die, result, where_offset);
14487 klass = pre_existing_class;
14490 die_size_in_bits(die, size);
14491 bool is_artificial = die_is_artificial(die);
14494 bool has_child = (dwarf_child(die, &child) == 0);
14496 decl_base_sptr res;
14499 res = result = klass;
14500 if (has_child && klass->get_is_declaration_only()
14501 && klass->get_definition_of_declaration())
14502 res = result =
is_class_type(klass->get_definition_of_declaration());
14504 result->set_location(loc);
14508 result.reset(
new class_decl(rdr.env(), name, size,
14510 decl_base::VISIBILITY_DEFAULT,
14513 result->set_is_declaration_only(is_declaration_only);
14516 result = dynamic_pointer_cast<class_decl>(res);
14520 if (!klass || klass->get_is_declaration_only())
14521 if (size != result->get_size_in_bits())
14522 result->set_size_in_bits(size);
14527 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
14540 result->set_is_declaration_only(is_declaration_only);
14544 if (!result->get_is_declaration_only() && has_child)
14545 if (result->get_size_in_bits() == 0 && size != 0)
14546 result->set_size_in_bits(size);
14548 result->set_is_artificial(is_artificial);
14550 rdr.associate_die_to_type(die, result, where_offset);
14557 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
14559 bool is_incomplete_type =
false;
14560 if (is_declaration_only && size == 0 && has_child)
14572 is_incomplete_type =
true;
14575 dynamic_pointer_cast<scope_decl>(res);
14577 rdr.scope_stack().push(scop.get());
14579 if (has_child && !is_incomplete_type)
14583 tag = dwarf_tag(&child);
14586 if (tag == DW_TAG_inheritance)
14588 result->set_is_declaration_only(
false);
14590 Dwarf_Die type_die;
14591 if (!die_die_attribute(&child, DW_AT_type, type_die))
14594 string type_name = die_type_name(rdr, &type_die,
14597 type_base_sptr base_type;
14598 if (!type_name.empty())
14600 base_type = result->find_base_class(type_name);
14606 lookup_class_or_typedef_from_corpus(rdr, &type_die,
14607 called_from_public_decl,
14611 is_type(build_ir_node_from_die(rdr, &type_die,
14612 called_from_public_decl,
14626 die_access_specifier(&child, access);
14628 bool is_virt= die_is_virtual(&child);
14629 int64_t offset = 0;
14630 bool is_offset_present =
14631 die_member_offset(rdr, &child, offset);
14635 is_offset_present ? offset : -1,
14637 if (b->get_is_declaration_only()
14644 && !b->get_qualified_name().empty())
14645 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
14646 if (result->find_base_class(b->get_qualified_name()))
14648 result->add_base_specifier(base);
14651 else if (tag == DW_TAG_member
14652 || tag == DW_TAG_variable)
14654 Dwarf_Die type_die;
14655 if (!die_die_attribute(&child, DW_AT_type, type_die))
14660 die_loc_and_name(rdr, &child, loc, n, m);
14665 if (n.substr(0, 5) ==
"_vptr"
14667 && !std::isalnum(n.at(5))
14677 int64_t offset_in_bits = 0;
14678 bool is_laid_out = die_member_offset(rdr, &child,
14683 bool is_static = !is_laid_out;
14699 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
14700 called_from_public_decl,
14702 type_base_sptr t =
is_type(ty);
14706 if (n.empty() && !die_is_anonymous_data_member(&child))
14712 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
14729 result->set_is_declaration_only(
false);
14735 die_access_specifier(&child, access);
14743 result->add_data_member(dm, access, is_laid_out,
14744 is_static, offset_in_bits);
14746 rdr.associate_die_to_decl(&child, dm, where_offset,
14750 else if (tag == DW_TAG_subprogram)
14753 add_or_update_member_function(rdr, &child, result,
14754 called_from_public_decl,
14757 rdr.associate_die_to_decl(&child, f, where_offset,
14761 else if (die_is_type(&child))
14766 && !result->find_member_type(die_name(&child)))
14767 build_ir_node_from_die(rdr, &child, result.get(),
14768 called_from_public_decl,
14775 string anonymous_type_name =
14776 die_class_or_enum_flat_representation(rdr, &child,
14781 if (type_base_sptr member_t =
14782 result->find_member_type(anonymous_type_name))
14783 rdr.associate_die_to_decl(&child,
is_decl(member_t),
14789 is_type(build_ir_node_from_die(rdr, &child,
14791 called_from_public_decl,
14796 maybe_set_member_type_access_specifier(result,
14802 }
while (dwarf_siblingof(&child, &child) == 0);
14805 rdr.scope_stack().pop();
14808 die_class_or_union_map_type::const_iterator i =
14809 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14810 if (i != rdr.die_wip_classes_map(source).end())
14815 rdr.die_wip_classes_map(source).erase(i);
14846static union_decl_sptr
14847add_or_update_union_type(reader& rdr,
14850 union_decl_sptr union_type,
14851 bool called_from_public_decl,
14852 size_t where_offset,
14853 bool is_declaration_only)
14855 union_decl_sptr result;
14859 unsigned tag = dwarf_tag(die);
14861 if (tag != DW_TAG_union_type)
14864 const die_source source = rdr.get_die_source(die);
14866 die_class_or_union_map_type::const_iterator i =
14867 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
14868 if (i != rdr.die_wip_classes_map(source).end())
14876 string name, linkage_name;
14878 die_loc_and_name(rdr, die, loc, name, linkage_name);
14879 cleanup_decl_name(name);
14881 bool is_anonymous =
false;
14886 name = get_internal_anonymous_die_prefix_name(die);
14889 is_anonymous =
true;
14893 s = scope->get_num_anonymous_member_unions();
14895 s = rdr.global_scope()->get_num_anonymous_member_classes();
14896 name = build_internal_anonymous_die_name(name, s);
14906 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14915 rdr.associate_die_to_type(die, result, where_offset);
14927 if (union_decl_sptr pre_existing_union =
14929 union_type = pre_existing_union;
14932 die_size_in_bits(die, size);
14933 bool is_artificial = die_is_artificial(die);
14937 result = union_type;
14938 result->set_location(loc);
14942 result.reset(
new union_decl(rdr.env(), name, size, loc,
14943 decl_base::VISIBILITY_DEFAULT,
14945 if (is_declaration_only)
14946 result->set_is_declaration_only(
true);
14953 result->set_size_in_bits(size);
14954 result->set_is_declaration_only(
false);
14957 result->set_is_artificial(is_artificial);
14959 rdr.associate_die_to_type(die, result, where_offset);
14962 bool has_child = (dwarf_child(die, &child) == 0);
14966 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
14969 dynamic_pointer_cast<scope_decl>(result);
14971 rdr.scope_stack().push(scop.get());
14977 tag = dwarf_tag(&child);
14979 if (tag == DW_TAG_member || tag == DW_TAG_variable)
14981 Dwarf_Die type_die;
14982 if (!die_die_attribute(&child, DW_AT_type, type_die))
14987 die_loc_and_name(rdr, &child, loc, n, m);
14996 ssize_t offset_in_bits = 0;
14997 decl_base_sptr ty =
14998 is_decl(build_ir_node_from_die(rdr, &type_die,
14999 called_from_public_decl,
15001 type_base_sptr t =
is_type(ty);
15008 result->set_is_declaration_only(
false);
15011 die_access_specifier(&child, access);
15017 if (n.empty() && result->find_data_member(dm))
15023 result->add_data_member(dm, access,
true,
15027 rdr.associate_die_to_decl(&child, dm, where_offset,
15031 else if (tag == DW_TAG_subprogram)
15034 is_decl(build_ir_node_from_die(rdr, &child,
15036 called_from_public_decl,
15044 finish_member_function_reading(&child, f, result, rdr);
15046 rdr.associate_die_to_decl(&child, f, where_offset,
15050 else if (die_is_type(&child))
15052 string type_name = die_type_name(rdr, &child,
15055 if (type_base_sptr member_t = result->find_member_type(type_name))
15056 rdr.associate_die_to_decl(&child,
is_decl(member_t),
15060 decl_base_sptr td =
15061 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
15062 called_from_public_decl,
15065 }
while (dwarf_siblingof(&child, &child) == 0);
15068 rdr.scope_stack().pop();
15071 die_class_or_union_map_type::const_iterator i =
15072 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
15073 if (i != rdr.die_wip_classes_map(source).end())
15078 rdr.die_wip_classes_map(source).erase(i);
15102static type_base_sptr
15103build_qualified_type(reader& rdr,
15105 bool called_from_public_decl,
15106 size_t where_offset)
15108 type_base_sptr result;
15112 unsigned tag = dwarf_tag(die);
15114 if (tag != DW_TAG_const_type
15115 && tag != DW_TAG_volatile_type
15116 && tag != DW_TAG_restrict_type)
15119 Dwarf_Die underlying_type_die;
15120 decl_base_sptr utype_decl;
15121 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15125 utype_decl = build_ir_node_for_void_type(rdr);
15128 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
15129 called_from_public_decl,
15136 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15139 rdr.associate_die_to_type(die, result, where_offset);
15143 type_base_sptr utype =
is_type(utype_decl);
15147 if (tag == DW_TAG_const_type)
15148 qual |= qualified_type_def::CV_CONST;
15149 else if (tag == DW_TAG_volatile_type)
15150 qual |= qualified_type_def::CV_VOLATILE;
15151 else if (tag == DW_TAG_restrict_type)
15152 qual |= qualified_type_def::CV_RESTRICT;
15157 result.reset(
new qualified_type_def(utype, qual, location()));
15159 rdr.associate_die_to_type(die, result, where_offset);
15177schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
15182 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
15184 rdr.schedule_type_for_late_canonicalization(t);
15188 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
15190 rdr.schedule_type_for_late_canonicalization(t);
15194 for (vector<array_type_def::subrange_sptr>::const_iterator i =
15195 type->get_subranges().begin();
15196 i != type->get_subranges().end();
15199 if (!(*i)->get_scope())
15201 rdr.schedule_type_for_late_canonicalization(*i);
15204 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
15206 rdr.schedule_type_for_late_canonicalization(type);
15225static decl_base_sptr
15226maybe_strip_qualification(
const qualified_type_def_sptr t,
15232 decl_base_sptr result = t;
15233 type_base_sptr u = t->get_underlying_type();
15237 if (result.get() != t.get())
15243 scope_decl * scope = 0;
15246 scope = array->get_scope();
15249 schedule_array_tree_for_late_canonicalization(array, rdr);
15251 t->set_underlying_type(array);
15252 u = t->get_underlying_type();
15260 schedule_array_tree_for_late_canonicalization(typdef, rdr);
15263 t->set_underlying_type(typdef);
15264 u = t->get_underlying_type();
15273 type_base_sptr element_type = array->get_element_type();
15278 ABG_ASSERT(!qualified->get_canonical_type());
15280 quals |= t->get_cv_quals();
15281 qualified->set_cv_quals(quals);
15287 qualified_type_def_sptr qual_type
15288 (
new qualified_type_def(element_type,
15290 t->get_location()));
15293 array->set_element_type(qual_type);
15294 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
15319build_pointer_type_def(reader& rdr,
15321 bool called_from_public_decl,
15322 size_t where_offset)
15329 unsigned tag = dwarf_tag(die);
15330 if (tag != DW_TAG_pointer_type)
15334 Dwarf_Die underlying_type_die;
15335 bool has_underlying_type_die =
false;
15336 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15339 utype_decl = build_ir_node_for_void_type(rdr);
15341 has_underlying_type_die =
true;
15343 if (!utype_decl && has_underlying_type_die)
15344 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
15345 called_from_public_decl,
15352 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15359 type_base_sptr utype =
is_type(utype_decl);
15365 uint64_t size = rdr.cur_transl_unit()->get_address_size();
15366 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
15373 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
15375 result.reset(
new pointer_type_def(utype, size, 0, location()));
15381 rdr.associate_die_to_type(die, result, where_offset);
15403build_reference_type(reader& rdr,
15405 bool called_from_public_decl,
15406 size_t where_offset)
15413 unsigned tag = dwarf_tag(die);
15414 if (tag != DW_TAG_reference_type
15415 && tag != DW_TAG_rvalue_reference_type)
15418 Dwarf_Die underlying_type_die;
15419 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
15423 build_ir_node_from_die(rdr, &underlying_type_die,
15424 called_from_public_decl,
15431 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15438 type_base_sptr utype =
is_type(utype_decl);
15444 uint64_t size = rdr.cur_transl_unit()->get_address_size();
15445 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
15450 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
15452 bool is_lvalue = tag == DW_TAG_reference_type;
15454 result.reset(
new reference_type_def(utype, is_lvalue, size,
15457 if (corpus_sptr corp = rdr.corpus())
15460 rdr.associate_die_to_type(die, result, where_offset);
15483build_ptr_to_mbr_type(reader& rdr,
15485 bool called_from_public_decl,
15486 size_t where_offset)
15493 unsigned tag = dwarf_tag(die);
15494 if (tag != DW_TAG_ptr_to_member_type)
15497 Dwarf_Die data_member_type_die, containing_type_die;
15499 if (!die_die_attribute(die, DW_AT_type, data_member_type_die)
15500 || !die_die_attribute(die, DW_AT_containing_type, containing_type_die))
15504 build_ir_node_from_die(rdr, &data_member_type_die,
15505 called_from_public_decl, where_offset);
15506 if (!data_member_type)
15510 build_ir_node_from_die(rdr, &containing_type_die,
15511 called_from_public_decl, where_offset);
15512 if (!containing_type)
15519 if (type_base_sptr t = rdr.lookup_type_from_die(die))
15526 uint64_t size_in_bits = rdr.cur_transl_unit()->get_address_size();
15528 result.reset(
new ptr_to_mbr_type(data_member_type->get_environment(),
15535 rdr.associate_die_to_type(die, result, where_offset);
15556build_function_type(reader& rdr,
15558 class_or_union_sptr is_method,
15559 size_t where_offset)
15566 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
15567 || dwarf_tag(die) == DW_TAG_subprogram);
15569 const die_source source = rdr.get_die_source(die);
15572 size_t off = dwarf_dieoffset(die);
15573 auto i = rdr.die_wip_function_types_map(source).find(off);
15574 if (i != rdr.die_wip_function_types_map(source).end())
15582 decl_base_sptr type_decl;
15590 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
15594 rdr.associate_die_to_type(die, result, where_offset);
15611 rdr.associate_die_to_type(die, fn_type, where_offset);
15619 bool is_const =
false;
15620 bool is_static =
false;
15621 Dwarf_Die object_pointer_die;
15622 Dwarf_Die class_type_die;
15623 bool has_this_parm_die =
15624 die_function_type_is_method_type(rdr, die, where_offset,
15625 object_pointer_die,
15628 if (has_this_parm_die)
15633 if (die_object_pointer_is_for_const_method(&object_pointer_die))
15641 class_or_union_sptr klass_type =
15652 is_method = klass_type;
15661 result.reset(is_method
15662 ?
new method_type(is_method, is_const,
15663 tu->get_address_size(),
15665 :
new function_type(rdr.env(), tu->get_address_size(),
15667 rdr.associate_die_to_type(die, result, where_offset);
15668 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
15670 type_base_sptr return_type;
15671 Dwarf_Die ret_type_die;
15672 if (die_die_attribute(die, DW_AT_type, ret_type_die))
15674 is_type(build_ir_node_from_die(rdr, &ret_type_die,
15678 return_type =
is_type(build_ir_node_for_void_type(rdr));
15679 result->set_return_type(return_type);
15684 if (dwarf_child(die, &child) == 0)
15687 int child_tag = dwarf_tag(&child);
15688 if (child_tag == DW_TAG_formal_parameter)
15691 string name, linkage_name;
15693 die_loc_and_name(rdr, &child, loc, name, linkage_name);
15698 bool is_artificial = die_is_artificial(&child);
15699 type_base_sptr parm_type;
15700 Dwarf_Die parm_type_die;
15701 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
15703 is_type(build_ir_node_from_die(rdr, &parm_type_die,
15710 && function_parms.empty())
15726 (
new function_decl::parameter(parm_type, name, loc,
15729 function_parms.push_back(p);
15731 else if (child_tag == DW_TAG_unspecified_parameters)
15734 bool is_artificial = die_is_artificial(&child);
15736 type_base_sptr parm_type =
15737 is_type(build_ir_node_for_variadic_parameter_type(rdr));
15739 (
new function_decl::parameter(parm_type,
15744 function_parms.push_back(p);
15754 while (dwarf_siblingof(&child, &child) == 0);
15756 result->set_parameters(function_parms);
15758 tu->bind_function_type_life_time(result);
15760 result->set_is_artificial(
true);
15762 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
15765 die_function_type_map_type::const_iterator i =
15766 rdr.die_wip_function_types_map(source).
15767 find(dwarf_dieoffset(die));
15768 if (i != rdr.die_wip_function_types_map(source).end())
15769 rdr.die_wip_function_types_map(source).erase(i);
15772 maybe_canonicalize_type(result, rdr);
15799build_subrange_type(reader& rdr,
15800 const Dwarf_Die* die,
15801 size_t where_offset,
15802 bool associate_type_to_die)
15809 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
15810 if (tag != DW_TAG_subrange_type)
15813 string name = die_name(die);
15816 Dwarf_Die underlying_type_die;
15817 type_base_sptr underlying_type;
15819 bool is_signed =
false;
15820 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
15822 is_type(build_ir_node_from_die(rdr,
15823 &underlying_type_die,
15827 if (underlying_type)
15830 if (die_unsigned_constant_attribute (&underlying_type_die,
15833 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
15839 bool has_size_info =
false;
15841 if ((has_size_info = die_unsigned_constant_attribute(die,
15842 DW_AT_byte_size, size)))
15845 has_size_info = die_unsigned_constant_attribute(die,
15846 DW_AT_bit_size, size);
15849 array_type_def::subrange_type::bound_value lower_bound =
15850 get_default_array_lower_bound(language);
15851 array_type_def::subrange_type::bound_value upper_bound;
15852 uint64_t count = 0;
15853 bool is_non_finite =
false;
15854 bool non_zero_count_present =
false;
15865 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
15867 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
15868 is_signed, upper_bound);
15869 if (!found_upper_bound)
15870 found_upper_bound = subrange_die_indirect_bound_value(die,
15875 if (!found_upper_bound)
15888 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
15896 non_zero_count_present =
true;
15901 int64_t u = lower_bound.get_signed_value() + count;
15903 upper_bound = u - 1;
15906 if (!non_zero_count_present)
15910 is_non_finite =
true;
15913 if (UINT64_MAX == upper_bound.get_unsigned_value())
15916 is_non_finite =
true;
15919 (
new array_type_def::subrange_type(rdr.env(),
15925 result->is_non_finite(is_non_finite);
15928 result->set_size_in_bits(size);
15935 if (!underlying_type)
15936 result->set_size_in_bits(rdr.cur_transl_unit()->get_address_size());
15941 || (result->get_length() ==
15942 (uint64_t) (result->get_upper_bound()
15943 - result->get_lower_bound() + 1)));
15945 if (associate_type_to_die)
15946 rdr.associate_die_to_type(die, result, where_offset);
15968build_subranges_from_array_type_die(
const reader& rdr,
15969 const Dwarf_Die* die,
15971 size_t where_offset,
15972 bool associate_type_to_die)
15976 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
15980 int child_tag = dwarf_tag(&child);
15981 if (child_tag == DW_TAG_subrange_type)
15984 if (associate_type_to_die)
15990 build_ir_node_from_die(
const_cast<reader&
>(rdr), &child,
15999 s = build_subrange_type(
const_cast<reader&
>(rdr), &child,
16003 subranges.push_back(s);
16006 while (dwarf_siblingof(&child, &child) == 0);
16027build_array_type(reader& rdr,
16029 bool called_from_public_decl,
16030 size_t where_offset)
16037 unsigned tag = dwarf_tag(die);
16038 if (tag != DW_TAG_array_type)
16041 decl_base_sptr type_decl;
16042 Dwarf_Die type_die;
16044 if (die_die_attribute(die, DW_AT_type, type_die))
16045 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
16046 called_from_public_decl,
16053 if (type_base_sptr t = rdr.lookup_type_from_die(die))
16060 type_base_sptr type =
is_type(type_decl);
16065 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
16067 result.reset(
new array_type_def(type, subranges, location()));
16068 rdr.associate_die_to_type(die, result, where_offset);
16089build_typedef_type(reader& rdr,
16091 bool called_from_public_decl,
16092 size_t where_offset)
16099 unsigned tag = dwarf_tag(die);
16100 if (tag != DW_TAG_typedef)
16103 string name, linkage_name;
16105 die_loc_and_name(rdr, die, loc, name, linkage_name);
16107 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
16113 type_base_sptr utype;
16114 Dwarf_Die underlying_type_die;
16115 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
16118 utype = rdr.env().get_void_type();
16122 is_type(build_ir_node_from_die(rdr,
16123 &underlying_type_die,
16124 called_from_public_decl,
16130 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
16137 decl_base_sptr decl =
is_decl(utype);
16139 decl->set_naming_typedef(result);
16140 rdr.maybe_schedule_decl_only_type_for_resolution(utype);
16144 rdr.associate_die_to_type(die, result, where_offset);
16181build_or_get_var_decl_if_not_suppressed(reader& rdr,
16184 size_t where_offset,
16185 bool is_declaration_only,
16187 bool is_required_decl_spec)
16190 if (variable_is_suppressed(rdr, scope, die,
16191 is_declaration_only,
16192 is_required_decl_spec))
16194 ++rdr.stats_.number_of_suppressed_variables;
16200 string var_name = die_name(die);
16201 if (!var_name.empty())
16202 if ((var = class_type->find_data_member(var_name)))
16207 ++rdr.stats_.number_of_suppressed_variables;
16209 var = build_var_decl(rdr, die, where_offset, result);
16232build_var_decl(reader& rdr,
16234 size_t where_offset,
16240 int tag = dwarf_tag(die);
16241 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
16243 if (!die_is_public_decl(die))
16246 type_base_sptr type;
16247 Dwarf_Die type_die;
16248 if (die_die_attribute(die, DW_AT_type, type_die))
16250 decl_base_sptr ty =
16251 is_decl(build_ir_node_from_die(rdr, &type_die,
16260 if (!type && !result)
16263 string name, linkage_name;
16265 die_loc_and_name(rdr, die, loc, name, linkage_name);
16268 result.reset(
new var_decl(name, type, loc, linkage_name));
16274 if (!linkage_name.empty())
16275 result->set_linkage_name(linkage_name);
16278 result->set_type(type);
16284 if (!result->get_symbol())
16287 Dwarf_Addr var_addr;
16289 if (rdr.get_variable_address(die, var_addr))
16292 update_main_symbol(var_addr,
16293 result->get_linkage_name().empty()
16294 ? result->get_name()
16295 : result->get_linkage_name());
16296 var_sym = rdr.variable_symbol_is_exported(var_addr);
16301 result->set_symbol(var_sym);
16304 string linkage_name = result->get_linkage_name();
16305 if (linkage_name.empty()
16306 || !var_sym->get_alias_from_name(linkage_name))
16307 result->set_linkage_name(var_sym->get_name());
16308 result->set_is_in_public_symbol_table(
true);
16311 if (!var_sym && rdr.is_decl_die_with_undefined_symbol(die))
16315 string n = result->get_linkage_name();
16317 n = result->get_name();
16318 var_sym = rdr.symtab()->lookup_undefined_variable_symbol(n);
16321 result->set_symbol(var_sym);
16322 result->set_is_in_public_symbol_table(
false);
16349function_is_suppressed(
const reader& rdr,
16350 const scope_decl* scope,
16351 Dwarf_Die *function_die,
16352 bool is_declaration_only)
16354 if (function_die == 0
16355 || dwarf_tag(function_die) != DW_TAG_subprogram)
16358 string fname = die_string_attribute(function_die, DW_AT_name);
16359 string flinkage_name = die_linkage_name(function_die);
16360 if (flinkage_name.empty() && die_is_in_c(function_die))
16361 flinkage_name = fname;
16371 && (!is_declaration_only || rdr.drop_undefined_syms()))
16373 Dwarf_Addr fn_addr;
16374 if (!rdr.get_function_address(function_die, fn_addr))
16378 rdr.function_symbol_is_exported(fn_addr);
16381 if (symbol->is_suppressed())
16388 if (symbol->has_aliases())
16390 !a->is_main_symbol(); a = a->get_next_alias())
16391 if (a->is_suppressed())
16440build_or_get_fn_decl_if_not_suppressed(reader& rdr,
16443 size_t where_offset,
16444 bool is_declaration_only,
16448 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
16450 ++rdr.stats_.number_of_suppressed_functions;
16454 string name = die_name(fn_die);
16455 string linkage_name = die_linkage_name(fn_die);
16456 bool is_dtor = !name.empty() && name[0]==
'~';
16457 bool is_virtual =
false;
16460 Dwarf_Attribute attr;
16461 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
16462 DW_AT_vtable_elem_location,
16474 if (!result && (!(is_dtor && is_virtual)))
16478 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
16479 rdr.associate_die_to_decl(fn_die, fn,
true);
16480 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
16486 ++rdr.stats_.number_of_allowed_functions;
16492 string linkage_name = die_linkage_name(fn_die);
16493 fn = klass->find_member_function_sptr(linkage_name);
16500 if (!fn || !fn->get_symbol())
16507 fn = build_function_decl(rdr, fn_die, where_offset, result);
16532variable_is_suppressed(
const reader& rdr,
16533 const scope_decl* scope,
16534 Dwarf_Die *variable_die,
16535 bool is_declaration_only,
16536 bool is_required_decl_spec)
16538 if (variable_die == 0
16539 || (dwarf_tag(variable_die) != DW_TAG_variable
16540 && dwarf_tag(variable_die) != DW_TAG_member))
16543 string name = die_string_attribute(variable_die, DW_AT_name);
16544 string linkage_name = die_linkage_name(variable_die);
16545 if (linkage_name.empty() && die_is_in_c(variable_die))
16546 linkage_name = name;
16555 && !is_required_decl_spec
16559 && (!is_declaration_only || !rdr.load_undefined_interfaces()))
16561 Dwarf_Addr var_addr = 0;
16562 if (!rdr.get_variable_address(variable_die, var_addr))
16566 rdr.variable_symbol_is_exported(var_addr);
16569 if (symbol->is_suppressed())
16576 if (symbol->has_aliases())
16578 !a->is_main_symbol(); a = a->get_next_alias())
16579 if (a->is_suppressed())
16608type_is_suppressed(
const reader& rdr,
16609 const scope_decl* scope,
16610 Dwarf_Die *type_die,
16611 bool &type_is_opaque)
16614 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
16615 && dwarf_tag(type_die) != DW_TAG_class_type
16616 && dwarf_tag(type_die) != DW_TAG_structure_type
16617 && dwarf_tag(type_die) != DW_TAG_union_type))
16620 string type_name, linkage_name;
16621 location type_location;
16622 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
16646type_is_suppressed(
const reader& rdr,
16647 const scope_decl* scope,
16648 Dwarf_Die *type_die)
16650 bool type_is_opaque =
false;
16651 return type_is_suppressed(rdr, scope, type_die, type_is_opaque);
16675get_opaque_version_of_type(reader &rdr,
16677 Dwarf_Die *type_die,
16678 size_t where_offset)
16685 unsigned tag = dwarf_tag(type_die);
16686 if (tag != DW_TAG_class_type
16687 && tag != DW_TAG_structure_type
16688 && tag != DW_TAG_union_type
16689 && tag != DW_TAG_enumeration_type)
16692 string type_name, linkage_name;
16693 location type_location;
16694 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
16703 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
16705 string_classes_or_unions_map::const_iterator i =
16706 rdr.declaration_only_classes().find(qualified_name);
16707 if (i != rdr.declaration_only_classes().end())
16708 result = i->second.back();
16719 tag == DW_TAG_structure_type,
16721 decl_base::VISIBILITY_DEFAULT));
16722 klass->set_is_declaration_only(
true);
16723 klass->set_is_artificial(die_is_artificial(type_die));
16725 rdr.associate_die_to_type(type_die, klass, where_offset);
16726 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
16731 if (tag == DW_TAG_enumeration_type)
16733 string_enums_map::const_iterator i =
16734 rdr.declaration_only_enums().find(qualified_name);
16735 if (i != rdr.declaration_only_enums().end())
16736 result = i->second.back();
16741 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
16744 build_enum_underlying_type(rdr, type_name, size,
16752 enum_type->set_is_artificial(die_is_artificial(type_die));
16754 result = enum_type;
16777 elf_symbol::FUNC_TYPE,
16778 elf_symbol::GLOBAL_BINDING,
16782 elf_symbol::DEFAULT_VISIBILITY);
16800build_function_decl(reader& rdr,
16802 size_t where_offset,
16808 int tag = dwarf_tag(die);
16809 ABG_ASSERT(tag == DW_TAG_subprogram || tag == DW_TAG_inlined_subroutine);
16811 if (!die_is_public_decl(die))
16817 string fname, flinkage_name;
16819 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
16820 cleanup_decl_name(fname);
16822 size_t is_inline = die_is_declared_inline(die);
16823 class_or_union_sptr is_method =
16836 if (!flinkage_name.empty()
16837 && result->get_linkage_name() != flinkage_name)
16838 result->set_linkage_name(flinkage_name);
16840 if (!result->get_location())
16841 result->set_location(floc);
16842 result->is_declared_inline(is_inline);
16851 maybe_canonicalize_type(fn_type, rdr);
16853 result.reset(is_method
16854 ?
new method_decl(fname, fn_type,
16857 :
new function_decl(fname, fn_type,
16864 if (!result->get_symbol())
16867 Dwarf_Addr fn_addr;
16868 if (rdr.get_function_address(die, fn_addr))
16871 update_main_symbol(fn_addr,
16872 result->get_linkage_name().empty()
16873 ? result->get_name()
16874 : result->get_linkage_name());
16875 fn_sym = rdr.function_symbol_is_exported(fn_addr);
16878 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
16880 result->set_symbol(fn_sym);
16881 string linkage_name = result->get_linkage_name();
16882 if (linkage_name.empty())
16883 result->set_linkage_name(fn_sym->get_name());
16884 result->set_is_in_public_symbol_table(
true);
16887 if (!fn_sym && rdr.is_decl_die_with_undefined_symbol(die))
16891 string n = result->get_linkage_name();
16893 n = result->get_name();
16894 fn_sym = rdr.symtab()->lookup_undefined_function_symbol(n);
16897 result->set_symbol(fn_sym);
16898 result->set_is_in_public_symbol_table(
false);
16903 rdr.associate_die_to_type(die, result->get_type(), where_offset);
16905 size_t die_offset = dwarf_dieoffset(die);
16910 && !result->get_linkage_name().empty())
16916 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
16935maybe_canonicalize_type(
const type_base_sptr& t,
16941 rdr.schedule_type_for_late_canonicalization(t);
16950maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
16953 if (
is_type(member_type_declaration)
16956 class_or_union* scope =
16962 if (!cl->is_struct())
16963 access = private_access;
16965 die_access_specifier(die, access);
16978cleanup_decl_name(
string& str)
16999 const Dwarf_Die *fn_die)
17001 if (!fn || fn->get_scope())
17005 !die_is_virtual(fn_die)
17007 && !fn->get_symbol())
17052build_ir_node_from_die(reader& rdr,
17055 bool called_from_public_decl,
17056 size_t where_offset,
17057 bool is_declaration_only,
17058 bool is_required_decl_spec)
17062 if (!die || !scope)
17065 int tag = dwarf_tag(die);
17067 if (!called_from_public_decl)
17069 if (rdr.load_all_types() && die_is_type(die))
17073 else if (tag != DW_TAG_subprogram
17074 && tag != DW_TAG_variable
17075 && tag != DW_TAG_member
17076 && tag != DW_TAG_namespace)
17080 const die_source source_of_die = rdr.get_die_source(die);
17082 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
17085 if (rdr.load_all_types())
17086 if (called_from_public_decl)
17087 if (type_base_sptr t =
is_type(result))
17088 if (corpus *abi_corpus = rdr.corpus().get())
17089 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
17098 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
17103 case DW_TAG_base_type:
17108 maybe_canonicalize_type(t, rdr);
17112 case DW_TAG_typedef:
17115 called_from_public_decl,
17121 maybe_set_member_type_access_specifier(
is_decl(result), die);
17122 maybe_canonicalize_type(t, rdr);
17127 case DW_TAG_pointer_type:
17130 build_pointer_type_def(rdr, die,
17131 called_from_public_decl,
17138 maybe_canonicalize_type(p, rdr);
17143 case DW_TAG_reference_type:
17144 case DW_TAG_rvalue_reference_type:
17147 build_reference_type(rdr, die,
17148 called_from_public_decl,
17154 maybe_canonicalize_type(r, rdr);
17159 case DW_TAG_ptr_to_member_type:
17162 build_ptr_to_mbr_type(rdr, die, called_from_public_decl,
17168 rdr.cur_transl_unit()->get_global_scope());
17169 maybe_canonicalize_type(p, rdr);
17174 case DW_TAG_const_type:
17175 case DW_TAG_volatile_type:
17176 case DW_TAG_restrict_type:
17179 build_qualified_type(rdr, die,
17180 called_from_public_decl,
17191 type_base_sptr ty =
is_type(d);
17195 rdr.associate_die_to_type(die, ty, where_offset);
17198 maybe_canonicalize_type(
is_type(result), rdr);
17203 case DW_TAG_enumeration_type:
17205 bool type_is_opaque =
false;
17206 bool type_suppressed =
17207 type_is_suppressed(rdr, scope, die, type_is_opaque);
17208 if (type_suppressed && type_is_opaque)
17216 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
17217 maybe_canonicalize_type(
is_type(result), rdr);
17219 else if (!type_suppressed)
17223 is_declaration_only);
17227 maybe_set_member_type_access_specifier(
is_decl(result), die);
17228 maybe_canonicalize_type(
is_type(result), rdr);
17234 case DW_TAG_class_type:
17235 case DW_TAG_structure_type:
17237 bool type_is_opaque =
false;
17238 bool type_suppressed=
17239 type_is_suppressed(rdr, scope, die, type_is_opaque);
17241 if (type_suppressed && type_is_opaque)
17249 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
17250 maybe_canonicalize_type(
is_type(result), rdr);
17252 else if (!type_suppressed)
17255 Dwarf_Die spec_die;
17256 if (die_die_attribute(die, DW_AT_specification, spec_die))
17259 get_scope_for_die(rdr, &spec_die,
17260 called_from_public_decl,
17263 decl_base_sptr cl =
17264 is_decl(build_ir_node_from_die(rdr, &spec_die,
17266 called_from_public_decl,
17268 is_declaration_only,
17271 klass = dynamic_pointer_cast<class_decl>(cl);
17275 add_or_update_class_type(rdr, die,
17277 tag == DW_TAG_structure_type,
17279 called_from_public_decl,
17281 is_declaration_only);
17287 string type_name = die_type_name(rdr, die,
17295 add_or_update_class_type(rdr, die, scope,
17296 tag == DW_TAG_structure_type,
17298 called_from_public_decl,
17300 is_declaration_only);
17304 add_or_update_class_type(rdr, die, scope,
17305 tag == DW_TAG_structure_type,
17307 called_from_public_decl,
17309 is_declaration_only);
17313 maybe_set_member_type_access_specifier(klass, die);
17314 maybe_canonicalize_type(klass, rdr);
17320 case DW_TAG_union_type:
17321 if (!type_is_suppressed(rdr, scope, die))
17323 union_decl_sptr union_type;
17326 string type_name = die_type_name(rdr, die,
17329 if (union_decl_sptr u =
17336 add_or_update_union_type(rdr, die, scope,
17338 called_from_public_decl,
17340 is_declaration_only);
17344 maybe_set_member_type_access_specifier(union_type, die);
17345 maybe_canonicalize_type(union_type, rdr);
17346 result = union_type;
17350 case DW_TAG_string_type:
17352 case DW_TAG_subroutine_type:
17360 result->set_is_artificial(
false);
17361 maybe_canonicalize_type(f, rdr);
17365 case DW_TAG_array_type:
17369 called_from_public_decl,
17375 maybe_canonicalize_type(a, rdr);
17379 case DW_TAG_subrange_type:
17385 build_subrange_type(rdr, die, where_offset,
17391 maybe_canonicalize_type(s, rdr);
17395 case DW_TAG_packed_type:
17397 case DW_TAG_set_type:
17399 case DW_TAG_file_type:
17401 case DW_TAG_thrown_type:
17403 case DW_TAG_interface_type:
17405 case DW_TAG_unspecified_type:
17407 case DW_TAG_shared_type:
17410 case DW_TAG_compile_unit:
17415 case DW_TAG_namespace:
17416 case DW_TAG_module:
17417 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
17420 case DW_TAG_variable:
17421 case DW_TAG_member:
17423 if (tag == DW_TAG_member)
17427 get_scope_for_die(rdr, die,
17429 die_is_effectively_public_decl(rdr, die),
17432 build_or_get_var_decl_if_not_suppressed(rdr, var_scope.get(), die,
17434 is_declaration_only,
17436 is_required_decl_spec);
17444 v = build_var_decl(rdr, die, where_offset, v);
17457 rdr.var_decls_to_re_add_to_tree().push_back(v);
17458 rdr.add_var_to_exported_or_undefined_decls(v);
17459 rdr.associate_die_to_decl(die, v, where_offset,
17466 case DW_TAG_subprogram:
17467 case DW_TAG_inlined_subroutine:
17469 if (die_is_artificial(die))
17472 Dwarf_Die abstract_origin_die;
17473 bool has_abstract_origin = die_die_attribute(die, DW_AT_abstract_origin,
17474 abstract_origin_die,
17478 scope_decl_sptr s = get_scope_for_die(rdr, die, called_from_public_decl,
17480 scope_decl* interface_scope = scope ? scope : s.get();
17483 string linkage_name = die_linkage_name(die);
17484 string spec_linkage_name;
17491 if (!linkage_name.empty())
17494 class_scope->find_member_function_sptr(linkage_name)))
17499 spec_linkage_name = existing_fn->get_linkage_name();
17500 if (has_abstract_origin
17501 && !spec_linkage_name.empty()
17502 && linkage_name != spec_linkage_name)
17509 existing_fn = existing_fn->clone();
17514 else if (has_abstract_origin)
17518 existing_fn = build_function_decl(rdr, &abstract_origin_die, where_offset,
17521 rdr.scope_stack().push(interface_scope);
17528 build_or_get_fn_decl_if_not_suppressed(rdr, interface_scope,
17530 is_declaration_only,
17533 if (result && !existing_fn)
17539 && !is_required_decl_spec)
17556 sptr_utils::noop_deleter());
17558 finish_member_function_reading(die, fn, klass, rdr);
17569 rdr.add_fn_to_exported_or_undefined_decls(fn.get());
17570 rdr.associate_die_to_decl(die, fn, where_offset,
17572 maybe_canonicalize_type(fn->get_type(), rdr);
17575 rdr.scope_stack().pop();
17579 case DW_TAG_formal_parameter:
17584 case DW_TAG_constant:
17586 case DW_TAG_enumerator:
17589 case DW_TAG_partial_unit:
17590 case DW_TAG_imported_unit:
17597 case DW_TAG_dwarf_procedure:
17598 case DW_TAG_imported_declaration:
17599 case DW_TAG_entry_point:
17601 case DW_TAG_lexical_block:
17602 case DW_TAG_unspecified_parameters:
17603 case DW_TAG_variant:
17604 case DW_TAG_common_block:
17605 case DW_TAG_common_inclusion:
17606 case DW_TAG_inheritance:
17607 case DW_TAG_with_stmt:
17608 case DW_TAG_access_declaration:
17609 case DW_TAG_catch_block:
17610 case DW_TAG_friend:
17611 case DW_TAG_namelist:
17612 case DW_TAG_namelist_item:
17613 case DW_TAG_template_type_parameter:
17614 case DW_TAG_template_value_parameter:
17615 case DW_TAG_try_block:
17616 case DW_TAG_variant_part:
17617 case DW_TAG_imported_module:
17618 case DW_TAG_condition:
17619 case DW_TAG_type_unit:
17620 case DW_TAG_template_alias:
17621 case DW_TAG_lo_user:
17622 case DW_TAG_MIPS_loop:
17623 case DW_TAG_format_label:
17624 case DW_TAG_function_template:
17625 case DW_TAG_class_template:
17626 case DW_TAG_GNU_BINCL:
17627 case DW_TAG_GNU_EINCL:
17628 case DW_TAG_GNU_template_template_param:
17629 case DW_TAG_GNU_template_parameter_pack:
17630 case DW_TAG_GNU_formal_parameter_pack:
17631 case DW_TAG_GNU_call_site:
17632 case DW_TAG_GNU_call_site_parameter:
17633 case DW_TAG_hi_user:
17638 if (result && tag != DW_TAG_subroutine_type)
17639 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
17643 if (rdr.load_all_types())
17644 if (called_from_public_decl)
17645 if (type_base_sptr t =
is_type(result))
17646 if (corpus *abi_corpus = scope->get_corpus())
17647 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
17649 rdr.maybe_schedule_decl_only_type_for_resolution(result);
17659static decl_base_sptr
17660build_ir_node_for_void_type(reader& rdr)
17662 const environment& env = rdr.env();
17664 type_base_sptr t = env.get_void_type();
17669 rdr.schedule_type_for_late_canonicalization(t);
17671 return type_declaration;
17686build_ir_node_for_void_pointer_type(reader& rdr)
17688 const environment& env = rdr.env();
17689 type_base_sptr t = env.get_void_pointer_type();
17694 rdr.schedule_type_for_late_canonicalization(t);
17696 return type_declaration;
17704static decl_base_sptr
17705build_ir_node_for_variadic_parameter_type(reader &rdr)
17708 const environment& env = rdr.env();
17709 type_base_sptr t = env.get_variadic_parameter_type();
17714 rdr.schedule_type_for_late_canonicalization(t);
17716 return type_declaration;
17742build_ir_node_from_die(reader& rdr,
17744 bool called_from_public_decl,
17745 size_t where_offset)
17748 return decl_base_sptr();
17758 bool consider_as_called_from_public_decl =
17759 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
17761 consider_as_called_from_public_decl,
17764 scope = rdr.global_scope();
17766 return build_ir_node_from_die(rdr, die, scope.get(),
17767 called_from_public_decl,
17768 where_offset,
true);
17802elf_based_reader_sptr
17804 const vector<char**>& debug_info_root_paths,
17806 bool load_all_types,
17807 bool linux_kernel_mode)
17810 reader_sptr r = reader::create(elf_path,
17811 debug_info_root_paths,
17814 linux_kernel_mode);
17815 return static_pointer_cast<elf_based_reader>(r);
17854 const std::string& elf_path,
17855 const vector<char**>&debug_info_root_path,
17856 bool read_all_types,
17857 bool linux_kernel_mode)
17859 reader& r =
dynamic_cast<reader&
>(rdr);
17860 r.initialize(elf_path, debug_info_root_path,
17861 read_all_types, linux_kernel_mode);
17898 const vector<char**>& debug_info_root_paths,
17900 bool load_all_types,
17903 elf_based_reader_sptr rdr =
17904 dwarf::reader::create(elf_path, debug_info_root_paths,
17908 return rdr->read_corpus(status);
17929 const string& elf_path,
17930 const string& symbol_name,
17932 vector<elf_symbol_sptr>& syms)
17935 if (elf_version(EV_CURRENT) == EV_NONE)
17938 int fd = open(elf_path.c_str(), O_RDONLY);
17946 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
17974 const string& path,
17975 const string& symname,
17976 vector<elf_symbol_sptr>& syms)
17978 if (elf_version(EV_CURRENT) == EV_NONE)
17981 int fd = open(path.c_str(), O_RDONLY);
17989 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.