14#include "abg-internal.h"
22#include <elfutils/libdwfl.h>
33#include <unordered_map>
34#include <unordered_set>
43ABG_BEGIN_EXPORT_DECLARATIONS
51ABG_END_EXPORT_DECLARATIONS
55#define UINT64_MAX 0xffffffffffffffff
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
71using std::unordered_map;
72using std::unordered_set;
79using namespace elf_helpers;
86 NO_DEBUG_INFO_DIE_SOURCE,
87 PRIMARY_DEBUG_INFO_DIE_SOURCE,
88 ALT_DEBUG_INFO_DIE_SOURCE,
90 NUMBER_OF_DIE_SOURCES,
138struct dwarf_offset_pair_hash
141 operator()(
const std::pair<Dwarf_Off, Dwarf_Off>& p)
const
142 {
return abigail::hashing::combine_hashes(p.first, p.second);}
145typedef unordered_set<std::pair<Dwarf_Off,
147 dwarf_offset_pair_hash> dwarf_offset_pair_set_type;
157 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
161 offset_type(
die_source source, Dwarf_Off offset)
166 offset_type(Dwarf_Off offset)
167 : source_(PRIMARY_DEBUG_INFO_DIE_SOURCE),
172 {
return source_ == o.source_ && offset_ == o.offset_;}
174 operator Dwarf_Off()
const
185 operator()(
const offset_type& p)
const
186 {
return abigail::hashing::combine_hashes(p.source_, p.offset_);}
191struct 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);
208typedef unordered_set<std::pair<offset_type,
217typedef unordered_map<std::pair<offset_type, offset_type>,
223typedef unordered_map<std::pair<offset_type, offset_type>,
233build_translation_unit_and_add_to_ir(reader& rdr,
238maybe_propagate_canonical_type(
const reader& rdr,
243propagate_canonical_type(
const reader& rdr,
285struct 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);
355typedef unordered_map<Dwarf_Off, imported_unit_points_type>
367operator<(
const imported_unit_point& l,
const imported_unit_point& r)
368{
return l.offset_of_import < r.offset_of_import;}
371get_parent_die(
const reader& rdr,
372 const Dwarf_Die* die,
373 Dwarf_Die& parent_die,
374 size_t where_offset);
377get_scope_die(
const reader& rdr,
378 const Dwarf_Die* die,
380 Dwarf_Die& scope_die);
383die_is_anonymous(
const Dwarf_Die* die);
386die_is_anonymous_data_member(
const Dwarf_Die* die);
389die_is_type(
const Dwarf_Die* die);
392die_is_decl(
const Dwarf_Die* die);
395die_is_declaration_only(Dwarf_Die* die);
398die_is_variable_decl(
const Dwarf_Die *die);
401die_is_function_decl(
const Dwarf_Die *die);
404die_has_size_attribute(
const Dwarf_Die *die);
407die_has_no_child(
const Dwarf_Die *die);
410die_is_namespace(
const Dwarf_Die* die);
413die_is_unspecified(Dwarf_Die* die);
416die_is_void_type(Dwarf_Die* die);
419die_is_pointer_type(
const Dwarf_Die* die);
422pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die);
425die_is_reference_type(
const Dwarf_Die* die);
428die_is_pointer_array_or_reference_type(
const Dwarf_Die* die);
431die_is_pointer_or_reference_type(
const Dwarf_Die* die);
434die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die);
437die_is_class_type(
const Dwarf_Die* die);
440die_is_qualified_type(
const Dwarf_Die* die);
443die_is_function_type(
const Dwarf_Die *die);
446die_has_object_pointer(
const Dwarf_Die* die,
447 Dwarf_Die& object_pointer);
450die_has_children(
const Dwarf_Die* die);
453die_this_pointer_from_object_pointer(Dwarf_Die* die,
454 Dwarf_Die& this_pointer);
457die_this_pointer_is_const(Dwarf_Die* die);
460die_object_pointer_is_for_const_method(Dwarf_Die* die);
463is_type_die_to_be_canonicalized(
const Dwarf_Die *die);
466die_is_at_class_scope(
const reader& rdr,
467 const Dwarf_Die* die,
469 Dwarf_Die& class_scope_die);
471eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
474 bool& is_tls_address);
477dwarf_language_to_tu_language(
size_t l);
480die_unsigned_constant_attribute(
const Dwarf_Die* die,
485die_signed_constant_attribute(
const Dwarf_Die*die,
490die_constant_attribute(
const Dwarf_Die *die,
493 array_type_def::subrange_type::bound_value &value);
496die_member_offset(
const reader& rdr,
497 const Dwarf_Die* die,
501form_is_DW_FORM_strx(
unsigned form);
504form_is_DW_FORM_line_strp(
unsigned form);
507die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result);
510die_name(
const Dwarf_Die* die);
513die_location(
const reader& rdr,
const Dwarf_Die* die);
516die_location_address(Dwarf_Die* die,
518 bool& is_tls_address);
521die_die_attribute(
const Dwarf_Die* die,
524 bool recursively =
true);
527subrange_die_indirect_bound_value(
const Dwarf_Die *die,
529 array_type_def::subrange_type::bound_value& v,
533subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
535 Dwarf_Die& referenced_subrange);
537get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
540build_internal_anonymous_die_name(
const string &
base_name,
541 size_t anonymous_type_index);
544get_internal_anonymous_die_name(Dwarf_Die *die,
545 size_t anonymous_type_index);
548die_qualified_type_name(
const reader& rdr,
549 const Dwarf_Die* die,
553die_qualified_decl_name(
const reader& rdr,
554 const Dwarf_Die* die,
558die_qualified_name(
const reader& rdr,
559 const Dwarf_Die* die,
563die_qualified_type_name_empty(
const reader& rdr,
564 const Dwarf_Die* die,
size_t where,
565 string &qualified_name);
568die_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,
579die_function_signature(
const reader& rdr,
580 const Dwarf_Die *die,
581 size_t where_offset);
584die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
587die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
590die_function_type_is_method_type(
const reader& rdr,
591 const Dwarf_Die *die,
593 Dwarf_Die& object_pointer_die,
594 Dwarf_Die& class_die,
598die_pretty_print_type(reader& rdr,
599 const Dwarf_Die* die,
600 size_t where_offset);
603die_pretty_print_decl(reader& rdr,
604 const Dwarf_Die* die,
605 size_t where_offset);
608die_pretty_print(reader& rdr,
609 const Dwarf_Die* die,
610 size_t where_offset);
613maybe_canonicalize_type(
const type_base_sptr& t,
622 imported_unit_points_type::const_iterator&);
625build_subrange_type(reader& rdr,
626 const Dwarf_Die* die,
628 bool associate_type_to_die =
true);
631build_subranges_from_array_type_die(reader& rdr,
632 const Dwarf_Die* die,
635 bool associate_type_to_die =
true);
638compare_dies(
const reader& rdr,
639 const Dwarf_Die *l,
const Dwarf_Die *r,
640 bool update_canonical_dies_on_the_fly);
643compare_dies_during_canonicalization(reader& rdr,
644 const Dwarf_Die *l,
const Dwarf_Die *r,
645 bool update_canonical_dies_on_the_fly);
648get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
662compare_symbol_name(
const string& symbol_name,
671 return symbol_name == name;
700lookup_symbol_from_sysv_hash_tab(
const environment& env,
702 const string& sym_name,
704 size_t sym_tab_index,
706 vector<elf_symbol_sptr>& syms_found)
708 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
711 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
714 GElf_Shdr sheader_mem;
715 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
717 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
722 unsigned long hash = elf_hash(sym_name.c_str());
723 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
724 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
725 size_t nb_buckets = ht_data[0];
726 size_t nb_chains = ht_data[1];
734 Elf32_Word* ht_buckets = &ht_data[2];
735 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
738 size_t bucket = hash % nb_buckets;
739 size_t symbol_index = ht_buckets[bucket];
742 const char* sym_name_str;
751 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
752 sym_name_str = elf_strptr(elf_handle,
753 sym_tab_section_header->sh_link,
756 && compare_symbol_name(sym_name_str, sym_name, demangle))
762 sym_size = symbol.st_size;
763 elf_symbol::version ver;
774 symbol.st_shndx != SHN_UNDEF,
775 symbol.st_shndx == SHN_COMMON,
776 ver, sym_visibility);
777 syms_found.push_back(symbol_found);
780 symbol_index = ht_chains[symbol_index];
781 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
792get_elf_class_size_in_bytes(Elf* elf_handle)
798 int c = hdr.e_ident[EI_CLASS];
832bloom_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;
907setup_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;
977lookup_symbol_from_gnu_hash_tab(
const environment& env,
979 const string& sym_name,
981 size_t sym_tab_index,
983 vector<elf_symbol_sptr>& syms_found)
986 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
992 size_t h1 = elf_gnu_hash(sym_name.c_str());
993 size_t h2 = h1 >> ht.shift;
996 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
997 int n = (h1 / c) % ht.bf_nwords;
1003 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1006 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1009 size_t i = ht.buckets[h1 % ht.nb_buckets];
1013 Elf32_Word stop_word, *stop_wordp;
1014 elf_symbol::version ver;
1016 const char* sym_name_str;
1025 for (i = ht.buckets[h1 % ht.nb_buckets],
1026 stop_wordp = &ht.chain[i - ht.first_sym_index];
1029 < ht.chain + (ht.sym_count - ht.first_sym_index));
1032 stop_word = *stop_wordp;
1033 if ((stop_word & ~ 1)!= (h1 & ~1))
1039 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1041 sym_name_str = elf_strptr(elf_handle,
1042 ht.sym_tab_section_header.sh_link,
1045 && compare_symbol_name(sym_name_str, sym_name, demangle))
1063 sym_type, sym_binding,
1064 symbol.st_shndx != SHN_UNDEF,
1065 symbol.st_shndx == SHN_COMMON,
1066 ver, sym_visibility);
1067 syms_found.push_back(symbol_found);
1109lookup_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,
1166lookup_symbol_from_symtab(
const environment& env,
1168 const string& sym_name,
1169 size_t sym_tab_index,
1171 vector<elf_symbol_sptr>& syms_found)
1176 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1179 GElf_Shdr header_mem;
1180 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1183 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1184 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1187 elf_symbol::version ver;
1190 for (
size_t i = 0; i < symcount; ++i)
1193 sym = gelf_getsym(symtab, i, &sym_mem);
1194 name_str = elf_strptr(elf_handle,
1195 sym_tab_header->sh_link,
1198 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1206 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1207 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1216 sym_binding, sym_is_defined,
1217 sym_is_common, ver, sym_visibility);
1218 syms_found.push_back(symbol_found);
1257lookup_symbol_from_elf(
const environment& env,
1259 const string& symbol_name,
1261 vector<elf_symbol_sptr>& syms_found)
1263 size_t hash_table_index = 0, symbol_table_index = 0;
1264 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1269 symbol_table_index);
1271 if (ht_kind == NO_HASH_TABLE_KIND)
1276 return lookup_symbol_from_symtab(env,
1284 return lookup_symbol_from_elf_hash_tab(env,
1308lookup_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();
1568class 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());}
1639struct 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);}
1700typedef shared_ptr<reader> reader_sptr;
1707class reader :
public elf_based_reader
1714 template <
typename ContainerType>
1715 class die_source_dependant_container_set
1717 ContainerType primary_debug_info_container_;
1718 ContainerType alt_debug_info_container_;
1719 ContainerType type_unit_container_;
1733 ContainerType *result = 0;
1736 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1737 result = &primary_debug_info_container_;
1739 case ALT_DEBUG_INFO_DIE_SOURCE:
1740 result = &alt_debug_info_container_;
1742 case TYPE_UNIT_DIE_SOURCE:
1743 result = &type_unit_container_;
1745 case NO_DEBUG_INFO_DIE_SOURCE:
1746 case NUMBER_OF_DIE_SOURCES:
1759 const ContainerType&
1762 return const_cast<die_source_dependant_container_set*
>(
this)->
1763 get_container(source);
1777 get_container(
const reader& rdr,
const Dwarf_Die *die)
1779 const die_source source = rdr.get_die_source(die);
1780 return get_container(source);
1793 const ContainerType&
1794 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1796 return const_cast<die_source_dependant_container_set*
>(
this)->
1797 get_container(rdr, die);
1804 primary_debug_info_container_.clear();
1805 alt_debug_info_container_.clear();
1806 type_unit_container_.clear();
1810 unsigned short dwarf_version_;
1811 Dwarf_Die* cur_tu_die_;
1812 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1816 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1817 decl_die_repr_die_offsets_maps_;
1821 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1822 type_die_repr_die_offsets_maps_;
1823 mutable die_source_dependant_container_set<die_istring_map_type>
1824 die_qualified_name_maps_;
1825 mutable die_source_dependant_container_set<die_istring_map_type>
1826 die_pretty_repr_maps_;
1827 mutable die_source_dependant_container_set<die_istring_map_type>
1828 die_pretty_type_repr_maps_;
1831 mutable die_source_dependant_container_set<die_artefact_map_type>
1832 decl_die_artefact_maps_;
1835 mutable die_source_dependant_container_set<die_artefact_map_type>
1836 type_die_artefact_maps_;
1839 mutable die_source_dependant_container_set<offset_offset_map_type>
1840 canonical_type_die_offsets_;
1843 mutable die_source_dependant_container_set<offset_offset_map_type>
1844 canonical_decl_die_offsets_;
1850 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1852 dwarf_offset_pair_hash> die_comparison_results_;
1862 vector<type_base_sptr> types_to_canonicalize_;
1881 list<var_decl_sptr> var_decls_to_add_;
1882#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1883 bool debug_die_canonicalization_is_on_;
1884 bool use_canonical_die_comparison_;
1886 mutable size_t compare_count_;
1887 mutable size_t canonical_propagated_count_;
1888 mutable size_t cancelled_propagation_count_;
1889 mutable optional<bool> leverage_dwarf_factorization_;
1924 reader(
const string& elf_path,
1925 const vector<char**>& debug_info_root_paths,
1926 environment& environment,
1927 bool load_all_types,
1928 bool linux_kernel_mode)
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();
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)
2075 if ((status & STATUS_NO_SYMBOLS_FOUND)
2076 || !(status & STATUS_OK))
2080 return corpus_sptr();
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);
2141 corpus()->set_symtab(symtab());
2146 || !
corpus()->get_symtab()->has_symbols())
2149 uint8_t address_size = 0;
2150 size_t header_size = 0;
2152#ifdef WITH_DEBUG_SELF_COMPARISON
2153 if (env().self_comparison_debug_is_on())
2154 env().set_self_comparison_debug_input(
corpus());
2160 tools_utils::timer t;
2163 cerr <<
"building die -> parent maps ...";
2167 build_die_parent_maps();
2172 cerr <<
" DONE@" <<
corpus()->get_path()
2179 env().canonicalization_is_done(
false);
2182 tools_utils::timer t;
2185 cerr <<
"building the libabigail internal representation ...";
2189 Dwarf_Half dwarf_vers = 0;
2190 for (Dwarf_Off offset = 0, next_offset = 0;
2192 offset, &next_offset, &header_size,
2193 &dwarf_vers, NULL, &address_size, NULL,
2195 offset = next_offset)
2197 Dwarf_Off die_offset = offset + header_size;
2201 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2204 dwarf_version(dwarf_vers);
2211 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2217 cerr <<
" DONE@" <<
corpus()->get_path()
2222 cerr <<
"Number of aggregate types compared: "
2223 << compare_count_ <<
"\n"
2224 <<
"Number of canonical types propagated: "
2225 << canonical_propagated_count_ <<
"\n"
2226 <<
"Number of cancelled propagated canonical types:"
2227 << cancelled_propagation_count_ <<
"\n";
2232 tools_utils::timer t;
2235 cerr <<
"resolving declaration only classes ...";
2238 resolve_declaration_only_classes();
2242 cerr <<
" DONE@" <<
corpus()->get_path()
2250 tools_utils::timer t;
2253 cerr <<
"resolving declaration only enums ...";
2256 resolve_declaration_only_enums();
2260 cerr <<
" DONE@" <<
corpus()->get_path()
2268 tools_utils::timer t;
2271 cerr <<
"fixing up functions with linkage name but "
2272 <<
"no advertised underlying symbols ....";
2275 fixup_functions_with_no_symbols();
2279 cerr <<
" DONE@" <<
corpus()->get_path()
2298 tools_utils::timer t;
2301 cerr <<
"perform late type canonicalizing ...\n";
2305 perform_late_type_canonicalizing();
2309 cerr <<
"late type canonicalizing DONE@"
2317 env().canonicalization_is_done(
true);
2320 tools_utils::timer t;
2323 cerr <<
"sort functions and variables ...";
2326 corpus()->sort_functions();
2327 corpus()->sort_variables();
2331 cerr <<
" DONE@" <<
corpus()->get_path()
2345 clear_per_translation_unit_data()
2347 while (!scope_stack().empty())
2348 scope_stack().pop();
2349 var_decls_to_re_add_to_tree().clear();
2350 per_tu_repr_to_fn_type_maps().clear();
2356 clear_per_corpus_data()
2358 die_qualified_name_maps_.clear();
2359 die_pretty_repr_maps_.clear();
2360 die_pretty_type_repr_maps_.clear();
2361 clear_types_to_canonicalize();
2376 {
return const_cast<reader*
>(
this)->env();}
2384 drop_undefined_syms()
const
2385 {
return options().drop_undefined_syms;}
2392 drop_undefined_syms(
bool f)
2393 {
options().drop_undefined_syms = f;}
2397 dwarf_version()
const
2398 {
return dwarf_version_;}
2401 dwarf_version(
unsigned short v)
2402 {dwarf_version_ = v;}
2414 dwarf_elf_handle()
const
2425 dwarf_is_splitted()
const
2426 {
return dwarf_elf_handle() != elf_handle();}
2435 dwarf_per_die_source(
die_source source)
const
2437 const Dwarf *result = 0;
2440 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2441 case TYPE_UNIT_DIE_SOURCE:
2444 case ALT_DEBUG_INFO_DIE_SOURCE:
2447 case NO_DEBUG_INFO_DIE_SOURCE:
2448 case NUMBER_OF_DIE_SOURCES:
2463 {
return cur_tu_die_;}
2466 cur_tu_die(Dwarf_Die* cur_tu_die)
2467 {cur_tu_die_ = cur_tu_die;}
2469 dwarf_expr_eval_context&
2470 dwarf_expr_eval_ctxt()
const
2471 {
return dwarf_expr_eval_context_;}
2478 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2479 decl_die_repr_die_offsets_maps()
const
2480 {
return decl_die_repr_die_offsets_maps_;}
2487 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2488 decl_die_repr_die_offsets_maps()
2489 {
return decl_die_repr_die_offsets_maps_;}
2496 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2497 type_die_repr_die_offsets_maps()
const
2498 {
return type_die_repr_die_offsets_maps_;}
2505 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2506 type_die_repr_die_offsets_maps()
2507 {
return type_die_repr_die_offsets_maps_;}
2520 compute_canonical_die_offset(
const Dwarf_Die *die,
2521 Dwarf_Off &canonical_die_offset,
2522 bool die_as_type)
const
2526 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2527 get_container(*
this, die)
2528 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2529 get_container(*
this, die);
2531 Dwarf_Die canonical_die;
2532 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2534 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2552 compute_canonical_die(
const Dwarf_Die *die,
2554 Dwarf_Die &canonical_die,
2555 bool die_as_type)
const
2557 const die_source source = get_die_source(die);
2559 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2561 compute_canonical_die(die_offset, source,
2563 canonical_die, die_as_type);
2583 compute_canonical_die(Dwarf_Off die_offset,
2586 Dwarf_Die &canonical_die,
2587 bool die_as_type)
const
2593 ? (
const_cast<reader*
>(
this)->
2594 type_die_repr_die_offsets_maps().get_container(source))
2595 : (
const_cast<reader*
>(
this)->
2596 decl_die_repr_die_offsets_maps().get_container(source));
2599 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2608 interned_string name =
2610 ? get_die_pretty_type_representation(&die, 0)
2611 : get_die_pretty_representation(&die, 0);
2613 Dwarf_Off canonical_die_offset = 0;
2614 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2618 offsets.push_back(die_offset);
2619 map[name] = offsets;
2620 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2621 get_die_from_offset(source, die_offset, &canonical_die);
2625 Dwarf_Off cur_die_offset;
2626 Dwarf_Die potential_canonical_die;
2627 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2628 o != i->second.end();
2631 cur_die_offset = *o;
2632 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2633 if (compare_dies(*
this, &die, &potential_canonical_die,
2636 canonical_die_offset = cur_die_offset;
2637 set_canonical_die_offset(canonical_dies, die_offset,
2638 canonical_die_offset);
2639 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2644 canonical_die_offset = die_offset;
2645 i->second.push_back(die_offset);
2646 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2647 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2666 get_canonical_die(
const Dwarf_Die *die,
2667 Dwarf_Die &canonical_die,
2671 const die_source source = get_die_source(die);
2675 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2676 get_container(source)
2677 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2678 get_container(source);
2680 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2681 if (Dwarf_Off canonical_die_offset =
2682 get_canonical_die_offset(canonical_dies, die_offset))
2684 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2692 ? (
const_cast<reader*
>(
this)->
2693 type_die_repr_die_offsets_maps().get_container(*
this, die))
2694 : (
const_cast<reader*
>(
this)->
2695 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2703 interned_string name =
2705 ? get_die_pretty_type_representation(die, where)
2706 : get_die_pretty_representation(die, where);
2708 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2712 Dwarf_Off cur_die_offset;
2713 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2714 o != i->second.end();
2717 cur_die_offset = *o;
2718 get_die_from_offset(source, cur_die_offset, &canonical_die);
2720 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2721 die, &canonical_die,
2724 set_canonical_die_offset(canonical_dies,
2758 get_or_compute_canonical_die(
const Dwarf_Die* die,
2759 Dwarf_Die& canonical_die,
2761 bool die_as_type)
const
2763 const die_source source = get_die_source(die);
2767 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2768 get_container(source)
2769 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2770 get_container(source);
2772 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2774 if (Dwarf_Off canonical_die_offset =
2775 get_canonical_die_offset(canonical_dies,
2776 initial_die_offset))
2778 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2782 if (!is_type_die_to_be_canonicalized(die))
2789 ? (
const_cast<reader*
>(
this)->
2790 type_die_repr_die_offsets_maps().get_container(*
this, die))
2791 : (
const_cast<reader*
>(
this)->
2792 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2800 interned_string name =
2802 ? get_die_pretty_type_representation(die, where)
2803 : get_die_pretty_representation(die, where);
2805 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2809 offsets.push_back(initial_die_offset);
2810 map[name] = offsets;
2811 get_die_from_offset(source, initial_die_offset, &canonical_die);
2812 set_canonical_die_offset(canonical_dies,
2814 initial_die_offset);
2821 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2824 Dwarf_Off die_offset = i->second[n];
2825 get_die_from_offset(source, die_offset, &canonical_die);
2827 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2828 die, &canonical_die,
2831 set_canonical_die_offset(canonical_dies,
2841 get_die_from_offset(source, initial_die_offset, &canonical_die);
2842 i->second.push_back(initial_die_offset);
2843 set_canonical_die_offset(canonical_dies,
2845 initial_die_offset);
2862 get_die_source(
const Dwarf_Die *die)
const
2864 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2885 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2889 uint8_t address_size = 0, offset_size = 0;
2890 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
2891 &cu_die, &address_size,
2895 Dwarf_Half version = 0;
2896 Dwarf_Off abbrev_offset = 0;
2897 uint64_t type_signature = 0;
2898 Dwarf_Off type_offset = 0;
2899 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2900 &version, &abbrev_offset,
2901 &address_size, &offset_size,
2902 &type_signature, &type_offset))
2905 int tag = dwarf_tag(&cu_kind);
2907 if (tag == DW_TAG_compile_unit
2908 || tag == DW_TAG_partial_unit)
2910 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
2912 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
2914 source = ALT_DEBUG_INFO_DIE_SOURCE;
2918 else if (tag == DW_TAG_type_unit)
2919 source = TYPE_UNIT_DIE_SOURCE;
2935 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
2937 if (source == TYPE_UNIT_DIE_SOURCE)
2938 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2941 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2968 associate_die_to_decl(Dwarf_Die* die,
2969 decl_base_sptr decl,
2970 size_t where_offset,
2971 bool do_associate_by_repr =
false)
2973 const die_source source = get_die_source(die);
2976 decl_die_artefact_maps().get_container(source);
2979 if (do_associate_by_repr)
2981 Dwarf_Die equiv_die;
2982 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
2985 die_offset = dwarf_dieoffset(&equiv_die);
2988 die_offset = dwarf_dieoffset(die);
2990 m[die_offset] = decl;
3012 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3014 decl_base_sptr result =
3015 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3034 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3038 die_qualified_name_maps_.get_container(*
this, die);
3040 size_t die_offset = dwarf_dieoffset(die);
3041 die_istring_map_type::const_iterator i = map.find(die_offset);
3045 reader& rdr = *
const_cast<reader*
>(
this);
3046 string qualified_name = die_qualified_name(rdr, die, where_offset);
3047 interned_string istr = env().intern(qualified_name);
3048 map[die_offset] = istr;
3068 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3070 return const_cast<reader*
>(
this)->
3071 get_die_qualified_name(die, where_offset);
3092 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3097 if (die == cur_tu_die())
3098 return env().intern(
"");
3101 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3104 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3105 die_istring_map_type::const_iterator i =
3106 map.find(die_offset);
3110 reader& rdr = *
const_cast<reader*
>(
this);
3111 string qualified_name;
3112 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3113 if ((tag == DW_TAG_structure_type
3114 || tag == DW_TAG_class_type
3115 || tag == DW_TAG_union_type)
3116 && die_is_anonymous(die))
3118 location l = die_location(*
this, die);
3119 qualified_name = l ? l.expand() :
"noloc";
3120 qualified_name =
"unnamed-at-" + qualified_name;
3124 die_qualified_type_name(rdr, die, where_offset);
3126 interned_string istr = env().intern(qualified_name);
3127 map[die_offset] = istr;
3151 get_die_pretty_type_representation(
const Dwarf_Die *die,
3152 size_t where_offset)
const
3156 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3159 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3160 die_istring_map_type::const_iterator i = map.find(die_offset);
3164 reader& rdr = *
const_cast<reader*
>(
this);
3165 string pretty_representation =
3166 die_pretty_print_type(rdr, die, where_offset);
3167 interned_string istr = env().intern(pretty_representation);
3168 map[die_offset] = istr;
3188 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3193 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3196 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3197 die_istring_map_type::const_iterator i = map.find(die_offset);
3201 reader& rdr = *
const_cast<reader*
>(
this);
3202 string pretty_representation =
3203 die_pretty_print(rdr, die, where_offset);
3204 interned_string istr = env().intern(pretty_representation);
3205 map[die_offset] = istr;
3229 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3232 lookup_artifact_from_die(die,
true);
3234 return fn->get_type();
3258 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3260 Dwarf_Die equiv_die;
3261 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3266 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3267 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3269 size_t die_offset = dwarf_dieoffset(&equiv_die);
3270 die_artefact_map_type::const_iterator i = m.find(die_offset);
3297 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3299 bool die_as_type =
false)
const
3303 ? type_die_artefact_maps().get_container(source)
3304 : decl_die_artefact_maps().get_container(source);
3306 die_artefact_map_type::const_iterator i = m.find(die_offset);
3323 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
3326 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
3329 lang = dwarf_language_to_tu_language(l);
3341 die_is_in_c(
const Dwarf_Die *die)
const
3344 if (!get_die_language(die, l))
3357 die_is_in_cplus_plus(
const Dwarf_Die *die)
const
3360 if (!get_die_language(die, l))
3373 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
const
3376 if (!get_die_language(die, l))
3418 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3433 if (!get_die_language(die, lang))
3444 die_source_dependant_container_set<die_artefact_map_type>&
3445 decl_die_artefact_maps()
3446 {
return decl_die_artefact_maps_;}
3453 const die_source_dependant_container_set<die_artefact_map_type>&
3454 decl_die_artefact_maps()
const
3455 {
return decl_die_artefact_maps_;}
3462 die_source_dependant_container_set<die_artefact_map_type>&
3463 type_die_artefact_maps()
3464 {
return type_die_artefact_maps_;}
3471 const die_source_dependant_container_set<die_artefact_map_type>&
3472 type_die_artefact_maps()
const
3473 {
return type_die_artefact_maps_;}
3481 per_tu_repr_to_fn_type_maps()
3482 {
return per_tu_repr_to_fn_type_maps_;}
3490 per_tu_repr_to_fn_type_maps()
const
3491 {
return per_tu_repr_to_fn_type_maps_;}
3501 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3504 if (!die_is_function_type(die))
3507 interned_string repr =
3508 get_die_pretty_type_representation(die, 0);
3511 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3522 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3524 if (!die_is_function_type(die))
3527 interned_string repr = die_name(die).empty() ?
3528 get_die_pretty_type_representation(die, 0)
3529 : get_die_pretty_representation(die, 0);
3532 istring_fn_type_map_type::const_iterator i =
3533 per_tu_repr_to_fn_type_maps().find(repr);
3535 if (i == per_tu_repr_to_fn_type_maps().end())
3552 Dwarf_Off die_offset,
3553 Dwarf_Off canonical_die_offset)
const
3555 canonical_dies[die_offset] = canonical_die_offset;}
3571 set_canonical_die_offset(Dwarf_Off die_offset,
3573 Dwarf_Off canonical_die_offset,
3574 bool die_as_type)
const
3578 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3579 get_container(source)
3580 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3581 get_container(source);
3583 set_canonical_die_offset(canonical_dies,
3585 canonical_die_offset);
3599 set_canonical_die_offset(
const Dwarf_Die *die,
3600 Dwarf_Off canonical_die_offset,
3601 bool die_as_type)
const
3603 const die_source source = get_die_source(die);
3605 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3607 set_canonical_die_offset(die_offset, source,
3608 canonical_die_offset,
3622 Dwarf_Off die_offset)
const
3624 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3625 if (it == canonical_dies.end())
3642 get_canonical_die_offset(Dwarf_Off die_offset,
3644 bool die_as_type)
const
3648 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3649 get_container(source)
3650 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3651 get_container(source);
3653 return get_canonical_die_offset(canonical_dies, die_offset);
3668 erase_canonical_die_offset(Dwarf_Off die_offset,
3670 bool die_as_type)
const
3674 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3675 get_container(source)
3676 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3677 get_container(source);
3679 return canonical_dies.erase(die_offset);
3692 associate_die_to_type(
const Dwarf_Die *die,
3693 type_base_sptr type,
3699 Dwarf_Die equiv_die;
3700 if (!get_or_compute_canonical_die(die, equiv_die, where,
3705 type_die_artefact_maps().get_container(*
this, &equiv_die);
3707 size_t die_offset = dwarf_dieoffset(&equiv_die);
3708 m[die_offset] = type;
3722 lookup_type_from_die(
const Dwarf_Die* die)
const
3725 lookup_artifact_from_die(die,
true);
3727 return fn->get_type();
3745 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3747 type_base_sptr result;
3749 type_die_artefact_maps().get_container(source);
3750 die_artefact_map_type::const_iterator i = m.find(die_offset);
3754 return fn->get_type();
3762 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3772 die_wip_function_types_map(source);
3773 die_function_type_map_type::const_iterator i = m.find(die_offset);
3792 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3807 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3809 case ALT_DEBUG_INFO_DIE_SOURCE:
3810 return alternate_die_wip_classes_map_;
3811 case TYPE_UNIT_DIE_SOURCE:
3812 return type_unit_die_wip_classes_map_;
3813 case NO_DEBUG_INFO_DIE_SOURCE:
3814 case NUMBER_OF_DIE_SOURCES:
3817 return die_wip_classes_map_;
3828 die_wip_function_types_map(
die_source source)
const
3829 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3839 die_wip_function_types_map(
die_source source)
3843 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3845 case ALT_DEBUG_INFO_DIE_SOURCE:
3846 return alternate_die_wip_function_types_map_;
3847 case TYPE_UNIT_DIE_SOURCE:
3848 return type_unit_die_wip_function_types_map_;
3849 case NO_DEBUG_INFO_DIE_SOURCE:
3850 case NUMBER_OF_DIE_SOURCES:
3853 return die_wip_function_types_map_;
3864 die_function_decl_with_no_symbol_map()
3865 {
return die_function_with_no_symbol_map_;}
3878 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3880 die_class_or_union_map_type::const_iterator i =
3881 die_wip_classes_map(source).find(offset);
3882 return (i != die_wip_classes_map(source).end());
3896 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3898 die_function_type_map_type::const_iterator i =
3899 die_wip_function_types_map(source).find(offset);
3900 return (i != die_wip_function_types_map(source).end());
3919 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3925 || dwarf_tag(die) != DW_TAG_member
3926 || !die_name(die).empty())
3932 if (die_is_anonymous_data_member(die))
3938 int64_t offset_in_bits = 0;
3939 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3943 loc = die_location(*
this, die);
3948 std::ostringstream o;
3949 o <<
"unnamed-dm-@-";
3951 o <<
"offset-" << offset_in_bits <<
"bits";
3953 o <<
"loc-" << loc.expand();
3966 declaration_only_classes()
const
3967 {
return decl_only_classes_map_;}
3977 declaration_only_classes()
3978 {
return decl_only_classes_map_;}
3986 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
3988 if (cou->get_is_declaration_only()
3989 && cou->get_definition_of_declaration() == 0)
3991 string qn = cou->get_qualified_name();
3992 string_classes_or_unions_map::iterator record =
3993 declaration_only_classes().find(qn);
3994 if (record == declaration_only_classes().end())
3995 declaration_only_classes()[qn].push_back(cou);
3997 record->second.push_back(cou);
4009 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4011 if (cou->get_is_declaration_only())
4012 return (declaration_only_classes().find(cou->get_qualified_name())
4013 != declaration_only_classes().end());
4033 const environment& e = l->get_environment();
4036 e.priv_->allow_type_comparison_results_caching(
true);
4037 bool s0 = e.decl_only_class_equals_definition();
4038 e.decl_only_class_equals_definition(
true);
4039 bool equal = l == r;
4040 e.decl_only_class_equals_definition(s0);
4041 e.priv_->clear_type_comparison_results_cache();
4042 e.priv_->allow_type_comparison_results_caching(
false);
4049 resolve_declaration_only_classes()
4051 vector<string> resolved_classes;
4053 for (string_classes_or_unions_map::iterator i =
4054 declaration_only_classes().begin();
4055 i != declaration_only_classes().end();
4058 bool to_resolve =
false;
4059 for (classes_or_unions_type::iterator j = i->second.begin();
4060 j != i->second.end();
4062 if ((*j)->get_is_declaration_only()
4063 && ((*j)->get_definition_of_declaration() == 0))
4068 resolved_classes.push_back(i->first);
4113 map<string, class_or_union_sptr> per_tu_class_map;
4114 for (type_base_wptrs_type::const_iterator c = classes->begin();
4115 c != classes->end();
4122 if (klass->get_is_declaration_only())
4125 string tu_path = klass->get_translation_unit()->get_absolute_path();
4126 if (tu_path.empty())
4132 per_tu_class_map[tu_path] = klass;
4135 if (!per_tu_class_map.empty())
4141 for (classes_or_unions_type::iterator j = i->second.begin();
4142 j != i->second.end();
4145 if ((*j)->get_is_declaration_only()
4146 && ((*j)->get_definition_of_declaration() == 0))
4149 (*j)->get_translation_unit()->get_absolute_path();
4150 map<string, class_or_union_sptr>::const_iterator e =
4151 per_tu_class_map.find(tu_path);
4152 if (e != per_tu_class_map.end())
4153 (*j)->set_definition_of_declaration(e->second);
4154 else if (per_tu_class_map.size() == 1)
4155 (*j)->set_definition_of_declaration
4156 (per_tu_class_map.begin()->second);
4166 class_or_union_sptr>::const_iterator it;
4167 class_or_union_sptr first_class =
4168 per_tu_class_map.begin()->second;
4169 bool all_class_definitions_are_equal =
true;
4170 for (it = per_tu_class_map.begin();
4171 it != per_tu_class_map.end();
4174 if (it == per_tu_class_map.begin())
4178 if (!compare_before_canonicalisation(it->second,
4181 all_class_definitions_are_equal =
false;
4186 if (all_class_definitions_are_equal)
4187 (*j)->set_definition_of_declaration(first_class);
4191 resolved_classes.push_back(i->first);
4195 size_t num_decl_only_classes = declaration_only_classes().size(),
4196 num_resolved = resolved_classes.size();
4198 cerr <<
"resolved " << num_resolved
4199 <<
" class declarations out of "
4200 << num_decl_only_classes
4203 for (vector<string>::const_iterator i = resolved_classes.begin();
4204 i != resolved_classes.end();
4206 declaration_only_classes().erase(*i);
4208 if (show_stats() && !declaration_only_classes().empty())
4210 cerr <<
"Here are the "
4211 << num_decl_only_classes - num_resolved
4212 <<
" unresolved class declarations:\n";
4213 for (string_classes_or_unions_map::iterator i =
4214 declaration_only_classes().begin();
4215 i != declaration_only_classes().end();
4217 cerr <<
" " << i->first <<
"\n";
4229 declaration_only_enums()
const
4230 {
return decl_only_enums_map_;}
4240 declaration_only_enums()
4241 {
return decl_only_enums_map_;}
4251 if (enom->get_is_declaration_only()
4252 && enom->get_definition_of_declaration() == 0)
4254 string qn = enom->get_qualified_name();
4255 string_enums_map::iterator record =
4256 declaration_only_enums().find(qn);
4257 if (record == declaration_only_enums().end())
4258 declaration_only_enums()[qn].push_back(enom);
4260 record->second.push_back(enom);
4274 if (enom->get_is_declaration_only())
4275 return (declaration_only_enums().find(enom->get_qualified_name())
4276 != declaration_only_enums().end());
4289 resolve_declaration_only_enums()
4291 vector<string> resolved_enums;
4293 for (string_enums_map::iterator i =
4294 declaration_only_enums().begin();
4295 i != declaration_only_enums().end();
4298 bool to_resolve =
false;
4299 for (enums_type::iterator j = i->second.begin();
4300 j != i->second.end();
4302 if ((*j)->get_is_declaration_only()
4303 && ((*j)->get_definition_of_declaration() == 0))
4308 resolved_enums.push_back(i->first);
4350 map<string, enum_type_decl_sptr> per_tu_enum_map;
4351 for (type_base_wptrs_type::const_iterator c = enums->begin();
4359 if (enom->get_is_declaration_only())
4362 string tu_path = enom->get_translation_unit()->get_absolute_path();
4363 if (tu_path.empty())
4369 per_tu_enum_map[tu_path] = enom;
4372 if (!per_tu_enum_map.empty())
4378 for (enums_type::iterator j = i->second.begin();
4379 j != i->second.end();
4382 if ((*j)->get_is_declaration_only()
4383 && ((*j)->get_definition_of_declaration() == 0))
4386 (*j)->get_translation_unit()->get_absolute_path();
4387 map<string, enum_type_decl_sptr>::const_iterator e =
4388 per_tu_enum_map.find(tu_path);
4389 if (e != per_tu_enum_map.end())
4390 (*j)->set_definition_of_declaration(e->second);
4391 else if (per_tu_enum_map.size() == 1)
4392 (*j)->set_definition_of_declaration
4393 (per_tu_enum_map.begin()->second);
4405 per_tu_enum_map.begin()->second;
4406 bool all_enum_definitions_are_equal =
true;
4407 for (it = per_tu_enum_map.begin();
4408 it != per_tu_enum_map.end();
4411 if (it == per_tu_enum_map.begin())
4415 if (!compare_before_canonicalisation(it->second,
4418 all_enum_definitions_are_equal =
false;
4423 if (all_enum_definitions_are_equal)
4424 (*j)->set_definition_of_declaration(first_enum);
4428 resolved_enums.push_back(i->first);
4432 size_t num_decl_only_enums = declaration_only_enums().size(),
4433 num_resolved = resolved_enums.size();
4435 cerr <<
"resolved " << num_resolved
4436 <<
" enum declarations out of "
4437 << num_decl_only_enums
4440 for (vector<string>::const_iterator i = resolved_enums.begin();
4441 i != resolved_enums.end();
4443 declaration_only_enums().erase(*i);
4445 if (show_stats() && !declaration_only_enums().empty())
4447 cerr <<
"Here are the "
4448 << num_decl_only_enums - num_resolved
4449 <<
" unresolved enum declarations:\n";
4450 for (string_enums_map::iterator i = declaration_only_enums().begin();
4451 i != declaration_only_enums().end();
4453 cerr <<
" " << i->first <<
"\n";
4469 corpus_sptr corp =
corpus();
4473 string id = fn->get_id_string();
4475 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4480 if (f->get_symbol())
4500 fixup_functions_with_no_symbols()
4502 corpus_sptr corp =
corpus();
4507 die_function_decl_with_no_symbol_map();
4510 cerr << fns_with_no_symbol.size()
4511 <<
" functions to fixup, potentially\n";
4513 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4514 i != fns_with_no_symbol.end();
4517 corp->lookup_function_symbol(i->second->get_linkage_name()))
4532 if (i->second->get_symbol()
4533 || symbol_already_belongs_to_a_function(sym))
4538 i->second->set_symbol(sym);
4541 i->second->set_is_in_public_symbol_table(
true);
4546 cerr <<
"fixed up '"
4547 << i->second->get_pretty_representation()
4548 <<
"' with symbol '"
4549 << sym->get_id_string()
4553 fns_with_no_symbol.clear();
4563 const vector<type_base_sptr>&
4564 types_to_canonicalize()
const
4565 {
return types_to_canonicalize_;}
4569 clear_types_to_canonicalize()
4571 types_to_canonicalize_.clear();
4579 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4581 types_to_canonicalize_.push_back(t);
4591 canonicalize_types_scheduled()
4593 tools_utils::timer cn_timer;
4596 cerr <<
"going to canonicalize types";
4597 corpus_sptr c =
corpus();
4599 cerr <<
" of corpus " <<
corpus()->get_path();
4603 if (!types_to_canonicalize().empty())
4605 types_to_canonicalize().end(),
4606 [](
const vector<type_base_sptr>::const_iterator& i)
4612 cerr <<
"finished canonicalizing types";
4613 corpus_sptr c =
corpus();
4615 cerr <<
" of corpus " <<
corpus()->get_path();
4616 cerr <<
": (" << cn_timer <<
")\n";
4633 add_late_canonicalized_types_stats(
size_t& canonicalized,
4634 size_t& missed)
const
4636 for (
auto t : types_to_canonicalize())
4638 if (t->get_canonical_type())
4648 perform_late_type_canonicalizing()
4650 canonicalize_types_scheduled();
4654 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4655 add_late_canonicalized_types_stats(num_canonicalized,
4657 total = num_canonicalized + num_missed;
4661 cerr <<
" # late canonicalized types: "
4662 << num_canonicalized;
4664 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4666 <<
" # missed canonicalization opportunities: "
4669 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4677 {
return die_tu_map_;}
4681 {
return die_tu_map_;}
4690 tu_die_imported_unit_points_map(
die_source source)
const
4691 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4700 tu_die_imported_unit_points_map(
die_source source)
4704 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4706 case ALT_DEBUG_INFO_DIE_SOURCE:
4707 return alt_tu_die_imported_unit_points_map_;
4708 case TYPE_UNIT_DIE_SOURCE:
4709 return type_units_tu_die_imported_unit_points_map_;
4710 case NO_DEBUG_INFO_DIE_SOURCE:
4711 case NUMBER_OF_DIE_SOURCES:
4715 return tu_die_imported_unit_points_map_;
4733 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4746 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4748 case ALT_DEBUG_INFO_DIE_SOURCE:
4749 return alternate_die_parent_map_;
4750 case TYPE_UNIT_DIE_SOURCE:
4751 return type_section_die_parent_map();
4752 case NO_DEBUG_INFO_DIE_SOURCE:
4753 case NUMBER_OF_DIE_SOURCES:
4756 return primary_die_parent_map_;
4760 type_section_die_parent_map()
const
4761 {
return type_section_die_parent_map_;}
4764 type_section_die_parent_map()
4765 {
return type_section_die_parent_map_;}
4771 cur_transl_unit()
const
4795 global_scope()
const
4796 {
return cur_transl_unit()->get_global_scope();}
4803 {
return nil_scope_;}
4807 {
return scope_stack_;}
4811 {
return scope_stack_;}
4816 if (scope_stack().empty())
4818 if (cur_transl_unit())
4821 return scope_stack().top();
4824 list<var_decl_sptr>&
4825 var_decls_to_re_add_to_tree()
4826 {
return var_decls_to_add_;}
4839 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
4841 if (!die || !die_is_decl(die))
4844 bool result =
false, address_found =
false, symbol_is_exported =
false;;
4845 Dwarf_Addr decl_symbol_address = 0;
4847 if (die_is_variable_decl(die))
4849 if ((address_found = get_variable_address(die, decl_symbol_address)))
4850 symbol_is_exported =
4853 else if (die_is_function_decl(die))
4855 if ((address_found = get_function_address(die, decl_symbol_address)))
4856 symbol_is_exported =
4861 result = symbol_is_exported;
4880 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
4886 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
4888 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4890 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4892 dwarf_elf_load_address));
4895 if (dwarf_is_splitted()
4896 && (dwarf_elf_load_address != elf_load_address))
4907 addr = addr - dwarf_elf_load_address + elf_load_address;
4933 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
4938 Elf* elf = elf_handle();
4940 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4942 if (elf_header->e_type == ET_REL)
4955 addr = maybe_adjust_address_for_exec_or_dyn(addr);
4980 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
4982 Elf* elf = elf_handle();
4984 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4986 if (elf_header->e_type == ET_REL)
4999 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5018 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5019 Dwarf_Addr& address)
const
5022 Dwarf_Addr end_addr;
5023 ptrdiff_t offset = 0;
5027 Dwarf_Addr addr = 0, fn_addr = 0;
5028 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5030 fn_addr = maybe_adjust_fn_sym_address(addr);
5037 }
while (offset > 0);
5055 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5057 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5058 DW_AT_low_pc, address))
5064 if (!get_first_exported_fn_address_from_DW_AT_ranges
5065 (
const_cast<Dwarf_Die*
>(function_die),
5069 address = maybe_adjust_fn_sym_address(address);
5088 get_variable_address(
const Dwarf_Die* variable_die,
5089 Dwarf_Addr& address)
const
5091 bool is_tls_address =
false;
5092 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5093 address, is_tls_address))
5095 if (!is_tls_address)
5096 address = maybe_adjust_var_sym_address(address);
5103 corpus::exported_decls_builder*
5104 exported_decls_builder()
5105 {
return corpus()->get_exported_decls_builder().get();}
5113 load_all_types()
const
5114 {
return options().load_all_types;}
5122 load_all_types(
bool f)
5123 {
options().load_all_types = f;}
5126 load_in_linux_kernel_mode()
const
5127 {
return options().load_in_linux_kernel_mode;}
5130 load_in_linux_kernel_mode(
bool f)
5131 {
options().load_in_linux_kernel_mode = f;}
5141 leverage_dwarf_factorization()
const
5143 if (!leverage_dwarf_factorization_.has_value())
5145 if (
options().leverage_dwarf_factorization
5146 && elf_helpers::find_section_by_name(elf_handle(),
5147 ".gnu_debugaltlink"))
5148 leverage_dwarf_factorization_ =
true;
5150 leverage_dwarf_factorization_ =
false;
5152 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5154 return *leverage_dwarf_factorization_;
5164 {
return options().show_stats;}
5213 build_die_parent_relations_under(Dwarf_Die* die,
5223 if (dwarf_child(die, &child) != 0)
5228 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5229 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5231 Dwarf_Die imported_unit;
5232 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5243 && die_has_children(&imported_unit))
5245 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5246 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5247 imported_units.push_back
5248 (imported_unit_point(dwarf_dieoffset(&child),
5250 imported_unit_die_source));
5253 build_die_parent_relations_under(&child, source, imported_units);
5255 while (dwarf_siblingof(&child, &child) == 0);
5287 case translation_unit::LANG_UNKNOWN:
5288#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5289 case translation_unit::LANG_Mips_Assembler:
5316 build_die_parent_maps()
5318 bool we_do_have_to_build_die_parent_map =
false;
5319 uint8_t address_size = 0;
5320 size_t header_size = 0;
5325 for (Dwarf_Off offset = 0, next_offset = 0;
5327 offset, &next_offset, &header_size,
5328 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5329 offset = next_offset)
5331 Dwarf_Off die_offset = offset + header_size;
5338 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5340 if (do_we_build_die_parent_maps(lang))
5341 we_do_have_to_build_die_parent_map =
true;
5344 if (!we_do_have_to_build_die_parent_map)
5349 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5350 for (Dwarf_Off offset = 0, next_offset = 0;
5352 offset, &next_offset, &header_size,
5353 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5354 offset = next_offset)
5356 Dwarf_Off die_offset = offset + header_size;
5364 tu_die_imported_unit_points_map(source)[die_offset] =
5366 build_die_parent_relations_under(&cu, source, imported_units);
5371 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5374 for (Dwarf_Off offset = 0, next_offset = 0;
5376 offset, &next_offset, &header_size,
5377 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5378 offset = next_offset)
5380 Dwarf_Off die_offset = offset + header_size;
5387 tu_die_imported_unit_points_map(source)[die_offset] =
5389 build_die_parent_relations_under(&cu, source, imported_units);
5394 source = TYPE_UNIT_DIE_SOURCE;
5397 uint64_t type_signature = 0;
5398 Dwarf_Off type_offset;
5399 for (Dwarf_Off offset = 0, next_offset = 0;
5401 offset, &next_offset, &header_size,
5402 NULL, NULL, &address_size, NULL,
5403 &type_signature, &type_offset) == 0);
5404 offset = next_offset)
5406 Dwarf_Off die_offset = offset + header_size;
5414 tu_die_imported_unit_points_map(source)[die_offset] =
5416 build_die_parent_relations_under(&cu, source, imported_units);
5431struct offset_pairs_stack_type
5448 offset_pairs_stack_type(
const reader& rdr)
5474 offset_pair_vector_type::iterator i;
5476 for (i = vect_.begin();i < vect_.end(); ++i)
5480 if (i != vect_.end())
5499 if (set_.find(p) == set_.end())
5526 bool result =
false;
5531 offset_pair_vector_type::const_iterator i;
5532 for (i = vect_.begin(); i != vect_.end(); ++i)
5536 if (i == vect_.end())
5541 for (++i; i != vect_.end(); ++i)
5543 pairs.push_back(*i);
5563 for (
auto type_pair : dependant_types)
5564 dependant_types_[type_pair].push_back(p);
5575 get_pairs_that_depend_on(p, dependant_types);
5578 auto it = redundant_types_.find(p);
5579 if (it == redundant_types_.end())
5581 auto entry = std::make_pair(p, dependant_types);
5582 redundant_types_.insert(entry);
5585 it->second.insert(it->second.end(),
5586 dependant_types.begin(),
5587 dependant_types.end());
5591 record_dependant_types(p, dependant_types);
5602 auto i = redundant_types_.find(p);
5603 if (i != redundant_types_.end())
5616 auto i = dependant_types_.find(p);
5617 if (i == dependant_types_.end())
5635 bool erase_cached_results =
false)
5639 auto redundant_type = redundant_types_.find(p);
5640 if (redundant_type != redundant_types_.end())
5642 for (
auto dependant_type : redundant_type->second)
5646 auto dependant_types_it = dependant_types_.find(dependant_type);
5647 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5651 auto i = dependant_types_it->second.begin();
5652 for (; i!= dependant_types_it->second.end();++i)
5655 if (i != dependant_types_it->second.end())
5656 dependant_types_it->second.erase(i);
5661 if (dependant_types_it->second.empty())
5663 if (erase_cached_results)
5664 rdr_.die_comparison_results_.erase(dependant_type);
5665 dependant_types_.erase(dependant_types_it);
5669 if (erase_cached_results)
5670 rdr_.die_comparison_results_.erase(p);
5671 redundant_types_.erase(p);
5683 {erase_redundant_type_pair_entry(p,
true);}
5696 get_dependant_types(p, dependant_types,
true);
5697 for (
auto dependant_type : dependant_types)
5701 if (rdr_.propagated_types_.find(dependant_type)
5702 != rdr_.propagated_types_.end())
5704 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5705 dependant_type.first.source_,
5707 rdr_.propagated_types_.erase(dependant_type);
5708 rdr_.cancelled_propagation_count_++;
5712 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5713 if (comp_result_it != rdr_.die_comparison_results_.end())
5714 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5718 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5719 if (comp_result_it != rdr_.die_comparison_results_.end())
5726 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5727 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5728 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5731 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5733 rdr_.erase_canonical_die_offset(p.first.offset_,
5736 rdr_.propagated_types_.erase(p);
5737 rdr_.cancelled_propagation_count_++;
5756 bool transitive_closure =
false)
5758 auto i = redundant_types_.find(p);
5759 if (i != redundant_types_.end())
5761 for (
auto dependant_type : i->second)
5762 if (result.find(dependant_type) == result.end())
5764 result.insert(dependant_type);
5765 if (transitive_closure)
5766 get_dependant_types(p, result,
true);
5775build_ir_node_from_die(reader& rdr,
5778 bool called_from_public_decl,
5779 size_t where_offset,
5780 bool is_declaration_only =
true,
5781 bool is_required_decl_spec =
false);
5784build_ir_node_from_die(reader& rdr,
5786 bool called_from_public_decl,
5787 size_t where_offset);
5789static decl_base_sptr
5790build_ir_node_for_void_type(reader& rdr);
5793build_ir_node_for_void_pointer_type(reader& rdr);
5796add_or_update_class_type(reader& rdr,
5801 bool called_from_public_decl,
5802 size_t where_offset,
5803 bool is_declaration_only);
5805static union_decl_sptr
5806add_or_update_union_type(reader& rdr,
5809 union_decl_sptr union_type,
5810 bool called_from_public_decl,
5811 size_t where_offset,
5812 bool is_declaration_only);
5814static decl_base_sptr
5815build_ir_node_for_void_type(reader& rdr);
5817static decl_base_sptr
5818build_ir_node_for_variadic_parameter_type(reader &rdr);
5821build_function_decl(reader& rdr,
5823 size_t where_offset,
5827function_is_suppressed(
const reader& rdr,
5828 const scope_decl* scope,
5829 Dwarf_Die *function_die,
5830 bool is_declaration_only);
5833build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5836 size_t where_offset,
5837 bool is_declaration_only,
5841build_var_decl(reader& rdr,
5843 size_t where_offset,
5847build_or_get_var_decl_if_not_suppressed(reader& rdr,
5850 size_t where_offset,
5852 bool is_required_decl_spec =
false);
5854variable_is_suppressed(
const reader& rdr,
5855 const scope_decl* scope,
5856 Dwarf_Die *variable_die,
5857 bool is_required_decl_spec =
false);
5860finish_member_function_reading(Dwarf_Die* die,
5862 const class_or_union_sptr klass,
5871die_is_anonymous(
const Dwarf_Die* die)
5873 Dwarf_Attribute attr;
5874 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
5888die_is_anonymous_data_member(
const Dwarf_Die* die)
5891 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
5892 || !die_name(die).empty())
5896 if (!die_die_attribute(die, DW_AT_type, type_die))
5899 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5900 && dwarf_tag(&type_die) != DW_TAG_union_type)
5917die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5922 Dwarf_Attribute attr;
5923 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5926 const char* str = dwarf_formstring(&attr);
5927 return str ? str :
"";
5941die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5946 Dwarf_Attribute attr;
5947 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5950 const char* str = dwarf_formstring(&attr);
5970die_unsigned_constant_attribute(
const Dwarf_Die* die,
5977 Dwarf_Attribute attr;
5978 Dwarf_Word result = 0;
5979 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
5980 || dwarf_formudata(&attr, &result))
6000die_signed_constant_attribute(
const Dwarf_Die *die,
6007 Dwarf_Attribute attr;
6008 Dwarf_Sword result = 0;
6009 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6010 || dwarf_formsdata(&attr, &result))
6036die_constant_attribute(
const Dwarf_Die *die,
6039 array_type_def::subrange_type::bound_value &value)
6044 if (!die_unsigned_constant_attribute(die, attr_name, l))
6046 value.set_unsigned(l);
6051 if (!die_signed_constant_attribute(die, attr_name, l))
6053 value.set_signed(l);
6068form_is_DW_FORM_strx(
unsigned form)
6072#if defined HAVE_DW_FORM_strx1 \
6073 && defined HAVE_DW_FORM_strx2 \
6074 && defined HAVE_DW_FORM_strx3 \
6075 && defined HAVE_DW_FORM_strx4
6076 if (form == DW_FORM_strx1
6077 || form == DW_FORM_strx2
6078 || form == DW_FORM_strx3
6079 ||form == DW_FORM_strx4)
6096form_is_DW_FORM_line_strp(
unsigned form)
6100#if defined HAVE_DW_FORM_line_strp
6101 if (form == DW_FORM_line_strp)
6128die_flag_attribute(
const Dwarf_Die* die,
6131 bool recursively =
true)
6133 Dwarf_Attribute attr;
6135 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6136 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6140 if (dwarf_formflag(&attr, &f))
6154die_linkage_name(
const Dwarf_Die* die)
6159 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6160 if (linkage_name.empty())
6161 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6162 return linkage_name;
6176die_decl_file_attribute(
const Dwarf_Die* die)
6181 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6183 return str ? str :
"";
6204die_die_attribute(
const Dwarf_Die* die,
6209 Dwarf_Attribute attr;
6211 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6212 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6215 return dwarf_formref_die(&attr, &result);
6245subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6247 Dwarf_Die& referenced_subrange)
6249 bool result =
false;
6251 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6254 Dwarf_Die referenced_die;
6255 if (die_die_attribute(die, attr_name, referenced_die))
6257 unsigned tag = dwarf_tag(&referenced_die);
6258 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6261 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6263 tag = dwarf_tag(&type_die);
6264 if (tag == DW_TAG_subrange_type)
6266 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6302subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6304 array_type_def::subrange_type::bound_value& v,
6307 bool result =
false;
6309 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6312 Dwarf_Die subrange_die;
6313 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6316 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6334die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6336 Dwarf_Attribute attr;
6337 if (!dwarf_attr_integrate(die, attr_name, &attr))
6339 return dwarf_formaddr(&attr, &result) == 0;
6350die_location(
const reader& rdr,
const Dwarf_Die* die)
6355 string file = die_decl_file_attribute(die);
6357 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6359 if (!file.empty() && line != 0)
6362 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6374die_name(
const Dwarf_Die* die)
6376 string name = die_string_attribute(die, DW_AT_name);
6392die_loc_and_name(
const reader& rdr,
6396 string& linkage_name)
6398 loc = die_location(rdr, die);
6399 name = die_name(die);
6400 linkage_name = die_linkage_name(die);
6413die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6418 uint64_t byte_size = 0, bit_size = 0;
6420 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6422 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6426 bit_size = byte_size * 8;
6449 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6456 case private_access:
6457 result = private_access;
6460 case protected_access:
6461 result = protected_access;
6465 result = public_access;
6484die_is_public_decl(
const Dwarf_Die* die)
6488 bool is_public =
false;
6494 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6495 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6496 die_flag_attribute(die, DW_AT_external, is_public);
6497 else if (tag == DW_TAG_namespace)
6499 string name = die_name(die);
6500 is_public = !name.empty();
6514die_is_effectively_public_decl(
const reader& rdr,
6515 const Dwarf_Die* die)
6517 if (die_is_public_decl(die))
6520 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6521 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6524 Dwarf_Die parent_die;
6525 size_t where_offset = 0;
6526 if (!get_parent_die(rdr, die, parent_die, where_offset))
6529 tag = dwarf_tag(&parent_die);
6530 if (tag == DW_TAG_compile_unit
6531 || tag == DW_TAG_partial_unit
6532 || tag == DW_TAG_type_unit)
6536 if (tag == DW_TAG_namespace)
6538 string name = die_name(&parent_die);
6557die_is_declaration_only(Dwarf_Die* die)
6559 bool is_declaration =
false;
6560 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6561 if (is_declaration && !die_has_size_attribute(die))
6572die_is_function_decl(
const Dwarf_Die *die)
6577 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6578 if (tag == DW_TAG_subprogram)
6589die_is_variable_decl(
const Dwarf_Die *die)
6594 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6595 if (tag == DW_TAG_variable)
6606die_has_size_attribute(
const Dwarf_Die *die)
6609 if (die_size_in_bits(die, s))
6620die_has_no_child(
const Dwarf_Die *die)
6626 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
6639die_is_declaration_only(
const Dwarf_Die* die)
6640{
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
6648die_is_artificial(Dwarf_Die* die)
6651 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6658is_type_tag(
unsigned tag)
6660 bool result =
false;
6664 case DW_TAG_array_type:
6665 case DW_TAG_class_type:
6666 case DW_TAG_enumeration_type:
6667 case DW_TAG_pointer_type:
6668 case DW_TAG_reference_type:
6669 case DW_TAG_string_type:
6670 case DW_TAG_structure_type:
6671 case DW_TAG_subroutine_type:
6672 case DW_TAG_typedef:
6673 case DW_TAG_union_type:
6674 case DW_TAG_ptr_to_member_type:
6675 case DW_TAG_set_type:
6676 case DW_TAG_subrange_type:
6677 case DW_TAG_base_type:
6678 case DW_TAG_const_type:
6679 case DW_TAG_file_type:
6680 case DW_TAG_packed_type:
6681 case DW_TAG_thrown_type:
6682 case DW_TAG_volatile_type:
6683 case DW_TAG_restrict_type:
6684 case DW_TAG_interface_type:
6685 case DW_TAG_unspecified_type:
6686 case DW_TAG_shared_type:
6687 case DW_TAG_rvalue_reference_type:
6688 case DW_TAG_coarray_type:
6689 case DW_TAG_atomic_type:
6690 case DW_TAG_immutable_type:
6713is_canon_type_to_be_propagated_tag(
unsigned tag)
6715 bool result =
false;
6719 case DW_TAG_class_type:
6720 case DW_TAG_structure_type:
6721 case DW_TAG_union_type:
6722 case DW_TAG_subroutine_type:
6723 case DW_TAG_subprogram:
6744type_comparison_result_to_be_cached(
unsigned tag)
6749 case DW_TAG_class_type:
6750 case DW_TAG_structure_type:
6751 case DW_TAG_union_type:
6752 case DW_TAG_subroutine_type:
6753 case DW_TAG_subprogram:
6774maybe_cache_type_comparison_result(
const reader& rdr,
6779 if (!type_comparison_result_to_be_cached(tag)
6780 || (result != COMPARISON_RESULT_EQUAL
6781 && result != COMPARISON_RESULT_DIFFERENT))
6784 rdr.die_comparison_results_[p] = result;
6804get_cached_type_comparison_result(
const reader& rdr,
6808 auto i = rdr.die_comparison_results_.find(p);
6809 if (i != rdr.die_comparison_results_.end())
6832maybe_get_cached_type_comparison_result(
const reader& rdr,
6837 if (type_comparison_result_to_be_cached(tag))
6842 if (get_cached_type_comparison_result(rdr, p, result))
6854is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
6856 bool result =
false;
6857 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6859 if (!is_type_tag(tag))
6864 case DW_TAG_class_type:
6865 case DW_TAG_structure_type:
6866 case DW_TAG_union_type:
6867 result = !die_is_declaration_only(die);
6870 case DW_TAG_subroutine_type:
6871 case DW_TAG_subprogram:
6872 case DW_TAG_array_type:
6888is_decl_tag(
unsigned tag)
6892 case DW_TAG_formal_parameter:
6893 case DW_TAG_imported_declaration:
6895 case DW_TAG_unspecified_parameters:
6896 case DW_TAG_subprogram:
6897 case DW_TAG_variable:
6898 case DW_TAG_namespace:
6899 case DW_TAG_GNU_template_template_param:
6900 case DW_TAG_GNU_template_parameter_pack:
6901 case DW_TAG_GNU_formal_parameter_pack:
6913die_is_type(
const Dwarf_Die* die)
6917 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
6926die_is_decl(
const Dwarf_Die* die)
6930 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
6939die_is_namespace(
const Dwarf_Die* die)
6943 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
6952die_is_unspecified(Dwarf_Die* die)
6956 return (dwarf_tag(die) == DW_TAG_unspecified_type);
6965die_is_void_type(Dwarf_Die* die)
6967 if (!die || dwarf_tag(die) != DW_TAG_base_type)
6970 string name = die_name(die);
6983die_is_pointer_type(
const Dwarf_Die* die)
6988 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6989 if (tag == DW_TAG_pointer_type)
7003pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7005 if (!die_is_pointer_array_or_reference_type(die)
7006 && !die_is_qualified_type(die))
7009 Dwarf_Die underlying_type_die;
7010 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7013 if (!die_is_class_type(&underlying_type_die))
7016 string name = die_name(&underlying_type_die);
7018 return name.empty();
7027die_is_reference_type(
const Dwarf_Die* die)
7032 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7033 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7045die_is_array_type(
const Dwarf_Die* die)
7050 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7051 if (tag == DW_TAG_array_type)
7063die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7064{
return (die_is_pointer_type(die)
7065 || die_is_reference_type(die)
7066 || die_is_array_type(die));}
7074die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7075{
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7084die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7085{
return (die_is_pointer_array_or_reference_type(die)
7086 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7094die_is_class_type(
const Dwarf_Die* die)
7096 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7098 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7110die_is_qualified_type(
const Dwarf_Die* die)
7112 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7113 if (tag == DW_TAG_const_type
7114 || tag == DW_TAG_volatile_type
7115 || tag == DW_TAG_restrict_type)
7127die_is_function_type(
const Dwarf_Die *die)
7129 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7130 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7148die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7153 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7165die_has_children(
const Dwarf_Die* die)
7171 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7191die_this_pointer_from_object_pointer(Dwarf_Die* die,
7192 Dwarf_Die& this_pointer_die)
7195 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7197 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7212die_this_pointer_is_const(Dwarf_Die* die)
7216 if (dwarf_tag(die) == DW_TAG_pointer_type)
7218 Dwarf_Die pointed_to_type_die;
7219 if (die_die_attribute(die, DW_AT_type, pointed_to_type_die))
7220 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7236die_object_pointer_is_for_const_method(Dwarf_Die* die)
7239 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7241 Dwarf_Die this_pointer_die;
7242 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7243 if (die_this_pointer_is_const(&this_pointer_die))
7265die_is_at_class_scope(
const reader& rdr,
7266 const Dwarf_Die* die,
7267 size_t where_offset,
7268 Dwarf_Die& class_scope_die)
7270 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7273 int tag = dwarf_tag(&class_scope_die);
7275 return (tag == DW_TAG_structure_type
7276 || tag == DW_TAG_class_type
7277 || tag == DW_TAG_union_type);
7290die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7295 int tag = dwarf_tag(die);
7297 if (tag == DW_TAG_const_type
7298 || tag == DW_TAG_volatile_type
7299 || tag == DW_TAG_restrict_type
7300 || tag == DW_TAG_pointer_type
7301 || tag == DW_TAG_reference_type
7302 || tag == DW_TAG_rvalue_reference_type)
7304 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7310 memcpy(&peeled_die, die,
sizeof(peeled_die));
7312 while (tag == DW_TAG_const_type
7313 || tag == DW_TAG_volatile_type
7314 || tag == DW_TAG_restrict_type
7315 || tag == DW_TAG_pointer_type
7316 || tag == DW_TAG_reference_type
7317 || tag == DW_TAG_rvalue_reference_type)
7319 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7321 tag = dwarf_tag(&peeled_die);
7336die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7341 memcpy(&peeled_die, die,
sizeof(peeled_die));
7343 int tag = dwarf_tag(&peeled_die);
7345 bool result =
false;
7346 while (tag == DW_TAG_const_type
7347 || tag == DW_TAG_volatile_type
7348 || tag == DW_TAG_restrict_type)
7350 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7352 tag = dwarf_tag(&peeled_die);
7368die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
7373 int tag = dwarf_tag(die);
7375 memcpy(&peeled_die, die,
sizeof(peeled_die));
7377 if (tag == DW_TAG_typedef)
7379 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7385 while (tag == DW_TAG_typedef)
7387 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7389 tag = dwarf_tag(&peeled_die);
7405die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
7410 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7412 if (tag == DW_TAG_pointer_type
7413 || tag == DW_TAG_reference_type
7414 || tag == DW_TAG_rvalue_reference_type
7415 || tag == DW_TAG_typedef)
7417 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7423 while (tag == DW_TAG_pointer_type
7424 || tag == DW_TAG_reference_type
7425 || tag == DW_TAG_rvalue_reference_type
7426 || tag == DW_TAG_typedef)
7428 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7430 tag = dwarf_tag(&peeled_die);
7458die_function_type_is_method_type(
const reader& rdr,
7459 const Dwarf_Die *die,
7460 size_t where_offset,
7461 Dwarf_Die& object_pointer_die,
7462 Dwarf_Die& class_die,
7468 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7469 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7471 bool has_object_pointer =
false;
7473 if (tag == DW_TAG_subprogram)
7475 Dwarf_Die spec_or_origin_die;
7476 if (die_die_attribute(die, DW_AT_specification,
7478 || die_die_attribute(die, DW_AT_abstract_origin,
7479 spec_or_origin_die))
7481 if (die_has_object_pointer(&spec_or_origin_die,
7482 object_pointer_die))
7483 has_object_pointer =
true;
7486 if (die_is_at_class_scope(rdr, &spec_or_origin_die,
7487 where_offset, class_die))
7495 if (die_has_object_pointer(die, object_pointer_die))
7496 has_object_pointer =
true;
7499 if (die_is_at_class_scope(rdr, die, where_offset, class_die))
7508 if (die_has_object_pointer(die, object_pointer_die))
7509 has_object_pointer =
true;
7520 Dwarf_Die this_type_die;
7521 if (!die_die_attribute(&object_pointer_die, DW_AT_type, this_type_die))
7526 if (!die_peel_qual_ptr(&this_type_die, class_die))
7531 die_peel_typedef(&class_die, class_die);
7539 VIRTUALITY_NOT_VIRTUAL,
7541 VIRTUALITY_PURE_VIRTUAL
7554die_virtuality(
const Dwarf_Die* die, virtuality& virt)
7560 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
7562 if (v == DW_VIRTUALITY_virtual)
7563 virt = VIRTUALITY_VIRTUAL;
7564 else if (v == DW_VIRTUALITY_pure_virtual)
7565 virt = VIRTUALITY_PURE_VIRTUAL;
7567 virt = VIRTUALITY_NOT_VIRTUAL;
7579die_is_virtual(
const Dwarf_Die* die)
7582 if (!die_virtuality(die, v))
7585 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
7595die_is_declared_inline(Dwarf_Die* die)
7597 uint64_t inline_value = 0;
7598 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
7600 return inline_value == DW_INL_declared_inlined;
7615slowly_compare_strings(
const Dwarf_Die *l,
7619 const char *l_str = die_char_str_attribute(l, attr_name),
7620 *r_str = die_char_str_attribute(r, attr_name);
7621 if (!l_str && !r_str)
7623 return l_str && r_str && !strcmp(l_str, r_str);
7649compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
7653 Dwarf_Attribute l_attr, r_attr;
7654 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
7655 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
7659 || l_attr.form == DW_FORM_string
7660 || l_attr.form == DW_FORM_GNU_strp_alt
7661 || form_is_DW_FORM_strx(l_attr.form)
7662 || form_is_DW_FORM_line_strp(l_attr.form));
7665 || r_attr.form == DW_FORM_string
7666 || r_attr.form == DW_FORM_GNU_strp_alt
7667 || form_is_DW_FORM_strx(r_attr.form)
7668 || form_is_DW_FORM_line_strp(r_attr.form));
7670 if ((l_attr.form == DW_FORM_strp
7671 && r_attr.form == DW_FORM_strp)
7672 || (l_attr.form == DW_FORM_GNU_strp_alt
7673 && r_attr.form == DW_FORM_GNU_strp_alt)
7674 || (form_is_DW_FORM_strx(l_attr.form)
7675 && form_is_DW_FORM_strx(r_attr.form))
7676 || (form_is_DW_FORM_line_strp(l_attr.form)
7677 && form_is_DW_FORM_line_strp(r_attr.form)))
7684 if (l_attr.valp == r_attr.valp)
7686#if WITH_DEBUG_TYPE_CANONICALIZATION
7687 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
7698 result = slowly_compare_strings(l, r, attr_name);
7716compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
7718 Dwarf_Die l_cu, r_cu;
7719 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
7720 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
7724 compare_dies_string_attribute_value(&l_cu, &r_cu,
7727 if (compared && result)
7729 Dwarf_Die peeled_l, peeled_r;
7730 if (die_is_pointer_reference_or_typedef_type(l)
7731 && die_is_pointer_reference_or_typedef_type(r)
7732 && die_peel_pointer_and_typedef(l, peeled_l)
7733 && die_peel_pointer_and_typedef(r, peeled_r))
7735 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
7736 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
7739 compare_dies_string_attribute_value(&l_cu, &r_cu,
7770die_location_expr(
const Dwarf_Die* die,
7778 Dwarf_Attribute attr;
7779 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
7783 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
7818op_pushes_constant_value(Dwarf_Op* ops,
7822 dwarf_expr_eval_context& ctxt)
7826 Dwarf_Op& op = ops[index];
7832 value = ops[index].number;
7845 value = ops[index].number;
7949 expr_result r(value);
7952 next_index = index + 1;
7982op_pushes_non_constant_value(Dwarf_Op* ops,
7986 dwarf_expr_eval_context& ctxt)
7989 Dwarf_Op& op = ops[index];
8025 next_index = index + 1;
8060 next_index = index + 1;
8064 next_index = index + 2;
8068 next_index = index + 1;
8072 next_index = index + 1;
8075 case DW_OP_GNU_variable_value:
8076 next_index = index + 1;
8083 expr_result r(
false);
8112op_manipulates_stack(Dwarf_Op* expr,
8116 dwarf_expr_eval_context& ctxt)
8118 Dwarf_Op& op = expr[index];
8124 v = ctxt.stack.front();
8129 v = ctxt.stack.front();
8148 ctxt.stack.erase(ctxt.stack.begin() + 1);
8155 ctxt.stack.erase(ctxt.stack.begin() + 2);
8160 case DW_OP_deref_size:
8168 case DW_OP_xderef_size:
8176 case DW_OP_push_object_address:
8181 case DW_OP_form_tls_address:
8182 case DW_OP_GNU_push_tls_address:
8185 if (op.atom == DW_OP_form_tls_address)
8190 case DW_OP_call_frame_cfa:
8202 if (op.atom == DW_OP_form_tls_address
8203 || op.atom == DW_OP_GNU_push_tls_address)
8204 ctxt.set_tls_address(
true);
8206 ctxt.set_tls_address(
false);
8208 next_index = index + 1;
8236op_is_arith_logic(Dwarf_Op* expr,
8240 dwarf_expr_eval_context& ctxt)
8244 Dwarf_Op& op = expr[index];
8245 expr_result val1, val2;
8246 bool result =
false;
8262 ctxt.push(val1 & val2);
8269 if (!val1.is_const())
8271 ctxt.push(val2 / val1);
8279 ctxt.push(val2 - val1);
8287 ctxt.push(val2 % val1);
8295 ctxt.push(val2 * val1);
8317 ctxt.push(val1 | val2);
8325 ctxt.push(val2 + val1);
8329 case DW_OP_plus_uconst:
8341 ctxt.push(val2 << val1);
8350 ctxt.push(val2 >> val1);
8358 ctxt.push(val2 ^ val1);
8368 if (ctxt.stack.front().is_const())
8369 ctxt.accum = ctxt.stack.front();
8371 next_index = index + 1;
8399op_is_control_flow(Dwarf_Op* expr,
8403 dwarf_expr_eval_context& ctxt)
8407 Dwarf_Op& op = expr[index];
8408 expr_result val1, val2;
8422 if (op.atom == DW_OP_eq)
8423 value = val2 == val1;
8424 else if (op.atom == DW_OP_ge)
8425 value = val2 >= val1;
8426 else if (op.atom == DW_OP_gt)
8427 value = val2 > val1;
8428 else if (op.atom == DW_OP_le)
8429 value = val2 <= val1;
8430 else if (op.atom == DW_OP_lt)
8431 value = val2 < val1;
8432 else if (op.atom == DW_OP_ne)
8433 value = val2 != val1;
8435 val1 = value ? 1 : 0;
8442 index += op.number - 1;
8447 if (val1.const_value() != 0)
8448 index += val1.const_value() - 1;
8453 case DW_OP_call_ref:
8461 if (ctxt.stack.front().is_const())
8462 ctxt.accum = ctxt.stack.front();
8464 next_index = index + 1;
8485eval_quickly(Dwarf_Op* expr,
8489 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
8491 value = expr[0].number;
8518eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8521 bool& is_tls_address,
8522 dwarf_expr_eval_context &eval_ctxt)
8528 size_t index = 0, next_index = 0;
8531 if (op_is_arith_logic(expr, expr_len, index,
8532 next_index, eval_ctxt)
8533 || op_pushes_constant_value(expr, expr_len, index,
8534 next_index, eval_ctxt)
8535 || op_manipulates_stack(expr, expr_len, index,
8536 next_index, eval_ctxt)
8537 || op_pushes_non_constant_value(expr, expr_len, index,
8538 next_index, eval_ctxt)
8539 || op_is_control_flow(expr, expr_len, index,
8540 next_index, eval_ctxt))
8543 next_index = index + 1;
8547 }
while (index < expr_len);
8549 is_tls_address = eval_ctxt.set_tls_address();
8550 if (eval_ctxt.accum.is_const())
8552 value = eval_ctxt.accum;
8572eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8575 bool& is_tls_address)
8577 dwarf_expr_eval_context eval_ctxt;
8578 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
8579 is_tls_address, eval_ctxt);
8771read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
8776 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
8789 uint64_t containing_anonymous_object_size = 0;
8790 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
8791 containing_anonymous_object_size));
8792 containing_anonymous_object_size *= 8;
8794 uint64_t bitfield_size = 0;
8795 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
8806 offset = containing_anonymous_object_size - off - bitfield_size;
8822die_constant_data_member_location(
const Dwarf_Die *die,
8828 Dwarf_Attribute attr;
8829 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
8830 DW_AT_data_member_location,
8835 if (dwarf_formudata(&attr, &val) != 0)
8891die_member_offset(
const reader& rdr,
8892 const Dwarf_Die* die,
8895 Dwarf_Op* expr = NULL;
8896 size_t expr_len = 0;
8897 uint64_t bit_offset = 0;
8901 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
8903 offset = bit_offset;
8915 if (!die_constant_data_member_location(die, offset))
8920 if (!die_location_expr(die, DW_AT_data_member_location,
8927 if (!eval_quickly(expr, expr_len, offset))
8929 bool is_tls_address =
false;
8930 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
8931 offset, is_tls_address,
8932 rdr.dwarf_expr_eval_ctxt()))
8950 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
8951 offset += bit_offset;
8968die_location_address(Dwarf_Die* die,
8969 Dwarf_Addr& address,
8970 bool& is_tls_address)
8972 Dwarf_Op* expr = NULL;
8973 size_t expr_len = 0;
8975 is_tls_address =
false;
8980 Dwarf_Attribute attr;
8981 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
8984 if (dwarf_getlocation(&attr, &expr, &expr_len))
8991 Dwarf_Attribute result;
8992 if (!dwarf_getlocation_attr(&attr, expr, &result))
8994 return !dwarf_formaddr(&result, &address);
8997 address = expr->number;
9012die_virtual_function_index(Dwarf_Die* die,
9018 Dwarf_Op* expr = NULL;
9019 size_t expr_len = 0;
9020 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9025 bool is_tls_addr =
false;
9026 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9044 int tag = dwarf_tag(die);
9046 if (tag == DW_TAG_class_type
9047 || tag == DW_TAG_structure_type
9048 || tag == DW_TAG_union_type
9049 || tag == DW_TAG_enumeration_type)
9050 return die_is_anonymous(die);
9072get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9075 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9077 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9079 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9081 else if (tag == DW_TAG_union_type)
9083 else if (tag == DW_TAG_enumeration_type)
9102build_internal_anonymous_die_name(
const string &
base_name,
9103 size_t anonymous_type_index)
9106 if (anonymous_type_index && !
base_name.empty())
9108 std::ostringstream o;
9128get_internal_anonymous_die_name(Dwarf_Die *die,
9129 size_t anonymous_type_index)
9131 string name = get_internal_anonymous_die_prefix_name(die);
9132 name = build_internal_anonymous_die_name(name, anonymous_type_index);
9154die_qualified_type_name(
const reader& rdr,
9155 const Dwarf_Die* die,
9156 size_t where_offset)
9161 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9162 if (tag == DW_TAG_compile_unit
9163 || tag == DW_TAG_partial_unit
9164 || tag == DW_TAG_type_unit)
9167 string name = die_name(die);
9169 Dwarf_Die scope_die;
9170 if (!get_scope_die(rdr, die, where_offset, scope_die))
9173 string parent_name = die_qualified_name(rdr, &scope_die, where_offset);
9174 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9175 string separator = colon_colon ?
"::" :
".";
9181 case DW_TAG_unspecified_type:
9184 case DW_TAG_base_type:
9194 case DW_TAG_typedef:
9195 case DW_TAG_enumeration_type:
9196 case DW_TAG_structure_type:
9197 case DW_TAG_class_type:
9198 case DW_TAG_union_type:
9206 name = get_internal_anonymous_die_prefix_name(die);
9209 repr = parent_name.empty() ? name : parent_name + separator + name;
9213 case DW_TAG_const_type:
9214 case DW_TAG_volatile_type:
9215 case DW_TAG_restrict_type:
9217 Dwarf_Die underlying_type_die;
9218 bool has_underlying_type_die =
9219 die_die_attribute(die, DW_AT_type, underlying_type_die);
9221 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9224 if (tag == DW_TAG_const_type)
9226 if (has_underlying_type_die
9227 && die_is_reference_type(&underlying_type_die))
9237 else if (!has_underlying_type_die
9238 || die_is_void_type(&underlying_type_die))
9246 else if (tag == DW_TAG_volatile_type)
9248 else if (tag == DW_TAG_restrict_type)
9253 string underlying_type_repr;
9254 if (has_underlying_type_die)
9255 underlying_type_repr =
9256 die_qualified_type_name(rdr, &underlying_type_die, where_offset);
9258 underlying_type_repr =
"void";
9260 if (underlying_type_repr.empty())
9264 if (has_underlying_type_die)
9267 die_peel_qualified(&underlying_type_die, peeled);
9268 if (die_is_pointer_or_reference_type(&peeled))
9269 repr = underlying_type_repr +
" " + repr;
9271 repr +=
" " + underlying_type_repr;
9274 repr +=
" " + underlying_type_repr;
9279 case DW_TAG_pointer_type:
9280 case DW_TAG_reference_type:
9281 case DW_TAG_rvalue_reference_type:
9283 Dwarf_Die pointed_to_type_die;
9284 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9286 if (tag == DW_TAG_pointer_type)
9291 if (die_is_unspecified(&pointed_to_type_die))
9294 string pointed_type_repr =
9295 die_qualified_type_name(rdr, &pointed_to_type_die, where_offset);
9297 repr = pointed_type_repr;
9301 if (tag == DW_TAG_pointer_type)
9303 else if (tag == DW_TAG_reference_type)
9305 else if (tag == DW_TAG_rvalue_reference_type)
9312 case DW_TAG_subrange_type:
9325 build_subrange_type(
const_cast<reader&
>(rdr),
9328 repr += s->as_string();
9332 case DW_TAG_array_type:
9334 Dwarf_Die element_type_die;
9335 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9337 string element_type_name =
9338 die_qualified_type_name(rdr, &element_type_die, where_offset);
9339 if (element_type_name.empty())
9343 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9344 die, subranges, where_offset,
9347 repr = element_type_name;
9348 repr += array_type_def::subrange_type::vector_as_string(subranges);
9352 case DW_TAG_subroutine_type:
9353 case DW_TAG_subprogram:
9355 string return_type_name;
9357 vector<string> parm_names;
9358 bool is_const =
false;
9359 bool is_static =
false;
9361 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9363 return_type_name, class_name,
9364 parm_names, is_const,
9366 if (return_type_name.empty())
9367 return_type_name =
"void";
9369 repr = return_type_name;
9371 if (!class_name.empty())
9374 repr +=
" (" + class_name +
"::*)";
9379 for (vector<string>::const_iterator i = parm_names.begin();
9380 i != parm_names.end();
9383 if (i != parm_names.begin())
9392 case DW_TAG_string_type:
9393 case DW_TAG_ptr_to_member_type:
9394 case DW_TAG_set_type:
9395 case DW_TAG_file_type:
9396 case DW_TAG_packed_type:
9397 case DW_TAG_thrown_type:
9398 case DW_TAG_interface_type:
9399 case DW_TAG_shared_type:
9419die_qualified_decl_name(
const reader& rdr,
9420 const Dwarf_Die* die,
9421 size_t where_offset)
9423 if (!die || !die_is_decl(die))
9426 string name = die_name(die);
9428 Dwarf_Die scope_die;
9429 if (!get_scope_die(rdr, die, where_offset, scope_die))
9432 string scope_name = die_qualified_name(rdr, &scope_die, where_offset);
9433 string separator =
"::";
9437 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9440 case DW_TAG_namespace:
9442 case DW_TAG_variable:
9443 repr = scope_name.empty() ? name : scope_name + separator + name;
9445 case DW_TAG_subprogram:
9446 repr = die_function_signature(rdr, die, where_offset);
9449 case DW_TAG_unspecified_parameters:
9453 case DW_TAG_formal_parameter:
9454 case DW_TAG_imported_declaration:
9455 case DW_TAG_GNU_template_template_param:
9456 case DW_TAG_GNU_template_parameter_pack:
9457 case DW_TAG_GNU_formal_parameter_pack:
9480die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
9482 if (die_is_type(die))
9483 return die_qualified_type_name(rdr, die, where);
9484 else if (die_is_decl(die))
9485 return die_qualified_decl_name(rdr, die, where);
9507die_qualified_type_name_empty(
const reader& rdr,
9508 const Dwarf_Die* die,
9509 size_t where,
string &qualified_name)
9514 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9517 if (tag == DW_TAG_typedef
9518 || tag == DW_TAG_pointer_type
9519 || tag == DW_TAG_reference_type
9520 || tag == DW_TAG_rvalue_reference_type
9521 || tag == DW_TAG_array_type
9522 || tag == DW_TAG_const_type
9523 || tag == DW_TAG_volatile_type
9524 || tag == DW_TAG_restrict_type)
9526 Dwarf_Die underlying_type_die;
9527 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
9530 die_qualified_type_name(rdr, &underlying_type_die, where);
9537 string name = die_qualified_type_name(rdr, die, where);
9542 qname = die_qualified_type_name(rdr, die, where);
9546 qualified_name = qname;
9586die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
9587 const Dwarf_Die* die,
9588 size_t where_offset,
9590 string &return_type_name,
9592 vector<string>& parm_names,
9597 Dwarf_Die ret_type_die;
9598 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
9599 return_type_name =
"void";
9603 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset)
9604 : rdr.get_die_qualified_type_name(&ret_type_die, where_offset);
9606 if (return_type_name.empty())
9607 return_type_name =
"void";
9609 Dwarf_Die object_pointer_die, class_die;
9611 die_function_type_is_method_type(rdr, die, where_offset,
9613 class_die, is_static);
9618 class_name = rdr.get_die_qualified_type_name(&class_die, where_offset);
9620 Dwarf_Die this_pointer_die;
9621 Dwarf_Die pointed_to_die;
9623 && die_die_attribute(&object_pointer_die, DW_AT_type,
9625 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
9626 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
9629 string fn_name = die_name(die);
9630 string non_qualified_class_name = die_name(&class_die);
9631 bool is_ctor = fn_name == non_qualified_class_name;
9632 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
9634 if (is_ctor || is_dtor)
9635 return_type_name.clear();
9638 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
9641 int child_tag = dwarf_tag(&child);
9642 if (child_tag == DW_TAG_formal_parameter)
9644 Dwarf_Die parm_type_die;
9645 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
9647 string qualified_name =
9649 ? rdr.get_die_pretty_representation(&parm_type_die, where_offset)
9650 : rdr.get_die_qualified_type_name(&parm_type_die, where_offset);
9652 if (qualified_name.empty())
9654 parm_names.push_back(qualified_name);
9656 else if (child_tag == DW_TAG_unspecified_parameters)
9659 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
9669 while (dwarf_siblingof(&child, &child) == 0);
9671 if (class_name.empty())
9673 Dwarf_Die parent_die;
9674 if (get_parent_die(rdr, die, parent_die, where_offset))
9676 if (die_is_class_type(&parent_die))
9678 rdr.get_die_qualified_type_name(&parent_die, where_offset);
9695die_function_signature(
const reader& rdr,
9696 const Dwarf_Die *fn_die,
9697 size_t where_offset)
9701 bool has_lang =
false;
9702 if ((has_lang = rdr.get_die_language(fn_die, lang)))
9710 string fn_name = die_linkage_name(fn_die);
9711 if (fn_name.empty())
9712 fn_name = die_name(fn_die);
9722 string return_type_name;
9723 Dwarf_Die ret_type_die;
9724 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
9725 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
9728 if (return_type_name.empty())
9729 return_type_name =
"void";
9731 Dwarf_Die scope_die;
9733 if (get_scope_die(rdr, fn_die, where_offset, scope_die))
9734 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset);
9735 string fn_name = die_name(fn_die);
9736 if (!scope_name.empty())
9737 fn_name = scope_name +
"::" + fn_name;
9740 vector<string> parm_names;
9741 bool is_const =
false;
9742 bool is_static =
false;
9744 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
9746 return_type_name, class_name,
9747 parm_names, is_const, is_static);
9749 bool is_virtual = die_is_virtual(fn_die);
9751 string repr = class_name.empty() ?
"function" :
"method";
9755 if (!return_type_name.empty())
9756 repr +=
" " + return_type_name;
9758 repr +=
" " + fn_name;
9762 bool some_parm_emitted =
false;
9763 for (vector<string>::const_iterator i = parm_names.begin();
9764 i != parm_names.end();
9767 if (i != parm_names.begin())
9769 if (some_parm_emitted)
9773 if (!is_static && !class_name.empty())
9778 some_parm_emitted =
true;
9809die_pretty_print_type(reader& rdr,
9810 const Dwarf_Die* die,
9811 size_t where_offset)
9814 || (!die_is_type(die)
9815 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
9820 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9823 case DW_TAG_string_type:
9832 repr =
"string type";
9834 case DW_TAG_unspecified_type:
9835 case DW_TAG_ptr_to_member_type:
9838 case DW_TAG_namespace:
9839 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset);
9842 case DW_TAG_base_type:
9843 repr = rdr.get_die_qualified_type_name(die, where_offset);
9846 case DW_TAG_typedef:
9848 string qualified_name;
9849 if (!die_qualified_type_name_empty(rdr, die,
9852 repr =
"typedef " + qualified_name;
9856 case DW_TAG_const_type:
9857 case DW_TAG_volatile_type:
9858 case DW_TAG_restrict_type:
9859 case DW_TAG_pointer_type:
9860 case DW_TAG_reference_type:
9861 case DW_TAG_rvalue_reference_type:
9862 repr = rdr.get_die_qualified_type_name(die, where_offset);
9865 case DW_TAG_enumeration_type:
9867 string qualified_name =
9868 rdr.get_die_qualified_type_name(die, where_offset);
9869 repr =
"enum " + qualified_name;
9873 case DW_TAG_structure_type:
9874 case DW_TAG_class_type:
9876 string qualified_name =
9877 rdr.get_die_qualified_type_name(die, where_offset);
9878 repr =
"class " + qualified_name;
9882 case DW_TAG_union_type:
9884 string qualified_name =
9885 rdr.get_die_qualified_type_name(die, where_offset);
9886 repr =
"union " + qualified_name;
9890 case DW_TAG_array_type:
9892 Dwarf_Die element_type_die;
9893 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9895 string element_type_name =
9896 rdr.get_die_qualified_type_name(&element_type_die, where_offset);
9897 if (element_type_name.empty())
9901 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
9904 repr = element_type_name;
9905 repr += array_type_def::subrange_type::vector_as_string(subranges);
9909 case DW_TAG_subrange_type:
9919 repr += die_qualified_type_name(rdr, die, where_offset);
9923 case DW_TAG_subroutine_type:
9924 case DW_TAG_subprogram:
9926 string return_type_name;
9928 vector<string> parm_names;
9929 bool is_const =
false;
9930 bool is_static =
false;
9932 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9934 return_type_name, class_name,
9935 parm_names, is_const,
9937 if (class_name.empty())
9938 repr =
"function type";
9940 repr =
"method type";
9941 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset);
9945 case DW_TAG_set_type:
9946 case DW_TAG_file_type:
9947 case DW_TAG_packed_type:
9948 case DW_TAG_thrown_type:
9949 case DW_TAG_interface_type:
9950 case DW_TAG_shared_type:
9976die_pretty_print_decl(reader& rdr,
9977 const Dwarf_Die* die,
9978 size_t where_offset)
9980 if (!die || !die_is_decl(die))
9985 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9988 case DW_TAG_namespace:
9989 repr =
"namespace " + die_qualified_name(rdr, die, where_offset);
9993 case DW_TAG_variable:
9995 string type_repr =
"void";
9997 if (die_die_attribute(die, DW_AT_type, type_die))
9998 type_repr = die_qualified_type_name(rdr, &type_die, where_offset);
9999 repr = die_qualified_name(rdr, die, where_offset);
10001 repr = type_repr +
" " + repr;
10005 case DW_TAG_subprogram:
10006 repr = die_function_signature(rdr, die, where_offset);
10032die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset)
10034 if (die_is_type(die))
10035 return die_pretty_print_type(rdr, die, where_offset);
10036 else if (die_is_decl(die))
10037 return die_pretty_print_decl(rdr, die, where_offset);
10060compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
10064 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10065 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10066 if (l_tag != r_tag)
10069 bool result =
false;
10071 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
10074 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
10076 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
10083 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10093 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10110at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
10111 const Dwarf_Die *l,
10112 const Dwarf_Die *r)
10114 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
10117 if ((die_is_declaration_only(l) && die_has_no_child(l))
10118 || (die_is_declaration_only(r) && die_has_no_child(r)))
10145compare_as_type_dies(
const reader& rdr,
10146 const Dwarf_Die *l,
10147 const Dwarf_Die *r)
10153 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
10154 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
10155 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10156 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
10164 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10169 uint64_t l_size = 0, r_size = 0;
10170 die_size_in_bits(l, l_size);
10171 die_size_in_bits(r, r_size);
10173 return l_size == r_size;
10188compare_as_decl_and_type_dies(
const reader &rdr,
10189 const Dwarf_Die *l,
10190 const Dwarf_Die *r)
10192 if (!compare_as_decl_dies(l, r)
10193 || !compare_as_type_dies(rdr, l, r))
10217fn_die_equal_by_linkage_name(
const reader &rdr,
10218 const Dwarf_Die *l,
10219 const Dwarf_Die *r)
10227 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10229 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10232 string lname = die_name(l), rname = die_name(r);
10233 string llinkage_name = die_linkage_name(l),
10234 rlinkage_name = die_linkage_name(r);
10236 if (rdr.die_is_in_c_or_cplusplus(l)
10237 && rdr.die_is_in_c_or_cplusplus(r))
10239 if (!llinkage_name.empty() && !rlinkage_name.empty())
10240 return llinkage_name == rlinkage_name;
10241 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
10244 return lname == rname;
10247 return (!llinkage_name.empty()
10248 && !rlinkage_name.empty()
10249 && llinkage_name == rlinkage_name);
10281try_canonical_die_comparison(
const reader& rdr,
10282 Dwarf_Off l_offset, Dwarf_Off r_offset,
10284 bool& l_has_canonical_die_offset,
10285 bool& r_has_canonical_die_offset,
10286 Dwarf_Off& l_canonical_die_offset,
10287 Dwarf_Off& r_canonical_die_offset,
10290#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10291 if (rdr.debug_die_canonicalization_is_on_
10292 && !rdr.use_canonical_die_comparison_)
10297 l_has_canonical_die_offset =
10298 (l_canonical_die_offset =
10299 rdr.get_canonical_die_offset(l_offset, l_die_source,
10302 r_has_canonical_die_offset =
10303 (r_canonical_die_offset =
10304 rdr.get_canonical_die_offset(r_offset, r_die_source,
10307 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
10309 result = (l_canonical_die_offset == r_canonical_die_offset);
10316#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10329notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
10333#define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
10334 notify_die_comparison_failed(l, r)
10336#define NOTIFY_DIE_COMPARISON_FAILED(l, r)
10349#define ABG_RETURN(value) \
10352 if ((value) == COMPARISON_RESULT_DIFFERENT) \
10354 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10356 return return_comparison_result(l, r, dies_being_compared, \
10357 value, aggregates_being_compared, \
10358 update_canonical_dies_on_the_fly); \
10369#define ABG_RETURN_FALSE \
10372 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10373 return return_comparison_result(l, r, dies_being_compared, \
10374 COMPARISON_RESULT_DIFFERENT, \
10375 aggregates_being_compared, \
10376 update_canonical_dies_on_the_fly); \
10391#define SET_RESULT_TO_FALSE(result, l , r) \
10394 result = COMPARISON_RESULT_DIFFERENT; \
10395 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10411#define SET_RESULT_TO(result, value, l , r) \
10414 result = (value); \
10415 if (result == COMPARISON_RESULT_DIFFERENT) \
10417 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10421#define RETURN_IF_COMPARISON_CYCLE_DETECTED \
10424 if (aggregates_being_compared.contains(dies_being_compared)) \
10426 result = COMPARISON_RESULT_CYCLE_DETECTED; \
10427 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
10428 ABG_RETURN(result); \
10443get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
10448 bool found_member =
false;
10449 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
10452 found_member = (dwarf_siblingof(member, member) == 0))
10454 int tag = dwarf_tag(member);
10455 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
10459 return found_member;
10473get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
10478 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10480 || tag == DW_TAG_union_type
10481 || tag == DW_TAG_class_type);
10483 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die),
10489 tag = dwarf_tag(child);
10491 if (!(tag == DW_TAG_member
10492 || tag == DW_TAG_inheritance
10493 || tag == DW_TAG_subprogram))
10494 found_child = get_next_member_sibling_die(child, child);
10496 return found_child;
10519maybe_propagate_canonical_type(
const reader& rdr,
10520 const Dwarf_Die* l,
10521 const Dwarf_Die* r)
10523 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10524 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10526 if (l_tag != r_tag)
10529 if (is_canon_type_to_be_propagated_tag(l_tag))
10530 propagate_canonical_type(rdr, l, r);
10548propagate_canonical_type(
const reader& rdr,
10549 const Dwarf_Die* l,
10550 const Dwarf_Die* r)
10559 const die_source l_source = rdr.get_die_source(l);
10560 const die_source r_source = rdr.get_die_source(r);
10562 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
10563 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
10564 bool l_has_canonical_die_offset =
false;
10565 bool r_has_canonical_die_offset =
false;
10566 Dwarf_Off l_canonical_die_offset = 0;
10567 Dwarf_Off r_canonical_die_offset = 0;
10569 l_has_canonical_die_offset =
10570 (l_canonical_die_offset =
10571 rdr.get_canonical_die_offset(l_offset, l_source,
10574 r_has_canonical_die_offset =
10575 (r_canonical_die_offset =
10576 rdr.get_canonical_die_offset(r_offset, r_source,
10580 if (!l_has_canonical_die_offset
10581 && r_has_canonical_die_offset
10584 && l_source == r_source)
10587 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
10589 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
10590 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
10591 rdr.canonical_propagated_count_++;
10629return_comparison_result(
const Dwarf_Die* l,
10630 const Dwarf_Die* r,
10633 offset_pairs_stack_type& comparison_stack,
10634 bool do_propagate_canonical_type =
true)
10636 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10638 if (result == COMPARISON_RESULT_EQUAL)
10643 if (do_propagate_canonical_type)
10646 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10652 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10665 else if (result == COMPARISON_RESULT_UNKNOWN)
10706 if (comparison_stack.is_redundant(cur_dies)
10707 && comparison_stack.vect_.back() == cur_dies)
10711 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10712 comparison_stack.confirm_canonical_propagated_type(cur_dies);
10714 result = COMPARISON_RESULT_EQUAL;
10716 else if (is_canon_type_to_be_propagated_tag(l_tag)
10717 && comparison_stack.vect_.back() == cur_dies)
10722 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
10723 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10727 else if (result == COMPARISON_RESULT_DIFFERENT)
10744 if (comparison_stack.is_redundant(cur_dies)
10745 && comparison_stack.vect_.back() == cur_dies)
10746 comparison_stack.cancel_canonical_propagated_type(cur_dies);
10754 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10755 result = COMPARISON_RESULT_UNKNOWN;
10756 else if (is_canon_type_to_be_propagated_tag(l_tag)
10757 && !comparison_stack.vect_.empty()
10758 && comparison_stack.vect_.back() == cur_dies)
10763 comparison_stack.erase(cur_dies);
10765 maybe_cache_type_comparison_result(comparison_stack.rdr_,
10766 l_tag, cur_dies, result);
10795compare_dies(
const reader& rdr,
10796 const Dwarf_Die *l,
const Dwarf_Die *r,
10797 offset_pairs_stack_type& aggregates_being_compared,
10798 bool update_canonical_dies_on_the_fly)
10803 const die_source l_die_source = rdr.get_die_source(l);
10804 const die_source r_die_source = rdr.get_die_source(r);
10806 offset_type l_offset =
10809 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10812 offset_type r_offset =
10815 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
10820 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10821 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10823 if (l_tag != r_tag)
10826 if (l_offset == r_offset)
10827 return COMPARISON_RESULT_EQUAL;
10829 if (rdr.leverage_dwarf_factorization()
10830 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
10831 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
10832 if (l_offset != r_offset)
10833 return COMPARISON_RESULT_DIFFERENT;
10836 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
10837 dies_being_compared,
10841 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
10842 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
10846 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
10848 bool canonical_compare_result =
false;
10849 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
10850 l_die_source, r_die_source,
10851 l_has_canonical_die_offset,
10852 r_has_canonical_die_offset,
10853 l_canonical_die_offset,
10854 r_canonical_die_offset,
10855 canonical_compare_result))
10859 (canonical_compare_result
10860 ? COMPARISON_RESULT_EQUAL
10861 : COMPARISON_RESULT_DIFFERENT),
10871 case DW_TAG_base_type:
10872 case DW_TAG_string_type:
10873 case DW_TAG_unspecified_type:
10874 if (!compare_as_decl_and_type_dies(rdr, l, r))
10878 case DW_TAG_typedef:
10879 case DW_TAG_pointer_type:
10880 case DW_TAG_reference_type:
10881 case DW_TAG_rvalue_reference_type:
10882 case DW_TAG_const_type:
10883 case DW_TAG_volatile_type:
10884 case DW_TAG_restrict_type:
10886 if (!compare_as_type_dies(rdr, l, r))
10892 bool from_the_same_tu =
false;
10893 if (!pointer_or_qual_die_of_anonymous_class_type(l)
10894 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
10895 && from_the_same_tu)
10912 Dwarf_Die lu_type_die, ru_type_die;
10913 bool lu_is_void, ru_is_void;
10915 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
10916 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
10918 if (lu_is_void && ru_is_void)
10919 result = COMPARISON_RESULT_EQUAL;
10920 else if (lu_is_void != ru_is_void)
10923 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
10924 aggregates_being_compared,
10925 update_canonical_dies_on_the_fly);
10929 case DW_TAG_enumeration_type:
10930 if (!compare_as_decl_and_type_dies(rdr, l, r))
10935 Dwarf_Die l_enumtor, r_enumtor;
10936 bool found_l_enumtor =
true, found_r_enumtor =
true;
10938 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10939 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
10941 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
10943 found_l_enumtor && found_r_enumtor;
10944 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
10945 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
10947 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
10948 if ( l_tag != r_tag)
10954 if (l_tag != DW_TAG_enumerator)
10957 uint64_t l_val = 0, r_val = 0;
10958 die_unsigned_constant_attribute(&l_enumtor,
10961 die_unsigned_constant_attribute(&r_enumtor,
10964 if (l_val != r_val)
10970 if (found_l_enumtor != found_r_enumtor )
10975 case DW_TAG_structure_type:
10976 case DW_TAG_union_type:
10977 case DW_TAG_class_type:
10979 RETURN_IF_COMPARISON_CYCLE_DETECTED;
10981 rdr.compare_count_++;
10983 if (!compare_as_decl_and_type_dies(rdr, l, r))
10985 else if (rdr.options().assume_odr_for_cplusplus
10986 && rdr.odr_is_relevant(l)
10987 && rdr.odr_is_relevant(r)
10988 && !die_is_anonymous(l)
10989 && !die_is_anonymous(r))
10990 result = COMPARISON_RESULT_EQUAL;
10993 aggregates_being_compared.add(dies_being_compared);
10995 Dwarf_Die l_member, r_member;
10996 bool found_l_member =
true, found_r_member =
true;
10998 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10999 for (found_l_member = get_member_child_die(l, &l_member),
11000 found_r_member = get_member_child_die(r, &r_member);
11001 found_l_member && found_r_member;
11002 found_l_member = get_next_member_sibling_die(&l_member,
11004 found_r_member = get_next_member_sibling_die(&r_member,
11007 int l_tag = dwarf_tag(&l_member),
11008 r_tag = dwarf_tag(&r_member);
11010 if (l_tag != r_tag)
11017 || l_tag == DW_TAG_variable
11018 || l_tag == DW_TAG_inheritance
11019 || l_tag == DW_TAG_subprogram);
11022 compare_dies(rdr, &l_member, &r_member,
11023 aggregates_being_compared,
11024 update_canonical_dies_on_the_fly);
11026 if (local_result == COMPARISON_RESULT_UNKNOWN)
11035 result = local_result;
11037 if (local_result == COMPARISON_RESULT_DIFFERENT)
11043 if (found_l_member != found_r_member)
11052 case DW_TAG_array_type:
11054 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11056 aggregates_being_compared.add(dies_being_compared);
11058 rdr.compare_count_++;
11060 Dwarf_Die l_child, r_child;
11061 bool found_l_child, found_r_child;
11062 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11064 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11066 found_l_child && found_r_child;
11067 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
11068 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
11070 int l_child_tag = dwarf_tag(&l_child),
11071 r_child_tag = dwarf_tag(&r_child);
11072 if (l_child_tag == DW_TAG_subrange_type
11073 || r_child_tag == DW_TAG_subrange_type)
11075 result = compare_dies(rdr, &l_child, &r_child,
11076 aggregates_being_compared,
11077 update_canonical_dies_on_the_fly);
11085 if (found_l_child != found_r_child)
11088 Dwarf_Die ltype_die, rtype_die;
11089 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
11090 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
11093 result = compare_dies(rdr, <ype_die, &rtype_die,
11094 aggregates_being_compared,
11095 update_canonical_dies_on_the_fly);
11101 case DW_TAG_subrange_type:
11103 uint64_t l_lower_bound = 0, r_lower_bound = 0,
11104 l_upper_bound = 0, r_upper_bound = 0;
11105 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
11106 l_upper_bound_set =
false, r_upper_bound_set =
false;
11108 l_lower_bound_set =
11109 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
11110 r_lower_bound_set =
11111 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
11113 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
11116 uint64_t l_count = 0;
11117 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
11119 l_upper_bound = l_lower_bound + l_count;
11120 l_upper_bound_set =
true;
11126 l_upper_bound_set =
true;
11128 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
11131 uint64_t r_count = 0;
11132 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
11134 r_upper_bound = r_lower_bound + r_count;
11135 r_upper_bound_set =
true;
11141 r_upper_bound_set =
true;
11143 if ((l_lower_bound_set != r_lower_bound_set)
11144 || (l_upper_bound_set != r_upper_bound_set)
11145 || (l_lower_bound != r_lower_bound)
11146 || (l_upper_bound != r_upper_bound))
11151 case DW_TAG_subroutine_type:
11152 case DW_TAG_subprogram:
11154 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11156 aggregates_being_compared.add(dies_being_compared);
11158 rdr.compare_count_++;
11160 if (l_tag == DW_TAG_subprogram
11161 && !fn_die_equal_by_linkage_name(rdr, l, r))
11166 else if (l_tag == DW_TAG_subprogram
11167 && rdr.die_is_in_c(l) && rdr.die_is_in_c(r)
11170 result = COMPARISON_RESULT_EQUAL;
11173 else if (!rdr.die_is_in_c(l) && !rdr.die_is_in_c(r))
11179 Dwarf_Die l_return_type, r_return_type;
11180 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
11182 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
11184 if (l_return_type_is_void != r_return_type_is_void
11185 || (!l_return_type_is_void
11186 && !compare_dies(rdr,
11187 &l_return_type, &r_return_type,
11188 aggregates_being_compared,
11189 update_canonical_dies_on_the_fly)))
11193 Dwarf_Die l_child, r_child;
11194 bool found_l_child, found_r_child;
11195 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11197 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11199 found_l_child && found_r_child;
11200 found_l_child = dwarf_siblingof(&l_child,
11202 found_r_child = dwarf_siblingof(&r_child,
11205 int l_child_tag = dwarf_tag(&l_child);
11206 int r_child_tag = dwarf_tag(&r_child);
11208 COMPARISON_RESULT_EQUAL;
11209 if (l_child_tag != r_child_tag)
11210 local_result = COMPARISON_RESULT_DIFFERENT;
11211 if (l_child_tag == DW_TAG_formal_parameter)
11213 compare_dies(rdr, &l_child, &r_child,
11214 aggregates_being_compared,
11215 update_canonical_dies_on_the_fly);
11216 if (local_result == COMPARISON_RESULT_DIFFERENT)
11218 result = local_result;
11222 if (local_result == COMPARISON_RESULT_UNKNOWN)
11233 result = local_result;
11235 if (found_l_child != found_r_child)
11245 case DW_TAG_formal_parameter:
11247 Dwarf_Die l_type, r_type;
11248 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
11249 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
11250 if (l_type_is_void != r_type_is_void)
11252 else if (!l_type_is_void)
11255 compare_dies(rdr, &l_type, &r_type,
11256 aggregates_being_compared,
11257 update_canonical_dies_on_the_fly);
11263 case DW_TAG_variable:
11264 case DW_TAG_member:
11265 if (compare_as_decl_dies(l, r))
11268 if (l_tag == DW_TAG_member)
11270 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11271 die_member_offset(rdr, l, l_offset_in_bits);
11272 die_member_offset(rdr, r, r_offset_in_bits);
11273 if (l_offset_in_bits != r_offset_in_bits)
11279 Dwarf_Die l_type, r_type;
11280 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11281 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11283 compare_dies(rdr, &l_type, &r_type,
11284 aggregates_being_compared,
11285 update_canonical_dies_on_the_fly);
11293 case DW_TAG_inheritance:
11295 Dwarf_Die l_type, r_type;
11296 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11297 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11298 result = compare_dies(rdr, &l_type, &r_type,
11299 aggregates_being_compared,
11300 update_canonical_dies_on_the_fly);
11304 uint64_t l_a = 0, r_a = 0;
11305 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
11306 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
11310 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
11311 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
11315 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11316 die_member_offset(rdr, l, l_offset_in_bits);
11317 die_member_offset(rdr, r, r_offset_in_bits);
11318 if (l_offset_in_bits != r_offset_in_bits)
11323 case DW_TAG_ptr_to_member_type:
11325 bool comp_result =
false;
11326 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
11330 Dwarf_Die l_type, r_type;
11331 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11332 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11333 result = compare_dies(rdr, &l_type, &r_type,
11334 aggregates_being_compared,
11335 update_canonical_dies_on_the_fly);
11339 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
11340 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
11341 result = compare_dies(rdr, &l_type, &r_type,
11342 aggregates_being_compared,
11343 update_canonical_dies_on_the_fly);
11349 case DW_TAG_enumerator:
11350 case DW_TAG_packed_type:
11351 case DW_TAG_set_type:
11352 case DW_TAG_file_type:
11353 case DW_TAG_thrown_type:
11354 case DW_TAG_interface_type:
11355 case DW_TAG_shared_type:
11356 case DW_TAG_compile_unit:
11357 case DW_TAG_namespace:
11358 case DW_TAG_module:
11359 case DW_TAG_constant:
11360 case DW_TAG_partial_unit:
11361 case DW_TAG_imported_unit:
11362 case DW_TAG_dwarf_procedure:
11363 case DW_TAG_imported_declaration:
11364 case DW_TAG_entry_point:
11366 case DW_TAG_lexical_block:
11367 case DW_TAG_unspecified_parameters:
11368 case DW_TAG_variant:
11369 case DW_TAG_common_block:
11370 case DW_TAG_common_inclusion:
11371 case DW_TAG_inlined_subroutine:
11372 case DW_TAG_with_stmt:
11373 case DW_TAG_access_declaration:
11374 case DW_TAG_catch_block:
11375 case DW_TAG_friend:
11376 case DW_TAG_namelist:
11377 case DW_TAG_namelist_item:
11378 case DW_TAG_template_type_parameter:
11379 case DW_TAG_template_value_parameter:
11380 case DW_TAG_try_block:
11381 case DW_TAG_variant_part:
11382 case DW_TAG_imported_module:
11383 case DW_TAG_condition:
11384 case DW_TAG_type_unit:
11385 case DW_TAG_template_alias:
11386 case DW_TAG_lo_user:
11387 case DW_TAG_MIPS_loop:
11388 case DW_TAG_format_label:
11389 case DW_TAG_function_template:
11390 case DW_TAG_class_template:
11391 case DW_TAG_GNU_BINCL:
11392 case DW_TAG_GNU_EINCL:
11393 case DW_TAG_GNU_template_template_param:
11394 case DW_TAG_GNU_template_parameter_pack:
11395 case DW_TAG_GNU_formal_parameter_pack:
11396 case DW_TAG_GNU_call_site:
11397 case DW_TAG_GNU_call_site_parameter:
11398 case DW_TAG_hi_user:
11399#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11400 if (rdr.debug_die_canonicalization_is_on_)
11427compare_dies(
const reader& rdr,
11428 const Dwarf_Die *l,
11429 const Dwarf_Die *r,
11430 bool update_canonical_dies_on_the_fly)
11432 offset_pairs_stack_type aggregates_being_compared(rdr);
11433 return compare_dies(rdr, l, r, aggregates_being_compared,
11434 update_canonical_dies_on_the_fly);
11456compare_dies_during_canonicalization(reader& rdr,
11457 const Dwarf_Die *l,
11458 const Dwarf_Die *r,
11459 bool update_canonical_dies_on_the_fly)
11461#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11462 if (rdr.debug_die_canonicalization_is_on_)
11464 bool canonical_equality =
false, structural_equality =
false;
11465 rdr.use_canonical_die_comparison_ =
false;
11466 structural_equality = compare_dies(rdr, l, r,
11468 rdr.use_canonical_die_comparison_ =
true;
11469 canonical_equality = compare_dies(rdr, l, r,
11470 update_canonical_dies_on_the_fly);
11471 if (canonical_equality != structural_equality)
11473 std::cerr <<
"structural & canonical equality different for DIEs: "
11475 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11476 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
11479 << rdr.get_die_pretty_type_representation(l, 0)
11484 return structural_equality;
11487 return compare_dies(rdr, l, r,
11488 update_canonical_dies_on_the_fly);
11530find_import_unit_point_between_dies(
const reader& rdr,
11531 size_t partial_unit_offset,
11532 Dwarf_Off first_die_offset,
11533 Dwarf_Off first_die_cu_offset,
11535 size_t last_die_offset,
11536 size_t& imported_point_offset)
11539 rdr.tu_die_imported_unit_points_map(source);
11541 tu_die_imported_unit_points_map_type::const_iterator iter =
11542 tu_die_imported_unit_points_map.find(first_die_cu_offset);
11544 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
11547 if (imported_unit_points.empty())
11550 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
11551 imported_unit_points_type::const_iterator e = imported_unit_points.end();
11553 find_lower_bound_in_imported_unit_points(imported_unit_points,
11557 if (last_die_offset !=
static_cast<size_t>(-1))
11558 find_lower_bound_in_imported_unit_points(imported_unit_points,
11562 if (e != imported_unit_points.end())
11564 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11565 if (i->imported_unit_die_off == partial_unit_offset)
11567 imported_point_offset = i->offset_of_import ;
11571 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11573 if (find_import_unit_point_between_dies(rdr,
11574 partial_unit_offset,
11575 i->imported_unit_child_off,
11576 i->imported_unit_cu_off,
11577 i->imported_unit_die_source,
11579 imported_point_offset))
11585 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11586 if (i->imported_unit_die_off == partial_unit_offset)
11588 imported_point_offset = i->offset_of_import ;
11592 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11594 if (find_import_unit_point_between_dies(rdr,
11595 partial_unit_offset,
11596 i->imported_unit_child_off,
11597 i->imported_unit_cu_off,
11598 i->imported_unit_die_source,
11600 imported_point_offset))
11633find_import_unit_point_before_die(
const reader& rdr,
11634 size_t partial_unit_offset,
11635 size_t where_offset,
11636 size_t& imported_point_offset)
11638 size_t import_point_offset = 0;
11639 Dwarf_Die first_die_of_tu;
11641 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
11642 &first_die_of_tu) != 0)
11645 Dwarf_Die cu_die_memory;
11648 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
11649 &cu_die_memory, 0, 0);
11651 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
11652 dwarf_dieoffset(&first_die_of_tu),
11653 dwarf_dieoffset(cu_die),
11654 PRIMARY_DEBUG_INFO_DIE_SOURCE,
11656 import_point_offset))
11658 imported_point_offset = import_point_offset;
11662 if (import_point_offset)
11664 imported_point_offset = import_point_offset;
11692get_parent_die(
const reader& rdr,
11693 const Dwarf_Die* die,
11694 Dwarf_Die& parent_die,
11695 size_t where_offset)
11699 const die_source source = rdr.get_die_source(die);
11702 offset_offset_map_type::const_iterator i =
11703 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
11710 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
11711 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11712 i->second, &parent_die));
11714 case ALT_DEBUG_INFO_DIE_SOURCE:
11715 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
11716 i->second, &parent_die));
11718 case TYPE_UNIT_DIE_SOURCE:
11719 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11720 i->second, &parent_die));
11722 case NO_DEBUG_INFO_DIE_SOURCE:
11723 case NUMBER_OF_DIE_SOURCES:
11727 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
11729 if (where_offset == 0)
11731 parent_die = *rdr.cur_tu_die();
11734 size_t import_point_offset = 0;
11736 find_import_unit_point_before_die(rdr,
11737 dwarf_dieoffset(&parent_die),
11739 import_point_offset);
11745 parent_die = *rdr.cur_tu_die();
11749 Dwarf_Die import_point_die;
11750 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11751 import_point_offset,
11752 &import_point_die));
11753 return get_parent_die(rdr, &import_point_die,
11754 parent_die, where_offset);
11781get_scope_die(
const reader& rdr,
11782 const Dwarf_Die* die,
11783 size_t where_offset,
11784 Dwarf_Die& scope_die)
11788 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
11789 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
11792 Dwarf_Die logical_parent_die;
11793 if (die_die_attribute(die, DW_AT_specification,
11794 logical_parent_die,
false)
11795 || die_die_attribute(die, DW_AT_abstract_origin,
11796 logical_parent_die,
false))
11797 return get_scope_die(rdr, &logical_parent_die, where_offset, scope_die);
11799 if (!get_parent_die(rdr, die, scope_die, where_offset))
11802 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
11803 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
11804 || dwarf_tag(&scope_die) == DW_TAG_array_type)
11805 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
11832get_scope_for_die(reader& rdr,
11834 bool called_for_public_decl,
11835 size_t where_offset)
11837 const die_source source_of_die = rdr.get_die_source(die);
11840 rdr.get_die_language(die, die_lang);
11842 || rdr.die_parent_map(source_of_die).empty())
11847 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
11848 return rdr.global_scope();
11851 Dwarf_Die cloned_die;
11852 if (die_die_attribute(die, DW_AT_specification, cloned_die,
false)
11853 || die_die_attribute(die, DW_AT_abstract_origin, cloned_die,
false))
11854 return get_scope_for_die(rdr, &cloned_die,
11855 called_for_public_decl,
11858 Dwarf_Die parent_die;
11860 if (!get_parent_die(rdr, die, parent_die, where_offset))
11861 return rdr.nil_scope();
11863 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
11864 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
11865 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11867 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
11868 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11870 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
11871 || source_of_die == TYPE_UNIT_DIE_SOURCE);
11872 return rdr.cur_transl_unit()->get_global_scope();
11881 die_tu_map_type::const_iterator i =
11882 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
11883 if (i != rdr.die_tu_map().end())
11884 return i->second->get_global_scope();
11885 return rdr.cur_transl_unit()->get_global_scope();
11890 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
11891 || dwarf_tag(&parent_die) == DW_TAG_array_type
11892 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
11904 called_for_public_decl,
11913 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
11914 return rdr.nil_scope();
11915 s = get_scope_for_die(rdr, &parent_die,
11916 called_for_public_decl,
11922 d = build_ir_node_from_die(rdr, &parent_die,
11923 called_for_public_decl,
11925 s = dynamic_pointer_cast<scope_decl>(d);
11929 return rdr.nil_scope();
11932 if (cl && cl->get_is_declaration_only())
11935 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
11952dwarf_language_to_tu_language(
size_t l)
11957 return translation_unit::LANG_C89;
11959 return translation_unit::LANG_C;
11960 case DW_LANG_Ada83:
11961 return translation_unit::LANG_Ada83;
11962 case DW_LANG_C_plus_plus:
11963 return translation_unit::LANG_C_plus_plus;
11964 case DW_LANG_Cobol74:
11965 return translation_unit::LANG_Cobol74;
11966 case DW_LANG_Cobol85:
11967 return translation_unit::LANG_Cobol85;
11968 case DW_LANG_Fortran77:
11969 return translation_unit::LANG_Fortran77;
11970 case DW_LANG_Fortran90:
11971 return translation_unit::LANG_Fortran90;
11972 case DW_LANG_Pascal83:
11973 return translation_unit::LANG_Pascal83;
11974 case DW_LANG_Modula2:
11975 return translation_unit::LANG_Modula2;
11977 return translation_unit::LANG_Java;
11979 return translation_unit::LANG_C99;
11980 case DW_LANG_Ada95:
11981 return translation_unit::LANG_Ada95;
11982 case DW_LANG_Fortran95:
11983 return translation_unit::LANG_Fortran95;
11985 return translation_unit::LANG_PLI;
11987 return translation_unit::LANG_ObjC;
11988 case DW_LANG_ObjC_plus_plus:
11989 return translation_unit::LANG_ObjC_plus_plus;
11991#ifdef HAVE_DW_LANG_Rust_enumerator
11993 return translation_unit::LANG_Rust;
11996#ifdef HAVE_DW_LANG_UPC_enumerator
11998 return translation_unit::LANG_UPC;
12001#ifdef HAVE_DW_LANG_D_enumerator
12003 return translation_unit::LANG_D;
12006#ifdef HAVE_DW_LANG_Python_enumerator
12007 case DW_LANG_Python:
12008 return translation_unit::LANG_Python;
12011#ifdef HAVE_DW_LANG_Go_enumerator
12013 return translation_unit::LANG_Go;
12016#ifdef HAVE_DW_LANG_C11_enumerator
12018 return translation_unit::LANG_C11;
12021#ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
12022 case DW_LANG_C_plus_plus_03:
12023 return translation_unit::LANG_C_plus_plus_03;
12026#ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
12027 case DW_LANG_C_plus_plus_11:
12028 return translation_unit::LANG_C_plus_plus_11;
12031#ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
12032 case DW_LANG_C_plus_plus_14:
12033 return translation_unit::LANG_C_plus_plus_14;
12036#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
12037 case DW_LANG_Mips_Assembler:
12038 return translation_unit::LANG_Mips_Assembler;
12042 return translation_unit::LANG_UNKNOWN;
12059 case translation_unit::LANG_UNKNOWN:
12062 case translation_unit::LANG_Cobol74:
12063 case translation_unit::LANG_Cobol85:
12066 case translation_unit::LANG_C89:
12067 case translation_unit::LANG_C99:
12068 case translation_unit::LANG_C11:
12069 case translation_unit::LANG_C:
12070 case translation_unit::LANG_C_plus_plus_03:
12071 case translation_unit::LANG_C_plus_plus_11:
12072 case translation_unit::LANG_C_plus_plus_14:
12073 case translation_unit::LANG_C_plus_plus:
12074 case translation_unit::LANG_ObjC:
12075 case translation_unit::LANG_ObjC_plus_plus:
12076 case translation_unit::LANG_Rust:
12079 case translation_unit::LANG_Fortran77:
12080 case translation_unit::LANG_Fortran90:
12081 case translation_unit::LANG_Fortran95:
12082 case translation_unit::LANG_Ada83:
12083 case translation_unit::LANG_Ada95:
12084 case translation_unit::LANG_Pascal83:
12085 case translation_unit::LANG_Modula2:
12088 case translation_unit::LANG_Java:
12091 case translation_unit::LANG_PLI:
12094 case translation_unit::LANG_UPC:
12095 case translation_unit::LANG_D:
12096 case translation_unit::LANG_Python:
12097 case translation_unit::LANG_Go:
12098 case translation_unit::LANG_Mips_Assembler:
12125 imported_unit_points_type::const_iterator& r)
12127 imported_unit_point v(val);
12128 imported_unit_points_type::const_iterator result =
12129 std::lower_bound(p.begin(), p.end(), v);
12131 bool is_ok = result != p.end();
12153build_translation_unit_and_add_to_ir(reader& rdr,
12161 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
12165 rdr.clear_per_translation_unit_data();
12167 rdr.cur_tu_die(die);
12169 string path = die_string_attribute(die, DW_AT_name);
12170 if (path ==
"<artificial>")
12176 std::ostringstream o;
12177 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
12180 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
12190 const string& abs_path =
12191 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
12192 result = rdr.corpus()->find_translation_unit(abs_path);
12197 result.reset(
new translation_unit(rdr.env(),
12200 result->set_compilation_dir_path(compilation_dir);
12201 rdr.corpus()->add(result);
12203 die_unsigned_constant_attribute(die, DW_AT_language, l);
12204 result->set_language(dwarf_language_to_tu_language(l));
12207 rdr.cur_transl_unit(result);
12208 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
12211 if (dwarf_child(die, &child) != 0)
12214 result->set_is_constructed(
false);
12219 if (!rdr.env().analyze_exported_interfaces_only()
12220 || rdr.is_decl_die_with_exported_symbol(&child))
12221 build_ir_node_from_die(rdr, &child,
12222 die_is_public_decl(&child),
12223 dwarf_dieoffset(&child));
12224 while (dwarf_siblingof(&child, &child) == 0);
12226 if (!rdr.var_decls_to_re_add_to_tree().empty())
12227 for (list<var_decl_sptr>::const_iterator v =
12228 rdr.var_decls_to_re_add_to_tree().begin();
12229 v != rdr.var_decls_to_re_add_to_tree().end();
12236 string demangled_name =
12238 if (!demangled_name.empty())
12240 std::list<string> fqn_comps;
12242 string mem_name = fqn_comps.back();
12243 fqn_comps.pop_back();
12246 if (!fqn_comps.empty())
12274 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
12280 rdr.var_decls_to_re_add_to_tree().clear();
12282 result->set_is_constructed(
true);
12307build_namespace_decl_and_add_to_ir(reader& rdr,
12309 size_t where_offset)
12316 unsigned tag = dwarf_tag(die);
12317 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
12324 string name, linkage_name;
12326 die_loc_and_name(rdr, die, loc, name, linkage_name);
12328 result.reset(
new namespace_decl(rdr.env(), name, loc));
12330 rdr.associate_die_to_decl(die, result, where_offset);
12333 if (dwarf_child(die, &child) != 0)
12336 rdr.scope_stack().push(result.get());
12338 build_ir_node_from_die(rdr, &child,
12344 die_is_public_decl(die) && die_is_public_decl(&child),
12346 while (dwarf_siblingof(&child, &child) == 0);
12347 rdr.scope_stack().pop();
12362build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
12368 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
12370 uint64_t byte_size = 0, bit_size = 0;
12371 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
12372 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
12375 if (bit_size == 0 && byte_size != 0)
12377 bit_size = byte_size * 8;
12379 string type_name, linkage_name;
12381 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
12383 if (byte_size == 0)
12387 if (type_name ==
"void")
12388 result =
is_type_decl(build_ir_node_for_void_type(rdr));
12395 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12397 string normalized_type_name = type_name;
12398 integral_type int_type;
12400 normalized_type_name = int_type.
to_string();
12405 if (corpus_sptr corp = rdr.corpus())
12408 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
12409 0, loc, linkage_name));
12410 rdr.associate_die_to_type(die, result, where_offset);
12428build_enum_underlying_type(reader& rdr,
12430 uint64_t enum_size,
12431 bool is_anonymous =
true)
12433 string underlying_type_name =
12437 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
12438 enum_size, enum_size, location()));
12439 result->set_is_anonymous(is_anonymous);
12440 result->set_is_artificial(
true);
12443 result = dynamic_pointer_cast<type_decl>(d);
12464build_enum_type(reader& rdr,
12467 size_t where_offset,
12468 bool is_declaration_only)
12474 unsigned tag = dwarf_tag(die);
12475 if (tag != DW_TAG_enumeration_type)
12478 string name, linkage_name;
12480 die_loc_and_name(rdr, die, loc, name, linkage_name);
12482 bool is_anonymous =
false;
12486 name = get_internal_anonymous_die_prefix_name(die);
12489 is_anonymous =
true;
12491 if (
size_t s = scope->get_num_anonymous_member_enums())
12492 name = build_internal_anonymous_die_name(name, s);
12495 bool use_odr = rdr.odr_is_relevant(die);
12507 result = pre_existing_enum;
12509 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12518 if (pre_existing_enum->get_location() == loc)
12519 result = pre_existing_enum;
12524 rdr.associate_die_to_type(die, result, where_offset);
12532 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
12534 bool is_artificial = die_is_artificial(die);
12537 bool enum_underlying_type_is_anonymous=
true;
12541 if (dwarf_child(die, &child) == 0)
12545 if (dwarf_tag(&child) != DW_TAG_enumerator)
12550 die_loc_and_name(rdr, &child, l, n, m);
12552 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
12553 enms.push_back(enum_type_decl::enumerator(n, val));
12555 while (dwarf_siblingof(&child, &child) == 0);
12563 build_enum_underlying_type(rdr, name, size,
12564 enum_underlying_type_is_anonymous);
12565 t->set_is_declaration_only(is_declaration_only);
12567 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
12568 result->set_is_anonymous(is_anonymous);
12569 result->set_is_declaration_only(is_declaration_only);
12570 result->set_is_artificial(is_artificial);
12571 rdr.associate_die_to_type(die, result, where_offset);
12573 rdr.maybe_schedule_declaration_only_enum_for_resolution(result);
12592finish_member_function_reading(Dwarf_Die* die,
12594 const class_or_union_sptr klass,
12605 bool is_ctor = (f->get_name() == klass->get_name());
12606 bool is_dtor = (!f->get_name().empty()
12607 &&
static_cast<string>(f->get_name())[0] ==
'~');
12608 bool is_virtual = die_is_virtual(die);
12609 int64_t vindex = -1;
12611 die_virtual_function_index(die, vindex);
12614 if (!c->is_struct())
12615 access = private_access;
12616 die_access_specifier(die, access);
12618 bool is_static =
false;
12626 if (!f->get_parameters().empty())
12627 first_parm = f->get_parameters()[0];
12629 bool is_artificial = first_parm && first_parm->get_is_artificial();
12630 type_base_sptr this_ptr_type, other_klass;
12633 this_ptr_type = first_parm->get_type();
12640 this_ptr_type = q->get_underlying_type();
12644 other_klass = p->get_pointed_to_type();
12649 other_klass = q->get_underlying_type();
12652 &&
get_type_name(other_klass) == klass->get_qualified_name())
12663 Dwarf_Die object_pointer_die;
12664 if (die_has_object_pointer(die, object_pointer_die))
12680 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol())
12699 Dwarf_Off die_offset = dwarf_dieoffset(die);
12701 rdr.die_function_decl_with_no_symbol_map();
12702 die_function_decl_map_type::const_iterator i =
12703 fns_with_no_symbol.find(die_offset);
12704 if (i == fns_with_no_symbol.end())
12705 fns_with_no_symbol[die_offset] = f;
12726maybe_finish_function_decl_reading(reader& rdr,
12728 size_t where_offset,
12746static type_base_sptr
12747lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
12750 corpus* corp = scope->get_corpus();
12771static type_base_sptr
12772lookup_class_or_typedef_from_corpus(reader& rdr,
12774 bool called_for_public_decl,
12775 size_t where_offset)
12780 string class_name = die_string_attribute(die, DW_AT_name);
12781 if (class_name.empty())
12785 called_for_public_decl,
12788 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
12790 return type_base_sptr();
12801static type_base_sptr
12802lookup_class_typedef_or_enum_type_from_corpus(scope_decl* scope,
12803 const string& type_name)
12806 corpus* corp = scope->get_corpus();
12824static type_base_sptr
12825lookup_class_typedef_or_enum_type_from_corpus(Dwarf_Die* die,
12826 size_t anonymous_member_type_idx,
12832 string type_name = die_string_attribute(die, DW_AT_name);
12835 get_internal_anonymous_die_name(die, anonymous_member_type_idx);
12837 if (type_name.empty())
12840 return lookup_class_typedef_or_enum_type_from_corpus(scope, type_name);
12858static method_decl_sptr
12859is_function_for_die_a_member_of_class(reader& rdr,
12860 Dwarf_Die* function_die,
12861 const class_or_union_sptr& class_type)
12866 return method_decl_sptr();
12872 method_type = method->get_type();
12877 class_or_union_sptr method_class = method_type->get_class_type();
12880 string method_class_name = method_class->get_qualified_name(),
12881 class_type_name = class_type->get_qualified_name();
12883 if (method_class_name == class_type_name)
12889 return method_decl_sptr();
12911static method_decl_sptr
12912add_or_update_member_function(reader& rdr,
12913 Dwarf_Die* function_die,
12914 const class_or_union_sptr& class_type,
12915 bool called_from_public_decl,
12916 size_t where_offset)
12918 method_decl_sptr method =
12919 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
12922 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
12924 called_from_public_decl,
12927 return method_decl_sptr();
12929 finish_member_function_reading(function_die,
12972add_or_update_class_type(reader& rdr,
12977 bool called_from_public_decl,
12978 size_t where_offset,
12979 bool is_declaration_only)
12985 const die_source source = rdr.get_die_source(die);
12987 unsigned tag = dwarf_tag(die);
12989 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
12993 die_class_or_union_map_type::const_iterator i =
12994 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
12995 if (i != rdr.die_wip_classes_map(source).end())
13003 string name, linkage_name;
13005 die_loc_and_name(rdr, die, loc, name, linkage_name);
13007 bool is_anonymous =
false;
13012 name = get_internal_anonymous_die_prefix_name(die);
13015 is_anonymous =
true;
13017 if (
size_t s = scope->get_num_anonymous_member_classes())
13018 name = build_internal_anonymous_die_name(name, s);
13023 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13039 && (result->get_is_declaration_only() == is_declaration_only
13040 || (!result->get_is_declaration_only()
13041 && is_declaration_only)))
13043 rdr.associate_die_to_type(die, result, where_offset);
13062 klass = pre_existing_class;
13065 die_size_in_bits(die, size);
13066 bool is_artificial = die_is_artificial(die);
13069 bool has_child = (dwarf_child(die, &child) == 0);
13071 decl_base_sptr res;
13074 res = result = klass;
13075 if (has_child && klass->get_is_declaration_only()
13076 && klass->get_definition_of_declaration())
13077 res = result =
is_class_type(klass->get_definition_of_declaration());
13079 result->set_location(loc);
13083 result.reset(
new class_decl(rdr.env(), name, size,
13085 decl_base::VISIBILITY_DEFAULT,
13088 result->set_is_declaration_only(is_declaration_only);
13091 result = dynamic_pointer_cast<class_decl>(res);
13095 if (!klass || klass->get_is_declaration_only())
13096 if (size != result->get_size_in_bits())
13097 result->set_size_in_bits(size);
13102 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
13115 result->set_is_declaration_only(is_declaration_only);
13119 if (!result->get_is_declaration_only() && has_child)
13120 if (result->get_size_in_bits() == 0 && size != 0)
13121 result->set_size_in_bits(size);
13123 result->set_is_artificial(is_artificial);
13125 rdr.associate_die_to_type(die, result, where_offset);
13127 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13134 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13136 bool is_incomplete_type =
false;
13137 if (is_declaration_only && size == 0 && has_child)
13149 is_incomplete_type =
true;
13152 dynamic_pointer_cast<scope_decl>(res);
13154 rdr.scope_stack().push(scop.get());
13156 if (has_child && !is_incomplete_type)
13158 int anonymous_member_class_index = -1;
13159 int anonymous_member_union_index = -1;
13160 int anonymous_member_enum_index = -1;
13164 tag = dwarf_tag(&child);
13167 if (tag == DW_TAG_inheritance)
13169 result->set_is_declaration_only(
false);
13171 Dwarf_Die type_die;
13172 if (!die_die_attribute(&child, DW_AT_type, type_die))
13175 type_base_sptr base_type;
13177 lookup_class_or_typedef_from_corpus(rdr, &type_die,
13178 called_from_public_decl,
13182 is_type(build_ir_node_from_die(rdr, &type_die,
13183 called_from_public_decl,
13197 die_access_specifier(&child, access);
13199 bool is_virt= die_is_virtual(&child);
13200 int64_t offset = 0;
13201 bool is_offset_present =
13202 die_member_offset(rdr, &child, offset);
13206 is_offset_present ? offset : -1,
13208 if (b->get_is_declaration_only())
13209 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
13210 if (result->find_base_class(b->get_qualified_name()))
13212 result->add_base_specifier(base);
13215 else if (tag == DW_TAG_member
13216 || tag == DW_TAG_variable)
13218 Dwarf_Die type_die;
13219 if (!die_die_attribute(&child, DW_AT_type, type_die))
13224 die_loc_and_name(rdr, &child, loc, n, m);
13229 if (n.substr(0, 5) ==
"_vptr"
13231 && !std::isalnum(n.at(5))
13241 int64_t offset_in_bits = 0;
13242 bool is_laid_out = die_member_offset(rdr, &child,
13247 bool is_static = !is_laid_out;
13249 if (is_static && variable_is_suppressed(rdr,
13254 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
13255 called_from_public_decl,
13257 type_base_sptr t =
is_type(ty);
13261 if (n.empty() && !die_is_anonymous_data_member(&child))
13267 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
13284 result->set_is_declaration_only(
false);
13290 die_access_specifier(&child, access);
13298 result->add_data_member(dm, access, is_laid_out,
13299 is_static, offset_in_bits);
13301 rdr.associate_die_to_decl(&child, dm, where_offset,
13305 else if (tag == DW_TAG_subprogram)
13308 add_or_update_member_function(rdr, &child, result,
13309 called_from_public_decl,
13312 rdr.associate_die_to_decl(&child, f, where_offset,
13316 else if (die_is_type(&child))
13322 int anonymous_member_type_index = 0;
13326 if (die_is_class_type(&child))
13327 anonymous_member_type_index =
13328 ++anonymous_member_class_index;
13329 else if (dwarf_tag(&child) == DW_TAG_union_type)
13330 anonymous_member_type_index =
13331 ++anonymous_member_union_index;
13332 else if (dwarf_tag(&child) == DW_TAG_enumeration_type)
13333 anonymous_member_type_index =
13334 ++anonymous_member_enum_index;
13339 && !lookup_class_typedef_or_enum_type_from_corpus
13340 (&child, anonymous_member_type_index, result.get()))
13341 || !result->find_member_type(die_name(&child)))
13342 build_ir_node_from_die(rdr, &child, result.get(),
13343 called_from_public_decl,
13346 }
while (dwarf_siblingof(&child, &child) == 0);
13349 rdr.scope_stack().pop();
13352 die_class_or_union_map_type::const_iterator i =
13353 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13354 if (i != rdr.die_wip_classes_map(source).end())
13359 rdr.die_wip_classes_map(source).erase(i);
13363 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13391static union_decl_sptr
13392add_or_update_union_type(reader& rdr,
13395 union_decl_sptr union_type,
13396 bool called_from_public_decl,
13397 size_t where_offset,
13398 bool is_declaration_only)
13400 union_decl_sptr result;
13404 unsigned tag = dwarf_tag(die);
13406 if (tag != DW_TAG_union_type)
13409 const die_source source = rdr.get_die_source(die);
13411 die_class_or_union_map_type::const_iterator i =
13412 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13413 if (i != rdr.die_wip_classes_map(source).end())
13421 string name, linkage_name;
13423 die_loc_and_name(rdr, die, loc, name, linkage_name);
13425 bool is_anonymous =
false;
13430 name = get_internal_anonymous_die_prefix_name(die);
13433 is_anonymous =
true;
13435 if (
size_t s = scope->get_num_anonymous_member_unions())
13436 name = build_internal_anonymous_die_name(name, s);
13446 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13455 rdr.associate_die_to_type(die, result, where_offset);
13467 if (union_decl_sptr pre_existing_union =
13469 union_type = pre_existing_union;
13472 die_size_in_bits(die, size);
13473 bool is_artificial = die_is_artificial(die);
13477 result = union_type;
13478 result->set_location(loc);
13482 result.reset(
new union_decl(rdr.env(), name, size, loc,
13483 decl_base::VISIBILITY_DEFAULT,
13485 if (is_declaration_only)
13486 result->set_is_declaration_only(
true);
13493 result->set_size_in_bits(size);
13494 result->set_is_declaration_only(
false);
13497 result->set_is_artificial(is_artificial);
13499 rdr.associate_die_to_type(die, result, where_offset);
13501 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13504 bool has_child = (dwarf_child(die, &child) == 0);
13508 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13511 dynamic_pointer_cast<scope_decl>(result);
13513 rdr.scope_stack().push(scop.get());
13519 tag = dwarf_tag(&child);
13521 if (tag == DW_TAG_member || tag == DW_TAG_variable)
13523 Dwarf_Die type_die;
13524 if (!die_die_attribute(&child, DW_AT_type, type_die))
13529 die_loc_and_name(rdr, &child, loc, n, m);
13538 ssize_t offset_in_bits = 0;
13539 decl_base_sptr ty =
13540 is_decl(build_ir_node_from_die(rdr, &type_die,
13541 called_from_public_decl,
13543 type_base_sptr t =
is_type(ty);
13550 result->set_is_declaration_only(
false);
13553 die_access_specifier(&child, access);
13559 if (n.empty() && result->find_data_member(dm))
13562 result->add_data_member(dm, access,
true,
13566 rdr.associate_die_to_decl(&child, dm, where_offset,
13570 else if (tag == DW_TAG_subprogram)
13573 is_decl(build_ir_node_from_die(rdr, &child,
13575 called_from_public_decl,
13583 finish_member_function_reading(&child, f, result, rdr);
13585 rdr.associate_die_to_decl(&child, f, where_offset,
13589 else if (die_is_type(&child))
13590 decl_base_sptr td =
13591 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
13592 called_from_public_decl,
13594 }
while (dwarf_siblingof(&child, &child) == 0);
13597 rdr.scope_stack().pop();
13600 die_class_or_union_map_type::const_iterator i =
13601 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13602 if (i != rdr.die_wip_classes_map(source).end())
13607 rdr.die_wip_classes_map(source).erase(i);
13631static type_base_sptr
13632build_qualified_type(reader& rdr,
13634 bool called_from_public_decl,
13635 size_t where_offset)
13637 type_base_sptr result;
13641 unsigned tag = dwarf_tag(die);
13643 if (tag != DW_TAG_const_type
13644 && tag != DW_TAG_volatile_type
13645 && tag != DW_TAG_restrict_type)
13648 Dwarf_Die underlying_type_die;
13649 decl_base_sptr utype_decl;
13650 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13654 utype_decl = build_ir_node_for_void_type(rdr);
13657 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
13658 called_from_public_decl,
13665 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13668 rdr.associate_die_to_type(die, result, where_offset);
13672 type_base_sptr utype =
is_type(utype_decl);
13676 if (tag == DW_TAG_const_type)
13677 qual |= qualified_type_def::CV_CONST;
13678 else if (tag == DW_TAG_volatile_type)
13679 qual |= qualified_type_def::CV_VOLATILE;
13680 else if (tag == DW_TAG_restrict_type)
13681 qual |= qualified_type_def::CV_RESTRICT;
13686 result.reset(
new qualified_type_def(utype, qual, location()));
13688 rdr.associate_die_to_type(die, result, where_offset);
13706schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
13711 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13713 rdr.schedule_type_for_late_canonicalization(t);
13717 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13719 rdr.schedule_type_for_late_canonicalization(t);
13723 for (vector<array_type_def::subrange_sptr>::const_iterator i =
13724 type->get_subranges().begin();
13725 i != type->get_subranges().end();
13728 if (!(*i)->get_scope())
13730 rdr.schedule_type_for_late_canonicalization(*i);
13733 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
13735 rdr.schedule_type_for_late_canonicalization(type);
13754static decl_base_sptr
13755maybe_strip_qualification(
const qualified_type_def_sptr t,
13761 decl_base_sptr result = t;
13762 type_base_sptr u = t->get_underlying_type();
13766 if (result.get() != t.get())
13772 scope_decl * scope = 0;
13775 scope = array->get_scope();
13778 schedule_array_tree_for_late_canonicalization(array, rdr);
13780 t->set_underlying_type(array);
13781 u = t->get_underlying_type();
13789 schedule_array_tree_for_late_canonicalization(typdef, rdr);
13792 t->set_underlying_type(typdef);
13793 u = t->get_underlying_type();
13802 type_base_sptr element_type = array->get_element_type();
13807 ABG_ASSERT(!qualified->get_canonical_type());
13809 quals |= t->get_cv_quals();
13810 qualified->set_cv_quals(quals);
13816 qualified_type_def_sptr qual_type
13817 (
new qualified_type_def(element_type,
13819 t->get_location()));
13822 array->set_element_type(qual_type);
13823 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
13848build_pointer_type_def(reader& rdr,
13850 bool called_from_public_decl,
13851 size_t where_offset)
13858 unsigned tag = dwarf_tag(die);
13859 if (tag != DW_TAG_pointer_type)
13863 Dwarf_Die underlying_type_die;
13864 bool has_underlying_type_die =
false;
13865 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13868 utype_decl = build_ir_node_for_void_type(rdr);
13870 has_underlying_type_die =
true;
13872 if (!utype_decl && has_underlying_type_die)
13873 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
13874 called_from_public_decl,
13881 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13888 type_base_sptr utype =
is_type(utype_decl);
13894 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13895 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13902 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
13904 result.reset(
new pointer_type_def(utype, size, 0, location()));
13910 rdr.associate_die_to_type(die, result, where_offset);
13932build_reference_type(reader& rdr,
13934 bool called_from_public_decl,
13935 size_t where_offset)
13942 unsigned tag = dwarf_tag(die);
13943 if (tag != DW_TAG_reference_type
13944 && tag != DW_TAG_rvalue_reference_type)
13947 Dwarf_Die underlying_type_die;
13948 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13952 build_ir_node_from_die(rdr, &underlying_type_die,
13953 called_from_public_decl,
13960 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13967 type_base_sptr utype =
is_type(utype_decl);
13973 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13974 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
13979 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
13981 bool is_lvalue = tag == DW_TAG_reference_type;
13983 result.reset(
new reference_type_def(utype, is_lvalue, size,
13986 if (corpus_sptr corp = rdr.corpus())
13989 rdr.associate_die_to_type(die, result, where_offset);
14010build_function_type(reader& rdr,
14012 class_or_union_sptr is_method,
14013 size_t where_offset)
14020 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
14021 || dwarf_tag(die) == DW_TAG_subprogram);
14023 const die_source source = rdr.get_die_source(die);
14026 size_t off = dwarf_dieoffset(die);
14027 auto i = rdr.die_wip_function_types_map(source).find(off);
14028 if (i != rdr.die_wip_function_types_map(source).end())
14036 decl_base_sptr type_decl;
14044 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
14048 rdr.associate_die_to_type(die, result, where_offset);
14065 rdr.associate_die_to_type(die, fn_type, where_offset);
14073 bool is_const =
false;
14074 bool is_static =
false;
14075 Dwarf_Die object_pointer_die;
14076 Dwarf_Die class_type_die;
14077 bool has_this_parm_die =
14078 die_function_type_is_method_type(rdr, die, where_offset,
14079 object_pointer_die,
14082 if (has_this_parm_die)
14087 if (die_object_pointer_is_for_const_method(&object_pointer_die))
14095 class_or_union_sptr klass_type =
14100 is_method = klass_type;
14109 result.reset(is_method
14110 ?
new method_type(is_method, is_const,
14111 tu->get_address_size(),
14113 :
new function_type(rdr.env(), tu->get_address_size(),
14115 rdr.associate_die_to_type(die, result, where_offset);
14116 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
14118 type_base_sptr return_type;
14119 Dwarf_Die ret_type_die;
14120 if (die_die_attribute(die, DW_AT_type, ret_type_die))
14122 is_type(build_ir_node_from_die(rdr, &ret_type_die,
14126 return_type =
is_type(build_ir_node_for_void_type(rdr));
14127 result->set_return_type(return_type);
14132 if (dwarf_child(die, &child) == 0)
14135 int child_tag = dwarf_tag(&child);
14136 if (child_tag == DW_TAG_formal_parameter)
14139 string name, linkage_name;
14141 die_loc_and_name(rdr, &child, loc, name, linkage_name);
14146 bool is_artificial = die_is_artificial(&child);
14147 type_base_sptr parm_type;
14148 Dwarf_Die parm_type_die;
14149 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
14151 is_type(build_ir_node_from_die(rdr, &parm_type_die,
14157 (
new function_decl::parameter(parm_type, name, loc,
14160 function_parms.push_back(p);
14162 else if (child_tag == DW_TAG_unspecified_parameters)
14165 bool is_artificial = die_is_artificial(&child);
14167 type_base_sptr parm_type =
14168 is_type(build_ir_node_for_variadic_parameter_type(rdr));
14170 (
new function_decl::parameter(parm_type,
14175 function_parms.push_back(p);
14185 while (dwarf_siblingof(&child, &child) == 0);
14187 result->set_parameters(function_parms);
14189 tu->bind_function_type_life_time(result);
14191 result->set_is_artificial(
true);
14193 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
14196 die_function_type_map_type::const_iterator i =
14197 rdr.die_wip_function_types_map(source).
14198 find(dwarf_dieoffset(die));
14199 if (i != rdr.die_wip_function_types_map(source).end())
14200 rdr.die_wip_function_types_map(source).erase(i);
14203 maybe_canonicalize_type(result, rdr);
14230build_subrange_type(reader& rdr,
14231 const Dwarf_Die* die,
14232 size_t where_offset,
14233 bool associate_type_to_die)
14240 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
14241 if (tag != DW_TAG_subrange_type)
14244 string name = die_name(die);
14247 Dwarf_Die underlying_type_die;
14248 type_base_sptr underlying_type;
14250 bool is_signed =
false;
14251 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
14253 is_type(build_ir_node_from_die(rdr,
14254 &underlying_type_die,
14258 if (underlying_type)
14261 if (die_unsigned_constant_attribute (&underlying_type_die,
14264 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
14268 array_type_def::subrange_type::bound_value lower_bound =
14269 get_default_array_lower_bound(language);
14270 array_type_def::subrange_type::bound_value upper_bound;
14271 uint64_t count = 0;
14272 bool is_infinite =
false;
14273 bool count_present =
false;
14284 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
14286 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
14287 is_signed, upper_bound);
14288 if (!found_upper_bound)
14289 found_upper_bound = subrange_die_indirect_bound_value(die,
14294 if (!found_upper_bound)
14307 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
14309 count_present =
true;
14313 int64_t u = lower_bound.get_signed_value() + count;
14314 upper_bound = u - 1;
14317 if (!count_present)
14321 is_infinite =
true;
14324 if (UINT64_MAX == upper_bound.get_unsigned_value())
14327 is_infinite =
true;
14330 (
new array_type_def::subrange_type(rdr.env(),
14335 result->is_infinite(is_infinite);
14337 if (underlying_type)
14338 result->set_underlying_type(underlying_type);
14342 || (result->get_length() ==
14343 (uint64_t) (result->get_upper_bound()
14344 - result->get_lower_bound() + 1)));
14346 if (associate_type_to_die)
14347 rdr.associate_die_to_type(die, result, where_offset);
14369build_subranges_from_array_type_die(reader& rdr,
14370 const Dwarf_Die* die,
14372 size_t where_offset,
14373 bool associate_type_to_die)
14377 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
14381 int child_tag = dwarf_tag(&child);
14382 if (child_tag == DW_TAG_subrange_type)
14385 if (associate_type_to_die)
14391 build_ir_node_from_die(rdr, &child,
14400 s = build_subrange_type(rdr, &child,
14404 subranges.push_back(s);
14407 while (dwarf_siblingof(&child, &child) == 0);
14428build_array_type(reader& rdr,
14430 bool called_from_public_decl,
14431 size_t where_offset)
14438 unsigned tag = dwarf_tag(die);
14439 if (tag != DW_TAG_array_type)
14442 decl_base_sptr type_decl;
14443 Dwarf_Die type_die;
14445 if (die_die_attribute(die, DW_AT_type, type_die))
14446 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
14447 called_from_public_decl,
14454 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14461 type_base_sptr type =
is_type(type_decl);
14466 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
14468 result.reset(
new array_type_def(type, subranges, location()));
14490build_typedef_type(reader& rdr,
14492 bool called_from_public_decl,
14493 size_t where_offset)
14500 unsigned tag = dwarf_tag(die);
14501 if (tag != DW_TAG_typedef)
14504 string name, linkage_name;
14506 die_loc_and_name(rdr, die, loc, name, linkage_name);
14508 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14514 type_base_sptr utype;
14515 Dwarf_Die underlying_type_die;
14516 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14519 utype = rdr.env().get_void_type();
14523 is_type(build_ir_node_from_die(rdr,
14524 &underlying_type_die,
14525 called_from_public_decl,
14531 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
14538 decl_base_sptr decl =
is_decl(utype);
14540 decl->set_naming_typedef(result);
14544 rdr.associate_die_to_type(die, result, where_offset);
14578build_or_get_var_decl_if_not_suppressed(reader& rdr,
14581 size_t where_offset,
14583 bool is_required_decl_spec)
14586 if (variable_is_suppressed(rdr, scope, die, is_required_decl_spec))
14591 string var_name = die_name(die);
14592 if (!var_name.empty())
14593 if ((var = class_type->find_data_member(var_name)))
14596 var = build_var_decl(rdr, die, where_offset, result);
14619build_var_decl(reader& rdr,
14621 size_t where_offset,
14627 int tag = dwarf_tag(die);
14628 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
14630 if (!die_is_public_decl(die))
14633 type_base_sptr type;
14634 Dwarf_Die type_die;
14635 if (die_die_attribute(die, DW_AT_type, type_die))
14637 decl_base_sptr ty =
14638 is_decl(build_ir_node_from_die(rdr, &type_die,
14647 if (!type && !result)
14650 string name, linkage_name;
14652 die_loc_and_name(rdr, die, loc, name, linkage_name);
14655 result.reset(
new var_decl(name, type, loc, linkage_name));
14661 if (!linkage_name.empty())
14662 result->set_linkage_name(linkage_name);
14665 result->set_type(type);
14671 if (!result->get_symbol())
14674 Dwarf_Addr var_addr;
14676 if (rdr.get_variable_address(die, var_addr))
14679 update_main_symbol(var_addr,
14680 result->get_linkage_name().empty()
14681 ? result->get_name()
14682 : result->get_linkage_name());
14683 var_sym = rdr.variable_symbol_is_exported(var_addr);
14688 result->set_symbol(var_sym);
14691 string linkage_name = result->get_linkage_name();
14692 if (linkage_name.empty()
14693 || !var_sym->get_alias_from_name(linkage_name))
14694 result->set_linkage_name(var_sym->get_name());
14695 result->set_is_in_public_symbol_table(
true);
14721function_is_suppressed(
const reader& rdr,
14722 const scope_decl* scope,
14723 Dwarf_Die *function_die,
14724 bool is_declaration_only)
14726 if (function_die == 0
14727 || dwarf_tag(function_die) != DW_TAG_subprogram)
14730 string fname = die_string_attribute(function_die, DW_AT_name);
14731 string flinkage_name = die_linkage_name(function_die);
14732 if (flinkage_name.empty() && rdr.die_is_in_c(function_die))
14733 flinkage_name = fname;
14743 && (!is_declaration_only || rdr.drop_undefined_syms()))
14745 Dwarf_Addr fn_addr;
14746 if (!rdr.get_function_address(function_die, fn_addr))
14750 rdr.function_symbol_is_exported(fn_addr);
14753 if (!symbol->is_suppressed())
14760 if (symbol->has_aliases())
14762 !a->is_main_symbol(); a = a->get_next_alias())
14763 if (!a->is_suppressed())
14812build_or_get_fn_decl_if_not_suppressed(reader& rdr,
14815 size_t where_offset,
14816 bool is_declaration_only,
14820 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
14823 string name = die_name(fn_die);
14824 string linkage_name = die_linkage_name(fn_die);
14825 bool is_dtor = !name.empty() && name[0]==
'~';
14826 bool is_virtual =
false;
14829 Dwarf_Attribute attr;
14830 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
14831 DW_AT_vtable_elem_location,
14843 if (!result && (!(is_dtor && is_virtual)))
14846 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
14847 rdr.associate_die_to_decl(fn_die, fn,
true);
14848 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
14856 string linkage_name = die_linkage_name(fn_die);
14857 fn = klass->find_member_function_sptr(linkage_name);
14864 if (!fn || !fn->get_symbol())
14871 fn = build_function_decl(rdr, fn_die, where_offset, result);
14893variable_is_suppressed(
const reader& rdr,
14894 const scope_decl* scope,
14895 Dwarf_Die *variable_die,
14896 bool is_required_decl_spec)
14898 if (variable_die == 0
14899 || (dwarf_tag(variable_die) != DW_TAG_variable
14900 && dwarf_tag(variable_die) != DW_TAG_member))
14903 string name = die_string_attribute(variable_die, DW_AT_name);
14904 string linkage_name = die_linkage_name(variable_die);
14905 if (linkage_name.empty() && rdr.die_is_in_c(variable_die))
14906 linkage_name = name;
14916 Dwarf_Addr var_addr = 0;
14917 if (!rdr.get_variable_address(variable_die, var_addr))
14921 rdr.variable_symbol_is_exported(var_addr);
14924 if (!symbol->is_suppressed())
14931 if (symbol->has_aliases())
14933 !a->is_main_symbol(); a = a->get_next_alias())
14934 if (!a->is_suppressed())
14963type_is_suppressed(
const reader& rdr,
14964 const scope_decl* scope,
14965 Dwarf_Die *type_die,
14966 bool &type_is_private)
14969 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
14970 && dwarf_tag(type_die) != DW_TAG_class_type
14971 && dwarf_tag(type_die) != DW_TAG_structure_type
14972 && dwarf_tag(type_die) != DW_TAG_union_type))
14975 string type_name, linkage_name;
14976 location type_location;
14977 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15001type_is_suppressed(
const reader& rdr,
15002 const scope_decl* scope,
15003 Dwarf_Die *type_die)
15005 bool type_is_private =
false;
15006 return type_is_suppressed(rdr, scope, type_die, type_is_private);
15030get_opaque_version_of_type(reader &rdr,
15032 Dwarf_Die *type_die,
15033 size_t where_offset)
15040 unsigned tag = dwarf_tag(type_die);
15041 if (tag != DW_TAG_class_type
15042 && tag != DW_TAG_structure_type
15043 && tag != DW_TAG_union_type
15044 && tag != DW_TAG_enumeration_type)
15047 string type_name, linkage_name;
15048 location type_location;
15049 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15050 if (!type_location)
15060 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
15062 string_classes_or_unions_map::const_iterator i =
15063 rdr.declaration_only_classes().find(qualified_name);
15064 if (i != rdr.declaration_only_classes().end())
15065 result = i->second.back();
15076 tag == DW_TAG_structure_type,
15078 decl_base::VISIBILITY_DEFAULT));
15079 klass->set_is_declaration_only(
true);
15080 klass->set_is_artificial(die_is_artificial(type_die));
15082 rdr.associate_die_to_type(type_die, klass, where_offset);
15083 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
15088 if (tag == DW_TAG_enumeration_type)
15090 string_enums_map::const_iterator i =
15091 rdr.declaration_only_enums().find(qualified_name);
15092 if (i != rdr.declaration_only_enums().end())
15093 result = i->second.back();
15098 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
15101 build_enum_underlying_type(rdr, type_name, size,
15109 enum_type->set_is_artificial(die_is_artificial(type_die));
15111 result = enum_type;
15134 elf_symbol::FUNC_TYPE,
15135 elf_symbol::GLOBAL_BINDING,
15139 elf_symbol::DEFAULT_VISIBILITY);
15157build_function_decl(reader& rdr,
15159 size_t where_offset,
15165 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subprogram);
15167 if (!die_is_public_decl(die))
15173 string fname, flinkage_name;
15175 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
15177 size_t is_inline = die_is_declared_inline(die);
15178 class_or_union_sptr is_method =
15191 if (!flinkage_name.empty()
15192 && result->get_linkage_name() != flinkage_name)
15193 result->set_linkage_name(flinkage_name);
15195 if (!result->get_location())
15196 result->set_location(floc);
15205 maybe_canonicalize_type(fn_type, rdr);
15207 result.reset(is_method
15208 ?
new method_decl(fname, fn_type,
15211 :
new function_decl(fname, fn_type,
15218 if (!result->get_symbol())
15221 Dwarf_Addr fn_addr;
15222 if (rdr.get_function_address(die, fn_addr))
15225 update_main_symbol(fn_addr,
15226 result->get_linkage_name().empty()
15227 ? result->get_name()
15228 : result->get_linkage_name());
15229 fn_sym = rdr.function_symbol_is_exported(fn_addr);
15232 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
15234 result->set_symbol(fn_sym);
15235 string linkage_name = result->get_linkage_name();
15236 if (linkage_name.empty())
15237 result->set_linkage_name(fn_sym->get_name());
15238 result->set_is_in_public_symbol_table(
true);
15242 rdr.associate_die_to_type(die, result->get_type(), where_offset);
15244 size_t die_offset = dwarf_dieoffset(die);
15249 && !result->get_linkage_name().empty())
15255 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
15274maybe_canonicalize_type(
const type_base_sptr& t,
15287 ||(
is_decl(peeled_type) &&
is_decl(peeled_type)->get_is_anonymous()))
15297 rdr.schedule_type_for_late_canonicalization(t);
15299 rdr.schedule_type_for_late_canonicalization(t);
15310maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
15313 if (
is_type(member_type_declaration)
15316 class_or_union* scope =
15322 if (!cl->is_struct())
15323 access = private_access;
15325 die_access_specifier(die, access);
15348 if (!fn || fn->get_scope())
15352 !die_is_virtual(fn_die)
15354 && !fn->get_linkage_name().empty()
15356 && !fn->get_symbol())
15401build_ir_node_from_die(reader& rdr,
15404 bool called_from_public_decl,
15405 size_t where_offset,
15406 bool is_declaration_only,
15407 bool is_required_decl_spec)
15411 if (!die || !scope)
15414 int tag = dwarf_tag(die);
15416 if (!called_from_public_decl)
15418 if (rdr.load_all_types() && die_is_type(die))
15422 else if (tag != DW_TAG_subprogram
15423 && tag != DW_TAG_variable
15424 && tag != DW_TAG_member
15425 && tag != DW_TAG_namespace)
15429 const die_source source_of_die = rdr.get_die_source(die);
15431 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
15434 if (rdr.load_all_types())
15435 if (called_from_public_decl)
15436 if (type_base_sptr t =
is_type(result))
15437 if (corpus *abi_corpus = scope->get_corpus())
15438 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15447 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
15452 case DW_TAG_base_type:
15461 case DW_TAG_typedef:
15464 t =
is_typedef(scope->find_member_type(die_name(die)));
15467 t = build_typedef_type(rdr, die,
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:
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);
15985static decl_base_sptr
15986build_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;
16009build_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;
16025static decl_base_sptr
16026build_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;
16061build_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,
16128elf_based_reader_sptr
16130 const vector<char**>& debug_info_root_paths,
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);
16141 return static_pointer_cast<elf_based_reader>(r);
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,
16226 bool load_all_types,
16229 elf_based_reader_sptr rdr =
16230 dwarf::reader::create(elf_path, debug_info_root_paths,
16234 return rdr->read_corpus(status);
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);
The private data and functions of the abigail::ir::corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define SET_RESULT_TO(result, value, l, r)
A macro to set the 'result' variable to a given value.
#define SET_RESULT_TO_FALSE(result, l, r)
A macro to set the 'result' variable to 'false'.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
This file contains the declarations of the entry points to de-serialize an instance of abigail::corpu...
This file contains the declarations for an elf-based. DWARF and CTF readers can inherit this one.
bool architecture_is_big_endian(Elf *elf_handle)
Test if the endianness of the current binary is Big Endian.
bool get_binary_load_address(Elf *elf_handle, GElf_Addr &load_address)
Get the address at which a given binary is loaded in memory.
bool get_version_for_symbol(Elf *elf_handle, size_t symbol_index, bool get_def_version, elf_symbol::version &version)
Return the version for a symbol that is at a given index in its SHT_SYMTAB section.
elf_symbol::binding stb_to_elf_symbol_binding(unsigned char stb)
Convert an elf symbol binding (given by the ELF{32,64}_ST_BIND macros) into an elf_symbol::binding va...
elf_symbol::visibility stv_to_elf_symbol_visibility(unsigned char stv)
Convert an ELF symbol visiblity given by the symbols ->st_other data member as returned by the GELF_S...
bool find_symbol_table_section_index(Elf *elf_handle, size_t &symtab_index)
Find the index (in the section headers table) of the symbol table section.
elf_symbol::type stt_to_elf_symbol_type(unsigned char stt)
Convert an elf symbol type (given by the ELF{32,64}_ST_TYPE macros) into an elf_symbol::type value.
hash_table_kind find_hash_table_section_index(Elf *elf_handle, size_t &ht_section_index, size_t &symtab_section_index)
Get the offset offset of the hash table section.
This contains a set of ELF utilities used by the dwarf reader.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
This contains the private implementation of the suppression engine of libabigail.
Utilities to ease the wrapping of C types into std::shared_ptr.
This contains the private implementation of the suppression engine of libabigail.
This contains the declarations for the symtab reader.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
const string & elf_architecture() const
Get the value of the 'ARCHITECTURE' property of the current ELF file.
const Dwarf * dwarf_debug_info() const
Getter of the handle used to access DWARF information from the current ELF file.
virtual ir::corpus_sptr read_corpus(status &status)
Read the ELF information associated to the current ELF file and construct an ABI representation from ...
const Dwarf * alternate_dwarf_debug_info() const
Getter of the handle use to access DWARF information from the alternate split DWARF information.
bool refers_to_alt_debug_info(string &alt_di_path) const
Check if the underlying elf file refers to an alternate debug info file associated to it.
elf_symbol_sptr variable_symbol_is_exported(GElf_Addr symbol_address) const
Test if a given variable symbol has been exported.
elf_symbol_sptr function_symbol_is_exported(GElf_Addr symbol_address) const
Test if a given function symbol has been exported.
const vector< string > & dt_needed() const
Get the value of the DT_NEEDED property of the current ELF file.
The common interface of readers based on ELF.
elf_based_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &env)
Readers that implement this interface must provide a factory method to create a reader instance as th...
virtual void initialize(const std::string &elf_path, const vector< char ** > &debug_info_root_paths)
(re)Initialize) the resources used by the current reader.
status
The status of the fe_iface::read_corpus call.
@ STATUS_DEBUG_INFO_NOT_FOUND
This status is for when the debug info could not be read.
@ STATUS_ALT_DEBUG_INFO_NOT_FOUND
This status is for when the alternate debug info could not be found.
@ STATUS_UNKNOWN
The status is in an unknown state.
const options_type & options() const
Getter of the the options of the current Front End Interface.
void maybe_add_fn_to_exported_decls(const function_decl *fn)
Try and add the representation of the ABI of a function to the set of exported declarations of the cu...
corpus_sptr corpus()
Getter for the ABI corpus being built by the current front-end.
corpus_group_sptr & corpus_group()
Getter for the ABI corpus group being built by the current front-end.
const std::string & corpus_path() const
Getter of the path to the file which an ABI corpus is to be created for.
const string & dt_soname() const
Getter for the SONAME of the analyzed binary.
The abstraction of an interned string.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
origin
This abstracts where the corpus comes from. That is, either it has been read from the native xml form...
scope_decl * get_scope() const
Return the type containing the current decl, if any.
The abstraction of the version of an ELF symbol.
binding
The binding of a symbol.
type
The type of a symbol.
static elf_symbol_sptr create(const environment &e, size_t i, size_t s, const string &n, type t, binding b, bool d, bool c, const version &ve, visibility vi, bool is_in_ksymtab=false, const abg_compat::optional< uint32_t > &crc={}, const abg_compat::optional< std::string > &ns={}, bool is_suppressed=false)
Factory of instances of elf_symbol.
visibility
The visibility of the symbol.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a function_decl::parameter.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
The internal representation of an integral type.
string to_string(bool internal=false) const
Return the string representation of the current instance of integral_type.
The source location of a token.
CV
Bit field values representing the cv qualifiers of the underlying type.
language
The language of the translation unit.
visiting_kind operator~(visiting_kind l)
The overloaded 'bit inversion' operator for visiting_kind.
unordered_map< std::pair< offset_type, offset_type >, offset_pair_set_type, offset_pair_hash > offset_pair_set_map_type
A convenience typedef for an unordered_map that associates a pair of offset_type to a set of pairs of...
unordered_map< Dwarf_Off, translation_unit_sptr > die_tu_map_type
Convenience typedef for a map which key is the offset of a DW_TAG_compile_unit and the value is the c...
bool lookup_symbol_from_elf(const environment &env, const string &elf_path, const string &symbol_name, bool demangle, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of a given elf file and see if we find a given symbol.
void reset_reader(elf_based_reader &rdr, const std::string &elf_path, const vector< char ** > &debug_info_root_path, bool read_all_types, bool linux_kernel_mode)
Re-initialize a reader so that it can re-used to read another binary.
unordered_map< string, classes_type > string_classes_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
std::pair< offset_type, offset_type > offset_pair_type
A convenience typedef for a pair of offset_type.
shared_ptr< addr_elf_symbol_sptr_map_type > addr_elf_symbol_sptr_map_sptr
Convenience typedef for a shared pointer to an addr_elf_symbol_sptr_map_type.
bool is_anonymous_type_die(Dwarf_Die *die)
Test if a given DIE represents an anonymous type.
unordered_map< Dwarf_Off, class_or_union_sptr > die_class_or_union_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
unordered_map< Dwarf_Off, function_type_sptr > die_function_type_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
unordered_map< Dwarf_Off, interned_string > die_istring_map_type
Convenience typedef for a map which key is the offset of a DIE and the value is the corresponding qua...
unordered_map< Dwarf_Off, function_decl_sptr > die_function_decl_map_type
Convenience typedef for a map which key the offset of a dwarf die and which value is the correspondin...
bool lookup_public_function_symbol_from_elf(environment &env, const string &path, const string &symname, vector< elf_symbol_sptr > &syms)
Look into the symbol tables of an elf file to see if a public function of a given name is found.
unordered_set< offset_type, offset_hash > offset_set_type
A convenience typedef for an unordered set of DIE offsets.
unordered_map< Dwarf_Off, type_or_decl_base_sptr > die_artefact_map_type
Convenience typedef for a map which key is the offset of a dwarf die and which value is the correspon...
unordered_map< std::pair< offset_type, offset_type >, offset_pair_vector_type, offset_pair_hash > offset_pair_vect_map_type
A convenience typedef for an unordered map that associates a pair of offset_type to a vector of pairs...
unordered_map< interned_string, function_type_sptr, hash_interned_string > istring_fn_type_map_type
Convenience typedef for a map that associates an interned_string to a function_type_sptr.
unordered_map< Dwarf_Off, class_decl_sptr > die_class_map_type
Convenience typedef for a map which key is the offset of a dwarf die, (given by dwarf_dieoffset()) an...
unordered_map< string, classes_or_unions_type > string_classes_or_unions_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
elf_symbol_sptr create_default_fn_sym(const string &sym_name, const environment &env)
Create a function symbol with a given name.
unordered_map< Dwarf_Off, imported_unit_points_type > tu_die_imported_unit_points_map_type
Convenience typedef for a vector of imported_unit_point.
vector< Dwarf_Off > dwarf_offsets_type
A convenience typedef for a vector of Dwarf_Off.
unordered_map< Dwarf_Off, Dwarf_Off > offset_offset_map_type
Convenience typedef for a map which key is a dwarf offset. The value is also a dwarf offset.
unordered_set< std::pair< offset_type, offset_type >, offset_pair_hash > offset_pair_set_type
A convenience typedef for an unordered set of pairs of offset_type.
unordered_map< string, enums_type > string_enums_map
Convenience typedef for a map which key is a string and which value is a vector of smart pointer to a...
stack< scope_decl * > scope_stack_type
Convenience typedef for a stack containing the scopes up to the current point in the abigail Internal...
vector< std::pair< offset_type, offset_type > > offset_pair_vector_type
A convenience typedef for a vector of pairs of offset_type.
elf_based_reader_sptr create_reader(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, bool linux_kernel_mode)
Create a dwarf::reader.
die_source
Where a DIE comes from. For instance, a DIE can come from the main debug info section,...
unordered_map< interned_string, dwarf_offsets_type, hash_interned_string > istring_dwarf_offsets_map_type
Convenience typedef for a map which is an interned_string and which value is a vector of offsets.
vector< imported_unit_point > imported_unit_points_type
Convenience typedef for a vector of imported_unit_point.
corpus_sptr read_corpus_from_elf(const std::string &elf_path, const vector< char ** > &debug_info_root_paths, environment &environment, bool load_all_types, fe_iface::status &status)
Read all abigail::translation_unit possible from the debug info accessible from an elf file,...
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
type_decl_sptr lookup_basic_type(const interned_string &type_name, const translation_unit &tu)
Lookup a basic type from a translation unit.
shared_ptr< method_type > method_type_sptr
Convenience typedef for shared pointer to method_type.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
const type_base_wptrs_type * lookup_enum_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the enum type*s* that have a given qualified name.
type_base_sptr lookup_class_or_typedef_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, union or typedef type which has a given qualified name.
void set_member_function_is_virtual(function_decl &f, bool is_virtual)
Set the virtual-ness of a member function.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
const type_base * is_void_pointer_type(const type_base *t)
Test if a type is a pointer to void type.
bool is_type(const type_or_decl_base &tod)
Test whether a declaration is a type.
bool has_scope(const decl_base &d)
Tests if a declaration has got a scope.
array_type_def::subrange_type * is_subrange_type(const type_or_decl_base *type)
Test if a type is an array_type_def::subrange_type.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
void set_member_function_vtable_offset(function_decl &f, ssize_t s)
Set the vtable offset of a member function.
class_decl_sptr is_compatible_with_class_type(const type_base_sptr &t)
Test if a type is a class. This function looks through typedefs.
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
bool is_anonymous_type(const type_base *t)
Test whether a declaration is a type.
type_base_sptr lookup_class_typedef_or_enum_type(const string &qualified_name, const corpus &corp)
Look into a corpus to find a class, typedef or enum type which has a given qualified name.
array_type_def * is_array_type(const type_or_decl_base *type)
Test if a type is an array_type_def.
reference_type_def * is_reference_type(type_or_decl_base *t)
Test whether a type is a reference_type_def.
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
shared_ptr< class_decl > class_decl_sptr
Convenience typedef for a shared pointer on a class_decl.
type_base_sptr peel_typedef_pointer_or_reference_type(const type_base_sptr type)
Return the leaf underlying or pointed-to type node of a typedef_decl, pointer_type_def,...
void set_member_function_is_const(function_decl &f, bool is_const)
set the const-ness property of a member function.
decl_base_sptr strip_useless_const_qualification(const qualified_type_def_sptr t)
Strip qualification from a qualified type, when it makes sense.
void 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.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
enum_type_decl_sptr lookup_enum_type_per_location(const interned_string &loc, const corpus &corp)
Look up an enum_type_decl from a given corpus, by its location.
shared_ptr< function_type > function_type_sptr
Convenience typedef for a shared pointer on a function_type.
shared_ptr< typedef_decl > typedef_decl_sptr
Convenience typedef for a shared pointer on a typedef_decl.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
bool parse_integral_type(const string &type_name, integral_type &type)
Parse an integral type from a string.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
const global_scope * get_global_scope(const decl_base &decl)
return the global scope as seen by a given declaration.
shared_ptr< var_decl > var_decl_sptr
Convenience typedef for a shared pointer on a var_decl.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
const decl_base_sptr lookup_var_decl_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a var_decl in a scope.
type_base * type_has_non_canonicalized_subtype(type_base_sptr t)
Test if a type has sub-types that are non-canonicalized.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
type_base_sptr canonicalize(type_base_sptr t)
Compute the canonical type of a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
pointer_type_def * is_pointer_type(type_or_decl_base *t)
Test whether a type is a pointer_type_def.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
interned_string get_type_name(const type_base_sptr &t, bool qualified, bool internal)
Get the name of a given type and return a copy of it.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
typedef_decl_sptr lookup_typedef_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a typedef_decl from a corpus, by its location.
function_decl * is_function_decl(const type_or_decl_base *d)
Test whether a declaration is a function_decl.
method_type_sptr is_method_type(const type_or_decl_base_sptr &t)
Test whether a type is a method_type.
qualified_type_def * is_qualified_type(const type_or_decl_base *t)
Test whether a type is a reference_type_def.
union_decl_sptr lookup_union_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a union type in a given corpus, from its location.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
enum_type_decl_sptr look_through_decl_only_enum(const enum_type_decl &the_enum)
If an enum is a decl-only enum, get its definition. Otherwise, just return the initial enum.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
bool is_type_suppressed(const fe_iface &fe, const string &type_name, const location &type_location, bool &type_is_private, bool require_drop_property)
Test if a type is matched by at least one suppression specification associated with a given front-end...
bool is_function_suppressed(const fe_iface &fe, const string &fn_name, const string &fn_linkage_name, bool require_drop_property)
Test if a function is matched by at least one suppression specification associated with a given front...
bool is_variable_suppressed(const fe_iface &fe, const string &var_name, const string &var_linkage_name, bool require_drop_property)
Test if a variable is matched by at least one suppression specification associated with a given front...
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
fe_iface::status operator&(fe_iface::status l, fe_iface::status r)
The bitwise AND operator for the fe_iface::status type.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
fe_iface::status operator|(fe_iface::status l, fe_iface::status r)
The bitwise OR operator for the fe_iface::status type.
std::ostream & operator<<(std::ostream &o, const interned_string &s)
Streaming operator.
A functor to hash instances of interned_string.