14 #include "abg-internal.h"
15 #include <sys/types.h>
22 #include <elfutils/libdwfl.h>
33 #include <unordered_map>
34 #include <unordered_set>
43 ABG_BEGIN_EXPORT_DECLARATIONS
55 #define UINT64_MAX 0xffffffffffffffff
69 using std::dynamic_pointer_cast;
70 using std::static_pointer_cast;
71 using std::unordered_map;
72 using std::unordered_set;
79 using namespace elf_helpers;
86 NO_DEBUG_INFO_DIE_SOURCE,
87 PRIMARY_DEBUG_INFO_DIE_SOURCE,
88 ALT_DEBUG_INFO_DIE_SOURCE,
90 NUMBER_OF_DIE_SOURCES,
138 struct dwarf_offset_pair_hash
141 operator()(
const std::pair<Dwarf_Off, Dwarf_Off>& p)
const
142 {
return abigail::hashing::combine_hashes(p.first, p.second);}
145 typedef unordered_set<std::pair<Dwarf_Off,
147 dwarf_offset_pair_hash> dwarf_offset_pair_set_type;
157 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
161 offset_type(
die_source source, Dwarf_Off offset)
166 offset_type(Dwarf_Off offset)
167 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
172 {
return source_ == o.source_ && offset_ == o.offset_;}
174 operator Dwarf_Off()
const
185 operator()(
const offset_type& p)
const
186 {
return abigail::hashing::combine_hashes(p.source_, p.offset_);}
191 struct offset_pair_hash
194 operator()(
const std::pair<offset_type, offset_type>& p)
const
196 size_t h1 = abigail::hashing::combine_hashes(p.first.source_,
198 size_t h2 = abigail::hashing::combine_hashes(p.second.source_,
200 return abigail::hashing::combine_hashes(h1, h2);
208 typedef unordered_set<std::pair<offset_type,
217 typedef unordered_map<std::pair<offset_type, offset_type>,
223 typedef unordered_map<std::pair<offset_type, offset_type>,
233 build_translation_unit_and_add_to_ir(reader& rdr,
238 maybe_propagate_canonical_type(
const reader& rdr,
243 propagate_canonical_type(
const reader& rdr,
253 typedef unordered_map<interned_string,
285 struct imported_unit_point
287 Dwarf_Off offset_of_import;
291 Dwarf_Off imported_unit_die_off;
292 Dwarf_Off imported_unit_cu_off;
293 Dwarf_Off imported_unit_child_off;
296 imported_unit_point()
297 : offset_of_import(),
298 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
299 imported_unit_die_off(),
300 imported_unit_cu_off(),
301 imported_unit_child_off()
308 imported_unit_point(Dwarf_Off import_off)
309 : offset_of_import(import_off),
310 imported_unit_die_source(PRIMARY_DEBUG_INFO_DIE_SOURCE),
311 imported_unit_die_off(),
312 imported_unit_cu_off(),
313 imported_unit_child_off()
324 imported_unit_point(Dwarf_Off import_off,
325 const Dwarf_Die& imported_die,
327 : offset_of_import(import_off),
328 imported_unit_die_source(from),
329 imported_unit_die_off(dwarf_dieoffset
330 (const_cast<Dwarf_Die*>(&imported_die))),
331 imported_unit_cu_off(),
332 imported_unit_child_off()
334 Dwarf_Die imported_unit_child;
336 ABG_ASSERT(dwarf_child(const_cast<Dwarf_Die*>(&imported_die),
337 &imported_unit_child) == 0);
339 imported_unit_child_off =
340 dwarf_dieoffset(const_cast<Dwarf_Die*>(&imported_unit_child));
342 Dwarf_Die cu_die_memory;
345 cu_die = dwarf_diecu(const_cast<Dwarf_Die*>(&imported_unit_child),
346 &cu_die_memory, 0, 0);
347 imported_unit_cu_off = dwarf_dieoffset(cu_die);
355 typedef unordered_map<Dwarf_Off, imported_unit_points_type>
367 operator<(
const imported_unit_point& l,
const imported_unit_point& r)
368 {
return l.offset_of_import < r.offset_of_import;}
371 get_parent_die(
const reader& rdr,
372 const Dwarf_Die* die,
373 Dwarf_Die& parent_die,
374 size_t where_offset);
377 get_scope_die(
const reader& rdr,
378 const Dwarf_Die* die,
380 Dwarf_Die& scope_die);
383 die_is_anonymous(
const Dwarf_Die* die);
386 die_is_anonymous_data_member(
const Dwarf_Die* die);
389 die_is_type(
const Dwarf_Die* die);
392 die_is_decl(
const Dwarf_Die* die);
395 die_is_declaration_only(Dwarf_Die* die);
398 die_is_variable_decl(
const Dwarf_Die *die);
401 die_is_function_decl(
const Dwarf_Die *die);
404 die_has_size_attribute(
const Dwarf_Die *die);
407 die_has_no_child(
const Dwarf_Die *die);
410 die_is_namespace(
const Dwarf_Die* die);
413 die_is_unspecified(Dwarf_Die* die);
416 die_is_void_type(Dwarf_Die* die);
419 die_is_pointer_type(
const Dwarf_Die* die);
422 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
425 die_is_reference_type(
const Dwarf_Die* die);
428 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
431 die_is_pointer_or_reference_type(
const Dwarf_Die* die);
434 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
437 die_is_class_type(
const Dwarf_Die* die);
440 die_is_qualified_type(
const Dwarf_Die* die);
443 die_is_function_type(
const Dwarf_Die *die);
446 die_has_object_pointer(
const Dwarf_Die* die,
447 Dwarf_Die& object_pointer);
450 die_has_children(
const Dwarf_Die* die);
453 die_this_pointer_from_object_pointer(Dwarf_Die* die,
454 Dwarf_Die& this_pointer);
457 die_this_pointer_is_const(Dwarf_Die* die);
460 die_object_pointer_is_for_const_method(Dwarf_Die* die);
463 is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
466 die_is_at_class_scope(
const reader& rdr,
467 const Dwarf_Die* die,
469 Dwarf_Die& class_scope_die);
471 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
474 bool& is_tls_address);
477 dwarf_language_to_tu_language(
size_t l);
480 die_unsigned_constant_attribute(
const Dwarf_Die* die,
485 die_signed_constant_attribute(
const Dwarf_Die*die,
490 die_constant_attribute(
const Dwarf_Die *die,
493 array_type_def::subrange_type::bound_value &value);
496 die_member_offset(
const reader& rdr,
497 const Dwarf_Die* die,
501 form_is_DW_FORM_strx(
unsigned form);
504 form_is_DW_FORM_line_strp(
unsigned form);
507 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
510 die_name(
const Dwarf_Die* die);
513 die_location(
const reader& rdr,
const Dwarf_Die* die);
516 die_location_address(Dwarf_Die* die,
518 bool& is_tls_address);
521 die_die_attribute(
const Dwarf_Die* die,
524 bool recursively =
true);
527 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
529 array_type_def::subrange_type::bound_value& v,
533 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
535 Dwarf_Die& referenced_subrange);
537 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
540 build_internal_anonymous_die_name(
const string &
base_name,
541 size_t anonymous_type_index);
544 get_internal_anonymous_die_name(Dwarf_Die *die,
545 size_t anonymous_type_index);
548 die_qualified_type_name(
const reader& rdr,
549 const Dwarf_Die* die,
553 die_qualified_decl_name(
const reader& rdr,
554 const Dwarf_Die* die,
558 die_qualified_name(
const reader& rdr,
559 const Dwarf_Die* die,
563 die_qualified_type_name_empty(
const reader& rdr,
564 const Dwarf_Die* die,
size_t where,
565 string &qualified_name);
568 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
569 const Dwarf_Die* die,
572 string &return_type_name,
574 vector<string>& parm_names,
579 die_function_signature(
const reader& rdr,
580 const Dwarf_Die *die,
581 size_t where_offset);
584 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
587 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
590 die_function_type_is_method_type(
const reader& rdr,
591 const Dwarf_Die *die,
593 Dwarf_Die& object_pointer_die,
594 Dwarf_Die& class_die,
598 die_pretty_print_type(reader& rdr,
599 const Dwarf_Die* die,
600 size_t where_offset);
603 die_pretty_print_decl(reader& rdr,
604 const Dwarf_Die* die,
605 size_t where_offset);
608 die_pretty_print(reader& rdr,
609 const Dwarf_Die* die,
610 size_t where_offset);
613 maybe_canonicalize_type(
const type_base_sptr& t,
620 find_lower_bound_in_imported_unit_points(
const imported_unit_points_type&,
622 imported_unit_points_type::const_iterator&);
625 build_subrange_type(reader& rdr,
626 const Dwarf_Die* die,
628 bool associate_type_to_die =
true);
631 build_subranges_from_array_type_die(reader& rdr,
632 const Dwarf_Die* die,
635 bool associate_type_to_die =
true);
638 compare_dies(
const reader& rdr,
639 const Dwarf_Die *l,
const Dwarf_Die *r,
640 bool update_canonical_dies_on_the_fly);
643 compare_dies_during_canonicalization(reader& rdr,
644 const Dwarf_Die *l,
const Dwarf_Die *r,
645 bool update_canonical_dies_on_the_fly);
648 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
662 compare_symbol_name(
const string& symbol_name,
671 return symbol_name == name;
700 lookup_symbol_from_sysv_hash_tab(
const environment& env,
702 const string& sym_name,
704 size_t sym_tab_index,
706 vector<elf_symbol_sptr>& syms_found)
708 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
711 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
714 GElf_Shdr sheader_mem;
715 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
717 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
722 unsigned long hash = elf_hash(sym_name.c_str());
723 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
724 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
725 size_t nb_buckets = ht_data[0];
726 size_t nb_chains = ht_data[1];
734 Elf32_Word* ht_buckets = &ht_data[2];
735 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
738 size_t bucket = hash % nb_buckets;
739 size_t symbol_index = ht_buckets[bucket];
742 const char* sym_name_str;
751 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
752 sym_name_str = elf_strptr(elf_handle,
753 sym_tab_section_header->sh_link,
756 && compare_symbol_name(sym_name_str, sym_name, demangle))
758 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
759 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
761 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
762 sym_size = symbol.st_size;
763 elf_symbol::version ver;
764 if (get_version_for_symbol(elf_handle, symbol_index,
774 symbol.st_shndx != SHN_UNDEF,
775 symbol.st_shndx == SHN_COMMON,
776 ver, sym_visibility);
777 syms_found.push_back(symbol_found);
780 symbol_index = ht_chains[symbol_index];
781 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
792 get_elf_class_size_in_bytes(Elf* elf_handle)
798 int c = hdr.e_ident[EI_CLASS];
832 bloom_word_at(Elf* elf_handle,
833 Elf32_Word* bloom_filter,
836 Elf64_Xword result = 0;
840 c = h.e_ident[EI_CLASS];
845 result = bloom_filter[index];
849 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
870 size_t first_sym_index;
873 Elf32_Word* bloom_filter;
876 Elf_Scn* sym_tab_section;
877 GElf_Shdr sym_tab_section_header;
907 setup_gnu_ht(Elf* elf_handle,
909 size_t sym_tab_index,
912 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
914 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
916 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
917 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
922 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
923 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
925 ht.nb_buckets = ht_data[0];
926 if (ht.nb_buckets == 0)
930 ht.first_sym_index = ht_data[1];
933 ht.bf_nwords = ht_data[2];
935 ht.shift = ht_data[3];
937 ht.bloom_filter = &ht_data[4];
942 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
944 ht.buckets = ht.bloom_filter + ht.bf_size;
946 ht.chain = ht.buckets + ht.nb_buckets;
977 lookup_symbol_from_gnu_hash_tab(
const environment& env,
979 const string& sym_name,
981 size_t sym_tab_index,
983 vector<elf_symbol_sptr>& syms_found)
986 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
992 size_t h1 = elf_gnu_hash(sym_name.c_str());
993 size_t h2 = h1 >> ht.shift;
996 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
997 int n = (h1 / c) % ht.bf_nwords;
1003 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1006 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1009 size_t i = ht.buckets[h1 % ht.nb_buckets];
1013 Elf32_Word stop_word, *stop_wordp;
1014 elf_symbol::version ver;
1016 const char* sym_name_str;
1025 for (i = ht.buckets[h1 % ht.nb_buckets],
1026 stop_wordp = &ht.chain[i - ht.first_sym_index];
1029 < ht.chain + (ht.sym_count - ht.first_sym_index));
1032 stop_word = *stop_wordp;
1033 if ((stop_word & ~ 1)!= (h1 & ~1))
1039 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1041 sym_name_str = elf_strptr(elf_handle,
1042 ht.sym_tab_section_header.sh_link,
1045 && compare_symbol_name(sym_name_str, sym_name, demangle))
1049 sym_type = stt_to_elf_symbol_type(GELF_ST_TYPE(symbol.st_info));
1050 sym_binding = stb_to_elf_symbol_binding(GELF_ST_BIND(symbol.st_info));
1052 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(symbol.st_other));
1054 if (get_version_for_symbol(elf_handle, i,
1063 sym_type, sym_binding,
1064 symbol.st_shndx != SHN_UNDEF,
1065 symbol.st_shndx == SHN_COMMON,
1066 ver, sym_visibility);
1067 syms_found.push_back(symbol_found);
1109 lookup_symbol_from_elf_hash_tab(
const environment& env,
1111 hash_table_kind ht_kind,
1113 size_t symtab_index,
1114 const string& symbol_name,
1116 vector<elf_symbol_sptr>& syms_found)
1118 if (elf_handle == 0 || symbol_name.empty())
1121 if (ht_kind == NO_HASH_TABLE_KIND)
1124 if (ht_kind == SYSV_HASH_TABLE_KIND)
1125 return lookup_symbol_from_sysv_hash_tab(env,
1126 elf_handle, symbol_name,
1131 else if (ht_kind == GNU_HASH_TABLE_KIND)
1132 return lookup_symbol_from_gnu_hash_tab(env,
1133 elf_handle, symbol_name,
1166 lookup_symbol_from_symtab(
const environment& env,
1168 const string& sym_name,
1169 size_t sym_tab_index,
1171 vector<elf_symbol_sptr>& syms_found)
1176 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1179 GElf_Shdr header_mem;
1180 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1183 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1184 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1187 elf_symbol::version ver;
1190 for (
size_t i = 0; i < symcount; ++i)
1193 sym = gelf_getsym(symtab, i, &sym_mem);
1194 name_str = elf_strptr(elf_handle,
1195 sym_tab_header->sh_link,
1198 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1201 stt_to_elf_symbol_type(GELF_ST_TYPE(sym->st_info));
1203 stb_to_elf_symbol_binding(GELF_ST_BIND(sym->st_info));
1205 stv_to_elf_symbol_visibility(GELF_ST_VISIBILITY(sym->st_other));
1206 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1207 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1209 if (get_version_for_symbol(elf_handle, i,
1216 sym_binding, sym_is_defined,
1217 sym_is_common, ver, sym_visibility);
1218 syms_found.push_back(symbol_found);
1257 lookup_symbol_from_elf(
const environment& env,
1259 const string& symbol_name,
1261 vector<elf_symbol_sptr>& syms_found)
1263 size_t hash_table_index = 0, symbol_table_index = 0;
1264 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1267 ht_kind = find_hash_table_section_index(elf_handle,
1269 symbol_table_index);
1271 if (ht_kind == NO_HASH_TABLE_KIND)
1273 if (!find_symbol_table_section_index(elf_handle, symbol_table_index))
1276 return lookup_symbol_from_symtab(env,
1284 return lookup_symbol_from_elf_hash_tab(env,
1308 lookup_public_function_symbol_from_elf(environment& env,
1310 const string& symbol_name,
1311 vector<elf_symbol_sptr>& func_syms)
1313 vector<elf_symbol_sptr> syms_found;
1316 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1319 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1320 i != syms_found.end();
1326 if ((type == elf_symbol::FUNC_TYPE
1327 || type == elf_symbol::GNU_IFUNC_TYPE
1328 || type == elf_symbol::COMMON_TYPE)
1329 && (binding == elf_symbol::GLOBAL_BINDING
1330 || binding == elf_symbol::WEAK_BINDING))
1332 func_syms.push_back(*i);
1353 int64_t const_value_;
1361 expr_result(
bool is_const)
1362 : is_const_(is_const),
1366 explicit expr_result(int64_t v)
1392 const_value(int64_t& value)
1396 value = const_value_;
1412 return const_value_;
1415 operator int64_t()
const
1416 {
return const_value();}
1419 operator=(
const int64_t v)
1427 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1430 operator>=(
const expr_result& o)
const
1431 {
return const_value_ >= o.const_value_;}
1434 operator<=(
const expr_result& o)
const
1435 {
return const_value_ <= o.const_value_;}
1438 operator>(
const expr_result& o)
const
1439 {
return const_value_ > o.const_value_;}
1442 operator<(
const expr_result& o)
const
1443 {
return const_value_ < o.const_value_;}
1448 expr_result r(*
this);
1449 r.const_value_ += v.const_value_;
1450 r.is_const_ = r.is_const_ && v.is_const_;
1455 operator+=(int64_t v)
1462 operator-(
const expr_result& v)
const
1464 expr_result r(*
this);
1465 r.const_value_ -= v.const_value_;
1466 r.is_const_ = r.is_const_ && v.is_const_;
1471 operator%(
const expr_result& v)
const
1473 expr_result r(*
this);
1474 r.const_value_ %= v.const_value_;
1475 r.is_const_ = r.is_const_ && v.is_const();
1480 operator*(
const expr_result& v)
const
1482 expr_result r(*
this);
1483 r.const_value_ *= v.const_value_;
1484 r.is_const_ = r.is_const_ && v.is_const();
1491 expr_result r(*
this);
1492 r.const_value_ |= v.const_value_;
1493 r.is_const_ = r.is_const_ && v.is_const_;
1498 operator^(
const expr_result& v)
const
1500 expr_result r(*
this);
1501 r.const_value_ ^= v.const_value_;
1502 r.is_const_ = r.is_const_ && v.is_const_;
1507 operator>>(
const expr_result& v)
const
1509 expr_result r(*
this);
1510 r.const_value_ = r.const_value_ >> v.const_value_;
1511 r.is_const_ = r.is_const_ && v.is_const_;
1518 expr_result r(*
this);
1519 r.const_value_ = r.const_value_ << v.const_value_;
1520 r.is_const_ = r.is_const_ && v.is_const_;
1527 expr_result r(*
this);
1528 r.const_value_ = ~r.const_value_;
1535 expr_result r(*
this);
1536 r.const_value_ = -r.const_value_;
1543 expr_result r = *
this;
1544 r.const_value_ = std::abs(static_cast<long double>(r.const_value()));
1551 expr_result r(*
this);
1552 r.const_value_ &= o.const_value_;
1553 r.is_const_ = r.is_const_ && o.is_const_;
1558 operator/(
const expr_result& o)
1560 expr_result r(*
this);
1561 r.is_const_ = r.is_const_ && o.is_const_;
1562 return r.const_value() / o.const_value();
1568 class expr_result_stack_type
1570 vector<expr_result> elems_;
1574 expr_result_stack_type()
1575 {elems_.reserve(4);}
1578 operator[](
unsigned i)
1580 unsigned s = elems_.size();
1582 return elems_[s - 1 -i];
1586 operator[](
unsigned i)
const
1587 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1591 {
return elems_.size();}
1593 vector<expr_result>::reverse_iterator
1595 {
return elems_.rbegin();}
1597 const vector<expr_result>::reverse_iterator
1599 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1601 vector<expr_result>::reverse_iterator
1603 {
return elems_.rend();}
1605 const vector<expr_result>::reverse_iterator
1607 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1611 {
return elems_.back();}
1615 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1618 push_front(expr_result e)
1619 {elems_.push_back(e);}
1624 expr_result r = front();
1630 erase(vector<expr_result>::reverse_iterator i)
1631 {elems_.erase(--i.base());}
1639 struct dwarf_expr_eval_context
1642 expr_result_stack_type stack;
1647 dwarf_expr_eval_context()
1651 stack.push_front(expr_result(
true));
1658 stack.push_front(expr_result(
true));
1659 accum = expr_result(
false);
1660 set_tls_addr =
false;
1669 set_tls_address(
bool f)
1678 set_tls_address()
const
1679 {
return set_tls_addr;}
1684 expr_result r = stack.front();
1690 push(
const expr_result& v)
1691 {stack.push_front(v);}
1700 typedef shared_ptr<reader> reader_sptr;
1707 class reader :
public elf_based_reader
1714 template <
typename ContainerType>
1715 class die_source_dependant_container_set
1717 ContainerType primary_debug_info_container_;
1718 ContainerType alt_debug_info_container_;
1719 ContainerType type_unit_container_;
1733 ContainerType *result = 0;
1736 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1737 result = &primary_debug_info_container_;
1739 case ALT_DEBUG_INFO_DIE_SOURCE:
1740 result = &alt_debug_info_container_;
1742 case TYPE_UNIT_DIE_SOURCE:
1743 result = &type_unit_container_;
1745 case NO_DEBUG_INFO_DIE_SOURCE:
1746 case NUMBER_OF_DIE_SOURCES:
1759 const ContainerType&
1762 return const_cast<die_source_dependant_container_set*
>(
this)->
1763 get_container(source);
1777 get_container(
const reader& rdr,
const Dwarf_Die *die)
1779 const die_source source = rdr.get_die_source(die);
1780 return get_container(source);
1793 const ContainerType&
1794 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1796 return const_cast<die_source_dependant_container_set*
>(
this)->
1797 get_container(rdr, die);
1804 primary_debug_info_container_.clear();
1805 alt_debug_info_container_.clear();
1806 type_unit_container_.clear();
1810 unsigned short dwarf_version_;
1811 Dwarf_Die* cur_tu_die_;
1812 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1816 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1817 decl_die_repr_die_offsets_maps_;
1821 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1822 type_die_repr_die_offsets_maps_;
1823 mutable die_source_dependant_container_set<die_istring_map_type>
1824 die_qualified_name_maps_;
1825 mutable die_source_dependant_container_set<die_istring_map_type>
1826 die_pretty_repr_maps_;
1827 mutable die_source_dependant_container_set<die_istring_map_type>
1828 die_pretty_type_repr_maps_;
1831 mutable die_source_dependant_container_set<die_artefact_map_type>
1832 decl_die_artefact_maps_;
1835 mutable die_source_dependant_container_set<die_artefact_map_type>
1836 type_die_artefact_maps_;
1839 mutable die_source_dependant_container_set<offset_offset_map_type>
1840 canonical_type_die_offsets_;
1843 mutable die_source_dependant_container_set<offset_offset_map_type>
1844 canonical_decl_die_offsets_;
1847 mutable istring_fn_type_map_type per_tu_repr_to_fn_type_maps_;
1850 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1852 dwarf_offset_pair_hash> die_comparison_results_;
1854 mutable offset_pair_set_type propagated_types_;
1855 die_class_or_union_map_type die_wip_classes_map_;
1856 die_class_or_union_map_type alternate_die_wip_classes_map_;
1857 die_class_or_union_map_type type_unit_die_wip_classes_map_;
1858 die_function_type_map_type die_wip_function_types_map_;
1859 die_function_type_map_type alternate_die_wip_function_types_map_;
1860 die_function_type_map_type type_unit_die_wip_function_types_map_;
1861 die_function_decl_map_type die_function_with_no_symbol_map_;
1862 vector<type_base_sptr> types_to_canonicalize_;
1863 string_classes_or_unions_map decl_only_classes_map_;
1864 string_enums_map decl_only_enums_map_;
1865 die_tu_map_type die_tu_map_;
1868 scope_stack_type scope_stack_;
1869 offset_offset_map_type primary_die_parent_map_;
1879 offset_offset_map_type alternate_die_parent_map_;
1880 offset_offset_map_type type_section_die_parent_map_;
1881 list<var_decl_sptr> var_decls_to_add_;
1882 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1883 bool debug_die_canonicalization_is_on_;
1884 bool use_canonical_die_comparison_;
1886 mutable size_t compare_count_;
1887 mutable size_t canonical_propagated_count_;
1888 mutable size_t cancelled_propagation_count_;
1889 mutable optional<bool> leverage_dwarf_factorization_;
1924 reader(
const string& elf_path,
1925 const vector<char**>& debug_info_root_paths,
1926 environment& environment,
1927 bool load_all_types,
1928 bool linux_kernel_mode)
1929 : elf_based_reader(elf_path,
1930 debug_info_root_paths,
1933 initialize(load_all_types, linux_kernel_mode);
1951 initialize(
bool load_all_types,
bool linux_kernel_mode)
1955 decl_die_repr_die_offsets_maps_.clear();
1956 type_die_repr_die_offsets_maps_.clear();
1957 die_qualified_name_maps_.clear();
1958 die_pretty_repr_maps_.clear();
1959 die_pretty_type_repr_maps_.clear();
1960 decl_die_artefact_maps_.clear();
1961 type_die_artefact_maps_.clear();
1962 canonical_type_die_offsets_.clear();
1963 canonical_decl_die_offsets_.clear();
1964 die_wip_classes_map_.clear();
1965 alternate_die_wip_classes_map_.clear();
1966 type_unit_die_wip_classes_map_.clear();
1967 die_wip_function_types_map_.clear();
1968 alternate_die_wip_function_types_map_.clear();
1969 type_unit_die_wip_function_types_map_.clear();
1970 die_function_with_no_symbol_map_.clear();
1971 types_to_canonicalize_.clear();
1972 decl_only_classes_map_.clear();
1973 die_tu_map_.clear();
1975 corpus_group().reset();
1977 primary_die_parent_map_.clear();
1978 tu_die_imported_unit_points_map_.clear();
1979 alt_tu_die_imported_unit_points_map_.clear();
1980 type_units_tu_die_imported_unit_points_map_.clear();
1981 alternate_die_parent_map_.clear();
1982 type_section_die_parent_map_.clear();
1983 var_decls_to_add_.clear();
1984 clear_per_translation_unit_data();
1985 options().load_in_linux_kernel_mode = linux_kernel_mode;
1986 options().load_all_types = load_all_types;
1987 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1988 debug_die_canonicalization_is_on_ =
1989 env().debug_die_canonicalization_is_on();
1990 use_canonical_die_comparison_ =
true;
1993 canonical_propagated_count_ = 0;
1994 cancelled_propagation_count_ = 0;
1995 load_in_linux_kernel_mode(linux_kernel_mode);
2017 const vector<char**>& debug_info_root_paths,
2018 bool load_all_types,
2019 bool linux_kernel_mode)
2022 initialize(load_all_types, linux_kernel_mode);
2042 static dwarf::reader_sptr
2043 create(
const std::string& elf_path,
2044 const vector<char**>& debug_info_root_paths,
2045 environment& environment,
2046 bool load_all_types,
2047 bool linux_kernel_mode)
2049 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2050 environment, load_all_types,
2051 linux_kernel_mode));
2068 read_corpus(status& status)
2070 status = STATUS_UNKNOWN;
2075 if (!(status & STATUS_OK))
2079 return corpus_sptr();
2083 if (dwarf_debug_info() ==
nullptr)
2084 status |= STATUS_DEBUG_INFO_NOT_FOUND;
2088 if (refers_to_alt_debug_info(alt_di_path)
2089 && !alternate_dwarf_debug_info())
2090 status |= STATUS_ALT_DEBUG_INFO_NOT_FOUND;
2095 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2096 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2098 return corpus_sptr();
2102 corpus_sptr corp = read_debug_info_into_corpus();
2104 status |= STATUS_OK;
2117 read_debug_info_into_corpus()
2119 clear_per_corpus_data();
2124 origin |= corpus::DWARF_ORIGIN;
2125 corpus()->set_origin(origin);
2127 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2128 && !env().user_set_analyze_exported_interfaces_only())
2135 env().analyze_exported_interfaces_only(
true);
2137 corpus()->set_soname(dt_soname());
2138 corpus()->set_needed(dt_needed());
2139 corpus()->set_architecture_name(elf_architecture());
2141 corpus()->set_symtab(symtab());
2145 if (!dwarf_debug_info()
2146 || !corpus()->get_symtab()
2147 || !corpus()->get_symtab()->has_symbols())
2150 uint8_t address_size = 0;
2151 size_t header_size = 0;
2153 #ifdef WITH_DEBUG_SELF_COMPARISON
2154 if (env().self_comparison_debug_is_on())
2155 env().set_self_comparison_debug_input(corpus());
2158 env().priv_->do_log(do_log());
2163 tools_utils::timer t;
2166 cerr <<
"building die -> parent maps ...";
2170 build_die_parent_maps();
2175 cerr <<
" DONE@" << corpus()->get_path()
2182 env().canonicalization_is_done(
false);
2185 tools_utils::timer t;
2188 cerr <<
"building the libabigail internal representation ...\n";
2192 Dwarf_Half dwarf_vers = 0;
2193 for (Dwarf_Off offset = 0, next_offset = 0;
2194 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
2195 offset, &next_offset, &header_size,
2196 &dwarf_vers, NULL, &address_size, NULL,
2198 offset = next_offset)
2200 Dwarf_Off die_offset = offset + header_size;
2202 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
2204 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2207 dwarf_version(dwarf_vers);
2214 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2220 cerr <<
"building the libabigail internal representation "
2221 <<
"DONE for corpus << corpus()->get_path()"
2226 cerr <<
"Number of aggregate types compared: "
2227 << compare_count_ <<
"\n"
2228 <<
"Number of canonical types propagated: "
2229 << canonical_propagated_count_ <<
"\n"
2230 <<
"Number of cancelled propagated canonical types:"
2231 << cancelled_propagation_count_ <<
"\n";
2236 tools_utils::timer t;
2239 cerr <<
"resolving declaration only classes ...";
2242 resolve_declaration_only_classes();
2246 cerr <<
" DONE@" << corpus()->get_path()
2254 tools_utils::timer t;
2257 cerr <<
"resolving declaration only enums ...";
2260 resolve_declaration_only_enums();
2264 cerr <<
" DONE@" << corpus()->get_path()
2272 tools_utils::timer t;
2275 cerr <<
"fixing up functions with linkage name but "
2276 <<
"no advertised underlying symbols ....";
2279 fixup_functions_with_no_symbols();
2283 cerr <<
" DONE@" << corpus()->get_path()
2302 tools_utils::timer t;
2305 cerr <<
"perform late type canonicalizing ...\n";
2309 perform_late_type_canonicalizing();
2313 cerr <<
"late type canonicalizing DONE for "
2314 << corpus()->get_path()
2321 env().canonicalization_is_done(
true);
2324 tools_utils::timer t;
2327 cerr <<
"sort functions and variables ...";
2330 corpus()->sort_functions();
2331 corpus()->sort_variables();
2335 cerr <<
" DONE@" << corpus()->get_path()
2349 clear_per_translation_unit_data()
2351 while (!scope_stack().empty())
2352 scope_stack().pop();
2353 var_decls_to_re_add_to_tree().clear();
2354 per_tu_repr_to_fn_type_maps().clear();
2360 clear_per_corpus_data()
2362 die_qualified_name_maps_.clear();
2363 die_pretty_repr_maps_.clear();
2364 die_pretty_type_repr_maps_.clear();
2365 clear_types_to_canonicalize();
2373 {
return options().env;}
2380 {
return const_cast<reader*
>(
this)->env();}
2388 drop_undefined_syms()
const
2389 {
return options().drop_undefined_syms;}
2396 drop_undefined_syms(
bool f)
2397 {options().drop_undefined_syms = f;}
2401 dwarf_version()
const
2402 {
return dwarf_version_;}
2405 dwarf_version(
unsigned short v)
2406 {dwarf_version_ = v;}
2418 dwarf_elf_handle()
const
2419 {
return dwarf_getelf(const_cast<Dwarf*>(dwarf_debug_info()));}
2429 dwarf_is_splitted()
const
2430 {
return dwarf_elf_handle() != elf_handle();}
2439 dwarf_per_die_source(
die_source source)
const
2441 const Dwarf *result = 0;
2444 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2445 case TYPE_UNIT_DIE_SOURCE:
2446 result = dwarf_debug_info();
2448 case ALT_DEBUG_INFO_DIE_SOURCE:
2449 result = alternate_dwarf_debug_info();
2451 case NO_DEBUG_INFO_DIE_SOURCE:
2452 case NUMBER_OF_DIE_SOURCES:
2463 {
return corpus_path();}
2467 {
return cur_tu_die_;}
2470 cur_tu_die(Dwarf_Die* cur_tu_die)
2471 {cur_tu_die_ = cur_tu_die;}
2473 dwarf_expr_eval_context&
2474 dwarf_expr_eval_ctxt()
const
2475 {
return dwarf_expr_eval_context_;}
2482 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2483 decl_die_repr_die_offsets_maps()
const
2484 {
return decl_die_repr_die_offsets_maps_;}
2491 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2492 decl_die_repr_die_offsets_maps()
2493 {
return decl_die_repr_die_offsets_maps_;}
2500 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2501 type_die_repr_die_offsets_maps()
const
2502 {
return type_die_repr_die_offsets_maps_;}
2509 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2510 type_die_repr_die_offsets_maps()
2511 {
return type_die_repr_die_offsets_maps_;}
2524 compute_canonical_die_offset(
const Dwarf_Die *die,
2525 Dwarf_Off &canonical_die_offset,
2526 bool die_as_type)
const
2528 offset_offset_map_type &canonical_dies =
2530 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2531 get_container(*
this, die)
2532 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2533 get_container(*
this, die);
2535 Dwarf_Die canonical_die;
2536 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2538 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2556 compute_canonical_die(
const Dwarf_Die *die,
2557 offset_offset_map_type& canonical_dies,
2558 Dwarf_Die &canonical_die,
2559 bool die_as_type)
const
2561 const die_source source = get_die_source(die);
2563 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2565 compute_canonical_die(die_offset, source,
2567 canonical_die, die_as_type);
2587 compute_canonical_die(Dwarf_Off die_offset,
2589 offset_offset_map_type& canonical_dies,
2590 Dwarf_Die &canonical_die,
2591 bool die_as_type)
const
2597 ? (
const_cast<reader*
>(
this)->
2598 type_die_repr_die_offsets_maps().get_container(source))
2599 : (const_cast<reader*>(
this)->
2600 decl_die_repr_die_offsets_maps().get_container(source));
2603 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2612 interned_string name =
2614 ? get_die_pretty_type_representation(&die, 0)
2615 : get_die_pretty_representation(&die, 0);
2617 Dwarf_Off canonical_die_offset = 0;
2618 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2621 dwarf_offsets_type offsets;
2622 offsets.push_back(die_offset);
2623 map[name] = offsets;
2624 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2625 get_die_from_offset(source, die_offset, &canonical_die);
2629 Dwarf_Off cur_die_offset;
2630 Dwarf_Die potential_canonical_die;
2631 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2632 o != i->second.end();
2635 cur_die_offset = *o;
2636 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2637 if (compare_dies(*
this, &die, &potential_canonical_die,
2640 canonical_die_offset = cur_die_offset;
2641 set_canonical_die_offset(canonical_dies, die_offset,
2642 canonical_die_offset);
2643 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2648 canonical_die_offset = die_offset;
2649 i->second.push_back(die_offset);
2650 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2651 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2670 get_canonical_die(
const Dwarf_Die *die,
2671 Dwarf_Die &canonical_die,
2675 const die_source source = get_die_source(die);
2677 offset_offset_map_type &canonical_dies =
2679 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2680 get_container(source)
2681 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2682 get_container(source);
2684 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2685 if (Dwarf_Off canonical_die_offset =
2686 get_canonical_die_offset(canonical_dies, die_offset))
2688 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2696 ? (
const_cast<reader*
>(
this)->
2697 type_die_repr_die_offsets_maps().get_container(*
this, die))
2698 : (const_cast<reader*>(
this)->
2699 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2707 interned_string name =
2709 ? get_die_pretty_type_representation(die, where)
2710 : get_die_pretty_representation(die, where);
2712 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2716 Dwarf_Off cur_die_offset;
2717 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2718 o != i->second.end();
2721 cur_die_offset = *o;
2722 get_die_from_offset(source, cur_die_offset, &canonical_die);
2724 if (compare_dies_during_canonicalization(const_cast<reader&>(*
this),
2725 die, &canonical_die,
2728 set_canonical_die_offset(canonical_dies,
2762 get_or_compute_canonical_die(
const Dwarf_Die* die,
2763 Dwarf_Die& canonical_die,
2765 bool die_as_type)
const
2767 const die_source source = get_die_source(die);
2769 offset_offset_map_type &canonical_dies =
2771 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2772 get_container(source)
2773 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2774 get_container(source);
2776 Dwarf_Off initial_die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
2778 if (Dwarf_Off canonical_die_offset =
2779 get_canonical_die_offset(canonical_dies,
2780 initial_die_offset))
2782 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2786 if (!is_type_die_to_be_canonicalized(die))
2793 ? (
const_cast<reader*
>(
this)->
2794 type_die_repr_die_offsets_maps().get_container(*
this, die))
2795 : (const_cast<reader*>(
this)->
2796 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2804 interned_string name =
2806 ? get_die_pretty_type_representation(die, where)
2807 : get_die_pretty_representation(die, where);
2809 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2812 dwarf_offsets_type offsets;
2813 offsets.push_back(initial_die_offset);
2814 map[name] = offsets;
2815 get_die_from_offset(source, initial_die_offset, &canonical_die);
2816 set_canonical_die_offset(canonical_dies,
2818 initial_die_offset);
2825 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2828 Dwarf_Off die_offset = i->second[n];
2829 get_die_from_offset(source, die_offset, &canonical_die);
2831 if (compare_dies_during_canonicalization(const_cast<reader&>(*
this),
2832 die, &canonical_die,
2835 set_canonical_die_offset(canonical_dies,
2845 get_die_from_offset(source, initial_die_offset, &canonical_die);
2846 i->second.push_back(initial_die_offset);
2847 set_canonical_die_offset(canonical_dies,
2849 initial_die_offset);
2866 get_die_source(
const Dwarf_Die *die)
const
2868 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2889 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2893 uint8_t address_size = 0, offset_size = 0;
2894 if (!dwarf_diecu(const_cast<Dwarf_Die*>(&die),
2895 &cu_die, &address_size,
2899 Dwarf_Half version = 0;
2900 Dwarf_Off abbrev_offset = 0;
2901 uint64_t type_signature = 0;
2902 Dwarf_Off type_offset = 0;
2903 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2904 &version, &abbrev_offset,
2905 &address_size, &offset_size,
2906 &type_signature, &type_offset))
2909 int tag = dwarf_tag(&cu_kind);
2911 if (tag == DW_TAG_compile_unit
2912 || tag == DW_TAG_partial_unit)
2914 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
2915 if (dwarf_debug_info() == die_dwarf)
2916 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
2917 else if (alternate_dwarf_debug_info() == die_dwarf)
2918 source = ALT_DEBUG_INFO_DIE_SOURCE;
2922 else if (tag == DW_TAG_type_unit)
2923 source = TYPE_UNIT_DIE_SOURCE;
2939 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
2941 if (source == TYPE_UNIT_DIE_SOURCE)
2942 ABG_ASSERT(dwarf_offdie_types(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2945 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
2972 associate_die_to_decl(Dwarf_Die* die,
2973 decl_base_sptr decl,
2974 size_t where_offset,
2975 bool do_associate_by_repr =
false)
2977 const die_source source = get_die_source(die);
2979 die_artefact_map_type& m =
2980 decl_die_artefact_maps().get_container(source);
2983 if (do_associate_by_repr)
2985 Dwarf_Die equiv_die;
2986 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
2989 die_offset = dwarf_dieoffset(&equiv_die);
2992 die_offset = dwarf_dieoffset(die);
2994 m[die_offset] = decl;
3016 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3018 decl_base_sptr result =
3019 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3038 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3041 die_istring_map_type& map =
3042 die_qualified_name_maps_.get_container(*
this, die);
3044 size_t die_offset = dwarf_dieoffset(die);
3045 die_istring_map_type::const_iterator i = map.find(die_offset);
3049 reader& rdr = *
const_cast<reader*
>(
this);
3050 string qualified_name = die_qualified_name(rdr, die, where_offset);
3051 interned_string istr = env().intern(qualified_name);
3052 map[die_offset] = istr;
3072 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3074 return const_cast<reader*
>(
this)->
3075 get_die_qualified_name(die, where_offset);
3096 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3101 if (die == cur_tu_die())
3102 return env().intern(
"");
3104 die_istring_map_type& map =
3105 die_qualified_name_maps_.get_container(*const_cast<reader*>(
this),
3108 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3109 die_istring_map_type::const_iterator i =
3110 map.find(die_offset);
3114 reader& rdr = *
const_cast<reader*
>(
this);
3115 string qualified_name;
3116 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
3117 if ((tag == DW_TAG_structure_type
3118 || tag == DW_TAG_class_type
3119 || tag == DW_TAG_union_type)
3120 && die_is_anonymous(die))
3122 location l = die_location(*
this, die);
3123 qualified_name = l ? l.expand() :
"noloc";
3124 qualified_name =
"unnamed-at-" + qualified_name;
3128 die_qualified_type_name(rdr, die, where_offset);
3130 interned_string istr = env().intern(qualified_name);
3131 map[die_offset] = istr;
3155 get_die_pretty_type_representation(
const Dwarf_Die *die,
3156 size_t where_offset)
const
3159 die_istring_map_type& map =
3160 die_pretty_type_repr_maps_.get_container(*const_cast<reader*>(
this),
3163 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3164 die_istring_map_type::const_iterator i = map.find(die_offset);
3168 reader& rdr = *
const_cast<reader*
>(
this);
3169 string pretty_representation =
3170 die_pretty_print_type(rdr, die, where_offset);
3171 interned_string istr = env().intern(pretty_representation);
3172 map[die_offset] = istr;
3192 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3196 die_istring_map_type& map =
3197 die_pretty_repr_maps_.get_container(*const_cast<reader*>(
this),
3200 size_t die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3201 die_istring_map_type::const_iterator i = map.find(die_offset);
3205 reader& rdr = *
const_cast<reader*
>(
this);
3206 string pretty_representation =
3207 die_pretty_print(rdr, die, where_offset);
3208 interned_string istr = env().intern(pretty_representation);
3209 map[die_offset] = istr;
3233 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3236 lookup_artifact_from_die(die,
true);
3238 return fn->get_type();
3262 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3264 Dwarf_Die equiv_die;
3265 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3268 const die_artefact_map_type& m =
3270 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3271 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3273 size_t die_offset = dwarf_dieoffset(&equiv_die);
3274 die_artefact_map_type::const_iterator i = m.find(die_offset);
3301 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3303 bool die_as_type =
false)
const
3305 const die_artefact_map_type& m =
3307 ? type_die_artefact_maps().get_container(source)
3308 : decl_die_artefact_maps().get_container(source);
3310 die_artefact_map_type::const_iterator i = m.find(die_offset);
3327 ABG_ASSERT(dwarf_diecu(const_cast<Dwarf_Die*>(die), &cu_die, 0, 0));
3330 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
3333 lang = dwarf_language_to_tu_language(l);
3345 die_is_in_c(
const Dwarf_Die *die)
const
3348 if (!get_die_language(die, l))
3361 die_is_in_cplus_plus(
const Dwarf_Die *die)
const
3364 if (!get_die_language(die, l))
3377 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
const
3380 if (!get_die_language(die, l))
3422 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(dwarf_per_die_source(source)),
3437 if (!get_die_language(die, lang))
3448 die_source_dependant_container_set<die_artefact_map_type>&
3449 decl_die_artefact_maps()
3450 {
return decl_die_artefact_maps_;}
3457 const die_source_dependant_container_set<die_artefact_map_type>&
3458 decl_die_artefact_maps()
const
3459 {
return decl_die_artefact_maps_;}
3466 die_source_dependant_container_set<die_artefact_map_type>&
3467 type_die_artefact_maps()
3468 {
return type_die_artefact_maps_;}
3475 const die_source_dependant_container_set<die_artefact_map_type>&
3476 type_die_artefact_maps()
const
3477 {
return type_die_artefact_maps_;}
3484 istring_fn_type_map_type&
3485 per_tu_repr_to_fn_type_maps()
3486 {
return per_tu_repr_to_fn_type_maps_;}
3493 const istring_fn_type_map_type&
3494 per_tu_repr_to_fn_type_maps()
const
3495 {
return per_tu_repr_to_fn_type_maps_;}
3505 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3506 const function_type_sptr &fn_type)
3508 if (!die_is_function_type(die))
3511 interned_string repr =
3512 get_die_pretty_type_representation(die, 0);
3515 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3526 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3528 if (!die_is_function_type(die))
3531 interned_string repr = die_name(die).empty() ?
3532 get_die_pretty_type_representation(die, 0)
3533 : get_die_pretty_representation(die, 0);
3536 istring_fn_type_map_type::const_iterator i =
3537 per_tu_repr_to_fn_type_maps().find(repr);
3539 if (i == per_tu_repr_to_fn_type_maps().end())
3555 set_canonical_die_offset(offset_offset_map_type &canonical_dies,
3556 Dwarf_Off die_offset,
3557 Dwarf_Off canonical_die_offset)
const
3559 canonical_dies[die_offset] = canonical_die_offset;}
3575 set_canonical_die_offset(Dwarf_Off die_offset,
3577 Dwarf_Off canonical_die_offset,
3578 bool die_as_type)
const
3580 offset_offset_map_type &canonical_dies =
3582 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3583 get_container(source)
3584 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3585 get_container(source);
3587 set_canonical_die_offset(canonical_dies,
3589 canonical_die_offset);
3603 set_canonical_die_offset(
const Dwarf_Die *die,
3604 Dwarf_Off canonical_die_offset,
3605 bool die_as_type)
const
3607 const die_source source = get_die_source(die);
3609 Dwarf_Off die_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(die));
3611 set_canonical_die_offset(die_offset, source,
3612 canonical_die_offset,
3625 get_canonical_die_offset(offset_offset_map_type &canonical_dies,
3626 Dwarf_Off die_offset)
const
3628 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3629 if (it == canonical_dies.end())
3646 get_canonical_die_offset(Dwarf_Off die_offset,
3648 bool die_as_type)
const
3650 offset_offset_map_type &canonical_dies =
3652 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3653 get_container(source)
3654 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3655 get_container(source);
3657 return get_canonical_die_offset(canonical_dies, die_offset);
3672 erase_canonical_die_offset(Dwarf_Off die_offset,
3674 bool die_as_type)
const
3676 offset_offset_map_type &canonical_dies =
3678 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3679 get_container(source)
3680 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3681 get_container(source);
3683 return canonical_dies.erase(die_offset);
3696 associate_die_to_type(
const Dwarf_Die *die,
3697 type_base_sptr type,
3703 Dwarf_Die equiv_die;
3704 if (!get_or_compute_canonical_die(die, equiv_die, where,
3708 die_artefact_map_type& m =
3709 type_die_artefact_maps().get_container(*
this, &equiv_die);
3711 size_t die_offset = dwarf_dieoffset(&equiv_die);
3712 m[die_offset] = type;
3726 lookup_type_from_die(
const Dwarf_Die* die)
const
3729 lookup_artifact_from_die(die,
true);
3731 return fn->get_type();
3749 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3751 type_base_sptr result;
3752 const die_artefact_map_type& m =
3753 type_die_artefact_maps().get_container(source);
3754 die_artefact_map_type::const_iterator i = m.find(die_offset);
3758 return fn->get_type();
3765 const die_class_or_union_map_type& m = die_wip_classes_map(source);
3766 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3775 const die_function_type_map_type& m =
3776 die_wip_function_types_map(source);
3777 die_function_type_map_type::const_iterator i = m.find(die_offset);
3794 const die_class_or_union_map_type&
3796 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3806 die_class_or_union_map_type&
3811 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3813 case ALT_DEBUG_INFO_DIE_SOURCE:
3814 return alternate_die_wip_classes_map_;
3815 case TYPE_UNIT_DIE_SOURCE:
3816 return type_unit_die_wip_classes_map_;
3817 case NO_DEBUG_INFO_DIE_SOURCE:
3818 case NUMBER_OF_DIE_SOURCES:
3821 return die_wip_classes_map_;
3831 const die_function_type_map_type&
3832 die_wip_function_types_map(
die_source source)
const
3833 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3842 die_function_type_map_type&
3843 die_wip_function_types_map(
die_source source)
3847 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3849 case ALT_DEBUG_INFO_DIE_SOURCE:
3850 return alternate_die_wip_function_types_map_;
3851 case TYPE_UNIT_DIE_SOURCE:
3852 return type_unit_die_wip_function_types_map_;
3853 case NO_DEBUG_INFO_DIE_SOURCE:
3854 case NUMBER_OF_DIE_SOURCES:
3857 return die_wip_function_types_map_;
3867 die_function_decl_map_type&
3868 die_function_decl_with_no_symbol_map()
3869 {
return die_function_with_no_symbol_map_;}
3882 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3884 die_class_or_union_map_type::const_iterator i =
3885 die_wip_classes_map(source).find(offset);
3886 return (i != die_wip_classes_map(source).end());
3900 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3902 die_function_type_map_type::const_iterator i =
3903 die_wip_function_types_map(source).find(offset);
3904 return (i != die_wip_function_types_map(source).end());
3923 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3929 || dwarf_tag(die) != DW_TAG_member
3930 || !die_name(die).empty())
3936 if (die_is_anonymous_data_member(die))
3942 int64_t offset_in_bits = 0;
3943 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3947 loc = die_location(*
this, die);
3952 std::ostringstream o;
3953 o <<
"unnamed-dm-@-";
3955 o <<
"offset-" << offset_in_bits <<
"bits";
3957 o <<
"loc-" << loc.expand();
3969 const string_classes_or_unions_map&
3970 declaration_only_classes()
const
3971 {
return decl_only_classes_map_;}
3980 string_classes_or_unions_map&
3981 declaration_only_classes()
3982 {
return decl_only_classes_map_;}
3990 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
3992 if (cou->get_is_declaration_only()
3993 && cou->get_definition_of_declaration() == 0)
3995 string qn = cou->get_qualified_name();
3996 string_classes_or_unions_map::iterator record =
3997 declaration_only_classes().find(qn);
3998 if (record == declaration_only_classes().end())
3999 declaration_only_classes()[qn].push_back(cou);
4001 record->second.push_back(cou);
4013 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4015 if (cou->get_is_declaration_only())
4016 return (declaration_only_classes().find(cou->get_qualified_name())
4017 != declaration_only_classes().end());
4037 const environment& e = l->get_environment();
4040 e.priv_->allow_type_comparison_results_caching(
true);
4041 bool s0 = e.decl_only_class_equals_definition();
4042 e.decl_only_class_equals_definition(
true);
4043 bool equal = l == r;
4044 e.decl_only_class_equals_definition(s0);
4045 e.priv_->clear_type_comparison_results_cache();
4046 e.priv_->allow_type_comparison_results_caching(
false);
4053 resolve_declaration_only_classes()
4055 vector<string> resolved_classes;
4057 for (string_classes_or_unions_map::iterator i =
4058 declaration_only_classes().begin();
4059 i != declaration_only_classes().end();
4062 bool to_resolve =
false;
4063 for (classes_or_unions_type::iterator j = i->second.begin();
4064 j != i->second.end();
4066 if ((*j)->get_is_declaration_only()
4067 && ((*j)->get_definition_of_declaration() == 0))
4072 resolved_classes.push_back(i->first);
4117 map<string, class_or_union_sptr> per_tu_class_map;
4118 for (type_base_wptrs_type::const_iterator c = classes->begin();
4119 c != classes->end();
4126 if (klass->get_is_declaration_only())
4129 string tu_path = klass->get_translation_unit()->get_absolute_path();
4130 if (tu_path.empty())
4136 per_tu_class_map[tu_path] = klass;
4139 if (!per_tu_class_map.empty())
4145 for (classes_or_unions_type::iterator j = i->second.begin();
4146 j != i->second.end();
4149 if ((*j)->get_is_declaration_only()
4150 && ((*j)->get_definition_of_declaration() == 0))
4153 (*j)->get_translation_unit()->get_absolute_path();
4154 map<string, class_or_union_sptr>::const_iterator e =
4155 per_tu_class_map.find(tu_path);
4156 if (e != per_tu_class_map.end())
4157 (*j)->set_definition_of_declaration(e->second);
4158 else if (per_tu_class_map.size() == 1)
4159 (*j)->set_definition_of_declaration
4160 (per_tu_class_map.begin()->second);
4170 class_or_union_sptr>::const_iterator it;
4171 class_or_union_sptr first_class =
4172 per_tu_class_map.begin()->second;
4173 bool all_class_definitions_are_equal =
true;
4174 for (it = per_tu_class_map.begin();
4175 it != per_tu_class_map.end();
4178 if (it == per_tu_class_map.begin())
4182 if (!compare_before_canonicalisation(it->second,
4185 all_class_definitions_are_equal =
false;
4190 if (all_class_definitions_are_equal)
4191 (*j)->set_definition_of_declaration(first_class);
4195 resolved_classes.push_back(i->first);
4199 size_t num_decl_only_classes = declaration_only_classes().size(),
4200 num_resolved = resolved_classes.size();
4202 cerr <<
"resolved " << num_resolved
4203 <<
" class declarations out of "
4204 << num_decl_only_classes
4207 for (vector<string>::const_iterator i = resolved_classes.begin();
4208 i != resolved_classes.end();
4210 declaration_only_classes().erase(*i);
4212 if (show_stats() && !declaration_only_classes().empty())
4214 cerr <<
"Here are the "
4215 << num_decl_only_classes - num_resolved
4216 <<
" unresolved class declarations:\n";
4217 for (string_classes_or_unions_map::iterator i =
4218 declaration_only_classes().begin();
4219 i != declaration_only_classes().end();
4221 cerr <<
" " << i->first <<
"\n";
4232 const string_enums_map&
4233 declaration_only_enums()
const
4234 {
return decl_only_enums_map_;}
4244 declaration_only_enums()
4245 {
return decl_only_enums_map_;}
4255 if (enom->get_is_declaration_only()
4256 && enom->get_definition_of_declaration() == 0)
4258 string qn = enom->get_qualified_name();
4259 string_enums_map::iterator record =
4260 declaration_only_enums().find(qn);
4261 if (record == declaration_only_enums().end())
4262 declaration_only_enums()[qn].push_back(enom);
4264 record->second.push_back(enom);
4278 if (enom->get_is_declaration_only())
4279 return (declaration_only_enums().find(enom->get_qualified_name())
4280 != declaration_only_enums().end());
4293 resolve_declaration_only_enums()
4295 vector<string> resolved_enums;
4297 for (string_enums_map::iterator i =
4298 declaration_only_enums().begin();
4299 i != declaration_only_enums().end();
4302 bool to_resolve =
false;
4303 for (enums_type::iterator j = i->second.begin();
4304 j != i->second.end();
4306 if ((*j)->get_is_declaration_only()
4307 && ((*j)->get_definition_of_declaration() == 0))
4312 resolved_enums.push_back(i->first);
4354 map<string, enum_type_decl_sptr> per_tu_enum_map;
4355 for (type_base_wptrs_type::const_iterator c = enums->begin();
4363 if (enom->get_is_declaration_only())
4366 string tu_path = enom->get_translation_unit()->get_absolute_path();
4367 if (tu_path.empty())
4373 per_tu_enum_map[tu_path] = enom;
4376 if (!per_tu_enum_map.empty())
4382 for (enums_type::iterator j = i->second.begin();
4383 j != i->second.end();
4386 if ((*j)->get_is_declaration_only()
4387 && ((*j)->get_definition_of_declaration() == 0))
4390 (*j)->get_translation_unit()->get_absolute_path();
4391 map<string, enum_type_decl_sptr>::const_iterator e =
4392 per_tu_enum_map.find(tu_path);
4393 if (e != per_tu_enum_map.end())
4394 (*j)->set_definition_of_declaration(e->second);
4395 else if (per_tu_enum_map.size() == 1)
4396 (*j)->set_definition_of_declaration
4397 (per_tu_enum_map.begin()->second);
4409 per_tu_enum_map.begin()->second;
4410 bool all_enum_definitions_are_equal =
true;
4411 for (it = per_tu_enum_map.begin();
4412 it != per_tu_enum_map.end();
4415 if (it == per_tu_enum_map.begin())
4419 if (!compare_before_canonicalisation(it->second,
4422 all_enum_definitions_are_equal =
false;
4427 if (all_enum_definitions_are_equal)
4428 (*j)->set_definition_of_declaration(first_enum);
4432 resolved_enums.push_back(i->first);
4436 size_t num_decl_only_enums = declaration_only_enums().size(),
4437 num_resolved = resolved_enums.size();
4439 cerr <<
"resolved " << num_resolved
4440 <<
" enum declarations out of "
4441 << num_decl_only_enums
4444 for (vector<string>::const_iterator i = resolved_enums.begin();
4445 i != resolved_enums.end();
4447 declaration_only_enums().erase(*i);
4449 if (show_stats() && !declaration_only_enums().empty())
4451 cerr <<
"Here are the "
4452 << num_decl_only_enums - num_resolved
4453 <<
" unresolved enum declarations:\n";
4454 for (string_enums_map::iterator i = declaration_only_enums().begin();
4455 i != declaration_only_enums().end();
4457 cerr <<
" " << i->first <<
"\n";
4473 corpus_sptr corp = corpus();
4477 string id = fn->get_id_string();
4479 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4484 if (f->get_symbol())
4504 fixup_functions_with_no_symbols()
4506 corpus_sptr corp = corpus();
4510 die_function_decl_map_type &fns_with_no_symbol =
4511 die_function_decl_with_no_symbol_map();
4514 cerr << fns_with_no_symbol.size()
4515 <<
" functions to fixup, potentially\n";
4517 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4518 i != fns_with_no_symbol.end();
4521 corp->lookup_function_symbol(i->second->get_linkage_name()))
4536 if (i->second->get_symbol()
4537 || symbol_already_belongs_to_a_function(sym))
4542 i->second->set_symbol(sym);
4545 i->second->set_is_in_public_symbol_table(
true);
4548 maybe_add_fn_to_exported_decls(i->second.get());
4550 cerr <<
"fixed up '"
4551 << i->second->get_pretty_representation()
4552 <<
"' with symbol '"
4553 << sym->get_id_string()
4557 fns_with_no_symbol.clear();
4567 const vector<type_base_sptr>&
4568 types_to_canonicalize()
const
4569 {
return types_to_canonicalize_;}
4573 clear_types_to_canonicalize()
4575 types_to_canonicalize_.clear();
4583 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4585 types_to_canonicalize_.push_back(t);
4595 canonicalize_types_scheduled()
4597 tools_utils::timer cn_timer;
4600 cerr <<
"DWARF Reader is going to canonicalize types";
4601 corpus_sptr c = corpus();
4603 cerr <<
" of corpus " << corpus()->get_path() <<
"\n";
4607 if (!types_to_canonicalize().empty())
4609 types_to_canonicalize().end(),
4610 [](
const vector<type_base_sptr>::const_iterator& i)
4616 cerr <<
"finished canonicalizing types";
4617 corpus_sptr c = corpus();
4619 cerr <<
" of corpus " << corpus()->get_path();
4620 cerr <<
": (" << cn_timer <<
")\n";
4637 add_late_canonicalized_types_stats(
size_t& canonicalized,
4638 size_t& missed)
const
4640 for (
auto t : types_to_canonicalize())
4642 if (t->get_canonical_type())
4652 perform_late_type_canonicalizing()
4654 canonicalize_types_scheduled();
4658 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4659 add_late_canonicalized_types_stats(num_canonicalized,
4661 total = num_canonicalized + num_missed;
4665 cerr <<
" # late canonicalized types: "
4666 << num_canonicalized;
4668 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4670 <<
" # missed canonicalization opportunities: "
4673 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4679 const die_tu_map_type&
4681 {
return die_tu_map_;}
4685 {
return die_tu_map_;}
4694 tu_die_imported_unit_points_map(
die_source source)
const
4695 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4704 tu_die_imported_unit_points_map(
die_source source)
4708 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4710 case ALT_DEBUG_INFO_DIE_SOURCE:
4711 return alt_tu_die_imported_unit_points_map_;
4712 case TYPE_UNIT_DIE_SOURCE:
4713 return type_units_tu_die_imported_unit_points_map_;
4714 case NO_DEBUG_INFO_DIE_SOURCE:
4715 case NUMBER_OF_DIE_SOURCES:
4719 return tu_die_imported_unit_points_map_;
4735 const offset_offset_map_type&
4737 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4745 offset_offset_map_type&
4750 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4752 case ALT_DEBUG_INFO_DIE_SOURCE:
4753 return alternate_die_parent_map_;
4754 case TYPE_UNIT_DIE_SOURCE:
4755 return type_section_die_parent_map();
4756 case NO_DEBUG_INFO_DIE_SOURCE:
4757 case NUMBER_OF_DIE_SOURCES:
4760 return primary_die_parent_map_;
4763 const offset_offset_map_type&
4764 type_section_die_parent_map()
const
4765 {
return type_section_die_parent_map_;}
4767 offset_offset_map_type&
4768 type_section_die_parent_map()
4769 {
return type_section_die_parent_map_;}
4775 cur_transl_unit()
const
4799 global_scope()
const
4800 {
return cur_transl_unit()->get_global_scope();}
4807 {
return nil_scope_;}
4809 const scope_stack_type&
4811 {
return scope_stack_;}
4815 {
return scope_stack_;}
4820 if (scope_stack().empty())
4822 if (cur_transl_unit())
4825 return scope_stack().top();
4828 list<var_decl_sptr>&
4829 var_decls_to_re_add_to_tree()
4830 {
return var_decls_to_add_;}
4843 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
4845 if (!die || !die_is_decl(die))
4848 bool result =
false, address_found =
false, symbol_is_exported =
false;;
4849 Dwarf_Addr decl_symbol_address = 0;
4851 if (die_is_variable_decl(die))
4853 if ((address_found = get_variable_address(die, decl_symbol_address)))
4854 symbol_is_exported =
4855 !!variable_symbol_is_exported(decl_symbol_address);
4857 else if (die_is_function_decl(die))
4859 if ((address_found = get_function_address(die, decl_symbol_address)))
4860 symbol_is_exported =
4861 !!function_symbol_is_exported(decl_symbol_address);
4865 result = symbol_is_exported;
4884 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
4890 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
4892 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4894 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4895 ABG_ASSERT(get_binary_load_address(dwarf_elf_handle(),
4896 dwarf_elf_load_address));
4897 ABG_ASSERT(get_binary_load_address(elf_handle(),
4899 if (dwarf_is_splitted()
4900 && (dwarf_elf_load_address != elf_load_address))
4911 addr = addr - dwarf_elf_load_address + elf_load_address;
4937 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
4942 Elf* elf = elf_handle();
4944 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4946 if (elf_header->e_type == ET_REL)
4959 addr = maybe_adjust_address_for_exec_or_dyn(addr);
4984 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
4986 Elf* elf = elf_handle();
4988 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4990 if (elf_header->e_type == ET_REL)
5003 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5022 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5023 Dwarf_Addr& address)
const
5026 Dwarf_Addr end_addr;
5027 ptrdiff_t offset = 0;
5031 Dwarf_Addr addr = 0, fn_addr = 0;
5032 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5034 fn_addr = maybe_adjust_fn_sym_address(addr);
5035 if (function_symbol_is_exported(fn_addr))
5041 }
while (offset > 0);
5059 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5061 if (!die_address_attribute(const_cast<Dwarf_Die*>(function_die),
5062 DW_AT_low_pc, address))
5068 if (!get_first_exported_fn_address_from_DW_AT_ranges
5069 (const_cast<Dwarf_Die*>(function_die),
5073 address = maybe_adjust_fn_sym_address(address);
5092 get_variable_address(
const Dwarf_Die* variable_die,
5093 Dwarf_Addr& address)
const
5095 bool is_tls_address =
false;
5096 if (!die_location_address(const_cast<Dwarf_Die*>(variable_die),
5097 address, is_tls_address))
5099 if (!is_tls_address)
5100 address = maybe_adjust_var_sym_address(address);
5107 corpus::exported_decls_builder*
5108 exported_decls_builder()
5109 {
return corpus()->get_exported_decls_builder().get();}
5117 load_all_types()
const
5118 {
return options().load_all_types;}
5126 load_all_types(
bool f)
5127 {options().load_all_types = f;}
5130 load_in_linux_kernel_mode()
const
5131 {
return options().load_in_linux_kernel_mode;}
5134 load_in_linux_kernel_mode(
bool f)
5135 {options().load_in_linux_kernel_mode = f;}
5145 leverage_dwarf_factorization()
const
5147 if (!leverage_dwarf_factorization_.has_value())
5149 if (options().leverage_dwarf_factorization
5150 && elf_helpers::find_section_by_name(elf_handle(),
5151 ".gnu_debugaltlink"))
5152 leverage_dwarf_factorization_ =
true;
5154 leverage_dwarf_factorization_ =
false;
5156 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5158 return *leverage_dwarf_factorization_;
5168 {
return options().show_stats;}
5178 {options().show_stats = f;}
5188 {
return options().do_log;}
5197 {options().do_log = f;}
5217 build_die_parent_relations_under(Dwarf_Die* die,
5219 imported_unit_points_type & imported_units)
5224 offset_offset_map_type& parent_of = die_parent_map(source);
5227 if (dwarf_child(die, &child) != 0)
5232 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5233 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5235 Dwarf_Die imported_unit;
5236 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5247 && die_has_children(&imported_unit))
5249 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5250 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5251 imported_units.push_back
5252 (imported_unit_point(dwarf_dieoffset(&child),
5254 imported_unit_die_source));
5257 build_die_parent_relations_under(&child, source, imported_units);
5259 while (dwarf_siblingof(&child, &child) == 0);
5291 case translation_unit::LANG_UNKNOWN:
5292 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5293 case translation_unit::LANG_Mips_Assembler:
5320 build_die_parent_maps()
5322 bool we_do_have_to_build_die_parent_map =
false;
5323 uint8_t address_size = 0;
5324 size_t header_size = 0;
5329 for (Dwarf_Off offset = 0, next_offset = 0;
5330 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5331 offset, &next_offset, &header_size,
5332 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5333 offset = next_offset)
5335 Dwarf_Off die_offset = offset + header_size;
5337 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
5342 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5344 if (do_we_build_die_parent_maps(lang))
5345 we_do_have_to_build_die_parent_map =
true;
5348 if (!we_do_have_to_build_die_parent_map)
5353 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5354 for (Dwarf_Off offset = 0, next_offset = 0;
5355 (dwarf_next_unit(const_cast<Dwarf*>(alternate_dwarf_debug_info()),
5356 offset, &next_offset, &header_size,
5357 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5358 offset = next_offset)
5360 Dwarf_Off die_offset = offset + header_size;
5362 if (!dwarf_offdie(const_cast<Dwarf*>(alternate_dwarf_debug_info()),
5367 imported_unit_points_type& imported_units =
5368 tu_die_imported_unit_points_map(source)[die_offset] =
5370 build_die_parent_relations_under(&cu, source, imported_units);
5375 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5378 for (Dwarf_Off offset = 0, next_offset = 0;
5379 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5380 offset, &next_offset, &header_size,
5381 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5382 offset = next_offset)
5384 Dwarf_Off die_offset = offset + header_size;
5386 if (!dwarf_offdie(const_cast<Dwarf*>(dwarf_debug_info()),
5390 imported_unit_points_type& imported_units =
5391 tu_die_imported_unit_points_map(source)[die_offset] =
5393 build_die_parent_relations_under(&cu, source, imported_units);
5398 source = TYPE_UNIT_DIE_SOURCE;
5401 uint64_t type_signature = 0;
5402 Dwarf_Off type_offset;
5403 for (Dwarf_Off offset = 0, next_offset = 0;
5404 (dwarf_next_unit(const_cast<Dwarf*>(dwarf_debug_info()),
5405 offset, &next_offset, &header_size,
5406 NULL, NULL, &address_size, NULL,
5407 &type_signature, &type_offset) == 0);
5408 offset = next_offset)
5410 Dwarf_Off die_offset = offset + header_size;
5413 if (!dwarf_offdie_types(const_cast<Dwarf*>(dwarf_debug_info()),
5417 imported_unit_points_type& imported_units =
5418 tu_die_imported_unit_points_map(source)[die_offset] =
5420 build_die_parent_relations_under(&cu, source, imported_units);
5435 struct offset_pairs_stack_type
5441 offset_pair_set_type set_;
5444 offset_pair_vector_type vect_;
5447 offset_pair_vect_map_type redundant_types_;
5450 offset_pair_vect_map_type dependant_types_;
5452 offset_pairs_stack_type(
const reader& rdr)
5461 add(
const offset_pair_type& p)
5474 erase(
const offset_pair_type& p)
5478 offset_pair_vector_type::iterator i;
5480 for (i = vect_.begin();i < vect_.end(); ++i)
5484 if (i != vect_.end())
5501 contains(
const offset_pair_type &p)
const
5503 if (set_.find(p) == set_.end())
5527 get_pairs_that_depend_on(
const offset_pair_type& p,
5528 offset_pair_vector_type& pairs)
const
5530 bool result =
false;
5535 offset_pair_vector_type::const_iterator i;
5536 for (i = vect_.begin(); i != vect_.end(); ++i)
5540 if (i == vect_.end())
5545 for (++i; i != vect_.end(); ++i)
5547 pairs.push_back(*i);
5564 record_dependant_types(
const offset_pair_type& p,
5565 const offset_pair_vector_type& dependant_types)
5567 for (
auto type_pair : dependant_types)
5568 dependant_types_[type_pair].push_back(p);
5576 record_redundant_type_die_pair(
const offset_pair_type& p)
5578 offset_pair_vector_type dependant_types;
5579 get_pairs_that_depend_on(p, dependant_types);
5582 auto it = redundant_types_.find(p);
5583 if (it == redundant_types_.end())
5585 auto entry = std::make_pair(p, dependant_types);
5586 redundant_types_.insert(entry);
5589 it->second.insert(it->second.end(),
5590 dependant_types.begin(),
5591 dependant_types.end());
5595 record_dependant_types(p, dependant_types);
5604 is_redundant(
const offset_pair_type& p)
5606 auto i = redundant_types_.find(p);
5607 if (i != redundant_types_.end())
5618 depends_on_redundant_types(
const offset_pair_type& p)
5620 auto i = dependant_types_.find(p);
5621 if (i == dependant_types_.end())
5638 erase_redundant_type_pair_entry(
const offset_pair_type& p,
5639 bool erase_cached_results =
false)
5643 auto redundant_type = redundant_types_.find(p);
5644 if (redundant_type != redundant_types_.end())
5646 for (
auto dependant_type : redundant_type->second)
5650 auto dependant_types_it = dependant_types_.find(dependant_type);
5651 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5655 auto i = dependant_types_it->second.begin();
5656 for (; i!= dependant_types_it->second.end();++i)
5659 if (i != dependant_types_it->second.end())
5660 dependant_types_it->second.erase(i);
5665 if (dependant_types_it->second.empty())
5667 if (erase_cached_results)
5668 rdr_.die_comparison_results_.erase(dependant_type);
5669 dependant_types_.erase(dependant_types_it);
5673 if (erase_cached_results)
5674 rdr_.die_comparison_results_.erase(p);
5675 redundant_types_.erase(p);
5686 confirm_canonical_propagated_type(
const offset_pair_type& p)
5687 {erase_redundant_type_pair_entry(p,
true);}
5697 cancel_canonical_propagated_type(
const offset_pair_type& p)
5699 offset_pair_set_type dependant_types;
5700 get_dependant_types(p, dependant_types,
true);
5701 for (
auto dependant_type : dependant_types)
5705 if (rdr_.propagated_types_.find(dependant_type)
5706 != rdr_.propagated_types_.end())
5708 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5709 dependant_type.first.source_,
5711 rdr_.propagated_types_.erase(dependant_type);
5712 rdr_.cancelled_propagation_count_++;
5716 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5717 if (comp_result_it != rdr_.die_comparison_results_.end())
5718 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5722 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5723 if (comp_result_it != rdr_.die_comparison_results_.end())
5730 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5731 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5732 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5735 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5737 rdr_.erase_canonical_die_offset(p.first.offset_,
5740 rdr_.propagated_types_.erase(p);
5741 rdr_.cancelled_propagation_count_++;
5758 get_dependant_types(
const offset_pair_type& p,
5759 offset_pair_set_type& result,
5760 bool transitive_closure =
false)
5762 auto i = redundant_types_.find(p);
5763 if (i != redundant_types_.end())
5765 for (
auto dependant_type : i->second)
5766 if (result.find(dependant_type) == result.end())
5768 result.insert(dependant_type);
5769 if (transitive_closure)
5770 get_dependant_types(p, result,
true);
5779 build_ir_node_from_die(reader& rdr,
5782 bool called_from_public_decl,
5783 size_t where_offset,
5784 bool is_declaration_only =
true,
5785 bool is_required_decl_spec =
false);
5788 build_ir_node_from_die(reader& rdr,
5790 bool called_from_public_decl,
5791 size_t where_offset);
5793 static decl_base_sptr
5794 build_ir_node_for_void_type(reader& rdr);
5797 build_ir_node_for_void_pointer_type(reader& rdr);
5800 add_or_update_class_type(reader& rdr,
5805 bool called_from_public_decl,
5806 size_t where_offset,
5807 bool is_declaration_only);
5809 static union_decl_sptr
5810 add_or_update_union_type(reader& rdr,
5813 union_decl_sptr union_type,
5814 bool called_from_public_decl,
5815 size_t where_offset,
5816 bool is_declaration_only);
5818 static decl_base_sptr
5819 build_ir_node_for_void_type(reader& rdr);
5821 static decl_base_sptr
5822 build_ir_node_for_variadic_parameter_type(reader &rdr);
5825 build_function_decl(reader& rdr,
5827 size_t where_offset,
5831 function_is_suppressed(
const reader& rdr,
5832 const scope_decl* scope,
5833 Dwarf_Die *function_die,
5834 bool is_declaration_only);
5837 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5840 size_t where_offset,
5841 bool is_declaration_only,
5845 build_var_decl(reader& rdr,
5847 size_t where_offset,
5851 build_or_get_var_decl_if_not_suppressed(reader& rdr,
5854 size_t where_offset,
5856 bool is_required_decl_spec =
false);
5858 variable_is_suppressed(
const reader& rdr,
5859 const scope_decl* scope,
5860 Dwarf_Die *variable_die,
5861 bool is_required_decl_spec =
false);
5864 finish_member_function_reading(Dwarf_Die* die,
5866 const class_or_union_sptr klass,
5875 die_is_anonymous(
const Dwarf_Die* die)
5877 Dwarf_Attribute attr;
5878 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), DW_AT_name, &attr))
5892 die_is_anonymous_data_member(
const Dwarf_Die* die)
5895 || dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_member
5896 || !die_name(die).empty())
5900 if (!die_die_attribute(die, DW_AT_type, type_die))
5903 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5904 && dwarf_tag(&type_die) != DW_TAG_union_type)
5921 die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5926 Dwarf_Attribute attr;
5927 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
5930 const char* str = dwarf_formstring(&attr);
5931 return str ? str :
"";
5945 die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5950 Dwarf_Attribute attr;
5951 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
5954 const char* str = dwarf_formstring(&attr);
5974 die_unsigned_constant_attribute(
const Dwarf_Die* die,
5981 Dwarf_Attribute attr;
5982 Dwarf_Word result = 0;
5983 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
5984 || dwarf_formudata(&attr, &result))
6004 die_signed_constant_attribute(
const Dwarf_Die *die,
6011 Dwarf_Attribute attr;
6012 Dwarf_Sword result = 0;
6013 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6014 || dwarf_formsdata(&attr, &result))
6040 die_constant_attribute(
const Dwarf_Die *die,
6043 array_type_def::subrange_type::bound_value &value)
6048 if (!die_unsigned_constant_attribute(die, attr_name, l))
6050 value.set_unsigned(l);
6055 if (!die_signed_constant_attribute(die, attr_name, l))
6057 value.set_signed(l);
6072 form_is_DW_FORM_strx(
unsigned form)
6076 #if defined HAVE_DW_FORM_strx1 \
6077 && defined HAVE_DW_FORM_strx2 \
6078 && defined HAVE_DW_FORM_strx3 \
6079 && defined HAVE_DW_FORM_strx4
6080 if (form == DW_FORM_strx1
6081 || form == DW_FORM_strx2
6082 || form == DW_FORM_strx3
6083 ||form == DW_FORM_strx4)
6100 form_is_DW_FORM_line_strp(
unsigned form)
6104 #if defined HAVE_DW_FORM_line_strp
6105 if (form == DW_FORM_line_strp)
6132 die_flag_attribute(
const Dwarf_Die* die,
6135 bool recursively =
true)
6137 Dwarf_Attribute attr;
6139 ? !dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6140 : !dwarf_attr(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6144 if (dwarf_formflag(&attr, &f))
6158 die_linkage_name(
const Dwarf_Die* die)
6163 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6164 if (linkage_name.empty())
6165 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6166 return linkage_name;
6180 die_decl_file_attribute(
const Dwarf_Die* die)
6185 const char* str = dwarf_decl_file(const_cast<Dwarf_Die*>(die));
6187 return str ? str :
"";
6208 die_die_attribute(
const Dwarf_Die* die,
6213 Dwarf_Attribute attr;
6215 ? !dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr)
6216 : !dwarf_attr(const_cast<Dwarf_Die*>(die), attr_name, &attr))
6219 return dwarf_formref_die(&attr, &result);
6249 subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6251 Dwarf_Die& referenced_subrange)
6253 bool result =
false;
6255 if (dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subrange_type)
6258 Dwarf_Die referenced_die;
6259 if (die_die_attribute(die, attr_name, referenced_die))
6261 unsigned tag = dwarf_tag(&referenced_die);
6262 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6265 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6267 tag = dwarf_tag(&type_die);
6268 if (tag == DW_TAG_subrange_type)
6270 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6306 subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6308 array_type_def::subrange_type::bound_value& v,
6311 bool result =
false;
6313 if (dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subrange_type)
6316 Dwarf_Die subrange_die;
6317 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6320 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6338 die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6340 Dwarf_Attribute attr;
6341 if (!dwarf_attr_integrate(die, attr_name, &attr))
6343 return dwarf_formaddr(&attr, &result) == 0;
6354 die_location(
const reader& rdr,
const Dwarf_Die* die)
6359 string file = die_decl_file_attribute(die);
6361 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6363 if (!file.empty() && line != 0)
6366 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6378 die_name(
const Dwarf_Die* die)
6380 string name = die_string_attribute(die, DW_AT_name);
6396 die_loc_and_name(
const reader& rdr,
6400 string& linkage_name)
6402 loc = die_location(rdr, die);
6403 name = die_name(die);
6404 linkage_name = die_linkage_name(die);
6417 die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6422 uint64_t byte_size = 0, bit_size = 0;
6424 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6426 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6430 bit_size = byte_size * 8;
6453 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6460 case private_access:
6461 result = private_access;
6464 case protected_access:
6465 result = protected_access;
6469 result = public_access;
6488 die_is_public_decl(
const Dwarf_Die* die)
6492 bool is_public =
false;
6498 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6499 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6500 die_flag_attribute(die, DW_AT_external, is_public);
6501 else if (tag == DW_TAG_namespace)
6503 string name = die_name(die);
6504 is_public = !name.empty();
6518 die_is_effectively_public_decl(
const reader& rdr,
6519 const Dwarf_Die* die)
6521 if (die_is_public_decl(die))
6524 unsigned tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6525 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6528 Dwarf_Die parent_die;
6529 size_t where_offset = 0;
6530 if (!get_parent_die(rdr, die, parent_die, where_offset))
6533 tag = dwarf_tag(&parent_die);
6534 if (tag == DW_TAG_compile_unit
6535 || tag == DW_TAG_partial_unit
6536 || tag == DW_TAG_type_unit)
6540 if (tag == DW_TAG_namespace)
6542 string name = die_name(&parent_die);
6561 die_is_declaration_only(Dwarf_Die* die)
6563 bool is_declaration =
false;
6564 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6565 if (is_declaration && !die_has_size_attribute(die))
6576 die_is_function_decl(
const Dwarf_Die *die)
6581 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6582 if (tag == DW_TAG_subprogram)
6593 die_is_variable_decl(
const Dwarf_Die *die)
6598 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6599 if (tag == DW_TAG_variable)
6610 die_has_size_attribute(
const Dwarf_Die *die)
6613 if (die_size_in_bits(die, s))
6624 die_has_no_child(
const Dwarf_Die *die)
6630 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
6643 die_is_declaration_only(
const Dwarf_Die* die)
6644 {
return die_is_declaration_only(const_cast<Dwarf_Die*>(die));}
6652 die_is_artificial(Dwarf_Die* die)
6655 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6662 is_type_tag(
unsigned tag)
6664 bool result =
false;
6668 case DW_TAG_array_type:
6669 case DW_TAG_class_type:
6670 case DW_TAG_enumeration_type:
6671 case DW_TAG_pointer_type:
6672 case DW_TAG_reference_type:
6673 case DW_TAG_string_type:
6674 case DW_TAG_structure_type:
6675 case DW_TAG_subroutine_type:
6676 case DW_TAG_typedef:
6677 case DW_TAG_union_type:
6678 case DW_TAG_ptr_to_member_type:
6679 case DW_TAG_set_type:
6680 case DW_TAG_subrange_type:
6681 case DW_TAG_base_type:
6682 case DW_TAG_const_type:
6683 case DW_TAG_file_type:
6684 case DW_TAG_packed_type:
6685 case DW_TAG_thrown_type:
6686 case DW_TAG_volatile_type:
6687 case DW_TAG_restrict_type:
6688 case DW_TAG_interface_type:
6689 case DW_TAG_unspecified_type:
6690 case DW_TAG_shared_type:
6691 case DW_TAG_rvalue_reference_type:
6692 case DW_TAG_coarray_type:
6693 case DW_TAG_atomic_type:
6694 case DW_TAG_immutable_type:
6717 is_canon_type_to_be_propagated_tag(
unsigned tag)
6719 bool result =
false;
6723 case DW_TAG_class_type:
6724 case DW_TAG_structure_type:
6725 case DW_TAG_union_type:
6726 case DW_TAG_subroutine_type:
6727 case DW_TAG_subprogram:
6748 type_comparison_result_to_be_cached(
unsigned tag)
6753 case DW_TAG_class_type:
6754 case DW_TAG_structure_type:
6755 case DW_TAG_union_type:
6756 case DW_TAG_subroutine_type:
6757 case DW_TAG_subprogram:
6778 maybe_cache_type_comparison_result(
const reader& rdr,
6780 const offset_pair_type& p,
6783 if (!type_comparison_result_to_be_cached(tag)
6784 || (result != COMPARISON_RESULT_EQUAL
6785 && result != COMPARISON_RESULT_DIFFERENT))
6788 rdr.die_comparison_results_[p] = result;
6808 get_cached_type_comparison_result(
const reader& rdr,
6809 const offset_pair_type& p,
6812 auto i = rdr.die_comparison_results_.find(p);
6813 if (i != rdr.die_comparison_results_.end())
6836 maybe_get_cached_type_comparison_result(
const reader& rdr,
6838 const offset_pair_type& p,
6841 if (type_comparison_result_to_be_cached(tag))
6846 if (get_cached_type_comparison_result(rdr, p, result))
6858 is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
6860 bool result =
false;
6861 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6863 if (!is_type_tag(tag))
6868 case DW_TAG_class_type:
6869 case DW_TAG_structure_type:
6870 case DW_TAG_union_type:
6871 result = !die_is_declaration_only(die);
6874 case DW_TAG_subroutine_type:
6875 case DW_TAG_subprogram:
6876 case DW_TAG_array_type:
6892 is_decl_tag(
unsigned tag)
6896 case DW_TAG_formal_parameter:
6897 case DW_TAG_imported_declaration:
6899 case DW_TAG_unspecified_parameters:
6900 case DW_TAG_subprogram:
6901 case DW_TAG_variable:
6902 case DW_TAG_namespace:
6903 case DW_TAG_GNU_template_template_param:
6904 case DW_TAG_GNU_template_parameter_pack:
6905 case DW_TAG_GNU_formal_parameter_pack:
6917 die_is_type(
const Dwarf_Die* die)
6921 return is_type_tag(dwarf_tag(const_cast<Dwarf_Die*>(die)));
6930 die_is_decl(
const Dwarf_Die* die)
6934 return is_decl_tag(dwarf_tag(const_cast<Dwarf_Die*>(die)));
6943 die_is_namespace(
const Dwarf_Die* die)
6947 return (dwarf_tag(const_cast<Dwarf_Die*>(die)) == DW_TAG_namespace);
6956 die_is_unspecified(Dwarf_Die* die)
6960 return (dwarf_tag(die) == DW_TAG_unspecified_type);
6969 die_is_void_type(Dwarf_Die* die)
6971 if (!die || dwarf_tag(die) != DW_TAG_base_type)
6974 string name = die_name(die);
6987 die_is_pointer_type(
const Dwarf_Die* die)
6992 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
6993 if (tag == DW_TAG_pointer_type)
7007 pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7009 if (!die_is_pointer_array_or_reference_type(die)
7010 && !die_is_qualified_type(die))
7013 Dwarf_Die underlying_type_die;
7014 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7017 if (!die_is_class_type(&underlying_type_die))
7020 string name = die_name(&underlying_type_die);
7022 return name.empty();
7031 die_is_reference_type(
const Dwarf_Die* die)
7036 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7037 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7049 die_is_array_type(
const Dwarf_Die* die)
7054 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7055 if (tag == DW_TAG_array_type)
7067 die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7068 {
return (die_is_pointer_type(die)
7069 || die_is_reference_type(die)
7070 || die_is_array_type(die));}
7078 die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7079 {
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7088 die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7089 {
return (die_is_pointer_array_or_reference_type(die)
7090 || dwarf_tag(const_cast<Dwarf_Die*>(die)) == DW_TAG_typedef);}
7098 die_is_class_type(
const Dwarf_Die* die)
7100 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7102 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7114 die_is_qualified_type(
const Dwarf_Die* die)
7116 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7117 if (tag == DW_TAG_const_type
7118 || tag == DW_TAG_volatile_type
7119 || tag == DW_TAG_restrict_type)
7131 die_is_function_type(
const Dwarf_Die *die)
7133 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7134 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7152 die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7157 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7169 die_has_children(
const Dwarf_Die* die)
7175 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
7195 die_this_pointer_from_object_pointer(Dwarf_Die* die,
7196 Dwarf_Die& this_pointer_die)
7199 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7201 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7216 die_this_pointer_is_const(Dwarf_Die* die)
7220 if (dwarf_tag(die) == DW_TAG_pointer_type)
7222 Dwarf_Die pointed_to_type_die;
7223 if (die_die_attribute(die, DW_AT_type, pointed_to_type_die))
7224 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7240 die_object_pointer_is_for_const_method(Dwarf_Die* die)
7243 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7245 Dwarf_Die this_pointer_die;
7246 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7247 if (die_this_pointer_is_const(&this_pointer_die))
7269 die_is_at_class_scope(
const reader& rdr,
7270 const Dwarf_Die* die,
7271 size_t where_offset,
7272 Dwarf_Die& class_scope_die)
7274 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7277 int tag = dwarf_tag(&class_scope_die);
7279 return (tag == DW_TAG_structure_type
7280 || tag == DW_TAG_class_type
7281 || tag == DW_TAG_union_type);
7294 die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7299 int tag = dwarf_tag(die);
7301 if (tag == DW_TAG_const_type
7302 || tag == DW_TAG_volatile_type
7303 || tag == DW_TAG_restrict_type
7304 || tag == DW_TAG_pointer_type
7305 || tag == DW_TAG_reference_type
7306 || tag == DW_TAG_rvalue_reference_type)
7308 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7314 memcpy(&peeled_die, die,
sizeof(peeled_die));
7316 while (tag == DW_TAG_const_type
7317 || tag == DW_TAG_volatile_type
7318 || tag == DW_TAG_restrict_type
7319 || tag == DW_TAG_pointer_type
7320 || tag == DW_TAG_reference_type
7321 || tag == DW_TAG_rvalue_reference_type)
7323 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7325 tag = dwarf_tag(&peeled_die);
7340 die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7345 memcpy(&peeled_die, die,
sizeof(peeled_die));
7347 int tag = dwarf_tag(&peeled_die);
7349 bool result =
false;
7350 while (tag == DW_TAG_const_type
7351 || tag == DW_TAG_volatile_type
7352 || tag == DW_TAG_restrict_type)
7354 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7356 tag = dwarf_tag(&peeled_die);
7372 die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
7377 int tag = dwarf_tag(die);
7379 memcpy(&peeled_die, die,
sizeof(peeled_die));
7381 if (tag == DW_TAG_typedef)
7383 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7389 while (tag == DW_TAG_typedef)
7391 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7393 tag = dwarf_tag(&peeled_die);
7409 die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
7414 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7416 if (tag == DW_TAG_pointer_type
7417 || tag == DW_TAG_reference_type
7418 || tag == DW_TAG_rvalue_reference_type
7419 || tag == DW_TAG_typedef)
7421 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7427 while (tag == DW_TAG_pointer_type
7428 || tag == DW_TAG_reference_type
7429 || tag == DW_TAG_rvalue_reference_type
7430 || tag == DW_TAG_typedef)
7432 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7434 tag = dwarf_tag(&peeled_die);
7462 die_function_type_is_method_type(
const reader& rdr,
7463 const Dwarf_Die *die,
7464 size_t where_offset,
7465 Dwarf_Die& object_pointer_die,
7466 Dwarf_Die& class_die,
7472 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
7473 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7475 bool has_object_pointer =
false;
7477 if (tag == DW_TAG_subprogram)
7479 Dwarf_Die spec_or_origin_die;
7480 if (die_die_attribute(die, DW_AT_specification,
7482 || die_die_attribute(die, DW_AT_abstract_origin,
7483 spec_or_origin_die))
7485 if (die_has_object_pointer(&spec_or_origin_die,
7486 object_pointer_die))
7487 has_object_pointer =
true;
7490 if (die_is_at_class_scope(rdr, &spec_or_origin_die,
7491 where_offset, class_die))
7499 if (die_has_object_pointer(die, object_pointer_die))
7500 has_object_pointer =
true;
7503 if (die_is_at_class_scope(rdr, die, where_offset, class_die))
7512 if (die_has_object_pointer(die, object_pointer_die))
7513 has_object_pointer =
true;
7524 Dwarf_Die this_type_die;
7525 if (!die_die_attribute(&object_pointer_die, DW_AT_type, this_type_die))
7530 if (!die_peel_qual_ptr(&this_type_die, class_die))
7535 die_peel_typedef(&class_die, class_die);
7543 VIRTUALITY_NOT_VIRTUAL,
7545 VIRTUALITY_PURE_VIRTUAL
7558 die_virtuality(
const Dwarf_Die* die, virtuality& virt)
7564 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
7566 if (v == DW_VIRTUALITY_virtual)
7567 virt = VIRTUALITY_VIRTUAL;
7568 else if (v == DW_VIRTUALITY_pure_virtual)
7569 virt = VIRTUALITY_PURE_VIRTUAL;
7571 virt = VIRTUALITY_NOT_VIRTUAL;
7583 die_is_virtual(
const Dwarf_Die* die)
7586 if (!die_virtuality(die, v))
7589 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
7599 die_is_declared_inline(Dwarf_Die* die)
7601 uint64_t inline_value = 0;
7602 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
7604 return inline_value == DW_INL_declared_inlined;
7619 slowly_compare_strings(
const Dwarf_Die *l,
7623 const char *l_str = die_char_str_attribute(l, attr_name),
7624 *r_str = die_char_str_attribute(r, attr_name);
7625 if (!l_str && !r_str)
7627 return l_str && r_str && !strcmp(l_str, r_str);
7653 compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
7657 Dwarf_Attribute l_attr, r_attr;
7658 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(l), attr_name, &l_attr)
7659 || !dwarf_attr_integrate(const_cast<Dwarf_Die*>(r), attr_name, &r_attr))
7663 || l_attr.form == DW_FORM_string
7664 || l_attr.form == DW_FORM_GNU_strp_alt
7665 || form_is_DW_FORM_strx(l_attr.form)
7666 || form_is_DW_FORM_line_strp(l_attr.form));
7669 || r_attr.form == DW_FORM_string
7670 || r_attr.form == DW_FORM_GNU_strp_alt
7671 || form_is_DW_FORM_strx(r_attr.form)
7672 || form_is_DW_FORM_line_strp(r_attr.form));
7674 if ((l_attr.form == DW_FORM_strp
7675 && r_attr.form == DW_FORM_strp)
7676 || (l_attr.form == DW_FORM_GNU_strp_alt
7677 && r_attr.form == DW_FORM_GNU_strp_alt)
7678 || (form_is_DW_FORM_strx(l_attr.form)
7679 && form_is_DW_FORM_strx(r_attr.form))
7680 || (form_is_DW_FORM_line_strp(l_attr.form)
7681 && form_is_DW_FORM_line_strp(r_attr.form)))
7688 if (l_attr.valp == r_attr.valp)
7690 #if WITH_DEBUG_TYPE_CANONICALIZATION
7691 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
7702 result = slowly_compare_strings(l, r, attr_name);
7720 compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
7722 Dwarf_Die l_cu, r_cu;
7723 if (!dwarf_diecu(const_cast<Dwarf_Die*>(l), &l_cu, 0, 0)
7724 ||!dwarf_diecu(const_cast<Dwarf_Die*>(r), &r_cu, 0, 0))
7728 compare_dies_string_attribute_value(&l_cu, &r_cu,
7731 if (compared && result)
7733 Dwarf_Die peeled_l, peeled_r;
7734 if (die_is_pointer_reference_or_typedef_type(l)
7735 && die_is_pointer_reference_or_typedef_type(r)
7736 && die_peel_pointer_and_typedef(l, peeled_l)
7737 && die_peel_pointer_and_typedef(r, peeled_r))
7739 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
7740 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
7743 compare_dies_string_attribute_value(&l_cu, &r_cu,
7774 die_location_expr(
const Dwarf_Die* die,
7782 Dwarf_Attribute attr;
7783 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), attr_name, &attr))
7787 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
7822 op_pushes_constant_value(Dwarf_Op* ops,
7826 dwarf_expr_eval_context& ctxt)
7830 Dwarf_Op& op = ops[index];
7836 value = ops[index].number;
7849 value = ops[index].number;
7953 expr_result r(value);
7956 next_index = index + 1;
7986 op_pushes_non_constant_value(Dwarf_Op* ops,
7990 dwarf_expr_eval_context& ctxt)
7993 Dwarf_Op& op = ops[index];
8029 next_index = index + 1;
8064 next_index = index + 1;
8068 next_index = index + 2;
8072 next_index = index + 1;
8076 next_index = index + 1;
8079 case DW_OP_GNU_variable_value:
8080 next_index = index + 1;
8087 expr_result r(
false);
8116 op_manipulates_stack(Dwarf_Op* expr,
8120 dwarf_expr_eval_context& ctxt)
8122 Dwarf_Op& op = expr[index];
8128 v = ctxt.stack.front();
8133 v = ctxt.stack.front();
8152 ctxt.stack.erase(ctxt.stack.begin() + 1);
8159 ctxt.stack.erase(ctxt.stack.begin() + 2);
8164 case DW_OP_deref_size:
8172 case DW_OP_xderef_size:
8180 case DW_OP_push_object_address:
8185 case DW_OP_form_tls_address:
8186 case DW_OP_GNU_push_tls_address:
8189 if (op.atom == DW_OP_form_tls_address)
8194 case DW_OP_call_frame_cfa:
8206 if (op.atom == DW_OP_form_tls_address
8207 || op.atom == DW_OP_GNU_push_tls_address)
8208 ctxt.set_tls_address(
true);
8210 ctxt.set_tls_address(
false);
8212 next_index = index + 1;
8240 op_is_arith_logic(Dwarf_Op* expr,
8244 dwarf_expr_eval_context& ctxt)
8248 Dwarf_Op& op = expr[index];
8249 expr_result val1, val2;
8250 bool result =
false;
8266 ctxt.push(val1 & val2);
8273 if (!val1.is_const())
8275 ctxt.push(val2 / val1);
8283 ctxt.push(val2 - val1);
8291 ctxt.push(val2 % val1);
8299 ctxt.push(val2 * val1);
8321 ctxt.push(val1 | val2);
8329 ctxt.push(val2 + val1);
8333 case DW_OP_plus_uconst:
8345 ctxt.push(val2 << val1);
8354 ctxt.push(val2 >> val1);
8362 ctxt.push(val2 ^ val1);
8372 if (ctxt.stack.front().is_const())
8373 ctxt.accum = ctxt.stack.front();
8375 next_index = index + 1;
8403 op_is_control_flow(Dwarf_Op* expr,
8407 dwarf_expr_eval_context& ctxt)
8411 Dwarf_Op& op = expr[index];
8412 expr_result val1, val2;
8426 if (op.atom == DW_OP_eq)
8427 value = val2 == val1;
8428 else if (op.atom == DW_OP_ge)
8429 value = val2 >= val1;
8430 else if (op.atom == DW_OP_gt)
8431 value = val2 > val1;
8432 else if (op.atom == DW_OP_le)
8433 value = val2 <= val1;
8434 else if (op.atom == DW_OP_lt)
8435 value = val2 < val1;
8436 else if (op.atom == DW_OP_ne)
8437 value = val2 != val1;
8439 val1 = value ? 1 : 0;
8446 index += op.number - 1;
8451 if (val1.const_value() != 0)
8452 index += val1.const_value() - 1;
8457 case DW_OP_call_ref:
8465 if (ctxt.stack.front().is_const())
8466 ctxt.accum = ctxt.stack.front();
8468 next_index = index + 1;
8489 eval_quickly(Dwarf_Op* expr,
8493 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
8495 value = expr[0].number;
8522 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8525 bool& is_tls_address,
8526 dwarf_expr_eval_context &eval_ctxt)
8532 size_t index = 0, next_index = 0;
8535 if (op_is_arith_logic(expr, expr_len, index,
8536 next_index, eval_ctxt)
8537 || op_pushes_constant_value(expr, expr_len, index,
8538 next_index, eval_ctxt)
8539 || op_manipulates_stack(expr, expr_len, index,
8540 next_index, eval_ctxt)
8541 || op_pushes_non_constant_value(expr, expr_len, index,
8542 next_index, eval_ctxt)
8543 || op_is_control_flow(expr, expr_len, index,
8544 next_index, eval_ctxt))
8547 next_index = index + 1;
8551 }
while (index < expr_len);
8553 is_tls_address = eval_ctxt.set_tls_address();
8554 if (eval_ctxt.accum.is_const())
8556 value = eval_ctxt.accum;
8576 eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8579 bool& is_tls_address)
8581 dwarf_expr_eval_context eval_ctxt;
8582 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
8583 is_tls_address, eval_ctxt);
8775 read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
8780 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
8793 uint64_t containing_anonymous_object_size = 0;
8794 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
8795 containing_anonymous_object_size));
8796 containing_anonymous_object_size *= 8;
8798 uint64_t bitfield_size = 0;
8799 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
8810 offset = containing_anonymous_object_size - off - bitfield_size;
8826 die_constant_data_member_location(
const Dwarf_Die *die,
8832 Dwarf_Attribute attr;
8833 if (!dwarf_attr(const_cast<Dwarf_Die*>(die),
8834 DW_AT_data_member_location,
8839 if (dwarf_formudata(&attr, &val) != 0)
8895 die_member_offset(
const reader& rdr,
8896 const Dwarf_Die* die,
8899 Dwarf_Op* expr = NULL;
8900 size_t expr_len = 0;
8901 uint64_t bit_offset = 0;
8905 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
8907 offset = bit_offset;
8919 if (!die_constant_data_member_location(die, offset))
8924 if (!die_location_expr(die, DW_AT_data_member_location,
8931 if (!eval_quickly(expr, expr_len, offset))
8933 bool is_tls_address =
false;
8934 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
8935 offset, is_tls_address,
8936 rdr.dwarf_expr_eval_ctxt()))
8953 bool is_big_endian = architecture_is_big_endian(rdr.elf_handle());
8954 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
8955 offset += bit_offset;
8972 die_location_address(Dwarf_Die* die,
8973 Dwarf_Addr& address,
8974 bool& is_tls_address)
8976 Dwarf_Op* expr = NULL;
8977 size_t expr_len = 0;
8979 is_tls_address =
false;
8984 Dwarf_Attribute attr;
8985 if (!dwarf_attr_integrate(const_cast<Dwarf_Die*>(die), DW_AT_location, &attr))
8988 if (dwarf_getlocation(&attr, &expr, &expr_len))
8995 Dwarf_Attribute result;
8996 if (!dwarf_getlocation_attr(&attr, expr, &result))
8998 return !dwarf_formaddr(&result, &address);
9001 address = expr->number;
9016 die_virtual_function_index(Dwarf_Die* die,
9022 Dwarf_Op* expr = NULL;
9023 size_t expr_len = 0;
9024 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9029 bool is_tls_addr =
false;
9030 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9048 int tag = dwarf_tag(die);
9050 if (tag == DW_TAG_class_type
9051 || tag == DW_TAG_structure_type
9052 || tag == DW_TAG_union_type
9053 || tag == DW_TAG_enumeration_type)
9054 return die_is_anonymous(die);
9076 get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9079 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9081 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
9083 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9085 else if (tag == DW_TAG_union_type)
9087 else if (tag == DW_TAG_enumeration_type)
9106 build_internal_anonymous_die_name(
const string &
base_name,
9107 size_t anonymous_type_index)
9110 if (anonymous_type_index && !base_name.empty())
9112 std::ostringstream o;
9113 o << base_name << anonymous_type_index;
9132 get_internal_anonymous_die_name(Dwarf_Die *die,
9133 size_t anonymous_type_index)
9135 string name = get_internal_anonymous_die_prefix_name(die);
9136 name = build_internal_anonymous_die_name(name, anonymous_type_index);
9158 die_qualified_type_name(
const reader& rdr,
9159 const Dwarf_Die* die,
9160 size_t where_offset)
9165 int tag = dwarf_tag (const_cast<Dwarf_Die*>(die));
9166 if (tag == DW_TAG_compile_unit
9167 || tag == DW_TAG_partial_unit
9168 || tag == DW_TAG_type_unit)
9171 string name = die_name(die);
9173 Dwarf_Die scope_die;
9174 if (!get_scope_die(rdr, die, where_offset, scope_die))
9177 string parent_name = die_qualified_name(rdr, &scope_die, where_offset);
9178 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9179 string separator = colon_colon ?
"::" :
".";
9185 case DW_TAG_unspecified_type:
9188 case DW_TAG_base_type:
9198 case DW_TAG_typedef:
9199 case DW_TAG_enumeration_type:
9200 case DW_TAG_structure_type:
9201 case DW_TAG_class_type:
9202 case DW_TAG_union_type:
9210 name = get_internal_anonymous_die_prefix_name(die);
9213 repr = parent_name.empty() ? name : parent_name + separator + name;
9217 case DW_TAG_const_type:
9218 case DW_TAG_volatile_type:
9219 case DW_TAG_restrict_type:
9221 Dwarf_Die underlying_type_die;
9222 bool has_underlying_type_die =
9223 die_die_attribute(die, DW_AT_type, underlying_type_die);
9225 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9228 if (tag == DW_TAG_const_type)
9230 if (has_underlying_type_die
9231 && die_is_reference_type(&underlying_type_die))
9241 else if (!has_underlying_type_die
9242 || die_is_void_type(&underlying_type_die))
9250 else if (tag == DW_TAG_volatile_type)
9252 else if (tag == DW_TAG_restrict_type)
9257 string underlying_type_repr;
9258 if (has_underlying_type_die)
9259 underlying_type_repr =
9260 die_qualified_type_name(rdr, &underlying_type_die, where_offset);
9262 underlying_type_repr =
"void";
9264 if (underlying_type_repr.empty())
9268 if (has_underlying_type_die)
9271 die_peel_qualified(&underlying_type_die, peeled);
9272 if (die_is_pointer_or_reference_type(&peeled))
9273 repr = underlying_type_repr +
" " + repr;
9275 repr +=
" " + underlying_type_repr;
9278 repr +=
" " + underlying_type_repr;
9283 case DW_TAG_pointer_type:
9284 case DW_TAG_reference_type:
9285 case DW_TAG_rvalue_reference_type:
9287 Dwarf_Die pointed_to_type_die;
9288 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9290 if (tag == DW_TAG_pointer_type)
9295 if (die_is_unspecified(&pointed_to_type_die))
9298 string pointed_type_repr =
9299 die_qualified_type_name(rdr, &pointed_to_type_die, where_offset);
9301 repr = pointed_type_repr;
9305 if (tag == DW_TAG_pointer_type)
9307 else if (tag == DW_TAG_reference_type)
9309 else if (tag == DW_TAG_rvalue_reference_type)
9316 case DW_TAG_subrange_type:
9329 build_subrange_type(const_cast<reader&>(rdr),
9332 repr += s->as_string();
9336 case DW_TAG_array_type:
9338 Dwarf_Die element_type_die;
9339 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9341 string element_type_name =
9342 die_qualified_type_name(rdr, &element_type_die, where_offset);
9343 if (element_type_name.empty())
9347 build_subranges_from_array_type_die(const_cast<reader&>(rdr),
9348 die, subranges, where_offset,
9351 repr = element_type_name;
9352 repr += array_type_def::subrange_type::vector_as_string(subranges);
9356 case DW_TAG_subroutine_type:
9357 case DW_TAG_subprogram:
9359 string return_type_name;
9361 vector<string> parm_names;
9362 bool is_const =
false;
9363 bool is_static =
false;
9365 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9367 return_type_name, class_name,
9368 parm_names, is_const,
9370 if (return_type_name.empty())
9371 return_type_name =
"void";
9373 repr = return_type_name;
9375 if (!class_name.empty())
9378 repr +=
" (" + class_name +
"::*)";
9383 for (vector<string>::const_iterator i = parm_names.begin();
9384 i != parm_names.end();
9387 if (i != parm_names.begin())
9396 case DW_TAG_string_type:
9397 case DW_TAG_ptr_to_member_type:
9398 case DW_TAG_set_type:
9399 case DW_TAG_file_type:
9400 case DW_TAG_packed_type:
9401 case DW_TAG_thrown_type:
9402 case DW_TAG_interface_type:
9403 case DW_TAG_shared_type:
9423 die_qualified_decl_name(
const reader& rdr,
9424 const Dwarf_Die* die,
9425 size_t where_offset)
9427 if (!die || !die_is_decl(die))
9430 string name = die_name(die);
9432 Dwarf_Die scope_die;
9433 if (!get_scope_die(rdr, die, where_offset, scope_die))
9436 string scope_name = die_qualified_name(rdr, &scope_die, where_offset);
9437 string separator =
"::";
9441 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
9444 case DW_TAG_namespace:
9446 case DW_TAG_variable:
9447 repr = scope_name.empty() ? name : scope_name + separator + name;
9449 case DW_TAG_subprogram:
9450 repr = die_function_signature(rdr, die, where_offset);
9453 case DW_TAG_unspecified_parameters:
9457 case DW_TAG_formal_parameter:
9458 case DW_TAG_imported_declaration:
9459 case DW_TAG_GNU_template_template_param:
9460 case DW_TAG_GNU_template_parameter_pack:
9461 case DW_TAG_GNU_formal_parameter_pack:
9484 die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
9486 if (die_is_type(die))
9487 return die_qualified_type_name(rdr, die, where);
9488 else if (die_is_decl(die))
9489 return die_qualified_decl_name(rdr, die, where);
9511 die_qualified_type_name_empty(
const reader& rdr,
9512 const Dwarf_Die* die,
9513 size_t where,
string &qualified_name)
9518 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
9521 if (tag == DW_TAG_typedef
9522 || tag == DW_TAG_pointer_type
9523 || tag == DW_TAG_reference_type
9524 || tag == DW_TAG_rvalue_reference_type
9525 || tag == DW_TAG_array_type
9526 || tag == DW_TAG_const_type
9527 || tag == DW_TAG_volatile_type
9528 || tag == DW_TAG_restrict_type)
9530 Dwarf_Die underlying_type_die;
9531 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
9534 die_qualified_type_name(rdr, &underlying_type_die, where);
9541 string name = die_qualified_type_name(rdr, die, where);
9546 qname = die_qualified_type_name(rdr, die, where);
9550 qualified_name = qname;
9590 die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
9591 const Dwarf_Die* die,
9592 size_t where_offset,
9594 string &return_type_name,
9596 vector<string>& parm_names,
9601 Dwarf_Die ret_type_die;
9602 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
9603 return_type_name =
"void";
9607 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset)
9608 : rdr.get_die_qualified_type_name(&ret_type_die, where_offset);
9610 if (return_type_name.empty())
9611 return_type_name =
"void";
9613 Dwarf_Die object_pointer_die, class_die;
9615 die_function_type_is_method_type(rdr, die, where_offset,
9617 class_die, is_static);
9622 class_name = rdr.get_die_qualified_type_name(&class_die, where_offset);
9624 Dwarf_Die this_pointer_die;
9625 Dwarf_Die pointed_to_die;
9627 && die_die_attribute(&object_pointer_die, DW_AT_type,
9629 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
9630 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
9633 string fn_name = die_name(die);
9634 string non_qualified_class_name = die_name(&class_die);
9635 bool is_ctor = fn_name == non_qualified_class_name;
9636 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
9638 if (is_ctor || is_dtor)
9639 return_type_name.clear();
9642 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
9645 int child_tag = dwarf_tag(&child);
9646 if (child_tag == DW_TAG_formal_parameter)
9648 Dwarf_Die parm_type_die;
9649 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
9651 string qualified_name =
9653 ? rdr.get_die_pretty_representation(&parm_type_die, where_offset)
9654 : rdr.get_die_qualified_type_name(&parm_type_die, where_offset);
9656 if (qualified_name.empty())
9658 parm_names.push_back(qualified_name);
9660 else if (child_tag == DW_TAG_unspecified_parameters)
9663 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
9673 while (dwarf_siblingof(&child, &child) == 0);
9675 if (class_name.empty())
9677 Dwarf_Die parent_die;
9678 if (get_parent_die(rdr, die, parent_die, where_offset))
9680 if (die_is_class_type(&parent_die))
9682 rdr.get_die_qualified_type_name(&parent_die, where_offset);
9699 die_function_signature(
const reader& rdr,
9700 const Dwarf_Die *fn_die,
9701 size_t where_offset)
9705 bool has_lang =
false;
9706 if ((has_lang = rdr.get_die_language(fn_die, lang)))
9714 string fn_name = die_linkage_name(fn_die);
9715 if (fn_name.empty())
9716 fn_name = die_name(fn_die);
9726 string return_type_name;
9727 Dwarf_Die ret_type_die;
9728 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
9729 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
9732 if (return_type_name.empty())
9733 return_type_name =
"void";
9735 Dwarf_Die scope_die;
9737 if (get_scope_die(rdr, fn_die, where_offset, scope_die))
9738 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset);
9739 string fn_name = die_name(fn_die);
9740 if (!scope_name.empty())
9741 fn_name = scope_name +
"::" + fn_name;
9744 vector<string> parm_names;
9745 bool is_const =
false;
9746 bool is_static =
false;
9748 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
9750 return_type_name, class_name,
9751 parm_names, is_const, is_static);
9753 bool is_virtual = die_is_virtual(fn_die);
9755 string repr = class_name.empty() ?
"function" :
"method";
9759 if (!return_type_name.empty())
9760 repr +=
" " + return_type_name;
9762 repr +=
" " + fn_name;
9766 bool some_parm_emitted =
false;
9767 for (vector<string>::const_iterator i = parm_names.begin();
9768 i != parm_names.end();
9771 if (i != parm_names.begin())
9773 if (some_parm_emitted)
9777 if (!is_static && !class_name.empty())
9782 some_parm_emitted =
true;
9813 die_pretty_print_type(reader& rdr,
9814 const Dwarf_Die* die,
9815 size_t where_offset)
9818 || (!die_is_type(die)
9819 && dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_subprogram))
9824 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
9827 case DW_TAG_string_type:
9836 repr =
"string type";
9838 case DW_TAG_unspecified_type:
9839 case DW_TAG_ptr_to_member_type:
9842 case DW_TAG_namespace:
9843 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset);
9846 case DW_TAG_base_type:
9847 repr = rdr.get_die_qualified_type_name(die, where_offset);
9850 case DW_TAG_typedef:
9852 string qualified_name;
9853 if (!die_qualified_type_name_empty(rdr, die,
9856 repr =
"typedef " + qualified_name;
9860 case DW_TAG_const_type:
9861 case DW_TAG_volatile_type:
9862 case DW_TAG_restrict_type:
9863 case DW_TAG_pointer_type:
9864 case DW_TAG_reference_type:
9865 case DW_TAG_rvalue_reference_type:
9866 repr = rdr.get_die_qualified_type_name(die, where_offset);
9869 case DW_TAG_enumeration_type:
9871 string qualified_name =
9872 rdr.get_die_qualified_type_name(die, where_offset);
9873 repr =
"enum " + qualified_name;
9877 case DW_TAG_structure_type:
9878 case DW_TAG_class_type:
9880 string qualified_name =
9881 rdr.get_die_qualified_type_name(die, where_offset);
9882 repr =
"class " + qualified_name;
9886 case DW_TAG_union_type:
9888 string qualified_name =
9889 rdr.get_die_qualified_type_name(die, where_offset);
9890 repr =
"union " + qualified_name;
9894 case DW_TAG_array_type:
9896 Dwarf_Die element_type_die;
9897 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9899 string element_type_name =
9900 rdr.get_die_qualified_type_name(&element_type_die, where_offset);
9901 if (element_type_name.empty())
9905 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
9908 repr = element_type_name;
9909 repr += array_type_def::subrange_type::vector_as_string(subranges);
9913 case DW_TAG_subrange_type:
9923 repr += die_qualified_type_name(rdr, die, where_offset);
9927 case DW_TAG_subroutine_type:
9928 case DW_TAG_subprogram:
9930 string return_type_name;
9932 vector<string> parm_names;
9933 bool is_const =
false;
9934 bool is_static =
false;
9936 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9938 return_type_name, class_name,
9939 parm_names, is_const,
9941 if (class_name.empty())
9942 repr =
"function type";
9944 repr =
"method type";
9945 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset);
9949 case DW_TAG_set_type:
9950 case DW_TAG_file_type:
9951 case DW_TAG_packed_type:
9952 case DW_TAG_thrown_type:
9953 case DW_TAG_interface_type:
9954 case DW_TAG_shared_type:
9980 die_pretty_print_decl(reader& rdr,
9981 const Dwarf_Die* die,
9982 size_t where_offset)
9984 if (!die || !die_is_decl(die))
9989 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
9992 case DW_TAG_namespace:
9993 repr =
"namespace " + die_qualified_name(rdr, die, where_offset);
9997 case DW_TAG_variable:
9999 string type_repr =
"void";
10000 Dwarf_Die type_die;
10001 if (die_die_attribute(die, DW_AT_type, type_die))
10002 type_repr = die_qualified_type_name(rdr, &type_die, where_offset);
10003 repr = die_qualified_name(rdr, die, where_offset);
10005 repr = type_repr +
" " + repr;
10009 case DW_TAG_subprogram:
10010 repr = die_function_signature(rdr, die, where_offset);
10036 die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset)
10038 if (die_is_type(die))
10039 return die_pretty_print_type(rdr, die, where_offset);
10040 else if (die_is_decl(die))
10041 return die_pretty_print_decl(rdr, die, where_offset);
10064 compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
10068 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
10069 int r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
10070 if (l_tag != r_tag)
10073 bool result =
false;
10075 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
10078 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
10080 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
10087 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10097 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10114 at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
10115 const Dwarf_Die *l,
10116 const Dwarf_Die *r)
10118 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
10121 if ((die_is_declaration_only(l) && die_has_no_child(l))
10122 || (die_is_declaration_only(r) && die_has_no_child(r)))
10149 compare_as_type_dies(
const reader& rdr,
10150 const Dwarf_Die *l,
10151 const Dwarf_Die *r)
10157 if (dwarf_tag(const_cast<Dwarf_Die*>(l)) == DW_TAG_string_type
10158 && dwarf_tag(const_cast<Dwarf_Die*>(r)) == DW_TAG_string_type
10159 && (dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
10160 != dwarf_dieoffset(const_cast<Dwarf_Die*>(r))))
10168 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10173 uint64_t l_size = 0, r_size = 0;
10174 die_size_in_bits(l, l_size);
10175 die_size_in_bits(r, r_size);
10177 return l_size == r_size;
10192 compare_as_decl_and_type_dies(
const reader &rdr,
10193 const Dwarf_Die *l,
10194 const Dwarf_Die *r)
10196 if (!compare_as_decl_dies(l, r)
10197 || !compare_as_type_dies(rdr, l, r))
10221 fn_die_equal_by_linkage_name(
const reader &rdr,
10222 const Dwarf_Die *l,
10223 const Dwarf_Die *r)
10231 int tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
10233 tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
10236 string lname = die_name(l), rname = die_name(r);
10237 string llinkage_name = die_linkage_name(l),
10238 rlinkage_name = die_linkage_name(r);
10240 if (rdr.die_is_in_c_or_cplusplus(l)
10241 && rdr.die_is_in_c_or_cplusplus(r))
10243 if (!llinkage_name.empty() && !rlinkage_name.empty())
10244 return llinkage_name == rlinkage_name;
10245 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
10248 return lname == rname;
10251 return (!llinkage_name.empty()
10252 && !rlinkage_name.empty()
10253 && llinkage_name == rlinkage_name);
10285 try_canonical_die_comparison(
const reader& rdr,
10286 Dwarf_Off l_offset, Dwarf_Off r_offset,
10288 bool& l_has_canonical_die_offset,
10289 bool& r_has_canonical_die_offset,
10290 Dwarf_Off& l_canonical_die_offset,
10291 Dwarf_Off& r_canonical_die_offset,
10294 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10295 if (rdr.debug_die_canonicalization_is_on_
10296 && !rdr.use_canonical_die_comparison_)
10301 l_has_canonical_die_offset =
10302 (l_canonical_die_offset =
10303 rdr.get_canonical_die_offset(l_offset, l_die_source,
10306 r_has_canonical_die_offset =
10307 (r_canonical_die_offset =
10308 rdr.get_canonical_die_offset(r_offset, r_die_source,
10311 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
10313 result = (l_canonical_die_offset == r_canonical_die_offset);
10320 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10333 notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
10337 #define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
10338 notify_die_comparison_failed(l, r)
10340 #define NOTIFY_DIE_COMPARISON_FAILED(l, r)
10353 #define ABG_RETURN(value) \
10356 if ((value) == COMPARISON_RESULT_DIFFERENT) \
10358 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10360 return return_comparison_result(l, r, dies_being_compared, \
10361 value, aggregates_being_compared, \
10362 update_canonical_dies_on_the_fly); \
10373 #define ABG_RETURN_FALSE \
10376 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10377 return return_comparison_result(l, r, dies_being_compared, \
10378 COMPARISON_RESULT_DIFFERENT, \
10379 aggregates_being_compared, \
10380 update_canonical_dies_on_the_fly); \
10395 #define SET_RESULT_TO_FALSE(result, l , r) \
10398 result = COMPARISON_RESULT_DIFFERENT; \
10399 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10415 #define SET_RESULT_TO(result, value, l , r) \
10418 result = (value); \
10419 if (result == COMPARISON_RESULT_DIFFERENT) \
10421 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10425 #define RETURN_IF_COMPARISON_CYCLE_DETECTED \
10428 if (aggregates_being_compared.contains(dies_being_compared)) \
10430 result = COMPARISON_RESULT_CYCLE_DETECTED; \
10431 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
10432 ABG_RETURN(result); \
10447 get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
10452 bool found_member =
false;
10453 for (found_member = (dwarf_siblingof(const_cast<Dwarf_Die*>(die),
10456 found_member = (dwarf_siblingof(member, member) == 0))
10458 int tag = dwarf_tag(member);
10459 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
10463 return found_member;
10477 get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
10482 int tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
10484 || tag == DW_TAG_union_type
10485 || tag == DW_TAG_class_type);
10487 bool found_child = (dwarf_child(const_cast<Dwarf_Die*>(die),
10493 tag = dwarf_tag(child);
10495 if (!(tag == DW_TAG_member
10496 || tag == DW_TAG_inheritance
10497 || tag == DW_TAG_subprogram))
10498 found_child = get_next_member_sibling_die(child, child);
10500 return found_child;
10523 maybe_propagate_canonical_type(
const reader& rdr,
10524 const Dwarf_Die* l,
10525 const Dwarf_Die* r)
10527 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l)),
10528 r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
10530 if (l_tag != r_tag)
10533 if (is_canon_type_to_be_propagated_tag(l_tag))
10534 propagate_canonical_type(rdr, l, r);
10552 propagate_canonical_type(
const reader& rdr,
10553 const Dwarf_Die* l,
10554 const Dwarf_Die* r)
10563 const die_source l_source = rdr.get_die_source(l);
10564 const die_source r_source = rdr.get_die_source(r);
10566 Dwarf_Off l_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(l));
10567 Dwarf_Off r_offset = dwarf_dieoffset(const_cast<Dwarf_Die*>(r));
10568 bool l_has_canonical_die_offset =
false;
10569 bool r_has_canonical_die_offset =
false;
10570 Dwarf_Off l_canonical_die_offset = 0;
10571 Dwarf_Off r_canonical_die_offset = 0;
10573 l_has_canonical_die_offset =
10574 (l_canonical_die_offset =
10575 rdr.get_canonical_die_offset(l_offset, l_source,
10578 r_has_canonical_die_offset =
10579 (r_canonical_die_offset =
10580 rdr.get_canonical_die_offset(r_offset, r_source,
10584 if (!l_has_canonical_die_offset
10585 && r_has_canonical_die_offset
10588 && l_source == r_source)
10591 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
10593 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
10594 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
10595 rdr.canonical_propagated_count_++;
10633 return_comparison_result(
const Dwarf_Die* l,
10634 const Dwarf_Die* r,
10635 const offset_pair_type& cur_dies,
10637 offset_pairs_stack_type& comparison_stack,
10638 bool do_propagate_canonical_type =
true)
10640 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l));
10642 if (result == COMPARISON_RESULT_EQUAL)
10647 if (do_propagate_canonical_type)
10650 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10656 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10669 else if (result == COMPARISON_RESULT_UNKNOWN)
10710 if (comparison_stack.is_redundant(cur_dies)
10711 && comparison_stack.vect_.back() == cur_dies)
10715 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10716 comparison_stack.confirm_canonical_propagated_type(cur_dies);
10718 result = COMPARISON_RESULT_EQUAL;
10720 else if (is_canon_type_to_be_propagated_tag(l_tag)
10721 && comparison_stack.vect_.back() == cur_dies)
10726 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
10727 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10731 else if (result == COMPARISON_RESULT_DIFFERENT)
10748 if (comparison_stack.is_redundant(cur_dies)
10749 && comparison_stack.vect_.back() == cur_dies)
10750 comparison_stack.cancel_canonical_propagated_type(cur_dies);
10758 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10759 result = COMPARISON_RESULT_UNKNOWN;
10760 else if (is_canon_type_to_be_propagated_tag(l_tag)
10761 && !comparison_stack.vect_.empty()
10762 && comparison_stack.vect_.back() == cur_dies)
10767 comparison_stack.erase(cur_dies);
10769 maybe_cache_type_comparison_result(comparison_stack.rdr_,
10770 l_tag, cur_dies, result);
10799 compare_dies(
const reader& rdr,
10800 const Dwarf_Die *l,
const Dwarf_Die *r,
10801 offset_pairs_stack_type& aggregates_being_compared,
10802 bool update_canonical_dies_on_the_fly)
10807 const die_source l_die_source = rdr.get_die_source(l);
10808 const die_source r_die_source = rdr.get_die_source(r);
10810 offset_type l_offset =
10813 dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
10816 offset_type r_offset =
10819 dwarf_dieoffset(const_cast<Dwarf_Die*>(r))
10822 offset_pair_type dies_being_compared(l_offset, r_offset);
10824 int l_tag = dwarf_tag(const_cast<Dwarf_Die*>(l)),
10825 r_tag = dwarf_tag(const_cast<Dwarf_Die*>(r));
10827 if (l_tag != r_tag)
10830 if (l_offset == r_offset)
10831 return COMPARISON_RESULT_EQUAL;
10833 if (rdr.leverage_dwarf_factorization()
10834 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
10835 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
10836 if (l_offset != r_offset)
10837 return COMPARISON_RESULT_DIFFERENT;
10840 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
10841 dies_being_compared,
10845 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
10846 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
10850 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
10852 bool canonical_compare_result =
false;
10853 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
10854 l_die_source, r_die_source,
10855 l_has_canonical_die_offset,
10856 r_has_canonical_die_offset,
10857 l_canonical_die_offset,
10858 r_canonical_die_offset,
10859 canonical_compare_result))
10863 (canonical_compare_result
10864 ? COMPARISON_RESULT_EQUAL
10865 : COMPARISON_RESULT_DIFFERENT),
10875 case DW_TAG_base_type:
10876 case DW_TAG_string_type:
10877 case DW_TAG_unspecified_type:
10878 if (!compare_as_decl_and_type_dies(rdr, l, r))
10882 case DW_TAG_typedef:
10883 case DW_TAG_pointer_type:
10884 case DW_TAG_reference_type:
10885 case DW_TAG_rvalue_reference_type:
10886 case DW_TAG_const_type:
10887 case DW_TAG_volatile_type:
10888 case DW_TAG_restrict_type:
10890 if (!compare_as_type_dies(rdr, l, r))
10896 bool from_the_same_tu =
false;
10897 if (!pointer_or_qual_die_of_anonymous_class_type(l)
10898 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
10899 && from_the_same_tu)
10916 Dwarf_Die lu_type_die, ru_type_die;
10917 bool lu_is_void, ru_is_void;
10919 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
10920 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
10922 if (lu_is_void && ru_is_void)
10923 result = COMPARISON_RESULT_EQUAL;
10924 else if (lu_is_void != ru_is_void)
10927 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
10928 aggregates_being_compared,
10929 update_canonical_dies_on_the_fly);
10933 case DW_TAG_enumeration_type:
10934 if (!compare_as_decl_and_type_dies(rdr, l, r))
10939 Dwarf_Die l_enumtor, r_enumtor;
10940 bool found_l_enumtor =
true, found_r_enumtor =
true;
10942 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10943 for (found_l_enumtor = dwarf_child(const_cast<Dwarf_Die*>(l),
10945 found_r_enumtor = dwarf_child(const_cast<Dwarf_Die*>(r),
10947 found_l_enumtor && found_r_enumtor;
10948 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
10949 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
10951 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
10952 if ( l_tag != r_tag)
10958 if (l_tag != DW_TAG_enumerator)
10961 uint64_t l_val = 0, r_val = 0;
10962 die_unsigned_constant_attribute(&l_enumtor,
10965 die_unsigned_constant_attribute(&r_enumtor,
10968 if (l_val != r_val)
10974 if (found_l_enumtor != found_r_enumtor )
10979 case DW_TAG_structure_type:
10980 case DW_TAG_union_type:
10981 case DW_TAG_class_type:
10983 RETURN_IF_COMPARISON_CYCLE_DETECTED;
10985 rdr.compare_count_++;
10987 if (!compare_as_decl_and_type_dies(rdr, l, r))
10989 else if (rdr.options().assume_odr_for_cplusplus
10990 && rdr.odr_is_relevant(l)
10991 && rdr.odr_is_relevant(r)
10992 && !die_is_anonymous(l)
10993 && !die_is_anonymous(r))
10994 result = COMPARISON_RESULT_EQUAL;
10997 aggregates_being_compared.add(dies_being_compared);
10999 Dwarf_Die l_member, r_member;
11000 bool found_l_member =
true, found_r_member =
true;
11002 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11003 for (found_l_member = get_member_child_die(l, &l_member),
11004 found_r_member = get_member_child_die(r, &r_member);
11005 found_l_member && found_r_member;
11006 found_l_member = get_next_member_sibling_die(&l_member,
11008 found_r_member = get_next_member_sibling_die(&r_member,
11011 int l_tag = dwarf_tag(&l_member),
11012 r_tag = dwarf_tag(&r_member);
11014 if (l_tag != r_tag)
11021 || l_tag == DW_TAG_variable
11022 || l_tag == DW_TAG_inheritance
11023 || l_tag == DW_TAG_subprogram);
11026 compare_dies(rdr, &l_member, &r_member,
11027 aggregates_being_compared,
11028 update_canonical_dies_on_the_fly);
11030 if (local_result == COMPARISON_RESULT_UNKNOWN)
11039 result = local_result;
11041 if (local_result == COMPARISON_RESULT_DIFFERENT)
11047 if (found_l_member != found_r_member)
11056 case DW_TAG_array_type:
11058 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11060 aggregates_being_compared.add(dies_being_compared);
11062 rdr.compare_count_++;
11064 Dwarf_Die l_child, r_child;
11065 bool found_l_child, found_r_child;
11066 for (found_l_child = dwarf_child(const_cast<Dwarf_Die*>(l),
11068 found_r_child = dwarf_child(const_cast<Dwarf_Die*>(r),
11070 found_l_child && found_r_child;
11071 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
11072 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
11074 int l_child_tag = dwarf_tag(&l_child),
11075 r_child_tag = dwarf_tag(&r_child);
11076 if (l_child_tag == DW_TAG_subrange_type
11077 || r_child_tag == DW_TAG_subrange_type)
11079 result = compare_dies(rdr, &l_child, &r_child,
11080 aggregates_being_compared,
11081 update_canonical_dies_on_the_fly);
11089 if (found_l_child != found_r_child)
11092 Dwarf_Die ltype_die, rtype_die;
11093 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
11094 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
11097 result = compare_dies(rdr, <ype_die, &rtype_die,
11098 aggregates_being_compared,
11099 update_canonical_dies_on_the_fly);
11105 case DW_TAG_subrange_type:
11107 uint64_t l_lower_bound = 0, r_lower_bound = 0,
11108 l_upper_bound = 0, r_upper_bound = 0;
11109 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
11110 l_upper_bound_set =
false, r_upper_bound_set =
false;
11112 l_lower_bound_set =
11113 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
11114 r_lower_bound_set =
11115 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
11117 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
11120 uint64_t l_count = 0;
11121 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
11123 l_upper_bound = l_lower_bound + l_count;
11124 l_upper_bound_set =
true;
11130 l_upper_bound_set =
true;
11132 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
11135 uint64_t r_count = 0;
11136 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
11138 r_upper_bound = r_lower_bound + r_count;
11139 r_upper_bound_set =
true;
11145 r_upper_bound_set =
true;
11147 if ((l_lower_bound_set != r_lower_bound_set)
11148 || (l_upper_bound_set != r_upper_bound_set)
11149 || (l_lower_bound != r_lower_bound)
11150 || (l_upper_bound != r_upper_bound))
11155 case DW_TAG_subroutine_type:
11156 case DW_TAG_subprogram:
11158 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11160 aggregates_being_compared.add(dies_being_compared);
11162 rdr.compare_count_++;
11164 if (l_tag == DW_TAG_subprogram
11165 && !fn_die_equal_by_linkage_name(rdr, l, r))
11170 else if (l_tag == DW_TAG_subprogram
11171 && rdr.die_is_in_c(l) && rdr.die_is_in_c(r)
11174 result = COMPARISON_RESULT_EQUAL;
11177 else if (!rdr.die_is_in_c(l) && !rdr.die_is_in_c(r))
11183 Dwarf_Die l_return_type, r_return_type;
11184 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
11186 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
11188 if (l_return_type_is_void != r_return_type_is_void
11189 || (!l_return_type_is_void
11190 && !compare_dies(rdr,
11191 &l_return_type, &r_return_type,
11192 aggregates_being_compared,
11193 update_canonical_dies_on_the_fly)))
11197 Dwarf_Die l_child, r_child;
11198 bool found_l_child, found_r_child;
11199 for (found_l_child = dwarf_child(const_cast<Dwarf_Die*>(l),
11201 found_r_child = dwarf_child(const_cast<Dwarf_Die*>(r),
11203 found_l_child && found_r_child;
11204 found_l_child = dwarf_siblingof(&l_child,
11206 found_r_child = dwarf_siblingof(&r_child,
11209 int l_child_tag = dwarf_tag(&l_child);
11210 int r_child_tag = dwarf_tag(&r_child);
11212 COMPARISON_RESULT_EQUAL;
11213 if (l_child_tag != r_child_tag)
11214 local_result = COMPARISON_RESULT_DIFFERENT;
11215 if (l_child_tag == DW_TAG_formal_parameter)
11217 compare_dies(rdr, &l_child, &r_child,
11218 aggregates_being_compared,
11219 update_canonical_dies_on_the_fly);
11220 if (local_result == COMPARISON_RESULT_DIFFERENT)
11222 result = local_result;
11226 if (local_result == COMPARISON_RESULT_UNKNOWN)
11237 result = local_result;
11239 if (found_l_child != found_r_child)
11249 case DW_TAG_formal_parameter:
11251 Dwarf_Die l_type, r_type;
11252 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
11253 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
11254 if (l_type_is_void != r_type_is_void)
11256 else if (!l_type_is_void)
11259 compare_dies(rdr, &l_type, &r_type,
11260 aggregates_being_compared,
11261 update_canonical_dies_on_the_fly);
11267 case DW_TAG_variable:
11268 case DW_TAG_member:
11269 if (compare_as_decl_dies(l, r))
11272 if (l_tag == DW_TAG_member)
11274 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11275 die_member_offset(rdr, l, l_offset_in_bits);
11276 die_member_offset(rdr, r, r_offset_in_bits);
11277 if (l_offset_in_bits != r_offset_in_bits)
11283 Dwarf_Die l_type, r_type;
11284 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11285 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11287 compare_dies(rdr, &l_type, &r_type,
11288 aggregates_being_compared,
11289 update_canonical_dies_on_the_fly);
11297 case DW_TAG_inheritance:
11299 Dwarf_Die l_type, r_type;
11300 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11301 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11302 result = compare_dies(rdr, &l_type, &r_type,
11303 aggregates_being_compared,
11304 update_canonical_dies_on_the_fly);
11308 uint64_t l_a = 0, r_a = 0;
11309 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
11310 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
11314 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
11315 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
11319 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11320 die_member_offset(rdr, l, l_offset_in_bits);
11321 die_member_offset(rdr, r, r_offset_in_bits);
11322 if (l_offset_in_bits != r_offset_in_bits)
11327 case DW_TAG_ptr_to_member_type:
11329 bool comp_result =
false;
11330 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
11334 Dwarf_Die l_type, r_type;
11335 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11336 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11337 result = compare_dies(rdr, &l_type, &r_type,
11338 aggregates_being_compared,
11339 update_canonical_dies_on_the_fly);
11343 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
11344 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
11345 result = compare_dies(rdr, &l_type, &r_type,
11346 aggregates_being_compared,
11347 update_canonical_dies_on_the_fly);
11353 case DW_TAG_enumerator:
11354 case DW_TAG_packed_type:
11355 case DW_TAG_set_type:
11356 case DW_TAG_file_type:
11357 case DW_TAG_thrown_type:
11358 case DW_TAG_interface_type:
11359 case DW_TAG_shared_type:
11360 case DW_TAG_compile_unit:
11361 case DW_TAG_namespace:
11362 case DW_TAG_module:
11363 case DW_TAG_constant:
11364 case DW_TAG_partial_unit:
11365 case DW_TAG_imported_unit:
11366 case DW_TAG_dwarf_procedure:
11367 case DW_TAG_imported_declaration:
11368 case DW_TAG_entry_point:
11370 case DW_TAG_lexical_block:
11371 case DW_TAG_unspecified_parameters:
11372 case DW_TAG_variant:
11373 case DW_TAG_common_block:
11374 case DW_TAG_common_inclusion:
11375 case DW_TAG_inlined_subroutine:
11376 case DW_TAG_with_stmt:
11377 case DW_TAG_access_declaration:
11378 case DW_TAG_catch_block:
11379 case DW_TAG_friend:
11380 case DW_TAG_namelist:
11381 case DW_TAG_namelist_item:
11382 case DW_TAG_template_type_parameter:
11383 case DW_TAG_template_value_parameter:
11384 case DW_TAG_try_block:
11385 case DW_TAG_variant_part:
11386 case DW_TAG_imported_module:
11387 case DW_TAG_condition:
11388 case DW_TAG_type_unit:
11389 case DW_TAG_template_alias:
11390 case DW_TAG_lo_user:
11391 case DW_TAG_MIPS_loop:
11392 case DW_TAG_format_label:
11393 case DW_TAG_function_template:
11394 case DW_TAG_class_template:
11395 case DW_TAG_GNU_BINCL:
11396 case DW_TAG_GNU_EINCL:
11397 case DW_TAG_GNU_template_template_param:
11398 case DW_TAG_GNU_template_parameter_pack:
11399 case DW_TAG_GNU_formal_parameter_pack:
11400 case DW_TAG_GNU_call_site:
11401 case DW_TAG_GNU_call_site_parameter:
11402 case DW_TAG_hi_user:
11403 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11404 if (rdr.debug_die_canonicalization_is_on_)
11431 compare_dies(
const reader& rdr,
11432 const Dwarf_Die *l,
11433 const Dwarf_Die *r,
11434 bool update_canonical_dies_on_the_fly)
11436 offset_pairs_stack_type aggregates_being_compared(rdr);
11437 return compare_dies(rdr, l, r, aggregates_being_compared,
11438 update_canonical_dies_on_the_fly);
11460 compare_dies_during_canonicalization(reader& rdr,
11461 const Dwarf_Die *l,
11462 const Dwarf_Die *r,
11463 bool update_canonical_dies_on_the_fly)
11465 #ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11466 if (rdr.debug_die_canonicalization_is_on_)
11468 bool canonical_equality =
false, structural_equality =
false;
11469 rdr.use_canonical_die_comparison_ =
false;
11470 structural_equality = compare_dies(rdr, l, r,
11472 rdr.use_canonical_die_comparison_ =
true;
11473 canonical_equality = compare_dies(rdr, l, r,
11474 update_canonical_dies_on_the_fly);
11475 if (canonical_equality != structural_equality)
11477 std::cerr <<
"structural & canonical equality different for DIEs: "
11479 <<
"l: " << dwarf_dieoffset(const_cast<Dwarf_Die*>(l))
11480 <<
", r: " << dwarf_dieoffset(const_cast<Dwarf_Die*>(r))
11483 << rdr.get_die_pretty_type_representation(l, 0)
11488 return structural_equality;
11491 return compare_dies(rdr, l, r,
11492 update_canonical_dies_on_the_fly);
11534 find_import_unit_point_between_dies(
const reader& rdr,
11535 size_t partial_unit_offset,
11536 Dwarf_Off first_die_offset,
11537 Dwarf_Off first_die_cu_offset,
11539 size_t last_die_offset,
11540 size_t& imported_point_offset)
11543 rdr.tu_die_imported_unit_points_map(source);
11545 tu_die_imported_unit_points_map_type::const_iterator iter =
11546 tu_die_imported_unit_points_map.find(first_die_cu_offset);
11548 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
11550 const imported_unit_points_type& imported_unit_points = iter->second;
11551 if (imported_unit_points.empty())
11554 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
11555 imported_unit_points_type::const_iterator e = imported_unit_points.end();
11557 find_lower_bound_in_imported_unit_points(imported_unit_points,
11561 if (last_die_offset != static_cast<size_t>(-1))
11562 find_lower_bound_in_imported_unit_points(imported_unit_points,
11566 if (e != imported_unit_points.end())
11568 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11569 if (i->imported_unit_die_off == partial_unit_offset)
11571 imported_point_offset = i->offset_of_import ;
11575 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11577 if (find_import_unit_point_between_dies(rdr,
11578 partial_unit_offset,
11579 i->imported_unit_child_off,
11580 i->imported_unit_cu_off,
11581 i->imported_unit_die_source,
11583 imported_point_offset))
11589 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11590 if (i->imported_unit_die_off == partial_unit_offset)
11592 imported_point_offset = i->offset_of_import ;
11596 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11598 if (find_import_unit_point_between_dies(rdr,
11599 partial_unit_offset,
11600 i->imported_unit_child_off,
11601 i->imported_unit_cu_off,
11602 i->imported_unit_die_source,
11604 imported_point_offset))
11637 find_import_unit_point_before_die(
const reader& rdr,
11638 size_t partial_unit_offset,
11639 size_t where_offset,
11640 size_t& imported_point_offset)
11642 size_t import_point_offset = 0;
11643 Dwarf_Die first_die_of_tu;
11645 if (dwarf_child(const_cast<Dwarf_Die*>(rdr.cur_tu_die()),
11646 &first_die_of_tu) != 0)
11649 Dwarf_Die cu_die_memory;
11652 cu_die = dwarf_diecu(const_cast<Dwarf_Die*>(&first_die_of_tu),
11653 &cu_die_memory, 0, 0);
11655 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
11656 dwarf_dieoffset(&first_die_of_tu),
11657 dwarf_dieoffset(cu_die),
11658 PRIMARY_DEBUG_INFO_DIE_SOURCE,
11660 import_point_offset))
11662 imported_point_offset = import_point_offset;
11666 if (import_point_offset)
11668 imported_point_offset = import_point_offset;
11696 get_parent_die(
const reader& rdr,
11697 const Dwarf_Die* die,
11698 Dwarf_Die& parent_die,
11699 size_t where_offset)
11703 const die_source source = rdr.get_die_source(die);
11705 const offset_offset_map_type& m = rdr.die_parent_map(source);
11706 offset_offset_map_type::const_iterator i =
11707 m.find(dwarf_dieoffset(const_cast<Dwarf_Die*>(die)));
11714 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
11715 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(rdr.dwarf_debug_info()),
11716 i->second, &parent_die));
11718 case ALT_DEBUG_INFO_DIE_SOURCE:
11719 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(rdr.alternate_dwarf_debug_info()),
11720 i->second, &parent_die));
11722 case TYPE_UNIT_DIE_SOURCE:
11723 ABG_ASSERT(dwarf_offdie_types(const_cast<Dwarf*>(rdr.dwarf_debug_info()),
11724 i->second, &parent_die));
11726 case NO_DEBUG_INFO_DIE_SOURCE:
11727 case NUMBER_OF_DIE_SOURCES:
11731 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
11733 if (where_offset == 0)
11735 parent_die = *rdr.cur_tu_die();
11738 size_t import_point_offset = 0;
11740 find_import_unit_point_before_die(rdr,
11741 dwarf_dieoffset(&parent_die),
11743 import_point_offset);
11749 parent_die = *rdr.cur_tu_die();
11753 Dwarf_Die import_point_die;
11754 ABG_ASSERT(dwarf_offdie(const_cast<Dwarf*>(rdr.dwarf_debug_info()),
11755 import_point_offset,
11756 &import_point_die));
11757 return get_parent_die(rdr, &import_point_die,
11758 parent_die, where_offset);
11785 get_scope_die(
const reader& rdr,
11786 const Dwarf_Die* die,
11787 size_t where_offset,
11788 Dwarf_Die& scope_die)
11792 ABG_ASSERT(dwarf_tag(const_cast<Dwarf_Die*>(die)) != DW_TAG_member);
11793 return dwarf_diecu(const_cast<Dwarf_Die*>(die), &scope_die, 0, 0);
11796 Dwarf_Die logical_parent_die;
11797 if (die_die_attribute(die, DW_AT_specification,
11798 logical_parent_die,
false)
11799 || die_die_attribute(die, DW_AT_abstract_origin,
11800 logical_parent_die,
false))
11801 return get_scope_die(rdr, &logical_parent_die, where_offset, scope_die);
11803 if (!get_parent_die(rdr, die, scope_die, where_offset))
11806 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
11807 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
11808 || dwarf_tag(&scope_die) == DW_TAG_array_type)
11809 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
11836 get_scope_for_die(reader& rdr,
11838 bool called_for_public_decl,
11839 size_t where_offset)
11841 const die_source source_of_die = rdr.get_die_source(die);
11844 rdr.get_die_language(die, die_lang);
11846 || rdr.die_parent_map(source_of_die).empty())
11851 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
11852 return rdr.global_scope();
11855 Dwarf_Die cloned_die;
11856 if (die_die_attribute(die, DW_AT_specification, cloned_die,
false)
11857 || die_die_attribute(die, DW_AT_abstract_origin, cloned_die,
false))
11858 return get_scope_for_die(rdr, &cloned_die,
11859 called_for_public_decl,
11862 Dwarf_Die parent_die;
11864 if (!get_parent_die(rdr, die, parent_die, where_offset))
11865 return rdr.nil_scope();
11867 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
11868 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
11869 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11871 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
11872 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11874 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
11875 || source_of_die == TYPE_UNIT_DIE_SOURCE);
11876 return rdr.cur_transl_unit()->get_global_scope();
11885 die_tu_map_type::const_iterator i =
11886 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
11887 if (i != rdr.die_tu_map().end())
11888 return i->second->get_global_scope();
11889 return rdr.cur_transl_unit()->get_global_scope();
11894 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
11895 || dwarf_tag(&parent_die) == DW_TAG_array_type
11896 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
11908 called_for_public_decl,
11917 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
11918 return rdr.nil_scope();
11919 s = get_scope_for_die(rdr, &parent_die,
11920 called_for_public_decl,
11926 d = build_ir_node_from_die(rdr, &parent_die,
11927 called_for_public_decl,
11929 s = dynamic_pointer_cast<scope_decl>(d);
11933 return rdr.nil_scope();
11936 if (cl && cl->get_is_declaration_only())
11939 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
11956 dwarf_language_to_tu_language(
size_t l)
11961 return translation_unit::LANG_C89;
11963 return translation_unit::LANG_C;
11964 case DW_LANG_Ada83:
11965 return translation_unit::LANG_Ada83;
11966 case DW_LANG_C_plus_plus:
11967 return translation_unit::LANG_C_plus_plus;
11968 case DW_LANG_Cobol74:
11969 return translation_unit::LANG_Cobol74;
11970 case DW_LANG_Cobol85:
11971 return translation_unit::LANG_Cobol85;
11972 case DW_LANG_Fortran77:
11973 return translation_unit::LANG_Fortran77;
11974 case DW_LANG_Fortran90:
11975 return translation_unit::LANG_Fortran90;
11976 case DW_LANG_Pascal83:
11977 return translation_unit::LANG_Pascal83;
11978 case DW_LANG_Modula2:
11979 return translation_unit::LANG_Modula2;
11981 return translation_unit::LANG_Java;
11983 return translation_unit::LANG_C99;
11984 case DW_LANG_Ada95:
11985 return translation_unit::LANG_Ada95;
11986 case DW_LANG_Fortran95:
11987 return translation_unit::LANG_Fortran95;
11989 return translation_unit::LANG_PLI;
11991 return translation_unit::LANG_ObjC;
11992 case DW_LANG_ObjC_plus_plus:
11993 return translation_unit::LANG_ObjC_plus_plus;
11995 #ifdef HAVE_DW_LANG_Rust_enumerator
11997 return translation_unit::LANG_Rust;
12000 #ifdef HAVE_DW_LANG_UPC_enumerator
12002 return translation_unit::LANG_UPC;
12005 #ifdef HAVE_DW_LANG_D_enumerator
12007 return translation_unit::LANG_D;
12010 #ifdef HAVE_DW_LANG_Python_enumerator
12011 case DW_LANG_Python:
12012 return translation_unit::LANG_Python;
12015 #ifdef HAVE_DW_LANG_Go_enumerator
12017 return translation_unit::LANG_Go;
12020 #ifdef HAVE_DW_LANG_C11_enumerator
12022 return translation_unit::LANG_C11;
12025 #ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
12026 case DW_LANG_C_plus_plus_03:
12027 return translation_unit::LANG_C_plus_plus_03;
12030 #ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
12031 case DW_LANG_C_plus_plus_11:
12032 return translation_unit::LANG_C_plus_plus_11;
12035 #ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
12036 case DW_LANG_C_plus_plus_14:
12037 return translation_unit::LANG_C_plus_plus_14;
12040 #ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
12041 case DW_LANG_Mips_Assembler:
12042 return translation_unit::LANG_Mips_Assembler;
12046 return translation_unit::LANG_UNKNOWN;
12063 case translation_unit::LANG_UNKNOWN:
12066 case translation_unit::LANG_Cobol74:
12067 case translation_unit::LANG_Cobol85:
12070 case translation_unit::LANG_C89:
12071 case translation_unit::LANG_C99:
12072 case translation_unit::LANG_C11:
12073 case translation_unit::LANG_C:
12074 case translation_unit::LANG_C_plus_plus_03:
12075 case translation_unit::LANG_C_plus_plus_11:
12076 case translation_unit::LANG_C_plus_plus_14:
12077 case translation_unit::LANG_C_plus_plus:
12078 case translation_unit::LANG_ObjC:
12079 case translation_unit::LANG_ObjC_plus_plus:
12080 case translation_unit::LANG_Rust:
12083 case translation_unit::LANG_Fortran77:
12084 case translation_unit::LANG_Fortran90:
12085 case translation_unit::LANG_Fortran95:
12086 case translation_unit::LANG_Ada83:
12087 case translation_unit::LANG_Ada95:
12088 case translation_unit::LANG_Pascal83:
12089 case translation_unit::LANG_Modula2:
12092 case translation_unit::LANG_Java:
12095 case translation_unit::LANG_PLI:
12098 case translation_unit::LANG_UPC:
12099 case translation_unit::LANG_D:
12100 case translation_unit::LANG_Python:
12101 case translation_unit::LANG_Go:
12102 case translation_unit::LANG_Mips_Assembler:
12127 find_lower_bound_in_imported_unit_points(
const imported_unit_points_type& p,
12129 imported_unit_points_type::const_iterator& r)
12131 imported_unit_point v(val);
12132 imported_unit_points_type::const_iterator result =
12133 std::lower_bound(p.begin(), p.end(), v);
12135 bool is_ok = result != p.end();
12157 build_translation_unit_and_add_to_ir(reader& rdr,
12165 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
12169 rdr.clear_per_translation_unit_data();
12171 rdr.cur_tu_die(die);
12173 string path = die_string_attribute(die, DW_AT_name);
12174 if (path ==
"<artificial>")
12180 std::ostringstream o;
12181 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
12184 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
12194 const string& abs_path =
12195 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
12196 result = rdr.corpus()->find_translation_unit(abs_path);
12201 result.reset(
new translation_unit(rdr.env(),
12204 result->set_compilation_dir_path(compilation_dir);
12205 rdr.corpus()->add(result);
12207 die_unsigned_constant_attribute(die, DW_AT_language, l);
12208 result->set_language(dwarf_language_to_tu_language(l));
12211 rdr.cur_transl_unit(result);
12212 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
12215 if (dwarf_child(die, &child) != 0)
12218 result->set_is_constructed(
false);
12223 if (!rdr.env().analyze_exported_interfaces_only()
12224 || rdr.is_decl_die_with_exported_symbol(&child))
12225 build_ir_node_from_die(rdr, &child,
12226 die_is_public_decl(&child),
12227 dwarf_dieoffset(&child));
12228 while (dwarf_siblingof(&child, &child) == 0);
12230 if (!rdr.var_decls_to_re_add_to_tree().empty())
12231 for (list<var_decl_sptr>::const_iterator v =
12232 rdr.var_decls_to_re_add_to_tree().begin();
12233 v != rdr.var_decls_to_re_add_to_tree().end();
12240 string demangled_name =
12242 if (!demangled_name.empty())
12244 std::list<string> fqn_comps;
12246 string mem_name = fqn_comps.back();
12247 fqn_comps.pop_back();
12250 if (!fqn_comps.empty())
12278 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
12284 rdr.var_decls_to_re_add_to_tree().clear();
12286 result->set_is_constructed(
true);
12311 build_namespace_decl_and_add_to_ir(reader& rdr,
12313 size_t where_offset)
12320 unsigned tag = dwarf_tag(die);
12321 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
12328 string name, linkage_name;
12330 die_loc_and_name(rdr, die, loc, name, linkage_name);
12332 result.reset(
new namespace_decl(rdr.env(), name, loc));
12334 rdr.associate_die_to_decl(die, result, where_offset);
12337 if (dwarf_child(die, &child) != 0)
12340 rdr.scope_stack().push(result.get());
12342 build_ir_node_from_die(rdr, &child,
12348 die_is_public_decl(die) && die_is_public_decl(&child),
12350 while (dwarf_siblingof(&child, &child) == 0);
12351 rdr.scope_stack().pop();
12366 build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
12372 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
12374 uint64_t byte_size = 0, bit_size = 0;
12375 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
12376 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
12379 if (bit_size == 0 && byte_size != 0)
12381 bit_size = byte_size * 8;
12383 string type_name, linkage_name;
12385 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
12387 if (byte_size == 0)
12391 if (type_name ==
"void")
12392 result =
is_type_decl(build_ir_node_for_void_type(rdr));
12399 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12401 string normalized_type_name = type_name;
12402 integral_type int_type;
12404 normalized_type_name = int_type.
to_string();
12409 if (corpus_sptr corp = rdr.corpus())
12412 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
12413 0, loc, linkage_name));
12414 rdr.associate_die_to_type(die, result, where_offset);
12432 build_enum_underlying_type(reader& rdr,
12434 uint64_t enum_size,
12435 bool is_anonymous =
true)
12437 string underlying_type_name =
12441 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
12442 enum_size, enum_size, location()));
12443 result->set_is_anonymous(is_anonymous);
12444 result->set_is_artificial(
true);
12447 result = dynamic_pointer_cast<type_decl>(d);
12468 build_enum_type(reader& rdr,
12471 size_t where_offset,
12472 bool is_declaration_only)
12478 unsigned tag = dwarf_tag(die);
12479 if (tag != DW_TAG_enumeration_type)
12482 string name, linkage_name;
12484 die_loc_and_name(rdr, die, loc, name, linkage_name);
12486 bool is_anonymous =
false;
12490 name = get_internal_anonymous_die_prefix_name(die);
12493 is_anonymous =
true;
12495 if (
size_t s = scope->get_num_anonymous_member_enums())
12496 name = build_internal_anonymous_die_name(name, s);
12499 bool use_odr = rdr.odr_is_relevant(die);
12511 result = pre_existing_enum;
12513 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12522 if (pre_existing_enum->get_location() == loc)
12523 result = pre_existing_enum;
12528 rdr.associate_die_to_type(die, result, where_offset);
12536 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
12538 bool is_artificial = die_is_artificial(die);
12541 bool enum_underlying_type_is_anonymous=
true;
12545 if (dwarf_child(die, &child) == 0)
12549 if (dwarf_tag(&child) != DW_TAG_enumerator)
12554 die_loc_and_name(rdr, &child, l, n, m);
12556 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
12557 enms.push_back(enum_type_decl::enumerator(n, val));
12559 while (dwarf_siblingof(&child, &child) == 0);
12567 build_enum_underlying_type(rdr, name, size,
12568 enum_underlying_type_is_anonymous);
12569 t->set_is_declaration_only(is_declaration_only);
12571 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
12572 result->set_is_anonymous(is_anonymous);
12573 result->set_is_declaration_only(is_declaration_only);
12574 result->set_is_artificial(is_artificial);
12575 rdr.associate_die_to_type(die, result, where_offset);
12577 rdr.maybe_schedule_declaration_only_enum_for_resolution(result);
12596 finish_member_function_reading(Dwarf_Die* die,
12598 const class_or_union_sptr klass,
12609 bool is_ctor = (f->get_name() == klass->get_name());
12610 bool is_dtor = (!f->get_name().empty()
12611 &&
static_cast<string>(f->get_name())[0] ==
'~');
12612 bool is_virtual = die_is_virtual(die);
12613 int64_t vindex = -1;
12615 die_virtual_function_index(die, vindex);
12618 if (!c->is_struct())
12619 access = private_access;
12620 die_access_specifier(die, access);
12622 bool is_static =
false;
12630 if (!f->get_parameters().empty())
12631 first_parm = f->get_parameters()[0];
12633 bool is_artificial = first_parm && first_parm->get_is_artificial();
12634 type_base_sptr this_ptr_type, other_klass;
12637 this_ptr_type = first_parm->get_type();
12644 this_ptr_type = q->get_underlying_type();
12648 other_klass = p->get_pointed_to_type();
12653 other_klass = q->get_underlying_type();
12656 &&
get_type_name(other_klass) == klass->get_qualified_name())
12667 Dwarf_Die object_pointer_die;
12668 if (die_has_object_pointer(die, object_pointer_die))
12684 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol())
12703 Dwarf_Off die_offset = dwarf_dieoffset(die);
12704 die_function_decl_map_type &fns_with_no_symbol =
12705 rdr.die_function_decl_with_no_symbol_map();
12706 die_function_decl_map_type::const_iterator i =
12707 fns_with_no_symbol.find(die_offset);
12708 if (i == fns_with_no_symbol.end())
12709 fns_with_no_symbol[die_offset] = f;
12730 maybe_finish_function_decl_reading(reader& rdr,
12732 size_t where_offset,
12750 static type_base_sptr
12751 lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
12754 corpus* corp = scope->get_corpus();
12775 static type_base_sptr
12776 lookup_class_or_typedef_from_corpus(reader& rdr,
12778 bool called_for_public_decl,
12779 size_t where_offset)
12784 string class_name = die_string_attribute(die, DW_AT_name);
12785 if (class_name.empty())
12789 called_for_public_decl,
12792 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
12794 return type_base_sptr();
12805 static type_base_sptr
12806 lookup_class_typedef_or_enum_type_from_corpus(scope_decl* scope,
12807 const string& type_name)
12810 corpus* corp = scope->get_corpus();
12828 static type_base_sptr
12829 lookup_class_typedef_or_enum_type_from_corpus(Dwarf_Die* die,
12830 size_t anonymous_member_type_idx,
12836 string type_name = die_string_attribute(die, DW_AT_name);
12839 get_internal_anonymous_die_name(die, anonymous_member_type_idx);
12841 if (type_name.empty())
12844 return lookup_class_typedef_or_enum_type_from_corpus(scope, type_name);
12862 static method_decl_sptr
12863 is_function_for_die_a_member_of_class(reader& rdr,
12864 Dwarf_Die* function_die,
12865 const class_or_union_sptr& class_type)
12870 return method_decl_sptr();
12876 method_type = method->get_type();
12881 class_or_union_sptr method_class = method_type->get_class_type();
12884 string method_class_name = method_class->get_qualified_name(),
12885 class_type_name = class_type->get_qualified_name();
12887 if (method_class_name == class_type_name)
12893 return method_decl_sptr();
12915 static method_decl_sptr
12916 add_or_update_member_function(reader& rdr,
12917 Dwarf_Die* function_die,
12918 const class_or_union_sptr& class_type,
12919 bool called_from_public_decl,
12920 size_t where_offset)
12922 method_decl_sptr method =
12923 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
12926 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
12928 called_from_public_decl,
12931 return method_decl_sptr();
12933 finish_member_function_reading(function_die,
12976 add_or_update_class_type(reader& rdr,
12981 bool called_from_public_decl,
12982 size_t where_offset,
12983 bool is_declaration_only)
12989 const die_source source = rdr.get_die_source(die);
12991 unsigned tag = dwarf_tag(die);
12993 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
12997 die_class_or_union_map_type::const_iterator i =
12998 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
12999 if (i != rdr.die_wip_classes_map(source).end())
13007 string name, linkage_name;
13009 die_loc_and_name(rdr, die, loc, name, linkage_name);
13011 bool is_anonymous =
false;
13016 name = get_internal_anonymous_die_prefix_name(die);
13019 is_anonymous =
true;
13021 if (
size_t s = scope->get_num_anonymous_member_classes())
13022 name = build_internal_anonymous_die_name(name, s);
13027 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13043 && (result->get_is_declaration_only() == is_declaration_only
13044 || (!result->get_is_declaration_only()
13045 && is_declaration_only)))
13047 rdr.associate_die_to_type(die, result, where_offset);
13066 klass = pre_existing_class;
13069 die_size_in_bits(die, size);
13070 bool is_artificial = die_is_artificial(die);
13073 bool has_child = (dwarf_child(die, &child) == 0);
13075 decl_base_sptr res;
13078 res = result = klass;
13079 if (has_child && klass->get_is_declaration_only()
13080 && klass->get_definition_of_declaration())
13081 res = result =
is_class_type(klass->get_definition_of_declaration());
13083 result->set_location(loc);
13087 result.reset(
new class_decl(rdr.env(), name, size,
13089 decl_base::VISIBILITY_DEFAULT,
13092 result->set_is_declaration_only(is_declaration_only);
13095 result = dynamic_pointer_cast<class_decl>(res);
13099 if (!klass || klass->get_is_declaration_only())
13100 if (size != result->get_size_in_bits())
13101 result->set_size_in_bits(size);
13106 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
13119 result->set_is_declaration_only(is_declaration_only);
13123 if (!result->get_is_declaration_only() && has_child)
13124 if (result->get_size_in_bits() == 0 && size != 0)
13125 result->set_size_in_bits(size);
13127 result->set_is_artificial(is_artificial);
13129 rdr.associate_die_to_type(die, result, where_offset);
13131 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13138 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13140 bool is_incomplete_type =
false;
13141 if (is_declaration_only && size == 0 && has_child)
13153 is_incomplete_type =
true;
13156 dynamic_pointer_cast<scope_decl>(res);
13158 rdr.scope_stack().push(scop.get());
13160 if (has_child && !is_incomplete_type)
13162 int anonymous_member_class_index = -1;
13163 int anonymous_member_union_index = -1;
13164 int anonymous_member_enum_index = -1;
13168 tag = dwarf_tag(&child);
13171 if (tag == DW_TAG_inheritance)
13173 result->set_is_declaration_only(
false);
13175 Dwarf_Die type_die;
13176 if (!die_die_attribute(&child, DW_AT_type, type_die))
13179 type_base_sptr base_type;
13181 lookup_class_or_typedef_from_corpus(rdr, &type_die,
13182 called_from_public_decl,
13186 is_type(build_ir_node_from_die(rdr, &type_die,
13187 called_from_public_decl,
13201 die_access_specifier(&child, access);
13203 bool is_virt= die_is_virtual(&child);
13204 int64_t offset = 0;
13205 bool is_offset_present =
13206 die_member_offset(rdr, &child, offset);
13210 is_offset_present ? offset : -1,
13212 if (b->get_is_declaration_only())
13213 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
13214 if (result->find_base_class(b->get_qualified_name()))
13216 result->add_base_specifier(base);
13219 else if (tag == DW_TAG_member
13220 || tag == DW_TAG_variable)
13222 Dwarf_Die type_die;
13223 if (!die_die_attribute(&child, DW_AT_type, type_die))
13228 die_loc_and_name(rdr, &child, loc, n, m);
13233 if (n.substr(0, 5) ==
"_vptr"
13235 && !std::isalnum(n.at(5))
13245 int64_t offset_in_bits = 0;
13246 bool is_laid_out = die_member_offset(rdr, &child,
13251 bool is_static = !is_laid_out;
13253 if (is_static && variable_is_suppressed(rdr,
13258 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
13259 called_from_public_decl,
13261 type_base_sptr t =
is_type(ty);
13265 if (n.empty() && !die_is_anonymous_data_member(&child))
13271 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
13288 result->set_is_declaration_only(
false);
13294 die_access_specifier(&child, access);
13302 result->add_data_member(dm, access, is_laid_out,
13303 is_static, offset_in_bits);
13305 rdr.associate_die_to_decl(&child, dm, where_offset,
13309 else if (tag == DW_TAG_subprogram)
13312 add_or_update_member_function(rdr, &child, result,
13313 called_from_public_decl,
13316 rdr.associate_die_to_decl(&child, f, where_offset,
13320 else if (die_is_type(&child))
13326 int anonymous_member_type_index = 0;
13330 if (die_is_class_type(&child))
13331 anonymous_member_type_index =
13332 ++anonymous_member_class_index;
13333 else if (dwarf_tag(&child) == DW_TAG_union_type)
13334 anonymous_member_type_index =
13335 ++anonymous_member_union_index;
13336 else if (dwarf_tag(&child) == DW_TAG_enumeration_type)
13337 anonymous_member_type_index =
13338 ++anonymous_member_enum_index;
13343 && !lookup_class_typedef_or_enum_type_from_corpus
13344 (&child, anonymous_member_type_index, result.get()))
13345 || !result->find_member_type(die_name(&child)))
13346 build_ir_node_from_die(rdr, &child, result.get(),
13347 called_from_public_decl,
13350 }
while (dwarf_siblingof(&child, &child) == 0);
13353 rdr.scope_stack().pop();
13356 die_class_or_union_map_type::const_iterator i =
13357 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13358 if (i != rdr.die_wip_classes_map(source).end())
13363 rdr.die_wip_classes_map(source).erase(i);
13367 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13395 static union_decl_sptr
13396 add_or_update_union_type(reader& rdr,
13399 union_decl_sptr union_type,
13400 bool called_from_public_decl,
13401 size_t where_offset,
13402 bool is_declaration_only)
13404 union_decl_sptr result;
13408 unsigned tag = dwarf_tag(die);
13410 if (tag != DW_TAG_union_type)
13413 const die_source source = rdr.get_die_source(die);
13415 die_class_or_union_map_type::const_iterator i =
13416 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13417 if (i != rdr.die_wip_classes_map(source).end())
13425 string name, linkage_name;
13427 die_loc_and_name(rdr, die, loc, name, linkage_name);
13429 bool is_anonymous =
false;
13434 name = get_internal_anonymous_die_prefix_name(die);
13437 is_anonymous =
true;
13439 if (
size_t s = scope->get_num_anonymous_member_unions())
13440 name = build_internal_anonymous_die_name(name, s);
13450 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13459 rdr.associate_die_to_type(die, result, where_offset);
13471 if (union_decl_sptr pre_existing_union =
13473 union_type = pre_existing_union;
13476 die_size_in_bits(die, size);
13477 bool is_artificial = die_is_artificial(die);
13481 result = union_type;
13482 result->set_location(loc);
13486 result.reset(
new union_decl(rdr.env(), name, size, loc,
13487 decl_base::VISIBILITY_DEFAULT,
13489 if (is_declaration_only)
13490 result->set_is_declaration_only(
true);
13497 result->set_size_in_bits(size);
13498 result->set_is_declaration_only(
false);
13501 result->set_is_artificial(is_artificial);
13503 rdr.associate_die_to_type(die, result, where_offset);
13505 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13508 bool has_child = (dwarf_child(die, &child) == 0);
13512 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13515 dynamic_pointer_cast<scope_decl>(result);
13517 rdr.scope_stack().push(scop.get());
13523 tag = dwarf_tag(&child);
13525 if (tag == DW_TAG_member || tag == DW_TAG_variable)
13527 Dwarf_Die type_die;
13528 if (!die_die_attribute(&child, DW_AT_type, type_die))
13533 die_loc_and_name(rdr, &child, loc, n, m);
13542 ssize_t offset_in_bits = 0;
13543 decl_base_sptr ty =
13544 is_decl(build_ir_node_from_die(rdr, &type_die,
13545 called_from_public_decl,
13547 type_base_sptr t =
is_type(ty);
13554 result->set_is_declaration_only(
false);
13557 die_access_specifier(&child, access);
13563 if (n.empty() && result->find_data_member(dm))
13566 result->add_data_member(dm, access,
true,
13570 rdr.associate_die_to_decl(&child, dm, where_offset,
13574 else if (tag == DW_TAG_subprogram)
13577 is_decl(build_ir_node_from_die(rdr, &child,
13579 called_from_public_decl,
13587 finish_member_function_reading(&child, f, result, rdr);
13589 rdr.associate_die_to_decl(&child, f, where_offset,
13593 else if (die_is_type(&child))
13594 decl_base_sptr td =
13595 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
13596 called_from_public_decl,
13598 }
while (dwarf_siblingof(&child, &child) == 0);
13601 rdr.scope_stack().pop();
13604 die_class_or_union_map_type::const_iterator i =
13605 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13606 if (i != rdr.die_wip_classes_map(source).end())
13611 rdr.die_wip_classes_map(source).erase(i);
13635 static type_base_sptr
13636 build_qualified_type(reader& rdr,
13638 bool called_from_public_decl,
13639 size_t where_offset)
13641 type_base_sptr result;
13645 unsigned tag = dwarf_tag(die);
13647 if (tag != DW_TAG_const_type
13648 && tag != DW_TAG_volatile_type
13649 && tag != DW_TAG_restrict_type)
13652 Dwarf_Die underlying_type_die;
13653 decl_base_sptr utype_decl;
13654 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13658 utype_decl = build_ir_node_for_void_type(rdr);
13661 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
13662 called_from_public_decl,
13669 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13672 rdr.associate_die_to_type(die, result, where_offset);
13676 type_base_sptr utype =
is_type(utype_decl);
13680 if (tag == DW_TAG_const_type)
13681 qual |= qualified_type_def::CV_CONST;
13682 else if (tag == DW_TAG_volatile_type)
13683 qual |= qualified_type_def::CV_VOLATILE;
13684 else if (tag == DW_TAG_restrict_type)
13685 qual |= qualified_type_def::CV_RESTRICT;
13690 result.reset(
new qualified_type_def(utype, qual, location()));
13692 rdr.associate_die_to_type(die, result, where_offset);
13710 schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
13715 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13717 rdr.schedule_type_for_late_canonicalization(t);
13721 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13723 rdr.schedule_type_for_late_canonicalization(t);
13727 for (vector<array_type_def::subrange_sptr>::const_iterator i =
13728 type->get_subranges().begin();
13729 i != type->get_subranges().end();
13732 if (!(*i)->get_scope())
13734 rdr.schedule_type_for_late_canonicalization(*i);
13737 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
13739 rdr.schedule_type_for_late_canonicalization(type);
13758 static decl_base_sptr
13759 maybe_strip_qualification(
const qualified_type_def_sptr t,
13765 decl_base_sptr result = t;
13766 type_base_sptr u = t->get_underlying_type();
13770 if (result.get() != t.get())
13776 scope_decl * scope = 0;
13779 scope = array->get_scope();
13782 schedule_array_tree_for_late_canonicalization(array, rdr);
13784 t->set_underlying_type(array);
13785 u = t->get_underlying_type();
13793 schedule_array_tree_for_late_canonicalization(typdef, rdr);
13796 t->set_underlying_type(typdef);
13797 u = t->get_underlying_type();
13806 type_base_sptr element_type = array->get_element_type();
13811 ABG_ASSERT(!qualified->get_canonical_type());
13813 quals |= t->get_cv_quals();
13814 qualified->set_cv_quals(quals);
13820 qualified_type_def_sptr qual_type
13821 (
new qualified_type_def(element_type,
13823 t->get_location()));
13826 array->set_element_type(qual_type);
13827 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
13852 build_pointer_type_def(reader& rdr,
13854 bool called_from_public_decl,
13855 size_t where_offset)
13862 unsigned tag = dwarf_tag(die);
13863 if (tag != DW_TAG_pointer_type)
13867 Dwarf_Die underlying_type_die;
13868 bool has_underlying_type_die =
false;
13869 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13872 utype_decl = build_ir_node_for_void_type(rdr);
13874 has_underlying_type_die =
true;
13876 if (!utype_decl && has_underlying_type_die)
13877 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
13878 called_from_public_decl,
13885 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13892 type_base_sptr utype =
is_type(utype_decl);
13898 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13899 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13906 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
13908 result.reset(
new pointer_type_def(utype, size, 0, location()));
13914 rdr.associate_die_to_type(die, result, where_offset);
13936 build_reference_type(reader& rdr,
13938 bool called_from_public_decl,
13939 size_t where_offset)
13946 unsigned tag = dwarf_tag(die);
13947 if (tag != DW_TAG_reference_type
13948 && tag != DW_TAG_rvalue_reference_type)
13951 Dwarf_Die underlying_type_die;
13952 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13956 build_ir_node_from_die(rdr, &underlying_type_die,
13957 called_from_public_decl,
13964 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13971 type_base_sptr utype =
is_type(utype_decl);
13977 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13978 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13983 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
13985 bool is_lvalue = tag == DW_TAG_reference_type;
13987 result.reset(
new reference_type_def(utype, is_lvalue, size,
13990 if (corpus_sptr corp = rdr.corpus())
13993 rdr.associate_die_to_type(die, result, where_offset);
14013 static function_type_sptr
14014 build_function_type(reader& rdr,
14016 class_or_union_sptr is_method,
14017 size_t where_offset)
14019 function_type_sptr result;
14024 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
14025 || dwarf_tag(die) == DW_TAG_subprogram);
14027 const die_source source = rdr.get_die_source(die);
14030 size_t off = dwarf_dieoffset(die);
14031 auto i = rdr.die_wip_function_types_map(source).find(off);
14032 if (i != rdr.die_wip_function_types_map(source).end())
14040 decl_base_sptr type_decl;
14048 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
14052 rdr.associate_die_to_type(die, result, where_offset);
14057 if (odr_is_relevant)
14066 if (function_type_sptr fn_type =
14069 rdr.associate_die_to_type(die, fn_type, where_offset);
14077 bool is_const =
false;
14078 bool is_static =
false;
14079 Dwarf_Die object_pointer_die;
14080 Dwarf_Die class_type_die;
14081 bool has_this_parm_die =
14082 die_function_type_is_method_type(rdr, die, where_offset,
14083 object_pointer_die,
14086 if (has_this_parm_die)
14091 if (die_object_pointer_is_for_const_method(&object_pointer_die))
14099 class_or_union_sptr klass_type =
14104 is_method = klass_type;
14113 result.reset(is_method
14114 ?
new method_type(is_method, is_const,
14115 tu->get_address_size(),
14117 :
new function_type(rdr.env(), tu->get_address_size(),
14119 rdr.associate_die_to_type(die, result, where_offset);
14120 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
14122 type_base_sptr return_type;
14123 Dwarf_Die ret_type_die;
14124 if (die_die_attribute(die, DW_AT_type, ret_type_die))
14126 is_type(build_ir_node_from_die(rdr, &ret_type_die,
14130 return_type =
is_type(build_ir_node_for_void_type(rdr));
14131 result->set_return_type(return_type);
14136 if (dwarf_child(die, &child) == 0)
14139 int child_tag = dwarf_tag(&child);
14140 if (child_tag == DW_TAG_formal_parameter)
14143 string name, linkage_name;
14145 die_loc_and_name(rdr, &child, loc, name, linkage_name);
14150 bool is_artificial = die_is_artificial(&child);
14151 type_base_sptr parm_type;
14152 Dwarf_Die parm_type_die;
14153 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
14155 is_type(build_ir_node_from_die(rdr, &parm_type_die,
14161 (
new function_decl::parameter(parm_type, name, loc,
14164 function_parms.push_back(p);
14166 else if (child_tag == DW_TAG_unspecified_parameters)
14169 bool is_artificial = die_is_artificial(&child);
14171 type_base_sptr parm_type =
14172 is_type(build_ir_node_for_variadic_parameter_type(rdr));
14174 (
new function_decl::parameter(parm_type,
14179 function_parms.push_back(p);
14189 while (dwarf_siblingof(&child, &child) == 0);
14191 result->set_parameters(function_parms);
14193 tu->bind_function_type_life_time(result);
14195 result->set_is_artificial(
true);
14197 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
14200 die_function_type_map_type::const_iterator i =
14201 rdr.die_wip_function_types_map(source).
14202 find(dwarf_dieoffset(die));
14203 if (i != rdr.die_wip_function_types_map(source).end())
14204 rdr.die_wip_function_types_map(source).erase(i);
14207 maybe_canonicalize_type(result, rdr);
14234 build_subrange_type(reader& rdr,
14235 const Dwarf_Die* die,
14236 size_t where_offset,
14237 bool associate_type_to_die)
14244 unsigned tag = dwarf_tag(const_cast<Dwarf_Die*>(die));
14245 if (tag != DW_TAG_subrange_type)
14248 string name = die_name(die);
14251 Dwarf_Die underlying_type_die;
14252 type_base_sptr underlying_type;
14254 bool is_signed =
false;
14255 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
14257 is_type(build_ir_node_from_die(rdr,
14258 &underlying_type_die,
14262 if (underlying_type)
14265 if (die_unsigned_constant_attribute (&underlying_type_die,
14268 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
14272 array_type_def::subrange_type::bound_value lower_bound =
14273 get_default_array_lower_bound(language);
14274 array_type_def::subrange_type::bound_value upper_bound;
14275 uint64_t count = 0;
14276 bool is_infinite =
false;
14277 bool count_present =
false;
14288 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
14290 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
14291 is_signed, upper_bound);
14292 if (!found_upper_bound)
14293 found_upper_bound = subrange_die_indirect_bound_value(die,
14298 if (!found_upper_bound)
14311 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
14313 count_present =
true;
14317 int64_t u = lower_bound.get_signed_value() + count;
14318 upper_bound = u - 1;
14321 if (!count_present)
14325 is_infinite =
true;
14328 if (UINT64_MAX == upper_bound.get_unsigned_value())
14331 is_infinite =
true;
14334 (
new array_type_def::subrange_type(rdr.env(),
14339 result->is_infinite(is_infinite);
14341 if (underlying_type)
14342 result->set_underlying_type(underlying_type);
14346 || (result->get_length() ==
14347 (uint64_t) (result->get_upper_bound()
14348 - result->get_lower_bound() + 1)));
14350 if (associate_type_to_die)
14351 rdr.associate_die_to_type(die, result, where_offset);
14373 build_subranges_from_array_type_die(reader& rdr,
14374 const Dwarf_Die* die,
14376 size_t where_offset,
14377 bool associate_type_to_die)
14381 if (dwarf_child(const_cast<Dwarf_Die*>(die), &child) == 0)
14385 int child_tag = dwarf_tag(&child);
14386 if (child_tag == DW_TAG_subrange_type)
14389 if (associate_type_to_die)
14395 build_ir_node_from_die(rdr, &child,
14404 s = build_subrange_type(rdr, &child,
14408 subranges.push_back(s);
14411 while (dwarf_siblingof(&child, &child) == 0);
14432 build_array_type(reader& rdr,
14434 bool called_from_public_decl,
14435 size_t where_offset)
14442 unsigned tag = dwarf_tag(die);
14443 if (tag != DW_TAG_array_type)
14446 decl_base_sptr type_decl;
14447 Dwarf_Die type_die;
14449 if (die_die_attribute(die, DW_AT_type, type_die))
14450 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
14451 called_from_public_decl,
14458 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14465 type_base_sptr type =
is_type(type_decl);
14470 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
14472 result.reset(
new array_type_def(type, subranges, location()));
14494 build_typedef_type(reader& rdr,
14496 bool called_from_public_decl,
14497 size_t where_offset)
14504 unsigned tag = dwarf_tag(die);
14505 if (tag != DW_TAG_typedef)
14508 string name, linkage_name;
14510 die_loc_and_name(rdr, die, loc, name, linkage_name);
14512 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14518 type_base_sptr utype;
14519 Dwarf_Die underlying_type_die;
14520 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14523 utype = rdr.env().get_void_type();
14527 is_type(build_ir_node_from_die(rdr,
14528 &underlying_type_die,
14529 called_from_public_decl,
14535 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
14542 decl_base_sptr decl =
is_decl(utype);
14544 decl->set_naming_typedef(result);
14548 rdr.associate_die_to_type(die, result, where_offset);
14582 build_or_get_var_decl_if_not_suppressed(reader& rdr,
14585 size_t where_offset,
14587 bool is_required_decl_spec)
14590 if (variable_is_suppressed(rdr, scope, die, is_required_decl_spec))
14595 string var_name = die_name(die);
14596 if (!var_name.empty())
14597 if ((var = class_type->find_data_member(var_name)))
14600 var = build_var_decl(rdr, die, where_offset, result);
14623 build_var_decl(reader& rdr,
14625 size_t where_offset,
14631 int tag = dwarf_tag(die);
14632 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
14634 if (!die_is_public_decl(die))
14637 type_base_sptr type;
14638 Dwarf_Die type_die;
14639 if (die_die_attribute(die, DW_AT_type, type_die))
14641 decl_base_sptr ty =
14642 is_decl(build_ir_node_from_die(rdr, &type_die,
14651 if (!type && !result)
14654 string name, linkage_name;
14656 die_loc_and_name(rdr, die, loc, name, linkage_name);
14659 result.reset(
new var_decl(name, type, loc, linkage_name));
14665 if (!linkage_name.empty())
14666 result->set_linkage_name(linkage_name);
14669 result->set_type(type);
14675 if (!result->get_symbol())
14678 Dwarf_Addr var_addr;
14680 if (rdr.get_variable_address(die, var_addr))
14683 update_main_symbol(var_addr,
14684 result->get_linkage_name().empty()
14685 ? result->get_name()
14686 : result->get_linkage_name());
14687 var_sym = rdr.variable_symbol_is_exported(var_addr);
14692 result->set_symbol(var_sym);
14695 string linkage_name = result->get_linkage_name();
14696 if (linkage_name.empty()
14697 || !var_sym->get_alias_from_name(linkage_name))
14698 result->set_linkage_name(var_sym->get_name());
14699 result->set_is_in_public_symbol_table(
true);
14725 function_is_suppressed(
const reader& rdr,
14726 const scope_decl* scope,
14727 Dwarf_Die *function_die,
14728 bool is_declaration_only)
14730 if (function_die == 0
14731 || dwarf_tag(function_die) != DW_TAG_subprogram)
14734 string fname = die_string_attribute(function_die, DW_AT_name);
14735 string flinkage_name = die_linkage_name(function_die);
14736 if (flinkage_name.empty() && rdr.die_is_in_c(function_die))
14737 flinkage_name = fname;
14747 && (!is_declaration_only || rdr.drop_undefined_syms()))
14749 Dwarf_Addr fn_addr;
14750 if (!rdr.get_function_address(function_die, fn_addr))
14754 rdr.function_symbol_is_exported(fn_addr);
14757 if (!symbol->is_suppressed())
14764 if (symbol->has_aliases())
14766 !a->is_main_symbol(); a = a->get_next_alias())
14767 if (!a->is_suppressed())
14816 build_or_get_fn_decl_if_not_suppressed(reader& rdr,
14819 size_t where_offset,
14820 bool is_declaration_only,
14824 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
14827 string name = die_name(fn_die);
14828 string linkage_name = die_linkage_name(fn_die);
14829 bool is_dtor = !name.empty() && name[0]==
'~';
14830 bool is_virtual =
false;
14833 Dwarf_Attribute attr;
14834 if (dwarf_attr_integrate(const_cast<Dwarf_Die*>(fn_die),
14835 DW_AT_vtable_elem_location,
14847 if (!result && (!(is_dtor && is_virtual)))
14850 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
14851 rdr.associate_die_to_decl(fn_die, fn,
true);
14852 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
14860 string linkage_name = die_linkage_name(fn_die);
14861 fn = klass->find_member_function_sptr(linkage_name);
14868 if (!fn || !fn->get_symbol())
14875 fn = build_function_decl(rdr, fn_die, where_offset, result);
14897 variable_is_suppressed(
const reader& rdr,
14898 const scope_decl* scope,
14899 Dwarf_Die *variable_die,
14900 bool is_required_decl_spec)
14902 if (variable_die == 0
14903 || (dwarf_tag(variable_die) != DW_TAG_variable
14904 && dwarf_tag(variable_die) != DW_TAG_member))
14907 string name = die_string_attribute(variable_die, DW_AT_name);
14908 string linkage_name = die_linkage_name(variable_die);
14909 if (linkage_name.empty() && rdr.die_is_in_c(variable_die))
14910 linkage_name = name;
14920 Dwarf_Addr var_addr = 0;
14921 if (!rdr.get_variable_address(variable_die, var_addr))
14925 rdr.variable_symbol_is_exported(var_addr);
14928 if (!symbol->is_suppressed())
14935 if (symbol->has_aliases())
14937 !a->is_main_symbol(); a = a->get_next_alias())
14938 if (!a->is_suppressed())
14967 type_is_suppressed(
const reader& rdr,
14968 const scope_decl* scope,
14969 Dwarf_Die *type_die,
14970 bool &type_is_private)
14973 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
14974 && dwarf_tag(type_die) != DW_TAG_class_type
14975 && dwarf_tag(type_die) != DW_TAG_structure_type
14976 && dwarf_tag(type_die) != DW_TAG_union_type))
14979 string type_name, linkage_name;
14980 location type_location;
14981 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15005 type_is_suppressed(
const reader& rdr,
15006 const scope_decl* scope,
15007 Dwarf_Die *type_die)
15009 bool type_is_private =
false;
15010 return type_is_suppressed(rdr, scope, type_die, type_is_private);
15034 get_opaque_version_of_type(reader &rdr,
15036 Dwarf_Die *type_die,
15037 size_t where_offset)
15044 unsigned tag = dwarf_tag(type_die);
15045 if (tag != DW_TAG_class_type
15046 && tag != DW_TAG_structure_type
15047 && tag != DW_TAG_union_type
15048 && tag != DW_TAG_enumeration_type)
15051 string type_name, linkage_name;
15052 location type_location;
15053 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15054 if (!type_location)
15064 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
15066 string_classes_or_unions_map::const_iterator i =
15067 rdr.declaration_only_classes().find(qualified_name);
15068 if (i != rdr.declaration_only_classes().end())
15069 result = i->second.back();
15080 tag == DW_TAG_structure_type,
15082 decl_base::VISIBILITY_DEFAULT));
15083 klass->set_is_declaration_only(
true);
15084 klass->set_is_artificial(die_is_artificial(type_die));
15086 rdr.associate_die_to_type(type_die, klass, where_offset);
15087 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
15092 if (tag == DW_TAG_enumeration_type)
15094 string_enums_map::const_iterator i =
15095 rdr.declaration_only_enums().find(qualified_name);
15096 if (i != rdr.declaration_only_enums().end())
15097 result = i->second.back();
15102 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
15105 build_enum_underlying_type(rdr, type_name, size,
15113 enum_type->set_is_artificial(die_is_artificial(type_die));
15115 result = enum_type;
15138 elf_symbol::FUNC_TYPE,
15139 elf_symbol::GLOBAL_BINDING,
15143 elf_symbol::DEFAULT_VISIBILITY);
15161 build_function_decl(reader& rdr,
15163 size_t where_offset,
15169 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subprogram);
15171 if (!die_is_public_decl(die))
15177 string fname, flinkage_name;
15179 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
15181 size_t is_inline = die_is_declared_inline(die);
15182 class_or_union_sptr is_method =
15195 if (!flinkage_name.empty()
15196 && result->get_linkage_name() != flinkage_name)
15197 result->set_linkage_name(flinkage_name);
15199 if (!result->get_location())
15200 result->set_location(floc);
15204 function_type_sptr fn_type(build_function_type(rdr, die, is_method,
15209 maybe_canonicalize_type(fn_type, rdr);
15211 result.reset(is_method
15212 ?
new method_decl(fname, fn_type,
15215 :
new function_decl(fname, fn_type,
15222 if (!result->get_symbol())
15225 Dwarf_Addr fn_addr;
15226 if (rdr.get_function_address(die, fn_addr))
15229 update_main_symbol(fn_addr,
15230 result->get_linkage_name().empty()
15231 ? result->get_name()
15232 : result->get_linkage_name());
15233 fn_sym = rdr.function_symbol_is_exported(fn_addr);
15236 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
15238 result->set_symbol(fn_sym);
15239 string linkage_name = result->get_linkage_name();
15240 if (linkage_name.empty())
15241 result->set_linkage_name(fn_sym->get_name());
15242 result->set_is_in_public_symbol_table(
true);
15246 rdr.associate_die_to_type(die, result->get_type(), where_offset);
15248 size_t die_offset = dwarf_dieoffset(die);
15253 && !result->get_linkage_name().empty())
15259 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
15278 maybe_canonicalize_type(
const type_base_sptr& t,
15291 ||(
is_decl(peeled_type) &&
is_decl(peeled_type)->get_is_anonymous()))
15301 rdr.schedule_type_for_late_canonicalization(t);
15303 rdr.schedule_type_for_late_canonicalization(t);
15314 maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
15317 if (
is_type(member_type_declaration)
15320 class_or_union* scope =
15326 if (!cl->is_struct())
15327 access = private_access;
15329 die_access_specifier(die, access);
15352 if (!fn || fn->get_scope())
15356 !die_is_virtual(fn_die)
15358 && !fn->get_linkage_name().empty()
15360 && !fn->get_symbol())
15405 build_ir_node_from_die(reader& rdr,
15408 bool called_from_public_decl,
15409 size_t where_offset,
15410 bool is_declaration_only,
15411 bool is_required_decl_spec)
15415 if (!die || !scope)
15418 int tag = dwarf_tag(die);
15420 if (!called_from_public_decl)
15422 if (rdr.load_all_types() && die_is_type(die))
15426 else if (tag != DW_TAG_subprogram
15427 && tag != DW_TAG_variable
15428 && tag != DW_TAG_member
15429 && tag != DW_TAG_namespace)
15433 const die_source source_of_die = rdr.get_die_source(die);
15435 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
15438 if (rdr.load_all_types())
15439 if (called_from_public_decl)
15440 if (type_base_sptr t =
is_type(result))
15441 if (corpus *abi_corpus = scope->get_corpus())
15442 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15451 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
15456 case DW_TAG_base_type:
15465 case DW_TAG_typedef:
15468 called_from_public_decl,
15474 maybe_set_member_type_access_specifier(
is_decl(result), die);
15475 maybe_canonicalize_type(t, rdr);
15480 case DW_TAG_pointer_type:
15483 build_pointer_type_def(rdr, die,
15484 called_from_public_decl,
15491 maybe_canonicalize_type(p, rdr);
15496 case DW_TAG_reference_type:
15497 case DW_TAG_rvalue_reference_type:
15500 build_reference_type(rdr, die,
15501 called_from_public_decl,
15508 rdr.associate_die_to_type(die, r, where_offset);
15509 maybe_canonicalize_type(r, rdr);
15514 case DW_TAG_const_type:
15515 case DW_TAG_volatile_type:
15516 case DW_TAG_restrict_type:
15519 build_qualified_type(rdr, die,
15520 called_from_public_decl,
15531 type_base_sptr ty =
is_type(d);
15535 rdr.associate_die_to_type(die, ty, where_offset);
15538 maybe_canonicalize_type(
is_type(result), rdr);
15543 case DW_TAG_enumeration_type:
15545 bool type_is_private =
false;
15546 bool type_suppressed =
15547 type_is_suppressed(rdr, scope, die, type_is_private);
15548 if (type_suppressed && type_is_private)
15556 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15557 maybe_canonicalize_type(
is_type(result), rdr);
15559 else if (!type_suppressed)
15563 is_declaration_only);
15567 maybe_set_member_type_access_specifier(
is_decl(result), die);
15568 maybe_canonicalize_type(
is_type(result), rdr);
15574 case DW_TAG_class_type:
15575 case DW_TAG_structure_type:
15577 bool type_is_private =
false;
15578 bool type_suppressed=
15579 type_is_suppressed(rdr, scope, die, type_is_private);
15581 if (type_suppressed && type_is_private)
15589 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15590 maybe_canonicalize_type(
is_type(result), rdr);
15592 else if (!type_suppressed)
15594 Dwarf_Die spec_die;
15597 if (die_die_attribute(die, DW_AT_specification, spec_die))
15600 get_scope_for_die(rdr, &spec_die,
15601 called_from_public_decl,
15604 decl_base_sptr cl =
15605 is_decl(build_ir_node_from_die(rdr, &spec_die,
15607 called_from_public_decl,
15609 is_declaration_only,
15612 klass = dynamic_pointer_cast<class_decl>(cl);
15616 add_or_update_class_type(rdr, die,
15618 tag == DW_TAG_structure_type,
15620 called_from_public_decl,
15622 is_declaration_only);
15626 add_or_update_class_type(rdr, die, scope,
15627 tag == DW_TAG_structure_type,
15629 called_from_public_decl,
15631 is_declaration_only);
15635 maybe_set_member_type_access_specifier(klass, die);
15636 maybe_canonicalize_type(klass, rdr);
15641 case DW_TAG_union_type:
15642 if (!type_is_suppressed(rdr, scope, die))
15644 union_decl_sptr union_type =
15645 add_or_update_union_type(rdr, die, scope,
15647 called_from_public_decl,
15649 is_declaration_only);
15652 maybe_set_member_type_access_specifier(union_type, die);
15653 maybe_canonicalize_type(union_type, rdr);
15655 result = union_type;
15658 case DW_TAG_string_type:
15660 case DW_TAG_subroutine_type:
15662 function_type_sptr f = build_function_type(rdr, die,
15668 result->set_is_artificial(
false);
15669 maybe_canonicalize_type(f, rdr);
15673 case DW_TAG_array_type:
15677 called_from_public_decl,
15683 rdr.associate_die_to_type(die, a, where_offset);
15684 maybe_canonicalize_type(a, rdr);
15688 case DW_TAG_subrange_type:
15694 build_subrange_type(rdr, die, where_offset);
15699 rdr.associate_die_to_type(die, s, where_offset);
15700 maybe_canonicalize_type(s, rdr);
15704 case DW_TAG_packed_type:
15706 case DW_TAG_set_type:
15708 case DW_TAG_file_type:
15710 case DW_TAG_ptr_to_member_type:
15712 case DW_TAG_thrown_type:
15714 case DW_TAG_interface_type:
15716 case DW_TAG_unspecified_type:
15718 case DW_TAG_shared_type:
15721 case DW_TAG_compile_unit:
15726 case DW_TAG_namespace:
15727 case DW_TAG_module:
15728 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
15731 case DW_TAG_variable:
15732 case DW_TAG_member:
15734 Dwarf_Die spec_die;
15735 bool var_is_cloned =
false;
15737 if (tag == DW_TAG_member)
15740 if (die_die_attribute(die, DW_AT_specification, spec_die,
false)
15741 || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin,
15745 get_scope_for_die(rdr, &spec_die,
15747 die_is_effectively_public_decl(rdr, die),
15752 is_decl(build_ir_node_from_die(rdr, &spec_die,
15754 called_from_public_decl,
15756 is_declaration_only,
15761 dynamic_pointer_cast<var_decl>(d);
15764 m = build_var_decl(rdr, die, where_offset, m);
15768 rdr.associate_die_to_decl(die, m, where_offset,
15774 rdr.var_decls_to_re_add_to_tree().push_back(m);
15777 rdr.maybe_add_var_to_exported_decls(m.get());
15783 build_or_get_var_decl_if_not_suppressed(rdr, scope, die,
15786 is_required_decl_spec))
15790 v = dynamic_pointer_cast<var_decl>(result);
15793 rdr.var_decls_to_re_add_to_tree().push_back(v);
15794 rdr.maybe_add_var_to_exported_decls(v.get());
15799 case DW_TAG_subprogram:
15801 Dwarf_Die spec_die;
15802 Dwarf_Die abstract_origin_die;
15803 Dwarf_Die *interface_die = 0, *origin_die = 0;
15805 if (die_is_artificial(die))
15809 bool has_spec = die_die_attribute(die, DW_AT_specification,
15811 bool has_abstract_origin =
15812 die_die_attribute(die, DW_AT_abstract_origin,
15813 abstract_origin_die,
true);
15814 if (has_spec || has_abstract_origin)
15819 : &abstract_origin_die;
15821 has_abstract_origin
15822 ? &abstract_origin_die
15825 string linkage_name = die_linkage_name(die);
15826 string spec_linkage_name = die_linkage_name(interface_die);
15828 interface_scope = get_scope_for_die(rdr, interface_die,
15829 called_from_public_decl,
15831 if (interface_scope)
15835 if (c && !linkage_name.empty())
15836 d = c->find_member_function_sptr(linkage_name);
15839 d =
is_decl(build_ir_node_from_die(rdr,
15841 interface_scope.get(),
15842 called_from_public_decl,
15844 is_declaration_only,
15848 fn = dynamic_pointer_cast<function_decl>(d);
15849 if (has_abstract_origin
15850 && (linkage_name != spec_linkage_name)
15851 && !c->find_member_function_sptr(linkage_name))
15861 rdr.scope_stack().push(scope);
15863 scope_decl* logical_scope =
15865 ? interface_scope.get()
15868 result = build_or_get_fn_decl_if_not_suppressed(rdr, logical_scope,
15870 is_declaration_only,
15877 && !is_required_decl_spec)
15889 sptr_utils::noop_deleter());
15891 finish_member_function_reading(die, fn, klass, rdr);
15896 rdr.maybe_add_fn_to_exported_decls(fn.get());
15897 rdr.associate_die_to_decl(die, fn, where_offset,
15899 maybe_canonicalize_type(fn->get_type(), rdr);
15902 rdr.scope_stack().pop();
15906 case DW_TAG_formal_parameter:
15911 case DW_TAG_constant:
15913 case DW_TAG_enumerator:
15916 case DW_TAG_partial_unit:
15917 case DW_TAG_imported_unit:
15924 case DW_TAG_dwarf_procedure:
15925 case DW_TAG_imported_declaration:
15926 case DW_TAG_entry_point:
15928 case DW_TAG_lexical_block:
15929 case DW_TAG_unspecified_parameters:
15930 case DW_TAG_variant:
15931 case DW_TAG_common_block:
15932 case DW_TAG_common_inclusion:
15933 case DW_TAG_inheritance:
15934 case DW_TAG_inlined_subroutine:
15935 case DW_TAG_with_stmt:
15936 case DW_TAG_access_declaration:
15937 case DW_TAG_catch_block:
15938 case DW_TAG_friend:
15939 case DW_TAG_namelist:
15940 case DW_TAG_namelist_item:
15941 case DW_TAG_template_type_parameter:
15942 case DW_TAG_template_value_parameter:
15943 case DW_TAG_try_block:
15944 case DW_TAG_variant_part:
15945 case DW_TAG_imported_module:
15946 case DW_TAG_condition:
15947 case DW_TAG_type_unit:
15948 case DW_TAG_template_alias:
15949 case DW_TAG_lo_user:
15950 case DW_TAG_MIPS_loop:
15951 case DW_TAG_format_label:
15952 case DW_TAG_function_template:
15953 case DW_TAG_class_template:
15954 case DW_TAG_GNU_BINCL:
15955 case DW_TAG_GNU_EINCL:
15956 case DW_TAG_GNU_template_template_param:
15957 case DW_TAG_GNU_template_parameter_pack:
15958 case DW_TAG_GNU_formal_parameter_pack:
15959 case DW_TAG_GNU_call_site:
15960 case DW_TAG_GNU_call_site_parameter:
15961 case DW_TAG_hi_user:
15966 if (result && tag != DW_TAG_subroutine_type)
15967 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
15971 if (rdr.load_all_types())
15972 if (called_from_public_decl)
15973 if (type_base_sptr t =
is_type(result))
15974 if (corpus *abi_corpus = scope->get_corpus())
15975 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15985 static decl_base_sptr
15986 build_ir_node_for_void_type(reader& rdr)
15988 const environment& env = rdr.env();
15990 type_base_sptr t = env.get_void_type();
15994 return type_declaration;
16009 build_ir_node_for_void_pointer_type(reader& rdr)
16011 const environment& env = rdr.env();
16013 type_base_sptr t = env.get_void_pointer_type();
16017 return type_declaration;
16025 static decl_base_sptr
16026 build_ir_node_for_variadic_parameter_type(reader &rdr)
16029 const environment& env = rdr.env();
16031 type_base_sptr t = env.get_variadic_parameter_type();
16035 return type_declaration;
16061 build_ir_node_from_die(reader& rdr,
16063 bool called_from_public_decl,
16064 size_t where_offset)
16067 return decl_base_sptr();
16072 return build_ir_node_from_die(rdr, die, scop.get(),
16073 called_from_public_decl,
16086 bool consider_as_called_from_public_decl =
16087 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
16089 consider_as_called_from_public_decl,
16091 return build_ir_node_from_die(rdr, die, scope.get(),
16092 called_from_public_decl,
16128 elf_based_reader_sptr
16130 const vector<char**>& debug_info_root_paths,
16131 environment& environment,
16132 bool load_all_types,
16133 bool linux_kernel_mode)
16136 reader_sptr r = reader::create(elf_path,
16137 debug_info_root_paths,
16140 linux_kernel_mode);
16180 const std::string& elf_path,
16181 const vector<char**>&debug_info_root_path,
16182 bool read_all_types,
16183 bool linux_kernel_mode)
16185 reader& r =
dynamic_cast<reader&
>(rdr);
16186 r.initialize(elf_path, debug_info_root_path,
16187 read_all_types, linux_kernel_mode);
16224 const vector<char**>& debug_info_root_paths,
16225 environment& environment,
16226 bool load_all_types,
16229 elf_based_reader_sptr rdr =
16230 dwarf::reader::create(elf_path, debug_info_root_paths,
16231 environment, load_all_types,
16234 return rdr->read_corpus(status);
16254 lookup_symbol_from_elf(
const environment& env,
16255 const string& elf_path,
16256 const string& symbol_name,
16258 vector<elf_symbol_sptr>& syms)
16261 if (elf_version(EV_CURRENT) == EV_NONE)
16264 int fd = open(elf_path.c_str(), O_RDONLY);
16272 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
16300 const string& path,
16301 const string& symname,
16302 vector<elf_symbol_sptr>& syms)
16304 if (elf_version(EV_CURRENT) == EV_NONE)
16307 int fd = open(path.c_str(), O_RDONLY);
16315 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_private, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
unordered_map< Dwarf_Off, function_type_sptr > die_function_type_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
shared_ptr< addr_elf_symbol_sptr_map_type > addr_elf_symbol_sptr_map_sptr
Convenience typedef for a shared pointer to an addr_elf_symbol_sptr_map_type.
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
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.
visibility
The visibility of the symbol.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
unordered_map< interned_string, dwarf_offsets_type, hash_interned_string > istring_dwarf_offsets_map_type
Convenience typedef for a map which is an interned_string and which value is a vector of offsets...
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
unordered_set< std::pair< offset_type, offset_type >, offset_pair_hash > offset_pair_set_type
A convenience typedef for an unordered set of pairs of offset_type.
The internal representation of an integral type.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
bool lookup_public_function_symbol_from_elf(environment &env, const string &path, const string &symname, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of an elf file to see if a public function of a given name is found...
Utilities to ease the wrapping of C types into std::shared_ptr.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
unordered_map< Dwarf_Off, interned_string > die_istring_map_type
Convenience typedef for a map which key is the offset of a DIE and the value is the corresponding qua...
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
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...
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
A functor to hash instances of interned_string.
status
The status of the fe_iface::read_corpus call.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
unordered_map< string, enums_type > string_enums_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
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.
This contains the declarations for the symtab reader.
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
unordered_map< string, classes_or_unions_type > string_classes_or_unions_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name...
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
Toplevel namespace for libabigail.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
scope_decl * get_scope() const
Return the type containing the current decl, if any.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
This contains the private implementation of the suppression engine of libabigail. ...
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section, the alternate debug info section or from the type unit section.
bool lookup_symbol_from_elf(const environment &env, const string &elf_path, const string &symbol_name, bool demangle, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of a given elf file and see if we find a given symbol.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name...
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
type
The type of a symbol.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
The source location of a token.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one...
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
unordered_map< Dwarf_Off, translation_unit_sptr > die_tu_map_type
Convenience typedef for a map which key is the offset of a DW_TAG_compile_unit and the value is the c...
unordered_map< Dwarf_Off, class_or_union_sptr > die_class_or_union_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
This contains the private implementation of the suppression engine of libabigail. ...
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
The common interface of readers based on ELF.
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...
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
unordered_map< string, classes_type > string_classes_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects...
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
binding
The binding of a symbol.
array_type_def * is_array_type(const type_or_decl_base *type)
Test if a type is an array_type_def.
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
language
The language of the translation unit.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
unordered_map< Dwarf_Off, Dwarf_Off > offset_offset_map_type
Convenience typedef for a map which key is a dwarf offset. The value is also a dwarf offset...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_set_type, offset_pair_hash > offset_pair_set_map_type
A convenience typedef for an unordered_map that associates a pair of offset_type to a set of pairs of...
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.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
This contains a set of ELF utilities used by the dwarf reader.
The abstraction of an interned string.
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
The abstraction of the version of an ELF symbol.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
unordered_map< interned_string, function_type_sptr, hash_interned_string > istring_fn_type_map_type
Convenience typedef for a map that associates an interned_string to a function_type_sptr.
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def, reference_type_def, or array_type_def node.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_vector_type, offset_pair_hash > offset_pair_vect_map_type
A convenience typedef for an unordered map that associates a pair of offset_type to a vector of pairs...
reference_type_def * is_reference_type(type_or_decl_base *t)
Test whether a type is a reference_type_def.
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
void canonicalize_types(const input_iterator &begin, const input_iterator &end, deref_lambda deref)
Compute the canonical type for all the IR types of the system.
access_specifier
Access specifier for class members.
The private data and functions of the abigail::ir::corpus type.
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
pointer_type_def * is_pointer_type(type_or_decl_base *t)
Test whether a type is a pointer_type_def.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
unordered_map< Dwarf_Off, type_or_decl_base_sptr > die_artefact_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
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...
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
CV
Bit field values representing the cv qualifiers of the underlying type.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...