20#include <unordered_map>
24#include "abg-internal.h"
26ABG_BEGIN_EXPORT_DECLARATIONS
33ABG_END_EXPORT_DECLARATIONS
50 do_update(abigail::ir::decl_base* d);
53 visit_begin(abigail::ir::decl_base* d);
56 visit_begin(abigail::ir::type_base* d);
68using std::unordered_map;
69using std::dynamic_pointer_cast;
70using std::static_pointer_cast;
77struct interned_string_pool::priv
97{
return priv_->map.find(s) != priv_->map.end();}
108 unordered_map<string, string*>::const_iterator i =
110 if (i == priv_->map.end())
113 return i->second->c_str();
125 string*& result = priv_->map[str_value];
126 if (!result && !str_value.empty())
127 result =
new string(str_value);
134 for (pool_map_type::iterator i = priv_->map.begin();
135 i != priv_->map.end();
152{
return r.operator==(l);}
155operator!=(
const std::string& l,
const interned_string& r)
170 o << static_cast<std::string>(s);
186{
return static_cast<std::string
>(s1) + s2;}
200{
return s1 +
static_cast<std::string
>(s2);}
206hash_as_canonical_type_or_constant(
const type_base *t);
209has_generic_anonymous_internal_type_name(
const decl_base *d);
211static interned_string
212get_generic_anonymous_internal_type_name(
const decl_base *d);
215get_internal_real_type_name(
const type_base*);
218update_qualified_name(decl_base * d);
221update_qualified_name(decl_base_sptr d);
223static interned_string
224pointer_declaration_name(
const type_base* ptr,
225 const string& variable_name,
226 bool qualified,
bool internal);
228static interned_string
229pointer_declaration_name(
const type_base_sptr& ptr,
230 const string& variable_name,
231 bool qualified,
bool internal);
233static interned_string
234ptr_to_mbr_declaration_name(
const ptr_to_mbr_type* ptr,
235 const string& variable_name,
236 bool qualified,
bool internal);
238static interned_string
240 const string& variable_name,
241 bool qualified,
bool internal);
243static interned_string
244array_declaration_name(
const array_type_def* array,
245 const string& variable_name,
246 bool qualified,
bool internal);
248static interned_string
250 const string& variable_name,
251 bool qualified,
bool internal);
254stream_pretty_representation_of_fn_parms(
const function_type& fn_type,
255 ostream& o,
bool qualified,
258add_outer_pointer_to_fn_type_expr(
const type_base* pointer_to_fn,
259 const string& input,
bool qualified,
263add_outer_pointer_to_fn_type_expr(
const type_base_sptr& pointer_to_fn,
264 const string& input,
bool qualified,
268add_outer_pointer_to_array_type_expr(
const type_base* pointer_to_ar,
269 const string& input,
bool qualified,
273add_outer_pointer_to_array_type_expr(
const type_base_sptr& pointer_to_ar,
274 const string& input,
bool qualified,
278add_outer_ptr_to_mbr_type_expr(
const ptr_to_mbr_type* p,
279 const string& input,
bool qualified,
284 const string& input,
bool qualified,
288add_outer_pointer_to_ptr_to_mbr_type_expr(
const type_base* p,
290 bool qualified,
bool internal);
294 const type_base& right);
298 const type_base& right);
315 env.priv_->push_composite_type_comparison_operands(&left, &right);
336 env.priv_->pop_composite_type_comparison_operands(&left, &right);
346{
return t.priv_->canonical_type_index;}
381 if (c && t->get_corpus())
386 if (t->get_corpus()->get_group() == g.get())
391 if (t->get_corpus() == c.get())
400class expanded_location
412 expanded_location(
const string& path,
unsigned line,
unsigned column)
413 : path_(path), line_(line), column_(column)
417 operator==(
const expanded_location& l)
const
419 return (path_ == l.path_
421 && column_ && l.column_);
425 operator<(
const expanded_location& l)
const
429 else if (path_ > l.path_)
434 else if (line_ > l.line_)
437 return column_ < l.column_;
454 if (!get_location_manager())
464 get_location_manager()->expand_location(*
this, path, line, column);
475 unsigned line = 0, column = 0;
476 expand(path, line, column);
478 std::ostringstream o;
479 o << path <<
":" << line <<
":" << column;
483struct location_manager::priv
489 std::vector<expanded_location> locs;
492location_manager::location_manager()
496location_manager::~location_manager() =
default;
511 expanded_location l(file_path, line, col);
515 priv_->locs.push_back(l);
516 return location(priv_->locs.size(),
this);
533 unsigned& column)
const
537 expanded_location &l = priv_->locs[
location.value_ - 1];
550struct type_maps::priv
567type_maps::type_maps()
571type_maps::~type_maps() =
default;
596{
return priv_->basic_types_;}
603{
return priv_->basic_types_;}
610{
return priv_->class_types_;}
617{
return priv_->class_types_;}
624{
return priv_->union_types_;}
631{
return priv_->union_types_;}
638{
return priv_->enum_types_;}
645{
return priv_->enum_types_;}
652{
return priv_->typedef_types_;}
659{
return priv_->typedef_types_;}
665{
return priv_->qualified_types_;}
671{
return priv_->qualified_types_;}
678{
return priv_->pointer_types_;}
685{
return priv_->ptr_to_mbr_types_;}
692{
return priv_->ptr_to_mbr_types_;}
699{
return priv_->pointer_types_;}
706{
return priv_->reference_types_;}
713{
return priv_->reference_types_;}
720{
return priv_->array_types_;}
727{
return priv_->array_types_;}
734{
return priv_->subrange_types_;}
741{
return priv_->subrange_types_;}
748{
return priv_->function_types_;}
755{
return priv_->function_types_;}
774 if (l == 0 && r == 0)
779 return l_repr < r_repr;
793 operator()(
const type_base_sptr &l,
const type_base_sptr &r)
const
794 {
return operator()(l.get(), r.get());}
808 {
return operator()(type_base_sptr(l), type_base_sptr(r));}
811#ifdef WITH_DEBUG_SELF_COMPARISON
849#define ABG_RETURN_EQUAL(l, r) \
853 notify_equality_failed(l, r); \
859#define ABG_RETURN_FALSE \
862 notify_equality_failed(l, r); \
866#define ABG_RETURN(value) \
869 if (value == false) \
870 notify_equality_failed(l, r); \
876#define ABG_RETURN_FALSE return false
877#define ABG_RETURN(value) return (value)
878#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
898 if (
type_base* type = t->get_naked_canonical_type())
899 return dynamic_cast<T*
>(type);
916#if WITH_DEBUG_TYPE_CANONICALIZATION
936 if (env.priv_->use_canonical_type_comparison_)
938 if (
const type_base *lc = l->get_naked_canonical_type())
939 if (
const type_base *rc = r->get_naked_canonical_type())
940 ABG_RETURN_EQUAL(lc, rc);
949 if (l_hash != r_hash)
958 if (
const type_base *lc = l->get_naked_canonical_type())
959 if (
const type_base *rc = r->get_naked_canonical_type())
960 ABG_RETURN_EQUAL(lc, rc);
968 if (l_hash != r_hash)
991 bool result = l.priv_->comparison_started(l, r);
1031#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1034 if (is_comparison_cycle_detected(l, r)) \
1052 l.priv_->mark_as_being_compared(l, r);
1087 l.priv_->unmark_as_being_compared(l, r);
1133#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1136 bool res = return_comparison_result(l, r, value); \
1137 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1145#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1148 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1156const vector<type_base_wptr>&
1159 if (priv_->sorted_types_.empty())
1161 istring_type_base_wptrs_map_type::const_iterator i;
1165 for (j = i->second.begin(); j != i->second.end(); ++j)
1166 priv_->sorted_types_.push_back(*j);
1169 for (j = i->second.begin(); j != i->second.end(); ++j)
1170 priv_->sorted_types_.push_back(*j);
1173 for (j = i->second.begin(); j != i->second.end(); ++j)
1174 priv_->sorted_types_.push_back(*j);
1177 for (j = i->second.begin(); j != i->second.end(); ++j)
1178 priv_->sorted_types_.push_back(*j);
1181 for (j = i->second.begin(); j != i->second.end(); ++j)
1182 priv_->sorted_types_.push_back(*j);
1184 type_name_comp comp;
1185 sort(priv_->sorted_types_.begin(), priv_->sorted_types_.end(), comp);
1188 return priv_->sorted_types_;
1207 const std::string& path,
1209 : priv_(new
priv(env))
1211 priv_->path_ = path;
1212 priv_->address_size_ = address_size;
1234 if (!priv_->global_scope_)
1236 priv_->global_scope_.reset
1237 (
new global_scope(
const_cast<translation_unit*
>(
this)));
1238 priv_->global_scope_->set_translation_unit
1239 (
const_cast<translation_unit*
>(
this));
1241 return priv_->global_scope_;
1249{
return priv_->types_;}
1256{
return priv_->types_;}
1265{
return priv_->live_fn_types_;}
1272{
return priv_->env_;}
1279{
return priv_->language_;}
1286{priv_->language_ = l;}
1299{
return priv_->path_;}
1310{priv_->path_ = a_path;}
1323{
return priv_->comp_dir_path_;}
1334{priv_->comp_dir_path_ = d;}
1343 if (priv_->abs_path_.empty())
1346 if (!priv_->path_.empty())
1348 if (!priv_->comp_dir_path_.empty())
1350 path = priv_->comp_dir_path_;
1353 path += priv_->path_;
1355 priv_->abs_path_ = path;
1358 return priv_->abs_path_;
1377{
return priv_->corp;}
1385{
return const_cast<translation_unit*
>(
this)->
get_corpus();}
1393{
return priv_->loc_mgr_;}
1401{
return priv_->loc_mgr_;}
1410 if (!priv_->global_scope_)
1420{
return priv_->address_size_;}
1427{priv_->address_size_= a;}
1443{
return priv_->is_constructed_;}
1459{priv_->is_constructed_ = f;}
1498 const_cast<translation_unit*
>(
this)->priv_->live_fn_types_.push_back(ftype);
1511 if (
const translation_unit* existing_tu = ftype->get_translation_unit())
1514 ftype->set_translation_unit(
const_cast<translation_unit*
>(
this));
1531translation_unit::~translation_unit()
1544 case translation_unit::LANG_UNKNOWN:
1545 return "LANG_UNKNOWN";
1546 case translation_unit::LANG_Cobol74:
1547 return "LANG_Cobol74";
1548 case translation_unit::LANG_Cobol85:
1549 return "LANG_Cobol85";
1550 case translation_unit::LANG_C89:
1552 case translation_unit::LANG_C99:
1554 case translation_unit::LANG_C11:
1556 case translation_unit::LANG_C17:
1558 case translation_unit::LANG_C23:
1560 case translation_unit::LANG_C:
1562 case translation_unit::LANG_C_plus_plus_03:
1563 return "LANG_C_plus_plus_03";
1564 case translation_unit::LANG_C_plus_plus_11:
1565 return "LANG_C_plus_plus_11";
1566 case translation_unit::LANG_C_plus_plus_14:
1567 return "LANG_C_plus_plus_14";
1568 case translation_unit::LANG_C_plus_plus_17:
1569 return "LANG_C_plus_plus_17";
1570 case translation_unit::LANG_C_plus_plus_20:
1571 return "LANG_C_plus_plus_20";
1572 case translation_unit::LANG_C_plus_plus_23:
1573 return "LANG_C_plus_plus_23";
1574 case translation_unit::LANG_C_plus_plus:
1575 return "LANG_C_plus_plus";
1576 case translation_unit::LANG_OCaml:
1577 return "LANG_OCaml";
1578 case translation_unit::LANG_Zig:
1580 case translation_unit::LANG_ObjC:
1582 case translation_unit::LANG_ObjC_plus_plus:
1583 return "LANG_ObjC_plus_plus";
1584 case translation_unit::LANG_D:
1586 case translation_unit::LANG_Go:
1588 case translation_unit::LANG_Rust:
1590 case translation_unit::LANG_Fortran77:
1591 return "LANG_Fortran77";
1592 case translation_unit::LANG_Fortran90:
1593 return "LANG_Fortran90";
1594 case translation_unit::LANG_Fortran95:
1595 return "LANG_Fortran95";
1596 case translation_unit::LANG_Fortran18:
1597 return "LANG_Fortran18";
1598 case translation_unit::LANG_Fortran23:
1599 return "LANG_Fortran23";
1600 case translation_unit::LANG_Ada83:
1601 return "LANG_Ada83";
1602 case translation_unit::LANG_Ada95:
1603 return "LANG_Ada95";
1604 case translation_unit::LANG_Ada2005:
1605 return "LANG_Ada2005";
1606 case translation_unit::LANG_Ada2012:
1607 return "LANG_Ada2012";
1608 case translation_unit::LANG_Pascal83:
1609 return "LANG_Pascal83";
1610 case translation_unit::LANG_Modula2:
1611 return "LANG_Modula2";
1612 case translation_unit::LANG_Java:
1614 case translation_unit::LANG_Kotlin:
1615 return "LANG_Kotlin";
1616 case translation_unit::LANG_C_sharp:
1617 return "LANG_C_sharp";
1618 case translation_unit::LANG_Python:
1619 return "LANG_Python";
1620 case translation_unit::LANG_Ruby:
1622 case translation_unit::LANG_PLI:
1624 case translation_unit::LANG_UPC:
1626 case translation_unit::LANG_Mips_Assembler:
1627 return "LANG_Mips_Assembler";
1628 case translation_unit::LANG_Assembly:
1629 return "LANG_Assembly";
1630 case translation_unit::LANG_Crystal:
1631 return "LANG_Crystal";
1632 case translation_unit::LANG_HIP:
1634 case translation_unit::LANG_Mojo:
1636 case translation_unit::LANG_GLSL:
1638 case translation_unit::LANG_GLSL_ES:
1639 return "LANG_GLSL_ES";
1640 case translation_unit::LANG_HLSL:
1642 case translation_unit::LANG_OpenCL_CPP:
1643 return "LANG_OpenCL_CPP";
1644 case translation_unit::LANG_CPP_for_OpenCL:
1645 return "LANG_CPP_for_OpenCL";
1646 case translation_unit::LANG_SYCL:
1648 case translation_unit::LANG_Odin:
1650 case translation_unit::LANG_P4:
1652 case translation_unit::LANG_Metal:
1653 return "LANG_Metal";
1654 case translation_unit::LANG_Move:
1656 case translation_unit::LANG_Hylo:
1660 return "LANG_UNKNOWN";
1672 if (l ==
"LANG_Cobol74")
1673 return translation_unit::LANG_Cobol74;
1674 else if (l ==
"LANG_Cobol85")
1675 return translation_unit::LANG_Cobol85;
1676 else if (l ==
"LANG_C89")
1677 return translation_unit::LANG_C89;
1678 else if (l ==
"LANG_C99")
1679 return translation_unit::LANG_C99;
1680 else if (l ==
"LANG_C11")
1681 return translation_unit::LANG_C11;
1682 else if (l ==
"LANG_C17")
1683 return translation_unit::LANG_C17;
1684 else if (l ==
"LANG_C23")
1685 return translation_unit::LANG_C23;
1686 else if (l ==
"LANG_C")
1687 return translation_unit::LANG_C;
1688 else if (l ==
"LANG_C_plus_plus_03")
1689 return translation_unit::LANG_C_plus_plus_03;
1690 else if (l ==
"LANG_C_plus_plus_11")
1691 return translation_unit::LANG_C_plus_plus_11;
1692 else if (l ==
"LANG_C_plus_plus_14")
1693 return translation_unit::LANG_C_plus_plus_14;
1694 else if (l ==
"LANG_C_plus_plus_17")
1695 return translation_unit::LANG_C_plus_plus_17;
1696 else if (l ==
"LANG_C_plus_plus_20")
1697 return translation_unit::LANG_C_plus_plus_20;
1698 else if (l ==
"LANG_C_plus_plus_23")
1699 return translation_unit::LANG_C_plus_plus_23;
1700 else if (l ==
"LANG_C_plus_plus")
1701 return translation_unit::LANG_C_plus_plus;
1702 else if (l ==
"LANG_OCaml")
1703 return translation_unit::LANG_OCaml;
1704 else if (l ==
"LANG_ObjC")
1705 return translation_unit::LANG_ObjC;
1706 else if (l ==
"LANG_ObjC_plus_plus")
1707 return translation_unit::LANG_ObjC_plus_plus;
1708 else if (l ==
"LANG_Zig")
1709 return translation_unit::LANG_Zig;
1710 else if (l ==
"LANG_Metal")
1711 return translation_unit::LANG_Metal;
1712 else if (l ==
"LANG_Fortran77")
1713 return translation_unit::LANG_Fortran77;
1714 else if (l ==
"LANG_Fortran90")
1715 return translation_unit::LANG_Fortran90;
1716 else if (l ==
"LANG_Fortran95")
1717 return translation_unit::LANG_Fortran95;
1718 else if (l ==
"LANG_Fortran18")
1719 return translation_unit::LANG_Fortran23;
1720 else if (l ==
"LANG_Ada83")
1721 return translation_unit::LANG_Ada83;
1722 else if (l ==
"LANG_Ada95")
1723 return translation_unit::LANG_Ada95;
1724 else if (l ==
"LANG_Ada2005")
1725 return translation_unit::LANG_Ada2005;
1726 else if (l ==
"LANG_Ada2012")
1727 return translation_unit::LANG_Ada2012;
1728 else if (l ==
"LANG_Pascal83")
1729 return translation_unit::LANG_Pascal83;
1730 else if (l ==
"LANG_Modula2")
1731 return translation_unit::LANG_Modula2;
1732 else if (l ==
"LANG_Java")
1733 return translation_unit::LANG_Java;
1734 else if (l ==
"LANG_Kotlin")
1735 return translation_unit::LANG_Kotlin;
1736 else if (l ==
"LANG_PLI")
1737 return translation_unit::LANG_PLI;
1738 else if (l ==
"LANG_UPC")
1739 return translation_unit::LANG_UPC;
1740 else if (l ==
"LANG_D")
1741 return translation_unit::LANG_D;
1742 else if (l ==
"LANG_Go")
1743 return translation_unit::LANG_Go;
1744 else if (l ==
"LANG_Rust")
1745 return translation_unit::LANG_Rust;
1746 else if (l ==
"LANG_Python")
1747 return translation_unit::LANG_Python;
1748 else if (l ==
"LANG_Ruby")
1749 return translation_unit::LANG_Ruby;
1750 else if (l ==
"LANG_Mips_Assembler")
1751 return translation_unit::LANG_Mips_Assembler;
1752 else if (l ==
"LANG_Assembly")
1753 return translation_unit::LANG_Assembly;
1754 else if (l ==
"LANG_Crystal")
1755 return translation_unit::LANG_Crystal;
1756 else if (l ==
"LANG_HIP")
1757 return translation_unit::LANG_HIP;
1758 else if (l ==
"LANG_C_sharp")
1759 return translation_unit::LANG_C_sharp;
1760 else if (l ==
"LANG_Mojo")
1761 return translation_unit::LANG_Mojo;
1762 else if (l ==
"LANG_GLSL")
1763 return translation_unit::LANG_GLSL;
1764 else if (l ==
"LANG_GLSL_ES")
1765 return translation_unit::LANG_GLSL_ES;
1766 else if (l ==
"LANG_HLSL")
1767 return translation_unit::LANG_HLSL;
1768 else if (l ==
"LANG_OpenCL_CPP")
1769 return translation_unit::LANG_OpenCL_CPP;
1770 else if (l ==
"LANG_CPP_for_OpenCL")
1771 return translation_unit::LANG_CPP_for_OpenCL;
1772 else if (l ==
"LANG_SYCL")
1773 return translation_unit::LANG_SYCL;
1774 else if (l ==
"LANG_Odin")
1775 return translation_unit::LANG_Odin;
1776 else if (l ==
"LANG_P4")
1777 return translation_unit::LANG_P4;
1778 else if (l ==
"LANG_Move")
1779 return translation_unit::LANG_Move;
1780 else if (l ==
"LANG_Hylo")
1781 return translation_unit::LANG_Hylo;
1783 return translation_unit::LANG_UNKNOWN;
1794 return (l == translation_unit::LANG_C89
1795 || l == translation_unit::LANG_C99
1796 || l == translation_unit::LANG_C11
1797 || l == translation_unit::LANG_C17
1798 || l == translation_unit::LANG_C23
1799 || l == translation_unit::LANG_C);
1810 return (l == translation_unit::LANG_C_plus_plus_03
1811 || l == translation_unit::LANG_C_plus_plus_11
1812 || l == translation_unit::LANG_C_plus_plus_14
1813 || l == translation_unit::LANG_C_plus_plus_20
1814 || l == translation_unit::LANG_C_plus_plus_23
1815 || l == translation_unit::LANG_C_plus_plus);
1825{
return l == translation_unit::LANG_Java;}
1835 return (l == translation_unit::LANG_Ada83
1836 || l == translation_unit::LANG_Ada95
1837 || l == translation_unit::LANG_Ada2005
1838 || l == translation_unit::LANG_Ada2012);
1851 if (l.get() == r.get())
1874struct elf_symbol::priv
1914 bool is_in_ksymtab_;
1917 bool is_suppressed_;
1932 is_in_ksymtab_(false),
1935 is_suppressed_(false)
1938 priv(
const environment& e,
1946 const elf_symbol::version& ve,
1968 is_common_ = type_ == COMMON_TYPE;
2013 const abg_compat::optional<uint32_t>& crc,
2014 const abg_compat::optional<std::string>& ns,
2078 elf_symbol_sptr sym(
new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2080 sym->priv_->main_symbol_ = sym;
2139{
return priv_->env_;}
2146{
return priv_->index_;}
2160{
return priv_->name_;}
2169 priv_->id_string_.clear();
2177{
return priv_->type_;}
2191{
return priv_->size_;}
2198{priv_->size_ = size;}
2205{
return priv_->binding_;}
2212{priv_->binding_ = b;}
2219{
return priv_->version_;}
2227 priv_->version_ = v;
2228 priv_->id_string_.clear();
2237{priv_->visibility_ = v;}
2245{
return priv_->visibility_;}
2253{
return priv_->is_defined_;}
2261{priv_->is_defined_ = d;}
2314{
return priv_->is_in_ksymtab_;}
2329{
return priv_->crc_;}
2343{
return priv_->namespace_;}
2350{priv_->namespace_ = ns;}
2359{
return priv_->is_suppressed_;}
2398{
return priv_->main_symbol_.lock();}
2405{
return priv_->main_symbol_.lock();}
2419{
return priv_->next_alias_.lock();}
2439 a = a->get_next_alias())
2462 a && !a->is_main_symbol();
2463 a = a->get_next_alias())
2465 if (a->get_next_alias()->is_main_symbol())
2473 last_alias->priv_->next_alias_ = alias;
2476 priv_->next_alias_ = alias;
2506 a = a->get_next_alias())
2507 if (a->get_name() == name)
2517 priv_->main_symbol_ = new_main;
2519 a = a->get_next_alias())
2520 a->priv_->main_symbol_ = new_main;
2530{
return priv_->is_common_;}
2561{
return priv_->next_common_instance_.lock();}
2576 ABG_ASSERT(!common->has_other_common_instances());
2585 c = c->get_next_common_instance())
2590 last_common_instance = c;
2595 last_common_instance->priv_->next_common_instance_ = common;
2598 priv_->next_common_instance_ = common;
2618 if (priv_->id_string_.empty())
2630 priv_->id_string_ = s;
2633 return priv_->id_string_;
2650 a = a->get_next_alias())
2651 if (a->get_name() == name)
2668 a && a.get() != a->get_main_symbol().get();
2669 a = a->get_next_alias())
2670 if (textually_equals(*
this, *a))
2687 bool include_symbol_itself)
const
2691 if (include_symbol_itself)
2695 compute_aliases_for_elf_symbol(*
this, syms, aliases);
2696 if (!aliases.empty() && include_symbol_itself)
2703 if (i != aliases.begin())
2705 result += (*i)->get_id_string();
2721 if (include_symbol_itself)
2726 a = a->get_next_alias())
2727 aliases.push_back(a);
2734 if (i != aliases.begin())
2736 result += (*i)->get_id_string();
2756 name.clear(), ver.clear();
2758 string::size_type i =
id.find(
'@');
2759 if (i == string::npos)
2765 name =
id.substr(0, i);
2771 string::size_type j =
id.find(
'@', i);
2772 if (j == string::npos)
2799 bool are_equal = textually_equals(*
this, other);
2820 a && !a->is_main_symbol();
2821 a = a->get_next_alias())
2845 return *lhs == *rhs;
2871compute_aliases_for_elf_symbol(
const elf_symbol& sym,
2877 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
2878 aliases.push_back(a);
2884 string_elf_symbols_map_type::const_iterator i =
2886 if (i == symtab.end())
2889 for (elf_symbols::const_iterator j = i->second.begin();
2890 j != i->second.end();
2895 s && !s->is_main_symbol();
2896 s = s->get_next_alias())
2897 aliases.push_back(s);
2900 s && !s->is_main_symbol();
2901 s = s->get_next_alias())
2903 aliases.push_back(*j);
2949 case elf_symbol::NOTYPE_TYPE:
2950 repr =
"unspecified symbol type";
2952 case elf_symbol::OBJECT_TYPE:
2953 repr =
"variable symbol type";
2955 case elf_symbol::FUNC_TYPE:
2956 repr =
"function symbol type";
2958 case elf_symbol::SECTION_TYPE:
2959 repr =
"section symbol type";
2961 case elf_symbol::FILE_TYPE:
2962 repr =
"file symbol type";
2964 case elf_symbol::COMMON_TYPE:
2965 repr =
"common data object symbol type";
2967 case elf_symbol::TLS_TYPE:
2968 repr =
"thread local data object symbol type";
2970 case elf_symbol::GNU_IFUNC_TYPE:
2971 repr =
"indirect function symbol type";
2975 std::ostringstream s;
2976 s <<
"unknown symbol type (" << (char)t <<
')';
2999 case elf_symbol::LOCAL_BINDING:
3000 repr =
"local binding";
3002 case elf_symbol::GLOBAL_BINDING:
3003 repr =
"global binding";
3005 case elf_symbol::WEAK_BINDING:
3006 repr =
"weak binding";
3008 case elf_symbol::GNU_UNIQUE_BINDING:
3009 repr =
"GNU unique binding";
3013 std::ostringstream s;
3014 s <<
"unknown binding (" << (
unsigned char) b <<
")";
3037 case elf_symbol::DEFAULT_VISIBILITY:
3038 repr =
"default visibility";
3040 case elf_symbol::PROTECTED_VISIBILITY:
3041 repr =
"protected visibility";
3043 case elf_symbol::HIDDEN_VISIBILITY:
3044 repr =
"hidden visibility";
3046 case elf_symbol::INTERNAL_VISIBILITY:
3047 repr =
"internal visibility";
3051 std::ostringstream s;
3052 s <<
"unknown visibility (" << (
unsigned char) v <<
")";
3074 t = elf_symbol::NOTYPE_TYPE;
3075 else if (s ==
"object-type")
3076 t = elf_symbol::OBJECT_TYPE;
3077 else if (s ==
"func-type")
3078 t = elf_symbol::FUNC_TYPE;
3079 else if (s ==
"section-type")
3080 t = elf_symbol::SECTION_TYPE;
3081 else if (s ==
"file-type")
3082 t = elf_symbol::FILE_TYPE;
3083 else if (s ==
"common-type")
3084 t = elf_symbol::COMMON_TYPE;
3085 else if (s ==
"tls-type")
3086 t = elf_symbol::TLS_TYPE;
3087 else if (s ==
"gnu-ifunc-type")
3088 t = elf_symbol::GNU_IFUNC_TYPE;
3106 if (s ==
"local-binding")
3107 b = elf_symbol::LOCAL_BINDING;
3108 else if (s ==
"global-binding")
3109 b = elf_symbol::GLOBAL_BINDING;
3110 else if (s ==
"weak-binding")
3111 b = elf_symbol::WEAK_BINDING;
3112 else if (s ==
"gnu-unique-binding")
3113 b = elf_symbol::GNU_UNIQUE_BINDING;
3131 if (s ==
"default-visibility")
3132 v = elf_symbol::DEFAULT_VISIBILITY;
3133 else if (s ==
"protected-visibility")
3134 v = elf_symbol::PROTECTED_VISIBILITY;
3135 else if (s ==
"hidden-visibility")
3136 v = elf_symbol::HIDDEN_VISIBILITY;
3137 else if (s ==
"internal-visibility")
3138 v = elf_symbol::INTERNAL_VISIBILITY;
3153{
return t == elf_symbol::FUNC_TYPE;}
3163{
return t == elf_symbol::OBJECT_TYPE;}
3167struct elf_symbol::version::priv
3173 : is_default_(false)
3176 priv(
const string& v,
3183elf_symbol::version::version()
3190elf_symbol::version::version(
const string& v,
3196 : priv_(new priv(v.str(), v.is_default()))
3200elf_symbol::version::~version() =
default;
3205elf_symbol::version::operator
const string&()
const
3206{
return priv_->version_;}
3213{
return priv_->version_;}
3220{priv_->version_ = s;}
3227{
return priv_->is_default_;}
3234{priv_->is_default_ = f;}
3237elf_symbol::version::is_empty()
const
3238{
return str().empty();}
3247{
return str() == o.
str();}
3276struct dm_context_rel::priv
3279 size_t offset_in_bits_;
3282 priv(
bool is_static =
false)
3283 : is_laid_out_(!is_static),
3285 anonymous_data_member_()
3288 priv(
bool is_laid_out,
size_t offset_in_bits)
3289 : is_laid_out_(is_laid_out),
3290 offset_in_bits_(offset_in_bits),
3291 anonymous_data_member_()
3295dm_context_rel::dm_context_rel()
3300dm_context_rel::dm_context_rel(scope_decl* s,
3302 size_t offset_in_bits,
3305 : context_rel(s, a, is_static),
3306 priv_(new priv(is_laid_out, offset_in_bits))
3309dm_context_rel::dm_context_rel(scope_decl* s)
3315dm_context_rel::get_is_laid_out()
const
3316{
return priv_->is_laid_out_;}
3319dm_context_rel::set_is_laid_out(
bool f)
3320{priv_->is_laid_out_ = f;}
3323dm_context_rel::get_offset_in_bits()
const
3324{
return priv_->offset_in_bits_;}
3327dm_context_rel::set_offset_in_bits(
size_t o)
3328{priv_->offset_in_bits_ = o;}
3331dm_context_rel::operator==(
const dm_context_rel& o)
const
3333 if (!context_rel::operator==(o))
3336 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3337 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3341dm_context_rel::operator!=(
const dm_context_rel& o)
const
3352{
return priv_->anonymous_data_member_;}
3362{priv_->anonymous_data_member_ = anon_dm;}
3364dm_context_rel::~dm_context_rel()
3390{
return priv_->canonical_types_;}
3434 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
3459 result.push_back(t);
3462 std::stable_sort(result.begin(), result.end(), comp);
3474const type_base_sptr&
3477 if (!priv_->void_type_)
3478 priv_->void_type_.reset(
new type_decl(*
this,
3481 return priv_->void_type_;
3493const type_base_sptr&
3496 if (!priv_->void_pointer_type_)
3499 return priv_->void_pointer_type_;
3512const type_base_sptr&
3515 if (!priv_->variadic_marker_type_)
3516 priv_->variadic_marker_type_.
3519 return priv_->variadic_marker_type_;
3528 static string variadic_parameter_type_name =
"variadic parameter type";
3529 return variadic_parameter_type_name;
3539{
return priv_->canonicalization_is_done_;}
3554 priv_->canonicalization_is_done_ = f;
3555 if (priv_->canonicalization_is_done_)
3566{
return priv_->canonicalization_started_;}
3575{priv_->canonicalization_started_ = f;}
3599{
return priv_->decl_only_class_equals_definition_;}
3624{priv_->decl_only_class_equals_definition_ = f;}
3729{
return const_cast<environment*
>(
this)->priv_->string_pool_.create_string(s);}
3736{
return priv_->config_;}
3746{
return priv_->analyze_exported_interfaces_only_.has_value();}
3759{priv_->analyze_exported_interfaces_only_ = f;}
3772{
return priv_->analyze_exported_interfaces_only_.value_or(
false);}
3774#ifdef WITH_DEBUG_SELF_COMPARISON
3787environment::set_self_comparison_debug_input(
const corpus_sptr& c)
3789 self_comparison_debug_is_on(
true);
3790 if (priv_->first_self_comparison_corpus_.expired())
3791 priv_->first_self_comparison_corpus_ = c;
3792 else if (priv_->second_self_comparison_corpus_.expired()
3793 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
3794 priv_->second_self_comparison_corpus_ = c;
3807environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
3808 corpus_sptr& second_corpus)
3810 first_corpus = priv_->first_self_comparison_corpus_.lock();
3811 second_corpus = priv_->second_self_comparison_corpus_.lock();
3818environment::self_comparison_debug_is_on(
bool f)
3819{priv_->self_comparison_debug_on_ = f;}
3826environment::self_comparison_debug_is_on()
const
3827{
return priv_->self_comparison_debug_on_;}
3830#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
3837environment::debug_type_canonicalization_is_on(
bool flag)
3838{priv_->debug_type_canonicalization_ = flag;}
3846environment::debug_type_canonicalization_is_on()
const
3847{
return priv_->debug_type_canonicalization_;}
3855environment::debug_die_canonicalization_is_on(
bool flag)
3856{priv_->debug_die_canonicalization_ = flag;}
3864environment::debug_die_canonicalization_is_on()
const
3865{
return priv_->debug_die_canonicalization_;}
3908 if (!types ||index >= types->size())
3910 return (*types)[index].get();
3913#ifdef WITH_DEBUG_SELF_COMPARISON
3923const unordered_map<string, uintptr_t>&
3924environment::get_type_id_canonical_type_map()
const
3925{
return priv_->get_type_id_canonical_type_map();}
3936unordered_map<string, uintptr_t>&
3937environment::get_type_id_canonical_type_map()
3938{
return priv_->get_type_id_canonical_type_map();}
3953const unordered_map<uintptr_t, string>&
3954environment::get_pointer_type_id_map()
const
3955{
return priv_->get_pointer_type_id_map();}
3970unordered_map<uintptr_t, string>&
3971environment::get_pointer_type_id_map()
3972{
return priv_->get_pointer_type_id_map();}
3990environment::get_type_id_from_pointer(uintptr_t ptr)
const
3991{
return priv_->get_type_id_from_pointer(ptr);}
4009environment::get_type_id_from_type(
const type_base *t)
const
4010{
return priv_->get_type_id_from_type(t);}
4027environment::get_canonical_type_from_type_id(
const char* type_id)
const
4028{
return priv_->get_canonical_type_from_type_id(type_id);}
4042 (
static_cast<unsigned>(l) |
static_cast<unsigned>(r));
4062 (
static_cast<unsigned>(l) &
static_cast<unsigned>(r));
4083 :priv_(new
priv(e, k))
4099{
return priv_->is_artificial_;}
4111{priv_->is_artificial_ = f;}
4122{
return priv_->kind();}
4142{
return priv_->rtti_;}
4151{
return priv_->rtti_;}
4163 priv_->type_or_decl_ptr_ = t;
4165 priv_->type_or_decl_ptr_ = d;
4188{
return priv_->type_or_decl_ptr_;}
4199{
return priv_->hash_value_;}
4202type_or_decl_base::set_hash_value(
hash_t h)
const
4203{priv_->set_hash_value(h);}
4210{
return priv_->env_;}
4228{priv_->artificial_location_ = l;}
4246{
return priv_->artificial_location_;}
4254 return (priv_->artificial_location_
4255 && priv_->artificial_location_.get_is_artificial());
4278{
return const_cast<type_or_decl_base*
>(
this)->
get_corpus();}
4286{priv_->translation_unit_ = tu;}
4295{
return priv_->translation_unit_;}
4327 *dr =
dynamic_cast<const decl_base*
>(r);
4336 *tr =
dynamic_cast<const type_base*
>(r);
4381struct decl_base::priv
4383 bool in_pub_sym_tab_;
4410 visibility visibility_;
4411 decl_base_sptr declaration_;
4413 decl_base* naked_definition_of_declaration_;
4414 bool is_declaration_only_;
4418 : in_pub_sym_tab_(false),
4419 is_anonymous_(true),
4421 visibility_(VISIBILITY_DEFAULT),
4422 naked_definition_of_declaration_(),
4423 is_declaration_only_(false)
4426 priv(interned_string name, interned_string linkage_name, visibility vis)
4427 : in_pub_sym_tab_(false),
4430 qualified_name_(name),
4431 linkage_name_(linkage_name),
4433 naked_definition_of_declaration_(),
4434 is_declaration_only_(false)
4436 is_anonymous_ = name_.
empty();
4461 const string& linkage_name,
4463 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4464 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
4487 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4488 priv_(new priv(name, linkage_name, vis))
4501 : type_or_decl_base(e, ABSTRACT_DECL_BASE),
4515{
return priv_->qualified_name_;}
4524{priv_->qualified_name_.
clear();}
4531{priv_->qualified_name_ = n;}
4544{
return priv_->temporary_qualified_name_;}
4558{priv_->temporary_qualified_name_ = n;}
4565{
return priv_->context_;}
4572{
return priv_->context_;}
4576{priv_->context_ = c;}
4585{
return priv_->in_pub_sym_tab_;}
4593{priv_->in_pub_sym_tab_ = f;}
4613{
return priv_->location_;}
4655 priv_->location_ = l;
4665 priv_->is_anonymous_ = n.empty();
4676{
return priv_->is_anonymous_;}
4686{priv_->is_anonymous_ = f;}
4723{
return priv_->naming_typedef_;}
4751 &&
is_type(
this)->get_naked_canonical_type() ==
nullptr);
4753 priv_->naming_typedef_ = t;
4760 update_qualified_name(
this);
4768{
return priv_->linkage_name_;}
4777 priv_->linkage_name_ = env.
intern(m);
4785{
return priv_->visibility_;}
4792{priv_->visibility_ = v;}
4801 if (priv_->context_)
4812{
return priv_->qualified_parent_name_;}
4819{
return priv_->name_;}
4854 bool qualified_name)
const
4858 && has_generic_anonymous_internal_type_name(
this))
4869 string name = get_generic_anonymous_internal_type_name(
this);
4905 if (priv_->internal_cached_repr_.empty())
4910 return priv_->internal_cached_repr_;
4913 if (priv_->cached_repr_.empty())
4919 return priv_->cached_repr_;
4939{
return priv_->qualified_name_;}
4953{
return priv_->scoped_name_;}
4961{
return priv_->declaration_;}
4970 if (d && d->get_is_declaration_only())
4971 priv_->declaration_ = d;
4981{
return priv_->definition_of_declaration_.lock();}
4997{
return priv_->naked_definition_of_declaration_;}
5004{
return priv_->is_declaration_only_;}
5014 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
5016 priv_->is_declaration_only_ = f;
5018 if (update_types_lookup_map)
5021 scope_decl::declarations::iterator i;
5022 if (s->find_iterator_for_member(
this, i))
5032 return static_cast<change_kind>(
static_cast<unsigned>(l)
5033 |
static_cast<unsigned>(r));
5039 return static_cast<change_kind>(
static_cast<unsigned>(l)
5040 &
static_cast<unsigned>(r));
5087 bool member_types_or_functions =
5091 if (member_types_or_functions)
5100 la = r1->get_access_specifier();
5101 ra = r2->get_access_specifier();
5102 r1->set_access_specifier(no_access);
5103 r2->set_access_specifier(no_access);
5106 bool rels_are_different = *r1 != *r2;
5108 if (member_types_or_functions)
5111 r1->set_access_specifier(la);
5112 r2->set_access_specifier(ra);
5115 if (rels_are_different)
5150 if (!l_linkage_name.
empty() && !r_linkage_name.
empty())
5152 if (l_linkage_name != r_linkage_name)
5192 bool decls_are_same = (ln == rn);
5194 if (!decls_are_same)
5217{
return equals(*
this, other, 0);}
5256 if (!priv_->context_)
5259 priv_->context_->set_scope(scope);
5277 case decl_base::VISIBILITY_NONE:
5280 case decl_base::VISIBILITY_DEFAULT:
5283 case decl_base::VISIBILITY_PROTECTED:
5286 case decl_base::VISIBILITY_HIDDEN:
5289 case decl_base::VISIBILITY_INTERNAL:
5309 case decl_base::BINDING_NONE:
5312 case decl_base::BINDING_LOCAL:
5315 case decl_base::BINDING_GLOBAL:
5318 case decl_base::BINDING_WEAK:
5341 if (l.get() == r.get())
5377 if (l.get() == r.get())
5463{
return dynamic_pointer_cast<scope_decl>(d);}
5529 return c->get_access_specifier();
5559 c->set_access_specifier(a);
5589 return c->get_is_static();
5731 var_decl_sptr first = *klass->get_non_static_data_members().begin();
5752 if (!klass ||!data_member)
5755 for (class_or_union::data_members::const_iterator it =
5759 if (**it == *data_member)
5828 bool result =
false;
5846 dms[member->get_name()] = member;
6055 return class_or_union_sptr();
6064const class_or_union_sptr
6069 if (cou->get_is_anonymous())
6072 return class_or_union_sptr();
6081const class_or_union_sptr
6086 return class_or_union_sptr();
6095const class_or_union_sptr
6110 return class_or_union_sptr();
6135 for (
auto anon_dm_m : cl->get_non_static_data_members())
6182 ctxt_rel->set_offset_in_bits(o);
6197 return ctxt_rel->get_offset_in_bits();
6287 const var_decl *containing_anonymous_data_member =
6290 uint64_t containing_anonymous_data_member_offset = 0;
6291 if (containing_anonymous_data_member)
6292 containing_anonymous_data_member_offset =
6295 return (ctxt_rel->get_offset_in_bits()
6297 containing_anonymous_data_member_offset);
6325 type_base_sptr t = v->get_type();
6328 return t->get_size_in_bits();
6342 ctxt_rel->set_is_laid_out(l);
6357 return ctxt_rel->get_is_laid_out();
6589 const method_decl* m =
6590 dynamic_cast<const method_decl*
>(&f);
6618set_member_function_vtable_offset(
function_decl& f, ssize_t s)
6640{
return set_member_function_vtable_offset(*f, s);}
6659 return ctxt->is_virtual();
6686set_member_function_is_virtual(
function_decl& f,
bool is_virtual)
6696 ctxt->is_virtual(is_virtual);
6709 set_member_function_is_virtual(*fn, is_virtual);
6728 set_member_function_vtable_offset(fn, voffset);
6729 set_member_function_is_virtual(fn, is_virtual);
6760 set_member_function_vtable_offset(fn, voffset);
6761 set_member_function_is_virtual(fn, is_virtual);
6798 if (!cl->get_canonical_type())
6804 type_base_sptr t = type;
6815 ty->get_size_in_bits(),
6816 ty->get_alignment_in_bits(),
6817 ty->get_location()));
6825 ty->get_size_in_bits(),
6826 ty->get_alignment_in_bits(),
6827 ty->get_location()));
6836 ty->get_location()));
6842 t.reset(
new array_type_def(p, ty->get_subranges(), ty->get_location()));
6847 for (function_decl::parameters::const_iterator i =
6848 ty->get_parameters().begin();
6849 i != ty->get_parameters().end();
6860 p->get_variadic_marker(),
6861 p->get_is_artificial()));
6862 parm.push_back(stripped);
6867 parm, ty->get_is_const(),
6868 ty->get_size_in_bits(),
6869 ty->get_alignment_in_bits()));
6874 for (function_decl::parameters::const_iterator i =
6875 ty->get_parameters().begin();
6876 i != ty->get_parameters().end();
6887 p->get_variadic_marker(),
6888 p->get_is_artificial()));
6889 parm.push_back(stripped);
6894 ty->get_size_in_bits(),
6895 ty->get_alignment_in_bits()));
6898 if (!t->get_translation_unit())
6899 t->set_translation_unit(type->get_translation_unit());
6904 return t->get_canonical_type() ? t->get_canonical_type() : t;
6927 decl_base_sptr result = t;
6928 type_base_sptr u = t->get_underlying_type();
6931 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
6933 || (t->get_cv_quals() & qualified_type_def::CV_CONST
6935 || t->get_cv_quals() == qualified_type_def::CV_NONE)
6981static qualified_type_def_sptr
6982strip_redundant_quals_from_underyling_types(
const qualified_type_def_sptr& t,
6991 qualified_type_def_sptr underlying_qualified_type =
6999 currated_quals &= ~redundant_quals;
7000 t->set_cv_quals(currated_quals);
7004 redundant_quals |= currated_quals;
7006 qualified_type_def_sptr result = t;
7007 if (underlying_qualified_type)
7011 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
7045strip_redundant_quals_from_underyling_types(
const qualified_type_def_sptr& t)
7051 strip_redundant_quals_from_underyling_types(t, redundant_quals);
7078 return t->get_underlying_type();
7132 return t->get_pointed_to_type();
7188 return t->get_pointed_to_type();
7313 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
7346 return q->get_underlying_type();
7395 type_base_sptr type = t;
7418 type_base_sptr typ = type;
7480 bool peel_qual_type)
7519 bool peel_qual_type)
7560 array->get_subranges().begin();
7561 i != array->get_subranges().end();
7567 (*i)->get_lower_bound(),
7568 (*i)->get_upper_bound(),
7569 (*i)->get_underlying_type(),
7570 (*i)->get_location(),
7571 (*i)->get_language()));
7572 subrange->is_non_finite((*i)->is_non_finite());
7575 subranges.push_back(subrange);
7580 subranges, array->get_location()));
7603 (
new typedef_decl(t->get_name(), t->get_underlying_type(),
7604 t->get_location(), t->get_linkage_name(),
7605 t->get_visibility()));
7621qualified_type_def_sptr
7627 qualified_type_def_sptr result
7629 t->get_cv_quals(), t->get_location()));
7641static type_base_sptr
7642clone_typedef_array_qualified_type(type_base_sptr type)
7648 type_base_sptr result;
7657 return type_base_sptr();
7680 type_base_sptr result = clone_typedef_array_qualified_type(t);
7683 type_base_sptr subtree;
7687 clone_typedef_array_qualified_type(type->get_underlying_type());
7691 type->set_underlying_type(subtree);
7697 clone_typedef_array_qualified_type(type->get_element_type());
7701 type->set_element_type(subtree);
7711 clone_typedef_array_qualified_type(t->get_underlying_type());
7718 t->set_underlying_type (s);
7727 clone_typedef_array_qualified_type(t->get_underlying_type());
7734 t->set_underlying_type(s);
7742 type_base_sptr e = t->get_element_type();
7746 clone_typedef_array_qualified_type(e);
7752 t->set_element_type(s);
7771 ::qualified_name_setter setter;
7779update_qualified_name(decl_base_sptr d)
7780{
return update_qualified_name(d.get());}
7800{
return reinterpret_cast<size_t>(l);}
7802struct scope_decl::priv
7811 bool clear_sorted_member_types_cache_ =
false;
7828 decl_base(env, name, locus, name, vis),
7841 decl_base(env,
"", l),
7848{
return priv_->canonical_types_;}
7866 if (priv_->sorted_canonical_types_.empty())
7868 for (canonical_type_sptr_set_type::const_iterator e =
7872 priv_->sorted_canonical_types_.push_back(*e);
7875 std::stable_sort(priv_->sorted_canonical_types_.begin(),
7876 priv_->sorted_canonical_types_.end(),
7879 return priv_->sorted_canonical_types_;
7889{
return priv_->members_;}
7898{
return priv_->members_;}
7909 if (priv_->sorted_members_.empty())
7914 priv_->sorted_members_.push_back(*i);
7916 std::stable_sort(priv_->sorted_members_.begin(),
7917 priv_->sorted_members_.end(),
7920 return priv_->sorted_members_;
7935 if (t->get_is_anonymous())
7953 if (t->get_is_anonymous())
7971 if (t->get_is_anonymous())
7982{
return priv_->member_scopes_;}
7989{
return priv_->member_scopes_;}
8011maybe_set_translation_unit(
const decl_base_sptr& decl,
8028 decl->set_translation_unit(tu);
8045 member->set_scope(
this);
8046 priv_->members_.push_back(member);
8049 priv_->member_types_.push_back(
is_type(member));
8050 priv_->clear_sorted_member_types_cache_ =
true;
8054 priv_->member_scopes_.push_back(m);
8056 update_qualified_name(member);
8059 maybe_set_translation_unit(member, tu);
8071{
return priv_->member_types_;}
8086 return type_base_sptr();
8096 declarations::iterator before)
8102 priv_->member_types_.push_back(t);
8103 priv_->clear_sorted_member_types_cache_=
true;
8139 for (
auto i = priv_->member_types_.begin();
8140 i != priv_->member_types_.end();
8145 priv_->member_types_.erase(i);
8158 if (priv_->clear_sorted_member_types_cache_)
8160 priv_->sorted_member_types_.clear();
8161 priv_->clear_sorted_member_types_cache_ =
false;
8164 if (priv_->sorted_member_types_.empty())
8166 unordered_set<type_base_sptr> canonical_pointer_types;
8170 priv_->sorted_member_types_.push_back(t);
8171 else if (
auto c = t->get_canonical_type())
8172 canonical_pointer_types.insert(c);
8174 canonical_pointer_types.insert(t);
8177 for (
auto t : canonical_pointer_types)
8178 priv_->sorted_member_types_.push_back(t);
8181 std::stable_sort(priv_->sorted_member_types_.begin(),
8182 priv_->sorted_member_types_.end(),
8188 priv_->clear_sorted_member_types_cache_ =
true;
8190 return priv_->sorted_member_types_;
8206 declarations::iterator before)
8210 member->set_scope(
this);
8211 priv_->members_.insert(before, member);
8214 priv_-> member_scopes_.push_back(m);
8216 update_qualified_name(member);
8219 maybe_set_translation_unit(member, tu);
8232 for (declarations::iterator i = priv_->members_.begin();
8233 i != priv_->members_.end();
8238 priv_->members_.erase(i);
8248 for (scopes::iterator i = priv_->member_scopes_.begin();
8249 i != priv_->member_scopes_.end();
8254 priv_->member_scopes_.erase(i);
8260 member->set_scope(
nullptr);
8261 member->set_translation_unit(
nullptr);
8288 if (!l.decl_base::operator==(r))
8297 scope_decl::declarations::const_iterator i, j;
8335 const scope_decl* other =
dynamic_cast<const scope_decl*
>(&o);
8339 return equals(*
this, *other, 0);
8354 if (l.get() == r.get())
8380 declarations::iterator& i)
8395 if ((*it).get() == decl)
8415 declarations::iterator& i)
8432 if (v.visit_begin(
this))
8435 for (scope_decl::declarations::const_iterator i =
8439 if (!(*i)->traverse(v))
8443 return v.visit_end(
this);
8446scope_decl::~scope_decl()
8462 if (scope && decl && !decl->get_scope())
8487 scope_decl* scope = decl->get_scope();
8502 scope_decl::declarations::iterator before,
8505 if (scope && decl && !decl->get_scope())
8524 scope_decl::declarations::iterator before,
8534 | ABSTRACT_DECL_BASE
8535 | ABSTRACT_SCOPE_DECL),
8538 translation_unit_(tu)
8540 runtime_type_instance(
this);
8559 return scope ?
dynamic_cast<global_scope*
> (scope) : 0;
8666 if (cv_quals & qualified_type_def::CV_RESTRICT)
8668 if (cv_quals & qualified_type_def::CV_CONST)
8674 if (cv_quals & qualified_type_def::CV_VOLATILE)
8726{
return get_name(tod.get(), qualified);}
8744 string qualified_name;
8748 if (qualified_name.empty())
8749 qualified_name = name;
8751 qualified_name = qualified_name +
"::" + name;
8753 return qualified_name;
8788 location loc = decl->get_location();
8792 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
8795 loc = c->get_location();
8853has_generic_anonymous_internal_type_name(
const decl_base *d)
8870static interned_string
8871get_generic_anonymous_internal_type_name(
const decl_base *d)
8873 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
8875 const environment&env = d->get_environment();
8877 interned_string result;
8910get_internal_real_type_name(
const type_base* t)
8920 name = int_type.to_string(
true);
8945 return empty_string;
8952 return empty_string;
8969 r += get_generic_anonymous_internal_type_name(d);
8979 return env.
intern(get_internal_real_type_name(t));
8988 internal, qualified));
9027 bool qualified,
bool internal)
9030 string tn =
get_type_name(pointed_to_type, qualified, internal);
9049 bool lvalue_reference,
9050 bool qualified,
bool internal)
9054 string name =
get_type_name(pointed_to_type, qualified, internal);
9055 if (lvalue_reference)
9080 bool qualified,
bool internal)
9082 const environment& env = underlying_type->get_environment();
9085 string name =
get_type_name(underlying_type, qualified, internal);
9087 if (quals_repr.empty() && internal)
9099 if (!quals_repr.empty())
9108 name = quals_repr +
" " + name;
9165 std::ostringstream o;
9174 stream_pretty_representation_of_fn_parms(fn_type, o,
9177 return env.
intern(o.str());
9196 c->get_exported_decls_builder();
9197 if (b->fn_id_maps_to_several_fns(fn))
9253 std::ostringstream o;
9272 o <<
" (" << class_type->get_qualified_name(internal) <<
"::*) ";
9273 stream_pretty_representation_of_fn_parms(fn_type, o,
9277 return env.
intern(o.str());
9443 std::ostringstream o;
9461 std::ostringstream o;
9516 const string& indent,
9519 bool qualified_names)
9522 string local_indent =
" ";
9527 if (!internal && clazz->is_struct())
9533 repr = indent +
"union";
9566 for (class_or_union::data_members::const_iterator dm = dmems.begin();
9570 if (dm != dmems.begin())
9575 real_indent =
"\n" + indent + local_indent;
9582 real_indent, one_line, internal, qualified_names);
9587 if (dm != dmems.begin())
9588 repr += real_indent;
9589 repr += (*dm)->get_pretty_representation(internal,
9594 real_indent+ (*dm)->get_pretty_representation(internal,
9603 repr += indent +
"}";
9631 const string& indent,
9634 bool qualified_names)
9638 internal, qualified_names);
9660 const string& indent,
9663 bool qualified_names)
9692 const string& indent,
bool one_line,
9693 bool qualified_names)
9696 std::ostringstream o;
9697 string local_indent =
" ";
9699 repr = indent +
"enum ";
9702 o << (qualified_names
9716 o << enumerator.get_name() +
"=" << enumerator.get_value() <<
", ";
9720 o <<
"\n" + indent <<
"}";
9751 const string& indent,
bool one_line,
9752 bool qualified_names)
9758 one_line, qualified_names);
9783 const string& indent,
bool one_line,
9784 bool qualified_names)
9813 const string& indent,
9816 bool qualified_name)
9822 internal, qualified_name);
9851 std::ostringstream o;
9866 o <<
" :" << std::endl;
9870 if (b->get_is_virtual())
9872 o << b->get_base_class()->get_qualified_name()
9876 o << std::hex << *h << std::dec;
9887 <<
" // translation unit: "
9892 <<
" // @: " << std::hex <<
is_type(c)
9898 o << std::hex << *h << std::dec;
9908 << member_type->get_pretty_representation(
false,
9911 if (member_type->get_canonical_type())
9913 o <<
" // uses canonical type: '@"
9914 << std::hex << member_type->get_canonical_type().get() <<
"'";
9917 o << std::hex << *h << std::dec;
9937 if (t && t->get_canonical_type())
9938 o <<
" // uses canonical type '@"
9939 << std::hex << t->get_canonical_type().get() <<
"'";
9944 o << std::hex << *h << std::dec;
9955 o <<
" // virtual member functions\n\n";
9964 o << std::hex << *h << std::dec;
9967 o <<
";" << std::endl;
9971 o <<
"};" << std::endl;
9977 string name = e->get_qualified_name();
9978 std::ostringstream o;
9979 o <<
"enum " << name
9981 << e->get_underlying_type()->get_pretty_representation(
false,
9985 <<
" // size in bits: " << e->get_size_in_bits() <<
"\n"
9986 <<
" // is-declaration-only: " << e->get_is_declaration_only() <<
"\n"
9988 <<
" // translation unit: "
9989 << e->get_translation_unit()->get_absolute_path() <<
"\n"
9990 <<
" // @: " << std::hex <<
is_type(e)
9991 <<
", @canonical: " << e->get_canonical_type().get() << std::dec <<
"\n"
9996 o << std::hex << *h << std::dec;
10002 for (
const auto &enom : e->get_enumerators())
10003 o <<
" " << enom.get_name() <<
" = " << enom.get_value() <<
",\n";
10011 std::ostringstream o;
10012 o << t->get_pretty_representation(
true,
10019 return artifact->get_pretty_representation(
true,
10118 return const_cast<type_base*
>(artifact);
10135 return const_cast<decl_base*
>(artifact);
10167 for (
auto t : vect)
10169 o <<
"|" << t->get_pretty_representation()
10170 <<
"@" << std::hex << t << std::dec;
10184 std::ostringstream o;
10185 o <<
"left-operands: ";
10186 debug_comp_vec(env.priv_->left_type_comp_operands_, o);
10187 o <<
"\n" <<
"right-operands: ";
10188 debug_comp_vec(env.priv_->right_type_comp_operands_, o);
10201 std::cerr << print_comp_stack(env);
10202 std::cerr << std::endl;
10237{
return dynamic_cast<const decl_base*
>(t);}
10255{
return dynamic_pointer_cast<decl_base>(t);}
10271#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10272#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10275#ifdef ENSURE_NO_ENDLESS_LOOP
10276#undef ENSURE_NO_ENDLESS_LOOP
10279#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
10282 auto t1 = is_class_or_union_type(f); \
10283 auto t2 = is_class_or_union_type(s); \
10284 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
10285 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
10289#define ENSURE_NO_ENDLESS_LOOP \
10292 auto t1 = is_class_or_union_type(f); \
10293 auto t2 = is_class_or_union_type(s); \
10294 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
10295 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
10296 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
10298 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
10299 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
10307 || (fc->get_qualified_name() != sc->get_qualified_name())
10308 || (fc->get_size_in_bits() != sc->get_size_in_bits())
10309 || (fc->get_data_members().size() != sc->get_data_members().size()))
10313 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
true);
10316 for (
auto f_decl_it = fc->get_data_members().begin(),
10317 s_decl_it = sc->get_data_members().begin();
10318 (f_decl_it != fc->get_data_members().end()
10319 && s_decl_it != sc->get_data_members().end());
10320 ++f_decl_it, ++s_decl_it)
10323 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
10325 if (*dm1_type != *dm2_type
10327 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
10331 for (
auto f_bs_it = fc->get_base_specifiers().begin(),
10332 s_bs_it = sc->get_base_specifiers().end();
10333 (f_bs_it != fc->get_base_specifiers().end()
10334 && s_bs_it != sc->get_base_specifiers().end());
10335 ++f_bs_it, ++s_bs_it)
10338 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
10339 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
10340 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
10342 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
10344 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
10347 if (fc->has_vtable() != sc->has_vtable())
10348 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
10351 ENSURE_NO_ENDLESS_LOOP;
10352 if (fc->has_vtable())
10354 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
10356 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
10358 for (
auto it1 = fc->get_virtual_mem_fns().begin(),
10359 it2 = sc->get_virtual_mem_fns().begin();
10360 (it1 != fc->get_virtual_mem_fns().end()
10361 && it2 != sc->get_virtual_mem_fns().end());
10364 method_decl_sptr method1 = *it1;
10365 method_decl_sptr method2 = *it2;
10370 method2->get_type()))
10371 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
10375 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
true);
10377#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10378#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
10381#ifdef ENSURE_NO_ENDLESS_LOOP
10382#undef ENSURE_NO_ENDLESS_LOOP
10406 if (!type1 || !type2)
10409 if (type1 == type2 || *type1 == *type2)
10415 if (t1 && t2 && *t1 == *t2)
10439 type_base_sptr e1 = a1->get_element_type();
10440 type_base_sptr e2 = a2->get_element_type();
10444 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
10445 || (a1->get_dimension_count() != a2->get_dimension_count())
10457 fn_type2->get_return_type()))
10464 if (fn_type1->get_parameters().size()
10465 != fn_type2->get_parameters().size())
10468 for (
auto p1 = fn_type1->get_first_non_implicit_parm(),
10469 p2 = fn_type2->get_first_non_implicit_parm();
10470 (p1 != fn_type1->get_parameters().end()
10471 && p2 != fn_type2->get_parameters().end());
10474 (*p2)->get_type()))
10500 const decl_base_sptr d2)
10661 const string& name)
10666 if (!containing_class_or_union)
10683{
return (decl &&
dynamic_cast<template_decl*
>(decl->get_scope()));}
10693 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
10694 || dynamic_pointer_cast<non_type_tparameter>(decl)
10695 || dynamic_pointer_cast<template_tparameter>(decl)));
10725{
return dynamic_pointer_cast<function_decl>(d);}
10748{
return dynamic_pointer_cast<function_decl::parameter>(tod);}
10759 if (d && (d->
kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
10761 if (!(d->
kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10768 (
const_cast<type_or_decl_base*
>(d)->type_or_decl_base_pointer());
10774 return dynamic_cast<decl_base*
>(
const_cast<type_or_decl_base*
>(d));
10787{
return dynamic_pointer_cast<decl_base>(d);}
10809{
return dynamic_pointer_cast<decl_base>(t);}
10819 if (
dynamic_cast<const type_base*
>(&tod))
10832 if (t && (t->
kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
10834 (
const_cast<type_or_decl_base*
>(t)->type_or_decl_base_pointer());
10846{
return dynamic_pointer_cast<type_base>(tod);}
10878 if (!cou->get_naming_typedef())
10920{
return dynamic_cast<const type_decl*
>(t);}
10928{
return dynamic_pointer_cast<type_decl>(t);}
11022{
return dynamic_pointer_cast<typedef_decl>(t);}
11120{
return dynamic_pointer_cast<enum_type_decl>(d);}
11189 if (t->
kind() & type_or_decl_base::CLASS_TYPE)
11191 (
const_cast<type_or_decl_base*
>(t)->runtime_type_instance());
11203{
return dynamic_pointer_cast<class_decl>(d);}
11225 if (array->is_non_finite())
11295 if (array->get_subranges().size() == 1
11296 && array->get_subranges()[0]->get_length() == 1)
11366 return klass->get_is_declaration_only();
11415shared_ptr<class_or_union>
11417{
return dynamic_pointer_cast<class_or_union>(t);}
11446 const class_or_union_sptr& second)
11476{
return dynamic_pointer_cast<union_decl>(t);}
11490 bool look_through_qualifiers)
11496 if (look_through_qualifiers)
11514 bool look_through_qualifiers)
11516 type_base_sptr type =
is_type(t);
11517 if (look_through_qualifiers)
11519 return dynamic_pointer_cast<pointer_type_def>(type);
11662 bool look_through_qualifiers)
11668 if (look_through_qualifiers)
11685 bool look_through_qualifiers)
11689 if (look_through_qualifiers)
11706 bool look_through_qualifiers)
11708 type_base_sptr type =
is_type(t);
11709 if (look_through_qualifiers)
11711 return dynamic_pointer_cast<reference_type_def>(type);
11722 bool look_through_qualifiers)
11725 if (look_through_qualifiers)
11742 bool look_through_qualifiers)
11744 type_base_sptr type =
is_type(t);
11745 if (look_through_qualifiers)
11747 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
11821const type_base_sptr
11824 type_base_sptr nil;
11828 if (t->get_environment().get_void_pointer_type().get() == t.get())
11857qualified_type_def_sptr
11859{
return dynamic_pointer_cast<qualified_type_def>(t);}
11869{
return dynamic_pointer_cast<function_type>(t);}
11899{
return dynamic_pointer_cast<method_type>(t);}
11979 decl_base_sptr decl;
11986 while (decl->get_is_declaration_only()
11987 && decl->get_definition_of_declaration())
11988 decl = decl->get_definition_of_declaration();
12055 decl_base_sptr d =
is_decl(t);
12080{
return dynamic_pointer_cast<var_decl>(decl);}
12089{
return dynamic_pointer_cast<namespace_decl>(d);}
12123 && dynamic_pointer_cast<function_decl>(decl)
12134 bool look_through_qualifiers)
12138 if (look_through_qualifiers)
12150 bool look_through_qualifiers)
12152 type_base_sptr t =
is_type(type);
12154 if (look_through_qualifiers)
12156 return dynamic_pointer_cast<array_type_def>(t);
12165qualified_type_def_sptr
12169 return qualified_type_def_sptr();
12239{
return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
12249{
return decl && dynamic_pointer_cast<template_decl>(decl);}
12255 LOOKUP_ENTITY_TYPE,
12287find_next_delim_in_cplus_type(
const string& fqn,
12291 int angle_count = 0;
12292 bool found =
false;
12294 for (; i < fqn.size(); ++i)
12298 else if (fqn[i] ==
'>')
12300 else if (i + 1 < fqn.size()
12303 && fqn[i+1] ==
':')
12320 list<string>& comps)
12322 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
12325 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
12326 comp_end = fqn_size;
12328 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
12329 comps.push_back(comp);
12331 comp_begin = comp_end + 2;
12332 if (comp_begin >= fqn_size)
12348 for (list<string>::const_iterator c = comps.begin();
12351 if (c == comps.begin())
12354 result +=
"::" + *c;
12369template<
typename T>
12371iterator_is_last(T& container,
12372 typename T::const_iterator i)
12374 typename T::const_iterator next = i;
12376 return (next == container.end());
12393lookup_types_in_map(
const interned_string& type_name,
12396 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12397 if (i != type_map.end())
12418template <
class TypeKind>
12419static shared_ptr<TypeKind>
12423 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
12424 if (i != type_map.end())
12428 for (
auto j : i->second)
12430 type_base_sptr t(j);
12431 decl_base_sptr d =
is_decl(t);
12432 if (d && !d->get_is_declaration_only())
12433 return dynamic_pointer_cast<TypeKind>(type_base_sptr(j));
12438 return dynamic_pointer_cast<TypeKind>(type_base_sptr(i->second.back()));
12440 return shared_ptr<TypeKind>();
12457 return lookup_type_in_map<type_decl>(type_name,
12516 return lookup_type_in_map<class_decl>(type_name,
12534 return lookup_type_in_map<union_decl>(type_name,
12569 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
12602 return lookup_type_in_map<enum_type_decl>(type_name,
12641 return lookup_type_in_map<typedef_decl>(type_name,
12677qualified_type_def_sptr
12682 return lookup_type_in_map<qualified_type_def>(type_name,
12701qualified_type_def_sptr
12728 return lookup_type_in_map<pointer_type_def>(type_name,
12790 return lookup_type_in_map<reference_type_def>(type_name,
12809 bool lvalue_reference,
12834 return lookup_type_in_map<array_type_def>(type_name,
12854 return lookup_type_in_map<function_type>(type_name,
12900const type_base_sptr
12904 type_base_sptr result;
12943const type_base_sptr
12967const type_base_sptr
12971 list<string> comps;
12984const decl_base_sptr
12988 list<string> comps;
13004template<
typename NodeKind>
13006get_node_name(shared_ptr<NodeKind> node);
13016{
return node->get_name();}
13025get_node_name(type_base_sptr node)
13036{
return node->get_name();}
13045template<
typename NodeKind>
13046static decl_base_sptr
13047convert_node_to_decl(shared_ptr<NodeKind> node);
13060template<
typename NodeKind>
13062lookup_node_in_scope(
const list<string>& fqn,
13066 shared_ptr<NodeKind> node;
13067 bool it_is_last =
false;
13070 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
13073 it_is_last = iterator_is_last(fqn, c);
13074 for (scope_decl::declarations::const_iterator m =
13075 cur_scope->get_member_decls().begin();
13076 m != cur_scope->get_member_decls().end();
13082 scope = dynamic_pointer_cast<scope_decl>(*m);
13083 if (scope && scope->get_name() == *c)
13092 node = dynamic_pointer_cast<NodeKind>(*m);
13093 if (node && get_node_name(node) == *c)
13096 dynamic_pointer_cast<class_decl>(node))
13097 if (cl->get_is_declaration_only()
13098 && !cl->get_definition_of_declaration())
13100 resulting_decl = node;
13105 if (!new_scope && !resulting_decl)
13106 return decl_base_sptr();
13107 cur_scope = new_scope;
13110 return resulting_decl;
13131const type_base_sptr
13134{
return is_type(lookup_node_in_scope<type_base>(comps, scope));}
13158static const type_base_sptr
13164 type_base_sptr result;
13169 first_scope = a.back();
13177 for (scope_decl::declarations::const_iterator i =
13181 if (
is_type(*i) && (*i)->get_name() == n)
13189 first_scope = a.back();
13191 for (scope_decl::scopes::const_iterator i =
13196 scope_name = (*i)->get_name();
13197 if (scope_name == cur_scope_name)
13223static const type_base_sptr
13228 return type_base_sptr();
13235 access_path.push_back(s);
13261const type_base_sptr
13276const decl_base_sptr
13279{
return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
13292template<
typename NodeKind>
13294lookup_node_in_translation_unit(
const list<string>& fqn,
13312{
return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
13332{
return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
13345lookup_basic_type_through_translation_units(
const interned_string& type_name,
13346 const corpus& abi_corpus)
13350 for (translation_units::const_iterator tu =
13370static union_decl_sptr
13371lookup_union_type_through_translation_units(
const interned_string& type_name,
13372 const corpus & abi_corpus)
13374 union_decl_sptr result;
13376 for (translation_units::const_iterator tu =
13377 abi_corpus.get_translation_units().begin();
13378 tu != abi_corpus.get_translation_units().end();
13397lookup_enum_type_through_translation_units(
const interned_string& type_name,
13398 const corpus & abi_corpus)
13402 for (translation_units::const_iterator tu =
13403 abi_corpus.get_translation_units().begin();
13404 tu != abi_corpus.get_translation_units().end();
13421lookup_typedef_type_through_translation_units(
const interned_string& type_name,
13422 const corpus & abi_corpus)
13426 for (translation_units::const_iterator tu =
13427 abi_corpus.get_translation_units().begin();
13428 tu != abi_corpus.get_translation_units().end();
13445static qualified_type_def_sptr
13446lookup_qualified_type_through_translation_units(
const interned_string& t_name,
13447 const corpus & abi_corpus)
13449 qualified_type_def_sptr result;
13451 for (translation_units::const_iterator tu =
13452 abi_corpus.get_translation_units().begin();
13453 tu != abi_corpus.get_translation_units().end();
13471lookup_pointer_type_through_translation_units(
const interned_string& type_name,
13472 const corpus & abi_corpus)
13476 for (translation_units::const_iterator tu =
13477 abi_corpus.get_translation_units().begin();
13478 tu != abi_corpus.get_translation_units().end();
13496lookup_reference_type_through_translation_units(
const interned_string& t_name,
13497 const corpus & abi_corpus)
13501 for (translation_units::const_iterator tu =
13502 abi_corpus.get_translation_units().begin();
13503 tu != abi_corpus.get_translation_units().end();
13521lookup_array_type_through_translation_units(
const interned_string& type_name,
13522 const corpus & abi_corpus)
13526 for (translation_units::const_iterator tu =
13527 abi_corpus.get_translation_units().begin();
13528 tu != abi_corpus.get_translation_units().end();
13546lookup_function_type_through_translation_units(
const interned_string& type_name,
13547 const corpus & abi_corpus)
13551 for (translation_units::const_iterator tu =
13552 abi_corpus.get_translation_units().begin();
13553 tu != abi_corpus.get_translation_units().end();
13571 const corpus& abi_corpus)
13573 type_base_sptr result;
13575 for (translation_units::const_iterator tu =
13596 const string& tu_path,
13599 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
13600 if (i == corp.priv_->path_tu_map.end())
13601 return type_base_sptr();
13630 for (translation_units::const_iterator i =
13676 result = lookup_type_in_map<type_decl>(qualified_name, m);
13678 result = lookup_basic_type_through_translation_units(qualified_name, corp);
13698 result = lookup_type_in_map<type_decl>(loc, m);
13789 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
13807 return lookup_types_in_map(qualified_name, m);
13833 for (
auto type : *v)
13835 type_base_sptr t(type);
13837 if (c->get_is_declaration_only()
13838 && !c->get_definition_of_declaration())
13839 result.push_back(type);
13842 return !result.empty();
13858 return lookup_types_in_map(qualified_name, m);
13939 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
13941 result = lookup_union_type_through_translation_units(type_name, corp);
14020 lookup_type_in_map<enum_type_decl>(qualified_name, m);
14022 result = lookup_enum_type_through_translation_units(qualified_name, corp);
14040 return lookup_types_in_map(qualified_name, m);
14145 lookup_type_in_map<typedef_decl>(qualified_name, m);
14147 result = lookup_typedef_type_through_translation_units(qualified_name,
14242qualified_type_def_sptr
14257qualified_type_def_sptr
14263 qualified_type_def_sptr result =
14264 lookup_type_in_map<qualified_type_def>(qualified_name, m);
14267 result = lookup_qualified_type_through_translation_units(qualified_name,
14309 lookup_type_in_map<pointer_type_def>(qualified_name, m);
14311 result = lookup_pointer_type_through_translation_units(qualified_name,
14359 lookup_type_in_map<reference_type_def>(qualified_name, m);
14361 result = lookup_reference_type_through_translation_units(qualified_name,
14408 lookup_type_in_map<array_type_def>(qualified_name, m);
14410 result = lookup_array_type_through_translation_units(qualified_name, corp);
14479 lookup_type_in_map<function_type>(qualified_name, m);
14481 result = lookup_function_type_through_translation_units(qualified_name,
14504 type_base_sptr result;
14537 type_base_sptr result;
14585 return type_base_sptr();
14602template<
typename TypeKind>
14606 bool use_type_name_as_key =
true)
14610 if (use_type_name_as_key)
14612 else if (
location l = type->get_location())
14614 string str = l.expand();
14615 s = type->get_environment().intern(str);
14618 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14619 bool result =
false;
14621 if (i == types_map.end())
14623 types_map[s].push_back(type);
14627 i->second.push_back(type);
14648 bool use_type_name_as_key)
14652 bool update_qname_map =
true;
14653 if (type->get_is_declaration_only())
14659 is_class_type(class_type->get_definition_of_declaration()))
14663 if (!update_qname_map)
14667 if (use_type_name_as_key)
14669 string qname = type->get_qualified_name();
14670 s = type->get_environment().intern(qname);
14672 else if (
location l = type->get_location())
14674 string str = l.expand();
14675 s = type->get_environment().intern(str);
14678 bool result =
false;
14679 istring_type_base_wptrs_map_type::iterator i = map.find(s);
14680 if (i == map.end())
14682 map[s].push_back(type);
14686 i->second.push_back(type);
14712 bool result =
false;
14714 istring_type_base_wptrs_map_type::iterator i = types_map.find(s);
14715 if (i == types_map.end())
14717 types_map[s].push_back(type);
14721 i->second.push_back(type);
14744 if (
corpus *type_corpus = basic_type->get_corpus())
14748 type_corpus->priv_->get_types().basic_types());
14752 type_corpus->get_type_per_loc_map().basic_types(),
14759 group->priv_->get_types().basic_types());
14763 group->get_type_per_loc_map().basic_types(),
14788 if (
corpus *type_corpus = class_type->get_corpus())
14792 type_corpus->priv_->get_types().class_types());
14796 type_corpus->get_type_per_loc_map().class_types(),
14803 group->priv_->get_types().class_types());
14807 group->get_type_per_loc_map().class_types(),
14831 if (
corpus *type_corpus = union_type->get_corpus())
14835 type_corpus->priv_->get_types().union_types());
14839 type_corpus->get_type_per_loc_map().union_types(),
14846 group->priv_->get_types().union_types());
14850 group->get_type_per_loc_map().union_types(),
14874 if (
corpus *type_corpus = enum_type->get_corpus())
14878 type_corpus->priv_->get_types().enum_types());
14882 type_corpus->get_type_per_loc_map().enum_types(),
14889 group->priv_->get_types().enum_types());
14893 group->get_type_per_loc_map().enum_types(),
14918 if (
corpus *type_corpus = typedef_type->get_corpus())
14922 type_corpus->priv_->get_types().typedef_types());
14926 type_corpus->get_type_per_loc_map().typedef_types(),
14933 group->priv_->get_types().typedef_types());
14937 group->get_type_per_loc_map().typedef_types(),
14961 if (
corpus *type_corpus = qualified_type->get_corpus())
14965 type_corpus->priv_->get_types().qualified_types());
14971 group->priv_->get_types().qualified_types());
14994 if (
corpus *type_corpus = pointer_type->get_corpus())
14998 type_corpus->priv_->get_types().pointer_types());
15004 group->priv_->get_types().pointer_types());
15027 if (
corpus *type_corpus = ptr_to_member->get_corpus())
15031 type_corpus->priv_->get_types().ptr_to_mbr_types());
15037 group->priv_->get_types().ptr_to_mbr_types());
15060 if (
corpus *type_corpus = reference_type->get_corpus())
15064 type_corpus->priv_->get_types().reference_types());
15070 group->priv_->get_types().reference_types());
15093 if (
corpus *type_corpus = array_type->get_corpus())
15097 type_corpus->priv_->get_types().array_types());
15101 type_corpus->get_type_per_loc_map().array_types(),
15108 group->priv_->get_types().array_types());
15112 group->get_type_per_loc_map().array_types(),
15137 if (
corpus *type_corpus = subrange_type->get_corpus())
15141 type_corpus->priv_->get_types().subrange_types());
15145 type_corpus->get_type_per_loc_map().subrange_types(),
15148 if (
corpus *group = subrange_type->get_corpus())
15152 group->priv_->get_types().subrange_types());
15156 group->get_type_per_loc_map().subrange_types(),
15181 if (
corpus *type_corpus = fn_type->get_corpus())
15185 type_corpus->priv_->get_types().function_types());
15187 if (
corpus *group = fn_type->get_corpus())
15191 group->priv_->get_types().function_types());
15282 translation_unit& tu)
15284 type_base_sptr result;
15292 type_base_sptr underlying_type =
15295 if (underlying_type)
15298 qual->get_cv_quals(),
15299 qual->get_location()));
15304 type_base_sptr pointed_to_type =
15307 if (pointed_to_type)
15310 p->get_size_in_bits(),
15311 p->get_alignment_in_bits(),
15312 p->get_location()));
15317 type_base_sptr pointed_to_type =
15319 if (pointed_to_type)
15323 r->get_size_in_bits(),
15324 r->get_alignment_in_bits(),
15325 r->get_location()));
15339 tu.priv_->synthesized_types_.push_back(result);
15365 translation_unit& tu)
15372 type_base_sptr result_return_type;
15377 if (!result_return_type)
15381 type_base_sptr parm_type;
15383 for (function_type::parameters::const_iterator i =
15388 type_base_sptr t = (*i)->get_type();
15395 (*i)->get_location(),
15396 (*i)->get_variadic_marker(),
15397 (*i)->get_is_artificial()));
15398 parms.push_back(parm);
15401 class_or_union_sptr class_type;
15413 result_fn_type.reset(
new method_type(result_return_type,
15425 tu.priv_->synthesized_types_.push_back(result_fn_type);
15429 return result_fn_type;
15440 if (mangled_name.empty())
15445 char * str = abi::__cxa_demangle(mangled_name.c_str(),
15446 NULL, &l, &status);
15447 string demangled_name = mangled_name;
15451 demangled_name = str;
15455 return demangled_name;
15480global_scope::~global_scope()
15501types_defined_same_linux_kernel_corpus_public(
const type_base& t1,
15502 const type_base& t2)
15504 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
15505 string t1_file_path, t2_file_path;
15509 if (!(t1_corpus && t2_corpus
15510 && t1_corpus == t2_corpus
15511 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
15516 class_or_union *c1 = 0, *c2 = 0;
15522 if ((c1 && c1->get_is_anonymous() && !c1->get_naming_typedef())
15523 || (c2 && c2->get_is_anonymous() && !c2->get_naming_typedef()))
15530 && c1->get_is_anonymous() && c1->get_naming_typedef()
15531 && c2->get_is_anonymous() && c2->get_naming_typedef())
15532 if (c1->get_naming_typedef()->get_name()
15533 != c2->get_naming_typedef()->get_name())
15539 if (e1->get_is_anonymous() || e2->get_is_anonymous())
15549 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
15551 if (c1->get_environment().decl_only_class_equals_definition())
15561 if (t1.get_size_in_bits() != t2.get_size_in_bits())
15570 l = c1->get_location();
15574 unsigned line = 0, col = 0;
15576 l.
expand(t1_file_path, line, col);
15578 l = c2->get_location();
15582 l.
expand(t2_file_path, line, col);
15585 if (t1_file_path.empty() || t2_file_path.empty())
15588 if (t1_file_path == t2_file_path)
15624compare_types_during_canonicalization(
const type_base& canonical_type,
15627#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
15628 const environment& env = canonical_type.get_environment();
15629 if (env.debug_type_canonicalization_is_on())
15631 bool canonical_equality =
false, structural_equality =
false;
15632 env.priv_->allow_type_comparison_results_caching(
false);
15633 env.priv_->use_canonical_type_comparison_ =
false;
15634 structural_equality = canonical_type == candidate_type;
15635 env.priv_->use_canonical_type_comparison_ =
true;
15636 canonical_equality = canonical_type == candidate_type;
15637 env.priv_->allow_type_comparison_results_caching(
true);
15638 if (canonical_equality != structural_equality)
15640 std::cerr <<
"structural & canonical equality different for type: "
15641 << canonical_type.get_pretty_representation(
true,
true)
15645 return structural_equality;
15648 return canonical_type == candidate_type;
15672compare_canonical_type_against_candidate(
const type_base& canonical_type,
15693 bool saved_decl_only_class_equals_definition =
15698 env.decl_only_class_equals_definition(
false);
15699 env.priv_->allow_type_comparison_results_caching(
true);
15700 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
15702 || compare_types_during_canonicalization(canonical_type,
15707 env.priv_->clear_type_comparison_results_cache();
15708 env.priv_->allow_type_comparison_results_caching(
false);
15709 env.decl_only_class_equals_definition
15710 (saved_decl_only_class_equals_definition);
15735compare_canonical_type_against_candidate(
const type_base* canonical_type,
15738 return compare_canonical_type_against_candidate(*canonical_type,
15763compare_canonical_type_against_candidate(
const type_base_sptr& canonical_type,
15764 const type_base_sptr& candidate_type)
15766 return compare_canonical_type_against_candidate(canonical_type.get(),
15767 candidate_type.get());
15787static type_base_sptr
15791 if (type.get_corpus()
15792 && type.get_corpus()->get_origin() == corpus::NATIVE_XML_ORIGIN
15801 for (
const auto& c : cncls)
15807 if (compare_canonical_type_against_candidate(*c, type))
15811 for (
const auto& c : cncls)
15816 if (compare_canonical_type_against_candidate(*c, type))
15866type_base::get_canonical_type_for(type_base_sptr t)
15875 return type_base_sptr();
15881 bool decl_only_class_equals_definition =
15894 if (decl_only_class_equals_definition)
15897 return type_base_sptr();
15900 if (t->get_canonical_type())
15901 return t->get_canonical_type();
15922 string repr = t->get_cached_pretty_representation(
true);
15927 type_base_sptr canonical_type_present_in_corpus;
15931 type_base_sptr result;
15932 environment::canonical_types_map_type::iterator i = types.find(repr);
15934 if (i == types.end())
15943 vector<type_base_sptr> &v = i->second;
15948 result = candidate_matches_a_canonical_type_hash(v, *t);
15956 for (vector<type_base_sptr>::const_reverse_iterator it = v.rbegin();
15957 !result && it != v.rend();
15960 bool equal = compare_canonical_type_against_candidate(*it, t);
15967#ifdef WITH_DEBUG_SELF_COMPARISON
15968 if (env.self_comparison_debug_is_on())
15972 corpus_sptr corp1, corp2;
15973 env.get_self_comparison_debug_inputs(corp1, corp2);
15975 && corp1->get_origin() != corp2->get_origin()
15976 && corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
15987 check_canonical_type_from_abixml_during_self_comp(t,
15993 uintptr_t should_have_canonical_type = 0;
15994 string type_id = env.get_type_id_from_type(t.get());
15995 if (type_id.empty())
15996 type_id =
"type-id-<not-found>";
15998 should_have_canonical_type =
15999 env.get_canonical_type_from_type_id(type_id.c_str());
16000 std::cerr <<
"error: wrong canonical type for '"
16009 <<
"'. Should have had canonical type: "
16011 << should_have_canonical_type
16018 uintptr_t ptr_val =
reinterpret_cast<uintptr_t
>(t.get());
16019 string type_id = env.get_type_id_from_pointer(ptr_val);
16020 if (type_id.empty())
16021 type_id =
"type-id-<not-found>";
16038 std::cerr <<
"error: wrong induced canonical type for '"
16040 <<
"' from second corpus"
16041 <<
", ptr: " << std::hex << t.get()
16042 <<
" type-id: " << type_id
16044 << *t->hash_value()
16054 if (t_hash != result_hash)
16056 std::cerr <<
"error: type hash mismatch"
16057 <<
" between type: '"
16063 << *t->hash_value()
16064 <<
" and its computed canonical type @"
16069 << *result->hash_value()
16084 t->priv_->canonical_type_index = v.size();
16113maybe_adjust_canonical_type(
const type_base_sptr& canonical,
16114 const type_base_sptr& type)
16116 if (type->get_naked_canonical_type())
16124 if (canonical_class
16125 && canonical_class.get() != cl.get())
16129 for (class_decl::member_functions::const_iterator i =
16130 cl->get_member_functions().begin();
16131 i != cl->get_member_functions().end();
16133 if ((*i)->get_symbol())
16136 find_member_function((*i)->get_linkage_name()))
16147 && canonical_class->get_corpus()
16148 && cl->get_corpus()
16149 && (cl->get_corpus() == canonical_class->get_corpus()))
16163 for (
const auto& data_member : cl->get_data_members())
16170 const auto& canonical_data_member =
16171 canonical_class->find_data_member(data_member->get_name());
16172 if (!canonical_data_member)
16180 && canonical_class->get_corpus()
16181 && cl->get_corpus()
16182 && canonical_class->get_corpus() == cl->get_corpus())
16188 if (!canonical_data_member->get_symbol())
16189 canonical_data_member->set_symbol(sym);
16205 canonical_class = cl;
16208 if (canonical_class)
16210 if (
auto abi_corpus = canonical_class->get_corpus())
16212 for (
auto& fn : canonical_class->get_member_functions())
16216 if (sym->is_defined() && sym->is_public())
16218 fn->set_is_in_public_symbol_table(
true);
16219 auto b = abi_corpus->get_exported_decls_builder();
16220 b->maybe_add_fn_to_exported_fns(fn.get());
16222 else if (!sym->is_defined())
16223 abi_corpus->get_undefined_functions().insert(fn.get());
16235 if (type->get_is_artificial() != canonical->get_is_artificial())
16236 canonical->set_is_artificial(
false);
16266 if (t->get_canonical_type())
16267 return t->get_canonical_type();
16269 if (do_log && show_stats)
16270 std::cerr <<
"Canonicalization of type '"
16271 << t->get_pretty_representation(
true,
true)
16272 <<
"/@#" << std::hex << t.get() <<
": ";
16276 if (do_log && show_stats)
16278 type_base_sptr canonical = type_base::get_canonical_type_for(t);
16280 if (do_log && show_stats)
16283 if (do_log && show_stats)
16284 std::cerr << tmr <<
"\n";
16286 maybe_adjust_canonical_type(canonical, t);
16288 t->priv_->canonical_type = canonical;
16289 t->priv_->naked_canonical_type = canonical.get();
16292 if (!t->priv_->canonical_type_index)
16293 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16296 if (type_base_sptr d =
is_type(cl->get_earlier_declaration()))
16297 if ((canonical = d->get_canonical_type()))
16299 d->priv_->canonical_type = canonical;
16300 d->priv_->naked_canonical_type = canonical.get();
16332 t->on_canonical_type_set();
16343 priv_->definition_of_declaration_ = d;
16345 if (type_base_sptr canonical_type =
is_type(d)->get_canonical_type())
16346 t->priv_->canonical_type = canonical_type;
16348 priv_->naked_definition_of_declaration_ =
const_cast<decl_base*
>(d.get());
16357 : type_or_decl_base(e, ABSTRACT_TYPE_BASE|ABSTRACT_TYPE_BASE),
16358 priv_(new
priv(s, a))
16372 return do_hash(
this);
16384{
return priv_->canonical_type.lock();}
16400{
return priv_->naked_canonical_type;}
16427 if (priv_->internal_cached_repr_.empty())
16432 return priv_->internal_cached_repr_;
16435 if (priv_->cached_repr_.empty())
16441 return priv_->cached_repr_;
16479{
return equals(*
this, other, 0);}
16496{priv_->size_in_bits = s;}
16503{
return priv_->size_in_bits;}
16510{priv_->alignment_in_bits = a;}
16517{
return priv_->alignment_in_bits;}
16533 v.visit_begin(
this);
16534 bool result = v.visit_end(
this);
16540type_base::~type_base()
16559 static_cast<unsigned>(r));
16574 static_cast<unsigned>(r));
16631parse_real_type_modifier(
const string& word,
16634 if (word ==
"signed")
16636 else if (word ==
"unsigned")
16638 else if (word ==
"short")
16640 else if (word ==
"long")
16642 else if (word ==
"long long")
16660parse_base_real_type(
const string& type_name,
16663 if (type_name ==
"int")
16665 else if (type_name ==
"char")
16667 else if (type_name ==
"bool" || type_name ==
"_Bool")
16669 else if (type_name ==
"double")
16671 else if (type_name ==
"float")
16673 else if (type_name ==
"char16_t")
16675 else if (type_name ==
"char32_t")
16677 else if (type_name ==
"wchar_t")
16679 else if (type_name ==
"__ARRAY_SIZE_TYPE__")
16681 else if (type_name ==
"sizetype")
16682 base = real_type::SIZE_BASE_TYPE;
16683 else if (type_name ==
"ssizetype")
16684 base = real_type::SSIZE_BASE_TYPE;
16685 else if (type_name ==
"bitsizetype")
16686 base = real_type::BIT_SIZE_BASE_TYPE;
16687 else if (type_name ==
"sbitsizetype")
16688 base = real_type::SBIT_SIZE_BASE_TYPE;
16712 string input = type_name;
16713 string::size_type len = input.length();
16714 string::size_type cur_pos = 0, prev_pos = 0;
16715 string cur_word, prev_word;
16718 while (cur_pos < len)
16720 if (cur_pos < len && isspace(input[cur_pos]))
16723 while (cur_pos < len && isspace(input[cur_pos]));
16725 prev_pos = cur_pos;
16726 cur_pos = input.find(
' ', prev_pos);
16727 prev_word = cur_word;
16728 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16731 && cur_word ==
"long"
16732 && prev_word !=
"long")
16734 if (cur_pos < len && isspace(input[cur_pos]))
16737 while (cur_pos < len && isspace(input[cur_pos]));
16738 prev_pos = cur_pos;
16740 cur_pos = input.find(
' ', prev_pos);
16741 string saved_prev_word = prev_word;
16742 prev_word = cur_word;
16743 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
16744 if (cur_word ==
"long")
16745 cur_word =
"long long";
16748 cur_pos = prev_pos;
16749 cur_word = prev_word;
16750 prev_word = saved_prev_word;
16754 if (!parse_real_type_modifier(cur_word, modifiers))
16756 if (!parse_base_real_type(cur_word, base))
16787 real_type int_type(base_type, modifiers);
16795 modifiers_(NO_MODIFIER)
16804 : base_(b), modifiers_(m)
16813 modifiers_(NO_MODIFIER)
16831{
return modifiers_;}
16848{
return base_ == other.base_ && modifiers_ == other.modifiers_;}
16866 result +=
"signed ";
16868 result +=
"unsigned ";
16879 result +=
"short ";
16883 result +=
"long long ";
16894 result +=
"double";
16898 result +=
"char16_t";
16900 result +=
"char32_t";
16902 result +=
"wchar_t";
16904 result +=
"__ARRAY_SIZE_TYPE__";
16905 else if (base_ == SIZE_BASE_TYPE)
16906 result +=
"sizetype";
16907 else if (base_ == SSIZE_BASE_TYPE)
16908 result +=
"ssizetype";
16909 else if (base_ == BIT_SIZE_BASE_TYPE)
16910 result +=
"bitsizetype";
16911 else if (base_ == SBIT_SIZE_BASE_TYPE)
16912 result +=
"sbitsizetype";
16921real_type::operator string()
const
16945 const string& name,
16946 size_t size_in_bits,
16947 size_t alignment_in_bits,
16949 const string& linkage_name,
16954 | ABSTRACT_TYPE_BASE
16955 | ABSTRACT_DECL_BASE),
16956 decl_base(env, name, locus, linkage_name, vis),
16957 type_base(env, size_in_bits, alignment_in_bits)
16963 real_type int_type(base_type, modifiers);
16968 string real_type_name = int_type;
17016 bool result =
false;
17044 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
17047 return *
this == *other;
17058 const type_decl* other =
dynamic_cast<const type_decl*
>(&o);
17074 const decl_base& other = o;
17075 return *
this == other;
17121 if (l.get() == r.get())
17149 bool internal)
const
17173 if (decl_base::priv_->internal_qualified_name_.
empty())
17174 decl_base::priv_->internal_qualified_name_ =
17175 env.
intern(get_internal_real_type_name(
this));
17176 return decl_base::priv_->internal_qualified_name_;
17180 decl_base::priv_->temporary_internal_qualified_name_ =
17181 env.
intern(get_internal_real_type_name(
this));
17182 return decl_base::priv_->temporary_internal_qualified_name_;
17208 bool qualified_name)
const
17212 return get_internal_real_type_name(
this);
17214 if (qualified_name)
17232 v.visit_begin(
this);
17233 bool result = v.visit_end(
this);
17239type_decl::~type_decl()
17259 const string& name,
17260 size_t size_in_bits,
17261 size_t alignment_in_bits,
17265 ABSTRACT_SCOPE_TYPE_DECL
17266 | ABSTRACT_TYPE_BASE
17267 | ABSTRACT_DECL_BASE),
17269 type_base(env, size_in_bits, alignment_in_bits),
17270 scope_decl(env, name, locus)
17318 const scope_type_decl* other =
dynamic_cast<const scope_type_decl*
>(&o);
17338 return *
this == *other;
17362 if (v.visit_begin(
this))
17365 for (scope_decl::declarations::const_iterator i =
17369 if (!(*i)->traverse(v))
17374 bool result = v.visit_end(
this);
17380scope_type_decl::~scope_type_decl()
17396 const string& name,
17407 | ABSTRACT_DECL_BASE
17408 | ABSTRACT_SCOPE_DECL),
17410 scope_decl(env, name, locus)
17434 bool qualified_name)
const
17437 "namespace " + scope_decl::get_pretty_representation(internal,
17476 if (!ns->is_empty_or_has_empty_sub_namespaces())
17497 if (v.visit_begin(
this))
17500 scope_decl::declarations::const_iterator i;
17506 dynamic_pointer_cast<ir_traversable_base>(*i);
17508 if (!t->traverse (v))
17513 return v.visit_end(
this);
17516namespace_decl::~namespace_decl()
17525class qualified_type_def::priv
17536 weak_ptr<type_base> underlying_type_;
17539 : cv_quals_(CV_NONE)
17544 : cv_quals_(quals),
17545 underlying_type_(t)
17597qualified_type_def::qualified_type_def(type_base_sptr type,
17602 | ABSTRACT_TYPE_BASE
17603 | ABSTRACT_DECL_BASE),
17608 priv_(new priv(quals, type))
17627 | ABSTRACT_TYPE_BASE
17628 | ABSTRACT_DECL_BASE),
17631 decl_base(env,
"", locus,
""),
17632 priv_(new priv(quals))
17669 s = ut->get_size_in_bits();
17698 bool result =
true;
17743 const qualified_type_def* other =
17744 dynamic_cast<const qualified_type_def*
>(&o);
17762 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
17765 return *
this == *other;
17780 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
17783 return *
this == *other;
17798 bool internal)
const
17826 if (priv_->temporary_internal_name_.empty())
17827 priv_->temporary_internal_name_ =
17829 return priv_->temporary_internal_name_;
17845 if (priv_->internal_name_.empty())
17846 priv_->internal_name_ =
17849 return priv_->internal_name_;
17878 if (v.visit_begin(
this))
17885 bool result = v.visit_end(
this);
17890qualified_type_def::~qualified_type_def()
17897{
return priv_->cv_quals_;}
17902{priv_->cv_quals_ = cv_quals;}
17916{
return priv_->underlying_type_.lock();}
17925 priv_->underlying_type_ = t;
17935 scope_decl::declarations::iterator i;
17936 if (s->find_iterator_for_member(
this, i))
17951operator==(
const qualified_type_def_sptr& l,
const qualified_type_def_sptr& r)
17953 if (l.get() == r.get())
17969operator!=(
const qualified_type_def_sptr& l,
const qualified_type_def_sptr& r)
17977 (
static_cast<unsigned>(lhs) |
static_cast<unsigned>(rhs));
18001 (
static_cast<unsigned>(lhs) &
static_cast<unsigned>(rhs));
18023 case qualified_type_def::CV_NONE:
18026 case qualified_type_def::CV_CONST:
18029 case qualified_type_def::CV_VOLATILE:
18032 case qualified_type_def::CV_RESTRICT:
18046struct pointer_type_def::priv
18053 priv(
const type_base_sptr& t)
18055 naked_pointed_to_type_(t.get())
18059 : naked_pointed_to_type_()
18084pointer_type_def::pointer_type_def(
const type_base_sptr& pointed_to,
18085 size_t size_in_bits,
18086 size_t align_in_bits,
18090 | ABSTRACT_TYPE_BASE
18091 | ABSTRACT_DECL_BASE),
18092 type_base(pointed_to->
get_environment(), size_in_bits, align_in_bits),
18094 priv_(new priv(pointed_to))
18100 const environment& env = pointed_to->get_environment();
18101 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18102 string name = (pto ? pto->get_name() :
string(
"void")) +
"*";
18120pointer_type_def::pointer_type_def(
const environment& env,
size_t size_in_bits,
18121 size_t alignment_in_bits,
18125 | ABSTRACT_TYPE_BASE
18126 | ABSTRACT_DECL_BASE),
18127 type_base(env, size_in_bits, alignment_in_bits),
18128 decl_base(env,
"", locus,
""),
18132 string name = string(
"void") +
"*";
18157 priv_->pointed_to_type_ = t;
18158 priv_->naked_pointed_to_type_ = t.get();
18163 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18164 string name = (pto ? pto->get_name() :
string(
"void")) +
"*";
18196 bool result = p1 == p2;
18235 const decl_base* o =
is_decl(&other);
18238 return *
this == *o;
18252 const decl_base& o = other;
18259const type_base_sptr
18261{
return priv_->pointed_to_type_.lock();}
18268{
return priv_->naked_pointed_to_type_;}
18306 if (priv_->internal_qualified_name_.empty())
18307 if (pointed_to_type)
18308 priv_->internal_qualified_name_ =
18309 pointer_declaration_name(
this,
18316 return priv_->internal_qualified_name_;
18324 if (pointed_to_type)
18325 if (priv_->temp_internal_qualified_name_.empty())
18326 priv_->temp_internal_qualified_name_ =
18327 pointer_declaration_name(
this,
18334 return priv_->temp_internal_qualified_name_;
18343 (pointer_declaration_name(
this,
18355 if (pointed_to_type)
18357 (pointer_declaration_name(
this,
18382 if (v.visit_begin(
this))
18390 bool result = v.visit_end(
this);
18395pointer_type_def::~pointer_type_def()
18412 if (l.get() == r.get())
18440struct reference_type_def::priv
18448 priv(
const type_base_sptr& t,
bool is_lvalue)
18450 is_lvalue_(is_lvalue)
18453 priv(
bool is_lvalue)
18454 : is_lvalue_(is_lvalue)
18483reference_type_def::reference_type_def(
const type_base_sptr pointed_to,
18485 size_t size_in_bits,
18486 size_t align_in_bits,
18490 | ABSTRACT_TYPE_BASE
18491 | ABSTRACT_DECL_BASE),
18492 type_base(pointed_to->
get_environment(), size_in_bits, align_in_bits),
18494 priv_(new priv(pointed_to, lvalue))
18500 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18505 name = string(pto->get_name()) +
"&";
18513 const environment& env = pointed_to->get_environment();
18537reference_type_def::reference_type_def(
const environment& env,
bool lvalue,
18538 size_t size_in_bits,
18539 size_t alignment_in_bits,
18543 | ABSTRACT_TYPE_BASE
18544 | ABSTRACT_DECL_BASE),
18545 type_base(env, size_in_bits, alignment_in_bits),
18546 decl_base(env,
"", locus,
""),
18547 priv_(new priv(lvalue))
18550 string name =
"void&";
18579 priv_->pointed_to_type_ = pointed_to_type;
18581 decl_base_sptr pto;
18583 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
18590 string name = string(pto->get_name()) +
"&";
18620 if (l.is_lvalue() != r.is_lvalue())
18626 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
18627 bool result = p1 == p2;
18647 const reference_type_def* other =
18648 dynamic_cast<const reference_type_def*
>(&o);
18663 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
18666 return *
this == *other;
18678 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
18681 return *
this == *other;
18685reference_type_def::get_pointed_to_type()
const
18686{
return priv_->pointed_to_type_.lock();}
18689reference_type_def::is_lvalue()
const
18690{
return priv_->is_lvalue_;}
18720 type_base_sptr pointed_to_type = get_pointed_to_type();
18727 if (priv_->internal_qualified_name_.empty())
18728 if (pointed_to_type)
18729 priv_->internal_qualified_name_ =
18737 return priv_->internal_qualified_name_;
18745 if (pointed_to_type)
18746 if (priv_->temp_internal_qualified_name_.empty())
18747 priv_->temp_internal_qualified_name_ =
18755 return priv_->temp_internal_qualified_name_;
18775 if (pointed_to_type)
18805 bool qualified_name)
const
18809 (get_pointed_to_type()),
18833 if (v.visit_begin(
this))
18836 if (type_base_sptr t = get_pointed_to_type())
18841 bool result = v.visit_end(
this);
18846reference_type_def::~reference_type_def()
18863 if (l.get() == r.get())
18891struct ptr_to_mbr_type::priv
18895 type_base_sptr dm_type_;
18898 type_base_sptr containing_type_;
18905 priv(
const type_base_sptr& dm_type,
const type_base_sptr& containing_type)
18906 : dm_type_(dm_type),
18907 containing_type_(containing_type)
18929 const type_base_sptr& member_type,
18930 const type_base_sptr& containing_type,
18931 size_t size_in_bits,
18932 size_t alignment_in_bits,
18935 POINTER_TO_MEMBER_TYPE
18936 | ABSTRACT_TYPE_BASE
18937 | ABSTRACT_DECL_BASE),
18938 type_base(env, size_in_bits, alignment_in_bits),
18939 decl_base(env,
"", locus,
""),
18940 priv_(new priv(member_type, containing_type))
18977const type_base_sptr&
18979{
return priv_->dm_type_;}
18986const type_base_sptr&
18988{
return priv_->containing_type_;}
18999 const ptr_to_mbr_type* other =
19000 dynamic_cast<const ptr_to_mbr_type*
>(&o);
19015 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
19018 return *
this == *other;
19030 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
19033 return *
this == *other;
19045 bool internal)
const
19064 if (priv_->internal_qualified_name_.empty())
19065 priv_->internal_qualified_name_ =
19066 ptr_to_mbr_declaration_name(
this,
"",
19069 return priv_->internal_qualified_name_;
19073 priv_->temp_internal_qualified_name_ =
19074 ptr_to_mbr_declaration_name(
this,
"",
true, internal);
19075 return priv_->temp_internal_qualified_name_;
19081 (ptr_to_mbr_declaration_name(
this,
"",
true,
19103 if (v.visit_begin(
this))
19114 bool result = v.visit_end(
this);
19146 bool result =
true;
19148 if (!(l.decl_base::operator==(r)))
19187array_type_def::subrange_type::~subrange_type() =
default;
19196 : s_(UNSIGNED_SIGNEDNESS)
19205 : s_(UNSIGNED_SIGNEDNESS)
19214 : s_(SIGNED_SIGNEDNESS)
19222enum array_type_def::subrange_type::bound_value::signedness
19246{
return v_.unsigned_;}
19254 s_ = UNSIGNED_SIGNEDNESS;
19264 s_ = SIGNED_SIGNEDNESS;
19276 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
19281struct array_type_def::subrange_type::priv
19291 : upper_bound_(ub), language_(l), infinite_(false)
19294 priv(bound_value lb, bound_value ub,
19296 : lower_bound_(lb), upper_bound_(ub),
19297 language_(l), infinite_(false)
19300 priv(bound_value lb, bound_value ub,
const type_base_sptr &u,
19302 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
19303 language_(l), infinite_(false)
19322 const string& name,
19325 const type_base_sptr& utype,
19328 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19334 decl_base(env, name, loc,
""),
19335 priv_(new priv(lower_bound, upper_bound, utype, l))
19355 const string& name,
19360 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19361 type_base(env, 0, 0),
19362 decl_base(env, name, loc,
""),
19363 priv_(new priv(lower_bound, upper_bound, l))
19381 const string& name,
19385 : type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
19386 type_base(env, upper_bound.get_unsigned_value(), 0),
19387 decl_base(env, name, loc,
""),
19388 priv_(new priv(upper_bound, l))
19413{
return priv_->underlying_type_.lock();}
19422 ABG_ASSERT(priv_->underlying_type_.expired());
19423 priv_->underlying_type_ = u;
19433{
return priv_->upper_bound_.get_signed_value();}
19440{
return priv_->lower_bound_.get_signed_value();}
19447{priv_->upper_bound_ = ub;}
19454{priv_->lower_bound_ = lb;}
19481{
return priv_->infinite_;}
19489{priv_->infinite_ = f;}
19496{
return priv_->language_;}
19504 std::ostringstream o;
19509 if (underlying_type)
19534 r += (*i)->as_string();
19563 bool result =
true;
19599 const subrange_type* other =
19600 dynamic_cast<const subrange_type*
>(&o);
19615 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
19618 return *
this == *other;
19630 const type_base &t = o;
19686 repr +=
"<anonymous range>";
19688 repr +=
"<range " +
get_name() +
">";
19707 if (v.visit_begin(
this))
19715 bool result = v.visit_end(
this);
19722struct array_type_def::priv
19729 priv(type_base_sptr t)
19733 priv(type_base_sptr t, subranges_type subs)
19734 : element_type_(t), subranges_(subs)
19754array_type_def::array_type_def(
const type_base_sptr e_type,
19755 const std::vector<subrange_sptr>& subs,
19759 | ABSTRACT_TYPE_BASE
19760 | ABSTRACT_DECL_BASE),
19763 priv_(new priv(e_type))
19787 const std::vector<subrange_sptr>& subs,
19791 | ABSTRACT_TYPE_BASE
19792 | ABSTRACT_DECL_BASE),
19793 type_base(env, 0, 0),
19794 decl_base(env, locus),
19820array_type_def::update_size()
19822 type_base_sptr e = priv_->element_type_.lock();
19825 size_t s = e->get_size_in_bits();
19829 s *= sub->get_length();
19837array_type_def::get_subrange_representation()
const
19863 bool qualified_name)
const
19865 return array_declaration_name(
this,
"",
19866 qualified_name, internal);
19891 std::vector<array_type_def::subrange_sptr > this_subs = l.
get_subranges();
19892 std::vector<array_type_def::subrange_sptr > other_subs = r.
get_subranges();
19894 bool result =
true;
19895 if (this_subs.size() != other_subs.size())
19904 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19905 for (i = this_subs.begin(), j = other_subs.begin();
19906 i != this_subs.end() && j != other_subs.end();
19953 std::vector<array_type_def::subrange_sptr > this_subs = l->
get_subranges();
19954 std::vector<array_type_def::subrange_sptr > other_subs = r->
get_subranges();
19956 if (this_subs.size() != other_subs.size())
19959 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
19960 for (i = this_subs.begin(), j = other_subs.begin();
19961 i != this_subs.end() && j != other_subs.end();
19971 if (*first_element_type != *second_element_type)
20027 return *l_ptt == *r_ptt;
20049 const std::vector<subrange_sptr>& subranges =
20052 if (subranges.empty())
20053 return translation_unit::LANG_C11;
20054 return subranges.front()->get_language();
20060 const array_type_def* other =
20061 dynamic_cast<const array_type_def*
>(&o);
20070 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
20073 return *
this == *other;
20079const type_base_sptr
20081{
return priv_->element_type_.lock();}
20097 priv_->element_type_ = element_type;
20108 for (
const auto &sub : subs)
20109 priv_->subranges_.push_back(sub);
20121 if (priv_->subranges_.empty())
20124 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20125 priv_->subranges_.begin();
20126 i != priv_->subranges_.end();
20128 if ((*i)->is_non_finite())
20135array_type_def::get_dimension_count()
const
20136{
return priv_->subranges_.size();}
20167 if (priv_->internal_qualified_name_.empty())
20168 priv_->internal_qualified_name_ =
20169 array_declaration_name(
this,
"",
20172 return priv_->internal_qualified_name_;
20176 priv_->temp_internal_qualified_name_ =
20177 array_declaration_name(
this,
"",
20179 return priv_->temp_internal_qualified_name_;
20196 (array_declaration_name(
this,
"",
20220 if (v.visit_begin(
this))
20228 bool result = v.visit_end(
this);
20238const std::vector<array_type_def::subrange_sptr>&
20240{
return priv_->subranges_;}
20242array_type_def::~array_type_def()
20249class enum_type_decl::priv
20251 type_base_sptr underlying_type_;
20260 priv(type_base_sptr underlying_type,
20262 : underlying_type_(underlying_type),
20280enum_type_decl::enum_type_decl(
const string& name,
20282 type_base_sptr underlying_type,
20284 const string& linkage_name,
20288 | ABSTRACT_TYPE_BASE
20289 | ABSTRACT_DECL_BASE),
20294 name, locus, linkage_name, vis),
20295 priv_(new priv(underlying_type, enums))
20301 e->set_enum_type(
this);
20321{
return priv_->underlying_type_;}
20326{
return priv_->enumerators_;}
20331{
return priv_->enumerators_;}
20339 if (priv_->sorted_enumerators_.empty())
20344 priv_->sorted_enumerators_.push_back(*e);
20346 std::sort(priv_->sorted_enumerators_.begin(),
20347 priv_->sorted_enumerators_.end(),
20351 if (l.get_name() == r.get_name())
20352 return l.get_value() < r.get_value();
20353 return (l.get_name() < r.get_name());
20357 return priv_->sorted_enumerators_;
20372 enum_type_decl:: enumerator& result)
20375 if (e.get_value() == value)
20399 if (e.get_name() == name)
20427 bool qualified_name)
const
20429 string r =
"enum ";
20459 if (v.visit_begin(
this))
20467 bool result = v.visit_end(
this);
20532is_enumerator_value_present_in_enum(
const enum_type_decl::enumerator &enr,
20533 const enum_type_decl &enom,
20534 vector<enum_type_decl::enumerator>& redundant_enrs)
20536 bool found =
false;
20537 for (
const auto &e : enom.get_enumerators())
20538 if (enumerators_values_are_equal(e, enr))
20542 redundant_enrs.push_back(e);
20564 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
20566 if (!redundant_enrs.empty())
20594 bool result =
true;
20610 if (!!def1 != !!def2)
20640 if (!(def1->decl_base::operator==(*def2)
20641 && def1->type_base::operator==(*def2)))
20646 if (!def1->decl_base::operator==(*def2))
20648 if (!def1->type_base::operator==(*def2))
20726 && (!is_enumerator_value_redundant(e, *def2)
20727 || !is_enumerator_value_redundant(e, *def1)))
20741 && (!is_enumerator_value_redundant(e, *def1)
20742 || !is_enumerator_value_redundant(e, *def2)))
20766 const enum_type_decl* op =
dynamic_cast<const enum_type_decl*
>(&o);
20781 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
20784 return *
this == *other;
20799 if (l.get() == r.get())
20801 decl_base_sptr o = r;
20818class enum_type_decl::enumerator::priv
20822 string qualified_name_;
20833 priv(
const string& name,
20835 enum_type_decl* e = 0)
20847enum_type_decl::enumerator::~enumerator() =
default;
20858 : priv_(new priv(name, value))
20865 : priv_(new priv(other.
get_name(),
20892 bool names_equal =
true;
20913{
return priv_->name_;}
20931 if (priv_->qualified_name_.empty())
20933 priv_->qualified_name_ =
20938 return priv_->qualified_name_;
20954{
return priv_->value_;}
20968{
return priv_->enum_type_;}
20975{priv_->enum_type_ = e;}
20981struct typedef_decl::priv
20985 priv(
const type_base_sptr& t)
20986 : underlying_type_(t)
21001typedef_decl::typedef_decl(
const string& name,
21002 const type_base_sptr underlying_type,
21004 const string& linkage_name,
21008 | ABSTRACT_TYPE_BASE
21009 | ABSTRACT_DECL_BASE),
21014 name, locus, linkage_name, vis),
21015 priv_(new priv(underlying_type))
21031typedef_decl::typedef_decl(
const string& name,
21034 const string& mangled_name,
21038 | ABSTRACT_TYPE_BASE
21039 | ABSTRACT_DECL_BASE),
21042 decl_base(env, name, locus, mangled_name, vis),
21043 priv_(new priv(nullptr))
21118 bool result =
true;
21122 if (!(l.decl_base::operator==(r)))
21151 const typedef_decl* other =
dynamic_cast<const typedef_decl*
>(&o);
21166 const decl_base* other =
dynamic_cast<const decl_base*
>(&o);
21169 return *
this == *other;
21191 bool qualified_name)
const
21194 string result =
"typedef ";
21195 if (qualified_name)
21208{
return priv_->underlying_type_.lock();}
21216 priv_->underlying_type_ = t;
21230 bool internal)
const
21248 return decl_base::priv_->internal_qualified_name_;
21250 return decl_base::priv_->qualified_name_;
21269 if (v.visit_begin(
this))
21277 bool result = v.visit_end(
this);
21282typedef_decl::~typedef_decl()
21288struct var_decl::priv
21301 priv(type_base_sptr t,
21304 naked_type_(t.get()),
21312 set_type(type_base_sptr t)
21315 naked_type_ = t.get();
21332var_decl::var_decl(
const string& name,
21333 type_base_sptr type,
21335 const string& linkage_name,
21339 VAR_DECL | ABSTRACT_DECL_BASE),
21341 priv_(new priv(type, bind))
21349const type_base_sptr
21351{
return priv_->type_.lock();}
21358{priv_->set_type(t);}
21369{
return priv_->naked_type_;}
21376{
return priv_->binding_;}
21383{priv_->binding_ = b;}
21399 priv_->symbol_ = sym;
21414{
return priv_->symbol_;}
21483 bool result =
true;
21496 else if (s0 && !textually_equals(*s0, *s1, k))
21502 bool symbols_are_equal = (s0 && s1 && result);
21504 if (symbols_are_equal)
21513 bool decl_bases_different = !l.decl_base::operator==(r);
21517 if (decl_bases_different)
21527 if (!l.decl_base::operator==(r))
21576 bool result =
true;
21608 const var_decl* other =
dynamic_cast<const var_decl*
>(&o);
21612 return equals(*
this, *other, 0);
21627 if (priv_->id_.empty())
21632 sym_str = s->get_id_string();
21637 priv_->id_ = env.
intern(repr);
21638 if (!sym_str.empty())
21639 priv_->id_ = env.
intern(priv_->id_ +
"{" + sym_str +
"}");
21706 result =
"static ";
21710 bool member_of_anonymous_class =
false;
21713 member_of_anonymous_class =
true;
21722 if (member_of_anonymous_class || !qualified_name)
21729 string quals_repr =
21731 if (!quals_repr.empty())
21732 name = quals_repr +
" " + name;
21736 name = string(
" ") + name;
21738 result += array_declaration_name(t, name, qualified_name, internal);
21740 result += pointer_declaration_name(t, name, qualified_name, internal);
21742 result += pointer_declaration_name(t, name, qualified_name, internal);
21744 result += ptr_to_mbr_declaration_name(t, name,
21759 "",
true, internal);
21765 "",
true, internal);
21768 && (member_of_anonymous_class || !qualified_name))
21784 && (member_of_anonymous_class || !qualified_name))
21838 if (v.visit_begin(
this))
21841 if (type_base_sptr t =
get_type())
21845 return v.visit_end(
this);
21848var_decl::~var_decl()
21863 priv_->cached_name_.clear();
21864 priv_->internal_cached_name_.clear();
21884function_type::function_type(type_base_sptr return_type,
21886 size_t size_in_bits,
21887 size_t alignment_in_bits)
21889 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21890 type_base(return_type->
get_environment(), size_in_bits, alignment_in_bits),
21891 priv_(new
priv(parms, return_type))
21895 for (parameters::size_type i = 0, j = 1;
21896 i < priv_->parms_.size();
21899 if (i == 0 && priv_->parms_[i]->get_is_artificial())
21906 priv_->parms_[i]->set_index(j);
21917function_type::function_type(type_base_sptr return_type,
21918 size_t size_in_bits,
size_t alignment_in_bits)
21920 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
21921 type_base(return_type->
get_environment(), size_in_bits, alignment_in_bits),
21922 priv_(new
priv(return_type))
21937 size_t size_in_bits,
21938 size_t alignment_in_bits)
21940 type_base(env, size_in_bits, alignment_in_bits),
21966{
return priv_->return_type_.lock();}
21974{priv_->return_type_ = t;}
21983{
return priv_->parms_;}
22026 for (parameters::size_type i = 0, j = 1;
22027 i < priv_->parms_.size();
22030 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22037 priv_->parms_[i]->set_index(j);
22048 parm->set_index(priv_->parms_.size());
22049 priv_->parms_.push_back(parm);
22063 return (!priv_->parms_.empty()
22064 && priv_->parms_.back()->get_variadic_marker());
22096#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22105 bool cached_result =
false;
22113 bool result =
true;
22115 if (!l.type_base::operator==(r))
22126 l_class = m->get_class_type().get();
22129 r_class = m->get_class_type().get();
22133 if (!!l_class != !!r_class)
22143 != r_class->get_qualified_name()))
22160 bool compare_result_types =
true;
22161 string l_rt_name = l_return_type_decl
22164 string r_rt_name = r_return_type_decl
22170 (r_class && (r_class->get_qualified_name() == r_rt_name)))
22171 compare_result_types =
false;
22173 if (compare_result_types)
22197 if (l_rt_name != r_rt_name)
22247function_type::parameters::const_iterator
22253 bool is_method =
dynamic_cast<const method_type*
>(
this);
22257 if (is_method && (*i)->get_is_artificial())
22269function_type::parameters::const_iterator
22296 if (priv_->internal_cached_name_.empty())
22297 priv_->internal_cached_name_ =
22299 return priv_->internal_cached_name_;
22303 priv_->temp_internal_cached_name_ =
22305 return priv_->temp_internal_cached_name_;
22312 if (priv_->cached_name_.empty())
22313 priv_->cached_name_ =
22315 return priv_->cached_name_;
22319 priv_->cached_name_ =
22321 return priv_->cached_name_;
22334 const function_type* o =
dynamic_cast<const function_type*
>(&other);
22382 if (v.visit_begin(
this))
22385 bool keep_going =
true;
22389 if (!t->traverse(v))
22390 keep_going =
false;
22397 if (type_base_sptr parm_type = (*i)->get_type())
22398 if (!parm_type->traverse(v))
22403 return v.visit_end(
this);
22406function_type::~function_type()
22412struct method_type::priv
22414 class_or_union_wptr class_type_;
22442method_type::method_type (type_base_sptr return_type,
22443 class_or_union_sptr class_type,
22444 const std::vector<function_decl::parameter_sptr>& p,
22446 size_t size_in_bits,
22447 size_t alignment_in_bits)
22449 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22451 function_type(return_type, p, size_in_bits, alignment_in_bits),
22482method_type::method_type(type_base_sptr return_type,
22483 type_base_sptr class_type,
22484 const std::vector<function_decl::parameter_sptr>& p,
22486 size_t size_in_bits,
22487 size_t alignment_in_bits)
22489 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22491 function_type(return_type, p, size_in_bits, alignment_in_bits),
22507 size_t size_in_bits,
22508 size_t alignment_in_bits)
22510 type_base(env, size_in_bits, alignment_in_bits),
22511 function_type(env, size_in_bits, alignment_in_bits),
22530method_type::method_type(class_or_union_sptr class_type,
22532 size_t size_in_bits,
22533 size_t alignment_in_bits)
22535 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
22539 alignment_in_bits),
22566{
return class_or_union_sptr(priv_->class_type_);}
22579 priv_->class_type_ = t;
22607{priv_->is_const = f;}
22614{
return priv_->is_const;}
22630 if (!first_parm->get_is_artificial())
22633 type_base_sptr this_ptr_type = first_parm->get_type();
22641 type_base_sptr candidate_class_type =
22661struct function_decl::priv
22663 bool declared_inline_;
22671 : declared_inline_(false),
22677 bool declared_inline,
22679 : declared_inline_(declared_inline),
22682 naked_type_(t.get())
22686 bool declared_inline,
22689 : declared_inline_(declared_inline),
22692 naked_type_(t.get()),
22714 bool declared_inline,
22716 const string& mangled_name,
22720 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22751 type_base_sptr fn_type,
22752 bool declared_inline,
22754 const string& linkage_name,
22758 FUNCTION_DECL | ABSTRACT_DECL_BASE),
22759 decl_base(fn_type->
get_environment(), name, locus, linkage_name, vis),
22760 priv_(new priv(dynamic_pointer_cast<
function_type>(fn_type),
22782 bool qualified_name)
const
22787 string fn_prefix = mem_fn ?
"method ":
"function ";
22793 fn_prefix +=
"virtual ";
22795 decl_base_sptr return_type;
22802 return_type = mem_fn
22813 internal) +
" " + result;
22816 result = add_outer_pointer_to_fn_type_expr(p, result,
22821 result = add_outer_pointer_to_array_type_expr(p, result,
22828 return fn_prefix + result;
22858 result += mem_fn->
get_type()->get_class_type()->get_qualified_name()
22864 std::ostringstream fn_parms;
22865 stream_pretty_representation_of_fn_parms(*
get_type(),
22869 result += fn_parms.str();
22874 result +=
" const";
22885function_decl::parameters::const_iterator
22891 bool is_method =
dynamic_cast<const method_decl*
>(
this);
22904const shared_ptr<function_type>
22906{
return priv_->type_.lock();}
22921{
return priv_->naked_type_;}
22926 priv_->type_ = fn_type;
22927 priv_->naked_type_ = fn_type.get();
22944 priv_->symbol_ = sym;
22959{
return priv_->symbol_;}
22966{
return priv_->declared_inline_;}
22973{priv_->declared_inline_ = value;}
22976function_decl::get_binding()
const
22977{
return priv_->binding_;}
22980const shared_ptr<type_base>
22982{
return get_type()->get_return_type();}
22985const std::vector<shared_ptr<function_decl::parameter> >&
22987{
return get_type()->get_parameters();}
22994{
get_type()->append_parameter(parm);}
23002 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
23075 bool result =
true;
23079 if (t0 == t1 || *t0 == *t1)
23105 else if (s0 && s0 != s1)
23116 bool symbols_are_equal = (s0 && s1 && result);
23118 if (symbols_are_equal)
23130 bool decl_bases_different = !l.decl_base::operator==(r);
23137 if (decl_bases_different)
23147 if (!l.decl_base::operator==(r))
23159 if (l.get_binding() != r.get_binding())
23216 return equals(*
this, *o, 0);
23243 if (priv_->id_.empty())
23248 string virtual_member_suffix;
23258 virtual_member_suffix +=
"/o";
23261 if (s->has_aliases())
23268 priv_->id_ = env.
intern(s->get_id_string());
23270 if (!virtual_member_suffix.empty())
23271 priv_->id_ = env.
intern(priv_->id_ + virtual_member_suffix);
23315 if (v.visit_begin(
this))
23318 if (type_base_sptr t =
get_type())
23322 return v.visit_end(
this);
23344 if (l.get() == r.get())
23367struct function_decl::parameter::priv
23371 bool variadic_marker_;
23378 priv(type_base_sptr type,
23380 bool variadic_marker)
23383 variadic_marker_(variadic_marker)
23387function_decl::parameter::parameter(
const type_base_sptr type,
23389 const string& name,
23393 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23394 decl_base(type->get_environment(), name, loc),
23395 priv_(new priv(type, index, is_variadic))
23397 runtime_type_instance(
this);
23400function_decl::parameter::parameter(
const type_base_sptr type,
23402 const string& name,
23405 bool is_artificial)
23407 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23408 decl_base(type->get_environment(), name, loc),
23409 priv_(new priv(type, index, is_variadic))
23411 runtime_type_instance(
this);
23412 set_is_artificial(is_artificial);
23415function_decl::parameter::parameter(
const type_base_sptr type,
23416 const string& name,
23419 bool is_artificial)
23421 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23422 decl_base(type->get_environment(), name, loc),
23423 priv_(new priv(type, 0, is_variadic))
23425 runtime_type_instance(
this);
23426 set_is_artificial(is_artificial);
23429function_decl::parameter::parameter(
const type_base_sptr type,
23433 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
23435 priv_(new priv(type, index, variad))
23437 runtime_type_instance(
this);
23440function_decl::parameter::~parameter() =
default;
23442const type_base_sptr
23443function_decl::parameter::get_type()
const
23444{
return priv_->type_.lock();}
23471 if (get_variadic_marker()
23491 std::ostringstream o;
23492 o <<
"parameter-" << get_index();
23494 return env.
intern(o.str());
23498function_decl::parameter::get_index()
const
23499{
return priv_->index_;}
23502function_decl::parameter::set_index(
unsigned i)
23503{priv_->index_ = i;}
23507function_decl::parameter::get_variadic_marker()
const
23508{
return priv_->variadic_marker_;}
23534 bool result =
true;
23536 if ((l.get_variadic_marker() != r.get_variadic_marker())
23537 || (l.get_index() != r.get_index())
23538 || (!!l.get_type() != !!r.get_type()))
23543 if (l.get_index() != r.get_index())
23545 if (l.get_variadic_marker() != r.get_variadic_marker()
23546 || !!l.get_type() != !!r.get_type())
23553 type_base_sptr l_type = l.get_type();
23554 type_base_sptr r_type = r.get_type();
23556 if (l_type != r_type)
23574function_decl::parameter::operator==(
const parameter& o)
const
23575{
return equals(*
this, o, 0);}
23578function_decl::parameter::operator==(
const decl_base& o)
const
23584 return function_decl::parameter::operator==(*p);
23630 if (v.visit_begin(
this))
23633 if (type_base_sptr t =
get_type())
23637 return v.visit_end(
this);
23670 bool qualified_name)
const
23677 type_repr =
"void";
23683 string result = type_repr;
23686 if (!parm_name.empty())
23687 result +=
" " + parm_name;
23721 size_t size_in_bits,
size_t align_in_bits,
23728 | ABSTRACT_DECL_BASE
23729 | ABSTRACT_SCOPE_TYPE_DECL
23730 | ABSTRACT_SCOPE_DECL),
23731 decl_base(env, name, locus, name, vis),
23732 type_base(env, size_in_bits, align_in_bits),
23733 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23736 for (member_types::iterator i = mem_types.begin();
23737 i != mem_types.end();
23748 for (member_functions::iterator i = member_fns.begin();
23749 i != member_fns.end();
23751 if (!
has_scope(static_pointer_cast<decl_base>(*i)))
23771 size_t size_in_bits,
size_t align_in_bits,
23775 | ABSTRACT_DECL_BASE
23776 | ABSTRACT_SCOPE_TYPE_DECL
23777 | ABSTRACT_SCOPE_DECL),
23778 decl_base(env, name, locus, name, vis),
23779 type_base(env, size_in_bits, align_in_bits),
23780 scope_type_decl(env, name, size_in_bits, align_in_bits, locus, vis),
23793 bool is_declaration_only)
23796 | ABSTRACT_DECL_BASE
23797 | ABSTRACT_SCOPE_TYPE_DECL
23798 | ABSTRACT_SCOPE_DECL),
23801 scope_type_decl(env, name, 0, 0,
location()),
23818 hash_t h = do_hash(
this);
23839 if (v.visit_begin(
this))
23848 if (!(*i)->traverse(v))
23858 if (!(*i)->traverse(v))
23868 if (!(*i)->traverse(v))
23875 for (member_function_templates::const_iterator i =
23879 if (!(*i)->traverse(v))
23886 for (member_class_templates::const_iterator i =
23890 if (!(*i)->traverse(v))
23898 bool result = v.visit_end(
this);
23927 type_base_sptr t =
is_type(decl);
23952 class_or_union * anon_dm_type =
23957 for (class_or_union::data_members::const_iterator it =
24046 if (t->get_is_anonymous())
24064 if (t->get_is_anonymous())
24082 if (t->get_is_anonymous())
24107 bool is_laid_out,
bool is_static,
24108 size_t offset_in_bits)
24112 priv_->data_members_.push_back(v);
24121 bool is_already_in =
false;
24124 for (
const auto& s_dm: priv_->static_data_members_)
24128 is_already_in =
true;
24132 if (!is_already_in)
24133 priv_->static_data_members_.push_back(v);
24139 for (data_members::const_iterator i =
24140 priv_->non_static_data_members_.begin();
24141 i != priv_->non_static_data_members_.end();
24145 is_already_in =
true;
24148 if (!is_already_in)
24149 priv_->non_static_data_members_.push_back(v);
24165{
return priv_->data_members_;}
24180 if ((*i)->get_name() == name)
24192 if (
var_decl_sptr data_member = type->find_data_member(name))
24193 return data_member;
24207 if (!v->get_name().empty())
24215 if ((*it)->get_pretty_representation(
false,
true)
24216 == v->get_pretty_representation(
false,
true))
24243 if (v->get_name().empty())
24256{
return priv_->non_static_data_members_;}
24264{
return priv_->static_data_members_;}
24282 bool is_static,
bool is_ctor,
24283 bool is_dtor,
bool is_const)
24295 priv_->member_functions_.push_back(f);
24299 if (!f->get_linkage_name().empty())
24300 priv_->mem_fns_map_[f->get_linkage_name()] = f;
24309{
return priv_->member_functions_;}
24330 string_mem_fn_sptr_map_type::const_iterator i =
24331 priv_->mem_fns_map_.find(linkage_name);
24332 if (i == priv_->mem_fns_map_.end())
24334 return i->second.get();
24345 string_mem_fn_sptr_map_type::const_iterator i =
24346 priv_->mem_fns_map_.find(linkage_name);
24347 if (i == priv_->mem_fns_map_.end())
24373 string_mem_fn_ptr_map_type::const_iterator i =
24374 priv_->signature_2_mem_fn_map_.find(s);
24375 if (i == priv_->signature_2_mem_fn_map_.end())
24383const member_function_templates&
24385{
return priv_->member_function_templates_;}
24390const member_class_templates&
24392{
return priv_->member_class_templates_;}
24403 priv_->member_function_templates_.push_back(m);
24418 priv_->member_class_templates_.push_back(m);
24428 && priv_->data_members_.empty()
24429 && priv_->member_functions_.empty()
24430 && priv_->member_function_templates_.empty()
24431 && priv_->member_class_templates_.empty());
24450 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
24456 else if (member_function_template_sptr f =
24457 dynamic_pointer_cast<member_function_template>(d))
24459 else if (member_class_template_sptr c =
24460 dynamic_pointer_cast<member_class_template>(d))
24476 const class_or_union* op =
dynamic_cast<const class_or_union*
>(&other);
24482 const class_or_union *l = 0;
24489 const class_or_union *r = 0;
24509 return *
this == *o;
24550 if (l_is_decl_only || r_is_decl_only)
24552 const class_or_union* def1 = l_is_decl_only
24556 const class_or_union* def2 = r_is_decl_only
24560 if (!def1 || !def2)
24564 && l_is_decl_only && r_is_decl_only
24603 if (!!def1 != !!def2)
24611 if (!(l.decl_base::operator==(r)
24612 && l.type_base::operator==(r)))
24623 bool val = *def1 == *def2;
24632 if (!(l.decl_base::operator==(r) && l.type_base::operator==(r)))
24639 if (types_defined_same_linux_kernel_corpus_public(l, r))
24647#define RETURN(value) \
24648 return return_comparison_result(l, r, value);
24654 bool result =
true;
24668 for (class_or_union::data_members::const_iterator
24682 || (*d0)->get_type() == (*d1)->get_type())
24709 for (member_function_templates::const_iterator
24714 ++fn_tmpl_it0, ++fn_tmpl_it1)
24715 if (**fn_tmpl_it0 != **fn_tmpl_it1)
24740 for (member_class_templates::const_iterator
24745 ++cl_tmpl_it0, ++cl_tmpl_it1)
24746 if (**cl_tmpl_it0 != **cl_tmpl_it1)
24774 const method_decl_sptr& method)
24796 old_type->get_parameters(),
24797 old_type->get_is_const(),
24798 old_type->get_size_in_bits(),
24799 old_type->get_alignment_in_bits()));
24800 t->get_translation_unit()->bind_function_type_life_time(new_type);
24803 new_method(
new method_decl(method->
get_name(),
24809 method->get_binding()));
24810 new_method->set_symbol(method->
get_symbol());
24813 class_type->add_member_function(new_method,
24822 t->add_member_function(new_method,
24848 type_base_sptr old_type = variable->
get_type();
24857 size_t offset_in_bits = 0;
24861 t->add_data_member(new_variable,
24867 return new_variable;
24903struct class_decl::priv
24906 unordered_map<string, base_spec_sptr> bases_map_;
24907 member_functions virtual_mem_fns_;
24908 virtual_mem_fn_map_type virtual_mem_fns_map_;
24912 : is_struct_(false)
24953 size_t size_in_bits,
size_t align_in_bits,
24961 | ABSTRACT_TYPE_BASE
24962 | ABSTRACT_DECL_BASE
24963 | ABSTRACT_SCOPE_TYPE_DECL
24964 | ABSTRACT_SCOPE_DECL),
24965 decl_base(env, name, locus, name, vis),
24966 type_base(env, size_in_bits, align_in_bits),
24967 class_or_union(env, name, size_in_bits, align_in_bits,
24968 locus, vis, mbr_types, data_mbrs, mbr_fns),
25004 size_t size_in_bits,
size_t align_in_bits,
25011 | ABSTRACT_TYPE_BASE
25012 | ABSTRACT_DECL_BASE
25013 | ABSTRACT_SCOPE_TYPE_DECL
25014 | ABSTRACT_SCOPE_DECL),
25023 is_anonymous ? string() : name,
25025 type_base(env, size_in_bits, align_in_bits),
25026 class_or_union(env, name, size_in_bits, align_in_bits,
25027 locus, vis, mbr_types, data_mbrs, mbr_fns),
25050 size_t size_in_bits,
size_t align_in_bits,
25055 | ABSTRACT_TYPE_BASE
25056 | ABSTRACT_DECL_BASE
25057 | ABSTRACT_SCOPE_TYPE_DECL
25058 | ABSTRACT_SCOPE_DECL),
25059 decl_base(env, name, locus, name, vis),
25060 type_base(env, size_in_bits, align_in_bits),
25061 class_or_union(env, name, size_in_bits, align_in_bits,
25087 size_t size_in_bits,
size_t align_in_bits,
25092 | ABSTRACT_TYPE_BASE
25093 | ABSTRACT_DECL_BASE
25094 | ABSTRACT_SCOPE_TYPE_DECL
25095 | ABSTRACT_SCOPE_DECL),
25104 is_anonymous ? string() : name,
25106 type_base(env, size_in_bits, align_in_bits),
25107 class_or_union(env, name, size_in_bits, align_in_bits,
25125 bool is_struct,
bool is_declaration_only)
25128 | ABSTRACT_TYPE_BASE
25129 | ABSTRACT_DECL_BASE
25130 | ABSTRACT_SCOPE_TYPE_DECL
25131 | ABSTRACT_SCOPE_DECL),
25134 class_or_union(env, name, is_declaration_only),
25150 for (class_decl::virtual_mem_fn_map_type::iterator i =
25151 priv_->virtual_mem_fns_map_.begin();
25152 i != priv_->virtual_mem_fns_map_.end();
25154 sort_virtual_member_functions(i->second);
25162{priv_->is_struct_ = f;}
25169{
return priv_->is_struct_;}
25177 priv_->bases_.push_back(b);
25178 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
25186{
return priv_->bases_;}
25197 unordered_map<string, base_spec_sptr>::iterator i =
25198 priv_->bases_map_.find(qualified_name);
25200 if (i != priv_->bases_map_.end())
25201 return i->second->get_base_class();
25212{
return priv_->virtual_mem_fns_;}
25231{
return priv_->virtual_mem_fns_map_;}
25236{sort_virtual_member_functions(priv_->virtual_mem_fns_);}
25257 bool qualified_name)
const
25259 string cl =
"class ";
25268 if (internal && !
get_name().empty())
25276 string result = cl;
25277 if (qualified_name)
25286class_decl::insert_member_decl(decl_base_sptr d)
25288 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25303struct class_decl::base_spec::priv
25306 long offset_in_bits_;
25310 long offset_in_bits,
25313 offset_in_bits_(offset_in_bits),
25314 is_virtual_(is_virtual)
25332 long offset_in_bits,
25335 ABSTRACT_DECL_BASE),
25339 priv_(new priv(base, offset_in_bits, is_virtual))
25365{
return priv_->base_class_.lock();}
25372{
return priv_->is_virtual_;}
25379{
return priv_->offset_in_bits_;}
25399 if (v.visit_begin(
this))
25406 return v.visit_end(
this);
25426class_decl::base_spec::base_spec(
const type_base_sptr& base,
25428 long offset_in_bits,
25431 ABSTRACT_DECL_BASE),
25437 priv_(new priv(dynamic_pointer_cast<class_decl>(base),
25444class_decl::base_spec::~base_spec() =
default;
25470 if (!l.member_base::operator==(r))
25496 return equals(*
this, *o, 0);
25514 return operator==(
static_cast<const decl_base&
>(*o));
25517mem_fn_context_rel::~mem_fn_context_rel()
25537method_decl::method_decl(
const string& name,
25539 bool declared_inline,
25541 const string& linkage_name,
25546 | ABSTRACT_DECL_BASE
25550 declared_inline, locus, linkage_name, vis, bind)
25574method_decl::method_decl(
const string& name,
25576 bool declared_inline,
25578 const string& linkage_name,
25583 | ABSTRACT_DECL_BASE
25588 declared_inline, locus, linkage_name, vis, bind)
25611method_decl::method_decl(
const string& name,
25612 type_base_sptr type,
25613 bool declared_inline,
25615 const string& linkage_name,
25620 | ABSTRACT_DECL_BASE
25625 declared_inline, locus, linkage_name, vis, bind)
25644 class_or_union_sptr cl = t->get_class_type();
25646 cl->priv_->mem_fns_map_[l] = m;
25647 if (!old_lname.empty() && l != old_lname)
25649 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
25652 cl->priv_->mem_fns_map_.erase(old_lname);
25658method_decl::~method_decl()
25695 if (l.get() == r.get())
25748{
return dynamic_pointer_cast<method_decl>(d);}
25752struct virtual_member_function_less_than
25776 if (f_offset != s_offset)
return f_offset < s_offset;
25782 if (fn != sn)
return fn < sn;
25788 if ((!f_sym) != (!s_sym))
return !f_sym;
25789 if (f_sym && s_sym)
25791 fn = f_sym->get_id_string();
25792 sn = s_sym->get_id_string();
25793 if (fn != sn)
return fn < sn;
25800 if (fn != sn)
return fn < sn;
25804 string fn_filepath, sn_filepath;
25805 unsigned line = 0, column = 0;
25808 fn_loc.
expand(fn_filepath, line, column);
25810 sn_loc.expand(sn_filepath, line, column);
25811 return fn_filepath < sn_filepath;
25826 operator()(
const method_decl_sptr f,
25827 const method_decl_sptr s)
25828 {
return operator()(*f, *s);}
25837 virtual_member_function_less_than lt;
25838 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25867 size_t vtable_offset,
25868 bool is_static,
bool is_ctor,
25869 bool is_dtor,
bool is_const)
25872 is_dtor, is_const);
25879 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
25898 class_decl::member_functions::const_iterator m;
25899 for (m = klass->priv_->virtual_mem_fns_.begin();
25900 m != klass->priv_->virtual_mem_fns_.end();
25902 if (m->get() == method.get()
25903 || (*m)->get_linkage_name() == method->get_linkage_name())
25905 if (m == klass->priv_->virtual_mem_fns_.end())
25906 klass->priv_->virtual_mem_fns_.push_back(method);
25914 class_decl::virtual_mem_fn_map_type::iterator i =
25915 klass->priv_->virtual_mem_fns_map_.find(voffset);
25916 if (i == klass->priv_->virtual_mem_fns_map_.end())
25919 virtual_mem_fns_at_voffset.push_back(method);
25920 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
25924 for (m = i->second.begin() ; m != i->second.end(); ++m)
25925 if (m->get() == method.get()
25926 || (*m)->get_linkage_name() == method->get_linkage_name())
25928 if (m == i->second.end())
25929 i->second.push_back(method);
25958 if ((*b)->get_is_virtual()
25959 || (*b)->get_base_class()->has_virtual_bases())
25988 ssize_t offset = -1;
25989 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
25993 if (e->first > offset)
26023methods_equal_modulo_elf_symbol(
const method_decl_sptr& f,
26024 const method_decl_sptr& s)
26026 method_decl_sptr first = f, second = s;
26028 first->get_symbol();
26030 second->get_symbol();
26032 first->get_linkage_name();
26034 second->get_linkage_name();
26037 first->set_linkage_name(
"");
26039 second->set_linkage_name(
"");
26041 bool equal = *first == *second;
26043 first->set_symbol(saved_first_elf_symbol);
26044 first->set_linkage_name(saved_first_linkage_name);
26045 second->set_symbol(saved_second_elf_symbol);
26046 second->set_linkage_name(saved_second_linkage_name);
26067method_matches_at_least_one_in_vector(
const method_decl_sptr& method,
26070 for (class_decl::member_functions::const_iterator i = fns.begin();
26079 if (methods_equal_modulo_elf_symbol(method, *i))
26112 bool result =
false;
26113 if (l.
get_environment().priv_->is_type_comparison_cached(l, r, result))
26121 static_cast<const class_or_union&
>(r),
26124 bool result =
true;
26125 if (!
equals(
static_cast<const class_or_union&
>(l),
26126 static_cast<const class_or_union&
>(r),
26138#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
26150 for (class_decl::base_specs::const_iterator
26162 (*b1)->get_base_class().get()))
26208 for (class_decl::virtual_mem_fn_map_type::const_iterator first_v_fn_entry =
26211 ++first_v_fn_entry)
26213 unsigned voffset = first_v_fn_entry->first;
26215 first_v_fn_entry->second;
26217 const class_decl::virtual_mem_fn_map_type::const_iterator
26229 second_v_fn_entry->second;
26231 bool matches =
false;
26232 for (class_decl::member_functions::const_iterator i =
26233 first_vfns.begin();
26234 i != first_vfns.end();
26236 if (method_matches_at_least_one_in_vector(*i, second_vfns))
26297 const class_decl *l = 0;
26306 const class_decl *r = 0;
26330 return *
this == *o;
26374 if (l.get() == r.get())
26406operator==(
const class_or_union_sptr& l,
const class_or_union_sptr& r)
26408 if (l.get() == r.get())
26425operator!=(
const class_or_union_sptr& l,
const class_or_union_sptr& r)
26445 if (v.visit_begin(
this))
26454 if (!(*i)->traverse(v))
26465 if (!(*i)->traverse(v))
26475 if (!(*i)->traverse(v))
26485 if (!(*i)->traverse(v))
26492 for (member_function_templates::const_iterator i =
26496 if (!(*i)->traverse(v))
26503 for (member_class_templates::const_iterator i =
26507 if (!(*i)->traverse(v))
26515 bool result = v.visit_end(
this);
26524context_rel::~context_rel()
26528member_base::operator==(
const member_base& o)
const
26548 if (l.get() == r.get())
26553 return *l ==
static_cast<const decl_base&
>(*r);
26592{
return dynamic_pointer_cast<class_decl::base_spec>(tod);}
26595member_function_template::operator==(
const member_base& other)
const
26602 if (!(is_constructor() == o.is_constructor()
26603 && is_const() == o.is_const()
26604 && member_base::operator==(o)))
26611 return ftdecl->function_tdecl::operator==(*other_ftdecl);
26630 const member_function_template_sptr& r)
26632 if (l.get() == r.get())
26651 const member_function_template_sptr& r)
26668 if (v.visit_begin(
this))
26675 return v.visit_end(
this);
26688 const member_class_template& o =
26689 dynamic_cast<const member_class_template&
>(other);
26691 if (!member_base::operator==(o))
26694 return as_class_tdecl()->class_tdecl::operator==(o);
26708 if (!decl_base::operator==(other))
26710 return as_class_tdecl()->class_tdecl::operator==(other);
26723 const decl_base* o =
dynamic_cast<const decl_base*
>(&other);
26724 return *
this == *o;
26737 const member_class_template_sptr& r)
26739 if (l.get() == r.get())
26757 const member_class_template_sptr& r)
26774 if (v.visit_begin(
this))
26781 return v.visit_end(
this);
26801 case private_access:
26804 case protected_access:
26807 case public_access:
26831 c->set_is_static(s);
26841 for (
const auto& dm : cl->get_data_members())
26842 if (dm->get_name() == v->get_name())
26853 for (class_decl::data_members::iterator i =
26854 cl->priv_->non_static_data_members_.begin();
26855 i != cl->priv_->non_static_data_members_.end();
26858 if ((*i)->get_name() == v->get_name())
26860 cl->priv_->non_static_data_members_.erase(i);
26867 bool already_in_static_dms =
false;
26868 for (
const auto& s_dm : cl->priv_->static_data_members_)
26869 if (s_dm->get_name() == v->get_name())
26871 already_in_static_dms =
true;
26874 if (!already_in_static_dms)
26875 cl->priv_->static_data_members_.push_back(var);
26880 for (class_or_union::data_members::iterator i =
26881 cl->priv_->static_data_members_.begin();
26882 i != cl->priv_->static_data_members_.end();
26884 if ((*i)->get_name() == v->get_name())
26886 cl->priv_->static_data_members_.erase(i);
26892 bool is_already_in_non_static_data_members =
false;
26893 for (
const auto& ns_dm : cl->priv_->non_static_data_members_)
26894 if (ns_dm->get_name() == v->get_name())
26896 is_already_in_non_static_data_members =
true;
26899 if (!is_already_in_non_static_data_members)
26900 cl->priv_->non_static_data_members_.push_back(var);
26940 size_t size_in_bits,
const location& locus,
26945 | ABSTRACT_TYPE_BASE
26946 | ABSTRACT_DECL_BASE),
26947 decl_base(env, name, locus, name, vis),
26949 class_or_union(env, name, size_in_bits, 0,
26950 locus, vis, mbr_types, data_mbrs, member_fns)
26976 size_t size_in_bits,
const location& locus,
26982 | ABSTRACT_TYPE_BASE
26983 | ABSTRACT_DECL_BASE),
26992 is_anonymous ? string() : name,
26995 class_or_union(env, name, size_in_bits, 0,
26996 locus, vis, mbr_types, data_mbrs, member_fns)
27014 size_t size_in_bits,
const location& locus,
27018 | ABSTRACT_TYPE_BASE
27019 | ABSTRACT_DECL_BASE
27020 | ABSTRACT_SCOPE_TYPE_DECL
27021 | ABSTRACT_SCOPE_DECL),
27022 decl_base(env, name, locus, name, vis),
27024 class_or_union(env, name, size_in_bits,
27045 size_t size_in_bits,
const location& locus,
27049 | ABSTRACT_TYPE_BASE
27050 | ABSTRACT_DECL_BASE
27051 | ABSTRACT_SCOPE_TYPE_DECL
27052 | ABSTRACT_SCOPE_DECL),
27061 is_anonymous ? string() : name,
27064 class_or_union(env, name, size_in_bits,
27080 const string& name,
27081 bool is_declaration_only)
27084 | ABSTRACT_TYPE_BASE
27085 | ABSTRACT_DECL_BASE
27086 | ABSTRACT_SCOPE_TYPE_DECL
27087 | ABSTRACT_SCOPE_DECL),
27090 class_or_union(env, name, is_declaration_only)
27128 bool qualified_name)
const
27133 if (internal && !
get_name().empty())
27134 repr = string(
"union ") +
27144 if (qualified_name)
27162 const union_decl* op =
dynamic_cast<const union_decl*
>(&other);
27181 return *
this == *o;
27195 return *
this == *o;
27228 if (v.visit_begin(
this))
27237 if (!(*i)->traverse(v))
27247 if (!(*i)->traverse(v))
27257 if (!(*i)->traverse(v))
27264 for (member_function_templates::const_iterator i =
27268 if (!(*i)->traverse(v))
27275 for (member_class_templates::const_iterator i =
27279 if (!(*i)->traverse(v))
27287 bool result = v.visit_end(
this);
27326 bool result =
false;
27327 if (l.
get_environment().priv_->is_type_comparison_cached(l, r, result))
27348 const method_decl_sptr& f)
27363 const class_or_union_sptr t = union_type;
27378 if (l.get() == r.get())
27402class template_decl::priv
27406 std::list<template_parameter_sptr> parms_;
27419{priv_->parms_.push_back(p);}
27425const std::list<template_parameter_sptr>&
27427{
return priv_->parms_;}
27440 const string& name,
27444 decl_base(env, name, locus,
"", vis),
27462 const template_decl* other =
dynamic_cast<const template_decl*
>(&o);
27465 return *
this == *other;
27478 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
27504class template_parameter::priv
27510 mutable bool hashing_started_;
27511 mutable bool comparison_started_;
27519 template_decl_(enclosing_template_decl),
27520 hashing_started_(),
27521 comparison_started_()
27525template_parameter::template_parameter(
unsigned index,
27527 : priv_(new priv(index, enclosing_template))
27531template_parameter::get_index()
const
27532{
return priv_->index_;}
27535template_parameter::get_enclosing_template_decl()
const
27536{
return priv_->template_decl_.lock();}
27542 if (get_index() != o.get_index())
27545 if (priv_->comparison_started_)
27548 bool result =
false;
27553 priv_->comparison_started_ =
true;
27555 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
27557 else if (get_enclosing_template_decl()
27558 && (*get_enclosing_template_decl()
27559 != *o.get_enclosing_template_decl()))
27564 priv_->comparison_started_ =
false;
27577{
return !operator==(other);}
27584class type_tparameter::priv
27599type_tparameter::type_tparameter(
unsigned index,
27601 const string& name,
27605 | ABSTRACT_TYPE_BASE
27610 template_parameter(index, enclosing_tdecl),
27624 if (!type_decl::operator==(other))
27629 const type_tparameter& o =
dynamic_cast<const type_tparameter&
>(other);
27630 return template_parameter::operator==(o);
27644 if (!type_decl::operator==(other))
27649 const type_tparameter& o =
dynamic_cast<const type_tparameter&
>(other);
27650 return template_parameter::operator==(o);
27664 if (!decl_base::operator==(other))
27669 const type_tparameter& o =
dynamic_cast<const type_tparameter&
>(other);
27670 return template_parameter::operator==(o);
27700{
return *
this ==
static_cast<const type_base&
>(other);}
27702type_tparameter::~type_tparameter()
27706class non_type_tparameter::priv
27716 priv(type_base_sptr type)
27734non_type_tparameter::non_type_tparameter(
unsigned index,
27736 const string& name,
27737 type_base_sptr type,
27741 template_parameter(index, enclosing_tdecl),
27742 priv_(new priv(type))
27750const type_base_sptr
27752{
return priv_->type_.lock();}
27758 if (!decl_base::operator==(other))
27763 const non_type_tparameter& o =
27764 dynamic_cast<const non_type_tparameter&
>(other);
27765 return (template_parameter::operator==(o)
27784non_type_tparameter::~non_type_tparameter()
27790class template_tparameter::priv
27804template_tparameter::template_tparameter(
unsigned index,
27806 const string& name,
27810 | ABSTRACT_TYPE_BASE
27815 0, 0, locus, name, VISIBILITY_DEFAULT),
27816 type_tparameter(index, enclosing_tdecl, name, locus),
27833 const template_tparameter& o =
27834 dynamic_cast<const template_tparameter&
>(other);
27835 return (type_tparameter::operator==(o)
27836 && template_decl::operator==(o));
27852 const template_tparameter& o =
27853 dynamic_cast<const template_tparameter&
>(other);
27854 return (type_tparameter::operator==(o)
27855 && template_decl::operator==(o));
27866 const template_tparameter& other =
27867 dynamic_cast<const template_tparameter&
>(o);
27868 return *
this ==
static_cast<const type_base&
>(other);
27879 const template_tparameter& other =
27880 dynamic_cast<const template_tparameter&
>(o);
27887template_tparameter::~template_tparameter()
27895class type_composition::priv
27919type_composition::type_composition(
unsigned index,
27923 ABSTRACT_DECL_BASE),
27925 template_parameter(index, tdecl),
27934const type_base_sptr
27936{
return priv_->type_.lock();}
27945type_composition::~type_composition()
27954class function_tdecl::priv
27966 : pattern_(pattern), binding_(bind)
27993 | ABSTRACT_SCOPE_DECL),
27995 template_decl(env,
"", locus, vis),
27996 scope_decl(env,
"", locus),
27997 priv_(new priv(bind))
28021 | ABSTRACT_SCOPE_DECL),
28026 priv_(new priv(pattern, bind))
28037 priv_->pattern_ = p;
28047{
return priv_->pattern_;}
28054{
return priv_->binding_;}
28064 const function_tdecl* o =
dynamic_cast<const function_tdecl*
>(&other);
28066 return *
this == *o;
28078 const function_tdecl* o =
dynamic_cast<const function_tdecl*
>(&other);
28080 return *
this == *o;
28093 && template_decl::operator==(o)
28094 && scope_decl::operator==(o)
28118 if (!v.visit_begin(
this))
28125 return v.visit_end(
this);
28128function_tdecl::~function_tdecl()
28136class class_tdecl::priv
28147 : pattern_(pattern)
28166 | ABSTRACT_SCOPE_DECL),
28168 template_decl(env,
"", locus, vis),
28169 scope_decl(env,
"", locus),
28191 | ABSTRACT_SCOPE_DECL),
28196 priv_(new priv(pattern))
28207 priv_->pattern_ = p;
28217{
return priv_->pattern_;}
28224 const class_tdecl& o =
dynamic_cast<const class_tdecl&
>(other);
28226 if (!(template_decl::operator==(o)
28227 && scope_decl::operator==(o)
28245 const class_tdecl& o =
dynamic_cast<const class_tdecl&
>(other);
28246 return *
this ==
static_cast<const decl_base&
>(o);
28254{
return *
this ==
static_cast<const decl_base&
>(o);}
28270 if (v.visit_begin(
this))
28274 pattern->traverse(v);
28277 return v.visit_end(
this);
28280class_tdecl::~class_tdecl()
28291 non_canonicalized_subtype_detector();
28294 non_canonicalized_subtype_detector(
type_base* type)
28296 has_non_canonical_type_()
28305 has_non_canonical_type()
const
28306 {
return has_non_canonical_type_;}
28311 visit_begin(function_decl* f)
28329 visit_begin(type_base* t)
28333 if (!t->get_canonical_type())
28337 has_non_canonical_type_ = t;
28352 visit_end(type_base* )
28354 if (has_non_canonical_type_)
28371 non_canonicalized_subtype_detector v(t.get());
28373 return v.has_non_canonical_type();
28389 const type_base_sptr t_v2)
28396 return (t1 != t2 && repr1 == repr2);
28407 env.priv_->extra_live_types_.push_back(t);
28442 result =
reinterpret_cast<size_t>(g);
28444 result =
reinterpret_cast<size_t>(s);
28450 string repr = v->get_pretty_representation(
true);
28451 std::hash<string> hash_string;
28459 string repr = f->get_pretty_representation(
true);
28460 std::hash<string> hash_string;
28466 type_base_sptr parm_type = p->get_type();
28468 std::hash<bool> hash_bool;
28469 std::hash<unsigned> hash_unsigned;
28478 std::hash<size_t> hash_size;
28479 std::hash<bool> hash_bool;
28480 type_base_sptr type = bs->get_base_class();
28517{
return hash_as_canonical_type_or_constant(t);}
28540 const type_or_decl_base* artefactp = &artefact;
28544 if (d->type_or_decl_base::priv_->get_hashing_state()
28546 return d->type_or_decl_base::priv_->hash_value_;
28549 return artefact.priv_->hash_value_;
28651 exemplar =
const_cast<type_base*
>(type);
28680hash_as_canonical_type_or_constant(
const type_base *t)
28687 if (!canonical_type)
28705 if (canonical_type)
28706 return reinterpret_cast<size_t>(canonical_type);
28781 const type_base_sptr& second,
28782 bool indirect_type)
28814 bool indirect_type)
28816 if (!!first != !!second)
28828 if (
typeid(*first) !=
typeid(*second))
28844 if (ty1->is_lvalue() != ty2->is_lvalue())
28847 ty2->get_pointed_to_type(),
28866 if (!indirect_type)
28870 return ty1->get_name() == ty2->
get_name();
28876 if (!indirect_type)
28880 return (
get_name(ty1->get_underlying_type())
28888 && ty1->get_name() != ty2->
get_name())
28891 if (!indirect_type)
28894 || (ty1->get_non_static_data_members().size()
28898 for (class_or_union::data_members::const_iterator
28899 i = ty1->get_non_static_data_members().begin(),
28901 (i != ty1->get_non_static_data_members().end()
28908 dm2->get_type().get(),
28921 && ty1->get_name() != ty2->
get_name())
28924 if (!indirect_type)
28933 if (!indirect_type)
28936 || ty1->get_dimension_count() != ty2->get_dimension_count())
28956 for (
auto r1 = ty1->get_subranges().begin(),
28957 r2 = ty1->get_subranges().begin();
28958 (r1 != ty1->get_subranges().end()
28961 if ((*r1)->get_length() != (*r2)->get_length())
28996 if (ty1->get_parameters().size() != ty2->
get_parameters().size())
28999 for (function_type::parameters::const_iterator
29000 i = ty1->get_parameters().begin(),
29002 (i != ty1->get_parameters().end()
29032 const char* dm_name)
29060 return cou->find_data_member(dm);
29075 unsigned parm_index)
29082 if (parms.size() <= parm_index)
29085 return parms[parm_index].get();
29100 std::ostringstream o;
29103 o <<
"unnamed-enum";
29105 o <<
"enum-" << base_name;
29107 o <<
"-underlying-type-" << size;
29127 return data_member;
29147 for (; d != e; ++d)
29168stream_pretty_representation_of_fn_parms(
const function_type& fn_type,
29169 ostream& o,
bool qualified,
29177 type_base_sptr type;
29184 if (i != first_parm)
29187 type = parm->get_type();
29250add_outer_pointer_to_fn_type_expr(
const type_base* p,
29251 const string& input,
29252 bool qualified,
bool internal)
29258 string star_or_ref;
29271 if (!pointed_to_fn)
29274 if (pointed_to_fn->priv_->is_pretty_printing())
29284 pointed_to_fn->priv_->set_is_pretty_printing();
29286 std::ostringstream left, right, inner;
29288 inner <<
"(" << star_or_ref << input <<
")";
29290 type_base_sptr type;
29291 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
29292 qualified, internal);
29294 type_base_sptr return_type = pointed_to_fn->get_return_type();
29303 result = left.str() +
" " + inner.str() + right.str();
29307 string inner_string = inner.str() + right.str();
29308 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
29309 qualified, internal);
29313 string inner_string = inner.str() + right.str();
29314 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29315 qualified, internal);
29323 pointed_to_fn->priv_->unset_is_pretty_printing();
29374add_outer_pointer_to_fn_type_expr(
const type_base_sptr& p,
29375 const string& input,
29376 bool qualified,
bool internal)
29377{
return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
29430add_outer_pointer_to_array_type_expr(
const type_base* p,
29431 const string& input,
bool qualified,
29437 string star_or_ref;
29438 type_base_sptr pointed_to_type;
29442 pointed_to_type = ptr->get_pointed_to_type();
29447 pointed_to_type = ref->get_pointed_to_type();
29455 std::ostringstream left, right, inner;
29456 inner <<
"(" << star_or_ref << input <<
")";
29457 right << array->get_subrange_representation();
29460 type_base_sptr array_element_type = array->get_element_type();
29466 left <<
get_type_name(array_element_type, qualified, internal);
29467 result = left.str() + inner.str() + right.str();
29472 string r = inner.str() + right.str();
29473 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
29478 string inner_string = inner.str() + right.str();
29479 result = add_outer_pointer_to_array_type_expr(p, inner_string,
29480 qualified, internal);
29539add_outer_pointer_to_array_type_expr(
const type_base_sptr& pointer_to_ar,
29540 const string& input,
bool qualified,
29542{
return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
29543 input, qualified, internal);}
29592 const string& input,
bool qualified,
29598 std::ostringstream left, right, inner;
29599 type_base_sptr void_type = p->get_environment().get_void_type();
29600 string containing_type_name =
get_type_name(p->get_containing_type(),
29601 qualified, internal);
29602 type_base_sptr mbr_type = p->get_member_type();
29606 inner <<
"(" << containing_type_name <<
"::*" << input <<
")";
29607 stream_pretty_representation_of_fn_parms(*fn_type, right,
29608 qualified, internal);
29611 return_type = void_type;
29618 left <<
get_type_name(return_type, qualified, internal) <<
" ";;
29619 result = left.str() + inner.str() + right.str();
29623 string inner_str = inner.str() + right.str();
29624 result = pointer_declaration_name(p, inner_str, qualified, internal);
29628 string inner_str = inner.str() + right.str();
29629 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
29630 qualified, internal);
29637 inner <<
"(" << containing_type_name <<
"::*" << input <<
")";
29638 stream_pretty_representation_of_fn_parms(*fn_type, right,
29639 qualified, internal);
29640 string inner_str = inner.str() + right.str();
29641 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
29642 qualified, internal);
29646 left <<
get_type_name(p->get_member_type(), qualified, internal) <<
" ";
29647 inner << containing_type_name <<
"::*" << input;
29648 result = left.str()+ inner.str();
29668 string d1_name, d2_name;
29685 return d1_name != d2_name;
29708 const type_base_sptr& s)
29720 && (f->get_size_in_bits() == s->get_size_in_bits())
29721 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
29735 const decl_base_sptr& s)
29786 const string& input,
bool qualified,
29788{
return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
29808add_outer_pointer_to_ptr_to_mbr_type_expr(
const type_base* p,
29809 const string& input,
bool qualified,
29815 string star_or_ref;
29816 type_base_sptr pointed_to_type;
29820 pointed_to_type = ptr->get_pointed_to_type();
29825 pointed_to_type= ref->get_pointed_to_type();
29829 if (!pointed_to_type)
29834 if (!pointed_to_ptr_to_mbr)
29837 std::ostringstream inner;
29838 inner << star_or_ref << input;
29839 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
29841 qualified, internal);
29858static interned_string
29859pointer_declaration_name(
const type_base* ptr,
29860 const string& idname,
29861 bool qualified,
bool internal)
29864 return interned_string();
29866 type_base_sptr pointed_to_type;
29867 string star_or_ref;
29870 pointed_to_type = p->get_pointed_to_type();
29875 pointed_to_type = p->get_pointed_to_type();
29879 if (!pointed_to_type)
29880 return interned_string();
29893 if (!idname.empty())
29900 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
29901 qualified, internal);
29903 result = add_outer_pointer_to_array_type_expr(ptr, idname,
29904 qualified, internal);
29906 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
29907 qualified, internal);
29911 return ptr->get_environment().intern(result);
29928static interned_string
29929pointer_declaration_name(
const type_base_sptr& ptr,
29930 const string& variable_name,
29931 bool qualified,
bool internal)
29932{
return pointer_declaration_name(ptr.get(), variable_name,
29933 qualified, internal);}
29948static interned_string
29950 const string& variable_name,
29951 bool qualified,
bool internal)
29954 return interned_string();
29956 type_base_sptr e_type = array->get_element_type();
29957 string e_type_repr =
29965 std::ostringstream o;
29966 if (!variable_name.empty())
29967 o << variable_name <<
" is ";
29969 << array->get_subrange_representation()
29970 <<
") of " << e_type_repr;
29975 if (is_npaf_type(e_type)
29976 || !(is_pointer_to_function_type(e_type)
29977 || is_pointer_to_array_type(e_type)
29978 || is_pointer_to_ptr_to_mbr_type(e_type)
29979 || is_ptr_to_mbr_type(e_type)))
29981 result = e_type_repr;
29982 if (!variable_name.empty())
29983 result += variable_name;
29984 result += array->get_subrange_representation();
29988 string s = variable_name + array->get_subrange_representation();
29989 result = pointer_declaration_name(p, s, qualified, internal);
29993 string s = variable_name + array->get_subrange_representation();
29994 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
29999 return array->get_environment().intern(result);
30017 const string& variable_name,
30018 bool qualified,
bool internal)
30019{
return array_declaration_name(array.get(), variable_name,
30020 qualified, internal);}
30037 const string& variable_name,
30038 bool qualified,
bool internal)
30043 string input = variable_name;
30044 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
30045 qualified, internal);
30046 return ptr->get_environment().intern(result);
30064 const string& variable_name,
30065 bool qualified,
bool internal)
30067 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
30068 qualified, internal);
30087struct ir_node_visitor::priv
30102ir_node_visitor::~ir_node_visitor() =
default;
30111{priv_->allow_visiting_already_visited_type_node = f;}
30120{
return priv_->allow_visiting_already_visited_type_node;}
30141 canonical_type = p;
30145 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical_type);
30146 priv_->visited_ir_nodes.insert(canonical_ptr_value);
30159{priv_->visited_ir_nodes.clear();}
30180 canonical_type = p;
30184 size_t ptr_value =
reinterpret_cast<size_t>(canonical_type);
30185 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
30186 if (it == priv_->visited_ir_nodes.end())
30193ir_node_visitor::visit_begin(
decl_base*)
30201ir_node_visitor::visit_begin(scope_decl*)
30209ir_node_visitor::visit_begin(
type_base*)
30218{
return visit_begin(
static_cast<type_base*
>(t));}
30222{
return visit_end(
static_cast<type_base*
>(t));}
30225ir_node_visitor::visit_begin(
type_decl* t)
30226{
return visit_begin(
static_cast<type_base*
>(t));}
30229ir_node_visitor::visit_end(
type_decl* t)
30230{
return visit_end(
static_cast<type_base*
>(t));}
30234{
return visit_begin(
static_cast<decl_base*
>(d));}
30238{
return visit_end(
static_cast<decl_base*
>(d));}
30242{
return visit_begin(
static_cast<type_base*
>(t));}
30246{
return visit_end(
static_cast<type_base*
>(t));}
30250{
return visit_begin(
static_cast<type_base*
>(t));}
30254{
return visit_end(
static_cast<type_base*
>(t));}
30258{
return visit_begin(
static_cast<type_base*
>(t));}
30262{
return visit_end(
static_cast<type_base*
>(t));}
30266{
return visit_begin(
static_cast<type_base*
>(t));}
30270{
return visit_end(
static_cast<type_base*
>(t));}
30274{
return visit_begin(
static_cast<type_base*
>(t));}
30278{
return visit_end(
static_cast<type_base*
>(t));}
30282{
return visit_begin(
static_cast<type_base*
>(t));}
30286{
return visit_end(
static_cast<type_base*
>(t));}
30290{
return visit_begin(
static_cast<type_base*
>(t));}
30294{
return visit_end(
static_cast<type_base*
>(t));}
30298{
return visit_begin(
static_cast<type_base*
>(t));}
30302{
return visit_end(
static_cast<type_base*
>(t));}
30306{
return visit_begin(
static_cast<type_base*
>(t));}
30310{
return visit_end(
static_cast<type_base*
>(t));}
30313ir_node_visitor::visit_begin(
var_decl* d)
30314{
return visit_begin(
static_cast<decl_base*
>(d));}
30317ir_node_visitor::visit_end(
var_decl* d)
30318{
return visit_end(
static_cast<decl_base*
>(d));}
30322{
return visit_begin(
static_cast<decl_base*
>(d));}
30326{
return visit_end(
static_cast<decl_base*
>(d));}
30330{
return visit_begin(
static_cast<decl_base*
>(d));}
30334{
return visit_end(
static_cast<decl_base*
>(d));}
30338{
return visit_begin(
static_cast<decl_base*
>(d));}
30342{
return visit_end(
static_cast<decl_base*
>(d));}
30346{
return visit_begin(
static_cast<decl_base*
>(d));}
30350{
return visit_end(
static_cast<decl_base*
>(d));}
30354{
return visit_begin(
static_cast<type_base*
>(t));}
30358{
return visit_end(
static_cast<type_base*
>(t));}
30362{
return visit_begin(
static_cast<type_base*
>(t));}
30366{
return visit_end(
static_cast<type_base*
>(t));}
30370{
return visit_begin(
static_cast<type_base*
>(t));}
30374{
return visit_end(
static_cast<type_base*
>(t));}
30378{
return visit_begin(
static_cast<decl_base*
>(d));}
30382{
return visit_end(
static_cast<decl_base*
>(d));}
30386{
return visit_begin(
static_cast<decl_base*
>(d));}
30390{
return visit_end(
static_cast<decl_base*
>(d));}
30394{
return visit_begin(
static_cast<decl_base*
>(d));}
30398{
return visit_end(
static_cast<decl_base*
>(d));}
30410 static __thread
size_t counter;
30412 std::ostringstream o;
30418struct function_decl_hash
30420 size_t operator()(
const function_decl* f)
const
30421 {
return reinterpret_cast<size_t>(f);}
30424 {
return operator()(f.get());}
30430 function_decl_hash,
30449static const string&
30453 fns_to_str_map_type::const_iterator i = m.find(fn);
30456 string s = get_next_string();
30483 for (i = begin; i != end; ++i)
30484 o <<
"'" << fn_to_str(*i, m) <<
"' ";
30510fns_to_str(vector<function_decl*>::const_iterator a_begin,
30511 vector<function_decl*>::const_iterator a_end,
30512 vector<function_decl*>::const_iterator b_begin,
30513 vector<function_decl*>::const_iterator b_end,
30517 fns_to_str(a_begin, a_end, m, o);
30519 fns_to_str(b_begin, b_end, m, o);
30550 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
30570qualified_name_setter::do_update(abigail::ir::decl_base* d)
30572 std::string parent_qualified_name;
30573 abigail::ir::scope_decl* parent = d->
get_scope();
30577 d->priv_->qualified_parent_name_ = abigail::interned_string();
30581 if (!d->priv_->qualified_parent_name_.
empty())
30584 d->priv_->qualified_name_ = abigail::interned_string();
30587 d->priv_->qualified_name_ =
30588 env.
intern(d->priv_->qualified_parent_name_ +
"::" + d->
get_name());
30596 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
30598 if (d->priv_->scoped_name_.
empty())
30603 d->priv_->scoped_name_ =
30606 d->priv_->scoped_name_ =
30623qualified_name_setter::visit_begin(abigail::ir::decl_base* d)
30624{
return do_update(d);}
30633qualified_name_setter::visit_begin(abigail::ir::type_base* t)
30636 return do_update(d);
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the corpus type.
#define ABG_RETURN_FALSE
A macro used to return the "false" boolean from DIE comparison routines.
#define ABG_RETURN(value)
A macro used to return from DIE comparison routines.
#define ABG_ASSERT(cond)
This is a wrapper around the 'assert' glibc call. It allows for its argument to have side effects,...
Declaration of types pertaining to the interned string pool used throughout Libabigail,...
This contains the private implementation of the suppression engine of libabigail.
#define CACHE_COMPARISON_RESULT_AND_RETURN(value)
Cache the result of a comparison between too artifacts (l & r) and return immediately.
#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r)
This macro is to be used while comparing composite types that might recursively refer to themselves....
Types of the main internal representation of libabigail.
Wrappers around regex types and functions.
Simplified implementation of std::optional just enough to be used as a replacement for our purposes a...
This type abstracts the configuration information of the library.
Abstraction of a function parameter.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a parameter.
bool has_string(const char *s) const
Test if the interned string pool already contains a string with a given value.
const char * get_string(const char *s) const
Get a pointer to the interned string which has a given value.
interned_string create_string(const std::string &)
Create an interned string with a given value.
interned_string_pool()
Default constructor.
~interned_string_pool()
Destructor.
The abstraction of an interned string.
bool empty() const
Test if the current instance of interned_string is empty.
void clear()
Clear the string.
This class is to hold the value of the bound of a subrange. The value can be either signed or unsigne...
void set_signed(int64_t v)
Setter of the bound value as signed.
void set_signedness(enum signedness s)
Setter of the signedness (unsigned VS signed) of the bound value.
enum signedness get_signedness() const
Getter of the signedness (unsigned VS signed) of the bound value.
int64_t get_signed_value() const
Getter of the bound value as a signed value.
bool operator==(const bound_value &) const
Equality operator of the bound value.
uint64_t get_unsigned_value()
Getter of the bound value as an unsigned value.
bound_value()
Default constructor of the bound_value class.
void set_unsigned(uint64_t v)
Setter of the bound value as unsigned.
Abstraction for an array range type, like in Ada, or just for an array dimension like in C or C++.
void set_lower_bound(int64_t lb)
Setter of the lower bound.
bool is_non_finite() const
Test if the length of the subrange type is infinite.
void set_upper_bound(int64_t ub)
Setter of the upper bound of the subrange type.
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type of the subrange, that is, the type that defines the range.
string as_string() const
Return a string representation of the sub range.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
bool operator!=(const decl_base &o) const
Equality operator.
int64_t get_upper_bound() const
Getter of the upper bound of the subrange type.
type_base_sptr get_underlying_type() const
Getter of the underlying type of the subrange, that is, the type that defines the range.
virtual bool operator==(const decl_base &) const
Equality operator.
int64_t get_lower_bound() const
Getter of the lower bound of the subrange type.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build a pretty representation for an array_type_def::subrange_type.
static string vector_as_string(const vector< subrange_sptr > &)
Return a string representation of a vector of subranges.
uint64_t get_length() const
Getter of the length of the subrange type.
translation_unit::language get_language() const
Getter of the language that generated this type.
The abstraction of an array type.
virtual bool is_non_finite() const
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the array_type_def.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
const type_base_sptr get_element_type() const
Getter of the type of an array element.
void set_element_type(const type_base_sptr &element_type)
Setter of the type of array element.
shared_ptr< subrange_type > subrange_sptr
Convenience typedef for a shared pointer on a function_decl::subrange.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
const std::vector< subrange_sptr > & get_subranges() const
Get the array's subranges.
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
std::vector< subrange_sptr > subranges_type
Convenience typedef for a vector of subrange_sptr.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of array_type_def.
translation_unit::language get_language() const
Get the language of the array.
virtual void append_subranges(const std::vector< subrange_sptr > &subs)
Append subranges from the vector.
Abstraction of a base specifier in a class declaration.
class_decl_sptr get_base_class() const
Get the base class referred to by the current base class specifier.
bool get_is_virtual() const
Getter of the "is-virtual" proprerty of the base class specifier.
long get_offset_in_bits() const
Getter of the offset of the base.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &)
Traverses an instance of base_spec, visiting all the sub-types and decls that it might contain.
virtual bool operator==(const decl_base &) const
Comparison operator for base_spec.
Abstracts a class declaration.
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
void is_struct(bool f)
Set the "is-struct" flag of the class.
bool has_virtual_member_functions() const
Test if the current instance of class_decl has virtual member functions.
const virtual_mem_fn_map_type & get_virtual_mem_fns_map() const
Get the map that associates a virtual table offset to the virtual member functions with that virtual ...
bool is_struct() const
Test if the class is a struct.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
const base_specs & get_base_specifiers() const
Get the base specifiers for this class.
virtual ~class_decl()
Destructor of the class_decl type.
virtual void on_canonical_type_set()
This method is invoked automatically right after the current instance of class_decl has been canonica...
bool has_vtable() const
Test if the current instance has a vtable.
ssize_t get_biggest_vtable_offset() const
Get the highest vtable offset of all the virtual methods of the class.
bool has_virtual_bases() const
Test if the current instance of class_decl has at least one virtual base.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
shared_ptr< base_spec > base_spec_sptr
Convenience typedef.
void add_base_specifier(shared_ptr< base_spec > b)
Add a base specifier to this class.
const member_functions & get_virtual_mem_fns() const
Get the virtual member functions of this class.
void sort_virtual_mem_fns()
Sort the virtual member functions by their virtual index.
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl.
class_decl_sptr find_base_class(const string &qualified_name) const
Find a base class of a given qualified name for the current class.
bool has_no_base_nor_member() const
Return true iff the class has no entity in its scope.
vector< base_spec_sptr > base_specs
Convenience typedef.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Getter of the pretty representation of the current instance of class_decl.
The base type of class_decl and union_decl.
virtual size_t get_num_anonymous_member_classes() const
Get the number of anonymous member classes contained in this class.
void add_member_function(method_decl_sptr f, access_specifier a, bool is_static, bool is_ctor, bool is_dtor, bool is_const)
Add a member function.
const var_decl_sptr find_anonymous_data_member(const var_decl_sptr &) const
Find an anonymous data member in the class.
const member_functions & get_member_functions() const
Get the member functions of this class_or_union.
virtual void remove_member_decl(decl_base_sptr)
Remove a given decl from the current class_or_union scope.
const member_function_templates & get_member_function_templates() const
Get the member function templates of this class.
virtual size_t get_size_in_bits() const
Getter of the size of the class_or_union type.
virtual size_t get_num_anonymous_member_unions() const
Get the number of anonymous member unions contained in this class.
void add_member_function_template(member_function_template_sptr)
Append a member function template to the class_or_union.
unordered_map< ssize_t, member_functions > virtual_mem_fn_map_type
Convenience typedef.
vector< method_decl_sptr > member_functions
Convenience typedef.
const data_members & get_data_members() const
Get the data members of this class_or_union.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
void add_data_member(var_decl_sptr v, access_specifier a, bool is_laid_out, bool is_static, size_t offset_in_bits)
Add a data member to the current instance of class_or_union.
const method_decl * find_member_function_from_signature(const string &s) const
Find a method (member function) using its signature (pretty representation) as a key.
method_decl_sptr find_member_function_sptr(const string &mangled_name)
Find a method, using its linkage name as a key.
virtual void set_size_in_bits(size_t)
Setter of the size of the class_or_union type.
decl_base_sptr insert_member_decl(decl_base_sptr member)
Insert a data member to this class_or_union type.
virtual decl_base_sptr add_member_decl(const decl_base_sptr &)
Add a member declaration to the current instance of class_or_union. The member declaration can be eit...
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
void add_member_class_template(member_class_template_sptr m)
Append a member class template to the class_or_union.
const data_members & get_non_static_data_members() const
Get the non-static data members of this class_or_union.
const method_decl * find_member_function(const string &mangled_name) const
Find a method, using its linkage name as a key.
const data_members & get_static_data_members() const
Get the static data memebers of this class_or_union.
void maybe_fixup_members_of_anon_data_member(var_decl_sptr &anon_dm)
Fixup the members of the type of an anonymous data member.
vector< var_decl_sptr > data_members
Convenience typedef.
virtual ~class_or_union()
Destrcutor of the class_or_union type.
bool has_no_member() const
virtual bool operator==(const decl_base &) const
Equality operator.
friend void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
virtual size_t get_alignment_in_bits() const
Getter of the alignment of the class_or_union type.
const member_class_templates & get_member_class_templates() const
Get the member class templates of this class.
virtual void set_alignment_in_bits(size_t)
Setter of the alignment of the class type.
vector< type_base_sptr > member_types
Convenience typedef.
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
const var_decl_sptr find_data_member(const string &) const
Find a data member of a given name in the current class_or_union.
Abstract a class template.
shared_ptr< class_decl > get_pattern() const
Getter of the pattern of the template.
void set_pattern(class_decl_sptr p)
Setter of the pattern of the template.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
virtual bool operator==(const decl_base &) const
Equality operator.
The abstraction of the relationship between an entity and its containing scope (its context)....
This is the abstraction of a set of translation units (themselves seen as bundles of unitary abi arte...
shared_ptr< exported_decls_builder > exported_decls_builder_sptr
Convenience typedef for shared_ptr<exported_decls_builder>.
const translation_units & get_translation_units() const
Return the list of translation units of the current corpus.
origin get_origin() const
Getter for the origin of the corpus.
type_maps & get_types()
Get the maps that associate a name to a certain kind of type.
type_maps & get_type_per_loc_map()
Get the maps that associate a location string to a certain kind of type.
const corpus_group * get_group() const
Getter of the group this corpus is a member of.
const environment & get_environment() const
Getter of the enviroment of the corpus.
The base type of all declarations.
void set_definition_of_declaration(const decl_base_sptr &)
Set the definition of this declaration-only decl_base.
void set_is_declaration_only(bool f)
Set a flag saying if the enum_type_decl is a declaration-only enum_type_decl.
virtual bool operator!=(const decl_base &) const
Inequality operator.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
scope_decl * get_scope() const
Return the type containing the current decl, if any.
void set_qualified_name(const interned_string &) const
Setter for the qualified name.
void set_is_in_public_symbol_table(bool)
Set the flag saying if this decl is from a symbol that is in a public symbols table,...
friend bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
const decl_base_sptr get_earlier_declaration() const
If this decl_base is a definition, get its earlier declaration.
virtual void set_linkage_name(const string &m)
Setter for the linkage name.
const decl_base * get_naked_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the decl.
void clear_qualified_name()
Clear the qualified name of this decl.
virtual void set_name(const string &n)
Setter for the name of the decl.
const location & get_location() const
Get the location of a given declaration.
typedef_decl_sptr get_naming_typedef() const
Getter for the naming typedef of the current decl.
virtual const interned_string & get_name() const
Getter for the name of the current decl.
virtual void set_scope(scope_decl *)
Setter of the scope of the current decl.
const interned_string & peek_qualified_name() const
Getter for the qualified name.
const context_rel * get_context_rel() const
Getter for the context relationship.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl *scpe)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
virtual const interned_string & get_scoped_name() const
Return the scoped name of the decl.
const decl_base_sptr get_definition_of_declaration() const
If this decl_base is declaration-only, get its definition, if any.
friend void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
void set_naming_typedef(const typedef_decl_sptr &)
Set the naming typedef of the current instance of decl_base.
void set_location(const location &l)
Set the location for a given declaration.
void set_is_anonymous(bool)
Set the "is_anonymous" flag of the current declaration.
void set_visibility(visibility v)
Setter for the visibility of the decl.
void set_temporary_qualified_name(const interned_string &) const
Setter for the temporary qualified name of the current declaration.
friend bool equals(const decl_base &, const decl_base &, change_kind *)
Compares two instances of decl_base.
visibility get_visibility() const
Getter for the visibility of the decl.
visibility
ELF visibility.
bool get_is_declaration_only() const
Test if a decl_base is a declaration-only decl.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
void set_earlier_declaration(const decl_base_sptr &)
set the earlier declaration of this decl_base definition.
const interned_string & get_linkage_name() const
Getter for the mangled name.
friend enum access_specifier get_member_access_specifier(const decl_base &d)
Gets the access specifier for a class member.
friend bool get_member_function_is_virtual(const function_decl &f)
Test if a given member function is virtual.
virtual ~decl_base()
Destructor of the decl_base type.
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
const interned_string & get_qualified_parent_name() const
Return a copy of the qualified name of the parent of the current decl.
bool get_is_anonymous_or_has_anonymous_parent() const
bool get_has_anonymous_parent() const
Get the "has_anonymous_parent" flag of the current declaration.
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
const interned_string & peek_temporary_qualified_name() const
Getter of the temporary qualified name of the current declaration.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representatin of the current declaration.
The abstraction for a data member context relationship. This relates a data member to its parent clas...
const var_decl * get_anonymous_data_member() const
Return a non-nil value if this data member context relationship has an anonymous data member....
void set_anonymous_data_member(var_decl *)
Set the containing anonymous data member of this data member context relationship....
The abstraction of the version of an ELF symbol.
version & operator=(const version &o)
Assign a version to the current one.
bool operator==(const version &o) const
Compares the current version against another one.
bool is_default() const
Getter for the 'is_default' property of the version.
const string & str() const
Getter for the version name.
bool operator!=(const version &o) const
Inequality operator.
Abstraction of an elf symbol.
const abg_compat::optional< std::string > & get_namespace() const
Getter of the 'namespace' property.
elf_symbol_sptr get_alias_which_equals(const elf_symbol &other) const
In the list of aliases of a given elf symbol, get the alias that equals this current symbol.
elf_symbol_sptr get_next_common_instance() const
Get the next common instance of the current common symbol.
type get_type() const
Getter for the type of the current instance of elf_symbol.
const elf_symbol_sptr get_main_symbol() const
Get the main symbol of an alias chain.
void set_is_in_ksymtab(bool is_in_ksymtab)
Setter of the 'is-in-ksymtab' property.
bool has_aliases() const
Check if the current elf_symbol has an alias.
void set_name(const string &n)
Setter for the name of the current intance of elf_symbol.
bool is_suppressed() const
Getter for the 'is-suppressed' property.
binding
The binding of a symbol.
int get_number_of_aliases() const
Get the number of aliases to this elf symbol.
string get_aliases_id_string(const string_elf_symbols_map_type &symtab, bool include_symbol_itself=true) const
Return a comma separated list of the id of the current symbol as well as the id string of its aliases...
void set_binding(binding b)
Setter for the binding of the current instance of elf_symbol.
void add_common_instance(const elf_symbol_sptr &)
Add a common instance to the current common elf symbol.
void add_alias(const elf_symbol_sptr &)
Add an alias to the current elf symbol.
void set_is_suppressed(bool is_suppressed)
Setter for the 'is-suppressed' property.
bool is_variable() const
Test if the current instance of elf_symbol is a variable symbol or not.
elf_symbol_sptr update_main_symbol(const std::string &)
Update the main symbol for a group of aliased symbols.
void set_size(size_t)
Setter of the size of the symbol.
const string & get_name() const
Getter for the name of the elf_symbol.
binding get_binding() const
Getter for the binding of the current instance of elf_symbol.
static bool get_name_and_version_from_id(const string &id, string &name, string &ver)
Given the ID of a symbol, get the name and the version of said symbol.
bool is_function() const
Test if the current instance of elf_symbol is a function symbol or not.
type
The type of a symbol.
void set_version(const version &v)
Setter for the version of the current instance of elf_symbol.
const abg_compat::optional< uint32_t > & get_crc() const
Getter of the 'crc' property.
void set_visibility(visibility v)
Setter of the visibility of the current instance of elf_symbol.
bool does_alias(const elf_symbol &) const
Test if the current symbol aliases another one.
bool is_main_symbol() const
Tests whether this symbol is the main symbol.
void set_crc(const abg_compat::optional< uint32_t > &crc)
Setter of the 'crc' property.
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.
version & get_version() const
Getter for the version of the current instanc of elf_symbol.
bool is_common_symbol() const
Return true if the symbol is a common one.
void set_index(size_t)
Setter for the index.
visibility get_visibility() const
Getter of the visibility of the current instance of elf_symbol.
bool has_other_common_instances() const
Return true if this common common symbol has other common instances.
size_t get_index() const
Getter for the index.
const string & get_id_string() const
Get a string that is representative of a given elf_symbol.
elf_symbol_sptr get_alias_from_name(const string &name) const
From the aliases of the current symbol, lookup one with a given name.
const environment & get_environment() const
Getter of the environment used by the current instance of elf_symbol.
void set_type(type t)
Setter for the type of the current instance of elf_symbol.
bool is_public() const
Test if the current instance of elf_symbol is public or not.
bool is_in_ksymtab() const
Getter of the 'is-in-ksymtab' property.
size_t get_size() const
Getter of the size of the symbol.
bool is_defined() const
Test if the current instance of elf_symbol is defined or not.
void set_namespace(const abg_compat::optional< std::string > &ns)
Setter of the 'namespace' property.
elf_symbol_sptr get_next_alias() const
Get the next alias of the current symbol.
bool operator==(const elf_symbol &) const
Test if two main symbols are textually equal, or, if they have aliases that are textually equal.
The abstraction of an enumerator.
enumerator()
Default constructor of the enumerator type.
bool operator!=(const enumerator &other) const
Inequality operator.
void set_name(const string &n)
Setter for the name of enumerator.
enum_type_decl * get_enum_type() const
Getter for the enum type that this enumerator is for.
const string & get_name() const
Getter for the name of the current instance of enum_type_decl::enumerator.
void set_enum_type(enum_type_decl *)
Setter for the enum type that this enumerator is for.
void set_value(int64_t v)
Setter for the value of enumerator.
const string & get_qualified_name(bool internal=false) const
Getter for the qualified name of the current instance of enum_type_decl::enumerator....
int64_t get_value() const
Getter for the value of enumerator.
bool operator==(const enumerator &other) const
Equality operator.
enumerator & operator=(const enumerator &)
Assignment operator of the enumerator type.
Abstracts a declaration for an enum type.
std::vector< enumerator > enumerators
Convenience typedef for a list of enumerator.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual ~enum_type_decl()
Destructor for the enum type declaration.
const enumerators & get_enumerators() const
bool find_enumerator_by_value(int64_t value, enum_type_decl::enumerator &result)
Find an enumerator by its value.
const enumerators & get_sorted_enumerators() const
Get the lexicographically sorted vector of enumerators.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
type_base_sptr get_underlying_type() const
Return the underlying type of the enum.
bool find_enumerator_by_name(const string &name, enum_type_decl::enumerator &result)
Find an enumerator by its name.
virtual bool operator==(const decl_base &) const
Equality operator.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of enum_type_decl.
This is an abstraction of the set of resources necessary to manage several aspects of the internal re...
bool decl_only_class_equals_definition() const
Getter of the "decl-only-class-equals-definition" flag.
bool is_void_pointer_type(const type_base_sptr &) const
Test if a given type is the same as the void pointer type of the environment.
std::unordered_map< string, std::vector< type_base_sptr > > canonical_types_map_type
A convenience typedef for a map of canonical types. The key is the pretty representation string of a ...
bool user_set_analyze_exported_interfaces_only() const
Getter for a property that says if the user actually did set the analyze_exported_interfaces_only() p...
const vector< type_base_sptr > * get_canonical_types(const char *name) const
Get the vector of canonical types which have a given "stringrepresentation".
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
bool is_variadic_parameter_type(const type_base *) const
Test if a type is a variadic parameter type as defined in the current environment.
static string & get_variadic_parameter_type_name()
Getter of the name of the variadic parameter type.
const type_base_sptr & get_void_pointer_type() const
Getter of the "pointer-to-void" IR node that is shared across the ABI corpus. This node must be the o...
const config & get_config() const
Getter of the general configuration object.
environment()
Default constructor of the environment type.
bool canonicalization_is_done() const
Test if the canonicalization of types created out of the current environment is done.
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "stringrepresentation".
const type_base_sptr & get_variadic_parameter_type() const
Get a type_decl instance that represents a the type of a variadic function parameter....
bool is_void_type(const type_base_sptr &) const
Test if a given type is a void type as defined in the current environment.
virtual ~environment()
Destructor for the environment type.
bool canonicalization_started() const
Getter of a flag saying if the canonicalization process has started or not.
interned_string intern(const string &) const
Do intern a string.
bool analyze_exported_interfaces_only() const
Getter for the property that controls if we are to restrict the analysis to the types that are only r...
canonical_types_map_type & get_canonical_types_map()
Getter the map of canonical types.
Abstraction of a function parameter.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Compute the qualified name of the parameter.
interned_string get_type_name() const
interned_string get_name_id() const
Get a name uniquely identifying the parameter in the function.
const string get_type_pretty_representation() const
virtual bool traverse(ir_node_visitor &v)
Traverse the diff sub-tree under the current instance function_decl.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Compute and return a copy of the pretty representation of the current function parameter.
Abstraction for a function declaration.
shared_ptr< parameter > parameter_sptr
Convenience typedef for a shared pointer on a parameter.
string get_pretty_representation_of_declarator(bool internal=false) const
Compute and return the pretty representation for the part of the function declaration that starts at ...
const function_type * get_naked_type() const
Fast getter of the type of the current instance of function_decl.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
void append_parameters(std::vector< parameter_sptr > &parms)
Append a vector of parameters to the type of this function.
bool is_variadic() const
Return true iff the function takes a variable number of parameters.
parameters::const_iterator get_first_non_implicit_parm() const
Getter for the first non-implicit parameter of a function decl.
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
function_decl(const string &name, function_type_sptr function_type, bool declared_inline, const location &locus, const string &mangled_name, visibility vis, binding bind)
Constructor of the function_decl.
const type_base_sptr get_return_type() const
function_decl_sptr clone() const
Create a new instance of function_decl that is a clone of the current one.
const std::vector< parameter_sptr > & get_parameters() const
void append_parameter(parameter_sptr parm)
Append a parameter to the type of this function.
void set_symbol(const elf_symbol_sptr &sym)
This sets the underlying ELF symbol for the current function decl.
virtual ~function_decl()
Destructor of the function_decl type.
const elf_symbol_sptr & get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using function_decl::set_sy...
virtual bool operator==(const decl_base &o) const
Comparison operator for function_decl.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
bool is_declared_inline() const
Test if the function was declared inline.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of function_decl.
interned_string get_id() const
Return an ID that tries to uniquely identify the function inside a program or a library.
Abstract a function template declaration.
binding get_binding() const
Get the binding of the function template.
void set_pattern(shared_ptr< function_decl > p)
Set a new pattern to the function template.
shared_ptr< function_decl > get_pattern() const
Get the pattern of the function template.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
virtual bool operator==(const decl_base &) const
Comparison operator for the function_tdecl type.
Abstraction of a function type.
shared_ptr< function_decl::parameter > parameter_sptr
Convenience typedef for a shared pointer on a parameter.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &)
Traverses an instance of function_type, visiting all the sub-types and decls that it might contain.
bool is_variadic() const
Test if the current instance of function_type is for a variadic function.
parameters::const_iterator get_first_parm() const
Get the first parameter of the function.
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
virtual bool operator==(const type_base &) const
Equality operator for function_type.
void append_parameter(parameter_sptr parm)
Append a new parameter to the vector of parameters of the current instance of function_type.
void set_parameters(const parameters &p)
Setter for the parameters of the current instance of function_type.
const interned_string & get_cached_name(bool internal=false) const
Get the name of the current function_type.
const parameter_sptr get_parm_at_index_from_first_non_implicit_parm(size_t) const
Get the Ith parameter of the vector of parameters of the current instance of function_type.
type_base_sptr get_return_type() const
Getter for the return type of the current instance of function_type.
void set_return_type(type_base_sptr t)
Setter of the return type of the current instance of function_type.
parameters::const_iterator get_first_non_implicit_parm() const
Get the first parameter of the function.
const parameters & get_parameters() const
Getter for the set of parameters of the current intance of function_type.
std::vector< parameter_sptr > parameters
Convenience typedef for a vector of parameter_sptr.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Return a copy of the pretty representation of the current function_type.
This abstracts the global scope of a given translation unit.
The base class for the visitor type hierarchy used for traversing a translation unit.
bool allow_visiting_already_visited_type_node() const
Get if the walker using this visitor is allowed to re-visit a type node that was previously visited o...
bool type_node_has_been_visited(type_base *) const
Test if a given type node has been marked as visited.
void forget_visited_type_nodes()
Un-mark all visited type nodes.
ir_node_visitor()
Default Constructor of the ir_node_visitor type.
void mark_type_node_as_visited(type_base *)
Mark a given type node as having been visited.
The entry point to manage locations.
location create_new_location(const std::string &fle, size_t lne, size_t col)
Insert the triplet representing a source locus into our internal vector of location triplet....
void expand_location(const location &location, std::string &path, unsigned &line, unsigned &column) const
Given an instance of location type, return the triplet {path,line,column} that represents the source ...
The source location of a token.
bool get_is_artificial() const
Test if the location is artificial.
unsigned get_value() const
Get the value of the location.
string expand(void) const
Expand the location into a string.
void expand(std::string &path, unsigned &line, unsigned &column) const
Expand the current location into a tripplet file path, line and column number.
Abstraction of a member function context relationship. This relates a member function to its parent c...
bool is_constructor() const
Getter for the 'is-constructor' property.
bool is_const() const
Getter for the 'is-const' property.
size_t vtable_offset() const
Getter for the vtable offset property.
bool is_destructor() const
Getter for the 'is-destructor' property.
The base class for member types, data members and member functions. Its purpose is mainly to carry th...
access_specifier get_access_specifier() const
Getter for the access specifier of this member.
bool get_is_static() const
Abstracts a member class template template.
virtual bool operator==(const member_base &o) const
Equality operator of the the member_class_template class.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
Abstract a member function template.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
Abstraction of the declaration of a method.
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
const method_type_sptr get_type() const
Abstracts the type of a class member function.
void set_class_type(const class_or_union_sptr &t)
Sets the class type of the current instance of method_type.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
void set_is_const(bool)
Setter of the "is-const" property of method_type.
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
virtual ~method_type()
The destructor of method_type.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Return a copy of the pretty representation of the current method_type.
class_or_union_sptr get_class_type() const
Get the class type this method belongs to.
bool get_is_const() const
Getter of the "is-const" property of method_type.
The abstraction of a namespace declaration.
bool is_empty_or_has_empty_sub_namespaces() const
Test if the current namespace_decl is empty or contains empty namespaces itself.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
namespace_decl(const environment &env, const string &name, const location &locus, visibility vis=VISIBILITY_DEFAULT)
Constructor.
virtual bool operator==(const decl_base &) const
Return true iff both namespaces and their members are equal.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return a copy of the pretty representation of the namespace.
Abstracts non type template parameters.
const type_base_sptr get_type() const
Getter for the type of the template parameter.
virtual bool operator==(const decl_base &) const
Return true iff the two decls have the same name.
The abstraction of a pointer type.
void set_pointed_to_type(const type_base_sptr &)
Set the pointed-to type of the pointer.
virtual void get_qualified_name(interned_string &, bool internal=false) const
Build and return the qualified name of the current instance of pointer_type_def.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
virtual bool operator==(const decl_base &) const
Return true iff both instances of pointer_type_def are equal.
const type_base_sptr get_pointed_to_type() const
Getter of the pointed-to type.
type_base * get_naked_pointed_to_type() const
Getter of a naked pointer to the pointed-to type.
The abstraction of a pointer-to-member type.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Get the qualified name for the current ptr_to_mbr_type.
virtual const interned_string & get_name() const
Getter of the name of the current ptr-to-mbr-type.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
const type_base_sptr & get_containing_type() const
Getter of the type containing the member pointed-to by the current ptr_to_mbr_type.
bool operator==(const ptr_to_mbr_type &) const
Equality operator for the current ptr_to_mbr_type.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function for ptr_to_mbr_type.
const type_base_sptr & get_member_type() const
Getter of the member type of the current ptr_to_mbr_type.
virtual ~ptr_to_mbr_type()
Desctructor for ptr_to_mbr_type.
The abstraction of a qualified type.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for qualified_type_def.
void set_underlying_type(const type_base_sptr &)
Setter of the underlying type.
virtual size_t get_size_in_bits() const
Get the size of the qualified type def.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
string get_cv_quals_string_prefix() const
Compute and return the string prefix or suffix representing the qualifiers hold by the current instan...
CV
Bit field values representing the cv qualifiers of the underlying type.
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
void set_cv_quals(CV cv_quals)
Setter of the const/value qualifiers bit field.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
CV get_cv_quals() const
Getter of the const/volatile qualifier bit field.
type_base_sptr get_underlying_type() const
Getter of the underlying type.
virtual bool operator==(const decl_base &) const
Equality operator for qualified types.
string build_name(bool, bool internal=false) const
Build the name of the current instance of qualified type.
The internal representation of an integral type.
void set_modifiers(modifiers_type)
Setter of the modifiers bitmap of the real_type.
string to_string(bool internal=false) const
Return the string representation of the current instance of real_type.
base_type get_base_type() const
Getter of the base type of the real_type.
bool operator==(const real_type &) const
Equality operator for the real_type.
real_type()
Default constructor of the real_type.
modifiers_type
The modifiers of the base types above. Several modifiers can be combined for a given base type....
@ LONG_LONG_MODIFIER
The "long long" modifier.
@ LONG_MODIFIER
The "long" modifier.
@ SIGNED_MODIFIER
The "signed" modifier.
@ UNSIGNED_MODIFIER
The "unsigned" modier.
@ SHORT_MODIFIER
The "short" modifier.
base_type
The possible base types of integral types. We might have forgotten many of these, so do not hesitate ...
@ WCHAR_T_BASE_TYPE
The "wchar_t" base type.
@ CHAR32_T_BASE_TYPE
The "char32_t" base type.
@ FLOAT_BASE_TYPE
The "float" base type.
@ BOOL_BASE_TYPE
The "bool" base type in C++ or "_Bool" in C11.
@ CHAR_BASE_TYPE
The "char" base type.
@ CHAR16_T_BASE_TYPE
The "char16_t base type.
@ INT_BASE_TYPE
The "int" base type.
@ ARRAY_SIZE_BASE_TYPE
The aray size type used by Clang.
@ DOUBLE_BASE_TYPE
The "double" base type.
modifiers_type get_modifiers() const
Getter of the modifiers bitmap of the real_type.
Abstracts a reference type.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Build and return the qualified name of the current instance of the reference_type_def.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual void on_canonical_type_set()
This function is automatically invoked whenever an instance of this type is canonicalized.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
void set_pointed_to_type(type_base_sptr &pointed_to_type)
Setter of the pointed_to type of the current reference type.
virtual bool operator==(const decl_base &) const
Equality operator of the reference_type_def type.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of reference_type_def.
A declaration that introduces a scope.
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
void remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
void insert_member_type(type_base_sptr t, declarations::iterator before)
Insert a member type.
void add_member_type(type_base_sptr t)
Add a member type to the current instance of class_or_union.
virtual size_t get_num_anonymous_member_unions() const
Getter for the number of anonymous unions contained in this scope.
scopes & get_member_scopes()
Getter for the scopes carried by the current scope.
std::vector< scope_decl_sptr > scopes
Convenience typedef for a vector of scope_decl_sptr.
bool is_empty() const
Test if the current scope is empty.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
const type_base_sptrs_type & get_member_types() const
Get the member types of this scope_decl.
decl_base_sptr insert_member_decl(decl_base_sptr member, declarations::iterator before)
Insert a member decl to this scope, right before an element pointed to by a given iterator....
std::vector< decl_base_sptr > declarations
Convenience typedef for a vector of decl_base_sptr.
const type_base_sptrs_type & get_sorted_canonical_types() const
Return a vector of sorted canonical types of the current scope.
bool find_iterator_for_member(const decl_base *, declarations::iterator &)
Find a member of the current scope and return an iterator on it.
virtual void remove_member_decl(decl_base_sptr member)
Remove a declaration from the current scope.
virtual decl_base_sptr add_member_decl(const decl_base_sptr &member)
Add a member decl to this scope. Note that user code should not use this, but rather use add_decl_to_...
type_base_sptr find_member_type(const string &name) const
Find a member type of a given name, inside the current scope_decl.
const declarations & get_member_decls() const
Getter for the member declarations carried by the current scope_decl.
const canonical_type_sptr_set_type & get_canonical_types() const
@eturn the set of canonical types of the the current scope.
const type_base_sptrs_type & get_sorted_member_types() const
Get the sorted member types of this scope_decl.
friend 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...
virtual bool operator==(const decl_base &) const
Return true iff both scopes have the same names and have the same member decls.
const declarations & get_sorted_member_decls() const
Getter for the sorted member declarations carried by the current scope_decl.
virtual size_t get_num_anonymous_member_enums() const
Getter for the number of anonymous enums contained in this scope.
A type that introduces a scope.
virtual bool traverse(ir_node_visitor &)
Traverses an instance of scope_type_decl, visiting all the sub-types and decls that it might contain.
virtual bool operator==(const decl_base &) const
Equality operator between two scope_type_decl.
The base class of templates.
const std::list< template_parameter_sptr > & get_template_parameters() const
Get the list of template parameters of the current instance of template_decl.
virtual ~template_decl()
Destructor.
void add_template_parameter(const template_parameter_sptr p)
Add a new template parameter to the current instance of template_decl.
virtual bool operator==(const decl_base &o) const
Equality operator.
Base class for a template parameter. Client code should use the more specialized type_template_parame...
virtual ~template_parameter()
Destructor.
bool operator!=(const template_parameter &) const
Inequality operator.
virtual bool operator==(const type_base &) const
Equality operator.
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
void set_address_size(char)
Setter of the address size in this translation unit.
const std::string & get_absolute_path() const
Get the concatenation of the build directory and the relative path of the translation unit.
void set_is_constructed(bool)
Setter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
bool operator==(const translation_unit &) const
Compare the current translation unit against another one.
const corpus * get_corpus() const
Get the corpus this translation unit is a member of.
char get_address_size() const
Getter of the address size in this translation unit.
const std::string & get_compilation_dir_path() const
Get the path of the directory that was 'current' when the translation unit was compiled.
void set_corpus(corpus *)
Set the corpus this translation unit is a member of.
void set_language(language l)
Setter of the language of the source code of the translation unit.
void bind_function_type_life_time(function_type_sptr) const
Ensure that the life time of a function type is bound to the life time of the current translation uni...
const scope_decl_sptr & get_global_scope() const
Getter of the the global scope of the translation unit.
bool is_empty() const
Tests whether if the current translation unit contains ABI artifacts or not.
bool is_constructed() const
Getter of the 'is_constructed" flag. It says if the translation unit is fully constructed or not.
const std::string & get_path() const
Get the path of the current translation unit.
void set_compilation_dir_path(const std::string &)
Set the path of the directory that was 'current' when the translation unit was compiled.
location_manager & get_loc_mgr()
Getter of the location manager for the current translation unit.
void set_path(const string &)
Set the path associated to the current instance of translation_unit.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse virtual function.
language
The language of the translation unit.
bool operator!=(const translation_unit &) const
Inequality operator.
const vector< function_type_sptr > & get_live_fn_types() const
Get the vector of function types that are used in the current translation unit.
const environment & get_environment() const
Getter of the environment of the current translation_unit.
const type_maps & get_types() const
Getter of the types of the current translation_unit.
language get_language() const
Getter of the language of the source code of the translation unit.
bool visiting() const
This should returns false before and after the node has been visiting. During the visiting of the nod...
An abstraction helper for type declarations.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current type.
type_base * get_naked_canonical_type() const
Getter of the canonical type pointer.
virtual size_t get_size_in_bits() const
Getter for the size of the type.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &)
Default implementation of traversal for types. This function does nothing. It must be implemented by ...
virtual void on_canonical_type_set()
This method is invoked automatically right after the current instance of class_decl has been canonica...
virtual void set_size_in_bits(size_t)
Setter for the size of the type.
virtual bool operator!=(const type_base &) const
Inequality operator.
virtual bool operator==(const type_base &) const
Return true iff both type declarations are equal.
virtual size_t get_alignment_in_bits() const
Getter for the alignment of the type.
virtual void set_alignment_in_bits(size_t)
Setter for the alignment of the type.
type_base_sptr get_canonical_type() const
Getter of the canonical type of the current instance of type_base.
This abstracts a composition of types based on template type parameters. The result of the compositio...
const type_base_sptr get_composed_type() const
Getter for the resulting composed type.
void set_composed_type(type_base_sptr t)
Setter for the resulting composed type.
A basic type declaration that introduces no scope.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation for the virtual qualified name builder for type_decl.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
virtual bool operator!=(const type_base &) const
Return true if both types equals.
virtual bool operator==(const type_base &) const
Return true if both types equals.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Get the pretty representation of the current instance of type_decl.
This is a type that aggregates maps of all the kinds of types that are supported by libabigail.
istring_type_base_wptrs_map_type & typedef_types()
Getter for the map that associates the name of a typedef to the vector of instances of typedef_decl_s...
istring_type_base_wptrs_map_type & function_types()
Getter for the map that associates the name of a function type to the vector of instances of function...
istring_type_base_wptrs_map_type & reference_types()
Getter for the map that associates the name of a reference type to the vector of instances of referen...
const istring_type_base_wptrs_map_type & class_types() const
Getter for the map that associates the name of a class type to the vector of instances of class_decl_...
istring_type_base_wptrs_map_type & union_types()
Getter for the map that associates the name of a union type to the vector of instances of union_decl_...
istring_type_base_wptrs_map_type & array_types()
Getter for the map that associates the name of an array type to the vector of instances of array_type...
istring_type_base_wptrs_map_type & enum_types()
Getter for the map that associates the name of an enum type to the vector of instances of enum_type_d...
bool empty() const
Test if the type_maps is empty.
istring_type_base_wptrs_map_type & qualified_types()
Getter for the map that associates the name of a qualified type to the vector of instances of qualifi...
istring_type_base_wptrs_map_type & ptr_to_mbr_types()
Getter for the map that associates the name of a pointer-to-member type to the vector of instances of...
const vector< type_base_wptr > & get_types_sorted_by_name() const
Getter of all types types sorted by their pretty representation.
istring_type_base_wptrs_map_type & pointer_types()
Getter for the map that associates the name of a pointer type to the vector of instances of pointer_t...
const istring_type_base_wptrs_map_type & basic_types() const
Getter for the map that associates the name of a basic type to the vector instances of type_decl_sptr...
const istring_type_base_wptrs_map_type & subrange_types() const
Getter for the map that associates the name of a subrange type to the vector of instances of subrange...
The base class of both types and declarations.
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
friend hash_t peek_hash_value(const type_or_decl_base &)
Get the hash value associated to an IR node.
bool get_is_artificial() const
Getter of the flag that says if the artefact is artificial.
virtual ~type_or_decl_base()
The destructor of the type_or_decl_base type.
location & get_artificial_location() const
Getter of the artificial location of the artifact.
bool has_artificial_location() const
Test if the current ABI artifact carries an artificial location.
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
enum type_or_decl_kind kind() const
Getter for the "kind" property of type_or_decl_base type.
void set_is_artificial(bool)
Setter of the flag that says if the artefact is artificial.
virtual bool traverse(ir_node_visitor &)
Traverse the the ABI artifact.
const void * runtime_type_instance() const
Getter of the pointer to the runtime type sub-object of the current instance.
const void * type_or_decl_base_pointer() const
Getter of the pointer to either the type_base sub-object of the current instance if it's a type,...
friend decl_base * is_decl(const type_or_decl_base *d)
Test if an ABI artifact is a declaration.
void set_artificial_location(const location &)
Setter of the artificial location of the artificat.
type_or_decl_kind
This is a bitmap type which instance is meant to contain the runtime type of a given ABI artifact....
const environment & get_environment() const
Getter of the environment of the current ABI artifact.
friend type_base * is_type(const type_or_decl_base *)
Test whether a declaration is a type.
const translation_unit * get_translation_unit() const
Get the translation_unit this ABI artifact belongs to.
Abstracts a type template parameter.
virtual bool operator==(const type_base &) const
Equality operator.
The abstraction of a typedef declaration.
virtual void get_qualified_name(interned_string &qualified_name, bool internal=false) const
Implementation of the virtual "get_qualified_name" method.
void set_underlying_type(const type_base_sptr &)
Setter ofthe underlying type of the typedef.
virtual size_t get_size_in_bits() const
Return the size of the typedef.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &)
This implements the ir_traversable_base::traverse pure virtual function.
type_base_sptr get_underlying_type() const
Getter of the underlying type of the typedef.
virtual bool operator==(const decl_base &) const
Equality operator.
virtual size_t get_alignment_in_bits() const
Return the alignment of the typedef.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build a pretty representation for a typedef_decl.
Abstracts a union type declaration.
virtual hash_t hash_value() const
Return the hash value of the current IR node.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
virtual bool operator==(const decl_base &) const
Comparison operator for union_decl.
virtual ~union_decl()
Destructor of the union_decl type.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Getter of the pretty representation of the current instance of union_decl.
Abstracts a variable declaration.
binding get_binding() const
Getter of the binding of the variable.
void set_type(type_base_sptr &)
Setter of the type of the variable.
void set_binding(binding b)
Setter of the binding of the variable.
friend uint64_t get_data_member_offset(const var_decl_sptr m)
Get the offset of a data member.
var_decl_sptr clone() const
Create a new var_decl that is a clone of the current one.
virtual const interned_string & get_qualified_name(bool internal=false) const
Get the qualified name of a given variable or data member.
const type_base * get_naked_type() const
Getter of the type of the variable.
friend bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
const type_base_sptr get_type() const
Getter of the type of the variable.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
string get_anon_dm_reliable_name(bool qualified=true) const
Get a name that is valid even for an anonymous data member.
void set_symbol(const elf_symbol_sptr &sym)
Sets the underlying ELF symbol for the current variable.
const elf_symbol_sptr & get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using var_decl::set_symbol(...
virtual bool operator==(const decl_base &) const
Comparison operator of var_decl.
virtual string get_pretty_representation(bool internal=false, bool qualified_name=true) const
Build and return the pretty representation of this variable.
interned_string get_id() const
Return an ID that tries to uniquely identify the variable inside a program or a library.
bool is_decl_only_class_with_size_change(const class_or_union &first, const class_or_union &second)
Test if two classes that are decl-only (have the decl-only flag and carry no data members) but are di...
string get_pretty_representation(diff *d)
Get a copy of the pretty representation of a diff node.
ostream & operator<<(ostream &o, diff_category c)
Serialize an instance of diff_category to an output stream.
hash_t combine_hashes(hash_t val1, hash_t val2)
Combine two hash values to produce a third hash value.
@ HASHING_FINISHED_STATE
Hashing of given IR node started and is now done. If an ABI artifact is in this state,...
real_type::modifiers_type operator~(real_type::modifiers_type l)
Bitwise one's complement operator for real_type::modifiers_type.
shared_ptr< reference_type_def > reference_type_def_sptr
Convenience typedef for a shared pointer on a reference_type_def.
const type_base_sptr lookup_type_in_scope(const string &fqn, const scope_decl_sptr &skope)
Lookup a type in a scope.
bool is_non_canonicalized_type(const type_base *t)
Test if a given type is allowed to be non canonicalized.
bool get_member_function_is_dtor(const function_decl &f)
Test whether a member function is a destructor.
const type_base * peel_qualified_type(const type_base *type)
Return the leaf underlying type of a qualified type.
hash_t peek_hash_value(const type_or_decl_base &artefact)
Get the hash value associated to an IR node.
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.
size_t hash_type(const type_base *t)
Hash an ABI artifact that is a type.
void fqn_to_components(const string &fqn, list< string > &comps)
Decompose a fully qualified name into the list of its components.
var_decl_sptr get_last_data_member(const class_or_union &klass)
Get the last data member of a class type.
bool is_anonymous_or_typedef_named(const decl_base &d)
Test if a given decl is anonymous or has a naming typedef.
bool is_template_parm_composition_type(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter composition type.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
pointer_type_def_sptr is_pointer_to_npaf_type(const type_base_sptr &t)
Test if we are looking at a pointer to a neither-a-pointer-to-an-array-nor-a-function type.
bool debug_equals(const type_or_decl_base *l, const type_or_decl_base *r)
Test if two ABI artifacts are equal.
shared_ptr< function_decl > function_decl_sptr
Convenience typedef for a shared pointer on a function_decl.
access_specifier
Access specifier for class members.
size_t get_canonical_type_index(const type_base &t)
Getter of the canonical type index of a given type.
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.
bool function_decls_alias(const function_decl &f1, const function_decl &f2)
Test if two function declarations are aliases.
pointer_type_def_sptr is_pointer_to_array_type(const type_base_sptr &t)
Test if a type is a pointer to array type.
bool type_is_suitable_for_hash_computing(const type_base &)
Test if we should attempt to compute a hash value for a given type.
shared_ptr< class_tdecl > class_tdecl_sptr
Convenience typedef for a shared pointer on a class_tdecl.
bool maybe_update_types_lookup_map< function_type >(const function_type_sptr &type, istring_type_base_wptrs_map_type &types_map, bool)
This is the specialization for type function_type of the function template:
weak_ptr< function_type > function_type_wptr
Convenience typedef for a weak pointer on a function_type.
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.
ssize_t get_member_function_vtable_offset(const function_decl &f)
Get the vtable offset of a member function.
corpus::origin operator|=(corpus::origin &l, corpus::origin r)
Bitwise |= operator for the corpus::origin type.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
scope_decl * get_type_scope(type_base *t)
Get the scope of a given type.
void fixup_virtual_member_function(method_decl_sptr method)
When a virtual member function has seen its virtualness set by set_member_function_is_virtual(),...
void pop_composite_type_comparison_operands(const type_base &left, const type_base &right)
Pop a pair of operands from the stack of operands to the current type comparison.
bool equals_modulo_cv_qualifier(const array_type_def *l, const array_type_def *r)
Test if two array types are equals modulo CV qualifiers.
const scope_decl * is_scope_decl(const decl_base *d)
Test if a declaration is a scope_decl.
qualified_type_def_sptr clone_qualified_type(const qualified_type_def_sptr &t)
Clone a qualifiend type.
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 is_anonymous_data_member(const decl_base &d)
Test if a decl is an anonymous data member.
bool is_template_parameter(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter.
string translation_unit_language_to_string(translation_unit::language l)
Converts a translation_unit::language enumerator into a string.
weak_ptr< type_base > type_base_wptr
Convenience typedef for a weak pointer on a type_base.
type_base_sptr peel_reference_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a reference_type_def node.
class_decl::base_spec * is_class_base_spec(const type_or_decl_base *tod)
Test if an ABI artifact is a class base specifier.
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.
T * maybe_get_canonical_type(T *t)
Get the canonical type of a given type T* as a T*.
shared_ptr< elf_symbol > elf_symbol_sptr
A convenience typedef for a shared pointer to elf_symbol.
type_base_sptr lookup_type_from_translation_unit(const string &type_name, const string &tu_path, const corpus &corp)
Lookup a type from a given translation unit present in a give corpus.
type_base * get_exemplar_type(const type_base *type)
For a given type, return its exemplar type.
bool type_originates_from_corpus(type_base_sptr t, corpus_sptr &c)
Test if a type originates from a corpus.
bool parse_real_type(const string &type_name, real_type &type)
Parse a real type from a string.
void remove_decl_from_scope(decl_base_sptr decl)
Remove a given decl from its scope.
bool odr_is_relevant(const type_or_decl_base &artifact)
By looking at the language of the TU a given ABI artifact belongs to, test if the ONE Definition Rule...
array_type_def_sptr clone_array(const array_type_def_sptr &array)
Clone an array type.
change_kind
A bitfield that gives callers of abigail::ir::equals() some insight about how different two internal ...
@ LOCAL_TYPE_CHANGE_KIND
This means that a given IR artifact has a local type change.
@ SUBTYPE_CHANGE_KIND
This means that a given IR artifact has changes in some of its sub-types, with respect to the other a...
@ LOCAL_NON_TYPE_CHANGE_KIND
This means that a given IR artifact has a local non-type change. That is a change that is carried by ...
var_decl_sptr find_last_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr ®ex)
Find the last data member of a class or union which name matches a regular expression.
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.
const var_decl_sptr get_first_non_anonymous_data_member(const var_decl_sptr anon_dm)
Get the first non-anonymous data member of a given anonymous data member.
class_decl_sptr lookup_class_type_through_scopes(const list< string > &fqn, const translation_unit &tu)
Lookup a class type from a translation unit by walking its scopes in sequence and by looking into the...
string get_enum_flat_representation(const enum_type_decl &enum_type, const string &indent, bool one_line, bool qualified_names)
Get the flat representation of an instance of enum_type_decl type.
bool is_user_defined_type(const type_base *t)
Test if a type is user-defined.
bool operator==(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep comparison operator for pointers to translation units.
weak_ptr< class_decl > class_decl_wptr
Convenience typedef for a weak pointer on a class_decl.
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.
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
void debug_comp_stack(const environment &env)
Emit a trace of the two comparison operands stack on the standard error stream.
bool collect_non_anonymous_data_members(const class_or_union *cou, string_decl_base_sptr_map &dms)
Collect all the non-anonymous data members of a class or union type.
bool is_class_type(const type_or_decl_base &t)
Test whether a type is a class.
type_base_sptr synthesize_type_from_translation_unit(const type_base_sptr &type, translation_unit &tu)
In a translation unit, lookup a given type or synthesize it if it's a qualified type.
void set_member_function_virtuality(function_decl &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
shared_ptr< array_type_def > array_type_def_sptr
Convenience typedef for a shared pointer on a array_type_def.
function_type_sptr lookup_or_synthesize_fn_type(const function_type_sptr &fn_t, const corpus &corpus)
Look into an ABI corpus for a function type.
bool is_declaration_only_class_or_union_type(const type_base *t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
string get_pretty_representation(const type_or_decl_base *tod, bool internal)
Build and return a copy of the pretty representation of an ABI artifact that could be either a type o...
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.
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
const class_or_union_sptr data_member_has_anonymous_type(const var_decl &d)
Test if a data member has annonymous type or not.
type_decl * is_integral_type(const type_or_decl_base *t)
Test if a type is an integral type.
bool anonymous_data_member_exists_in_class(const var_decl &anon_dm, const class_or_union &clazz)
Test if a given anonymous data member exists in a class or union.
class_decl_sptr lookup_class_type_per_location(const interned_string &loc, const corpus &corp)
Look up a class_decl from a given corpus by its location.
void set_member_function_is_dtor(function_decl &f, bool d)
Set the destructor-ness property of a member function.
const type_base_sptr peel_array_type(const type_base_sptr &type)
Return the leaf element type of an array.
reference_type_def_sptr lookup_reference_type(const interned_string &type_name, const translation_unit &tu)
Lookup a reference type from a translation unit.
bool types_have_similar_structure(const type_base_sptr &first, const type_base_sptr &second, bool indirect_type)
Test if two types have similar structures, even though they are (or can be) different.
corpus_group_sptr is_corpus_group(const corpus_sptr &corpus)
Test if a corpus is a corpus_group.
shared_ptr< template_parameter > template_parameter_sptr
Convenience typedef for shared pointer to template parameter.
class_or_union * is_class_or_union_type(const type_or_decl_base *t)
Test if a type is a class_or_union.
var_decl_sptr get_data_member(class_or_union *clazz, const char *member_name)
Get a given data member, referred to by its name, of a class type.
type_base * look_through_decl_only_type(type_base *t)
If a type is is decl-only, then get its definition. Otherwise, just return the initial type.
const var_decl_sptr get_next_data_member(const class_or_union *klass, const var_decl_sptr &data_member)
In the context of a given class or union, this function returns the data member that is located after...
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.
bool is_comparison_cycle_detected(T &l, T &r)
Detect if a recursive comparison cycle is detected while structurally comparing two types (a....
bool string_to_elf_symbol_type(const string &s, elf_symbol::type &t)
Convert a string representing a symbol type into an elf_symbol::type.
namespace_decl_sptr is_namespace(const decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
hash_t set_or_get_cached_hash_value(const T &tod)
Set the hash value of an IR node and return it.
const type_decl * is_type_decl(const type_or_decl_base *t)
Test whether a type is a type_decl (a builtin type).
decl_base * is_decl_slow(const type_or_decl_base *t)
Test if an ABI artifact is a declaration.
decl_base_sptr look_through_decl_only(const decl_base &d)
If a decl is decl-only get its definition. Otherwise, just return nil.
function_type_sptr is_function_type(const type_or_decl_base_sptr &t)
Test whether a type is a function_type.
string get_name(const type_or_decl_base *tod, bool qualified)
Build and return a copy of the name of an ABI artifact that is either a type or a decl.
void set_member_access_specifier(decl_base &d, access_specifier a)
Sets the access specifier for a class member.
const class_decl * is_compatible_with_class_type(const type_base *t)
Test if a type is a class. This function looks through typedefs.
typedef_decl_sptr is_typedef(const type_or_decl_base_sptr t)
Test whether a type is a typedef.
abg_compat::optional< uint64_t > hash_t
The abstraction for an 8 bytes hash value.
uint64_t get_var_size_in_bits(const var_decl_sptr &v)
Get the size of a given variable.
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.
string get_debug_representation(const type_or_decl_base *artifact)
Get the textual representation of a type for debugging purposes.
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.
function_type_sptr synthesize_function_type_from_translation_unit(const function_type &fn_type, translation_unit &tu)
In a translation unit, lookup the sub-types that make up a given function type and if the sub-types a...
std::ostream & operator<<(std::ostream &o, elf_symbol::type t)
Serialize an instance of symbol_type and stream it to a given output stream.
type_base_sptr peel_pointer_type(const type_base_sptr &type)
Return the leaf pointed-to type node of a pointer_type_def node.
bool var_equals_modulo_types(const var_decl &l, const var_decl &r, change_kind *k)
Compares two instances of var_decl without taking their type into account.
class_decl_sptr lookup_class_type(const string &fqn, const translation_unit &tu)
Lookup a class type from a translation unit.
type_base_sptr lookup_type_through_translation_units(const string &qn, const corpus &abi_corpus)
Lookup a type definition in all the translation units of a given ABI corpus.
qualified_type_def_sptr is_array_of_qualified_element(const array_type_def_sptr &array)
Tests if the element of a given array is a qualified type.
void sort_types(const canonical_type_sptr_set_type &types, vector< type_base_sptr > &result)
Sort types in a hopefully stable manner.
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...
type_base * peel_pointer_or_reference_type(const type_base *type, bool peel_qual_type)
Return the leaf underlying or pointed-to type node of a, pointer_type_def, reference_type_def or qual...
reference_type_def * is_reference_type(type_or_decl_base *t, bool look_through_qualifiers)
Test whether a type is a reference_type_def.
corpus::origin operator|(corpus::origin l, corpus::origin r)
Bitwise | operator for the corpus::origin type.
bool elf_symbol_is_function(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
bool is_cplus_plus_language(translation_unit::language l)
Test if a language enumerator designates the C++ language.
bool lookup_decl_only_class_types(const interned_string &qualified_name, const corpus &corp, type_base_wptrs_type &result)
Look into a given corpus to find the class type*s* that have a given qualified name and that are decl...
bool member_function_has_vtable_offset(const function_decl &f)
Test if a virtual member function has a vtable offset set.
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl *scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
unordered_map< interned_string, bool, hash_interned_string > interned_string_bool_map_type
Convenience typedef for a map of interned_string -> bool.
const enum_type_decl * is_enum_type(const type_or_decl_base *d)
Test if a decl is an enum_type_decl.
unordered_map< interned_string, type_base_wptrs_type, hash_interned_string > istring_type_base_wptrs_map_type
A convenience typedef for a map which key is an interned_string and which value is a vector of type_b...
bool function_decl_is_less_than(const function_decl &f, const function_decl &s)
Test if the pretty representation of a given function_decl is lexicographically less then the pretty ...
bool elf_symbols_alias(const elf_symbol &s1, const elf_symbol &s2)
Test if two symbols alias.
var_decl_sptr find_data_member_from_anonymous_data_member(const var_decl_sptr &anon_dm, const string &name)
Find a data member inside an anonymous data member.
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.
const location & get_natural_or_artificial_location(const decl_base *decl)
Get the non-artificial (natural) location of a decl.
size_t hash_type_or_decl(const type_or_decl_base *tod)
Hash an ABI artifact that is either a type or a decl.
method_decl_sptr copy_member_function(class_or_union_sptr t, const method_decl_sptr &method)
Copy a method of a class_or_union into a new class_or_union.
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
bool is_template_decl(const decl_base_sptr &decl)
Tests whether a decl is a template.
shared_ptr< scope_decl > scope_decl_sptr
Convenience typedef for a shared pointer on a scope_decl.
bool string_to_elf_symbol_binding(const string &s, elf_symbol::binding &b)
Convert a string representing a an elf symbol binding into an elf_symbol::binding.
shared_ptr< type_or_decl_base > type_or_decl_base_sptr
A convenience typedef for a shared_ptr to type_or_decl_base.
pointer_type_def_sptr lookup_pointer_type(const interned_string &type_name, const translation_unit &tu)
Lookup a pointer type from a translation unit.
shared_ptr< translation_unit > translation_unit_sptr
Convenience typedef for a shared pointer on a translation_unit type.
bool is_data_member_of_anonymous_class_or_union(const var_decl &d)
Test if a var_decl is a data member belonging to an anonymous type.
bool integral_type_has_harmless_name_change(const type_base_sptr &f, const type_base_sptr &s)
Test if a diff node carries a change whereby two integral types have different names in a harmless wa...
const type_base * is_void_pointer_type_equivalent(const type_base *type)
Test if a type is equivalent to a pointer to void type.
unordered_map< const function_decl *, string, function_decl_hash, function_decl::ptr_equal > fns_to_str_map_type
Convenience typedef for a hash map of pointer to function_decl and string.
lookup_entity_kind
This enum describe the kind of entity to lookup, while using the lookup API.
bool try_canonical_compare(const T *l, const T *r)
Compare two types by comparing their canonical types if present.
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.
unordered_map< string, decl_base_sptr > string_decl_base_sptr_map
Convenience typedef for a map which key is a string and which value is a decl_base_sptr.
qualified_type_def_sptr lookup_qualified_type(const interned_string &type_name, const translation_unit &tu)
Lookup a qualified type from a translation unit.
void push_composite_type_comparison_operands(const type_base &left, const type_base &right)
Push a pair of operands on the stack of operands of the current type comparison, during type canonica...
const type_base_sptr lookup_type(const interned_string &fqn, const translation_unit &tu)
Lookup a type in a translation unit.
bool is_java_language(translation_unit::language l)
Test if a language enumerator designates the Java language.
function_decl::parameter * is_function_parameter(const type_or_decl_base *tod)
Test whether a declaration is a function_decl.
bool equals(const decl_base &l, const decl_base &r, change_kind *k)
Compares two instances of decl_base.
bool get_data_member_is_laid_out(const var_decl &m)
Test whether a data member is laid out.
union_decl_sptr lookup_union_type(const interned_string &type_name, const translation_unit &tu)
Lookup a union type from a translation unit.
bool string_to_elf_symbol_visibility(const string &s, elf_symbol::visibility &v)
Convert a string representing a an elf symbol visibility into an elf_symbol::visibility.
const enum_type_decl * is_compatible_with_enum_type(const type_base *t)
Test if a type is an enum. This function looks through typedefs.
weak_ptr< elf_symbol > elf_symbol_wptr
A convenience typedef for a weak pointer to elf_symbol.
bool get_member_function_is_const(const function_decl &f)
Test whether a member function is const.
interned_string get_name_of_reference_to_type(const type_base &pointed_to_type, bool lvalue_reference, bool qualified, bool internal)
Get the name of the reference to a given type.
shared_ptr< pointer_type_def > pointer_type_def_sptr
Convenience typedef for a shared pointer on a pointer_type_def.
void maybe_update_types_lookup_map(const type_decl_sptr &basic_type)
Update the map that associates the fully qualified name of a basic type with the type itself.
bool is_enumerator_present_in_enum(const enum_type_decl::enumerator &enr, const enum_type_decl &enom)
Test if a given enumerator is found present in an enum.
bool is_const_qualified_type(const qualified_type_def_sptr &t)
Test if a given qualified type is const.
translation_unit::language string_to_translation_unit_language(const string &l)
Parse a string representing a language into a translation_unit::language enumerator into a string.
type_base_sptr lookup_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type from a corpus, by its location.
bool get_next_data_member_offset(const class_or_union *klass, const var_decl_sptr &dm, uint64_t &offset)
Get the offset of the non-static data member that comes after a given one.
uint64_t get_absolute_data_member_offset(const var_decl &m)
Get the absolute offset of a data member.
shared_ptr< ir_traversable_base > ir_traversable_base_sptr
Convenience typedef for a shared pointer to ir_traversable_base.
bool is_member_function(const function_decl &f)
Test whether a function_decl is a member function.
const function_decl::parameter * get_function_parameter(const decl_base *fun, unsigned parm_index)
Get the function parameter designated by its index.
var_decl * is_var_decl(const type_or_decl_base *tod)
Tests if a declaration is a variable declaration.
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.
void keep_type_alive(type_base_sptr t)
Make sure that the life time of a given (smart pointer to a) type is the same as the life time of the...
method_decl * is_method_decl(const type_or_decl_base *d)
Test if a function_decl is actually a method_decl.
array_type_def_sptr lookup_array_type(const interned_string &type_name, const translation_unit &tu)
Lookup an array type from a translation unit.
bool is_member_type(const type_base_sptr &t)
Tests if a type is a class member.
string get_class_or_union_flat_representation(const class_or_union &cou, const string &indent, bool one_line, bool internal, bool qualified_names)
Get the flat representation of an instance of class_or_union type.
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.
bool is_npaf_type(const type_base_sptr &t)
Test if a type is a neither a pointer, an array nor a function type.
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.
void set_data_member_offset(var_decl_sptr m, uint64_t o)
Set the offset of a data member into its containing class.
type_base_sptr strip_typedef(const type_base_sptr type)
Recursively returns the the underlying type of a typedef. The return type should not be a typedef of ...
uint64_t get_data_member_offset(const var_decl &m)
Get the offset of a data member.
unordered_set< uintptr_t > pointer_set
A convenience typedef for an unordered set of pointer values.
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end)
Sort types before hashing (and then canonicalizing) them.
class_or_union * is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
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.
string get_class_or_enum_flat_representation(const type_base &coe, const string &indent, bool one_line, bool internal, bool qualified_name)
Get the flat representation of an instance of enum_type_decl type.
class_or_union * anonymous_data_member_to_class_or_union(const var_decl *d)
Get the class_or_union type of a given anonymous data member.
location get_location(const type_base_sptr &type)
Get the location of the declaration of a given type.
pointer_type_def_sptr is_pointer_to_function_type(const type_base_sptr &t)
Test if a type is a pointer to function type.
translation_unit * get_translation_unit(const type_or_decl_base &t)
Return the translation unit a declaration belongs to.
weak_ptr< decl_base > decl_base_wptr
Convenience typedef for a weak pointer to a decl_base.
var_decl_sptr has_fake_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with one element.
interned_string get_function_type_name(const function_type_sptr &fn_type, bool internal)
Get the name of a given function type and return a copy of it.
bool is_function_template_pattern(const shared_ptr< decl_base > decl)
Test whether a decl is the pattern of a function template.
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 location & get_artificial_or_natural_location(const decl_base *decl)
Get the artificial location of a decl.
enum_type_decl_sptr lookup_enum_type(const interned_string &type_name, const translation_unit &tu)
Lookup an enum type from a translation unit.
type_base_sptr peel_typedef_type(const type_base_sptr &type)
Return the leaf underlying type node of a typedef_decl node.
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.
var_decl_sptr copy_member_variable(class_or_union_sptr t, const var_decl *variable)
Copy a data member of a class_or_union into a new class_or_union.
interned_string get_name_of_qualified_type(const type_base_sptr &underlying_type, qualified_type_def::CV quals, bool qualified, bool internal)
Get the name of a qualified type, given the underlying type and its qualifiers.
shared_ptr< template_decl > template_decl_sptr
Convenience typedef for a shared pointer to template_decl.
array_type_def_sptr is_typedef_of_array(const type_base_sptr &t)
Test if a type is a typedef of an array.
function_type_sptr lookup_function_type(const interned_string &type_name, const translation_unit &tu)
Lookup a function type from a translation unit.
bool is_global_scope(const scope_decl &scope)
Tests whether if a given scope is the global scope.
string get_string_representation_of_cv_quals(const qualified_type_def::CV cv_quals)
Get the string representation of a CV qualifier bitmap.
void set_data_member_is_laid_out(var_decl_sptr m, bool l)
Set a flag saying if a data member is laid out.
pointer_type_def_sptr is_pointer_to_ptr_to_mbr_type(const type_base_sptr &t)
Test if we are looking at a pointer to pointer to member type.
bool is_data_member(const var_decl &v)
Test if a var_decl is a data member.
var_decl_sptr find_first_data_member_matching_regexp(const class_or_union &t, const regex::regex_t_sptr &r)
Find the first data member of a class or union which name matches a regular expression.
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.
var_decl_sptr has_flexible_array_data_member(const class_decl &klass)
Test if the last data member of a class is an array with non-finite data member.
void set_member_is_static(decl_base &d, bool s)
Sets the static-ness property of a class member.
type_base_sptr canonicalize(type_base_sptr t, bool do_log, bool show_stats)
Compute the canonical type of a given type.
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.
interned_string get_method_type_name(const method_type_sptr fn_type, bool internal)
Get the name of a given method type and return a copy of it.
weak_ptr< template_decl > template_decl_wptr
Convenience typedef for a weak pointer to template_decl.
const var_decl * lookup_data_member(const type_base *type, const char *dm_name)
Look for a data member of a given class, struct or union type and return it.
interned_string get_function_id_or_pretty_representation(const function_decl *fn)
Get the ID of a function, or, if the ID can designate several different functions,...
shared_ptr< type_decl > type_decl_sptr
Convenience typedef for a shared pointer on a type_decl.
typedef_decl_sptr clone_typedef(const typedef_decl_sptr &t)
Clone a typedef type.
type_decl_sptr lookup_basic_type_per_location(const interned_string &loc, const corpus &corp)
Lookup a type_decl type from a given corpus, by its location.
bool compare_using_locations(const decl_base *f, const decl_base *s)
Compare decls using their locations.
bool classes_have_same_layout(const type_base_sptr &f, const type_base_sptr &s)
Test if two classes have the same layout.
const type_base_sptr lookup_type_through_scopes(const type_base_sptr type, const translation_unit &tu)
Lookup a type from a translation unit by walking the scopes of the translation unit in sequence and l...
type_or_decl_base * debug(const type_or_decl_base *artifact)
Emit a textual representation of an artifact to std error stream for debugging purposes.
unordered_set< type_base_sptr, canonical_type_hash > canonical_type_sptr_set_type
Helper typedef for an unordered set of type_base_sptr which uses pointer value to tell its members ap...
bool return_comparison_result(T &l, T &r, bool value)
Return the result of the comparison of two (sub) 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.
bool is_unique_type(const type_base_sptr &t)
Test if a type is unique in the entire environment.
bool types_are_compatible(const type_base_sptr type1, const type_base_sptr type2)
Test if two types are equal modulo a typedef or CV qualifiers.
void mark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being compared.
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.
const scope_decl * get_top_most_scope_under(const decl_base *decl, const scope_decl *scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
corpus::origin operator&=(corpus::origin &l, corpus::origin r)
Bitwise &= operator for the corpus::origin type.
type_base_sptr clone_array_tree(const type_base_sptr t)
Clone a type tree made of an array or a typedef of array.
bool operator!=(const translation_unit_sptr &l, const translation_unit_sptr &r)
A deep inequality operator for pointers to translation units.
interned_string get_name_of_pointer_to_type(const type_base &pointed_to_type, bool qualified, bool internal)
Get the name of the pointer to a given type.
bool decl_name_changed(const type_or_decl_base *a1, const type_or_decl_base *a2)
Test if two decls have different names.
bool is_at_template_scope(const shared_ptr< decl_base > decl)
Tests whether a given decl is at template scope.
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.
bool elf_symbol_is_variable(elf_symbol::type t)
Test if the type of an ELF symbol denotes a function symbol.
bool type_has_sub_type_changes(const type_base_sptr t_v1, const type_base_sptr t_v2)
Tests if the change of a given type effectively comes from just its sub-types. That is,...
bool maybe_update_types_lookup_map< class_decl >(const class_decl_sptr &class_type, istring_type_base_wptrs_map_type &map, bool use_type_name_as_key)
This is the specialization for type class_decl of the function template:
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.
typedef_decl_sptr lookup_typedef_type(const interned_string &type_name, const translation_unit &tu)
Lookup a typedef type from a translation unit.
bool is_typedef_ptr_or_ref_to_decl_only_class_or_union_type(const type_base *t)
Test if a type is a typedef, pointer or reference to a decl-only class/union.
std::unordered_map< string, elf_symbols > string_elf_symbols_map_type
Convenience typedef for a map which key is a string and which value is a vector of elf_symbol.
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.
bool class_or_union_types_of_same_kind(const class_or_union *first, const class_or_union *second)
Test if two class or union types are of the same kind.
string build_qualified_name(const scope_decl *scope, const string &name)
Build and return a qualified name from a name and its scope.
bool is_ptr_ref_or_qual_type(const type_base *t)
Helper to detect if a type is either a reference, a pointer, or a qualified type.
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.
shared_ptr< function_tdecl > function_tdecl_sptr
Convenience typedef for a shared pointer on a function_tdecl.
type_base * peel_qualified_or_typedef_type(const type_base *type)
Return the leaf underlying type of a qualified or typedef type.
type_base_sptr type_or_void(const type_base_sptr t, const environment &env)
Return either the type given in parameter if it's non-null, or the void type.
bool is_at_global_scope(const decl_base &decl)
Tests whether a given declaration is at global scope.
type_decl * is_real_type(const type_or_decl_base *t)
Test if a type is a real type.
bool is_member_decl(const decl_base_sptr d)
Tests if a declaration is a class member.
bool maybe_compare_as_member_decls(const decl_base &l, const decl_base &r, change_kind *k)
Compare the properties that belong to the "is-a-member-relation" of a decl.
bool get_member_function_is_ctor(const function_decl &f)
Test whether a member function is a constructor.
void set_member_function_is_ctor(function_decl &f, bool c)
Setter for the is_ctor property of the member function.
bool is_declaration_only_class_type(const type_base_sptr &t, bool look_through_decl_only)
Test wheter a type is a declaration-only class.
Namespace for regex types and functions.
bool match(const regex_t_sptr &r, const std::string &str)
See if a string matches a regex.
std::shared_ptr< regex_t > regex_t_sptr
A convenience typedef for a shared pointer of regex_t.
Toplevel namespace for libabigail.
bool operator==(const std::string &l, const interned_string &r)
Equality operator.
std::string operator+(const interned_string &s1, const std::string &s2)
Concatenation operator.
unordered_map< string, string * > pool_map_type
Convenience typedef for a map of string -> string*.
A functor to hash instances of interned_string.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
Hasher for the class_or_union type.
bool is_printing_flat_representation() const
Getter of the 'is_printing_flat_representation_' boolean.
void unset_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to false.
void set_printing_flat_representation()
Set the 'is_printing_flat_representation_' boolean to true.
A functor to sort decls somewhat topologically. That is, types are sorted in a way that makes the one...
The private data of the environment type.
Equality functor for instances of function_decl.
The hashing functor for function_type.
The type of the private data of the function_type type.
virtual bool traverse(ir_node_visitor &v)
Traverse a given IR node and its children, calling an visitor on each node.
The hashing functor for member_base.
Private type to hold private members of translation_unit.
Hash functor for instances of type_base.
Definition of the private data of type_base.
The private data of type_or_decl_base.
A predicate for deep equality of instances of shared_ptr<type_base>.
A functor to sort types somewhat topologically. That is, types are sorted in a way that makes the one...
A deleter for shared pointers that ... doesn't delete the object managed by the shared pointer.