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);
527die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die);
530subrange_die_indirect_bound_value(
const Dwarf_Die *die,
532 array_type_def::subrange_type::bound_value& v,
536subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
538 Dwarf_Die& referenced_subrange);
540get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die);
543build_internal_anonymous_die_name(
const string &
base_name,
544 size_t anonymous_type_index);
547get_internal_anonymous_die_name(Dwarf_Die *die,
548 size_t anonymous_type_index);
551die_qualified_type_name(
const reader& rdr,
552 const Dwarf_Die* die,
556die_qualified_decl_name(
const reader& rdr,
557 const Dwarf_Die* die,
561die_qualified_name(
const reader& rdr,
562 const Dwarf_Die* die,
566die_qualified_type_name_empty(
const reader& rdr,
567 const Dwarf_Die* die,
size_t where,
568 string &qualified_name);
571die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
572 const Dwarf_Die* die,
575 string &return_type_name,
577 vector<string>& parm_names,
582die_function_signature(
const reader& rdr,
583 const Dwarf_Die *die,
584 size_t where_offset);
587die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die);
590die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die);
593die_function_type_is_method_type(
const reader& rdr,
594 const Dwarf_Die *die,
596 Dwarf_Die& object_pointer_die,
597 Dwarf_Die& class_die,
601die_pretty_print_type(reader& rdr,
602 const Dwarf_Die* die,
603 size_t where_offset);
606die_pretty_print_decl(reader& rdr,
607 const Dwarf_Die* die,
608 size_t where_offset);
611die_pretty_print(reader& rdr,
612 const Dwarf_Die* die,
613 size_t where_offset);
616maybe_canonicalize_type(
const type_base_sptr& t,
625 imported_unit_points_type::const_iterator&);
628build_subrange_type(reader& rdr,
629 const Dwarf_Die* die,
631 bool associate_type_to_die =
true);
634build_subranges_from_array_type_die(reader& rdr,
635 const Dwarf_Die* die,
638 bool associate_type_to_die =
true);
641compare_dies(
const reader& rdr,
642 const Dwarf_Die *l,
const Dwarf_Die *r,
643 bool update_canonical_dies_on_the_fly);
646compare_dies_during_canonicalization(reader& rdr,
647 const Dwarf_Die *l,
const Dwarf_Die *r,
648 bool update_canonical_dies_on_the_fly);
651get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child);
665compare_symbol_name(
const string& symbol_name,
674 return symbol_name == name;
703lookup_symbol_from_sysv_hash_tab(
const environment& env,
705 const string& sym_name,
707 size_t sym_tab_index,
709 vector<elf_symbol_sptr>& syms_found)
711 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
714 Elf_Data* sym_tab_data = elf_getdata(sym_tab_section, 0);
717 GElf_Shdr sheader_mem;
718 GElf_Shdr* sym_tab_section_header = gelf_getshdr(sym_tab_section,
720 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
725 unsigned long hash = elf_hash(sym_name.c_str());
726 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
727 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
728 size_t nb_buckets = ht_data[0];
729 size_t nb_chains = ht_data[1];
737 Elf32_Word* ht_buckets = &ht_data[2];
738 Elf32_Word* ht_chains = &ht_buckets[nb_buckets];
741 size_t bucket = hash % nb_buckets;
742 size_t symbol_index = ht_buckets[bucket];
745 const char* sym_name_str;
754 ABG_ASSERT(gelf_getsym(sym_tab_data, symbol_index, &symbol));
755 sym_name_str = elf_strptr(elf_handle,
756 sym_tab_section_header->sh_link,
759 && compare_symbol_name(sym_name_str, sym_name, demangle))
765 sym_size = symbol.st_size;
766 elf_symbol::version ver;
777 symbol.st_shndx != SHN_UNDEF,
778 symbol.st_shndx == SHN_COMMON,
779 ver, sym_visibility);
780 syms_found.push_back(symbol_found);
783 symbol_index = ht_chains[symbol_index];
784 }
while (symbol_index != STN_UNDEF || symbol_index >= nb_chains);
795get_elf_class_size_in_bytes(Elf* elf_handle)
801 int c = hdr.e_ident[EI_CLASS];
835bloom_word_at(Elf* elf_handle,
836 Elf32_Word* bloom_filter,
839 Elf64_Xword result = 0;
843 c = h.e_ident[EI_CLASS];
848 result = bloom_filter[index];
852 Elf64_Xword* f=
reinterpret_cast<Elf64_Xword*
>(bloom_filter);
873 size_t first_sym_index;
876 Elf32_Word* bloom_filter;
879 Elf_Scn* sym_tab_section;
880 GElf_Shdr sym_tab_section_header;
910setup_gnu_ht(Elf* elf_handle,
912 size_t sym_tab_index,
915 ht.sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
917 ABG_ASSERT(gelf_getshdr(ht.sym_tab_section, &ht.sym_tab_section_header));
919 ht.sym_tab_section_header.sh_size / ht.sym_tab_section_header.sh_entsize;
920 Elf_Scn* hash_section = elf_getscn(elf_handle, ht_index);
925 Elf_Data* ht_section_data = elf_getdata(hash_section, 0);
926 Elf32_Word* ht_data =
reinterpret_cast<Elf32_Word*
>(ht_section_data->d_buf);
928 ht.nb_buckets = ht_data[0];
929 if (ht.nb_buckets == 0)
933 ht.first_sym_index = ht_data[1];
936 ht.bf_nwords = ht_data[2];
938 ht.shift = ht_data[3];
940 ht.bloom_filter = &ht_data[4];
945 ht.bf_size = (get_elf_class_size_in_bytes(elf_handle) / 4) * ht.bf_nwords;
947 ht.buckets = ht.bloom_filter + ht.bf_size;
949 ht.chain = ht.buckets + ht.nb_buckets;
980lookup_symbol_from_gnu_hash_tab(
const environment& env,
982 const string& sym_name,
984 size_t sym_tab_index,
986 vector<elf_symbol_sptr>& syms_found)
989 if (!setup_gnu_ht(elf_handle, ht_index, sym_tab_index, ht))
995 size_t h1 = elf_gnu_hash(sym_name.c_str());
996 size_t h2 = h1 >> ht.shift;
999 int c = get_elf_class_size_in_bytes(elf_handle) * 8;
1000 int n = (h1 / c) % ht.bf_nwords;
1006 Elf64_Xword bitmask = (1ul << (h1 % c)) | (1ul << (h2 % c));
1009 if ((bloom_word_at(elf_handle, ht.bloom_filter, n) & bitmask) != bitmask)
1012 size_t i = ht.buckets[h1 % ht.nb_buckets];
1016 Elf32_Word stop_word, *stop_wordp;
1017 elf_symbol::version ver;
1019 const char* sym_name_str;
1028 for (i = ht.buckets[h1 % ht.nb_buckets],
1029 stop_wordp = &ht.chain[i - ht.first_sym_index];
1032 < ht.chain + (ht.sym_count - ht.first_sym_index));
1035 stop_word = *stop_wordp;
1036 if ((stop_word & ~ 1)!= (h1 & ~1))
1042 ABG_ASSERT(gelf_getsym(elf_getdata(ht.sym_tab_section, 0),
1044 sym_name_str = elf_strptr(elf_handle,
1045 ht.sym_tab_section_header.sh_link,
1048 && compare_symbol_name(sym_name_str, sym_name, demangle))
1066 sym_type, sym_binding,
1067 symbol.st_shndx != SHN_UNDEF,
1068 symbol.st_shndx == SHN_COMMON,
1069 ver, sym_visibility);
1070 syms_found.push_back(symbol_found);
1112lookup_symbol_from_elf_hash_tab(
const environment& env,
1114 hash_table_kind ht_kind,
1116 size_t symtab_index,
1117 const string& symbol_name,
1119 vector<elf_symbol_sptr>& syms_found)
1121 if (elf_handle == 0 || symbol_name.empty())
1124 if (ht_kind == NO_HASH_TABLE_KIND)
1127 if (ht_kind == SYSV_HASH_TABLE_KIND)
1128 return lookup_symbol_from_sysv_hash_tab(env,
1129 elf_handle, symbol_name,
1134 else if (ht_kind == GNU_HASH_TABLE_KIND)
1135 return lookup_symbol_from_gnu_hash_tab(env,
1136 elf_handle, symbol_name,
1169lookup_symbol_from_symtab(
const environment& env,
1171 const string& sym_name,
1172 size_t sym_tab_index,
1174 vector<elf_symbol_sptr>& syms_found)
1179 Elf_Scn* sym_tab_section = elf_getscn(elf_handle, sym_tab_index);
1182 GElf_Shdr header_mem;
1183 GElf_Shdr * sym_tab_header = gelf_getshdr(sym_tab_section,
1186 size_t symcount = sym_tab_header->sh_size / sym_tab_header->sh_entsize;
1187 Elf_Data* symtab = elf_getdata(sym_tab_section, NULL);
1190 elf_symbol::version ver;
1193 for (
size_t i = 0; i < symcount; ++i)
1196 sym = gelf_getsym(symtab, i, &sym_mem);
1197 name_str = elf_strptr(elf_handle,
1198 sym_tab_header->sh_link,
1201 if (name_str && compare_symbol_name(name_str, sym_name, demangle))
1209 bool sym_is_defined = sym->st_shndx != SHN_UNDEF;
1210 bool sym_is_common = sym->st_shndx == SHN_COMMON;
1219 sym_binding, sym_is_defined,
1220 sym_is_common, ver, sym_visibility);
1221 syms_found.push_back(symbol_found);
1260lookup_symbol_from_elf(
const environment& env,
1262 const string& symbol_name,
1264 vector<elf_symbol_sptr>& syms_found)
1266 size_t hash_table_index = 0, symbol_table_index = 0;
1267 hash_table_kind ht_kind = NO_HASH_TABLE_KIND;
1272 symbol_table_index);
1274 if (ht_kind == NO_HASH_TABLE_KIND)
1279 return lookup_symbol_from_symtab(env,
1287 return lookup_symbol_from_elf_hash_tab(env,
1311lookup_public_function_symbol_from_elf(environment& env,
1313 const string& symbol_name,
1314 vector<elf_symbol_sptr>& func_syms)
1316 vector<elf_symbol_sptr> syms_found;
1319 if (lookup_symbol_from_elf(env, elf_handle, symbol_name,
1322 for (vector<elf_symbol_sptr>::const_iterator i = syms_found.begin();
1323 i != syms_found.end();
1329 if ((type == elf_symbol::FUNC_TYPE
1330 || type == elf_symbol::GNU_IFUNC_TYPE
1331 || type == elf_symbol::COMMON_TYPE)
1332 && (binding == elf_symbol::GLOBAL_BINDING
1333 || binding == elf_symbol::WEAK_BINDING))
1335 func_syms.push_back(*i);
1356 int64_t const_value_;
1364 expr_result(
bool is_const)
1365 : is_const_(is_const),
1369 explicit expr_result(int64_t v)
1395 const_value(int64_t& value)
1399 value = const_value_;
1415 return const_value_;
1418 operator int64_t()
const
1419 {
return const_value();}
1422 operator=(
const int64_t v)
1430 {
return const_value_ == o.const_value_ && is_const_ == o.is_const_;}
1433 operator>=(
const expr_result& o)
const
1434 {
return const_value_ >= o.const_value_;}
1437 operator<=(
const expr_result& o)
const
1438 {
return const_value_ <= o.const_value_;}
1441 operator>(
const expr_result& o)
const
1442 {
return const_value_ > o.const_value_;}
1445 operator<(
const expr_result& o)
const
1446 {
return const_value_ < o.const_value_;}
1451 expr_result r(*
this);
1452 r.const_value_ += v.const_value_;
1453 r.is_const_ = r.is_const_ && v.is_const_;
1458 operator+=(int64_t v)
1465 operator-(
const expr_result& v)
const
1467 expr_result r(*
this);
1468 r.const_value_ -= v.const_value_;
1469 r.is_const_ = r.is_const_ && v.is_const_;
1474 operator%(
const expr_result& v)
const
1476 expr_result r(*
this);
1477 r.const_value_ %= v.const_value_;
1478 r.is_const_ = r.is_const_ && v.is_const();
1483 operator*(
const expr_result& v)
const
1485 expr_result r(*
this);
1486 r.const_value_ *= v.const_value_;
1487 r.is_const_ = r.is_const_ && v.is_const();
1494 expr_result r(*
this);
1495 r.const_value_ |= v.const_value_;
1496 r.is_const_ = r.is_const_ && v.is_const_;
1501 operator^(
const expr_result& v)
const
1503 expr_result r(*
this);
1504 r.const_value_ ^= v.const_value_;
1505 r.is_const_ = r.is_const_ && v.is_const_;
1510 operator>>(
const expr_result& v)
const
1512 expr_result r(*
this);
1513 r.const_value_ = r.const_value_ >> v.const_value_;
1514 r.is_const_ = r.is_const_ && v.is_const_;
1521 expr_result r(*
this);
1522 r.const_value_ = r.const_value_ << v.const_value_;
1523 r.is_const_ = r.is_const_ && v.is_const_;
1530 expr_result r(*
this);
1531 r.const_value_ = ~r.const_value_;
1538 expr_result r(*
this);
1539 r.const_value_ = -r.const_value_;
1546 expr_result r = *
this;
1547 r.const_value_ = std::abs(
static_cast<long double>(r.const_value()));
1554 expr_result r(*
this);
1555 r.const_value_ &= o.const_value_;
1556 r.is_const_ = r.is_const_ && o.is_const_;
1561 operator/(
const expr_result& o)
1563 expr_result r(*
this);
1564 r.is_const_ = r.is_const_ && o.is_const_;
1565 return r.const_value() / o.const_value();
1571class expr_result_stack_type
1573 vector<expr_result> elems_;
1577 expr_result_stack_type()
1578 {elems_.reserve(4);}
1581 operator[](
unsigned i)
1583 unsigned s = elems_.size();
1585 return elems_[s - 1 -i];
1589 operator[](
unsigned i)
const
1590 {
return const_cast<expr_result_stack_type*
>(
this)->
operator[](i);}
1594 {
return elems_.size();}
1596 vector<expr_result>::reverse_iterator
1598 {
return elems_.rbegin();}
1600 const vector<expr_result>::reverse_iterator
1602 {
return const_cast<expr_result_stack_type*
>(
this)->begin();}
1604 vector<expr_result>::reverse_iterator
1606 {
return elems_.rend();}
1608 const vector<expr_result>::reverse_iterator
1610 {
return const_cast<expr_result_stack_type*
>(
this)->end();}
1614 {
return elems_.back();}
1618 {
return const_cast<expr_result_stack_type*
>(
this)->front();}
1621 push_front(expr_result e)
1622 {elems_.push_back(e);}
1627 expr_result r = front();
1633 erase(vector<expr_result>::reverse_iterator i)
1634 {elems_.erase(--i.base());}
1642struct dwarf_expr_eval_context
1645 expr_result_stack_type stack;
1650 dwarf_expr_eval_context()
1654 stack.push_front(expr_result(
true));
1661 stack.push_front(expr_result(
true));
1662 accum = expr_result(
false);
1663 set_tls_addr =
false;
1672 set_tls_address(
bool f)
1681 set_tls_address()
const
1682 {
return set_tls_addr;}
1687 expr_result r = stack.front();
1693 push(
const expr_result& v)
1694 {stack.push_front(v);}
1703typedef shared_ptr<reader> reader_sptr;
1710class reader :
public elf_based_reader
1717 template <
typename ContainerType>
1718 class die_source_dependant_container_set
1720 ContainerType primary_debug_info_container_;
1721 ContainerType alt_debug_info_container_;
1722 ContainerType type_unit_container_;
1736 ContainerType *result = 0;
1739 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
1740 result = &primary_debug_info_container_;
1742 case ALT_DEBUG_INFO_DIE_SOURCE:
1743 result = &alt_debug_info_container_;
1745 case TYPE_UNIT_DIE_SOURCE:
1746 result = &type_unit_container_;
1748 case NO_DEBUG_INFO_DIE_SOURCE:
1749 case NUMBER_OF_DIE_SOURCES:
1762 const ContainerType&
1765 return const_cast<die_source_dependant_container_set*
>(
this)->
1766 get_container(source);
1780 get_container(
const reader& rdr,
const Dwarf_Die *die)
1782 const die_source source = rdr.get_die_source(die);
1783 return get_container(source);
1796 const ContainerType&
1797 get_container(
const reader& rdr,
const Dwarf_Die *die)
const
1799 return const_cast<die_source_dependant_container_set*
>(
this)->
1800 get_container(rdr, die);
1807 primary_debug_info_container_.clear();
1808 alt_debug_info_container_.clear();
1809 type_unit_container_.clear();
1813 unsigned short dwarf_version_;
1814 Dwarf_Die* cur_tu_die_;
1815 mutable dwarf_expr_eval_context dwarf_expr_eval_context_;
1819 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1820 decl_die_repr_die_offsets_maps_;
1824 mutable die_source_dependant_container_set<istring_dwarf_offsets_map_type>
1825 type_die_repr_die_offsets_maps_;
1826 mutable die_source_dependant_container_set<die_istring_map_type>
1827 die_qualified_name_maps_;
1828 mutable die_source_dependant_container_set<die_istring_map_type>
1829 die_pretty_repr_maps_;
1830 mutable die_source_dependant_container_set<die_istring_map_type>
1831 die_pretty_type_repr_maps_;
1834 mutable die_source_dependant_container_set<die_artefact_map_type>
1835 decl_die_artefact_maps_;
1838 mutable die_source_dependant_container_set<die_artefact_map_type>
1839 type_die_artefact_maps_;
1842 mutable die_source_dependant_container_set<offset_offset_map_type>
1843 canonical_type_die_offsets_;
1846 mutable die_source_dependant_container_set<offset_offset_map_type>
1847 canonical_decl_die_offsets_;
1853 mutable std::unordered_map<std::pair<offset_type,offset_type>,
1855 dwarf_offset_pair_hash> die_comparison_results_;
1865 vector<type_base_sptr> types_to_canonicalize_;
1884 list<var_decl_sptr> var_decls_to_add_;
1885#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1886 bool debug_die_canonicalization_is_on_;
1887 bool use_canonical_die_comparison_;
1889 mutable size_t compare_count_;
1890 mutable size_t canonical_propagated_count_;
1891 mutable size_t cancelled_propagation_count_;
1892 mutable optional<bool> leverage_dwarf_factorization_;
1927 reader(
const string& elf_path,
1928 const vector<char**>& debug_info_root_paths,
1929 environment& environment,
1930 bool load_all_types,
1931 bool linux_kernel_mode)
1933 debug_info_root_paths,
1936 initialize(load_all_types, linux_kernel_mode);
1954 initialize(
bool load_all_types,
bool linux_kernel_mode)
1958 decl_die_repr_die_offsets_maps_.clear();
1959 type_die_repr_die_offsets_maps_.clear();
1960 die_qualified_name_maps_.clear();
1961 die_pretty_repr_maps_.clear();
1962 die_pretty_type_repr_maps_.clear();
1963 decl_die_artefact_maps_.clear();
1964 type_die_artefact_maps_.clear();
1965 canonical_type_die_offsets_.clear();
1966 canonical_decl_die_offsets_.clear();
1967 die_wip_classes_map_.clear();
1968 alternate_die_wip_classes_map_.clear();
1969 type_unit_die_wip_classes_map_.clear();
1970 die_wip_function_types_map_.clear();
1971 alternate_die_wip_function_types_map_.clear();
1972 type_unit_die_wip_function_types_map_.clear();
1973 die_function_with_no_symbol_map_.clear();
1974 types_to_canonicalize_.clear();
1975 decl_only_classes_map_.clear();
1976 die_tu_map_.clear();
1980 primary_die_parent_map_.clear();
1981 tu_die_imported_unit_points_map_.clear();
1982 alt_tu_die_imported_unit_points_map_.clear();
1983 type_units_tu_die_imported_unit_points_map_.clear();
1984 alternate_die_parent_map_.clear();
1985 type_section_die_parent_map_.clear();
1986 var_decls_to_add_.clear();
1987 clear_per_translation_unit_data();
1988 options().load_in_linux_kernel_mode = linux_kernel_mode;
1989 options().load_all_types = load_all_types;
1990#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
1991 debug_die_canonicalization_is_on_ =
1992 env().debug_die_canonicalization_is_on();
1993 use_canonical_die_comparison_ =
true;
1996 canonical_propagated_count_ = 0;
1997 cancelled_propagation_count_ = 0;
1998 load_in_linux_kernel_mode(linux_kernel_mode);
2020 const vector<char**>& debug_info_root_paths,
2021 bool load_all_types,
2022 bool linux_kernel_mode)
2025 initialize(load_all_types, linux_kernel_mode);
2045 static dwarf::reader_sptr
2046 create(
const std::string& elf_path,
2047 const vector<char**>& debug_info_root_paths,
2048 environment& environment,
2049 bool load_all_types,
2050 bool linux_kernel_mode)
2052 reader_sptr result(
new reader(elf_path, debug_info_root_paths,
2053 environment, load_all_types,
2054 linux_kernel_mode));
2071 read_corpus(status& status)
2078 if (!(status & STATUS_OK))
2082 return corpus_sptr();
2098 ((status & STATUS_ALT_DEBUG_INFO_NOT_FOUND)
2099 && !(status & STATUS_DEBUG_INFO_NOT_FOUND)))
2101 return corpus_sptr();
2105 corpus_sptr corp = read_debug_info_into_corpus();
2107 status |= STATUS_OK;
2120 read_debug_info_into_corpus()
2122 clear_per_corpus_data();
2127 origin |= corpus::DWARF_ORIGIN;
2128 corpus()->set_origin(origin);
2130 if (origin & corpus::LINUX_KERNEL_BINARY_ORIGIN
2131 && !env().user_set_analyze_exported_interfaces_only())
2138 env().analyze_exported_interfaces_only(
true);
2144 corpus()->set_symtab(symtab());
2149 || !
corpus()->get_symtab()
2150 || !
corpus()->get_symtab()->has_symbols())
2153 uint8_t address_size = 0;
2154 size_t header_size = 0;
2156#ifdef WITH_DEBUG_SELF_COMPARISON
2157 if (env().self_comparison_debug_is_on())
2158 env().set_self_comparison_debug_input(
corpus());
2161 env().priv_->do_log(do_log());
2166 tools_utils::timer t;
2169 cerr <<
"building die -> parent maps ...";
2173 build_die_parent_maps();
2178 cerr <<
" DONE@" <<
corpus()->get_path()
2185 env().canonicalization_is_done(
false);
2188 tools_utils::timer t;
2191 cerr <<
"building the libabigail internal representation ...\n";
2195 Dwarf_Half dwarf_vers = 0;
2196 for (Dwarf_Off offset = 0, next_offset = 0;
2198 offset, &next_offset, &header_size,
2199 &dwarf_vers, NULL, &address_size, NULL,
2201 offset = next_offset)
2203 Dwarf_Off die_offset = offset + header_size;
2207 || dwarf_tag(&unit) != DW_TAG_compile_unit)
2210 dwarf_version(dwarf_vers);
2217 build_translation_unit_and_add_to_ir(*
this, &unit, address_size);
2223 cerr <<
"building the libabigail internal representation "
2224 <<
"DONE for corpus << corpus()->get_path()"
2229 cerr <<
"Number of aggregate types compared: "
2230 << compare_count_ <<
"\n"
2231 <<
"Number of canonical types propagated: "
2232 << canonical_propagated_count_ <<
"\n"
2233 <<
"Number of cancelled propagated canonical types:"
2234 << cancelled_propagation_count_ <<
"\n";
2239 tools_utils::timer t;
2242 cerr <<
"resolving declaration only classes ...";
2245 resolve_declaration_only_classes();
2249 cerr <<
" DONE@" <<
corpus()->get_path()
2257 tools_utils::timer t;
2260 cerr <<
"resolving declaration only enums ...";
2263 resolve_declaration_only_enums();
2267 cerr <<
" DONE@" <<
corpus()->get_path()
2275 tools_utils::timer t;
2278 cerr <<
"fixing up functions with linkage name but "
2279 <<
"no advertised underlying symbols ....";
2282 fixup_functions_with_no_symbols();
2286 cerr <<
" DONE@" <<
corpus()->get_path()
2305 tools_utils::timer t;
2308 cerr <<
"perform late type canonicalizing ...\n";
2312 perform_late_type_canonicalizing();
2316 cerr <<
"late type canonicalizing DONE for "
2324 env().canonicalization_is_done(
true);
2327 tools_utils::timer t;
2330 cerr <<
"sort functions and variables ...";
2333 corpus()->sort_functions();
2334 corpus()->sort_variables();
2338 cerr <<
" DONE@" <<
corpus()->get_path()
2352 clear_per_translation_unit_data()
2354 while (!scope_stack().empty())
2355 scope_stack().pop();
2356 var_decls_to_re_add_to_tree().clear();
2357 per_tu_repr_to_fn_type_maps().clear();
2363 clear_per_corpus_data()
2365 die_qualified_name_maps_.clear();
2366 die_pretty_repr_maps_.clear();
2367 die_pretty_type_repr_maps_.clear();
2368 clear_types_to_canonicalize();
2383 {
return const_cast<reader*
>(
this)->env();}
2391 drop_undefined_syms()
const
2392 {
return options().drop_undefined_syms;}
2399 drop_undefined_syms(
bool f)
2400 {
options().drop_undefined_syms = f;}
2404 dwarf_version()
const
2405 {
return dwarf_version_;}
2408 dwarf_version(
unsigned short v)
2409 {dwarf_version_ = v;}
2421 dwarf_elf_handle()
const
2432 dwarf_is_splitted()
const
2433 {
return dwarf_elf_handle() != elf_handle();}
2442 dwarf_per_die_source(
die_source source)
const
2444 const Dwarf *result = 0;
2447 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
2448 case TYPE_UNIT_DIE_SOURCE:
2451 case ALT_DEBUG_INFO_DIE_SOURCE:
2454 case NO_DEBUG_INFO_DIE_SOURCE:
2455 case NUMBER_OF_DIE_SOURCES:
2470 {
return cur_tu_die_;}
2473 cur_tu_die(Dwarf_Die* cur_tu_die)
2474 {cur_tu_die_ = cur_tu_die;}
2476 dwarf_expr_eval_context&
2477 dwarf_expr_eval_ctxt()
const
2478 {
return dwarf_expr_eval_context_;}
2485 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2486 decl_die_repr_die_offsets_maps()
const
2487 {
return decl_die_repr_die_offsets_maps_;}
2494 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2495 decl_die_repr_die_offsets_maps()
2496 {
return decl_die_repr_die_offsets_maps_;}
2503 const die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2504 type_die_repr_die_offsets_maps()
const
2505 {
return type_die_repr_die_offsets_maps_;}
2512 die_source_dependant_container_set<istring_dwarf_offsets_map_type>&
2513 type_die_repr_die_offsets_maps()
2514 {
return type_die_repr_die_offsets_maps_;}
2527 compute_canonical_die_offset(
const Dwarf_Die *die,
2528 Dwarf_Off &canonical_die_offset,
2529 bool die_as_type)
const
2533 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2534 get_container(*
this, die)
2535 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2536 get_container(*
this, die);
2538 Dwarf_Die canonical_die;
2539 compute_canonical_die(die, canonical_dies, canonical_die, die_as_type);
2541 canonical_die_offset = dwarf_dieoffset(&canonical_die);
2559 compute_canonical_die(
const Dwarf_Die *die,
2561 Dwarf_Die &canonical_die,
2562 bool die_as_type)
const
2564 const die_source source = get_die_source(die);
2566 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2568 compute_canonical_die(die_offset, source,
2570 canonical_die, die_as_type);
2590 compute_canonical_die(Dwarf_Off die_offset,
2593 Dwarf_Die &canonical_die,
2594 bool die_as_type)
const
2600 ? (
const_cast<reader*
>(
this)->
2601 type_die_repr_die_offsets_maps().get_container(source))
2602 : (
const_cast<reader*
>(
this)->
2603 decl_die_repr_die_offsets_maps().get_container(source));
2606 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2615 interned_string name =
2617 ? get_die_pretty_type_representation(&die, 0)
2618 : get_die_pretty_representation(&die, 0);
2620 Dwarf_Off canonical_die_offset = 0;
2621 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2625 offsets.push_back(die_offset);
2626 map[name] = offsets;
2627 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2628 get_die_from_offset(source, die_offset, &canonical_die);
2632 Dwarf_Off cur_die_offset;
2633 Dwarf_Die potential_canonical_die;
2634 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2635 o != i->second.end();
2638 cur_die_offset = *o;
2639 get_die_from_offset(source, cur_die_offset, &potential_canonical_die);
2640 if (compare_dies(*
this, &die, &potential_canonical_die,
2643 canonical_die_offset = cur_die_offset;
2644 set_canonical_die_offset(canonical_dies, die_offset,
2645 canonical_die_offset);
2646 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2651 canonical_die_offset = die_offset;
2652 i->second.push_back(die_offset);
2653 set_canonical_die_offset(canonical_dies, die_offset, die_offset);
2654 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2673 get_canonical_die(
const Dwarf_Die *die,
2674 Dwarf_Die &canonical_die,
2678 const die_source source = get_die_source(die);
2682 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2683 get_container(source)
2684 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2685 get_container(source);
2687 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2688 if (Dwarf_Off canonical_die_offset =
2689 get_canonical_die_offset(canonical_dies, die_offset))
2691 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2699 ? (
const_cast<reader*
>(
this)->
2700 type_die_repr_die_offsets_maps().get_container(*
this, die))
2701 : (
const_cast<reader*
>(
this)->
2702 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2710 interned_string name =
2712 ? get_die_pretty_type_representation(die, where)
2713 : get_die_pretty_representation(die, where);
2715 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2719 Dwarf_Off cur_die_offset;
2720 for (dwarf_offsets_type::const_iterator o = i->second.begin();
2721 o != i->second.end();
2724 cur_die_offset = *o;
2725 get_die_from_offset(source, cur_die_offset, &canonical_die);
2727 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2728 die, &canonical_die,
2731 set_canonical_die_offset(canonical_dies,
2765 get_or_compute_canonical_die(
const Dwarf_Die* die,
2766 Dwarf_Die& canonical_die,
2768 bool die_as_type)
const
2770 const die_source source = get_die_source(die);
2774 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
2775 get_container(source)
2776 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
2777 get_container(source);
2779 Dwarf_Off initial_die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
2781 if (Dwarf_Off canonical_die_offset =
2782 get_canonical_die_offset(canonical_dies,
2783 initial_die_offset))
2785 get_die_from_offset(source, canonical_die_offset, &canonical_die);
2789 if (!is_type_die_to_be_canonicalized(die))
2796 ? (
const_cast<reader*
>(
this)->
2797 type_die_repr_die_offsets_maps().get_container(*
this, die))
2798 : (
const_cast<reader*
>(
this)->
2799 decl_die_repr_die_offsets_maps().get_container(*
this, die));
2807 interned_string name =
2809 ? get_die_pretty_type_representation(die, where)
2810 : get_die_pretty_representation(die, where);
2812 istring_dwarf_offsets_map_type::iterator i = map.find(name);
2816 offsets.push_back(initial_die_offset);
2817 map[name] = offsets;
2818 get_die_from_offset(source, initial_die_offset, &canonical_die);
2819 set_canonical_die_offset(canonical_dies,
2821 initial_die_offset);
2828 dwarf_offsets_type::size_type n = 0, s = i->second.size();
2831 Dwarf_Off die_offset = i->second[n];
2832 get_die_from_offset(source, die_offset, &canonical_die);
2834 if (compare_dies_during_canonicalization(
const_cast<reader&
>(*
this),
2835 die, &canonical_die,
2838 set_canonical_die_offset(canonical_dies,
2848 get_die_from_offset(source, initial_die_offset, &canonical_die);
2849 i->second.push_back(initial_die_offset);
2850 set_canonical_die_offset(canonical_dies,
2852 initial_die_offset);
2869 get_die_source(
const Dwarf_Die *die)
const
2871 die_source source = NO_DEBUG_INFO_DIE_SOURCE;
2892 get_die_source(
const Dwarf_Die &die,
die_source &source)
const
2896 uint8_t address_size = 0, offset_size = 0;
2897 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(&die),
2898 &cu_die, &address_size,
2902 Dwarf_Half version = 0;
2903 Dwarf_Off abbrev_offset = 0;
2904 uint64_t type_signature = 0;
2905 Dwarf_Off type_offset = 0;
2906 if (!dwarf_cu_die(cu_die.cu, &cu_kind,
2907 &version, &abbrev_offset,
2908 &address_size, &offset_size,
2909 &type_signature, &type_offset))
2912 int tag = dwarf_tag(&cu_kind);
2914 if (tag == DW_TAG_compile_unit
2915 || tag == DW_TAG_partial_unit)
2917 const Dwarf *die_dwarf = dwarf_cu_getdwarf(cu_die.cu);
2919 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
2921 source = ALT_DEBUG_INFO_DIE_SOURCE;
2925 else if (tag == DW_TAG_type_unit)
2926 source = TYPE_UNIT_DIE_SOURCE;
2942 get_die_from_offset(
die_source source, Dwarf_Off offset, Dwarf_Die *die)
const
2944 if (source == TYPE_UNIT_DIE_SOURCE)
2945 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2948 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
2975 associate_die_to_decl(Dwarf_Die* die,
2976 decl_base_sptr decl,
2977 size_t where_offset,
2978 bool do_associate_by_repr =
false)
2980 const die_source source = get_die_source(die);
2983 decl_die_artefact_maps().get_container(source);
2986 if (do_associate_by_repr)
2988 Dwarf_Die equiv_die;
2989 if (!get_or_compute_canonical_die(die, equiv_die, where_offset,
2992 die_offset = dwarf_dieoffset(&equiv_die);
2995 die_offset = dwarf_dieoffset(die);
2997 m[die_offset] = decl;
3019 lookup_decl_from_die_offset(Dwarf_Off die_offset,
die_source source)
3021 decl_base_sptr result =
3022 is_decl(lookup_artifact_from_die_offset(die_offset, source,
3041 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
3045 die_qualified_name_maps_.get_container(*
this, die);
3047 size_t die_offset = dwarf_dieoffset(die);
3048 die_istring_map_type::const_iterator i = map.find(die_offset);
3052 reader& rdr = *
const_cast<reader*
>(
this);
3053 string qualified_name = die_qualified_name(rdr, die, where_offset);
3054 interned_string istr = env().intern(qualified_name);
3055 map[die_offset] = istr;
3075 get_die_qualified_name(Dwarf_Die *die,
size_t where_offset)
const
3077 return const_cast<reader*
>(
this)->
3078 get_die_qualified_name(die, where_offset);
3099 get_die_qualified_type_name(
const Dwarf_Die *die,
size_t where_offset)
const
3104 if (die == cur_tu_die())
3105 return env().intern(
"");
3108 die_qualified_name_maps_.get_container(*
const_cast<reader*
>(
this),
3111 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3112 die_istring_map_type::const_iterator i =
3113 map.find(die_offset);
3117 reader& rdr = *
const_cast<reader*
>(
this);
3118 string qualified_name;
3119 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
3120 if ((tag == DW_TAG_structure_type
3121 || tag == DW_TAG_class_type
3122 || tag == DW_TAG_union_type)
3123 && die_is_anonymous(die))
3125 location l = die_location(*
this, die);
3126 qualified_name = l ? l.expand() :
"noloc";
3127 qualified_name =
"unnamed-at-" + qualified_name;
3131 die_qualified_type_name(rdr, die, where_offset);
3133 interned_string istr = env().intern(qualified_name);
3134 map[die_offset] = istr;
3158 get_die_pretty_type_representation(
const Dwarf_Die *die,
3159 size_t where_offset)
const
3163 die_pretty_type_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3166 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3167 die_istring_map_type::const_iterator i = map.find(die_offset);
3171 reader& rdr = *
const_cast<reader*
>(
this);
3172 string pretty_representation =
3173 die_pretty_print_type(rdr, die, where_offset);
3174 interned_string istr = env().intern(pretty_representation);
3175 map[die_offset] = istr;
3195 get_die_pretty_representation(
const Dwarf_Die *die,
size_t where_offset)
const
3200 die_pretty_repr_maps_.get_container(*
const_cast<reader*
>(
this),
3203 size_t die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3204 die_istring_map_type::const_iterator i = map.find(die_offset);
3208 reader& rdr = *
const_cast<reader*
>(
this);
3209 string pretty_representation =
3210 die_pretty_print(rdr, die, where_offset);
3211 interned_string istr = env().intern(pretty_representation);
3212 map[die_offset] = istr;
3236 lookup_type_artifact_from_die(Dwarf_Die *die)
const
3239 lookup_artifact_from_die(die,
true);
3241 return fn->get_type();
3265 lookup_artifact_from_die(
const Dwarf_Die *die,
bool die_as_type =
false)
const
3267 Dwarf_Die equiv_die;
3268 if (!get_or_compute_canonical_die(die, equiv_die, 0, die_as_type))
3273 ? type_die_artefact_maps().get_container(*
this, &equiv_die)
3274 : decl_die_artefact_maps().get_container(*
this, &equiv_die);
3276 size_t die_offset = dwarf_dieoffset(&equiv_die);
3277 die_artefact_map_type::const_iterator i = m.find(die_offset);
3304 lookup_artifact_from_die_offset(Dwarf_Off die_offset,
3306 bool die_as_type =
false)
const
3310 ? type_die_artefact_maps().get_container(source)
3311 : decl_die_artefact_maps().get_container(source);
3313 die_artefact_map_type::const_iterator i = m.find(die_offset);
3330 ABG_ASSERT(dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &cu_die, 0, 0));
3333 if (!die_unsigned_constant_attribute(&cu_die, DW_AT_language, l))
3336 lang = dwarf_language_to_tu_language(l);
3348 die_is_in_c(
const Dwarf_Die *die)
const
3351 if (!get_die_language(die, l))
3364 die_is_in_cplus_plus(
const Dwarf_Die *die)
const
3367 if (!get_die_language(die, l))
3380 die_is_in_c_or_cplusplus(
const Dwarf_Die *die)
const
3383 if (!get_die_language(die, l))
3425 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(dwarf_per_die_source(source)),
3440 if (!get_die_language(die, lang))
3451 die_source_dependant_container_set<die_artefact_map_type>&
3452 decl_die_artefact_maps()
3453 {
return decl_die_artefact_maps_;}
3460 const die_source_dependant_container_set<die_artefact_map_type>&
3461 decl_die_artefact_maps()
const
3462 {
return decl_die_artefact_maps_;}
3469 die_source_dependant_container_set<die_artefact_map_type>&
3470 type_die_artefact_maps()
3471 {
return type_die_artefact_maps_;}
3478 const die_source_dependant_container_set<die_artefact_map_type>&
3479 type_die_artefact_maps()
const
3480 {
return type_die_artefact_maps_;}
3488 per_tu_repr_to_fn_type_maps()
3489 {
return per_tu_repr_to_fn_type_maps_;}
3497 per_tu_repr_to_fn_type_maps()
const
3498 {
return per_tu_repr_to_fn_type_maps_;}
3508 associate_die_repr_to_fn_type_per_tu(
const Dwarf_Die *die,
3511 if (!die_is_function_type(die))
3514 interned_string repr =
3515 get_die_pretty_type_representation(die, 0);
3518 per_tu_repr_to_fn_type_maps()[repr]= fn_type;
3529 lookup_fn_type_from_die_repr_per_tu(
const Dwarf_Die *die)
3531 if (!die_is_function_type(die))
3534 interned_string repr = die_name(die).empty() ?
3535 get_die_pretty_type_representation(die, 0)
3536 : get_die_pretty_representation(die, 0);
3539 istring_fn_type_map_type::const_iterator i =
3540 per_tu_repr_to_fn_type_maps().find(repr);
3542 if (i == per_tu_repr_to_fn_type_maps().end())
3559 Dwarf_Off die_offset,
3560 Dwarf_Off canonical_die_offset)
const
3562 canonical_dies[die_offset] = canonical_die_offset;}
3578 set_canonical_die_offset(Dwarf_Off die_offset,
3580 Dwarf_Off canonical_die_offset,
3581 bool die_as_type)
const
3585 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3586 get_container(source)
3587 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3588 get_container(source);
3590 set_canonical_die_offset(canonical_dies,
3592 canonical_die_offset);
3606 set_canonical_die_offset(
const Dwarf_Die *die,
3607 Dwarf_Off canonical_die_offset,
3608 bool die_as_type)
const
3610 const die_source source = get_die_source(die);
3612 Dwarf_Off die_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die));
3614 set_canonical_die_offset(die_offset, source,
3615 canonical_die_offset,
3629 Dwarf_Off die_offset)
const
3631 offset_offset_map_type::const_iterator it = canonical_dies.find(die_offset);
3632 if (it == canonical_dies.end())
3649 get_canonical_die_offset(Dwarf_Off die_offset,
3651 bool die_as_type)
const
3655 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3656 get_container(source)
3657 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3658 get_container(source);
3660 return get_canonical_die_offset(canonical_dies, die_offset);
3675 erase_canonical_die_offset(Dwarf_Off die_offset,
3677 bool die_as_type)
const
3681 ?
const_cast<reader*
>(
this)->canonical_type_die_offsets_.
3682 get_container(source)
3683 :
const_cast<reader*
>(
this)->canonical_decl_die_offsets_.
3684 get_container(source);
3686 return canonical_dies.erase(die_offset);
3699 associate_die_to_type(
const Dwarf_Die *die,
3700 type_base_sptr type,
3706 Dwarf_Die equiv_die;
3707 if (!get_or_compute_canonical_die(die, equiv_die, where,
3712 type_die_artefact_maps().get_container(*
this, &equiv_die);
3714 size_t die_offset = dwarf_dieoffset(&equiv_die);
3715 m[die_offset] = type;
3729 lookup_type_from_die(
const Dwarf_Die* die)
const
3732 lookup_artifact_from_die(die,
true);
3734 return fn->get_type();
3752 lookup_type_from_die_offset(
size_t die_offset,
die_source source)
const
3754 type_base_sptr result;
3756 type_die_artefact_maps().get_container(source);
3757 die_artefact_map_type::const_iterator i = m.find(die_offset);
3761 return fn->get_type();
3769 die_class_or_union_map_type::const_iterator i = m.find(die_offset);
3779 die_wip_function_types_map(source);
3780 die_function_type_map_type::const_iterator i = m.find(die_offset);
3799 {
return const_cast<reader*
>(
this)->die_wip_classes_map(source);}
3814 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3816 case ALT_DEBUG_INFO_DIE_SOURCE:
3817 return alternate_die_wip_classes_map_;
3818 case TYPE_UNIT_DIE_SOURCE:
3819 return type_unit_die_wip_classes_map_;
3820 case NO_DEBUG_INFO_DIE_SOURCE:
3821 case NUMBER_OF_DIE_SOURCES:
3824 return die_wip_classes_map_;
3835 die_wip_function_types_map(
die_source source)
const
3836 {
return const_cast<reader*
>(
this)->die_wip_function_types_map(source);}
3846 die_wip_function_types_map(
die_source source)
3850 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
3852 case ALT_DEBUG_INFO_DIE_SOURCE:
3853 return alternate_die_wip_function_types_map_;
3854 case TYPE_UNIT_DIE_SOURCE:
3855 return type_unit_die_wip_function_types_map_;
3856 case NO_DEBUG_INFO_DIE_SOURCE:
3857 case NUMBER_OF_DIE_SOURCES:
3860 return die_wip_function_types_map_;
3871 die_function_decl_with_no_symbol_map()
3872 {
return die_function_with_no_symbol_map_;}
3885 is_wip_class_die_offset(Dwarf_Off offset,
die_source source)
const
3887 die_class_or_union_map_type::const_iterator i =
3888 die_wip_classes_map(source).find(offset);
3889 return (i != die_wip_classes_map(source).end());
3903 is_wip_function_type_die_offset(Dwarf_Off offset,
die_source source)
const
3905 die_function_type_map_type::const_iterator i =
3906 die_wip_function_types_map(source).find(offset);
3907 return (i != die_wip_function_types_map(source).end());
3926 build_name_for_buggy_anonymous_data_member(Dwarf_Die *die)
3932 || dwarf_tag(die) != DW_TAG_member
3933 || !die_name(die).empty())
3939 if (die_is_anonymous_data_member(die))
3945 int64_t offset_in_bits = 0;
3946 bool has_offset = die_member_offset(*
this, die, offset_in_bits);
3950 loc = die_location(*
this, die);
3955 std::ostringstream o;
3956 o <<
"unnamed-dm-@-";
3958 o <<
"offset-" << offset_in_bits <<
"bits";
3960 o <<
"loc-" << loc.expand();
3973 declaration_only_classes()
const
3974 {
return decl_only_classes_map_;}
3984 declaration_only_classes()
3985 {
return decl_only_classes_map_;}
3993 maybe_schedule_declaration_only_class_for_resolution(
const class_or_union_sptr& cou)
3995 if (cou->get_is_declaration_only()
3996 && cou->get_definition_of_declaration() == 0
4001 && !cou->get_qualified_name().empty())
4003 string qn = cou->get_qualified_name();
4004 string_classes_or_unions_map::iterator record =
4005 declaration_only_classes().find(qn);
4006 if (record == declaration_only_classes().end())
4007 declaration_only_classes()[qn].push_back(cou);
4009 record->second.push_back(cou);
4021 is_decl_only_class_scheduled_for_resolution(
const class_or_union_sptr& cou)
4023 if (cou->get_is_declaration_only())
4024 return ((declaration_only_classes().find(cou->get_qualified_name())
4025 != declaration_only_classes().end())
4026 || (declaration_only_classes().find(cou->get_name())
4027 != declaration_only_classes().end()));
4047 const environment& e = l->get_environment();
4050 e.priv_->allow_type_comparison_results_caching(
true);
4051 bool s0 = e.decl_only_class_equals_definition();
4052 e.decl_only_class_equals_definition(
true);
4053 bool equal = l == r;
4054 e.decl_only_class_equals_definition(s0);
4055 e.priv_->clear_type_comparison_results_cache();
4056 e.priv_->allow_type_comparison_results_caching(
false);
4063 resolve_declaration_only_classes()
4065 vector<string> resolved_classes;
4067 for (string_classes_or_unions_map::iterator i =
4068 declaration_only_classes().begin();
4069 i != declaration_only_classes().end();
4072 bool to_resolve =
false;
4073 for (classes_or_unions_type::iterator j = i->second.begin();
4074 j != i->second.end();
4076 if ((*j)->get_is_declaration_only()
4077 && ((*j)->get_definition_of_declaration() == 0))
4082 resolved_classes.push_back(i->first);
4127 map<string, class_or_union_sptr> per_tu_class_map;
4128 for (type_base_wptrs_type::const_iterator c = classes->begin();
4129 c != classes->end();
4136 if (klass->get_is_declaration_only())
4139 string tu_path = klass->get_translation_unit()->get_absolute_path();
4140 if (tu_path.empty())
4146 per_tu_class_map[tu_path] = klass;
4149 if (!per_tu_class_map.empty())
4155 for (classes_or_unions_type::iterator j = i->second.begin();
4156 j != i->second.end();
4159 if ((*j)->get_is_declaration_only()
4160 && ((*j)->get_definition_of_declaration() == 0))
4163 (*j)->get_translation_unit()->get_absolute_path();
4164 map<string, class_or_union_sptr>::const_iterator e =
4165 per_tu_class_map.find(tu_path);
4166 if (e != per_tu_class_map.end())
4167 (*j)->set_definition_of_declaration(e->second);
4168 else if (per_tu_class_map.size() == 1)
4169 (*j)->set_definition_of_declaration
4170 (per_tu_class_map.begin()->second);
4180 class_or_union_sptr>::const_iterator it;
4181 class_or_union_sptr first_class =
4182 per_tu_class_map.begin()->second;
4183 bool all_class_definitions_are_equal =
true;
4184 for (it = per_tu_class_map.begin();
4185 it != per_tu_class_map.end();
4188 if (it == per_tu_class_map.begin())
4192 if (!compare_before_canonicalisation(it->second,
4195 all_class_definitions_are_equal =
false;
4200 if (all_class_definitions_are_equal)
4201 (*j)->set_definition_of_declaration(first_class);
4205 resolved_classes.push_back(i->first);
4209 size_t num_decl_only_classes = declaration_only_classes().size(),
4210 num_resolved = resolved_classes.size();
4212 cerr <<
"resolved " << num_resolved
4213 <<
" class declarations out of "
4214 << num_decl_only_classes
4217 for (vector<string>::const_iterator i = resolved_classes.begin();
4218 i != resolved_classes.end();
4220 declaration_only_classes().erase(*i);
4222 if (show_stats() && !declaration_only_classes().empty())
4224 cerr <<
"Here are the "
4225 << num_decl_only_classes - num_resolved
4226 <<
" unresolved class declarations:\n";
4227 for (string_classes_or_unions_map::iterator i =
4228 declaration_only_classes().begin();
4229 i != declaration_only_classes().end();
4231 cerr <<
" " << i->first <<
"\n";
4243 declaration_only_enums()
const
4244 {
return decl_only_enums_map_;}
4254 declaration_only_enums()
4255 {
return decl_only_enums_map_;}
4265 if (enom->get_is_declaration_only()
4266 && enom->get_definition_of_declaration() == 0
4271 && !enom->get_qualified_name().empty())
4273 string qn = enom->get_qualified_name();
4274 string_enums_map::iterator record =
4275 declaration_only_enums().find(qn);
4276 if (record == declaration_only_enums().end())
4277 declaration_only_enums()[qn].push_back(enom);
4279 record->second.push_back(enom);
4293 if (enom->get_is_declaration_only())
4294 return (declaration_only_enums().find(enom->get_qualified_name())
4295 != declaration_only_enums().end());
4308 resolve_declaration_only_enums()
4310 vector<string> resolved_enums;
4312 for (string_enums_map::iterator i =
4313 declaration_only_enums().begin();
4314 i != declaration_only_enums().end();
4317 bool to_resolve =
false;
4318 for (enums_type::iterator j = i->second.begin();
4319 j != i->second.end();
4321 if ((*j)->get_is_declaration_only()
4322 && ((*j)->get_definition_of_declaration() == 0))
4327 resolved_enums.push_back(i->first);
4369 map<string, enum_type_decl_sptr> per_tu_enum_map;
4370 for (type_base_wptrs_type::const_iterator c = enums->begin();
4378 if (enom->get_is_declaration_only())
4381 string tu_path = enom->get_translation_unit()->get_absolute_path();
4382 if (tu_path.empty())
4388 per_tu_enum_map[tu_path] = enom;
4391 if (!per_tu_enum_map.empty())
4397 for (enums_type::iterator j = i->second.begin();
4398 j != i->second.end();
4401 if ((*j)->get_is_declaration_only()
4402 && ((*j)->get_definition_of_declaration() == 0))
4405 (*j)->get_translation_unit()->get_absolute_path();
4406 map<string, enum_type_decl_sptr>::const_iterator e =
4407 per_tu_enum_map.find(tu_path);
4408 if (e != per_tu_enum_map.end())
4409 (*j)->set_definition_of_declaration(e->second);
4410 else if (per_tu_enum_map.size() == 1)
4411 (*j)->set_definition_of_declaration
4412 (per_tu_enum_map.begin()->second);
4424 per_tu_enum_map.begin()->second;
4425 bool all_enum_definitions_are_equal =
true;
4426 for (it = per_tu_enum_map.begin();
4427 it != per_tu_enum_map.end();
4430 if (it == per_tu_enum_map.begin())
4434 if (!compare_before_canonicalisation(it->second,
4437 all_enum_definitions_are_equal =
false;
4442 if (all_enum_definitions_are_equal)
4443 (*j)->set_definition_of_declaration(first_enum);
4447 resolved_enums.push_back(i->first);
4451 size_t num_decl_only_enums = declaration_only_enums().size(),
4452 num_resolved = resolved_enums.size();
4454 cerr <<
"resolved " << num_resolved
4455 <<
" enum declarations out of "
4456 << num_decl_only_enums
4459 for (vector<string>::const_iterator i = resolved_enums.begin();
4460 i != resolved_enums.end();
4462 declaration_only_enums().erase(*i);
4464 if (show_stats() && !declaration_only_enums().empty())
4466 cerr <<
"Here are the "
4467 << num_decl_only_enums - num_resolved
4468 <<
" unresolved enum declarations:\n";
4469 for (string_enums_map::iterator i = declaration_only_enums().begin();
4470 i != declaration_only_enums().end();
4472 cerr <<
" " << i->first <<
"\n";
4488 corpus_sptr corp =
corpus();
4492 interned_string
id = corp->get_environment().intern(fn->get_id_string());
4494 const std::unordered_set<function_decl*> *fns = corp->lookup_functions(
id);
4499 if (f->get_symbol())
4519 fixup_functions_with_no_symbols()
4521 corpus_sptr corp =
corpus();
4526 die_function_decl_with_no_symbol_map();
4529 cerr << fns_with_no_symbol.size()
4530 <<
" functions to fixup, potentially\n";
4532 for (die_function_decl_map_type::iterator i = fns_with_no_symbol.begin();
4533 i != fns_with_no_symbol.end();
4536 corp->lookup_function_symbol(i->second->get_linkage_name()))
4551 if (i->second->get_symbol()
4552 || symbol_already_belongs_to_a_function(sym))
4557 i->second->set_symbol(sym);
4560 cerr <<
"fixed up '"
4561 << i->second->get_pretty_representation()
4562 <<
"' with symbol '"
4563 << sym->get_id_string()
4567 fns_with_no_symbol.clear();
4577 const vector<type_base_sptr>&
4578 types_to_canonicalize()
const
4579 {
return types_to_canonicalize_;}
4583 clear_types_to_canonicalize()
4585 types_to_canonicalize_.clear();
4593 schedule_type_for_late_canonicalization(
const type_base_sptr &t)
4595 types_to_canonicalize_.push_back(t);
4605 canonicalize_types_scheduled()
4607 tools_utils::timer cn_timer;
4610 cerr <<
"DWARF Reader is going to canonicalize types";
4611 corpus_sptr c =
corpus();
4613 cerr <<
" of corpus " <<
corpus()->get_path() <<
"\n";
4617 if (!types_to_canonicalize().empty())
4619 types_to_canonicalize().end(),
4620 [](
const vector<type_base_sptr>::const_iterator& i)
4626 cerr <<
"finished canonicalizing types";
4627 corpus_sptr c =
corpus();
4629 cerr <<
" of corpus " <<
corpus()->get_path();
4630 cerr <<
": (" << cn_timer <<
")\n";
4647 add_late_canonicalized_types_stats(
size_t& canonicalized,
4648 size_t& missed)
const
4650 for (
auto t : types_to_canonicalize())
4652 if (t->get_canonical_type())
4662 perform_late_type_canonicalizing()
4664 canonicalize_types_scheduled();
4668 size_t num_canonicalized = 0, num_missed = 0, total = 0;
4669 add_late_canonicalized_types_stats(num_canonicalized,
4671 total = num_canonicalized + num_missed;
4675 cerr <<
" # late canonicalized types: "
4676 << num_canonicalized;
4678 cerr <<
" (" << num_canonicalized * 100 / total <<
"%)";
4680 <<
" # missed canonicalization opportunities: "
4683 cerr <<
" (" << num_missed * 100 / total <<
"%)";
4691 {
return die_tu_map_;}
4695 {
return die_tu_map_;}
4704 tu_die_imported_unit_points_map(
die_source source)
const
4705 {
return const_cast<reader*
>(
this)->tu_die_imported_unit_points_map(source);}
4714 tu_die_imported_unit_points_map(
die_source source)
4718 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4720 case ALT_DEBUG_INFO_DIE_SOURCE:
4721 return alt_tu_die_imported_unit_points_map_;
4722 case TYPE_UNIT_DIE_SOURCE:
4723 return type_units_tu_die_imported_unit_points_map_;
4724 case NO_DEBUG_INFO_DIE_SOURCE:
4725 case NUMBER_OF_DIE_SOURCES:
4729 return tu_die_imported_unit_points_map_;
4747 {
return const_cast<reader*
>(
this)->die_parent_map(source);}
4760 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
4762 case ALT_DEBUG_INFO_DIE_SOURCE:
4763 return alternate_die_parent_map_;
4764 case TYPE_UNIT_DIE_SOURCE:
4765 return type_section_die_parent_map();
4766 case NO_DEBUG_INFO_DIE_SOURCE:
4767 case NUMBER_OF_DIE_SOURCES:
4770 return primary_die_parent_map_;
4774 type_section_die_parent_map()
const
4775 {
return type_section_die_parent_map_;}
4778 type_section_die_parent_map()
4779 {
return type_section_die_parent_map_;}
4785 cur_transl_unit()
const
4809 global_scope()
const
4810 {
return cur_transl_unit()->get_global_scope();}
4817 {
return nil_scope_;}
4821 {
return scope_stack_;}
4825 {
return scope_stack_;}
4830 if (scope_stack().empty())
4832 if (cur_transl_unit())
4835 return scope_stack().top();
4838 list<var_decl_sptr>&
4839 var_decls_to_re_add_to_tree()
4840 {
return var_decls_to_add_;}
4853 is_decl_die_with_exported_symbol(
const Dwarf_Die *die)
4855 if (!die || !die_is_decl(die))
4858 bool result =
false, address_found =
false, symbol_is_exported =
false;;
4859 Dwarf_Addr decl_symbol_address = 0;
4861 if (die_is_variable_decl(die))
4863 if ((address_found = get_variable_address(die, decl_symbol_address)))
4864 symbol_is_exported =
4867 else if (die_is_function_decl(die))
4869 if ((address_found = get_function_address(die, decl_symbol_address)))
4870 symbol_is_exported =
4875 result = symbol_is_exported;
4894 maybe_adjust_address_for_exec_or_dyn(Dwarf_Addr addr)
const
4900 GElf_Ehdr *elf_header = gelf_getehdr(elf_handle(), &eh_mem);
4902 if (elf_header->e_type == ET_DYN || elf_header->e_type == ET_EXEC)
4904 Dwarf_Addr dwarf_elf_load_address = 0, elf_load_address = 0;
4906 dwarf_elf_load_address));
4909 if (dwarf_is_splitted()
4910 && (dwarf_elf_load_address != elf_load_address))
4921 addr = addr - dwarf_elf_load_address + elf_load_address;
4947 maybe_adjust_fn_sym_address(Dwarf_Addr addr)
const
4952 Elf* elf = elf_handle();
4954 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
4956 if (elf_header->e_type == ET_REL)
4969 addr = maybe_adjust_address_for_exec_or_dyn(addr);
4994 maybe_adjust_var_sym_address(Dwarf_Addr addr)
const
4996 Elf* elf = elf_handle();
4998 GElf_Ehdr* elf_header = gelf_getehdr(elf, &eh_mem);
5000 if (elf_header->e_type == ET_REL)
5013 addr = maybe_adjust_address_for_exec_or_dyn(addr);
5032 get_first_exported_fn_address_from_DW_AT_ranges(Dwarf_Die* die,
5033 Dwarf_Addr& address)
const
5036 Dwarf_Addr end_addr;
5037 ptrdiff_t offset = 0;
5041 Dwarf_Addr addr = 0, fn_addr = 0;
5042 if ((offset = dwarf_ranges(die, offset, &base, &addr, &end_addr)) >= 0)
5044 fn_addr = maybe_adjust_fn_sym_address(addr);
5051 }
while (offset > 0);
5069 get_function_address(
const Dwarf_Die* function_die, Dwarf_Addr& address)
const
5071 if (!die_address_attribute(
const_cast<Dwarf_Die*
>(function_die),
5072 DW_AT_low_pc, address))
5078 if (!get_first_exported_fn_address_from_DW_AT_ranges
5079 (
const_cast<Dwarf_Die*
>(function_die),
5083 address = maybe_adjust_fn_sym_address(address);
5102 get_variable_address(
const Dwarf_Die* variable_die,
5103 Dwarf_Addr& address)
const
5105 bool is_tls_address =
false;
5106 if (!die_location_address(
const_cast<Dwarf_Die*
>(variable_die),
5107 address, is_tls_address))
5109 if (!is_tls_address)
5110 address = maybe_adjust_var_sym_address(address);
5117 corpus::exported_decls_builder*
5118 exported_decls_builder()
5119 {
return corpus()->get_exported_decls_builder().get();}
5127 load_all_types()
const
5128 {
return options().load_all_types;}
5136 load_all_types(
bool f)
5137 {
options().load_all_types = f;}
5140 load_in_linux_kernel_mode()
const
5141 {
return options().load_in_linux_kernel_mode;}
5144 load_in_linux_kernel_mode(
bool f)
5145 {
options().load_in_linux_kernel_mode = f;}
5155 leverage_dwarf_factorization()
const
5157 if (!leverage_dwarf_factorization_.has_value())
5159 if (
options().leverage_dwarf_factorization
5160 && elf_helpers::find_section_by_name(elf_handle(),
5161 ".gnu_debugaltlink"))
5162 leverage_dwarf_factorization_ =
true;
5164 leverage_dwarf_factorization_ =
false;
5166 ABG_ASSERT(leverage_dwarf_factorization_.has_value());
5168 return *leverage_dwarf_factorization_;
5178 {
return options().show_stats;}
5227 build_die_parent_relations_under(Dwarf_Die* die,
5237 if (dwarf_child(die, &child) != 0)
5242 parent_of[dwarf_dieoffset(&child)] = dwarf_dieoffset(die);
5243 if (dwarf_tag(&child) == DW_TAG_imported_unit)
5245 Dwarf_Die imported_unit;
5246 if (die_die_attribute(&child, DW_AT_import, imported_unit)
5257 && die_has_children(&imported_unit))
5259 die_source imported_unit_die_source = NO_DEBUG_INFO_DIE_SOURCE;
5260 ABG_ASSERT(get_die_source(imported_unit, imported_unit_die_source));
5261 imported_units.push_back
5262 (imported_unit_point(dwarf_dieoffset(&child),
5264 imported_unit_die_source));
5267 build_die_parent_relations_under(&child, source, imported_units);
5269 while (dwarf_siblingof(&child, &child) == 0);
5301 case translation_unit::LANG_UNKNOWN:
5302#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
5303 case translation_unit::LANG_Mips_Assembler:
5330 build_die_parent_maps()
5332 bool we_do_have_to_build_die_parent_map =
false;
5333 uint8_t address_size = 0;
5334 size_t header_size = 0;
5339 for (Dwarf_Off offset = 0, next_offset = 0;
5341 offset, &next_offset, &header_size,
5342 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5343 offset = next_offset)
5345 Dwarf_Off die_offset = offset + header_size;
5352 die_unsigned_constant_attribute(&cu, DW_AT_language, l);
5354 if (do_we_build_die_parent_maps(lang))
5355 we_do_have_to_build_die_parent_map =
true;
5358 if (!we_do_have_to_build_die_parent_map)
5363 die_source source = ALT_DEBUG_INFO_DIE_SOURCE;
5364 for (Dwarf_Off offset = 0, next_offset = 0;
5366 offset, &next_offset, &header_size,
5367 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5368 offset = next_offset)
5370 Dwarf_Off die_offset = offset + header_size;
5378 tu_die_imported_unit_points_map(source)[die_offset] =
5380 build_die_parent_relations_under(&cu, source, imported_units);
5385 source = PRIMARY_DEBUG_INFO_DIE_SOURCE;
5388 for (Dwarf_Off offset = 0, next_offset = 0;
5390 offset, &next_offset, &header_size,
5391 NULL, NULL, &address_size, NULL, NULL, NULL) == 0);
5392 offset = next_offset)
5394 Dwarf_Off die_offset = offset + header_size;
5401 tu_die_imported_unit_points_map(source)[die_offset] =
5403 build_die_parent_relations_under(&cu, source, imported_units);
5408 source = TYPE_UNIT_DIE_SOURCE;
5411 uint64_t type_signature = 0;
5412 Dwarf_Off type_offset;
5413 for (Dwarf_Off offset = 0, next_offset = 0;
5415 offset, &next_offset, &header_size,
5416 NULL, NULL, &address_size, NULL,
5417 &type_signature, &type_offset) == 0);
5418 offset = next_offset)
5420 Dwarf_Off die_offset = offset + header_size;
5428 tu_die_imported_unit_points_map(source)[die_offset] =
5430 build_die_parent_relations_under(&cu, source, imported_units);
5445struct offset_pairs_stack_type
5462 offset_pairs_stack_type(
const reader& rdr)
5488 offset_pair_vector_type::iterator i;
5490 for (i = vect_.begin();i < vect_.end(); ++i)
5494 if (i != vect_.end())
5513 if (set_.find(p) == set_.end())
5540 bool result =
false;
5545 offset_pair_vector_type::const_iterator i;
5546 for (i = vect_.begin(); i != vect_.end(); ++i)
5550 if (i == vect_.end())
5555 for (++i; i != vect_.end(); ++i)
5557 pairs.push_back(*i);
5577 for (
auto type_pair : dependant_types)
5578 dependant_types_[type_pair].push_back(p);
5589 get_pairs_that_depend_on(p, dependant_types);
5592 auto it = redundant_types_.find(p);
5593 if (it == redundant_types_.end())
5595 auto entry = std::make_pair(p, dependant_types);
5596 redundant_types_.insert(entry);
5599 it->second.insert(it->second.end(),
5600 dependant_types.begin(),
5601 dependant_types.end());
5605 record_dependant_types(p, dependant_types);
5616 auto i = redundant_types_.find(p);
5617 if (i != redundant_types_.end())
5630 auto i = dependant_types_.find(p);
5631 if (i == dependant_types_.end())
5649 bool erase_cached_results =
false)
5653 auto redundant_type = redundant_types_.find(p);
5654 if (redundant_type != redundant_types_.end())
5656 for (
auto dependant_type : redundant_type->second)
5660 auto dependant_types_it = dependant_types_.find(dependant_type);
5661 ABG_ASSERT(dependant_types_it != dependant_types_.end());
5665 auto i = dependant_types_it->second.begin();
5666 for (; i!= dependant_types_it->second.end();++i)
5669 if (i != dependant_types_it->second.end())
5670 dependant_types_it->second.erase(i);
5675 if (dependant_types_it->second.empty())
5677 if (erase_cached_results)
5678 rdr_.die_comparison_results_.erase(dependant_type);
5679 dependant_types_.erase(dependant_types_it);
5683 if (erase_cached_results)
5684 rdr_.die_comparison_results_.erase(p);
5685 redundant_types_.erase(p);
5697 {erase_redundant_type_pair_entry(p,
true);}
5710 get_dependant_types(p, dependant_types,
true);
5711 for (
auto dependant_type : dependant_types)
5715 if (rdr_.propagated_types_.find(dependant_type)
5716 != rdr_.propagated_types_.end())
5718 rdr_.erase_canonical_die_offset(dependant_type.first.offset_,
5719 dependant_type.first.source_,
5721 rdr_.propagated_types_.erase(dependant_type);
5722 rdr_.cancelled_propagation_count_++;
5726 auto comp_result_it = rdr_.die_comparison_results_.find(dependant_type);
5727 if (comp_result_it != rdr_.die_comparison_results_.end())
5728 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5732 auto comp_result_it = rdr_.die_comparison_results_.find(p);
5733 if (comp_result_it != rdr_.die_comparison_results_.end())
5740 if (comp_result_it->second == COMPARISON_RESULT_UNKNOWN)
5741 comp_result_it->second= COMPARISON_RESULT_DIFFERENT;
5742 ABG_ASSERT(comp_result_it->second == COMPARISON_RESULT_DIFFERENT);
5745 if (rdr_.propagated_types_.find(p) != rdr_.propagated_types_.end())
5747 rdr_.erase_canonical_die_offset(p.first.offset_,
5750 rdr_.propagated_types_.erase(p);
5751 rdr_.cancelled_propagation_count_++;
5770 bool transitive_closure =
false)
5772 auto i = redundant_types_.find(p);
5773 if (i != redundant_types_.end())
5775 for (
auto dependant_type : i->second)
5776 if (result.find(dependant_type) == result.end())
5778 result.insert(dependant_type);
5779 if (transitive_closure)
5780 get_dependant_types(p, result,
true);
5789build_ir_node_from_die(reader& rdr,
5792 bool called_from_public_decl,
5793 size_t where_offset,
5794 bool is_declaration_only =
true,
5795 bool is_required_decl_spec =
false);
5798build_ir_node_from_die(reader& rdr,
5800 bool called_from_public_decl,
5801 size_t where_offset);
5803static decl_base_sptr
5804build_ir_node_for_void_type(reader& rdr);
5807build_ir_node_for_void_pointer_type(reader& rdr);
5810add_or_update_class_type(reader& rdr,
5815 bool called_from_public_decl,
5816 size_t where_offset,
5817 bool is_declaration_only);
5819static union_decl_sptr
5820add_or_update_union_type(reader& rdr,
5823 union_decl_sptr union_type,
5824 bool called_from_public_decl,
5825 size_t where_offset,
5826 bool is_declaration_only);
5828static decl_base_sptr
5829build_ir_node_for_void_type(reader& rdr);
5831static decl_base_sptr
5832build_ir_node_for_variadic_parameter_type(reader &rdr);
5835build_function_decl(reader& rdr,
5837 size_t where_offset,
5841function_is_suppressed(
const reader& rdr,
5842 const scope_decl* scope,
5843 Dwarf_Die *function_die,
5844 bool is_declaration_only);
5847build_or_get_fn_decl_if_not_suppressed(reader& rdr,
5850 size_t where_offset,
5851 bool is_declaration_only,
5855build_var_decl(reader& rdr,
5857 size_t where_offset,
5861build_or_get_var_decl_if_not_suppressed(reader& rdr,
5864 size_t where_offset,
5866 bool is_required_decl_spec =
false);
5868variable_is_suppressed(
const reader& rdr,
5869 const scope_decl* scope,
5870 Dwarf_Die *variable_die,
5871 bool is_required_decl_spec =
false);
5874finish_member_function_reading(Dwarf_Die* die,
5876 const class_or_union_sptr klass,
5885die_is_anonymous(
const Dwarf_Die* die)
5887 Dwarf_Attribute attr;
5888 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_name, &attr))
5902die_is_anonymous_data_member(
const Dwarf_Die* die)
5905 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member
5906 || !die_name(die).empty())
5910 if (!die_die_attribute(die, DW_AT_type, type_die))
5913 if (dwarf_tag(&type_die) != DW_TAG_structure_type
5914 && dwarf_tag(&type_die) != DW_TAG_union_type)
5931die_string_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5936 Dwarf_Attribute attr;
5937 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5940 const char* str = dwarf_formstring(&attr);
5941 return str ? str :
"";
5955die_char_str_attribute(
const Dwarf_Die* die,
unsigned attr_name)
5960 Dwarf_Attribute attr;
5961 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
5964 const char* str = dwarf_formstring(&attr);
5984die_unsigned_constant_attribute(
const Dwarf_Die* die,
5991 Dwarf_Attribute attr;
5992 Dwarf_Word result = 0;
5993 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
5994 || dwarf_formudata(&attr, &result))
6014die_signed_constant_attribute(
const Dwarf_Die *die,
6021 Dwarf_Attribute attr;
6022 Dwarf_Sword result = 0;
6023 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6024 || dwarf_formsdata(&attr, &result))
6050die_constant_attribute(
const Dwarf_Die *die,
6053 array_type_def::subrange_type::bound_value &value)
6058 if (!die_unsigned_constant_attribute(die, attr_name, l))
6060 value.set_unsigned(l);
6065 if (!die_signed_constant_attribute(die, attr_name, l))
6067 value.set_signed(l);
6082form_is_DW_FORM_strx(
unsigned form)
6086#if defined HAVE_DW_FORM_strx1 \
6087 && defined HAVE_DW_FORM_strx2 \
6088 && defined HAVE_DW_FORM_strx3 \
6089 && defined HAVE_DW_FORM_strx4
6090 if (form == DW_FORM_strx1
6091 || form == DW_FORM_strx2
6092 || form == DW_FORM_strx3
6093 ||form == DW_FORM_strx4)
6110form_is_DW_FORM_line_strp(
unsigned form)
6114#if defined HAVE_DW_FORM_line_strp
6115 if (form == DW_FORM_line_strp)
6142die_flag_attribute(
const Dwarf_Die* die,
6145 bool recursively =
true)
6147 Dwarf_Attribute attr;
6149 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6150 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6154 if (dwarf_formflag(&attr, &f))
6168die_linkage_name(
const Dwarf_Die* die)
6173 string linkage_name = die_string_attribute(die, DW_AT_linkage_name);
6174 if (linkage_name.empty())
6175 linkage_name = die_string_attribute(die, DW_AT_MIPS_linkage_name);
6176 return linkage_name;
6190die_decl_file_attribute(
const Dwarf_Die* die)
6195 const char* str = dwarf_decl_file(
const_cast<Dwarf_Die*
>(die));
6197 return str ? str :
"";
6218die_die_attribute(
const Dwarf_Die* die,
6223 Dwarf_Attribute attr;
6225 ? !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr)
6226 : !dwarf_attr(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
6229 return dwarf_formref_die(&attr, &result);
6254die_origin_die(
const Dwarf_Die* die, Dwarf_Die& origin_die)
6256 if (die_die_attribute(die, DW_AT_specification, origin_die,
true)
6257 || die_die_attribute(die, DW_AT_abstract_origin, origin_die,
true))
6259 while (die_die_attribute(&origin_die,
6260 DW_AT_specification,
6262 || die_die_attribute(&origin_die,
6263 DW_AT_abstract_origin,
6301subrange_die_indirectly_references_subrange_die(
const Dwarf_Die *die,
6303 Dwarf_Die& referenced_subrange)
6305 bool result =
false;
6307 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6310 Dwarf_Die referenced_die;
6311 if (die_die_attribute(die, attr_name, referenced_die))
6313 unsigned tag = dwarf_tag(&referenced_die);
6314 if ( tag == DW_TAG_member || tag == DW_TAG_variable)
6317 if (die_die_attribute(&referenced_die, DW_AT_type, type_die))
6319 tag = dwarf_tag(&type_die);
6320 if (tag == DW_TAG_subrange_type)
6322 memcpy(&referenced_subrange, &type_die,
sizeof(type_die));
6358subrange_die_indirect_bound_value(
const Dwarf_Die *die,
6360 array_type_def::subrange_type::bound_value& v,
6363 bool result =
false;
6365 if (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subrange_type)
6368 Dwarf_Die subrange_die;
6369 if (subrange_die_indirectly_references_subrange_die(die, attr_name,
6372 if (die_constant_attribute(&subrange_die, attr_name, is_signed, v))
6390die_address_attribute(Dwarf_Die* die,
unsigned attr_name, Dwarf_Addr& result)
6392 Dwarf_Attribute attr;
6393 if (!dwarf_attr_integrate(die, attr_name, &attr))
6395 return dwarf_formaddr(&attr, &result) == 0;
6406die_location(
const reader& rdr,
const Dwarf_Die* die)
6411 string file = die_decl_file_attribute(die);
6413 die_unsigned_constant_attribute(die, DW_AT_decl_line, line);
6415 if (!file.empty() && line != 0)
6418 location l = tu->get_loc_mgr().create_new_location(file, line, 1);
6430die_name(
const Dwarf_Die* die)
6432 string name = die_string_attribute(die, DW_AT_name);
6448die_loc_and_name(
const reader& rdr,
6452 string& linkage_name)
6454 loc = die_location(rdr, die);
6455 name = die_name(die);
6456 linkage_name = die_linkage_name(die);
6469die_size_in_bits(
const Dwarf_Die* die, uint64_t& size)
6474 uint64_t byte_size = 0, bit_size = 0;
6476 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
6478 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
6482 bit_size = byte_size * 8;
6505 if (!die_unsigned_constant_attribute(die, DW_AT_accessibility, a))
6512 case private_access:
6513 result = private_access;
6516 case protected_access:
6517 result = protected_access;
6521 result = public_access;
6540die_is_public_decl(
const Dwarf_Die* die)
6544 bool is_public =
false;
6550 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6551 if (tag == DW_TAG_subprogram || tag == DW_TAG_variable)
6552 die_flag_attribute(die, DW_AT_external, is_public);
6553 else if (tag == DW_TAG_namespace)
6555 string name = die_name(die);
6556 is_public = !name.empty();
6570die_is_effectively_public_decl(
const reader& rdr,
6571 const Dwarf_Die* die)
6573 if (die_is_public_decl(die))
6576 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6577 if (tag == DW_TAG_variable || tag == DW_TAG_member)
6580 Dwarf_Die parent_die;
6581 size_t where_offset = 0;
6582 if (!get_parent_die(rdr, die, parent_die, where_offset))
6585 tag = dwarf_tag(&parent_die);
6586 if (tag == DW_TAG_compile_unit
6587 || tag == DW_TAG_partial_unit
6588 || tag == DW_TAG_type_unit)
6592 if (tag == DW_TAG_namespace)
6594 string name = die_name(&parent_die);
6613die_is_declaration_only(Dwarf_Die* die)
6615 bool is_declaration =
false;
6616 die_flag_attribute(die, DW_AT_declaration, is_declaration,
false);
6617 if (is_declaration && !die_has_size_attribute(die))
6628die_is_function_decl(
const Dwarf_Die *die)
6633 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6634 if (tag == DW_TAG_subprogram)
6645die_is_variable_decl(
const Dwarf_Die *die)
6650 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6651 if (tag == DW_TAG_variable)
6662die_has_size_attribute(
const Dwarf_Die *die)
6665 if (die_size_in_bits(die, s))
6676die_has_no_child(
const Dwarf_Die *die)
6682 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
6695die_is_declaration_only(
const Dwarf_Die* die)
6696{
return die_is_declaration_only(
const_cast<Dwarf_Die*
>(die));}
6704die_is_artificial(Dwarf_Die* die)
6707 return die_flag_attribute(die, DW_AT_artificial, is_artificial);
6714is_type_tag(
unsigned tag)
6716 bool result =
false;
6720 case DW_TAG_array_type:
6721 case DW_TAG_class_type:
6722 case DW_TAG_enumeration_type:
6723 case DW_TAG_pointer_type:
6724 case DW_TAG_reference_type:
6725 case DW_TAG_string_type:
6726 case DW_TAG_structure_type:
6727 case DW_TAG_subroutine_type:
6728 case DW_TAG_typedef:
6729 case DW_TAG_union_type:
6730 case DW_TAG_ptr_to_member_type:
6731 case DW_TAG_set_type:
6732 case DW_TAG_subrange_type:
6733 case DW_TAG_base_type:
6734 case DW_TAG_const_type:
6735 case DW_TAG_file_type:
6736 case DW_TAG_packed_type:
6737 case DW_TAG_thrown_type:
6738 case DW_TAG_volatile_type:
6739 case DW_TAG_restrict_type:
6740 case DW_TAG_interface_type:
6741 case DW_TAG_unspecified_type:
6742 case DW_TAG_shared_type:
6743 case DW_TAG_rvalue_reference_type:
6744 case DW_TAG_coarray_type:
6745 case DW_TAG_atomic_type:
6746 case DW_TAG_immutable_type:
6769is_canon_type_to_be_propagated_tag(
unsigned tag)
6771 bool result =
false;
6775 case DW_TAG_class_type:
6776 case DW_TAG_structure_type:
6777 case DW_TAG_union_type:
6778 case DW_TAG_subroutine_type:
6779 case DW_TAG_subprogram:
6800type_comparison_result_to_be_cached(
unsigned tag)
6805 case DW_TAG_class_type:
6806 case DW_TAG_structure_type:
6807 case DW_TAG_union_type:
6808 case DW_TAG_subroutine_type:
6809 case DW_TAG_subprogram:
6830maybe_cache_type_comparison_result(
const reader& rdr,
6835 if (!type_comparison_result_to_be_cached(tag)
6836 || (result != COMPARISON_RESULT_EQUAL
6837 && result != COMPARISON_RESULT_DIFFERENT))
6840 rdr.die_comparison_results_[p] = result;
6860get_cached_type_comparison_result(
const reader& rdr,
6864 auto i = rdr.die_comparison_results_.find(p);
6865 if (i != rdr.die_comparison_results_.end())
6888maybe_get_cached_type_comparison_result(
const reader& rdr,
6893 if (type_comparison_result_to_be_cached(tag))
6898 if (get_cached_type_comparison_result(rdr, p, result))
6910is_type_die_to_be_canonicalized(
const Dwarf_Die *die)
6912 bool result =
false;
6913 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
6915 if (!is_type_tag(tag))
6920 case DW_TAG_class_type:
6921 case DW_TAG_structure_type:
6922 case DW_TAG_union_type:
6923 result = !die_is_declaration_only(die);
6926 case DW_TAG_subroutine_type:
6927 case DW_TAG_subprogram:
6928 case DW_TAG_array_type:
6944is_decl_tag(
unsigned tag)
6948 case DW_TAG_formal_parameter:
6949 case DW_TAG_imported_declaration:
6951 case DW_TAG_unspecified_parameters:
6952 case DW_TAG_subprogram:
6953 case DW_TAG_variable:
6954 case DW_TAG_namespace:
6955 case DW_TAG_GNU_template_template_param:
6956 case DW_TAG_GNU_template_parameter_pack:
6957 case DW_TAG_GNU_formal_parameter_pack:
6969die_is_type(
const Dwarf_Die* die)
6973 return is_type_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
6982die_is_decl(
const Dwarf_Die* die)
6986 return is_decl_tag(dwarf_tag(
const_cast<Dwarf_Die*
>(die)));
6995die_is_namespace(
const Dwarf_Die* die)
6999 return (dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_namespace);
7008die_is_unspecified(Dwarf_Die* die)
7012 return (dwarf_tag(die) == DW_TAG_unspecified_type);
7021die_is_void_type(Dwarf_Die* die)
7023 if (!die || dwarf_tag(die) != DW_TAG_base_type)
7026 string name = die_name(die);
7039die_is_pointer_type(
const Dwarf_Die* die)
7044 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7045 if (tag == DW_TAG_pointer_type)
7059pointer_or_qual_die_of_anonymous_class_type(
const Dwarf_Die* die)
7061 if (!die_is_pointer_array_or_reference_type(die)
7062 && !die_is_qualified_type(die))
7065 Dwarf_Die underlying_type_die;
7066 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
7069 if (!die_is_class_type(&underlying_type_die))
7072 string name = die_name(&underlying_type_die);
7074 return name.empty();
7083die_is_reference_type(
const Dwarf_Die* die)
7088 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7089 if (tag == DW_TAG_reference_type || tag == DW_TAG_rvalue_reference_type)
7101die_is_array_type(
const Dwarf_Die* die)
7106 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7107 if (tag == DW_TAG_array_type)
7119die_is_pointer_array_or_reference_type(
const Dwarf_Die* die)
7120{
return (die_is_pointer_type(die)
7121 || die_is_reference_type(die)
7122 || die_is_array_type(die));}
7130die_is_pointer_or_reference_type(
const Dwarf_Die* die)
7131{
return (die_is_pointer_type(die) || die_is_reference_type(die));}
7140die_is_pointer_reference_or_typedef_type(
const Dwarf_Die* die)
7141{
return (die_is_pointer_array_or_reference_type(die)
7142 || dwarf_tag(
const_cast<Dwarf_Die*
>(die)) == DW_TAG_typedef);}
7150die_is_class_type(
const Dwarf_Die* die)
7152 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7154 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
7166die_is_qualified_type(
const Dwarf_Die* die)
7168 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7169 if (tag == DW_TAG_const_type
7170 || tag == DW_TAG_volatile_type
7171 || tag == DW_TAG_restrict_type)
7183die_is_function_type(
const Dwarf_Die *die)
7185 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7186 if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type)
7204die_has_object_pointer(
const Dwarf_Die* die, Dwarf_Die& object_pointer)
7209 if (die_die_attribute(die, DW_AT_object_pointer, object_pointer))
7221die_has_children(
const Dwarf_Die* die)
7227 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
7247die_this_pointer_from_object_pointer(Dwarf_Die* die,
7248 Dwarf_Die& this_pointer_die)
7251 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7253 if (die_die_attribute(die, DW_AT_type, this_pointer_die))
7268die_this_pointer_is_const(Dwarf_Die* die)
7272 if (dwarf_tag(die) == DW_TAG_pointer_type)
7274 Dwarf_Die pointed_to_type_die;
7275 if (die_die_attribute(die, DW_AT_type, pointed_to_type_die))
7276 if (dwarf_tag(&pointed_to_type_die) == DW_TAG_const_type)
7292die_object_pointer_is_for_const_method(Dwarf_Die* die)
7295 ABG_ASSERT(dwarf_tag(die) == DW_TAG_formal_parameter);
7297 Dwarf_Die this_pointer_die;
7298 if (die_this_pointer_from_object_pointer(die, this_pointer_die))
7299 if (die_this_pointer_is_const(&this_pointer_die))
7321die_is_at_class_scope(
const reader& rdr,
7322 const Dwarf_Die* die,
7323 size_t where_offset,
7324 Dwarf_Die& class_scope_die)
7326 if (!get_scope_die(rdr, die, where_offset, class_scope_die))
7329 int tag = dwarf_tag(&class_scope_die);
7331 return (tag == DW_TAG_structure_type
7332 || tag == DW_TAG_class_type
7333 || tag == DW_TAG_union_type);
7346die_peel_qual_ptr(Dwarf_Die *die, Dwarf_Die& peeled_die)
7351 int tag = dwarf_tag(die);
7353 if (tag == DW_TAG_const_type
7354 || tag == DW_TAG_volatile_type
7355 || tag == DW_TAG_restrict_type
7356 || tag == DW_TAG_pointer_type
7357 || tag == DW_TAG_reference_type
7358 || tag == DW_TAG_rvalue_reference_type)
7360 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7366 memcpy(&peeled_die, die,
sizeof(peeled_die));
7368 while (tag == DW_TAG_const_type
7369 || tag == DW_TAG_volatile_type
7370 || tag == DW_TAG_restrict_type
7371 || tag == DW_TAG_pointer_type
7372 || tag == DW_TAG_reference_type
7373 || tag == DW_TAG_rvalue_reference_type)
7375 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7377 tag = dwarf_tag(&peeled_die);
7392die_peel_qualified(Dwarf_Die *die, Dwarf_Die& peeled_die)
7397 memcpy(&peeled_die, die,
sizeof(peeled_die));
7399 int tag = dwarf_tag(&peeled_die);
7401 bool result =
false;
7402 while (tag == DW_TAG_const_type
7403 || tag == DW_TAG_volatile_type
7404 || tag == DW_TAG_restrict_type)
7406 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7408 tag = dwarf_tag(&peeled_die);
7424die_peel_typedef(Dwarf_Die *die, Dwarf_Die& peeled_die)
7429 int tag = dwarf_tag(die);
7431 memcpy(&peeled_die, die,
sizeof(peeled_die));
7433 if (tag == DW_TAG_typedef)
7435 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7441 while (tag == DW_TAG_typedef)
7443 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7445 tag = dwarf_tag(&peeled_die);
7461die_peel_pointer_and_typedef(
const Dwarf_Die *die, Dwarf_Die& peeled_die)
7466 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7468 if (tag == DW_TAG_pointer_type
7469 || tag == DW_TAG_reference_type
7470 || tag == DW_TAG_rvalue_reference_type
7471 || tag == DW_TAG_typedef)
7473 if (!die_die_attribute(die, DW_AT_type, peeled_die))
7479 while (tag == DW_TAG_pointer_type
7480 || tag == DW_TAG_reference_type
7481 || tag == DW_TAG_rvalue_reference_type
7482 || tag == DW_TAG_typedef)
7484 if (!die_die_attribute(&peeled_die, DW_AT_type, peeled_die))
7486 tag = dwarf_tag(&peeled_die);
7514die_function_type_is_method_type(
const reader& rdr,
7515 const Dwarf_Die *die,
7516 size_t where_offset,
7517 Dwarf_Die& object_pointer_die,
7518 Dwarf_Die& class_die,
7524 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
7525 ABG_ASSERT(tag == DW_TAG_subroutine_type || tag == DW_TAG_subprogram);
7527 bool has_object_pointer =
false;
7529 if (tag == DW_TAG_subprogram)
7531 Dwarf_Die spec_or_origin_die;
7532 if (die_die_attribute(die, DW_AT_specification,
7534 || die_die_attribute(die, DW_AT_abstract_origin,
7535 spec_or_origin_die))
7537 if (die_has_object_pointer(&spec_or_origin_die,
7538 object_pointer_die))
7539 has_object_pointer =
true;
7542 if (die_is_at_class_scope(rdr, &spec_or_origin_die,
7543 where_offset, class_die))
7551 if (die_has_object_pointer(die, object_pointer_die))
7552 has_object_pointer =
true;
7555 if (die_is_at_class_scope(rdr, die, where_offset, class_die))
7564 if (die_has_object_pointer(die, object_pointer_die))
7565 has_object_pointer =
true;
7576 Dwarf_Die this_type_die;
7577 if (!die_die_attribute(&object_pointer_die, DW_AT_type, this_type_die))
7582 if (!die_peel_qual_ptr(&this_type_die, class_die))
7587 die_peel_typedef(&class_die, class_die);
7595 VIRTUALITY_NOT_VIRTUAL,
7597 VIRTUALITY_PURE_VIRTUAL
7610die_virtuality(
const Dwarf_Die* die, virtuality& virt)
7616 die_unsigned_constant_attribute(die, DW_AT_virtuality, v);
7618 if (v == DW_VIRTUALITY_virtual)
7619 virt = VIRTUALITY_VIRTUAL;
7620 else if (v == DW_VIRTUALITY_pure_virtual)
7621 virt = VIRTUALITY_PURE_VIRTUAL;
7623 virt = VIRTUALITY_NOT_VIRTUAL;
7635die_is_virtual(
const Dwarf_Die* die)
7638 if (!die_virtuality(die, v))
7641 return v == VIRTUALITY_PURE_VIRTUAL || v == VIRTUALITY_VIRTUAL;
7651die_is_declared_inline(Dwarf_Die* die)
7653 uint64_t inline_value = 0;
7654 if (!die_unsigned_constant_attribute(die, DW_AT_inline, inline_value))
7656 return inline_value == DW_INL_declared_inlined;
7671slowly_compare_strings(
const Dwarf_Die *l,
7675 const char *l_str = die_char_str_attribute(l, attr_name),
7676 *r_str = die_char_str_attribute(r, attr_name);
7677 if (!l_str && !r_str)
7679 return l_str && r_str && !strcmp(l_str, r_str);
7705compare_dies_string_attribute_value(
const Dwarf_Die *l,
const Dwarf_Die *r,
7709 Dwarf_Attribute l_attr, r_attr;
7710 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(l), attr_name, &l_attr)
7711 || !dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(r), attr_name, &r_attr))
7715 || l_attr.form == DW_FORM_string
7716 || l_attr.form == DW_FORM_GNU_strp_alt
7717 || form_is_DW_FORM_strx(l_attr.form)
7718 || form_is_DW_FORM_line_strp(l_attr.form));
7721 || r_attr.form == DW_FORM_string
7722 || r_attr.form == DW_FORM_GNU_strp_alt
7723 || form_is_DW_FORM_strx(r_attr.form)
7724 || form_is_DW_FORM_line_strp(r_attr.form));
7726 if ((l_attr.form == DW_FORM_strp
7727 && r_attr.form == DW_FORM_strp)
7728 || (l_attr.form == DW_FORM_GNU_strp_alt
7729 && r_attr.form == DW_FORM_GNU_strp_alt)
7730 || (form_is_DW_FORM_strx(l_attr.form)
7731 && form_is_DW_FORM_strx(r_attr.form))
7732 || (form_is_DW_FORM_line_strp(l_attr.form)
7733 && form_is_DW_FORM_line_strp(r_attr.form)))
7740 if (l_attr.valp == r_attr.valp)
7742#if WITH_DEBUG_TYPE_CANONICALIZATION
7743 ABG_ASSERT(slowly_compare_strings(l, r, attr_name));
7754 result = slowly_compare_strings(l, r, attr_name);
7772compare_dies_cu_decl_file(
const Dwarf_Die* l,
const Dwarf_Die *r,
bool &result)
7774 Dwarf_Die l_cu, r_cu;
7775 if (!dwarf_diecu(
const_cast<Dwarf_Die*
>(l), &l_cu, 0, 0)
7776 ||!dwarf_diecu(
const_cast<Dwarf_Die*
>(r), &r_cu, 0, 0))
7780 compare_dies_string_attribute_value(&l_cu, &r_cu,
7783 if (compared && result)
7785 Dwarf_Die peeled_l, peeled_r;
7786 if (die_is_pointer_reference_or_typedef_type(l)
7787 && die_is_pointer_reference_or_typedef_type(r)
7788 && die_peel_pointer_and_typedef(l, peeled_l)
7789 && die_peel_pointer_and_typedef(r, peeled_r))
7791 if (!dwarf_diecu(&peeled_l, &l_cu, 0, 0)
7792 ||!dwarf_diecu(&peeled_r, &r_cu, 0, 0))
7795 compare_dies_string_attribute_value(&l_cu, &r_cu,
7826die_location_expr(
const Dwarf_Die* die,
7834 Dwarf_Attribute attr;
7835 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), attr_name, &attr))
7839 bool result = (dwarf_getlocation(&attr, expr, &len) == 0);
7874op_pushes_constant_value(Dwarf_Op* ops,
7878 dwarf_expr_eval_context& ctxt)
7882 Dwarf_Op& op = ops[index];
7888 value = ops[index].number;
7901 value = ops[index].number;
8005 expr_result r(value);
8008 next_index = index + 1;
8038op_pushes_non_constant_value(Dwarf_Op* ops,
8042 dwarf_expr_eval_context& ctxt)
8045 Dwarf_Op& op = ops[index];
8081 next_index = index + 1;
8116 next_index = index + 1;
8120 next_index = index + 2;
8124 next_index = index + 1;
8128 next_index = index + 1;
8131 case DW_OP_GNU_variable_value:
8132 next_index = index + 1;
8139 expr_result r(
false);
8168op_manipulates_stack(Dwarf_Op* expr,
8172 dwarf_expr_eval_context& ctxt)
8174 Dwarf_Op& op = expr[index];
8180 v = ctxt.stack.front();
8185 v = ctxt.stack.front();
8204 ctxt.stack.erase(ctxt.stack.begin() + 1);
8211 ctxt.stack.erase(ctxt.stack.begin() + 2);
8216 case DW_OP_deref_size:
8224 case DW_OP_xderef_size:
8232 case DW_OP_push_object_address:
8237 case DW_OP_form_tls_address:
8238 case DW_OP_GNU_push_tls_address:
8241 if (op.atom == DW_OP_form_tls_address)
8246 case DW_OP_call_frame_cfa:
8258 if (op.atom == DW_OP_form_tls_address
8259 || op.atom == DW_OP_GNU_push_tls_address)
8260 ctxt.set_tls_address(
true);
8262 ctxt.set_tls_address(
false);
8264 next_index = index + 1;
8292op_is_arith_logic(Dwarf_Op* expr,
8296 dwarf_expr_eval_context& ctxt)
8300 Dwarf_Op& op = expr[index];
8301 expr_result val1, val2;
8302 bool result =
false;
8318 ctxt.push(val1 & val2);
8325 if (!val1.is_const())
8327 ctxt.push(val2 / val1);
8335 ctxt.push(val2 - val1);
8343 ctxt.push(val2 % val1);
8351 ctxt.push(val2 * val1);
8373 ctxt.push(val1 | val2);
8381 ctxt.push(val2 + val1);
8385 case DW_OP_plus_uconst:
8397 ctxt.push(val2 << val1);
8406 ctxt.push(val2 >> val1);
8414 ctxt.push(val2 ^ val1);
8424 if (ctxt.stack.front().is_const())
8425 ctxt.accum = ctxt.stack.front();
8427 next_index = index + 1;
8455op_is_control_flow(Dwarf_Op* expr,
8459 dwarf_expr_eval_context& ctxt)
8463 Dwarf_Op& op = expr[index];
8464 expr_result val1, val2;
8478 if (op.atom == DW_OP_eq)
8479 value = val2 == val1;
8480 else if (op.atom == DW_OP_ge)
8481 value = val2 >= val1;
8482 else if (op.atom == DW_OP_gt)
8483 value = val2 > val1;
8484 else if (op.atom == DW_OP_le)
8485 value = val2 <= val1;
8486 else if (op.atom == DW_OP_lt)
8487 value = val2 < val1;
8488 else if (op.atom == DW_OP_ne)
8489 value = val2 != val1;
8491 val1 = value ? 1 : 0;
8498 index += op.number - 1;
8503 if (val1.const_value() != 0)
8504 index += val1.const_value() - 1;
8509 case DW_OP_call_ref:
8517 if (ctxt.stack.front().is_const())
8518 ctxt.accum = ctxt.stack.front();
8520 next_index = index + 1;
8541eval_quickly(Dwarf_Op* expr,
8545 if (expr_len == 1 && (expr[0].atom == DW_OP_plus_uconst))
8547 value = expr[0].number;
8574eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8577 bool& is_tls_address,
8578 dwarf_expr_eval_context &eval_ctxt)
8584 size_t index = 0, next_index = 0;
8587 if (op_is_arith_logic(expr, expr_len, index,
8588 next_index, eval_ctxt)
8589 || op_pushes_constant_value(expr, expr_len, index,
8590 next_index, eval_ctxt)
8591 || op_manipulates_stack(expr, expr_len, index,
8592 next_index, eval_ctxt)
8593 || op_pushes_non_constant_value(expr, expr_len, index,
8594 next_index, eval_ctxt)
8595 || op_is_control_flow(expr, expr_len, index,
8596 next_index, eval_ctxt))
8599 next_index = index + 1;
8603 }
while (index < expr_len);
8605 is_tls_address = eval_ctxt.set_tls_address();
8606 if (eval_ctxt.accum.is_const())
8608 value = eval_ctxt.accum;
8628eval_last_constant_dwarf_sub_expr(Dwarf_Op* expr,
8631 bool& is_tls_address)
8633 dwarf_expr_eval_context eval_ctxt;
8634 return eval_last_constant_dwarf_sub_expr(expr, expr_len, value,
8635 is_tls_address, eval_ctxt);
8827read_and_convert_DW_at_bit_offset(
const Dwarf_Die* die,
8832 if (!die_unsigned_constant_attribute(die, DW_AT_bit_offset, off))
8845 uint64_t containing_anonymous_object_size = 0;
8846 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_byte_size,
8847 containing_anonymous_object_size));
8848 containing_anonymous_object_size *= 8;
8850 uint64_t bitfield_size = 0;
8851 ABG_ASSERT(die_unsigned_constant_attribute(die, DW_AT_bit_size,
8862 offset = containing_anonymous_object_size - off - bitfield_size;
8878die_constant_data_member_location(
const Dwarf_Die *die,
8884 Dwarf_Attribute attr;
8885 if (!dwarf_attr(
const_cast<Dwarf_Die*
>(die),
8886 DW_AT_data_member_location,
8891 if (dwarf_formudata(&attr, &val) != 0)
8947die_member_offset(
const reader& rdr,
8948 const Dwarf_Die* die,
8951 Dwarf_Op* expr = NULL;
8952 size_t expr_len = 0;
8953 uint64_t bit_offset = 0;
8957 if (die_unsigned_constant_attribute(die, DW_AT_data_bit_offset, bit_offset))
8959 offset = bit_offset;
8971 if (!die_constant_data_member_location(die, offset))
8976 if (!die_location_expr(die, DW_AT_data_member_location,
8983 if (!eval_quickly(expr, expr_len, offset))
8985 bool is_tls_address =
false;
8986 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len,
8987 offset, is_tls_address,
8988 rdr.dwarf_expr_eval_ctxt()))
9006 if (read_and_convert_DW_at_bit_offset(die, is_big_endian, bit_offset))
9007 offset += bit_offset;
9024die_location_address(Dwarf_Die* die,
9025 Dwarf_Addr& address,
9026 bool& is_tls_address)
9028 Dwarf_Op* expr = NULL;
9029 size_t expr_len = 0;
9031 is_tls_address =
false;
9036 Dwarf_Attribute attr;
9037 if (!dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(die), DW_AT_location, &attr))
9040 if (dwarf_getlocation(&attr, &expr, &expr_len))
9047 Dwarf_Attribute result;
9048 if (!dwarf_getlocation_attr(&attr, expr, &result))
9050 return !dwarf_formaddr(&result, &address);
9053 address = expr->number;
9068die_virtual_function_index(Dwarf_Die* die,
9074 Dwarf_Op* expr = NULL;
9075 size_t expr_len = 0;
9076 if (!die_location_expr(die, DW_AT_vtable_elem_location,
9081 bool is_tls_addr =
false;
9082 if (!eval_last_constant_dwarf_sub_expr(expr, expr_len, i, is_tls_addr))
9100 int tag = dwarf_tag(die);
9102 if (tag == DW_TAG_class_type
9103 || tag == DW_TAG_structure_type
9104 || tag == DW_TAG_union_type
9105 || tag == DW_TAG_enumeration_type)
9106 return die_is_anonymous(die);
9128get_internal_anonymous_die_prefix_name(
const Dwarf_Die *die)
9131 ABG_ASSERT(die_string_attribute(die, DW_AT_name) ==
"");
9133 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9135 if (tag == DW_TAG_class_type || tag == DW_TAG_structure_type)
9137 else if (tag == DW_TAG_union_type)
9139 else if (tag == DW_TAG_enumeration_type)
9158build_internal_anonymous_die_name(
const string &
base_name,
9159 size_t anonymous_type_index)
9162 if (anonymous_type_index && !
base_name.empty())
9164 std::ostringstream o;
9184get_internal_anonymous_die_name(Dwarf_Die *die,
9185 size_t anonymous_type_index)
9187 string name = get_internal_anonymous_die_prefix_name(die);
9188 name = build_internal_anonymous_die_name(name, anonymous_type_index);
9210die_qualified_type_name(
const reader& rdr,
9211 const Dwarf_Die* die,
9212 size_t where_offset)
9217 int tag = dwarf_tag (
const_cast<Dwarf_Die*
>(die));
9218 if (tag == DW_TAG_compile_unit
9219 || tag == DW_TAG_partial_unit
9220 || tag == DW_TAG_type_unit)
9223 string name = die_name(die);
9225 Dwarf_Die scope_die;
9226 if (!get_scope_die(rdr, die, where_offset, scope_die))
9229 string parent_name = die_qualified_name(rdr, &scope_die, where_offset);
9230 bool colon_colon = die_is_type(die) || die_is_namespace(die);
9231 string separator = colon_colon ?
"::" :
".";
9237 case DW_TAG_unspecified_type:
9240 case DW_TAG_base_type:
9250 case DW_TAG_typedef:
9251 case DW_TAG_enumeration_type:
9252 case DW_TAG_structure_type:
9253 case DW_TAG_class_type:
9254 case DW_TAG_union_type:
9262 name = get_internal_anonymous_die_prefix_name(die);
9265 repr = parent_name.empty() ? name : parent_name + separator + name;
9269 case DW_TAG_const_type:
9270 case DW_TAG_volatile_type:
9271 case DW_TAG_restrict_type:
9273 Dwarf_Die underlying_type_die;
9274 bool has_underlying_type_die =
9275 die_die_attribute(die, DW_AT_type, underlying_type_die);
9277 if (has_underlying_type_die && die_is_unspecified(&underlying_type_die))
9280 if (tag == DW_TAG_const_type)
9282 if (has_underlying_type_die
9283 && die_is_reference_type(&underlying_type_die))
9293 else if (!has_underlying_type_die
9294 || die_is_void_type(&underlying_type_die))
9302 else if (tag == DW_TAG_volatile_type)
9304 else if (tag == DW_TAG_restrict_type)
9309 string underlying_type_repr;
9310 if (has_underlying_type_die)
9311 underlying_type_repr =
9312 die_qualified_type_name(rdr, &underlying_type_die, where_offset);
9314 underlying_type_repr =
"void";
9316 if (underlying_type_repr.empty())
9320 if (has_underlying_type_die)
9323 die_peel_qualified(&underlying_type_die, peeled);
9324 if (die_is_pointer_or_reference_type(&peeled))
9325 repr = underlying_type_repr +
" " + repr;
9327 repr +=
" " + underlying_type_repr;
9330 repr +=
" " + underlying_type_repr;
9335 case DW_TAG_pointer_type:
9336 case DW_TAG_reference_type:
9337 case DW_TAG_rvalue_reference_type:
9339 Dwarf_Die pointed_to_type_die;
9340 if (!die_die_attribute(die, DW_AT_type, pointed_to_type_die))
9342 if (tag == DW_TAG_pointer_type)
9347 if (die_is_unspecified(&pointed_to_type_die))
9350 string pointed_type_repr =
9351 die_qualified_type_name(rdr, &pointed_to_type_die, where_offset);
9353 repr = pointed_type_repr;
9357 if (tag == DW_TAG_pointer_type)
9359 else if (tag == DW_TAG_reference_type)
9361 else if (tag == DW_TAG_rvalue_reference_type)
9368 case DW_TAG_subrange_type:
9381 build_subrange_type(
const_cast<reader&
>(rdr),
9384 repr += s->as_string();
9388 case DW_TAG_array_type:
9390 Dwarf_Die element_type_die;
9391 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9393 string element_type_name =
9394 die_qualified_type_name(rdr, &element_type_die, where_offset);
9395 if (element_type_name.empty())
9399 build_subranges_from_array_type_die(
const_cast<reader&
>(rdr),
9400 die, subranges, where_offset,
9403 repr = element_type_name;
9404 repr += array_type_def::subrange_type::vector_as_string(subranges);
9408 case DW_TAG_subroutine_type:
9409 case DW_TAG_subprogram:
9411 string return_type_name;
9413 vector<string> parm_names;
9414 bool is_const =
false;
9415 bool is_static =
false;
9417 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9419 return_type_name, class_name,
9420 parm_names, is_const,
9422 if (return_type_name.empty())
9423 return_type_name =
"void";
9425 repr = return_type_name;
9427 if (!class_name.empty())
9430 repr +=
" (" + class_name +
"::*)";
9435 for (vector<string>::const_iterator i = parm_names.begin();
9436 i != parm_names.end();
9439 if (i != parm_names.begin())
9448 case DW_TAG_string_type:
9449 case DW_TAG_ptr_to_member_type:
9450 case DW_TAG_set_type:
9451 case DW_TAG_file_type:
9452 case DW_TAG_packed_type:
9453 case DW_TAG_thrown_type:
9454 case DW_TAG_interface_type:
9455 case DW_TAG_shared_type:
9475die_qualified_decl_name(
const reader& rdr,
9476 const Dwarf_Die* die,
9477 size_t where_offset)
9479 if (!die || !die_is_decl(die))
9482 string name = die_name(die);
9484 Dwarf_Die scope_die;
9485 if (!get_scope_die(rdr, die, where_offset, scope_die))
9488 string scope_name = die_qualified_name(rdr, &scope_die, where_offset);
9489 string separator =
"::";
9493 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9496 case DW_TAG_namespace:
9498 case DW_TAG_variable:
9499 repr = scope_name.empty() ? name : scope_name + separator + name;
9501 case DW_TAG_subprogram:
9502 repr = die_function_signature(rdr, die, where_offset);
9505 case DW_TAG_unspecified_parameters:
9509 case DW_TAG_formal_parameter:
9510 case DW_TAG_imported_declaration:
9511 case DW_TAG_GNU_template_template_param:
9512 case DW_TAG_GNU_template_parameter_pack:
9513 case DW_TAG_GNU_formal_parameter_pack:
9536die_qualified_name(
const reader& rdr,
const Dwarf_Die* die,
size_t where)
9538 if (die_is_type(die))
9539 return die_qualified_type_name(rdr, die, where);
9540 else if (die_is_decl(die))
9541 return die_qualified_decl_name(rdr, die, where);
9563die_qualified_type_name_empty(
const reader& rdr,
9564 const Dwarf_Die* die,
9565 size_t where,
string &qualified_name)
9570 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9573 if (tag == DW_TAG_typedef
9574 || tag == DW_TAG_pointer_type
9575 || tag == DW_TAG_reference_type
9576 || tag == DW_TAG_rvalue_reference_type
9577 || tag == DW_TAG_array_type
9578 || tag == DW_TAG_const_type
9579 || tag == DW_TAG_volatile_type
9580 || tag == DW_TAG_restrict_type)
9582 Dwarf_Die underlying_type_die;
9583 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
9586 die_qualified_type_name(rdr, &underlying_type_die, where);
9593 string name = die_qualified_type_name(rdr, die, where);
9598 qname = die_qualified_type_name(rdr, die, where);
9602 qualified_name = qname;
9642die_return_and_parm_names_from_fn_type_die(
const reader& rdr,
9643 const Dwarf_Die* die,
9644 size_t where_offset,
9646 string &return_type_name,
9648 vector<string>& parm_names,
9653 Dwarf_Die ret_type_die;
9654 if (!die_die_attribute(die, DW_AT_type, ret_type_die))
9655 return_type_name =
"void";
9659 ? rdr.get_die_pretty_representation(&ret_type_die, where_offset)
9660 : rdr.get_die_qualified_type_name(&ret_type_die, where_offset);
9662 if (return_type_name.empty())
9663 return_type_name =
"void";
9665 Dwarf_Die object_pointer_die, class_die;
9667 die_function_type_is_method_type(rdr, die, where_offset,
9669 class_die, is_static);
9674 class_name = rdr.get_die_qualified_type_name(&class_die, where_offset);
9676 Dwarf_Die this_pointer_die;
9677 Dwarf_Die pointed_to_die;
9679 && die_die_attribute(&object_pointer_die, DW_AT_type,
9681 if (die_die_attribute(&this_pointer_die, DW_AT_type, pointed_to_die))
9682 if (dwarf_tag(&pointed_to_die) == DW_TAG_const_type)
9685 string fn_name = die_name(die);
9686 string non_qualified_class_name = die_name(&class_die);
9687 bool is_ctor = fn_name == non_qualified_class_name;
9688 bool is_dtor = !fn_name.empty() && fn_name[0] ==
'~';
9690 if (is_ctor || is_dtor)
9691 return_type_name.clear();
9694 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
9697 int child_tag = dwarf_tag(&child);
9698 if (child_tag == DW_TAG_formal_parameter)
9700 Dwarf_Die parm_type_die;
9701 if (!die_die_attribute(&child, DW_AT_type, parm_type_die))
9703 string qualified_name =
9705 ? rdr.get_die_pretty_representation(&parm_type_die, where_offset)
9706 : rdr.get_die_qualified_type_name(&parm_type_die, where_offset);
9708 if (qualified_name.empty())
9710 parm_names.push_back(qualified_name);
9712 else if (child_tag == DW_TAG_unspecified_parameters)
9715 parm_names.push_back(rdr.env().get_variadic_parameter_type_name());
9725 while (dwarf_siblingof(&child, &child) == 0);
9727 if (class_name.empty())
9729 Dwarf_Die parent_die;
9730 if (get_parent_die(rdr, die, parent_die, where_offset))
9732 if (die_is_class_type(&parent_die))
9734 rdr.get_die_qualified_type_name(&parent_die, where_offset);
9751die_function_signature(
const reader& rdr,
9752 const Dwarf_Die *fn_die,
9753 size_t where_offset)
9757 bool has_lang =
false;
9758 if ((has_lang = rdr.get_die_language(fn_die, lang)))
9766 string fn_name = die_linkage_name(fn_die);
9767 if (fn_name.empty())
9768 fn_name = die_name(fn_die);
9778 string return_type_name;
9779 Dwarf_Die ret_type_die;
9780 if (die_die_attribute(fn_die, DW_AT_type, ret_type_die))
9781 return_type_name = rdr.get_die_qualified_type_name(&ret_type_die,
9784 if (return_type_name.empty())
9785 return_type_name =
"void";
9787 Dwarf_Die scope_die;
9789 if (get_scope_die(rdr, fn_die, where_offset, scope_die))
9790 scope_name = rdr.get_die_qualified_name(&scope_die, where_offset);
9791 string fn_name = die_name(fn_die);
9792 if (!scope_name.empty())
9793 fn_name = scope_name +
"::" + fn_name;
9796 vector<string> parm_names;
9797 bool is_const =
false;
9798 bool is_static =
false;
9800 die_return_and_parm_names_from_fn_type_die(rdr, fn_die, where_offset,
9802 return_type_name, class_name,
9803 parm_names, is_const, is_static);
9805 bool is_virtual = die_is_virtual(fn_die);
9807 string repr = class_name.empty() ?
"function" :
"method";
9811 if (!return_type_name.empty())
9812 repr +=
" " + return_type_name;
9814 repr +=
" " + fn_name;
9818 bool some_parm_emitted =
false;
9819 for (vector<string>::const_iterator i = parm_names.begin();
9820 i != parm_names.end();
9823 if (i != parm_names.begin())
9825 if (some_parm_emitted)
9829 if (!is_static && !class_name.empty())
9834 some_parm_emitted =
true;
9865die_pretty_print_type(reader& rdr,
9866 const Dwarf_Die* die,
9867 size_t where_offset)
9870 || (!die_is_type(die)
9871 && dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_subprogram))
9876 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
9879 case DW_TAG_string_type:
9888 repr =
"string type";
9890 case DW_TAG_unspecified_type:
9891 case DW_TAG_ptr_to_member_type:
9894 case DW_TAG_namespace:
9895 repr =
"namespace " + rdr.get_die_qualified_type_name(die, where_offset);
9898 case DW_TAG_base_type:
9899 repr = rdr.get_die_qualified_type_name(die, where_offset);
9902 case DW_TAG_typedef:
9904 string qualified_name;
9905 if (!die_qualified_type_name_empty(rdr, die,
9908 repr =
"typedef " + qualified_name;
9912 case DW_TAG_const_type:
9913 case DW_TAG_volatile_type:
9914 case DW_TAG_restrict_type:
9915 case DW_TAG_pointer_type:
9916 case DW_TAG_reference_type:
9917 case DW_TAG_rvalue_reference_type:
9918 repr = rdr.get_die_qualified_type_name(die, where_offset);
9921 case DW_TAG_enumeration_type:
9923 string qualified_name =
9924 rdr.get_die_qualified_type_name(die, where_offset);
9925 repr =
"enum " + qualified_name;
9929 case DW_TAG_structure_type:
9930 case DW_TAG_class_type:
9932 string qualified_name =
9933 rdr.get_die_qualified_type_name(die, where_offset);
9934 repr =
"class " + qualified_name;
9938 case DW_TAG_union_type:
9940 string qualified_name =
9941 rdr.get_die_qualified_type_name(die, where_offset);
9942 repr =
"union " + qualified_name;
9946 case DW_TAG_array_type:
9948 Dwarf_Die element_type_die;
9949 if (!die_die_attribute(die, DW_AT_type, element_type_die))
9951 string element_type_name =
9952 rdr.get_die_qualified_type_name(&element_type_die, where_offset);
9953 if (element_type_name.empty())
9957 build_subranges_from_array_type_die(rdr, die, subranges, where_offset,
9960 repr = element_type_name;
9961 repr += array_type_def::subrange_type::vector_as_string(subranges);
9965 case DW_TAG_subrange_type:
9975 repr += die_qualified_type_name(rdr, die, where_offset);
9979 case DW_TAG_subroutine_type:
9980 case DW_TAG_subprogram:
9982 string return_type_name;
9984 vector<string> parm_names;
9985 bool is_const =
false;
9986 bool is_static =
false;
9988 die_return_and_parm_names_from_fn_type_die(rdr, die, where_offset,
9990 return_type_name, class_name,
9991 parm_names, is_const,
9993 if (class_name.empty())
9994 repr =
"function type";
9996 repr =
"method type";
9997 repr +=
" " + rdr.get_die_qualified_type_name(die, where_offset);
10001 case DW_TAG_set_type:
10002 case DW_TAG_file_type:
10003 case DW_TAG_packed_type:
10004 case DW_TAG_thrown_type:
10005 case DW_TAG_interface_type:
10006 case DW_TAG_shared_type:
10032die_pretty_print_decl(reader& rdr,
10033 const Dwarf_Die* die,
10034 size_t where_offset)
10036 if (!die || !die_is_decl(die))
10041 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10044 case DW_TAG_namespace:
10045 repr =
"namespace " + die_qualified_name(rdr, die, where_offset);
10048 case DW_TAG_member:
10049 case DW_TAG_variable:
10051 string type_repr =
"void";
10052 Dwarf_Die type_die;
10053 if (die_die_attribute(die, DW_AT_type, type_die))
10054 type_repr = die_qualified_type_name(rdr, &type_die, where_offset);
10055 repr = die_qualified_name(rdr, die, where_offset);
10057 repr = type_repr +
" " + repr;
10061 case DW_TAG_subprogram:
10062 repr = die_function_signature(rdr, die, where_offset);
10088die_pretty_print(reader& rdr,
const Dwarf_Die* die,
size_t where_offset)
10090 if (die_is_type(die))
10091 return die_pretty_print_type(rdr, die, where_offset);
10092 else if (die_is_decl(die))
10093 return die_pretty_print_decl(rdr, die, where_offset);
10116compare_as_decl_dies(
const Dwarf_Die *l,
const Dwarf_Die *r)
10120 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10121 int r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10122 if (l_tag != r_tag)
10125 bool result =
false;
10127 if (l_tag == DW_TAG_subprogram || l_tag == DW_TAG_variable)
10130 if (compare_dies_string_attribute_value(l, r, DW_AT_linkage_name,
10132 || compare_dies_string_attribute_value(l, r, DW_AT_MIPS_linkage_name,
10139 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10149 if (compare_dies_string_attribute_value(l, r, DW_AT_name,
10166at_least_one_decl_only_among_odr_relevant_dies(
const reader &rdr,
10167 const Dwarf_Die *l,
10168 const Dwarf_Die *r)
10170 if (!(rdr.odr_is_relevant(l) && rdr.odr_is_relevant(r)))
10173 if ((die_is_declaration_only(l) && die_has_no_child(l))
10174 || (die_is_declaration_only(r) && die_has_no_child(r)))
10201compare_as_type_dies(
const reader& rdr,
10202 const Dwarf_Die *l,
10203 const Dwarf_Die *r)
10209 if (dwarf_tag(
const_cast<Dwarf_Die*
>(l)) == DW_TAG_string_type
10210 && dwarf_tag(
const_cast<Dwarf_Die*
>(r)) == DW_TAG_string_type
10211 && (dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10212 != dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))))
10220 if (at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10225 uint64_t l_size = 0, r_size = 0;
10226 die_size_in_bits(l, l_size);
10227 die_size_in_bits(r, r_size);
10229 return l_size == r_size;
10244compare_as_decl_and_type_dies(
const reader &rdr,
10245 const Dwarf_Die *l,
10246 const Dwarf_Die *r)
10248 if (!compare_as_decl_dies(l, r)
10249 || !compare_as_type_dies(rdr, l, r))
10273fn_die_equal_by_linkage_name(
const reader &rdr,
10274 const Dwarf_Die *l,
10275 const Dwarf_Die *r)
10283 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10285 tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10288 string lname = die_name(l), rname = die_name(r);
10289 string llinkage_name = die_linkage_name(l),
10290 rlinkage_name = die_linkage_name(r);
10292 if (rdr.die_is_in_c_or_cplusplus(l)
10293 && rdr.die_is_in_c_or_cplusplus(r))
10295 if (!llinkage_name.empty() && !rlinkage_name.empty())
10296 return llinkage_name == rlinkage_name;
10297 else if (!!llinkage_name.empty() != !!rlinkage_name.empty())
10300 return lname == rname;
10303 return (!llinkage_name.empty()
10304 && !rlinkage_name.empty()
10305 && llinkage_name == rlinkage_name);
10337try_canonical_die_comparison(
const reader& rdr,
10338 Dwarf_Off l_offset, Dwarf_Off r_offset,
10340 bool& l_has_canonical_die_offset,
10341 bool& r_has_canonical_die_offset,
10342 Dwarf_Off& l_canonical_die_offset,
10343 Dwarf_Off& r_canonical_die_offset,
10346#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10347 if (rdr.debug_die_canonicalization_is_on_
10348 && !rdr.use_canonical_die_comparison_)
10353 l_has_canonical_die_offset =
10354 (l_canonical_die_offset =
10355 rdr.get_canonical_die_offset(l_offset, l_die_source,
10358 r_has_canonical_die_offset =
10359 (r_canonical_die_offset =
10360 rdr.get_canonical_die_offset(r_offset, r_die_source,
10363 if (l_has_canonical_die_offset && r_has_canonical_die_offset)
10365 result = (l_canonical_die_offset == r_canonical_die_offset);
10372#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
10385notify_die_comparison_failed(
const Dwarf_Die* ,
const Dwarf_Die* )
10389#define NOTIFY_DIE_COMPARISON_FAILED(l, r) \
10390 notify_die_comparison_failed(l, r)
10392#define NOTIFY_DIE_COMPARISON_FAILED(l, r)
10405#define ABG_RETURN(value) \
10408 if ((value) == COMPARISON_RESULT_DIFFERENT) \
10410 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10412 return return_comparison_result(l, r, dies_being_compared, \
10413 value, aggregates_being_compared, \
10414 update_canonical_dies_on_the_fly); \
10425#define ABG_RETURN_FALSE \
10428 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10429 return return_comparison_result(l, r, dies_being_compared, \
10430 COMPARISON_RESULT_DIFFERENT, \
10431 aggregates_being_compared, \
10432 update_canonical_dies_on_the_fly); \
10447#define SET_RESULT_TO_FALSE(result, l , r) \
10450 result = COMPARISON_RESULT_DIFFERENT; \
10451 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10467#define SET_RESULT_TO(result, value, l , r) \
10470 result = (value); \
10471 if (result == COMPARISON_RESULT_DIFFERENT) \
10473 NOTIFY_DIE_COMPARISON_FAILED(l, r); \
10477#define RETURN_IF_COMPARISON_CYCLE_DETECTED \
10480 if (aggregates_being_compared.contains(dies_being_compared)) \
10482 result = COMPARISON_RESULT_CYCLE_DETECTED; \
10483 aggregates_being_compared.record_redundant_type_die_pair(dies_being_compared); \
10484 ABG_RETURN(result); \
10499get_next_member_sibling_die(
const Dwarf_Die *die, Dwarf_Die *member)
10504 bool found_member =
false;
10505 for (found_member = (dwarf_siblingof(
const_cast<Dwarf_Die*
>(die),
10508 found_member = (dwarf_siblingof(member, member) == 0))
10510 int tag = dwarf_tag(member);
10511 if (tag == DW_TAG_member || tag == DW_TAG_inheritance)
10515 return found_member;
10529get_member_child_die(
const Dwarf_Die *die, Dwarf_Die *child)
10534 int tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
10536 || tag == DW_TAG_union_type
10537 || tag == DW_TAG_class_type);
10539 bool found_child = (dwarf_child(
const_cast<Dwarf_Die*
>(die),
10545 tag = dwarf_tag(child);
10547 if (!(tag == DW_TAG_member
10548 || tag == DW_TAG_inheritance
10549 || tag == DW_TAG_subprogram))
10550 found_child = get_next_member_sibling_die(child, child);
10552 return found_child;
10575maybe_propagate_canonical_type(
const reader& rdr,
10576 const Dwarf_Die* l,
10577 const Dwarf_Die* r)
10579 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10580 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10582 if (l_tag != r_tag)
10585 if (is_canon_type_to_be_propagated_tag(l_tag))
10586 propagate_canonical_type(rdr, l, r);
10604propagate_canonical_type(
const reader& rdr,
10605 const Dwarf_Die* l,
10606 const Dwarf_Die* r)
10615 const die_source l_source = rdr.get_die_source(l);
10616 const die_source r_source = rdr.get_die_source(r);
10618 Dwarf_Off l_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l));
10619 Dwarf_Off r_offset = dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r));
10620 bool l_has_canonical_die_offset =
false;
10621 bool r_has_canonical_die_offset =
false;
10622 Dwarf_Off l_canonical_die_offset = 0;
10623 Dwarf_Off r_canonical_die_offset = 0;
10625 l_has_canonical_die_offset =
10626 (l_canonical_die_offset =
10627 rdr.get_canonical_die_offset(l_offset, l_source,
10630 r_has_canonical_die_offset =
10631 (r_canonical_die_offset =
10632 rdr.get_canonical_die_offset(r_offset, r_source,
10636 if (!l_has_canonical_die_offset
10637 && r_has_canonical_die_offset
10640 && l_source == r_source)
10643 rdr.set_canonical_die_offset(l, r_canonical_die_offset,
10645 offset_type l_off = {l_source, l_offset}, r_off = {r_source, r_offset};
10646 rdr.propagated_types_.insert(std::make_pair(l_off,r_off));
10647 rdr.canonical_propagated_count_++;
10685return_comparison_result(
const Dwarf_Die* l,
10686 const Dwarf_Die* r,
10689 offset_pairs_stack_type& comparison_stack,
10690 bool do_propagate_canonical_type =
true)
10692 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l));
10694 if (result == COMPARISON_RESULT_EQUAL)
10699 if (do_propagate_canonical_type)
10702 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10708 else if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10721 else if (result == COMPARISON_RESULT_UNKNOWN)
10762 if (comparison_stack.is_redundant(cur_dies)
10763 && comparison_stack.vect_.back() == cur_dies)
10767 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10768 comparison_stack.confirm_canonical_propagated_type(cur_dies);
10770 result = COMPARISON_RESULT_EQUAL;
10772 else if (is_canon_type_to_be_propagated_tag(l_tag)
10773 && comparison_stack.vect_.back() == cur_dies)
10778 ABG_ASSERT(comparison_stack.depends_on_redundant_types(cur_dies));
10779 maybe_propagate_canonical_type(comparison_stack.rdr_, l, r);
10783 else if (result == COMPARISON_RESULT_DIFFERENT)
10800 if (comparison_stack.is_redundant(cur_dies)
10801 && comparison_stack.vect_.back() == cur_dies)
10802 comparison_stack.cancel_canonical_propagated_type(cur_dies);
10810 if (result == COMPARISON_RESULT_CYCLE_DETECTED)
10811 result = COMPARISON_RESULT_UNKNOWN;
10812 else if (is_canon_type_to_be_propagated_tag(l_tag)
10813 && !comparison_stack.vect_.empty()
10814 && comparison_stack.vect_.back() == cur_dies)
10819 comparison_stack.erase(cur_dies);
10821 maybe_cache_type_comparison_result(comparison_stack.rdr_,
10822 l_tag, cur_dies, result);
10851compare_dies(
const reader& rdr,
10852 const Dwarf_Die *l,
const Dwarf_Die *r,
10853 offset_pairs_stack_type& aggregates_being_compared,
10854 bool update_canonical_dies_on_the_fly)
10859 const die_source l_die_source = rdr.get_die_source(l);
10860 const die_source r_die_source = rdr.get_die_source(r);
10862 offset_type l_offset =
10865 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
10868 offset_type r_offset =
10871 dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
10876 int l_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(l)),
10877 r_tag = dwarf_tag(
const_cast<Dwarf_Die*
>(r));
10879 if (l_tag != r_tag)
10882 if (l_offset == r_offset)
10883 return COMPARISON_RESULT_EQUAL;
10885 if (rdr.leverage_dwarf_factorization()
10886 && (l_die_source == ALT_DEBUG_INFO_DIE_SOURCE
10887 && r_die_source == ALT_DEBUG_INFO_DIE_SOURCE))
10888 if (l_offset != r_offset)
10889 return COMPARISON_RESULT_DIFFERENT;
10892 if (maybe_get_cached_type_comparison_result(rdr, l_tag,
10893 dies_being_compared,
10897 Dwarf_Off l_canonical_die_offset = 0, r_canonical_die_offset = 0;
10898 bool l_has_canonical_die_offset =
false, r_has_canonical_die_offset =
false;
10902 if (is_type_die_to_be_canonicalized(l) && is_type_die_to_be_canonicalized(r))
10904 bool canonical_compare_result =
false;
10905 if (try_canonical_die_comparison(rdr, l_offset, r_offset,
10906 l_die_source, r_die_source,
10907 l_has_canonical_die_offset,
10908 r_has_canonical_die_offset,
10909 l_canonical_die_offset,
10910 r_canonical_die_offset,
10911 canonical_compare_result))
10915 (canonical_compare_result
10916 ? COMPARISON_RESULT_EQUAL
10917 : COMPARISON_RESULT_DIFFERENT),
10927 case DW_TAG_base_type:
10928 case DW_TAG_string_type:
10929 case DW_TAG_unspecified_type:
10930 if (!compare_as_decl_and_type_dies(rdr, l, r))
10934 case DW_TAG_typedef:
10935 case DW_TAG_pointer_type:
10936 case DW_TAG_reference_type:
10937 case DW_TAG_rvalue_reference_type:
10938 case DW_TAG_const_type:
10939 case DW_TAG_volatile_type:
10940 case DW_TAG_restrict_type:
10942 if (!compare_as_type_dies(rdr, l, r))
10948 bool from_the_same_tu =
false;
10949 if (!pointer_or_qual_die_of_anonymous_class_type(l)
10950 && compare_dies_cu_decl_file(l, r, from_the_same_tu)
10951 && from_the_same_tu)
10968 Dwarf_Die lu_type_die, ru_type_die;
10969 bool lu_is_void, ru_is_void;
10971 lu_is_void = !die_die_attribute(l, DW_AT_type, lu_type_die);
10972 ru_is_void = !die_die_attribute(r, DW_AT_type, ru_type_die);
10974 if (lu_is_void && ru_is_void)
10975 result = COMPARISON_RESULT_EQUAL;
10976 else if (lu_is_void != ru_is_void)
10979 result = compare_dies(rdr, &lu_type_die, &ru_type_die,
10980 aggregates_being_compared,
10981 update_canonical_dies_on_the_fly);
10985 case DW_TAG_enumeration_type:
10986 if (!compare_as_decl_and_type_dies(rdr, l, r))
10991 Dwarf_Die l_enumtor, r_enumtor;
10992 bool found_l_enumtor =
true, found_r_enumtor =
true;
10994 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
10995 for (found_l_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(l),
10997 found_r_enumtor = dwarf_child(
const_cast<Dwarf_Die*
>(r),
10999 found_l_enumtor && found_r_enumtor;
11000 found_l_enumtor = dwarf_siblingof(&l_enumtor, &l_enumtor) == 0,
11001 found_r_enumtor = dwarf_siblingof(&r_enumtor, &r_enumtor) == 0)
11003 int l_tag = dwarf_tag(&l_enumtor), r_tag = dwarf_tag(&r_enumtor);
11004 if ( l_tag != r_tag)
11010 if (l_tag != DW_TAG_enumerator)
11013 uint64_t l_val = 0, r_val = 0;
11014 die_unsigned_constant_attribute(&l_enumtor,
11017 die_unsigned_constant_attribute(&r_enumtor,
11020 if (l_val != r_val)
11026 if (found_l_enumtor != found_r_enumtor )
11031 case DW_TAG_structure_type:
11032 case DW_TAG_union_type:
11033 case DW_TAG_class_type:
11035 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11037 rdr.compare_count_++;
11039 if (!compare_as_decl_and_type_dies(rdr, l, r))
11041 else if (rdr.options().assume_odr_for_cplusplus
11042 && rdr.odr_is_relevant(l)
11043 && rdr.odr_is_relevant(r)
11044 && !die_is_anonymous(l)
11045 && !die_is_anonymous(r))
11046 result = COMPARISON_RESULT_EQUAL;
11049 aggregates_being_compared.add(dies_being_compared);
11051 Dwarf_Die l_member, r_member;
11052 bool found_l_member =
true, found_r_member =
true;
11054 if (!at_least_one_decl_only_among_odr_relevant_dies(rdr, l, r))
11055 for (found_l_member = get_member_child_die(l, &l_member),
11056 found_r_member = get_member_child_die(r, &r_member);
11057 found_l_member && found_r_member;
11058 found_l_member = get_next_member_sibling_die(&l_member,
11060 found_r_member = get_next_member_sibling_die(&r_member,
11063 int l_tag = dwarf_tag(&l_member),
11064 r_tag = dwarf_tag(&r_member);
11066 if (l_tag != r_tag)
11073 || l_tag == DW_TAG_variable
11074 || l_tag == DW_TAG_inheritance
11075 || l_tag == DW_TAG_subprogram);
11078 compare_dies(rdr, &l_member, &r_member,
11079 aggregates_being_compared,
11080 update_canonical_dies_on_the_fly);
11082 if (local_result == COMPARISON_RESULT_UNKNOWN)
11091 result = local_result;
11093 if (local_result == COMPARISON_RESULT_DIFFERENT)
11099 if (found_l_member != found_r_member)
11108 case DW_TAG_array_type:
11110 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11112 aggregates_being_compared.add(dies_being_compared);
11114 rdr.compare_count_++;
11116 Dwarf_Die l_child, r_child;
11117 bool found_l_child, found_r_child;
11118 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11120 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11122 found_l_child && found_r_child;
11123 found_l_child = dwarf_siblingof(&l_child, &l_child) == 0,
11124 found_r_child = dwarf_siblingof(&r_child, &r_child) == 0)
11126 int l_child_tag = dwarf_tag(&l_child),
11127 r_child_tag = dwarf_tag(&r_child);
11128 if (l_child_tag == DW_TAG_subrange_type
11129 || r_child_tag == DW_TAG_subrange_type)
11131 result = compare_dies(rdr, &l_child, &r_child,
11132 aggregates_being_compared,
11133 update_canonical_dies_on_the_fly);
11141 if (found_l_child != found_r_child)
11144 Dwarf_Die ltype_die, rtype_die;
11145 bool found_ltype = die_die_attribute(l, DW_AT_type, ltype_die);
11146 bool found_rtype = die_die_attribute(r, DW_AT_type, rtype_die);
11149 result = compare_dies(rdr, <ype_die, &rtype_die,
11150 aggregates_being_compared,
11151 update_canonical_dies_on_the_fly);
11157 case DW_TAG_subrange_type:
11159 uint64_t l_lower_bound = 0, r_lower_bound = 0,
11160 l_upper_bound = 0, r_upper_bound = 0;
11161 bool l_lower_bound_set =
false, r_lower_bound_set =
false,
11162 l_upper_bound_set =
false, r_upper_bound_set =
false;
11164 l_lower_bound_set =
11165 die_unsigned_constant_attribute(l, DW_AT_lower_bound, l_lower_bound);
11166 r_lower_bound_set =
11167 die_unsigned_constant_attribute(r, DW_AT_lower_bound, r_lower_bound);
11169 if (!die_unsigned_constant_attribute(l, DW_AT_upper_bound,
11172 uint64_t l_count = 0;
11173 if (die_unsigned_constant_attribute(l, DW_AT_count, l_count))
11175 l_upper_bound = l_lower_bound + l_count;
11176 l_upper_bound_set =
true;
11182 l_upper_bound_set =
true;
11184 if (!die_unsigned_constant_attribute(r, DW_AT_upper_bound,
11187 uint64_t r_count = 0;
11188 if (die_unsigned_constant_attribute(l, DW_AT_count, r_count))
11190 r_upper_bound = r_lower_bound + r_count;
11191 r_upper_bound_set =
true;
11197 r_upper_bound_set =
true;
11199 if ((l_lower_bound_set != r_lower_bound_set)
11200 || (l_upper_bound_set != r_upper_bound_set)
11201 || (l_lower_bound != r_lower_bound)
11202 || (l_upper_bound != r_upper_bound))
11207 case DW_TAG_subroutine_type:
11208 case DW_TAG_subprogram:
11210 RETURN_IF_COMPARISON_CYCLE_DETECTED;
11212 aggregates_being_compared.add(dies_being_compared);
11214 rdr.compare_count_++;
11216 if (l_tag == DW_TAG_subprogram
11217 && !fn_die_equal_by_linkage_name(rdr, l, r))
11222 else if (l_tag == DW_TAG_subprogram
11223 && rdr.die_is_in_c(l) && rdr.die_is_in_c(r)
11226 result = COMPARISON_RESULT_EQUAL;
11229 else if (!rdr.die_is_in_c(l) && !rdr.die_is_in_c(r))
11235 Dwarf_Die l_return_type, r_return_type;
11236 bool l_return_type_is_void = !die_die_attribute(l, DW_AT_type,
11238 bool r_return_type_is_void = !die_die_attribute(r, DW_AT_type,
11240 if (l_return_type_is_void != r_return_type_is_void
11241 || (!l_return_type_is_void
11242 && !compare_dies(rdr,
11243 &l_return_type, &r_return_type,
11244 aggregates_being_compared,
11245 update_canonical_dies_on_the_fly)))
11249 Dwarf_Die l_child, r_child;
11250 bool found_l_child, found_r_child;
11251 for (found_l_child = dwarf_child(
const_cast<Dwarf_Die*
>(l),
11253 found_r_child = dwarf_child(
const_cast<Dwarf_Die*
>(r),
11255 found_l_child && found_r_child;
11256 found_l_child = dwarf_siblingof(&l_child,
11258 found_r_child = dwarf_siblingof(&r_child,
11261 int l_child_tag = dwarf_tag(&l_child);
11262 int r_child_tag = dwarf_tag(&r_child);
11264 COMPARISON_RESULT_EQUAL;
11265 if (l_child_tag != r_child_tag)
11266 local_result = COMPARISON_RESULT_DIFFERENT;
11267 if (l_child_tag == DW_TAG_formal_parameter)
11269 compare_dies(rdr, &l_child, &r_child,
11270 aggregates_being_compared,
11271 update_canonical_dies_on_the_fly);
11272 if (local_result == COMPARISON_RESULT_DIFFERENT)
11274 result = local_result;
11278 if (local_result == COMPARISON_RESULT_UNKNOWN)
11289 result = local_result;
11291 if (found_l_child != found_r_child)
11301 case DW_TAG_formal_parameter:
11303 Dwarf_Die l_type, r_type;
11304 bool l_type_is_void = !die_die_attribute(l, DW_AT_type, l_type);
11305 bool r_type_is_void = !die_die_attribute(r, DW_AT_type, r_type);
11306 if (l_type_is_void != r_type_is_void)
11308 else if (!l_type_is_void)
11311 compare_dies(rdr, &l_type, &r_type,
11312 aggregates_being_compared,
11313 update_canonical_dies_on_the_fly);
11319 case DW_TAG_variable:
11320 case DW_TAG_member:
11321 if (compare_as_decl_dies(l, r))
11324 if (l_tag == DW_TAG_member)
11326 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11327 die_member_offset(rdr, l, l_offset_in_bits);
11328 die_member_offset(rdr, r, r_offset_in_bits);
11329 if (l_offset_in_bits != r_offset_in_bits)
11335 Dwarf_Die l_type, r_type;
11336 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11337 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11339 compare_dies(rdr, &l_type, &r_type,
11340 aggregates_being_compared,
11341 update_canonical_dies_on_the_fly);
11349 case DW_TAG_inheritance:
11351 Dwarf_Die l_type, r_type;
11352 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11353 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11354 result = compare_dies(rdr, &l_type, &r_type,
11355 aggregates_being_compared,
11356 update_canonical_dies_on_the_fly);
11360 uint64_t l_a = 0, r_a = 0;
11361 die_unsigned_constant_attribute(l, DW_AT_accessibility, l_a);
11362 die_unsigned_constant_attribute(r, DW_AT_accessibility, r_a);
11366 die_unsigned_constant_attribute(l, DW_AT_virtuality, l_a);
11367 die_unsigned_constant_attribute(r, DW_AT_virtuality, r_a);
11371 int64_t l_offset_in_bits = 0, r_offset_in_bits = 0;
11372 die_member_offset(rdr, l, l_offset_in_bits);
11373 die_member_offset(rdr, r, r_offset_in_bits);
11374 if (l_offset_in_bits != r_offset_in_bits)
11379 case DW_TAG_ptr_to_member_type:
11381 bool comp_result =
false;
11382 if (compare_dies_string_attribute_value(l, r, DW_AT_name, comp_result))
11386 Dwarf_Die l_type, r_type;
11387 ABG_ASSERT(die_die_attribute(l, DW_AT_type, l_type));
11388 ABG_ASSERT(die_die_attribute(r, DW_AT_type, r_type));
11389 result = compare_dies(rdr, &l_type, &r_type,
11390 aggregates_being_compared,
11391 update_canonical_dies_on_the_fly);
11395 ABG_ASSERT(die_die_attribute(l, DW_AT_containing_type, l_type));
11396 ABG_ASSERT(die_die_attribute(r, DW_AT_containing_type, r_type));
11397 result = compare_dies(rdr, &l_type, &r_type,
11398 aggregates_being_compared,
11399 update_canonical_dies_on_the_fly);
11405 case DW_TAG_enumerator:
11406 case DW_TAG_packed_type:
11407 case DW_TAG_set_type:
11408 case DW_TAG_file_type:
11409 case DW_TAG_thrown_type:
11410 case DW_TAG_interface_type:
11411 case DW_TAG_shared_type:
11412 case DW_TAG_compile_unit:
11413 case DW_TAG_namespace:
11414 case DW_TAG_module:
11415 case DW_TAG_constant:
11416 case DW_TAG_partial_unit:
11417 case DW_TAG_imported_unit:
11418 case DW_TAG_dwarf_procedure:
11419 case DW_TAG_imported_declaration:
11420 case DW_TAG_entry_point:
11422 case DW_TAG_lexical_block:
11423 case DW_TAG_unspecified_parameters:
11424 case DW_TAG_variant:
11425 case DW_TAG_common_block:
11426 case DW_TAG_common_inclusion:
11427 case DW_TAG_inlined_subroutine:
11428 case DW_TAG_with_stmt:
11429 case DW_TAG_access_declaration:
11430 case DW_TAG_catch_block:
11431 case DW_TAG_friend:
11432 case DW_TAG_namelist:
11433 case DW_TAG_namelist_item:
11434 case DW_TAG_template_type_parameter:
11435 case DW_TAG_template_value_parameter:
11436 case DW_TAG_try_block:
11437 case DW_TAG_variant_part:
11438 case DW_TAG_imported_module:
11439 case DW_TAG_condition:
11440 case DW_TAG_type_unit:
11441 case DW_TAG_template_alias:
11442 case DW_TAG_lo_user:
11443 case DW_TAG_MIPS_loop:
11444 case DW_TAG_format_label:
11445 case DW_TAG_function_template:
11446 case DW_TAG_class_template:
11447 case DW_TAG_GNU_BINCL:
11448 case DW_TAG_GNU_EINCL:
11449 case DW_TAG_GNU_template_template_param:
11450 case DW_TAG_GNU_template_parameter_pack:
11451 case DW_TAG_GNU_formal_parameter_pack:
11452 case DW_TAG_GNU_call_site:
11453 case DW_TAG_GNU_call_site_parameter:
11454 case DW_TAG_hi_user:
11455#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11456 if (rdr.debug_die_canonicalization_is_on_)
11483compare_dies(
const reader& rdr,
11484 const Dwarf_Die *l,
11485 const Dwarf_Die *r,
11486 bool update_canonical_dies_on_the_fly)
11488 offset_pairs_stack_type aggregates_being_compared(rdr);
11489 return compare_dies(rdr, l, r, aggregates_being_compared,
11490 update_canonical_dies_on_the_fly);
11512compare_dies_during_canonicalization(reader& rdr,
11513 const Dwarf_Die *l,
11514 const Dwarf_Die *r,
11515 bool update_canonical_dies_on_the_fly)
11517#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
11518 if (rdr.debug_die_canonicalization_is_on_)
11520 bool canonical_equality =
false, structural_equality =
false;
11521 rdr.use_canonical_die_comparison_ =
false;
11522 structural_equality = compare_dies(rdr, l, r,
11524 rdr.use_canonical_die_comparison_ =
true;
11525 canonical_equality = compare_dies(rdr, l, r,
11526 update_canonical_dies_on_the_fly);
11527 if (canonical_equality != structural_equality)
11529 std::cerr <<
"structural & canonical equality different for DIEs: "
11531 <<
"l: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(l))
11532 <<
", r: " << dwarf_dieoffset(
const_cast<Dwarf_Die*
>(r))
11535 << rdr.get_die_pretty_type_representation(l, 0)
11540 return structural_equality;
11543 return compare_dies(rdr, l, r,
11544 update_canonical_dies_on_the_fly);
11586find_import_unit_point_between_dies(
const reader& rdr,
11587 size_t partial_unit_offset,
11588 Dwarf_Off first_die_offset,
11589 Dwarf_Off first_die_cu_offset,
11591 size_t last_die_offset,
11592 size_t& imported_point_offset)
11595 rdr.tu_die_imported_unit_points_map(source);
11597 tu_die_imported_unit_points_map_type::const_iterator iter =
11598 tu_die_imported_unit_points_map.find(first_die_cu_offset);
11600 ABG_ASSERT(iter != tu_die_imported_unit_points_map.end());
11603 if (imported_unit_points.empty())
11606 imported_unit_points_type::const_iterator b = imported_unit_points.begin();
11607 imported_unit_points_type::const_iterator e = imported_unit_points.end();
11609 find_lower_bound_in_imported_unit_points(imported_unit_points,
11613 if (last_die_offset !=
static_cast<size_t>(-1))
11614 find_lower_bound_in_imported_unit_points(imported_unit_points,
11618 if (e != imported_unit_points.end())
11620 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11621 if (i->imported_unit_die_off == partial_unit_offset)
11623 imported_point_offset = i->offset_of_import ;
11627 for (imported_unit_points_type::const_iterator i = e; i >= b; --i)
11629 if (find_import_unit_point_between_dies(rdr,
11630 partial_unit_offset,
11631 i->imported_unit_child_off,
11632 i->imported_unit_cu_off,
11633 i->imported_unit_die_source,
11635 imported_point_offset))
11641 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11642 if (i->imported_unit_die_off == partial_unit_offset)
11644 imported_point_offset = i->offset_of_import ;
11648 for (imported_unit_points_type::const_iterator i = b; i != e; ++i)
11650 if (find_import_unit_point_between_dies(rdr,
11651 partial_unit_offset,
11652 i->imported_unit_child_off,
11653 i->imported_unit_cu_off,
11654 i->imported_unit_die_source,
11656 imported_point_offset))
11689find_import_unit_point_before_die(
const reader& rdr,
11690 size_t partial_unit_offset,
11691 size_t where_offset,
11692 size_t& imported_point_offset)
11694 size_t import_point_offset = 0;
11695 Dwarf_Die first_die_of_tu;
11697 if (dwarf_child(
const_cast<Dwarf_Die*
>(rdr.cur_tu_die()),
11698 &first_die_of_tu) != 0)
11701 Dwarf_Die cu_die_memory;
11704 cu_die = dwarf_diecu(
const_cast<Dwarf_Die*
>(&first_die_of_tu),
11705 &cu_die_memory, 0, 0);
11707 if (find_import_unit_point_between_dies(rdr, partial_unit_offset,
11708 dwarf_dieoffset(&first_die_of_tu),
11709 dwarf_dieoffset(cu_die),
11710 PRIMARY_DEBUG_INFO_DIE_SOURCE,
11712 import_point_offset))
11714 imported_point_offset = import_point_offset;
11718 if (import_point_offset)
11720 imported_point_offset = import_point_offset;
11748get_parent_die(
const reader& rdr,
11749 const Dwarf_Die* die,
11750 Dwarf_Die& parent_die,
11751 size_t where_offset)
11755 const die_source source = rdr.get_die_source(die);
11758 offset_offset_map_type::const_iterator i =
11759 m.find(dwarf_dieoffset(
const_cast<Dwarf_Die*
>(die)));
11766 case PRIMARY_DEBUG_INFO_DIE_SOURCE:
11767 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11768 i->second, &parent_die));
11770 case ALT_DEBUG_INFO_DIE_SOURCE:
11771 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.alternate_dwarf_debug_info()),
11772 i->second, &parent_die));
11774 case TYPE_UNIT_DIE_SOURCE:
11775 ABG_ASSERT(dwarf_offdie_types(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11776 i->second, &parent_die));
11778 case NO_DEBUG_INFO_DIE_SOURCE:
11779 case NUMBER_OF_DIE_SOURCES:
11783 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit)
11785 if (where_offset == 0)
11787 parent_die = *rdr.cur_tu_die();
11790 size_t import_point_offset = 0;
11792 find_import_unit_point_before_die(rdr,
11793 dwarf_dieoffset(&parent_die),
11795 import_point_offset);
11801 parent_die = *rdr.cur_tu_die();
11805 Dwarf_Die import_point_die;
11806 ABG_ASSERT(dwarf_offdie(
const_cast<Dwarf*
>(rdr.dwarf_debug_info()),
11807 import_point_offset,
11808 &import_point_die));
11809 return get_parent_die(rdr, &import_point_die,
11810 parent_die, where_offset);
11843get_scope_die(
const reader& rdr,
11844 const Dwarf_Die* dye,
11845 size_t where_offset,
11846 Dwarf_Die& scope_die)
11848 Dwarf_Die origin_die_mem;
11849 Dwarf_Die *die = &origin_die_mem;
11850 if (!die_origin_die(dye, origin_die_mem))
11851 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
11854 rdr.get_die_language(die, die_lang);
11856 || rdr.die_parent_map(rdr.get_die_source(die)).empty())
11858 ABG_ASSERT(dwarf_tag(
const_cast<Dwarf_Die*
>(die)) != DW_TAG_member);
11859 return dwarf_diecu(
const_cast<Dwarf_Die*
>(die), &scope_die, 0, 0);
11862 if (!get_parent_die(rdr, die, scope_die, where_offset))
11865 if (dwarf_tag(&scope_die) == DW_TAG_subprogram
11866 || dwarf_tag(&scope_die) == DW_TAG_subroutine_type
11867 || dwarf_tag(&scope_die) == DW_TAG_array_type)
11868 return get_scope_die(rdr, &scope_die, where_offset, scope_die);
11898get_scope_for_die(reader& rdr,
11900 bool called_for_public_decl,
11901 size_t where_offset)
11903 Dwarf_Die origin_die_mem;
11904 Dwarf_Die *die = &origin_die_mem;
11906 if (!die_origin_die(dye, origin_die_mem))
11909 memcpy(&origin_die_mem, dye,
sizeof(origin_die_mem));
11911 const die_source source_of_die = rdr.get_die_source(die);
11914 rdr.get_die_language(die, die_lang);
11916 || rdr.die_parent_map(source_of_die).empty())
11921 ABG_ASSERT(dwarf_tag(die) != DW_TAG_member);
11922 return rdr.global_scope();
11925 Dwarf_Die parent_die;
11927 if (!get_parent_die(rdr, die, parent_die, where_offset))
11928 return rdr.nil_scope();
11930 if (dwarf_tag(&parent_die) == DW_TAG_compile_unit
11931 || dwarf_tag(&parent_die) == DW_TAG_partial_unit
11932 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11934 if (dwarf_tag(&parent_die) == DW_TAG_partial_unit
11935 || dwarf_tag(&parent_die) == DW_TAG_type_unit)
11937 ABG_ASSERT(source_of_die == ALT_DEBUG_INFO_DIE_SOURCE
11938 || source_of_die == TYPE_UNIT_DIE_SOURCE);
11939 return rdr.cur_transl_unit()->get_global_scope();
11948 die_tu_map_type::const_iterator i =
11949 rdr.die_tu_map().find(dwarf_dieoffset(&parent_die));
11950 if (i != rdr.die_tu_map().end())
11951 return i->second->get_global_scope();
11952 return rdr.cur_transl_unit()->get_global_scope();
11957 if (dwarf_tag(&parent_die) == DW_TAG_subprogram
11958 || dwarf_tag(&parent_die) == DW_TAG_array_type
11959 || dwarf_tag(&parent_die) == DW_TAG_lexical_block)
11971 called_for_public_decl,
11980 if (!get_parent_die(rdr, &parent_die, parent_die, where_offset))
11981 return rdr.nil_scope();
11982 s = get_scope_for_die(rdr, &parent_die,
11983 called_for_public_decl,
11989 d = build_ir_node_from_die(rdr, &parent_die,
11990 called_for_public_decl,
11992 s = dynamic_pointer_cast<scope_decl>(d);
11996 return rdr.nil_scope();
11999 if (cl && cl->get_is_declaration_only())
12002 dynamic_pointer_cast<scope_decl>(cl->get_definition_of_declaration());
12019dwarf_language_to_tu_language(
size_t l)
12024 return translation_unit::LANG_C89;
12026 return translation_unit::LANG_C;
12027 case DW_LANG_Ada83:
12028 return translation_unit::LANG_Ada83;
12029 case DW_LANG_C_plus_plus:
12030 return translation_unit::LANG_C_plus_plus;
12031 case DW_LANG_Cobol74:
12032 return translation_unit::LANG_Cobol74;
12033 case DW_LANG_Cobol85:
12034 return translation_unit::LANG_Cobol85;
12035 case DW_LANG_Fortran77:
12036 return translation_unit::LANG_Fortran77;
12037 case DW_LANG_Fortran90:
12038 return translation_unit::LANG_Fortran90;
12039 case DW_LANG_Pascal83:
12040 return translation_unit::LANG_Pascal83;
12041 case DW_LANG_Modula2:
12042 return translation_unit::LANG_Modula2;
12044 return translation_unit::LANG_Java;
12046 return translation_unit::LANG_C99;
12047 case DW_LANG_Ada95:
12048 return translation_unit::LANG_Ada95;
12049 case DW_LANG_Fortran95:
12050 return translation_unit::LANG_Fortran95;
12052 return translation_unit::LANG_PLI;
12054 return translation_unit::LANG_ObjC;
12055 case DW_LANG_ObjC_plus_plus:
12056 return translation_unit::LANG_ObjC_plus_plus;
12058#ifdef HAVE_DW_LANG_Rust_enumerator
12060 return translation_unit::LANG_Rust;
12063#ifdef HAVE_DW_LANG_UPC_enumerator
12065 return translation_unit::LANG_UPC;
12068#ifdef HAVE_DW_LANG_D_enumerator
12070 return translation_unit::LANG_D;
12073#ifdef HAVE_DW_LANG_Python_enumerator
12074 case DW_LANG_Python:
12075 return translation_unit::LANG_Python;
12078#ifdef HAVE_DW_LANG_Go_enumerator
12080 return translation_unit::LANG_Go;
12083#ifdef HAVE_DW_LANG_C11_enumerator
12085 return translation_unit::LANG_C11;
12088#ifdef HAVE_DW_LANG_C_plus_plus_03_enumerator
12089 case DW_LANG_C_plus_plus_03:
12090 return translation_unit::LANG_C_plus_plus_03;
12093#ifdef HAVE_DW_LANG_C_plus_plus_11_enumerator
12094 case DW_LANG_C_plus_plus_11:
12095 return translation_unit::LANG_C_plus_plus_11;
12098#ifdef HAVE_DW_LANG_C_plus_plus_14_enumerator
12099 case DW_LANG_C_plus_plus_14:
12100 return translation_unit::LANG_C_plus_plus_14;
12103#ifdef HAVE_DW_LANG_Mips_Assembler_enumerator
12104 case DW_LANG_Mips_Assembler:
12105 return translation_unit::LANG_Mips_Assembler;
12109 return translation_unit::LANG_UNKNOWN;
12126 case translation_unit::LANG_UNKNOWN:
12129 case translation_unit::LANG_Cobol74:
12130 case translation_unit::LANG_Cobol85:
12133 case translation_unit::LANG_C89:
12134 case translation_unit::LANG_C99:
12135 case translation_unit::LANG_C11:
12136 case translation_unit::LANG_C:
12137 case translation_unit::LANG_C_plus_plus_03:
12138 case translation_unit::LANG_C_plus_plus_11:
12139 case translation_unit::LANG_C_plus_plus_14:
12140 case translation_unit::LANG_C_plus_plus:
12141 case translation_unit::LANG_ObjC:
12142 case translation_unit::LANG_ObjC_plus_plus:
12143 case translation_unit::LANG_Rust:
12146 case translation_unit::LANG_Fortran77:
12147 case translation_unit::LANG_Fortran90:
12148 case translation_unit::LANG_Fortran95:
12149 case translation_unit::LANG_Ada83:
12150 case translation_unit::LANG_Ada95:
12151 case translation_unit::LANG_Pascal83:
12152 case translation_unit::LANG_Modula2:
12155 case translation_unit::LANG_Java:
12158 case translation_unit::LANG_PLI:
12161 case translation_unit::LANG_UPC:
12162 case translation_unit::LANG_D:
12163 case translation_unit::LANG_Python:
12164 case translation_unit::LANG_Go:
12165 case translation_unit::LANG_Mips_Assembler:
12192 imported_unit_points_type::const_iterator& r)
12194 imported_unit_point v(val);
12195 imported_unit_points_type::const_iterator result =
12196 std::lower_bound(p.begin(), p.end(), v);
12198 bool is_ok = result != p.end();
12220build_translation_unit_and_add_to_ir(reader& rdr,
12228 ABG_ASSERT(dwarf_tag(die) == DW_TAG_compile_unit);
12232 rdr.clear_per_translation_unit_data();
12234 rdr.cur_tu_die(die);
12236 string path = die_string_attribute(die, DW_AT_name);
12237 if (path ==
"<artificial>")
12243 std::ostringstream o;
12244 o << path <<
"-" << std::hex << dwarf_dieoffset(die);
12247 string compilation_dir = die_string_attribute(die, DW_AT_comp_dir);
12257 const string& abs_path =
12258 compilation_dir.empty() ? path : compilation_dir +
"/" + path;
12259 result = rdr.corpus()->find_translation_unit(abs_path);
12264 result.reset(
new translation_unit(rdr.env(),
12267 result->set_compilation_dir_path(compilation_dir);
12268 rdr.corpus()->add(result);
12270 die_unsigned_constant_attribute(die, DW_AT_language, l);
12271 result->set_language(dwarf_language_to_tu_language(l));
12274 rdr.cur_transl_unit(result);
12275 rdr.die_tu_map()[dwarf_dieoffset(die)] = result;
12278 if (dwarf_child(die, &child) != 0)
12281 result->set_is_constructed(
false);
12286 if (!rdr.env().analyze_exported_interfaces_only()
12287 || rdr.is_decl_die_with_exported_symbol(&child))
12288 build_ir_node_from_die(rdr, &child,
12289 die_is_public_decl(&child),
12290 dwarf_dieoffset(&child));
12291 while (dwarf_siblingof(&child, &child) == 0);
12293 if (!rdr.var_decls_to_re_add_to_tree().empty())
12294 for (list<var_decl_sptr>::const_iterator v =
12295 rdr.var_decls_to_re_add_to_tree().begin();
12296 v != rdr.var_decls_to_re_add_to_tree().end();
12303 string demangled_name =
12305 if (!demangled_name.empty())
12307 std::list<string> fqn_comps;
12309 string mem_name = fqn_comps.back();
12310 fqn_comps.pop_back();
12313 if (!fqn_comps.empty())
12341 ABG_ASSERT(dynamic_pointer_cast<var_decl>(d));
12347 rdr.var_decls_to_re_add_to_tree().clear();
12349 result->set_is_constructed(
true);
12374build_namespace_decl_and_add_to_ir(reader& rdr,
12376 size_t where_offset)
12383 unsigned tag = dwarf_tag(die);
12384 if (tag != DW_TAG_namespace && tag != DW_TAG_module)
12391 string name, linkage_name;
12393 die_loc_and_name(rdr, die, loc, name, linkage_name);
12395 result.reset(
new namespace_decl(rdr.env(), name, loc));
12397 rdr.associate_die_to_decl(die, result, where_offset);
12400 if (dwarf_child(die, &child) != 0)
12403 rdr.scope_stack().push(result.get());
12405 build_ir_node_from_die(rdr, &child,
12411 die_is_public_decl(die) && die_is_public_decl(&child),
12413 while (dwarf_siblingof(&child, &child) == 0);
12414 rdr.scope_stack().pop();
12429build_type_decl(reader& rdr, Dwarf_Die* die,
size_t where_offset)
12435 ABG_ASSERT(dwarf_tag(die) == DW_TAG_base_type);
12437 uint64_t byte_size = 0, bit_size = 0;
12438 if (!die_unsigned_constant_attribute(die, DW_AT_byte_size, byte_size))
12439 if (!die_unsigned_constant_attribute(die, DW_AT_bit_size, bit_size))
12442 if (bit_size == 0 && byte_size != 0)
12444 bit_size = byte_size * 8;
12446 string type_name, linkage_name;
12448 die_loc_and_name(rdr, die, loc, type_name, linkage_name);
12450 if (byte_size == 0)
12454 if (type_name ==
"void")
12455 result =
is_type_decl(build_ir_node_for_void_type(rdr));
12462 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12464 string normalized_type_name = type_name;
12465 integral_type int_type;
12467 normalized_type_name = int_type.
to_string();
12472 if (corpus_sptr corp = rdr.corpus())
12475 result.reset(
new type_decl(rdr.env(), type_name, bit_size,
12476 0, loc, linkage_name));
12477 rdr.associate_die_to_type(die, result, where_offset);
12495build_enum_underlying_type(reader& rdr,
12497 uint64_t enum_size,
12498 bool is_anonymous =
true)
12500 string underlying_type_name =
12504 type_decl_sptr result(
new type_decl(rdr.env(), underlying_type_name,
12505 enum_size, enum_size, location()));
12506 result->set_is_anonymous(is_anonymous);
12507 result->set_is_artificial(
true);
12510 result = dynamic_pointer_cast<type_decl>(d);
12531build_enum_type(reader& rdr,
12534 size_t where_offset,
12535 bool is_declaration_only)
12541 unsigned tag = dwarf_tag(die);
12542 if (tag != DW_TAG_enumeration_type)
12545 string name, linkage_name;
12547 die_loc_and_name(rdr, die, loc, name, linkage_name);
12549 bool is_anonymous =
false;
12553 name = get_internal_anonymous_die_prefix_name(die);
12556 is_anonymous =
true;
12558 if (
size_t s = scope->get_num_anonymous_member_enums())
12559 name = build_internal_anonymous_die_name(name, s);
12562 bool use_odr = rdr.odr_is_relevant(die);
12574 result = pre_existing_enum;
12576 else if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
12585 if (pre_existing_enum->get_location() == loc)
12586 result = pre_existing_enum;
12591 rdr.associate_die_to_type(die, result, where_offset);
12599 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
12601 bool is_artificial = die_is_artificial(die);
12604 bool enum_underlying_type_is_anonymous=
true;
12608 if (dwarf_child(die, &child) == 0)
12612 if (dwarf_tag(&child) != DW_TAG_enumerator)
12617 die_loc_and_name(rdr, &child, l, n, m);
12619 die_unsigned_constant_attribute(&child, DW_AT_const_value, val);
12620 enms.push_back(enum_type_decl::enumerator(n, val));
12622 while (dwarf_siblingof(&child, &child) == 0);
12630 build_enum_underlying_type(rdr, name, size,
12631 enum_underlying_type_is_anonymous);
12632 t->set_is_declaration_only(is_declaration_only);
12634 result.reset(
new enum_type_decl(name, loc, t, enms, linkage_name));
12635 result->set_is_anonymous(is_anonymous);
12636 result->set_is_declaration_only(is_declaration_only);
12637 result->set_is_artificial(is_artificial);
12638 rdr.associate_die_to_type(die, result, where_offset);
12640 rdr.maybe_schedule_declaration_only_enum_for_resolution(result);
12659finish_member_function_reading(Dwarf_Die* die,
12661 const class_or_union_sptr klass,
12672 bool is_ctor = (f->get_name() == klass->get_name());
12673 bool is_dtor = (!f->get_name().empty()
12674 &&
static_cast<string>(f->get_name())[0] ==
'~');
12675 bool is_virtual = die_is_virtual(die);
12676 int64_t vindex = -1;
12678 die_virtual_function_index(die, vindex);
12681 if (!c->is_struct())
12682 access = private_access;
12683 die_access_specifier(die, access);
12685 bool is_static =
false;
12693 if (!f->get_parameters().empty())
12694 first_parm = f->get_parameters()[0];
12696 bool is_artificial = first_parm && first_parm->get_is_artificial();
12697 type_base_sptr this_ptr_type, other_klass;
12700 this_ptr_type = first_parm->get_type();
12707 this_ptr_type = q->get_underlying_type();
12711 other_klass = p->get_pointed_to_type();
12716 other_klass = q->get_underlying_type();
12719 &&
get_type_name(other_klass) == klass->get_qualified_name())
12730 Dwarf_Die object_pointer_die;
12731 if (die_has_object_pointer(die, object_pointer_die))
12747 if (is_virtual && !f->get_linkage_name().empty() && !f->get_symbol())
12766 Dwarf_Off die_offset = dwarf_dieoffset(die);
12768 rdr.die_function_decl_with_no_symbol_map();
12769 die_function_decl_map_type::const_iterator i =
12770 fns_with_no_symbol.find(die_offset);
12771 if (i == fns_with_no_symbol.end())
12772 fns_with_no_symbol[die_offset] = f;
12793maybe_finish_function_decl_reading(reader& rdr,
12795 size_t where_offset,
12813static type_base_sptr
12814lookup_class_or_typedef_from_corpus(scope_decl* scope,
const string& type_name)
12817 corpus* corp = scope->get_corpus();
12838static type_base_sptr
12839lookup_class_or_typedef_from_corpus(reader& rdr,
12841 bool called_for_public_decl,
12842 size_t where_offset)
12847 string class_name = die_string_attribute(die, DW_AT_name);
12848 if (class_name.empty())
12852 called_for_public_decl,
12855 return lookup_class_or_typedef_from_corpus(scope.get(), class_name);
12857 return type_base_sptr();
12868static type_base_sptr
12869lookup_class_typedef_or_enum_type_from_corpus(scope_decl* scope,
12870 const string& type_name)
12873 corpus* corp = scope->get_corpus();
12891static type_base_sptr
12892lookup_class_typedef_or_enum_type_from_corpus(Dwarf_Die* die,
12893 size_t anonymous_member_type_idx,
12899 string type_name = die_string_attribute(die, DW_AT_name);
12902 get_internal_anonymous_die_name(die, anonymous_member_type_idx);
12904 if (type_name.empty())
12907 return lookup_class_typedef_or_enum_type_from_corpus(scope, type_name);
12925static method_decl_sptr
12926is_function_for_die_a_member_of_class(reader& rdr,
12927 Dwarf_Die* function_die,
12928 const class_or_union_sptr& class_type)
12933 return method_decl_sptr();
12939 method_type = method->get_type();
12944 class_or_union_sptr method_class = method_type->get_class_type();
12947 string method_class_name = method_class->get_qualified_name(),
12948 class_type_name = class_type->get_qualified_name();
12950 if (method_class_name == class_type_name)
12956 return method_decl_sptr();
12978static method_decl_sptr
12979add_or_update_member_function(reader& rdr,
12980 Dwarf_Die* function_die,
12981 const class_or_union_sptr& class_type,
12982 bool called_from_public_decl,
12983 size_t where_offset)
12985 method_decl_sptr method =
12986 is_function_for_die_a_member_of_class(rdr, function_die, class_type);
12989 method =
is_method_decl(build_ir_node_from_die(rdr, function_die,
12991 called_from_public_decl,
12994 return method_decl_sptr();
12996 finish_member_function_reading(function_die,
13039add_or_update_class_type(reader& rdr,
13044 bool called_from_public_decl,
13045 size_t where_offset,
13046 bool is_declaration_only)
13052 const die_source source = rdr.get_die_source(die);
13054 unsigned tag = dwarf_tag(die);
13056 if (tag != DW_TAG_class_type && tag != DW_TAG_structure_type)
13060 die_class_or_union_map_type::const_iterator i =
13061 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13062 if (i != rdr.die_wip_classes_map(source).end())
13070 string name, linkage_name;
13072 die_loc_and_name(rdr, die, loc, name, linkage_name);
13074 bool is_anonymous =
false;
13079 name = get_internal_anonymous_die_prefix_name(die);
13082 is_anonymous =
true;
13084 if (
size_t s = scope->get_num_anonymous_member_classes())
13085 name = build_internal_anonymous_die_name(name, s);
13090 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13106 && (result->get_is_declaration_only() == is_declaration_only
13107 || (!result->get_is_declaration_only()
13108 && is_declaration_only)))
13110 rdr.associate_die_to_type(die, result, where_offset);
13129 klass = pre_existing_class;
13132 die_size_in_bits(die, size);
13133 bool is_artificial = die_is_artificial(die);
13136 bool has_child = (dwarf_child(die, &child) == 0);
13138 decl_base_sptr res;
13141 res = result = klass;
13142 if (has_child && klass->get_is_declaration_only()
13143 && klass->get_definition_of_declaration())
13144 res = result =
is_class_type(klass->get_definition_of_declaration());
13146 result->set_location(loc);
13150 result.reset(
new class_decl(rdr.env(), name, size,
13152 decl_base::VISIBILITY_DEFAULT,
13155 result->set_is_declaration_only(is_declaration_only);
13158 result = dynamic_pointer_cast<class_decl>(res);
13162 if (!klass || klass->get_is_declaration_only())
13163 if (size != result->get_size_in_bits())
13164 result->set_size_in_bits(size);
13169 if (!!result->get_size_in_bits() == result->get_is_declaration_only())
13182 result->set_is_declaration_only(is_declaration_only);
13186 if (!result->get_is_declaration_only() && has_child)
13187 if (result->get_size_in_bits() == 0 && size != 0)
13188 result->set_size_in_bits(size);
13190 result->set_is_artificial(is_artificial);
13192 rdr.associate_die_to_type(die, result, where_offset);
13194 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13201 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13203 bool is_incomplete_type =
false;
13204 if (is_declaration_only && size == 0 && has_child)
13216 is_incomplete_type =
true;
13219 dynamic_pointer_cast<scope_decl>(res);
13221 rdr.scope_stack().push(scop.get());
13223 if (has_child && !is_incomplete_type)
13225 int anonymous_member_class_index = -1;
13226 int anonymous_member_union_index = -1;
13227 int anonymous_member_enum_index = -1;
13231 tag = dwarf_tag(&child);
13234 if (tag == DW_TAG_inheritance)
13236 result->set_is_declaration_only(
false);
13238 Dwarf_Die type_die;
13239 if (!die_die_attribute(&child, DW_AT_type, type_die))
13242 type_base_sptr base_type;
13244 lookup_class_or_typedef_from_corpus(rdr, &type_die,
13245 called_from_public_decl,
13249 is_type(build_ir_node_from_die(rdr, &type_die,
13250 called_from_public_decl,
13264 die_access_specifier(&child, access);
13266 bool is_virt= die_is_virtual(&child);
13267 int64_t offset = 0;
13268 bool is_offset_present =
13269 die_member_offset(rdr, &child, offset);
13273 is_offset_present ? offset : -1,
13275 if (b->get_is_declaration_only()
13282 && !b->get_qualified_name().empty())
13283 ABG_ASSERT(rdr.is_decl_only_class_scheduled_for_resolution(b));
13284 if (result->find_base_class(b->get_qualified_name()))
13286 result->add_base_specifier(base);
13289 else if (tag == DW_TAG_member
13290 || tag == DW_TAG_variable)
13292 Dwarf_Die type_die;
13293 if (!die_die_attribute(&child, DW_AT_type, type_die))
13298 die_loc_and_name(rdr, &child, loc, n, m);
13303 if (n.substr(0, 5) ==
"_vptr"
13305 && !std::isalnum(n.at(5))
13315 int64_t offset_in_bits = 0;
13316 bool is_laid_out = die_member_offset(rdr, &child,
13321 bool is_static = !is_laid_out;
13323 if (is_static && variable_is_suppressed(rdr,
13328 decl_base_sptr ty =
is_decl(build_ir_node_from_die(rdr, &type_die,
13329 called_from_public_decl,
13331 type_base_sptr t =
is_type(ty);
13335 if (n.empty() && !die_is_anonymous_data_member(&child))
13341 n = rdr.build_name_for_buggy_anonymous_data_member(&child);
13358 result->set_is_declaration_only(
false);
13364 die_access_specifier(&child, access);
13372 result->add_data_member(dm, access, is_laid_out,
13373 is_static, offset_in_bits);
13375 rdr.associate_die_to_decl(&child, dm, where_offset,
13379 else if (tag == DW_TAG_subprogram)
13382 add_or_update_member_function(rdr, &child, result,
13383 called_from_public_decl,
13386 rdr.associate_die_to_decl(&child, f, where_offset,
13390 else if (die_is_type(&child))
13396 int anonymous_member_type_index = 0;
13400 if (die_is_class_type(&child))
13401 anonymous_member_type_index =
13402 ++anonymous_member_class_index;
13403 else if (dwarf_tag(&child) == DW_TAG_union_type)
13404 anonymous_member_type_index =
13405 ++anonymous_member_union_index;
13406 else if (dwarf_tag(&child) == DW_TAG_enumeration_type)
13407 anonymous_member_type_index =
13408 ++anonymous_member_enum_index;
13413 && !lookup_class_typedef_or_enum_type_from_corpus
13414 (&child, anonymous_member_type_index, result.get()))
13415 || !result->find_member_type(die_name(&child)))
13416 build_ir_node_from_die(rdr, &child, result.get(),
13417 called_from_public_decl,
13420 }
while (dwarf_siblingof(&child, &child) == 0);
13423 rdr.scope_stack().pop();
13426 die_class_or_union_map_type::const_iterator i =
13427 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13428 if (i != rdr.die_wip_classes_map(source).end())
13433 rdr.die_wip_classes_map(source).erase(i);
13437 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13465static union_decl_sptr
13466add_or_update_union_type(reader& rdr,
13469 union_decl_sptr union_type,
13470 bool called_from_public_decl,
13471 size_t where_offset,
13472 bool is_declaration_only)
13474 union_decl_sptr result;
13478 unsigned tag = dwarf_tag(die);
13480 if (tag != DW_TAG_union_type)
13483 const die_source source = rdr.get_die_source(die);
13485 die_class_or_union_map_type::const_iterator i =
13486 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13487 if (i != rdr.die_wip_classes_map(source).end())
13495 string name, linkage_name;
13497 die_loc_and_name(rdr, die, loc, name, linkage_name);
13499 bool is_anonymous =
false;
13504 name = get_internal_anonymous_die_prefix_name(die);
13507 is_anonymous =
true;
13509 if (
size_t s = scope->get_num_anonymous_member_unions())
13510 name = build_internal_anonymous_die_name(name, s);
13520 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
13529 rdr.associate_die_to_type(die, result, where_offset);
13541 if (union_decl_sptr pre_existing_union =
13543 union_type = pre_existing_union;
13546 die_size_in_bits(die, size);
13547 bool is_artificial = die_is_artificial(die);
13551 result = union_type;
13552 result->set_location(loc);
13556 result.reset(
new union_decl(rdr.env(), name, size, loc,
13557 decl_base::VISIBILITY_DEFAULT,
13559 if (is_declaration_only)
13560 result->set_is_declaration_only(
true);
13567 result->set_size_in_bits(size);
13568 result->set_is_declaration_only(
false);
13571 result->set_is_artificial(is_artificial);
13573 rdr.associate_die_to_type(die, result, where_offset);
13575 rdr.maybe_schedule_declaration_only_class_for_resolution(result);
13578 bool has_child = (dwarf_child(die, &child) == 0);
13582 rdr.die_wip_classes_map(source)[dwarf_dieoffset(die)] = result;
13585 dynamic_pointer_cast<scope_decl>(result);
13587 rdr.scope_stack().push(scop.get());
13593 tag = dwarf_tag(&child);
13595 if (tag == DW_TAG_member || tag == DW_TAG_variable)
13597 Dwarf_Die type_die;
13598 if (!die_die_attribute(&child, DW_AT_type, type_die))
13603 die_loc_and_name(rdr, &child, loc, n, m);
13612 ssize_t offset_in_bits = 0;
13613 decl_base_sptr ty =
13614 is_decl(build_ir_node_from_die(rdr, &type_die,
13615 called_from_public_decl,
13617 type_base_sptr t =
is_type(ty);
13624 result->set_is_declaration_only(
false);
13627 die_access_specifier(&child, access);
13633 if (n.empty() && result->find_data_member(dm))
13639 result->add_data_member(dm, access,
true,
13643 rdr.associate_die_to_decl(&child, dm, where_offset,
13647 else if (tag == DW_TAG_subprogram)
13650 is_decl(build_ir_node_from_die(rdr, &child,
13652 called_from_public_decl,
13660 finish_member_function_reading(&child, f, result, rdr);
13662 rdr.associate_die_to_decl(&child, f, where_offset,
13666 else if (die_is_type(&child))
13667 decl_base_sptr td =
13668 is_decl(build_ir_node_from_die(rdr, &child, result.get(),
13669 called_from_public_decl,
13671 }
while (dwarf_siblingof(&child, &child) == 0);
13674 rdr.scope_stack().pop();
13677 die_class_or_union_map_type::const_iterator i =
13678 rdr.die_wip_classes_map(source).find(dwarf_dieoffset(die));
13679 if (i != rdr.die_wip_classes_map(source).end())
13684 rdr.die_wip_classes_map(source).erase(i);
13708static type_base_sptr
13709build_qualified_type(reader& rdr,
13711 bool called_from_public_decl,
13712 size_t where_offset)
13714 type_base_sptr result;
13718 unsigned tag = dwarf_tag(die);
13720 if (tag != DW_TAG_const_type
13721 && tag != DW_TAG_volatile_type
13722 && tag != DW_TAG_restrict_type)
13725 Dwarf_Die underlying_type_die;
13726 decl_base_sptr utype_decl;
13727 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13731 utype_decl = build_ir_node_for_void_type(rdr);
13734 utype_decl =
is_decl(build_ir_node_from_die(rdr, &underlying_type_die,
13735 called_from_public_decl,
13742 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13745 rdr.associate_die_to_type(die, result, where_offset);
13749 type_base_sptr utype =
is_type(utype_decl);
13753 if (tag == DW_TAG_const_type)
13754 qual |= qualified_type_def::CV_CONST;
13755 else if (tag == DW_TAG_volatile_type)
13756 qual |= qualified_type_def::CV_VOLATILE;
13757 else if (tag == DW_TAG_restrict_type)
13758 qual |= qualified_type_def::CV_RESTRICT;
13763 result.reset(
new qualified_type_def(utype, qual, location()));
13765 rdr.associate_die_to_type(die, result, where_offset);
13783schedule_array_tree_for_late_canonicalization(
const type_base_sptr& t,
13788 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13790 rdr.schedule_type_for_late_canonicalization(t);
13794 schedule_array_tree_for_late_canonicalization(type->get_underlying_type(),
13796 rdr.schedule_type_for_late_canonicalization(t);
13800 for (vector<array_type_def::subrange_sptr>::const_iterator i =
13801 type->get_subranges().begin();
13802 i != type->get_subranges().end();
13805 if (!(*i)->get_scope())
13807 rdr.schedule_type_for_late_canonicalization(*i);
13810 schedule_array_tree_for_late_canonicalization(type->get_element_type(),
13812 rdr.schedule_type_for_late_canonicalization(type);
13831static decl_base_sptr
13832maybe_strip_qualification(
const qualified_type_def_sptr t,
13838 decl_base_sptr result = t;
13839 type_base_sptr u = t->get_underlying_type();
13843 if (result.get() != t.get())
13849 scope_decl * scope = 0;
13852 scope = array->get_scope();
13855 schedule_array_tree_for_late_canonicalization(array, rdr);
13857 t->set_underlying_type(array);
13858 u = t->get_underlying_type();
13866 schedule_array_tree_for_late_canonicalization(typdef, rdr);
13869 t->set_underlying_type(typdef);
13870 u = t->get_underlying_type();
13879 type_base_sptr element_type = array->get_element_type();
13884 ABG_ASSERT(!qualified->get_canonical_type());
13886 quals |= t->get_cv_quals();
13887 qualified->set_cv_quals(quals);
13893 qualified_type_def_sptr qual_type
13894 (
new qualified_type_def(element_type,
13896 t->get_location()));
13899 array->set_element_type(qual_type);
13900 rdr.schedule_type_for_late_canonicalization(
is_type(qual_type));
13925build_pointer_type_def(reader& rdr,
13927 bool called_from_public_decl,
13928 size_t where_offset)
13935 unsigned tag = dwarf_tag(die);
13936 if (tag != DW_TAG_pointer_type)
13940 Dwarf_Die underlying_type_die;
13941 bool has_underlying_type_die =
false;
13942 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
13945 utype_decl = build_ir_node_for_void_type(rdr);
13947 has_underlying_type_die =
true;
13949 if (!utype_decl && has_underlying_type_die)
13950 utype_decl = build_ir_node_from_die(rdr, &underlying_type_die,
13951 called_from_public_decl,
13958 if (type_base_sptr t = rdr.lookup_type_from_die(die))
13965 type_base_sptr utype =
is_type(utype_decl);
13971 uint64_t size = rdr.cur_transl_unit()->get_address_size();
13972 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 result.reset(
new pointer_type_def(utype, size, 0, location()));
13987 rdr.associate_die_to_type(die, result, where_offset);
14009build_reference_type(reader& rdr,
14011 bool called_from_public_decl,
14012 size_t where_offset)
14019 unsigned tag = dwarf_tag(die);
14020 if (tag != DW_TAG_reference_type
14021 && tag != DW_TAG_rvalue_reference_type)
14024 Dwarf_Die underlying_type_die;
14025 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14029 build_ir_node_from_die(rdr, &underlying_type_die,
14030 called_from_public_decl,
14037 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14044 type_base_sptr utype =
is_type(utype_decl);
14050 uint64_t size = rdr.cur_transl_unit()->get_address_size();
14051 if (die_unsigned_constant_attribute(die, DW_AT_byte_size, size))
14056 ABG_ASSERT((
size_t) rdr.cur_transl_unit()->get_address_size() == size);
14058 bool is_lvalue = tag == DW_TAG_reference_type;
14060 result.reset(
new reference_type_def(utype, is_lvalue, size,
14063 if (corpus_sptr corp = rdr.corpus())
14066 rdr.associate_die_to_type(die, result, where_offset);
14089build_ptr_to_mbr_type(reader& rdr,
14091 bool called_from_public_decl,
14092 size_t where_offset)
14099 unsigned tag = dwarf_tag(die);
14100 if (tag != DW_TAG_ptr_to_member_type)
14103 Dwarf_Die data_member_type_die, containing_type_die;
14105 if (!die_die_attribute(die, DW_AT_type, data_member_type_die)
14106 || !die_die_attribute(die, DW_AT_containing_type, containing_type_die))
14110 build_ir_node_from_die(rdr, &data_member_type_die,
14111 called_from_public_decl, where_offset);
14112 if (!data_member_type)
14116 build_ir_node_from_die(rdr, &containing_type_die,
14117 called_from_public_decl, where_offset);
14118 if (!containing_type)
14125 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14132 uint64_t size_in_bits = rdr.cur_transl_unit()->get_address_size();
14134 result.reset(
new ptr_to_mbr_type(data_member_type->get_environment(),
14141 rdr.associate_die_to_type(die, result, where_offset);
14162build_function_type(reader& rdr,
14164 class_or_union_sptr is_method,
14165 size_t where_offset)
14172 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subroutine_type
14173 || dwarf_tag(die) == DW_TAG_subprogram);
14175 const die_source source = rdr.get_die_source(die);
14178 size_t off = dwarf_dieoffset(die);
14179 auto i = rdr.die_wip_function_types_map(source).find(off);
14180 if (i != rdr.die_wip_function_types_map(source).end())
14188 decl_base_sptr type_decl;
14196 if (type_base_sptr t = rdr.lookup_fn_type_from_die_repr_per_tu(die))
14200 rdr.associate_die_to_type(die, result, where_offset);
14217 rdr.associate_die_to_type(die, fn_type, where_offset);
14225 bool is_const =
false;
14226 bool is_static =
false;
14227 Dwarf_Die object_pointer_die;
14228 Dwarf_Die class_type_die;
14229 bool has_this_parm_die =
14230 die_function_type_is_method_type(rdr, die, where_offset,
14231 object_pointer_die,
14234 if (has_this_parm_die)
14239 if (die_object_pointer_is_for_const_method(&object_pointer_die))
14247 class_or_union_sptr klass_type =
14252 is_method = klass_type;
14261 result.reset(is_method
14262 ?
new method_type(is_method, is_const,
14263 tu->get_address_size(),
14265 :
new function_type(rdr.env(), tu->get_address_size(),
14267 rdr.associate_die_to_type(die, result, where_offset);
14268 rdr.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result;
14270 type_base_sptr return_type;
14271 Dwarf_Die ret_type_die;
14272 if (die_die_attribute(die, DW_AT_type, ret_type_die))
14274 is_type(build_ir_node_from_die(rdr, &ret_type_die,
14278 return_type =
is_type(build_ir_node_for_void_type(rdr));
14279 result->set_return_type(return_type);
14284 if (dwarf_child(die, &child) == 0)
14287 int child_tag = dwarf_tag(&child);
14288 if (child_tag == DW_TAG_formal_parameter)
14291 string name, linkage_name;
14293 die_loc_and_name(rdr, &child, loc, name, linkage_name);
14298 bool is_artificial = die_is_artificial(&child);
14299 type_base_sptr parm_type;
14300 Dwarf_Die parm_type_die;
14301 if (die_die_attribute(&child, DW_AT_type, parm_type_die))
14303 is_type(build_ir_node_from_die(rdr, &parm_type_die,
14309 (
new function_decl::parameter(parm_type, name, loc,
14312 function_parms.push_back(p);
14314 else if (child_tag == DW_TAG_unspecified_parameters)
14317 bool is_artificial = die_is_artificial(&child);
14319 type_base_sptr parm_type =
14320 is_type(build_ir_node_for_variadic_parameter_type(rdr));
14322 (
new function_decl::parameter(parm_type,
14327 function_parms.push_back(p);
14337 while (dwarf_siblingof(&child, &child) == 0);
14339 result->set_parameters(function_parms);
14341 tu->bind_function_type_life_time(result);
14343 result->set_is_artificial(
true);
14345 rdr.associate_die_repr_to_fn_type_per_tu(die, result);
14348 die_function_type_map_type::const_iterator i =
14349 rdr.die_wip_function_types_map(source).
14350 find(dwarf_dieoffset(die));
14351 if (i != rdr.die_wip_function_types_map(source).end())
14352 rdr.die_wip_function_types_map(source).erase(i);
14355 maybe_canonicalize_type(result, rdr);
14382build_subrange_type(reader& rdr,
14383 const Dwarf_Die* die,
14384 size_t where_offset,
14385 bool associate_type_to_die)
14392 unsigned tag = dwarf_tag(
const_cast<Dwarf_Die*
>(die));
14393 if (tag != DW_TAG_subrange_type)
14396 string name = die_name(die);
14399 Dwarf_Die underlying_type_die;
14400 type_base_sptr underlying_type;
14402 bool is_signed =
false;
14403 if (die_die_attribute(die, DW_AT_type, underlying_type_die))
14405 is_type(build_ir_node_from_die(rdr,
14406 &underlying_type_die,
14410 if (underlying_type)
14413 if (die_unsigned_constant_attribute (&underlying_type_die,
14416 is_signed = (ate == DW_ATE_signed || ate == DW_ATE_signed_char);
14420 array_type_def::subrange_type::bound_value lower_bound =
14421 get_default_array_lower_bound(language);
14422 array_type_def::subrange_type::bound_value upper_bound;
14423 uint64_t count = 0;
14424 bool is_non_finite =
false;
14425 bool non_zero_count_present =
false;
14436 die_constant_attribute(die, DW_AT_lower_bound, is_signed, lower_bound);
14438 bool found_upper_bound = die_constant_attribute(die, DW_AT_upper_bound,
14439 is_signed, upper_bound);
14440 if (!found_upper_bound)
14441 found_upper_bound = subrange_die_indirect_bound_value(die,
14446 if (!found_upper_bound)
14459 if (die_unsigned_constant_attribute(die, DW_AT_count, count))
14467 non_zero_count_present =
true;
14472 int64_t u = lower_bound.get_signed_value() + count;
14474 upper_bound = u - 1;
14477 if (!non_zero_count_present)
14481 is_non_finite =
true;
14484 if (UINT64_MAX == upper_bound.get_unsigned_value())
14487 is_non_finite =
true;
14490 (
new array_type_def::subrange_type(rdr.env(),
14495 result->is_non_finite(is_non_finite);
14497 if (underlying_type)
14498 result->set_underlying_type(underlying_type);
14502 || (result->get_length() ==
14503 (uint64_t) (result->get_upper_bound()
14504 - result->get_lower_bound() + 1)));
14506 if (associate_type_to_die)
14507 rdr.associate_die_to_type(die, result, where_offset);
14529build_subranges_from_array_type_die(reader& rdr,
14530 const Dwarf_Die* die,
14532 size_t where_offset,
14533 bool associate_type_to_die)
14537 if (dwarf_child(
const_cast<Dwarf_Die*
>(die), &child) == 0)
14541 int child_tag = dwarf_tag(&child);
14542 if (child_tag == DW_TAG_subrange_type)
14545 if (associate_type_to_die)
14551 build_ir_node_from_die(rdr, &child,
14560 s = build_subrange_type(rdr, &child,
14564 subranges.push_back(s);
14567 while (dwarf_siblingof(&child, &child) == 0);
14588build_array_type(reader& rdr,
14590 bool called_from_public_decl,
14591 size_t where_offset)
14598 unsigned tag = dwarf_tag(die);
14599 if (tag != DW_TAG_array_type)
14602 decl_base_sptr type_decl;
14603 Dwarf_Die type_die;
14605 if (die_die_attribute(die, DW_AT_type, type_die))
14606 type_decl =
is_decl(build_ir_node_from_die(rdr, &type_die,
14607 called_from_public_decl,
14614 if (type_base_sptr t = rdr.lookup_type_from_die(die))
14621 type_base_sptr type =
is_type(type_decl);
14626 build_subranges_from_array_type_die(rdr, die, subranges, where_offset);
14628 result.reset(
new array_type_def(type, subranges, location()));
14650build_typedef_type(reader& rdr,
14652 bool called_from_public_decl,
14653 size_t where_offset)
14660 unsigned tag = dwarf_tag(die);
14661 if (tag != DW_TAG_typedef)
14664 string name, linkage_name;
14666 die_loc_and_name(rdr, die, loc, name, linkage_name);
14668 if (corpus_sptr corp = rdr.should_reuse_type_from_corpus_group())
14674 type_base_sptr utype;
14675 Dwarf_Die underlying_type_die;
14676 if (!die_die_attribute(die, DW_AT_type, underlying_type_die))
14679 utype = rdr.env().get_void_type();
14683 is_type(build_ir_node_from_die(rdr,
14684 &underlying_type_die,
14685 called_from_public_decl,
14691 result.reset(
new typedef_decl(name, utype, loc, linkage_name));
14698 decl_base_sptr decl =
is_decl(utype);
14700 decl->set_naming_typedef(result);
14702 rdr.maybe_schedule_declaration_only_class_for_resolution
14705 rdr.maybe_schedule_declaration_only_enum_for_resolution
14710 rdr.associate_die_to_type(die, result, where_offset);
14744build_or_get_var_decl_if_not_suppressed(reader& rdr,
14747 size_t where_offset,
14749 bool is_required_decl_spec)
14752 if (variable_is_suppressed(rdr, scope, die, is_required_decl_spec))
14757 string var_name = die_name(die);
14758 if (!var_name.empty())
14759 if ((var = class_type->find_data_member(var_name)))
14762 var = build_var_decl(rdr, die, where_offset, result);
14785build_var_decl(reader& rdr,
14787 size_t where_offset,
14793 int tag = dwarf_tag(die);
14794 ABG_ASSERT(tag == DW_TAG_variable || tag == DW_TAG_member);
14796 if (!die_is_public_decl(die))
14799 type_base_sptr type;
14800 Dwarf_Die type_die;
14801 if (die_die_attribute(die, DW_AT_type, type_die))
14803 decl_base_sptr ty =
14804 is_decl(build_ir_node_from_die(rdr, &type_die,
14813 if (!type && !result)
14816 string name, linkage_name;
14818 die_loc_and_name(rdr, die, loc, name, linkage_name);
14821 result.reset(
new var_decl(name, type, loc, linkage_name));
14827 if (!linkage_name.empty())
14828 result->set_linkage_name(linkage_name);
14831 result->set_type(type);
14837 if (!result->get_symbol())
14840 Dwarf_Addr var_addr;
14842 if (rdr.get_variable_address(die, var_addr))
14845 update_main_symbol(var_addr,
14846 result->get_linkage_name().empty()
14847 ? result->get_name()
14848 : result->get_linkage_name());
14849 var_sym = rdr.variable_symbol_is_exported(var_addr);
14854 result->set_symbol(var_sym);
14857 string linkage_name = result->get_linkage_name();
14858 if (linkage_name.empty()
14859 || !var_sym->get_alias_from_name(linkage_name))
14860 result->set_linkage_name(var_sym->get_name());
14861 result->set_is_in_public_symbol_table(
true);
14887function_is_suppressed(
const reader& rdr,
14888 const scope_decl* scope,
14889 Dwarf_Die *function_die,
14890 bool is_declaration_only)
14892 if (function_die == 0
14893 || dwarf_tag(function_die) != DW_TAG_subprogram)
14896 string fname = die_string_attribute(function_die, DW_AT_name);
14897 string flinkage_name = die_linkage_name(function_die);
14898 if (flinkage_name.empty() && rdr.die_is_in_c(function_die))
14899 flinkage_name = fname;
14909 && (!is_declaration_only || rdr.drop_undefined_syms()))
14911 Dwarf_Addr fn_addr;
14912 if (!rdr.get_function_address(function_die, fn_addr))
14916 rdr.function_symbol_is_exported(fn_addr);
14919 if (!symbol->is_suppressed())
14926 if (symbol->has_aliases())
14928 !a->is_main_symbol(); a = a->get_next_alias())
14929 if (!a->is_suppressed())
14978build_or_get_fn_decl_if_not_suppressed(reader& rdr,
14981 size_t where_offset,
14982 bool is_declaration_only,
14986 if (function_is_suppressed(rdr, scope, fn_die, is_declaration_only))
14989 string name = die_name(fn_die);
14990 string linkage_name = die_linkage_name(fn_die);
14991 bool is_dtor = !name.empty() && name[0]==
'~';
14992 bool is_virtual =
false;
14995 Dwarf_Attribute attr;
14996 if (dwarf_attr_integrate(
const_cast<Dwarf_Die*
>(fn_die),
14997 DW_AT_vtable_elem_location,
15009 if (!result && (!(is_dtor && is_virtual)))
15012 fn = maybe_finish_function_decl_reading(rdr, fn_die, where_offset, fn);
15013 rdr.associate_die_to_decl(fn_die, fn,
true);
15014 rdr.associate_die_to_type(fn_die, fn->get_type(), where_offset);
15022 string linkage_name = die_linkage_name(fn_die);
15023 fn = klass->find_member_function_sptr(linkage_name);
15030 if (!fn || !fn->get_symbol())
15037 fn = build_function_decl(rdr, fn_die, where_offset, result);
15059variable_is_suppressed(
const reader& rdr,
15060 const scope_decl* scope,
15061 Dwarf_Die *variable_die,
15062 bool is_required_decl_spec)
15064 if (variable_die == 0
15065 || (dwarf_tag(variable_die) != DW_TAG_variable
15066 && dwarf_tag(variable_die) != DW_TAG_member))
15069 string name = die_string_attribute(variable_die, DW_AT_name);
15070 string linkage_name = die_linkage_name(variable_die);
15071 if (linkage_name.empty() && rdr.die_is_in_c(variable_die))
15072 linkage_name = name;
15082 Dwarf_Addr var_addr = 0;
15083 if (!rdr.get_variable_address(variable_die, var_addr))
15087 rdr.variable_symbol_is_exported(var_addr);
15090 if (!symbol->is_suppressed())
15097 if (symbol->has_aliases())
15099 !a->is_main_symbol(); a = a->get_next_alias())
15100 if (!a->is_suppressed())
15129type_is_suppressed(
const reader& rdr,
15130 const scope_decl* scope,
15131 Dwarf_Die *type_die,
15132 bool &type_is_private)
15135 || (dwarf_tag(type_die) != DW_TAG_enumeration_type
15136 && dwarf_tag(type_die) != DW_TAG_class_type
15137 && dwarf_tag(type_die) != DW_TAG_structure_type
15138 && dwarf_tag(type_die) != DW_TAG_union_type))
15141 string type_name, linkage_name;
15142 location type_location;
15143 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15167type_is_suppressed(
const reader& rdr,
15168 const scope_decl* scope,
15169 Dwarf_Die *type_die)
15171 bool type_is_private =
false;
15172 return type_is_suppressed(rdr, scope, type_die, type_is_private);
15196get_opaque_version_of_type(reader &rdr,
15198 Dwarf_Die *type_die,
15199 size_t where_offset)
15206 unsigned tag = dwarf_tag(type_die);
15207 if (tag != DW_TAG_class_type
15208 && tag != DW_TAG_structure_type
15209 && tag != DW_TAG_union_type
15210 && tag != DW_TAG_enumeration_type)
15213 string type_name, linkage_name;
15214 location type_location;
15215 die_loc_and_name(rdr, type_die, type_location, type_name, linkage_name);
15216 if (!type_location)
15226 if (tag == DW_TAG_structure_type || tag == DW_TAG_class_type)
15228 string_classes_or_unions_map::const_iterator i =
15229 rdr.declaration_only_classes().find(qualified_name);
15230 if (i != rdr.declaration_only_classes().end())
15231 result = i->second.back();
15242 tag == DW_TAG_structure_type,
15244 decl_base::VISIBILITY_DEFAULT));
15245 klass->set_is_declaration_only(
true);
15246 klass->set_is_artificial(die_is_artificial(type_die));
15248 rdr.associate_die_to_type(type_die, klass, where_offset);
15249 rdr.maybe_schedule_declaration_only_class_for_resolution(klass);
15254 if (tag == DW_TAG_enumeration_type)
15256 string_enums_map::const_iterator i =
15257 rdr.declaration_only_enums().find(qualified_name);
15258 if (i != rdr.declaration_only_enums().end())
15259 result = i->second.back();
15264 if (die_unsigned_constant_attribute(type_die, DW_AT_byte_size, size))
15267 build_enum_underlying_type(rdr, type_name, size,
15275 enum_type->set_is_artificial(die_is_artificial(type_die));
15277 result = enum_type;
15300 elf_symbol::FUNC_TYPE,
15301 elf_symbol::GLOBAL_BINDING,
15305 elf_symbol::DEFAULT_VISIBILITY);
15323build_function_decl(reader& rdr,
15325 size_t where_offset,
15331 ABG_ASSERT(dwarf_tag(die) == DW_TAG_subprogram);
15333 if (!die_is_public_decl(die))
15339 string fname, flinkage_name;
15341 die_loc_and_name(rdr, die, floc, fname, flinkage_name);
15343 size_t is_inline = die_is_declared_inline(die);
15344 class_or_union_sptr is_method =
15357 if (!flinkage_name.empty()
15358 && result->get_linkage_name() != flinkage_name)
15359 result->set_linkage_name(flinkage_name);
15361 if (!result->get_location())
15362 result->set_location(floc);
15371 maybe_canonicalize_type(fn_type, rdr);
15373 result.reset(is_method
15374 ?
new method_decl(fname, fn_type,
15377 :
new function_decl(fname, fn_type,
15384 if (!result->get_symbol())
15387 Dwarf_Addr fn_addr;
15388 if (rdr.get_function_address(die, fn_addr))
15391 update_main_symbol(fn_addr,
15392 result->get_linkage_name().empty()
15393 ? result->get_name()
15394 : result->get_linkage_name());
15395 fn_sym = rdr.function_symbol_is_exported(fn_addr);
15398 if (fn_sym && !rdr.symbol_already_belongs_to_a_function(fn_sym))
15400 result->set_symbol(fn_sym);
15401 string linkage_name = result->get_linkage_name();
15402 if (linkage_name.empty())
15403 result->set_linkage_name(fn_sym->get_name());
15404 result->set_is_in_public_symbol_table(
true);
15408 rdr.associate_die_to_type(die, result->get_type(), where_offset);
15410 size_t die_offset = dwarf_dieoffset(die);
15415 && !result->get_linkage_name().empty())
15421 rdr.die_function_decl_with_no_symbol_map().erase(die_offset);
15440maybe_canonicalize_type(
const type_base_sptr& t,
15453 ||(
is_decl(peeled_type) &&
is_decl(peeled_type)->get_is_anonymous()))
15463 rdr.schedule_type_for_late_canonicalization(t);
15465 rdr.schedule_type_for_late_canonicalization(t);
15476maybe_set_member_type_access_specifier(decl_base_sptr member_type_declaration,
15479 if (
is_type(member_type_declaration)
15482 class_or_union* scope =
15488 if (!cl->is_struct())
15489 access = private_access;
15491 die_access_specifier(die, access);
15514 if (!fn || fn->get_scope())
15518 !die_is_virtual(fn_die)
15520 && !fn->get_linkage_name().empty()
15522 && !fn->get_symbol())
15567build_ir_node_from_die(reader& rdr,
15570 bool called_from_public_decl,
15571 size_t where_offset,
15572 bool is_declaration_only,
15573 bool is_required_decl_spec)
15577 if (!die || !scope)
15580 int tag = dwarf_tag(die);
15582 if (!called_from_public_decl)
15584 if (rdr.load_all_types() && die_is_type(die))
15588 else if (tag != DW_TAG_subprogram
15589 && tag != DW_TAG_variable
15590 && tag != DW_TAG_member
15591 && tag != DW_TAG_namespace)
15595 const die_source source_of_die = rdr.get_die_source(die);
15597 if ((result = rdr.lookup_decl_from_die_offset(dwarf_dieoffset(die),
15600 if (rdr.load_all_types())
15601 if (called_from_public_decl)
15602 if (type_base_sptr t =
is_type(result))
15603 if (corpus *abi_corpus = scope->get_corpus())
15604 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
15613 is_declaration_only = is_declaration_only && die_is_declaration_only(die);
15618 case DW_TAG_base_type:
15627 case DW_TAG_typedef:
15630 called_from_public_decl,
15636 maybe_set_member_type_access_specifier(
is_decl(result), die);
15637 maybe_canonicalize_type(t, rdr);
15642 case DW_TAG_pointer_type:
15645 build_pointer_type_def(rdr, die,
15646 called_from_public_decl,
15653 maybe_canonicalize_type(p, rdr);
15658 case DW_TAG_reference_type:
15659 case DW_TAG_rvalue_reference_type:
15662 build_reference_type(rdr, die,
15663 called_from_public_decl,
15670 rdr.associate_die_to_type(die, r, where_offset);
15671 maybe_canonicalize_type(r, rdr);
15676 case DW_TAG_ptr_to_member_type:
15679 build_ptr_to_mbr_type(rdr, die, called_from_public_decl,
15685 maybe_canonicalize_type(p, rdr);
15690 case DW_TAG_const_type:
15691 case DW_TAG_volatile_type:
15692 case DW_TAG_restrict_type:
15695 build_qualified_type(rdr, die,
15696 called_from_public_decl,
15707 type_base_sptr ty =
is_type(d);
15711 rdr.associate_die_to_type(die, ty, where_offset);
15714 maybe_canonicalize_type(
is_type(result), rdr);
15719 case DW_TAG_enumeration_type:
15721 bool type_is_private =
false;
15722 bool type_suppressed =
15723 type_is_suppressed(rdr, scope, die, type_is_private);
15724 if (type_suppressed && type_is_private)
15732 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15733 maybe_canonicalize_type(
is_type(result), rdr);
15735 else if (!type_suppressed)
15739 is_declaration_only);
15743 maybe_set_member_type_access_specifier(
is_decl(result), die);
15744 maybe_canonicalize_type(
is_type(result), rdr);
15750 case DW_TAG_class_type:
15751 case DW_TAG_structure_type:
15753 bool type_is_private =
false;
15754 bool type_suppressed=
15755 type_is_suppressed(rdr, scope, die, type_is_private);
15757 if (type_suppressed && type_is_private)
15765 result = get_opaque_version_of_type(rdr, scope, die, where_offset);
15766 maybe_canonicalize_type(
is_type(result), rdr);
15768 else if (!type_suppressed)
15770 Dwarf_Die spec_die;
15773 if (die_die_attribute(die, DW_AT_specification, spec_die))
15776 get_scope_for_die(rdr, &spec_die,
15777 called_from_public_decl,
15780 decl_base_sptr cl =
15781 is_decl(build_ir_node_from_die(rdr, &spec_die,
15783 called_from_public_decl,
15785 is_declaration_only,
15788 klass = dynamic_pointer_cast<class_decl>(cl);
15792 add_or_update_class_type(rdr, die,
15794 tag == DW_TAG_structure_type,
15796 called_from_public_decl,
15798 is_declaration_only);
15802 add_or_update_class_type(rdr, die, scope,
15803 tag == DW_TAG_structure_type,
15805 called_from_public_decl,
15807 is_declaration_only);
15811 maybe_set_member_type_access_specifier(klass, die);
15812 maybe_canonicalize_type(klass, rdr);
15817 case DW_TAG_union_type:
15818 if (!type_is_suppressed(rdr, scope, die))
15820 union_decl_sptr union_type =
15821 add_or_update_union_type(rdr, die, scope,
15823 called_from_public_decl,
15825 is_declaration_only);
15828 maybe_set_member_type_access_specifier(union_type, die);
15829 maybe_canonicalize_type(union_type, rdr);
15831 result = union_type;
15834 case DW_TAG_string_type:
15836 case DW_TAG_subroutine_type:
15844 result->set_is_artificial(
false);
15845 maybe_canonicalize_type(f, rdr);
15849 case DW_TAG_array_type:
15853 called_from_public_decl,
15859 rdr.associate_die_to_type(die, a, where_offset);
15860 maybe_canonicalize_type(a, rdr);
15864 case DW_TAG_subrange_type:
15870 build_subrange_type(rdr, die, where_offset);
15875 rdr.associate_die_to_type(die, s, where_offset);
15876 maybe_canonicalize_type(s, rdr);
15880 case DW_TAG_packed_type:
15882 case DW_TAG_set_type:
15884 case DW_TAG_file_type:
15886 case DW_TAG_thrown_type:
15888 case DW_TAG_interface_type:
15890 case DW_TAG_unspecified_type:
15892 case DW_TAG_shared_type:
15895 case DW_TAG_compile_unit:
15900 case DW_TAG_namespace:
15901 case DW_TAG_module:
15902 result = build_namespace_decl_and_add_to_ir(rdr, die, where_offset);
15905 case DW_TAG_variable:
15906 case DW_TAG_member:
15908 Dwarf_Die spec_die;
15909 bool var_is_cloned =
false;
15911 if (tag == DW_TAG_member)
15914 if (die_die_attribute(die, DW_AT_specification, spec_die,
false)
15915 || (var_is_cloned = die_die_attribute(die, DW_AT_abstract_origin,
15919 get_scope_for_die(rdr, &spec_die,
15921 die_is_effectively_public_decl(rdr, die),
15926 is_decl(build_ir_node_from_die(rdr, &spec_die,
15928 called_from_public_decl,
15930 is_declaration_only,
15935 dynamic_pointer_cast<var_decl>(d);
15938 m = build_var_decl(rdr, die, where_offset, m);
15942 rdr.associate_die_to_decl(die, m, where_offset,
15948 rdr.var_decls_to_re_add_to_tree().push_back(m);
15951 rdr.maybe_add_var_to_exported_decls(m.get());
15957 build_or_get_var_decl_if_not_suppressed(rdr, scope, die,
15960 is_required_decl_spec))
15964 v = dynamic_pointer_cast<var_decl>(result);
15967 rdr.var_decls_to_re_add_to_tree().push_back(v);
15968 rdr.maybe_add_var_to_exported_decls(v.get());
15973 case DW_TAG_subprogram:
15975 if (die_is_artificial(die))
15978 Dwarf_Die abstract_origin_die;
15979 bool has_abstract_origin = die_die_attribute(die, DW_AT_abstract_origin,
15980 abstract_origin_die,
15984 scope_decl_sptr s = get_scope_for_die(rdr, die, called_from_public_decl,
15986 scope_decl* interface_scope = scope ? scope : s.get();
15989 string linkage_name = die_linkage_name(die);
15990 string spec_linkage_name;
15997 if (!linkage_name.empty())
16000 class_scope->find_member_function_sptr(linkage_name)))
16005 spec_linkage_name = existing_fn->get_linkage_name();
16006 if (has_abstract_origin
16007 && !spec_linkage_name.empty()
16008 && linkage_name != spec_linkage_name)
16015 existing_fn = existing_fn->clone();
16021 rdr.scope_stack().push(interface_scope);
16028 build_or_get_fn_decl_if_not_suppressed(rdr, interface_scope,
16030 is_declaration_only,
16033 if (result && !existing_fn)
16040 && !is_required_decl_spec)
16056 sptr_utils::noop_deleter());
16058 finish_member_function_reading(die, fn, klass, rdr);
16069 rdr.maybe_add_fn_to_exported_decls(fn.get());
16070 rdr.associate_die_to_decl(die, fn, where_offset,
16072 maybe_canonicalize_type(fn->get_type(), rdr);
16075 rdr.scope_stack().pop();
16079 case DW_TAG_formal_parameter:
16084 case DW_TAG_constant:
16086 case DW_TAG_enumerator:
16089 case DW_TAG_partial_unit:
16090 case DW_TAG_imported_unit:
16097 case DW_TAG_dwarf_procedure:
16098 case DW_TAG_imported_declaration:
16099 case DW_TAG_entry_point:
16101 case DW_TAG_lexical_block:
16102 case DW_TAG_unspecified_parameters:
16103 case DW_TAG_variant:
16104 case DW_TAG_common_block:
16105 case DW_TAG_common_inclusion:
16106 case DW_TAG_inheritance:
16107 case DW_TAG_inlined_subroutine:
16108 case DW_TAG_with_stmt:
16109 case DW_TAG_access_declaration:
16110 case DW_TAG_catch_block:
16111 case DW_TAG_friend:
16112 case DW_TAG_namelist:
16113 case DW_TAG_namelist_item:
16114 case DW_TAG_template_type_parameter:
16115 case DW_TAG_template_value_parameter:
16116 case DW_TAG_try_block:
16117 case DW_TAG_variant_part:
16118 case DW_TAG_imported_module:
16119 case DW_TAG_condition:
16120 case DW_TAG_type_unit:
16121 case DW_TAG_template_alias:
16122 case DW_TAG_lo_user:
16123 case DW_TAG_MIPS_loop:
16124 case DW_TAG_format_label:
16125 case DW_TAG_function_template:
16126 case DW_TAG_class_template:
16127 case DW_TAG_GNU_BINCL:
16128 case DW_TAG_GNU_EINCL:
16129 case DW_TAG_GNU_template_template_param:
16130 case DW_TAG_GNU_template_parameter_pack:
16131 case DW_TAG_GNU_formal_parameter_pack:
16132 case DW_TAG_GNU_call_site:
16133 case DW_TAG_GNU_call_site_parameter:
16134 case DW_TAG_hi_user:
16139 if (result && tag != DW_TAG_subroutine_type)
16140 rdr.associate_die_to_decl(die,
is_decl(result), where_offset,
16144 if (rdr.load_all_types())
16145 if (called_from_public_decl)
16146 if (type_base_sptr t =
is_type(result))
16147 if (corpus *abi_corpus = scope->get_corpus())
16148 abi_corpus->record_type_as_reachable_from_public_interfaces(*t);
16158static decl_base_sptr
16159build_ir_node_for_void_type(reader& rdr)
16161 const environment& env = rdr.env();
16163 type_base_sptr t = env.get_void_type();
16167 return type_declaration;
16182build_ir_node_for_void_pointer_type(reader& rdr)
16184 const environment& env = rdr.env();
16186 type_base_sptr t = env.get_void_pointer_type();
16190 return type_declaration;
16198static decl_base_sptr
16199build_ir_node_for_variadic_parameter_type(reader &rdr)
16202 const environment& env = rdr.env();
16204 type_base_sptr t = env.get_variadic_parameter_type();
16208 return type_declaration;
16234build_ir_node_from_die(reader& rdr,
16236 bool called_from_public_decl,
16237 size_t where_offset)
16240 return decl_base_sptr();
16250 bool consider_as_called_from_public_decl =
16251 called_from_public_decl || die_is_effectively_public_decl(rdr, die);
16253 consider_as_called_from_public_decl,
16255 return build_ir_node_from_die(rdr, die, scope.get(),
16256 called_from_public_decl,
16257 where_offset,
true);
16291elf_based_reader_sptr
16293 const vector<char**>& debug_info_root_paths,
16295 bool load_all_types,
16296 bool linux_kernel_mode)
16299 reader_sptr r = reader::create(elf_path,
16300 debug_info_root_paths,
16303 linux_kernel_mode);
16304 return static_pointer_cast<elf_based_reader>(r);
16343 const std::string& elf_path,
16344 const vector<char**>&debug_info_root_path,
16345 bool read_all_types,
16346 bool linux_kernel_mode)
16348 reader& r =
dynamic_cast<reader&
>(rdr);
16349 r.initialize(elf_path, debug_info_root_path,
16350 read_all_types, linux_kernel_mode);
16387 const vector<char**>& debug_info_root_paths,
16389 bool load_all_types,
16392 elf_based_reader_sptr rdr =
16393 dwarf::reader::create(elf_path, debug_info_root_paths,
16397 return rdr->read_corpus(status);
16418 const string& elf_path,
16419 const string& symbol_name,
16421 vector<elf_symbol_sptr>& syms)
16424 if (elf_version(EV_CURRENT) == EV_NONE)
16427 int fd = open(elf_path.c_str(), O_RDONLY);
16435 Elf* elf = elf_begin(fd, ELF_C_READ, 0);
16463 const string& path,
16464 const string& symname,
16465 vector<elf_symbol_sptr>& syms)
16467 if (elf_version(EV_CURRENT) == EV_NONE)
16470 int fd = open(path.c_str(), O_RDONLY);
16478 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.
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...
const ptr_to_mbr_type * is_ptr_to_mbr_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a ptr_to_mbr_type.
string components_to_type_name(const list< string > &comps)
Turn a set of qualified name components (that name a type) into a qualified name string.
comparison_result
The result of structural comparison of type ABI artifacts.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
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.
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_typedef_of_maybe_qualified_class_or_union_type(const type_base *t)
Test if a type is a typedef of a class or union type, or a typedef of a qualified class or union type...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
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< ptr_to_mbr_type > ptr_to_mbr_type_sptr
Convenience typedef for a shared pointer to a ptr_to_mbr_type.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
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.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
bool is_c_language(translation_unit::language l)
Test if a language enumerator designates the C language.
decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
string build_internal_underlying_enum_type_name(const string &base_name, bool is_anonymous, uint64_t size)
Build the internal name of the underlying type of an enum.
access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
shared_ptr< enum_type_decl > enum_type_decl_sptr
Convenience typedef for shared pointer to a enum_type_decl.
bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
const pointer_type_def * is_pointer_type(const type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a pointer_type_def.
class_or_union * look_through_decl_only_class(class_or_union *the_class)
If a class (or union) is a decl-only class, get its definition. Otherwise, just return the initial cl...
bool is_union_type(const type_or_decl_base &t)
Test if a type is a union_decl.
const type_base_wptrs_type * lookup_union_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the union type*s* that have a given qualified name.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
const type_base_wptrs_type * lookup_class_types(const interned_string &qualified_name, const corpus &corp)
Look into a given corpus to find the class type*s* that have a given qualified name.
const decl_base * get_type_declaration(const type_base *t)
Get the declaration for a given type.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
array_type_def * is_array_type(const type_or_decl_base *type, bool look_through_qualifiers)
Test if a type is an array_type_def.
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
void strip_redundant_quals_from_underyling_types(const qualified_type_def_sptr &t)
Merge redundant qualifiers from a tree of qualified types.
shared_ptr< namespace_decl > namespace_decl_sptr
Convenience typedef for a shared pointer on namespace_decl.
bool is_ada_language(translation_unit::language l)
Test if a language enumerator designates the Ada language.
string demangle_cplus_mangled_name(const string &mangled_name)
Demangle a C++ mangled name and return the resulting string.
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.