19#include <unordered_map>
25#include "abg-internal.h"
27ABG_BEGIN_EXPORT_DECLARATIONS
34ABG_END_EXPORT_DECLARATIONS
69using std::unordered_map;
70using std::dynamic_pointer_cast;
71using std::static_pointer_cast;
73using std::recursive_mutex;
77using namespace abg_compat::views;
84struct interned_string_pool::priv
94 lock_guard<mutex> lock(priv_->mutex_);
107 lock_guard<mutex> lock(priv_->mutex_);
108 return priv_->map.find(s) != priv_->map.end();
120 lock_guard<mutex> lock(priv_->mutex_);
121 unordered_map<string, string*>::const_iterator i =
123 if (i == priv_->map.end())
126 return i->second->c_str();
136interned_string_pool::create_string(
const std::string& str_value)
138 lock_guard<mutex> lock(priv_->mutex_);
139 string*& result = priv_->map[str_value];
140 if (!result && !str_value.empty())
141 result =
new string(str_value);
147interned_string_pool::create_string()
const
149 string* result =
nullptr;
157 lock_guard<mutex> lock(priv_->mutex_);
158 for (pool_map_type::iterator i = priv_->map.begin();
159 i != priv_->map.end();
166struct interned_string::priv
185interned_string::interned_string(
string* raw)
186 : priv_(new priv(raw))
190interned_string::interned_string()
195interned_string::~interned_string()
203 : priv_(new priv(o.priv_->raw.load()))
213 lock_guard<mutex> lock(priv_->m);
214 priv_->raw = o.priv_->raw.load();
223 lock_guard<mutex> lock(priv_->m);
224 priv_->raw =
nullptr;
234 lock_guard<mutex> lock(priv_->m);
235 return !
raw() ||
raw()->empty();
262 return priv_->raw == o.priv_->raw.load();
289 return *priv_->raw == o;
319{
return static_cast<string>(*this) <
static_cast<std::string
>(o);}
324interned_string::operator string()
const
342{
return r.operator==(l);}
345operator!=(
const std::string& l,
const interned_string& r)
360 o << static_cast<std::string>(s);
376{
return static_cast<std::string
>(s1) + s2;}
390{
return s1 +
static_cast<std::string
>(s2);}
396hash_as_canonical_type_or_constant(
const type_base *t);
399has_generic_anonymous_internal_type_name(
const decl_base *d);
401static interned_string
402get_generic_anonymous_internal_type_name(
const decl_base *d);
405get_internal_real_type_name(
const type_base*);
408update_qualified_name(decl_base * d);
411update_qualified_name(decl_base_sptr d);
413static interned_string
414pointer_declaration_name(
const type_base* ptr,
415 const string& variable_name,
416 bool qualified,
bool internal);
418static interned_string
419pointer_declaration_name(
const type_base_sptr& ptr,
420 const string& variable_name,
421 bool qualified,
bool internal);
423static interned_string
424ptr_to_mbr_declaration_name(
const ptr_to_mbr_type* ptr,
425 const string& variable_name,
426 bool qualified,
bool internal);
428static interned_string
430 const string& variable_name,
431 bool qualified,
bool internal);
433static interned_string
434array_declaration_name(
const array_type_def* array,
435 const string& variable_name,
436 bool qualified,
bool internal);
438static interned_string
440 const string& variable_name,
441 bool qualified,
bool internal);
444stream_pretty_representation_of_fn_parms(
const function_type& fn_type,
445 ostream& o,
bool qualified,
448add_outer_pointer_to_fn_type_expr(
const type_base* pointer_to_fn,
449 const string& input,
bool qualified,
453add_outer_pointer_to_fn_type_expr(
const type_base_sptr& pointer_to_fn,
454 const string& input,
bool qualified,
458add_outer_pointer_to_array_type_expr(
const type_base* pointer_to_ar,
459 const string& input,
bool qualified,
463add_outer_pointer_to_array_type_expr(
const type_base_sptr& pointer_to_ar,
464 const string& input,
bool qualified,
468add_outer_ptr_to_mbr_type_expr(
const ptr_to_mbr_type* p,
469 const string& input,
bool qualified,
474 const string& input,
bool qualified,
478add_outer_pointer_to_ptr_to_mbr_type_expr(
const type_base* p,
480 bool qualified,
bool internal);
482template <
typename TypeArtifact>
493{
return t.priv_->canonical_type_index;}
528 if (c && t->get_corpus())
533 if (t->get_corpus()->get_group() == g.get())
538 if (t->get_corpus() == c.get())
548class expanded_location
560 expanded_location(
const string& path,
unsigned line,
unsigned column)
561 : path_(path), line_(line), column_(column)
565 operator==(
const expanded_location& l)
const
567 return (path_ == l.path_
569 && column_ && l.column_);
573 operator<(
const expanded_location& l)
const
577 else if (path_ > l.path_)
582 else if (line_ > l.line_)
585 return column_ < l.column_;
591 std::atomic<unsigned> value_;
595 std::atomic<location_manager*> loc_manager_;
602 std::atomic<size_t> artificial_location_;
606 loc_manager_(nullptr),
607 artificial_location_()
610 priv(
unsigned v, location_manager* m)
613 artificial_location_()
622 : priv_(new priv(v, m))
630location::get_location_manager()
const
631{
return priv_->loc_manager_;}
647{
return !!get_artificial_value();}
650location::get_artificial_value()
const
651{
return priv_->artificial_location_;}
668{priv_->artificial_location_ = l;}
674 : priv_(new priv(l.priv_->value_, l.priv_->loc_manager_))
676 priv_->artificial_location_.store(l.priv_->artificial_location_);
685 priv_->value_.store(l.priv_->value_);
686 priv_->loc_manager_.store(l.priv_->loc_manager_);
687 priv_->artificial_location_.store(l.priv_->artificial_location_);
699{
return priv_->value_;}
705location::operator bool()
const
706{
return !!priv_->value_;}
715{
return priv_->value_ == other.priv_->value_;}
725{
return priv_->value_ < other.priv_->value_;}
740 if (!get_location_manager())
761 unsigned line = 0, column = 0;
762 expand(path, line, column);
764 std::ostringstream o;
765 o << path <<
":" << line <<
":" << column;
769struct location_manager::priv
775 std::vector<expanded_location> locs;
779location_manager::location_manager()
783location_manager::~location_manager() =
default;
798 expanded_location l(file_path, line, col);
802 lock_guard<mutex> lock(priv_->locs_mutex);
803 priv_->locs.push_back(l);
804 return location(priv_->locs.size(),
this);
821 unsigned& column)
const
825 lock_guard<mutex> lock(priv_->locs_mutex);
826 expanded_location &l = priv_->locs[
location.priv_->value_ - 1];
839struct type_maps::priv
841 typedef unordered_map<size_t,
844 mutable type_map_hash_type type_maps_hash_;
857 mutable vector<type_base_wptr> sorted_types_;
860type_maps::type_maps()
863 priv_->type_maps_hash_[
typeid(
type_decl).hash_code()] = &priv_->basic_types_;
864 priv_->type_maps_hash_[
typeid(
class_decl).hash_code()] = &priv_->class_types_;
865 priv_->type_maps_hash_[
typeid(
union_decl).hash_code()] = &priv_->union_types_;
868 priv_->type_maps_hash_[
typeid(
typedef_decl).hash_code()] =
869 &priv_->typedef_types_;
871 &priv_->qualified_types_;
873 &priv_->pointer_types_;
875 &priv_->reference_types_;
877 &priv_->ptr_to_mbr_types_;
879 &priv_->array_types_;
881 &priv_->subrange_types_;
883 &priv_->function_types_;
884 priv_->type_maps_hash_[
typeid(
method_type).hash_code()] =
885 &priv_->function_types_;
888type_maps::~type_maps() =
default;
913{
return priv_->basic_types_;}
920{
return priv_->basic_types_;}
927{
return priv_->class_types_;}
934{
return priv_->class_types_;}
941{
return priv_->union_types_;}
948{
return priv_->union_types_;}
955{
return priv_->enum_types_;}
962{
return priv_->enum_types_;}
969{
return priv_->typedef_types_;}
976{
return priv_->typedef_types_;}
982{
return priv_->qualified_types_;}
988{
return priv_->qualified_types_;}
995{
return priv_->pointer_types_;}
1002{
return priv_->ptr_to_mbr_types_;}
1009{
return priv_->ptr_to_mbr_types_;}
1016{
return priv_->pointer_types_;}
1023{
return priv_->reference_types_;}
1030{
return priv_->reference_types_;}
1037{
return priv_->array_types_;}
1044{
return priv_->array_types_;}
1051{
return priv_->subrange_types_;}
1058{
return priv_->subrange_types_;}
1065{
return priv_->function_types_;}
1072{
return priv_->function_types_;}
1076struct type_name_comp
1091 if (l == 0 && r == 0)
1096 return l_repr < r_repr;
1110 operator()(
const type_base_sptr &l,
const type_base_sptr &r)
const
1111 {
return operator()(l.get(), r.get());}
1125 {
return operator()(type_base_sptr(l), type_base_sptr(r));}
1128#ifdef WITH_DEBUG_SELF_COMPARISON
1144notify_equality_failed(
const type_or_decl_base &l __attribute__((unused)),
1145 const type_or_decl_base &r __attribute__((unused)))
1162notify_equality_failed(
const type_or_decl_base *l __attribute__((unused)),
1163 const type_or_decl_base *r __attribute__((unused)))
1166#define ABG_RETURN_EQUAL(l, r) \
1170 notify_equality_failed(l, r); \
1176#define ABG_RETURN_FALSE \
1179 notify_equality_failed(l, r); \
1183#define ABG_RETURN(value) \
1186 if (value == false) \
1187 notify_equality_failed(l, r); \
1193#define ABG_RETURN_FALSE return false
1194#define ABG_RETURN(value) return (value)
1195#define ABG_RETURN_EQUAL(l, r) return ((l) == (r));
1216 return dynamic_cast<T*
>(type);
1233#if WITH_DEBUG_TYPE_CANONICALIZATION
1253 if (env.priv_->use_canonical_type_comparison_)
1257 ABG_RETURN_EQUAL(lc, rc);
1266 if (l_hash != r_hash)
1273 return equals(*l, *r, 0);
1277 ABG_RETURN_EQUAL(lc, rc);
1285 if (l_hash != r_hash)
1292 return equals(*l, *r, 0);
1296thread_local class_set_type class_or_union::priv::left_classes_being_compared_;
1297thread_local class_set_type class_or_union::priv::right_classes_being_compared_;
1298thread_local class_set_type class_or_union::priv::classes_being_printed_;
1312 bool result = l.priv_->comparison_started(l, r);
1352#define RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED(l, r) \
1355 if (is_comparison_cycle_detected(l, r)) \
1373 l.priv_->mark_as_being_compared(l, r);
1407 l.priv_->unmark_as_being_compared(l, r);
1431thread_local bool environment::priv::allow_type_comparison_results_caching_ =
false;
1432std::atomic<size_t> environment::priv::number_of_threads_to_use_
1459 size_t computed_value = initial_value;
1461 if (initial_value > 1)
1462 if (
const char* v = std::getenv(
"ABIGAIL_THREAD_POOL_SIZE"))
1465 return computed_value;
1485 return default_value;
1488 bool is_percentage =
false;
1490 is_percentage =
true;
1495 string percentage_value;
1497 result = strtoull(percentage_value.c_str(), 0, 0);
1499 result = (default_value * result) / 100;
1503 result = strtoull(tps.c_str(), 0, 0);
1506 result = default_value;
1514{type_comparison_results_cache_.clear();}
1523{allow_type_comparison_results_caching_ = f;}
1534{
return allow_type_comparison_results_caching_;}
1559#define CACHE_AND_RETURN_COMPARISON_RESULT(value) \
1562 bool res = return_comparison_result(l, r, value); \
1563 l.get_environment().priv_->cache_type_comparison_result(l, r, res); \
1571#define CACHE_COMPARISON_RESULT_AND_RETURN(value) \
1574 l.get_environment().priv_->cache_type_comparison_result(l, r, value); \
1582const vector<type_base_wptr>&
1585 if (priv_->sorted_types_.empty())
1587 for (
auto e : basic_types())
1588 for (
auto t : e.second)
1589 priv_->sorted_types_.push_back(t);
1591 for (
auto e : class_types())
1592 for (
auto t : e.second)
1593 priv_->sorted_types_.push_back(t);
1595 for (
auto e : union_types())
1596 for (
auto t : e.second)
1597 priv_->sorted_types_.push_back(t);
1599 for (
auto e : enum_types())
1600 for (
auto t : e.second)
1601 priv_->sorted_types_.push_back(t);
1603 for (
auto e : typedef_types())
1604 for (
auto t : e.second)
1605 priv_->sorted_types_.push_back(t);
1607 for (
auto e : qualified_types())
1608 for (
auto t : e.second)
1609 priv_->sorted_types_.push_back(t);
1611 for (
auto e : pointer_types())
1612 for (
auto t : e.second)
1613 priv_->sorted_types_.push_back(t);
1615 for (
auto e : ptr_to_mbr_types())
1616 for (
auto t : e.second)
1617 priv_->sorted_types_.push_back(t);
1619 for (
auto e : reference_types())
1620 for (
auto t : e.second)
1621 priv_->sorted_types_.push_back(t);
1623 for (
auto e : array_types())
1624 for (
auto t : e.second)
1625 priv_->sorted_types_.push_back(t);
1627 for (
auto e : subrange_types())
1628 for (
auto t : e.second)
1629 priv_->sorted_types_.push_back(t);
1631 for (
auto e : function_types())
1632 for (
auto t : e.second)
1633 priv_->sorted_types_.push_back(t);
1637 priv_->sorted_types_.end(),
1641 return priv_->sorted_types_;
1645type_maps::get_type_map(
const std::type_info& ti)
1647 auto i = priv_->type_maps_hash_.find(ti.hash_code());
1648 if (i == priv_->type_maps_hash_.end())
1669 const std::string& path,
1671 : priv_(new
priv(env))
1673 priv_->path_ = path;
1674 priv_->address_size_ = address_size;
1696 lock_guard<recursive_mutex> lock(priv_->mutex_);
1698 if (!priv_->global_scope_)
1702 return priv_->global_scope_;
1710{
return priv_->types_;}
1717{
return priv_->types_;}
1726{
return priv_->live_fn_types_;}
1733{
return priv_->env_;}
1741 lock_guard<recursive_mutex> lock(priv_->mutex_);
1742 return priv_->language_;
1751 lock_guard<recursive_mutex> lock(priv_->mutex_);
1752 priv_->language_ = l;
1767 lock_guard<recursive_mutex> lock(priv_->mutex_);
1768 return priv_->path_;
1781 lock_guard<recursive_mutex> lock(priv_->mutex_);
1782 priv_->path_ = a_path;
1797 lock_guard<recursive_mutex> lock(priv_->mutex_);
1798 return priv_->comp_dir_path_;
1811 lock_guard<recursive_mutex> lock(priv_->mutex_);
1812 priv_->comp_dir_path_ = d;
1822 lock_guard<recursive_mutex> lock(priv_->mutex_);
1824 if (priv_->abs_path_.empty())
1827 if (!priv_->path_.empty())
1829 if (!priv_->comp_dir_path_.empty())
1831 path = priv_->comp_dir_path_;
1834 path += priv_->path_;
1836 priv_->abs_path_ = path;
1840 return priv_->abs_path_;
1852 lock_guard<recursive_mutex> lock(priv_->mutex_);
1863 lock_guard<recursive_mutex> lock(priv_->mutex_);
1881{
return priv_->loc_mgr_;}
1889{
return priv_->loc_mgr_;}
1899 lock_guard<recursive_mutex> lock(priv_->mutex_);
1900 if (!priv_->global_scope_)
1912 lock_guard<recursive_mutex> lock(priv_->mutex_);
1913 return priv_->address_size_;
1922 lock_guard<recursive_mutex> lock(priv_->mutex_);
1923 priv_->address_size_= a;
1941 lock_guard<recursive_mutex> lock(priv_->mutex_);
1942 return priv_->is_constructed_;
1960 lock_guard<recursive_mutex> lock(priv_->mutex_);
1961 priv_->is_constructed_ = f;
2011 if (ftype->get_translation_unit())
2022 lock_guard<mutex> lock(priv_->live_fn_types_mutex_);
2027 lock_guard<recursive_mutex> lock(priv_->types_mutex_);
2052translation_unit::~translation_unit()
2065 case translation_unit::LANG_UNKNOWN:
2066 return "LANG_UNKNOWN";
2067 case translation_unit::LANG_Cobol74:
2068 return "LANG_Cobol74";
2069 case translation_unit::LANG_Cobol85:
2070 return "LANG_Cobol85";
2071 case translation_unit::LANG_C89:
2073 case translation_unit::LANG_C99:
2075 case translation_unit::LANG_C11:
2077 case translation_unit::LANG_C17:
2079 case translation_unit::LANG_C23:
2081 case translation_unit::LANG_C:
2083 case translation_unit::LANG_C_plus_plus_03:
2084 return "LANG_C_plus_plus_03";
2085 case translation_unit::LANG_C_plus_plus_11:
2086 return "LANG_C_plus_plus_11";
2087 case translation_unit::LANG_C_plus_plus_14:
2088 return "LANG_C_plus_plus_14";
2089 case translation_unit::LANG_C_plus_plus_17:
2090 return "LANG_C_plus_plus_17";
2091 case translation_unit::LANG_C_plus_plus_20:
2092 return "LANG_C_plus_plus_20";
2093 case translation_unit::LANG_C_plus_plus_23:
2094 return "LANG_C_plus_plus_23";
2095 case translation_unit::LANG_C_plus_plus:
2096 return "LANG_C_plus_plus";
2097 case translation_unit::LANG_OCaml:
2098 return "LANG_OCaml";
2099 case translation_unit::LANG_Zig:
2101 case translation_unit::LANG_ObjC:
2103 case translation_unit::LANG_ObjC_plus_plus:
2104 return "LANG_ObjC_plus_plus";
2105 case translation_unit::LANG_D:
2107 case translation_unit::LANG_Go:
2109 case translation_unit::LANG_Rust:
2111 case translation_unit::LANG_Fortran77:
2112 return "LANG_Fortran77";
2113 case translation_unit::LANG_Fortran90:
2114 return "LANG_Fortran90";
2115 case translation_unit::LANG_Fortran95:
2116 return "LANG_Fortran95";
2117 case translation_unit::LANG_Fortran18:
2118 return "LANG_Fortran18";
2119 case translation_unit::LANG_Fortran23:
2120 return "LANG_Fortran23";
2121 case translation_unit::LANG_Ada83:
2122 return "LANG_Ada83";
2123 case translation_unit::LANG_Ada95:
2124 return "LANG_Ada95";
2125 case translation_unit::LANG_Ada2005:
2126 return "LANG_Ada2005";
2127 case translation_unit::LANG_Ada2012:
2128 return "LANG_Ada2012";
2129 case translation_unit::LANG_Pascal83:
2130 return "LANG_Pascal83";
2131 case translation_unit::LANG_Modula2:
2132 return "LANG_Modula2";
2133 case translation_unit::LANG_Java:
2135 case translation_unit::LANG_Kotlin:
2136 return "LANG_Kotlin";
2137 case translation_unit::LANG_C_sharp:
2138 return "LANG_C_sharp";
2139 case translation_unit::LANG_Python:
2140 return "LANG_Python";
2141 case translation_unit::LANG_Ruby:
2143 case translation_unit::LANG_PLI:
2145 case translation_unit::LANG_UPC:
2147 case translation_unit::LANG_Mips_Assembler:
2148 return "LANG_Mips_Assembler";
2149 case translation_unit::LANG_Assembly:
2150 return "LANG_Assembly";
2151 case translation_unit::LANG_Crystal:
2152 return "LANG_Crystal";
2153 case translation_unit::LANG_HIP:
2155 case translation_unit::LANG_Mojo:
2157 case translation_unit::LANG_GLSL:
2159 case translation_unit::LANG_GLSL_ES:
2160 return "LANG_GLSL_ES";
2161 case translation_unit::LANG_HLSL:
2163 case translation_unit::LANG_OpenCL_CPP:
2164 return "LANG_OpenCL_CPP";
2165 case translation_unit::LANG_CPP_for_OpenCL:
2166 return "LANG_CPP_for_OpenCL";
2167 case translation_unit::LANG_SYCL:
2169 case translation_unit::LANG_Odin:
2171 case translation_unit::LANG_P4:
2173 case translation_unit::LANG_Metal:
2174 return "LANG_Metal";
2175 case translation_unit::LANG_Move:
2177 case translation_unit::LANG_Hylo:
2181 return "LANG_UNKNOWN";
2193 if (l ==
"LANG_Cobol74")
2194 return translation_unit::LANG_Cobol74;
2195 else if (l ==
"LANG_Cobol85")
2196 return translation_unit::LANG_Cobol85;
2197 else if (l ==
"LANG_C89")
2198 return translation_unit::LANG_C89;
2199 else if (l ==
"LANG_C99")
2200 return translation_unit::LANG_C99;
2201 else if (l ==
"LANG_C11")
2202 return translation_unit::LANG_C11;
2203 else if (l ==
"LANG_C17")
2204 return translation_unit::LANG_C17;
2205 else if (l ==
"LANG_C23")
2206 return translation_unit::LANG_C23;
2207 else if (l ==
"LANG_C")
2208 return translation_unit::LANG_C;
2209 else if (l ==
"LANG_C_plus_plus_03")
2210 return translation_unit::LANG_C_plus_plus_03;
2211 else if (l ==
"LANG_C_plus_plus_11")
2212 return translation_unit::LANG_C_plus_plus_11;
2213 else if (l ==
"LANG_C_plus_plus_14")
2214 return translation_unit::LANG_C_plus_plus_14;
2215 else if (l ==
"LANG_C_plus_plus_17")
2216 return translation_unit::LANG_C_plus_plus_17;
2217 else if (l ==
"LANG_C_plus_plus_20")
2218 return translation_unit::LANG_C_plus_plus_20;
2219 else if (l ==
"LANG_C_plus_plus_23")
2220 return translation_unit::LANG_C_plus_plus_23;
2221 else if (l ==
"LANG_C_plus_plus")
2222 return translation_unit::LANG_C_plus_plus;
2223 else if (l ==
"LANG_OCaml")
2224 return translation_unit::LANG_OCaml;
2225 else if (l ==
"LANG_ObjC")
2226 return translation_unit::LANG_ObjC;
2227 else if (l ==
"LANG_ObjC_plus_plus")
2228 return translation_unit::LANG_ObjC_plus_plus;
2229 else if (l ==
"LANG_Zig")
2230 return translation_unit::LANG_Zig;
2231 else if (l ==
"LANG_Metal")
2232 return translation_unit::LANG_Metal;
2233 else if (l ==
"LANG_Fortran77")
2234 return translation_unit::LANG_Fortran77;
2235 else if (l ==
"LANG_Fortran90")
2236 return translation_unit::LANG_Fortran90;
2237 else if (l ==
"LANG_Fortran95")
2238 return translation_unit::LANG_Fortran95;
2239 else if (l ==
"LANG_Fortran18")
2240 return translation_unit::LANG_Fortran23;
2241 else if (l ==
"LANG_Ada83")
2242 return translation_unit::LANG_Ada83;
2243 else if (l ==
"LANG_Ada95")
2244 return translation_unit::LANG_Ada95;
2245 else if (l ==
"LANG_Ada2005")
2246 return translation_unit::LANG_Ada2005;
2247 else if (l ==
"LANG_Ada2012")
2248 return translation_unit::LANG_Ada2012;
2249 else if (l ==
"LANG_Pascal83")
2250 return translation_unit::LANG_Pascal83;
2251 else if (l ==
"LANG_Modula2")
2252 return translation_unit::LANG_Modula2;
2253 else if (l ==
"LANG_Java")
2254 return translation_unit::LANG_Java;
2255 else if (l ==
"LANG_Kotlin")
2256 return translation_unit::LANG_Kotlin;
2257 else if (l ==
"LANG_PLI")
2258 return translation_unit::LANG_PLI;
2259 else if (l ==
"LANG_UPC")
2260 return translation_unit::LANG_UPC;
2261 else if (l ==
"LANG_D")
2262 return translation_unit::LANG_D;
2263 else if (l ==
"LANG_Go")
2264 return translation_unit::LANG_Go;
2265 else if (l ==
"LANG_Rust")
2266 return translation_unit::LANG_Rust;
2267 else if (l ==
"LANG_Python")
2268 return translation_unit::LANG_Python;
2269 else if (l ==
"LANG_Ruby")
2270 return translation_unit::LANG_Ruby;
2271 else if (l ==
"LANG_Mips_Assembler")
2272 return translation_unit::LANG_Mips_Assembler;
2273 else if (l ==
"LANG_Assembly")
2274 return translation_unit::LANG_Assembly;
2275 else if (l ==
"LANG_Crystal")
2276 return translation_unit::LANG_Crystal;
2277 else if (l ==
"LANG_HIP")
2278 return translation_unit::LANG_HIP;
2279 else if (l ==
"LANG_C_sharp")
2280 return translation_unit::LANG_C_sharp;
2281 else if (l ==
"LANG_Mojo")
2282 return translation_unit::LANG_Mojo;
2283 else if (l ==
"LANG_GLSL")
2284 return translation_unit::LANG_GLSL;
2285 else if (l ==
"LANG_GLSL_ES")
2286 return translation_unit::LANG_GLSL_ES;
2287 else if (l ==
"LANG_HLSL")
2288 return translation_unit::LANG_HLSL;
2289 else if (l ==
"LANG_OpenCL_CPP")
2290 return translation_unit::LANG_OpenCL_CPP;
2291 else if (l ==
"LANG_CPP_for_OpenCL")
2292 return translation_unit::LANG_CPP_for_OpenCL;
2293 else if (l ==
"LANG_SYCL")
2294 return translation_unit::LANG_SYCL;
2295 else if (l ==
"LANG_Odin")
2296 return translation_unit::LANG_Odin;
2297 else if (l ==
"LANG_P4")
2298 return translation_unit::LANG_P4;
2299 else if (l ==
"LANG_Move")
2300 return translation_unit::LANG_Move;
2301 else if (l ==
"LANG_Hylo")
2302 return translation_unit::LANG_Hylo;
2304 return translation_unit::LANG_UNKNOWN;
2315 return (l == translation_unit::LANG_C89
2316 || l == translation_unit::LANG_C99
2317 || l == translation_unit::LANG_C11
2318 || l == translation_unit::LANG_C17
2319 || l == translation_unit::LANG_C23
2320 || l == translation_unit::LANG_C);
2331 return (l == translation_unit::LANG_C_plus_plus_03
2332 || l == translation_unit::LANG_C_plus_plus_11
2333 || l == translation_unit::LANG_C_plus_plus_14
2334 || l == translation_unit::LANG_C_plus_plus_20
2335 || l == translation_unit::LANG_C_plus_plus_23
2336 || l == translation_unit::LANG_C_plus_plus);
2346{
return l == translation_unit::LANG_Java;}
2356 return (l == translation_unit::LANG_Ada83
2357 || l == translation_unit::LANG_Ada95
2358 || l == translation_unit::LANG_Ada2005
2359 || l == translation_unit::LANG_Ada2012);
2372 if (l.get() == r.get())
2395struct elf_symbol::priv
2397 recursive_mutex mutex_;
2436 bool is_in_ksymtab_;
2439 bool is_suppressed_;
2454 is_in_ksymtab_(false),
2457 is_suppressed_(false)
2460 priv(
const environment& e,
2468 const elf_symbol::version& ve,
2490 is_common_ = type_ == COMMON_TYPE;
2524elf_symbol::elf_symbol(
const environment& e,
2600 elf_symbol_sptr sym(
new elf_symbol(e, i, s, n, t, b, d, c, ve, vi,
2602 sym->priv_->main_symbol_ = sym;
2661{
return priv_->env_;}
2669 lock_guard<recursive_mutex> lock(priv_->mutex_);
2670 return priv_->index_;
2679 lock_guard<recursive_mutex> lock(priv_->mutex_);
2689 lock_guard<recursive_mutex> lock(priv_->mutex_);
2690 return priv_->name_;
2699 lock_guard<recursive_mutex> lock(priv_->mutex_);
2701 priv_->id_string_.clear();
2710 lock_guard<recursive_mutex> lock(priv_->mutex_);
2711 return priv_->type_;
2720 lock_guard<recursive_mutex> lock(priv_->mutex_);
2730 lock_guard<recursive_mutex> lock(priv_->mutex_);
2731 return priv_->size_;
2740 lock_guard<recursive_mutex> lock(priv_->mutex_);
2741 priv_->size_ = size;
2750 lock_guard<recursive_mutex> lock(priv_->mutex_);
2751 return priv_->binding_;
2760 lock_guard<recursive_mutex> lock(priv_->mutex_);
2761 priv_->binding_ = b;
2770 lock_guard<recursive_mutex> lock(priv_->mutex_);
2771 return priv_->version_;
2780 lock_guard<recursive_mutex> lock(priv_->mutex_);
2781 priv_->version_ = v;
2782 priv_->id_string_.clear();
2792 lock_guard<recursive_mutex> lock(priv_->mutex_);
2793 priv_->visibility_ = v;
2803 lock_guard<recursive_mutex> lock(priv_->mutex_);
2804 return priv_->visibility_;
2814 lock_guard<recursive_mutex> lock(priv_->mutex_);
2815 return priv_->is_defined_;
2825 lock_guard<recursive_mutex> lock(priv_->mutex_);
2826 priv_->is_defined_ = d;
2881 lock_guard<recursive_mutex> lock(priv_->mutex_);
2882 return priv_->is_in_ksymtab_;
2892 lock_guard<recursive_mutex> lock(priv_->mutex_);
2902 lock_guard<recursive_mutex> lock(priv_->mutex_);
2912 lock_guard<recursive_mutex> lock(priv_->mutex_);
2922 lock_guard<recursive_mutex> lock(priv_->mutex_);
2923 return priv_->namespace_;
2932 lock_guard<recursive_mutex> lock(priv_->mutex_);
2933 priv_->namespace_ = ns;
2944 lock_guard<recursive_mutex> lock(priv_->mutex_);
2945 return priv_->is_suppressed_;
2956 lock_guard<recursive_mutex> lock(priv_->mutex_);
2989 lock_guard<recursive_mutex> lock(priv_->mutex_);
2990 return priv_->main_symbol_.lock();
2999 lock_guard<recursive_mutex> lock(priv_->mutex_);
3000 return priv_->main_symbol_.lock();
3009 lock_guard<recursive_mutex> lock(priv_->mutex_);
3019 lock_guard<recursive_mutex> lock(priv_->mutex_);
3020 return priv_->next_alias_.lock();
3037 lock_guard<recursive_mutex> lock(priv_->mutex_);
3042 a = a->get_next_alias())
3065 a && !a->is_main_symbol();
3066 a = a->get_next_alias())
3068 if (a->get_next_alias()->is_main_symbol())
3076 last_alias->priv_->next_alias_ = alias;
3080 lock_guard<recursive_mutex> lock(priv_->mutex_);
3081 priv_->next_alias_ = alias;
3111 a = a->get_next_alias())
3112 if (a->get_name() == name)
3122 lock_guard<recursive_mutex> lock(priv_->mutex_);
3124 priv_->main_symbol_ = new_main;
3129 a = a->get_next_alias())
3131 lock_guard<recursive_mutex> lock(a->priv_->mutex_);
3132 a->priv_->main_symbol_ = new_main;
3145 lock_guard<recursive_mutex> lock(priv_->mutex_);
3146 return priv_->is_common_;
3179 lock_guard<recursive_mutex> lock(priv_->mutex_);
3180 return priv_->next_common_instance_.lock();
3196 lock_guard<recursive_mutex> lock(priv_->mutex_);
3198 ABG_ASSERT(!common->has_other_common_instances());
3207 c = c->get_next_common_instance())
3212 last_common_instance = c;
3217 last_common_instance->priv_->next_common_instance_ = common;
3220 priv_->next_common_instance_ = common;
3240 if (priv_->id_string_.empty())
3252 priv_->id_string_ = s;
3255 return priv_->id_string_;
3272 a = a->get_next_alias())
3273 if (a->get_name() == name)
3290 a && a.get() != a->get_main_symbol().get();
3291 a = a->get_next_alias())
3292 if (textually_equals(*
this, *a))
3309 bool include_symbol_itself)
const
3313 if (include_symbol_itself)
3316 vector<elf_symbol_sptr> aliases;
3317 compute_aliases_for_elf_symbol(*
this, syms, aliases);
3318 if (!aliases.empty() && include_symbol_itself)
3321 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
3325 if (i != aliases.begin())
3327 result += (*i)->get_id_string();
3342 vector<elf_symbol_sptr> aliases;
3343 if (include_symbol_itself)
3348 a = a->get_next_alias())
3349 aliases.push_back(a);
3352 for (vector<elf_symbol_sptr>::const_iterator i = aliases.begin();
3356 if (i != aliases.begin())
3358 result += (*i)->get_id_string();
3378 name.clear(), ver.clear();
3380 string::size_type i =
id.find(
'@');
3381 if (i == string::npos)
3387 name =
id.substr(0, i);
3393 string::size_type j =
id.find(
'@', i);
3394 if (j == string::npos)
3421 bool are_equal = textually_equals(*
this, other);
3442 a && !a->is_main_symbol();
3443 a = a->get_next_alias())
3467 return *lhs == *rhs;
3493compute_aliases_for_elf_symbol(
const elf_symbol& sym,
3495 vector<elf_symbol_sptr>& aliases)
3499 for (; a && !a->is_main_symbol(); a = a->get_next_alias())
3500 aliases.push_back(a);
3506 string_elf_symbols_map_type::const_iterator i =
3508 if (i == symtab.end())
3511 for (elf_symbols::const_iterator j = i->second.begin();
3512 j != i->second.end();
3517 s && !s->is_main_symbol();
3518 s = s->get_next_alias())
3519 aliases.push_back(s);
3522 s && !s->is_main_symbol();
3523 s = s->get_next_alias())
3525 aliases.push_back(*j);
3571 case elf_symbol::NOTYPE_TYPE:
3572 repr =
"unspecified symbol type";
3574 case elf_symbol::OBJECT_TYPE:
3575 repr =
"variable symbol type";
3577 case elf_symbol::FUNC_TYPE:
3578 repr =
"function symbol type";
3580 case elf_symbol::SECTION_TYPE:
3581 repr =
"section symbol type";
3583 case elf_symbol::FILE_TYPE:
3584 repr =
"file symbol type";
3586 case elf_symbol::COMMON_TYPE:
3587 repr =
"common data object symbol type";
3589 case elf_symbol::TLS_TYPE:
3590 repr =
"thread local data object symbol type";
3592 case elf_symbol::GNU_IFUNC_TYPE:
3593 repr =
"indirect function symbol type";
3597 std::ostringstream s;
3598 s <<
"unknown symbol type (" << (char)t <<
')';
3621 case elf_symbol::LOCAL_BINDING:
3622 repr =
"local binding";
3624 case elf_symbol::GLOBAL_BINDING:
3625 repr =
"global binding";
3627 case elf_symbol::WEAK_BINDING:
3628 repr =
"weak binding";
3630 case elf_symbol::GNU_UNIQUE_BINDING:
3631 repr =
"GNU unique binding";
3635 std::ostringstream s;
3636 s <<
"unknown binding (" << (
unsigned char) b <<
")";
3659 case elf_symbol::DEFAULT_VISIBILITY:
3660 repr =
"default visibility";
3662 case elf_symbol::PROTECTED_VISIBILITY:
3663 repr =
"protected visibility";
3665 case elf_symbol::HIDDEN_VISIBILITY:
3666 repr =
"hidden visibility";
3668 case elf_symbol::INTERNAL_VISIBILITY:
3669 repr =
"internal visibility";
3673 std::ostringstream s;
3674 s <<
"unknown visibility (" << (
unsigned char) v <<
")";
3696 t = elf_symbol::NOTYPE_TYPE;
3697 else if (s ==
"object-type")
3698 t = elf_symbol::OBJECT_TYPE;
3699 else if (s ==
"func-type")
3700 t = elf_symbol::FUNC_TYPE;
3701 else if (s ==
"section-type")
3702 t = elf_symbol::SECTION_TYPE;
3703 else if (s ==
"file-type")
3704 t = elf_symbol::FILE_TYPE;
3705 else if (s ==
"common-type")
3706 t = elf_symbol::COMMON_TYPE;
3707 else if (s ==
"tls-type")
3708 t = elf_symbol::TLS_TYPE;
3709 else if (s ==
"gnu-ifunc-type")
3710 t = elf_symbol::GNU_IFUNC_TYPE;
3728 if (s ==
"local-binding")
3729 b = elf_symbol::LOCAL_BINDING;
3730 else if (s ==
"global-binding")
3731 b = elf_symbol::GLOBAL_BINDING;
3732 else if (s ==
"weak-binding")
3733 b = elf_symbol::WEAK_BINDING;
3734 else if (s ==
"gnu-unique-binding")
3735 b = elf_symbol::GNU_UNIQUE_BINDING;
3753 if (s ==
"default-visibility")
3754 v = elf_symbol::DEFAULT_VISIBILITY;
3755 else if (s ==
"protected-visibility")
3756 v = elf_symbol::PROTECTED_VISIBILITY;
3757 else if (s ==
"hidden-visibility")
3758 v = elf_symbol::HIDDEN_VISIBILITY;
3759 else if (s ==
"internal-visibility")
3760 v = elf_symbol::INTERNAL_VISIBILITY;
3775{
return t == elf_symbol::FUNC_TYPE;}
3785{
return t == elf_symbol::OBJECT_TYPE;}
3789struct elf_symbol::version::priv
3795 : is_default_(false)
3798 priv(
const string& v,
3805elf_symbol::version::version()
3812elf_symbol::version::version(
const string& v,
3814 : priv_(new priv(v, is_default))
3818 : priv_(new priv(v.str(), v.is_default()))
3822elf_symbol::version::~version() =
default;
3827elf_symbol::version::operator
const string&()
const
3828{
return priv_->version_;}
3835{
return priv_->version_;}
3842{priv_->version_ = s;}
3849{
return priv_->is_default_;}
3856{priv_->is_default_ = f;}
3859elf_symbol::version::is_empty()
const
3860{
return str().empty();}
3869{
return str() == o.
str();}
3898struct dm_context_rel::priv
3901 size_t offset_in_bits_;
3904 priv(
bool is_static =
false)
3905 : is_laid_out_(!is_static),
3909 priv(
bool is_laid_out,
size_t offset_in_bits)
3910 : is_laid_out_(is_laid_out),
3911 offset_in_bits_(offset_in_bits)
3915dm_context_rel::dm_context_rel()
3922 size_t offset_in_bits,
3925 : context_rel(s, a, is_static),
3926 priv_(new priv(is_laid_out, offset_in_bits))
3935dm_context_rel::get_is_laid_out()
const
3936{
return priv_->is_laid_out_;}
3939dm_context_rel::set_is_laid_out(
bool f)
3940{priv_->is_laid_out_ = f;}
3943dm_context_rel::get_offset_in_bits()
const
3944{
return priv_->offset_in_bits_;}
3947dm_context_rel::set_offset_in_bits(
size_t o)
3948{priv_->offset_in_bits_ = o;}
3951dm_context_rel::operator==(
const dm_context_rel& o)
const
3953 if (!context_rel::operator==(o))
3956 return (priv_->is_laid_out_ == o.priv_->is_laid_out_
3957 && priv_->offset_in_bits_ == o.priv_->offset_in_bits_);
3961dm_context_rel::operator!=(
const dm_context_rel& o)
const
3973 var_decl_sptr result = priv_->anonymous_data_member_.lock();
3985{priv_->anonymous_data_member_ = anon_dm;}
3987dm_context_rel::~dm_context_rel()
4004 if (group->types_set_.find(t) != group->types_set_.end())
4006 group->types_set_.insert(t);
4007 group->types_.push_back(t);
4008 t->priv_->group = group;
4022 if (group->canonical_types_set_.find(t) != group->types_set_.end())
4024 group->canonical_types_set_.insert(t);
4025 group->canonical_types_.push_back(t);
4026 t->priv_->group = group;
4065 return type_base_sptr();
4067 if (t->get_canonical_type())
4068 return t->get_canonical_type();
4077 string repr = t->get_cached_pretty_representation(
true);
4079 type_base_sptr result;
4082 for (
auto canonical_type :
reverse(canonical_types_))
4088 result = canonical_type;
4093#ifdef WITH_DEBUG_SELF_COMPARISON
4096 if (env.self_comparison_debug_is_on())
4101 corpus_sptr corp1, corp2;
4102 env.get_self_comparison_debug_inputs(corp1, corp2);
4113 if ((corp1->get_origin() != corp2->get_origin()
4114 && (corp2->get_origin() & corpus::NATIVE_XML_ORIGIN))
4116 check_canonical_type_from_abixml_during_self_comp(t, result))
4123 uintptr_t should_have_canonical_type = 0;
4124 string type_id = env.get_type_id_from_type(t.get());
4125 if (type_id.empty())
4126 type_id =
"type-id-<not-found>";
4128 should_have_canonical_type =
4129 env.get_canonical_type_from_type_id(type_id.c_str());
4131 std::cerr <<
"error: wrong canonical type for '"
4140 <<
"'. Should have had canonical type: "
4142 << should_have_canonical_type
4149 if (corp2->get_origin() & corpus::NATIVE_XML_ORIGIN)
4151 uintptr_t ptr_val =
reinterpret_cast<uintptr_t
>(t.get());
4152 string type_id = env.get_type_id_from_pointer(ptr_val);
4153 if (type_id.empty())
4154 type_id =
"type-id-<not-found>";
4171 std::cerr <<
"error: wrong induced canonical type for '"
4173 <<
"' from second corpus"
4174 <<
", ptr: " << std::hex << t.get()
4175 <<
" type-id: " << type_id
4183 std::cerr <<
"error: wrong induced canonical type for '"
4185 <<
"' from second corpus"
4186 <<
", ptr: " << std::hex << t.get()
4199 if (t_hash != result_hash)
4201 std::cerr <<
"error: type hash mismatch"
4202 <<
" between type: '"
4209 <<
" and its computed canonical type @"
4214 << *result->hash_value()
4227 if (!canonical_types_.empty())
4229 int canonical_type_index = 0;
4231 canonical_type_index))
4232 t->priv_->canonical_type_index = canonical_type_index;
4244thread_local string variadic_parameter_type_name =
"variadic parameter type";
4266{
return priv_->canonical_types_;}
4309 result = fl.get_artificial_value() < sl.get_artificial_value();
4317 unsigned l1 = 0, l2 = 0, c1 = 0, c2 = 0;
4356 vector<type_base_sptr>& result)
4359 result.push_back(t);
4362 std::stable_sort(result.begin(), result.end(), comp);
4374const type_base_sptr&
4377 lock_guard<mutex> lock(priv_->void_type_mutex_);
4378 if (!priv_->void_type_)
4379 priv_->void_type_.reset(
new type_decl(*
this,
4382 return priv_->void_type_;
4394const type_base_sptr&
4397 lock_guard<mutex> lock(priv_->void_pointer_type_mutex_);
4398 if (!priv_->void_pointer_type_)
4401 return priv_->void_pointer_type_;
4414const type_base_sptr&
4417 lock_guard<mutex> lock(priv_->variadic_marker_type_mutex_);
4418 if (!priv_->variadic_marker_type_)
4419 priv_->variadic_marker_type_.
4422 return priv_->variadic_marker_type_;
4431 return variadic_parameter_type_name;
4456{
return priv_->decl_only_class_equals_definition_;}
4481{priv_->decl_only_class_equals_definition_ = f;}
4586{
return const_cast<environment*
>(
this)->priv_->string_pool_.create_string(s);}
4593{
return priv_->config_;}
4603{
return priv_->analyze_exported_interfaces_only_.has_value();}
4616{priv_->analyze_exported_interfaces_only_ = f;}
4629{
return priv_->analyze_exported_interfaces_only_.value_or(
false);}
4632environment::user_set_load_all_types()
const
4633{
return priv_->load_all_types_.has_value();}
4636environment::load_all_types(
bool f)
4637{priv_->load_all_types_ = f;}
4640environment::load_all_types()
const
4641{
return priv_->load_all_types_.value_or(
false);}
4651{
return environment::priv::number_of_threads_to_use_.load();}
4663 environment::priv::number_of_threads_to_use_ =
4667#ifdef WITH_DEBUG_SELF_COMPARISON
4680environment::set_self_comparison_debug_input(
const corpus_sptr& c)
4682 self_comparison_debug_is_on(
true);
4683 if (priv_->first_self_comparison_corpus_.expired())
4684 priv_->first_self_comparison_corpus_ = c;
4685 else if (priv_->second_self_comparison_corpus_.expired()
4686 && c.get() != corpus_sptr(priv_->first_self_comparison_corpus_).get())
4687 priv_->second_self_comparison_corpus_ = c;
4700environment::get_self_comparison_debug_inputs(corpus_sptr& first_corpus,
4701 corpus_sptr& second_corpus)
4703 first_corpus = priv_->first_self_comparison_corpus_.lock();
4704 second_corpus = priv_->second_self_comparison_corpus_.lock();
4711environment::self_comparison_debug_is_on(
bool f)
4712{priv_->self_comparison_debug_on_ = f;}
4719environment::self_comparison_debug_is_on()
const
4720{
return priv_->self_comparison_debug_on_;}
4723#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
4730environment::debug_type_canonicalization_is_on(
bool flag)
4731{priv_->debug_type_canonicalization_ = flag;}
4739environment::debug_type_canonicalization_is_on()
const
4740{
return priv_->debug_type_canonicalization_;}
4748environment::debug_die_canonicalization_is_on(
bool flag)
4749{priv_->debug_die_canonicalization_ = flag;}
4757environment::debug_die_canonicalization_is_on()
const
4758{
return priv_->debug_die_canonicalization_;}
4774const vector<type_base_sptr>*
4796const vector<type_base_sptr>*
4822 if (!types ||index >= types->size())
4824 return (*types)[index].get();
4830const vector<type_base_sptr>&
4833 if (priv_->sorted_canonical_types_.empty())
4835 for (
auto& entry : priv_->canonical_types_)
4836 for (
auto t : entry.second)
4837 priv_->sorted_canonical_types_.push_back(t);
4840 std::sort(priv_->sorted_canonical_types_.begin(),
4841 priv_->sorted_canonical_types_.end(),
4845 return priv_->sorted_canonical_types_;
4848#ifdef WITH_DEBUG_SELF_COMPARISON
4858const unordered_map<string, uintptr_t>&
4859environment::get_type_id_canonical_type_map()
const
4860{
return priv_->get_type_id_canonical_type_map();}
4871unordered_map<string, uintptr_t>&
4872environment::get_type_id_canonical_type_map()
4873{
return priv_->get_type_id_canonical_type_map();}
4888const unordered_map<uintptr_t, string>&
4889environment::get_pointer_type_id_map()
const
4890{
return priv_->get_pointer_type_id_map();}
4905unordered_map<uintptr_t, string>&
4906environment::get_pointer_type_id_map()
4907{
return priv_->get_pointer_type_id_map();}
4925environment::get_type_id_from_pointer(uintptr_t ptr)
const
4926{
return priv_->get_type_id_from_pointer(ptr);}
4944environment::get_type_id_from_type(
const type_base *t)
const
4945{
return priv_->get_type_id_from_type(t);}
4962environment::get_canonical_type_from_type_id(
const char* type_id)
const
4963{
return priv_->get_canonical_type_from_type_id(type_id);}
4977 (
static_cast<unsigned>(l) |
static_cast<unsigned>(r));
4997 (
static_cast<unsigned>(l) &
static_cast<unsigned>(r));
5018 :priv_(new
priv(e, k))
5034{
return priv_->is_artificial_;}
5046{priv_->is_artificial_ = f;}
5057{
return priv_->kind();}
5077{
return priv_->rtti_;}
5086{
return priv_->rtti_;}
5098 priv_->type_or_decl_ptr_ = t;
5100 priv_->type_or_decl_ptr_ = d;
5125{
return priv_->type_or_decl_ptr_;}
5137 return priv_->hash_value_;
5141type_or_decl_base::set_hash_value(
hash_t h)
const
5142{priv_->set_hash_value(h);}
5149{
return priv_->env_;}
5167{priv_->artificial_location_ = l;}
5185{
return priv_->artificial_location_;}
5206{
return priv_->native_offset_.load();}
5217{priv_->native_offset_ = o;}
5226 return priv_->corpus_.load();
5235 priv_->corpus_ = abi_corpus;
5254 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5255 priv_->translation_unit_ = tu;
5269 if (!priv_->translation_unit_)
5272 if (
auto s = d->get_scope())
5273 priv_->translation_unit_ = s->get_translation_unit();
5275 return priv_->translation_unit_;
5297{
return priv_->original_artefact_;}
5307 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5308 priv_->original_artefact_ = o;
5336 if (priv_->internal_cached_repr_.empty())
5339 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5342 return priv_->internal_cached_repr_;
5345 if (priv_->cached_repr_.empty())
5348 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5352 return priv_->cached_repr_;
5358std::recursive_mutex&
5360{
return priv_->mutex_;}
5384 *dr =
dynamic_cast<const decl_base*
>(r);
5393 *tr =
dynamic_cast<const type_base*
>(r);
5438struct decl_base::priv
5441 recursive_mutex add_decl_to_scope_mutex_;
5444 recursive_mutex local_mutex_;
5445 bool in_pub_sym_tab_;
5448 std::atomic<context_rel*> context_;
5473 decl_base_sptr declaration_;
5475 decl_base* naked_definition_of_declaration_;
5476 std::atomic<bool> is_declaration_only_;
5477 std::list<typedef_decl_sptr> naming_typedefs_;
5480 : in_pub_sym_tab_(false),
5481 is_anonymous_(true),
5483 visibility_(VISIBILITY_DEFAULT),
5484 naked_definition_of_declaration_(),
5485 is_declaration_only_(false)
5488 priv(interned_string name, interned_string linkage_name,
visibility vis)
5489 : in_pub_sym_tab_(false),
5492 qualified_name_(name),
5493 linkage_name_(linkage_name),
5495 naked_definition_of_declaration_(),
5496 is_declaration_only_(false)
5498 is_anonymous_ = name_.
empty();
5503 delete context_.load();
5523 const string& linkage_name,
5526 priv_(new priv(e.intern(name), e.intern(linkage_name), vis))
5550 priv_(new priv(name, linkage_name, vis))
5578 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5579 return priv_->qualified_name_;
5590 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5591 priv_->qualified_name_.clear();
5600 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5601 priv_->qualified_name_ = n;
5616 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5617 return priv_->temporary_qualified_name_;
5633 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5634 priv_->temporary_qualified_name_ = n;
5643 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5644 return priv_->context_;
5653 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5654 return priv_->context_;
5660 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5661 priv_->context_ = c;
5672 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5673 return priv_->in_pub_sym_tab_;
5683 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5684 priv_->in_pub_sym_tab_ = f;
5706 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5707 return priv_->location_;
5751 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5752 priv_->location_ = l;
5762 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5764 priv_->is_anonymous_ = n.empty();
5776 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5777 return priv_->is_anonymous_;
5789 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5790 priv_->is_anonymous_ = f;
5807 return scope->get_is_anonymous();
5826list<typedef_decl_sptr>&
5829 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5830 return priv_->naming_typedefs_;
5852 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5853 priv_->naming_typedefs_.push_back(t);
5869 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5870 for (
auto t : priv_->naming_typedefs_)
5871 if (t == naming_typedef)
5883 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5884 return priv_->linkage_name_;
5894 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5895 priv_->linkage_name_ = env.
intern(m);
5904 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5905 return priv_->visibility_;
5914 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5915 priv_->visibility_ = v;
5925 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5926 if (
auto c = priv_->context_.load())
5927 return c->get_scope();
5938 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5939 return priv_->qualified_parent_name_;
5948 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5949 return priv_->name_;
5963 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
5988 bool qualified_name)
const
5992 && has_generic_anonymous_internal_type_name(
this))
6003 string name = get_generic_anonymous_internal_type_name(
this);
6033 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6034 return priv_->qualified_name_;
6050 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6051 return priv_->scoped_name_;
6061 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6062 return priv_->declaration_;
6072 if (d && d->get_is_declaration_only())
6074 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6075 priv_->declaration_ = d;
6087 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6088 return priv_->definition_of_declaration_.lock();
6106 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6107 return priv_->naked_definition_of_declaration_;
6116 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6117 return priv_->is_declaration_only_;
6128 bool update_types_lookup_map = !f && priv_->is_declaration_only_;
6131 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6132 priv_->is_declaration_only_ = f;
6135 if (update_types_lookup_map)
6138 scope_decl::declarations::iterator i;
6139 if (s->find_iterator_for_member(
this, i))
6149 return static_cast<change_kind>(
static_cast<unsigned>(l)
6150 |
static_cast<unsigned>(r));
6156 return static_cast<change_kind>(
static_cast<unsigned>(l)
6157 &
static_cast<unsigned>(r));
6203 bool rels_are_different = *r1 != *r2;
6205 if (rels_are_different)
6244 bool qualified_name,
bool linkage_name)
6250 if (!l_linkage_name.
empty() && !r_linkage_name.
empty())
6252 if (l_linkage_name != r_linkage_name)
6274 bool decls_are_same =
true;
6279 decls_are_same = (ln == rn);
6282 if (!decls_are_same)
6305{
return equals(*
this, other,
nullptr);}
6345 lock_guard<recursive_mutex> lock(priv_->local_mutex_);
6346 if (!priv_->context_.load())
6349 priv_->context_.load()->set_scope(scope);
6367 case decl_base::VISIBILITY_NONE:
6370 case decl_base::VISIBILITY_DEFAULT:
6373 case decl_base::VISIBILITY_PROTECTED:
6376 case decl_base::VISIBILITY_HIDDEN:
6379 case decl_base::VISIBILITY_INTERNAL:
6399 case decl_base::BINDING_NONE:
6402 case decl_base::BINDING_LOCAL:
6405 case decl_base::BINDING_GLOBAL:
6408 case decl_base::BINDING_WEAK:
6431 if (l.get() == r.get())
6467 if (l.get() == r.get())
6553{
return dynamic_pointer_cast<scope_decl>(d);}
6631 return c->get_access_specifier();
6661 c->set_access_specifier(a);
6691 return c->get_is_static();
6806 lock_guard<recursive_mutex> lock(klass->get_mutex());
6807 var_decl_sptr first = *klass->get_non_static_data_members().begin();
6828 if (!klass ||!data_member)
6831 lock_guard<recursive_mutex> lock(klass->
get_mutex());
6832 for (class_or_union::data_members::const_iterator it =
6836 if (**it == *data_member)
6905 bool result =
false;
6913 lock_guard<recursive_mutex> lock(cou->
get_mutex());
6924 dms[member->get_name()] = member;
7080 if (scope && scope->get_is_anonymous())
7133 return class_or_union_sptr();
7142const class_or_union_sptr
7147 if (cou->get_is_anonymous())
7150 return class_or_union_sptr();
7159const class_or_union_sptr
7164 return class_or_union_sptr();
7173const class_or_union_sptr
7188 return class_or_union_sptr();
7213 lock_guard<recursive_mutex> lock(cl->get_mutex());
7214 for (
auto anon_dm_m : cl->get_non_static_data_members())
7261 ctxt_rel->set_offset_in_bits(o);
7276 return ctxt_rel->get_offset_in_bits();
7369 uint64_t containing_anonymous_data_member_offset = 0;
7370 if (containing_anonymous_data_member)
7371 containing_anonymous_data_member_offset =
7374 return (ctxt_rel->get_offset_in_bits()
7376 containing_anonymous_data_member_offset);
7404 type_base_sptr t = v->get_type();
7407 return t->get_size_in_bits();
7421 ctxt_rel->set_is_laid_out(l);
7436 return ctxt_rel->get_is_laid_out();
7488 lock_guard<recursive_mutex> lock(f.
get_mutex());
7520 lock_guard<recursive_mutex> lock(f.
get_mutex());
7551 lock_guard<recursive_mutex> lock(f.
get_mutex());
7609 lock_guard<recursive_mutex> lock(f.
get_mutex());
7640 lock_guard<recursive_mutex> lock(f.
get_mutex());
7683 lock_guard<recursive_mutex> lock(f.
get_mutex());
7710set_member_function_vtable_offset(
function_decl& f, ssize_t s)
7717 lock_guard<recursive_mutex> lock(f.
get_mutex());
7734{
return set_member_function_vtable_offset(*f, s);}
7750 lock_guard<recursive_mutex> lock(f.
get_mutex());
7755 return ctxt->is_virtual();
7782set_member_function_is_virtual(
function_decl& f,
bool is_virtual)
7789 lock_guard<recursive_mutex> lock(f.
get_mutex());
7794 ctxt->is_virtual(is_virtual);
7807 set_member_function_is_virtual(*fn, is_virtual);
7824 set_member_function_vtable_offset(fn, voffset);
7825 set_member_function_is_virtual(fn, is_virtual);
7862 if (!cl->get_canonical_type())
7868 type_base_sptr t = type;
7874 auto typ =
type_or_void(ty->get_pointed_to_type(), env);
7879 ty->get_size_in_bits(),
7880 ty->get_alignment_in_bits(),
7881 ty->get_location()));
7888 auto typ =
type_or_void(ty->get_pointed_to_type(), env);
7892 ty->get_size_in_bits(),
7893 ty->get_alignment_in_bits(),
7894 ty->get_location()));
7901 auto typ =
type_or_void(ty->get_underlying_type(), env);
7906 ty->get_location()));
7916 t.reset(
new array_type_def(p, ty->get_subranges(), ty->get_location()));
7924 for (function_decl::parameters::const_iterator i =
7925 ty->get_parameters().begin();
7926 i != ty->get_parameters().end();
7937 p->get_variadic_marker(),
7938 p->get_is_artificial()));
7939 parm.push_back(stripped);
7944 parm, ty->get_is_const(),
7945 ty->get_size_in_bits(),
7946 ty->get_alignment_in_bits()));
7954 for (function_decl::parameters::const_iterator i =
7955 ty->get_parameters().begin();
7956 i != ty->get_parameters().end();
7967 p->get_variadic_marker(),
7968 p->get_is_artificial()));
7969 parm.push_back(stripped);
7974 ty->get_size_in_bits(),
7975 ty->get_alignment_in_bits()));
7981 if (!t->get_translation_unit())
7982 t->set_translation_unit(type->get_translation_unit());
7983 if (!t->get_corpus())
7984 t->set_corpus(type->get_corpus());
7989 return t->get_canonical_type() ? t->get_canonical_type() : t;
8012 decl_base_sptr result = t;
8013 type_base_sptr u = t->get_underlying_type();
8016 if ((t->get_cv_quals() & qualified_type_def::CV_CONST
8018 || (t->get_cv_quals() & qualified_type_def::CV_CONST
8020 || t->get_cv_quals() == qualified_type_def::CV_NONE)
8066static qualified_type_def_sptr
8067strip_redundant_quals_from_underyling_types(
const qualified_type_def_sptr& t,
8076 qualified_type_def_sptr underlying_qualified_type =
8084 currated_quals &= ~redundant_quals;
8085 t->set_cv_quals(currated_quals);
8089 redundant_quals |= currated_quals;
8091 qualified_type_def_sptr result = t;
8092 if (underlying_qualified_type)
8096 strip_redundant_quals_from_underyling_types(underlying_qualified_type,
8130strip_redundant_quals_from_underyling_types(
const qualified_type_def_sptr& t)
8136 strip_redundant_quals_from_underyling_types(t, redundant_quals);
8162 && *t->get_underlying_type() != *type)
8164 return t->get_underlying_type();
8218 return t->get_pointed_to_type();
8274 return t->get_pointed_to_type();
8399 if (t->get_cv_quals() == qualified_type_def::CV_CONST)
8432 return q->get_underlying_type();
8481 type_base_sptr type = t;
8504 type_base_sptr typ = type;
8566 bool peel_qual_type)
8605 bool peel_qual_type)
8643 vector<array_type_def::subrange_sptr> subranges;
8645 for (vector<array_type_def::subrange_sptr>::const_iterator i =
8646 array->get_subranges().begin();
8647 i != array->get_subranges().end();
8653 (*i)->get_lower_bound(),
8654 (*i)->get_upper_bound(),
8655 (*i)->get_underlying_type(),
8656 (*i)->get_location(),
8657 (*i)->get_language()));
8658 subrange->is_non_finite((*i)->is_non_finite());
8659 subrange->set_native_offset((*i)->get_native_offset());
8660 if (
auto scope = (*i)->get_scope())
8662 subranges.push_back(subrange);
8667 subranges, array->get_location()));
8668 result->set_native_offset(array->get_native_offset());
8691 (
new typedef_decl(t->get_name(), t->get_underlying_type(),
8692 t->get_location(), t->get_linkage_name(),
8693 t->get_visibility()));
8694 result->set_native_offset(0xDEADBEEF);
8710qualified_type_def_sptr
8716 qualified_type_def_sptr result
8718 t->get_cv_quals(), t->get_location()));
8730static type_base_sptr
8731clone_typedef_array_qualified_type(type_base_sptr type)
8737 type_base_sptr result;
8746 return type_base_sptr();
8769 type_base_sptr result = clone_typedef_array_qualified_type(t);
8772 type_base_sptr subtree;
8776 clone_typedef_array_qualified_type(type->get_underlying_type());
8780 type->set_underlying_type(subtree);
8786 clone_typedef_array_qualified_type(type->get_element_type());
8790 type->set_element_type(subtree);
8800 clone_typedef_array_qualified_type(t->get_underlying_type());
8807 t->set_underlying_type (s);
8816 clone_typedef_array_qualified_type(t->get_underlying_type());
8823 t->set_underlying_type(s);
8831 type_base_sptr e = t->get_element_type();
8835 clone_typedef_array_qualified_type(e);
8841 t->set_element_type(s);
8860 ::qualified_name_setter setter;
8868update_qualified_name(decl_base_sptr d)
8869{
return update_qualified_name(d.get());}
8892 return reinterpret_cast<size_t>(l);
8929{
return priv_->canonical_types_;}
8947 if (priv_->sorted_canonical_types_.empty())
8950 lock_guard<recursive_mutex> lock(
get_mutex());
8952 priv_->sorted_canonical_types_.push_back(t);
8956 std::stable_sort(priv_->sorted_canonical_types_.begin(),
8957 priv_->sorted_canonical_types_.end(),
8960 return priv_->sorted_canonical_types_;
8970{
return priv_->members_;}
8979{
return priv_->members_;}
8991 lock_guard<recursive_mutex> lock(
get_mutex());
8992 result.reserve(priv_->members_.size());
8993 for (
auto m : priv_->members_)
8994 result.push_back(m);
9008 if (priv_->sorted_members_.empty())
9011 lock_guard<recursive_mutex> lock(
get_mutex());
9013 priv_->sorted_members_.push_back(m);
9016 std::stable_sort(priv_->sorted_members_.begin(),
9017 priv_->sorted_members_.end(),
9020 return priv_->sorted_members_;
9035 if (t->get_is_anonymous())
9053 if (t->get_is_anonymous())
9071 if (t->get_is_anonymous())
9082{
return priv_->member_scopes_;}
9089{
return priv_->member_scopes_;}
9097 lock_guard<recursive_mutex> lock(
get_mutex());
9112maybe_set_translation_unit(
const decl_base_sptr& decl,
9129 decl->set_translation_unit(tu);
9152 lock_guard<recursive_mutex> lock(scope->get_mutex());
9153 member->set_scope(scope);
9154 scope->priv_->members_.push_back(member);
9157 scope->priv_->member_types_.push_back(
is_type(member));
9158 scope->priv_->clear_sorted_member_types_cache_ =
true;
9162 scope->priv_->member_scopes_.push_back(m);
9165 update_qualified_name(member);
9168 maybe_set_translation_unit(member, tu);
9180{
return priv_->member_types_;}
9192 lock_guard<recursive_mutex> lock(
get_mutex());
9196 return type_base_sptr();
9209 scope_decl::declarations::iterator before)
9216 lock_guard<recursive_mutex> lock(scope->get_mutex());
9217 scope->priv_->member_types_.push_back(t);
9218 scope->priv_->clear_sorted_member_types_cache_=
true;
9260 lock_guard<recursive_mutex> lock(
get_mutex());
9261 for (
auto i = priv_->member_types_.begin();
9262 i != priv_->member_types_.end();
9267 priv_->member_types_.erase(i);
9281 lock_guard<recursive_mutex> lock(
get_mutex());
9283 if (priv_->clear_sorted_member_types_cache_)
9285 priv_->sorted_member_types_.clear();
9286 priv_->clear_sorted_member_types_cache_ =
false;
9289 if (priv_->sorted_member_types_.empty())
9291 unordered_set<type_base_sptr> canonical_pointer_types;
9296 priv_->sorted_member_types_.push_back(t);
9297 else if (
auto c = t->get_canonical_type())
9298 canonical_pointer_types.insert(c);
9300 canonical_pointer_types.insert(t);
9303 for (
auto t : canonical_pointer_types)
9304 priv_->sorted_member_types_.push_back(t);
9307 std::stable_sort(priv_->sorted_member_types_.begin(),
9308 priv_->sorted_member_types_.end(),
9313 if (!abi || !abi->priv_->types_are_canonicalized())
9314 priv_->clear_sorted_member_types_cache_ =
true;
9316 return priv_->sorted_member_types_;
9346 decl_base_sptr member,
9347 scope_decl::declarations::iterator before)
9352 lock_guard<recursive_mutex> lock(scope->get_mutex());
9353 member->set_scope(scope);
9354 scope->priv_->members_.insert(before, member);
9359 lock_guard<recursive_mutex> lock(scope->get_mutex());
9360 scope->priv_-> member_scopes_.push_back(m);
9363 update_qualified_name(member);
9366 maybe_set_translation_unit(member, tu);
9378 decl_base_sptr member)
9381 lock_guard<recursive_mutex> lock(scope->get_mutex());
9382 for (
auto i = scope->priv_->members_.begin();
9383 i < scope->priv_->members_.end(); ++i)
9387 scope->priv_->members_.erase(i);
9390 lock_guard<recursive_mutex> lock(member->get_mutex());
9392 member->set_scope(
nullptr);
9393 member->set_translation_unit(
nullptr);
9394 update_qualified_name(member);
9404 lock_guard<recursive_mutex> lock(scope->get_mutex());
9405 for (
auto i = scope->priv_->member_scopes_.begin();
9406 i != scope->priv_->member_scopes_.end();
9411 scope->priv_->member_scopes_.erase(i);
9412 member->set_scope(
nullptr);
9413 member->set_translation_unit(
nullptr);
9414 update_qualified_name(member);
9447 if (!l.decl_base::operator==(r))
9456 scope_decl::declarations::const_iterator i, j;
9498 return equals(*
this, *other, 0);
9513 if (l.get() == r.get())
9539 declarations::iterator& i)
9544 lock_guard<recursive_mutex> lock(
get_mutex());
9555 if ((*it).get() == decl)
9575 declarations::iterator& i)
9592 if (v.visit_begin(
this))
9598 if (!(*i)->traverse(v))
9602 return v.visit_end(
this);
9605scope_decl::~scope_decl()
9618 if (!scope || !decl)
9624 lock_guard<recursive_mutex> lock(decl->priv_->add_decl_to_scope_mutex_);
9625 if (!decl->get_scope())
9650 decl->set_scope(
nullptr);
9651 decl->set_translation_unit(
nullptr);
9652 decl->set_corpus(
nullptr);
9667 scope_decl::declarations::iterator before,
9674 lock_guard<recursive_mutex> lock(decl->get_mutex());
9675 if (scope && decl && !decl->get_scope())
9686struct global_scope::priv
9701 | ABSTRACT_DECL_BASE
9702 | ABSTRACT_SCOPE_DECL),
9714 | ABSTRACT_DECL_BASE
9715 | ABSTRACT_SCOPE_DECL),
9718 priv_(new priv(nullptr))
9724global_scope::get_translation_unit()
const
9739 auto scope = decl->get_scope();
9740 while (scope && !dynamic_pointer_cast<global_scope>(scope))
9741 scope = scope->get_scope();
9743 return scope ? dynamic_pointer_cast<global_scope>(scope) :
nullptr;
9762 if (
auto d =
dynamic_cast<decl_base*
>(&type))
9821 if (scope ==
nullptr)
9827 s = decl->get_scope();
9834 if (s.get() == scope.get())
9837 while (s && !
is_global_scope(s) && s->get_scope().get() != scope.get())
9861 if (cv_quals & qualified_type_def::CV_RESTRICT)
9863 if (cv_quals & qualified_type_def::CV_CONST)
9869 if (cv_quals & qualified_type_def::CV_VOLATILE)
9921{
return get_name(tod.get(), qualified);}
9939 string qualified_name;
9941 qualified_name = scope->get_qualified_name();
9943 if (qualified_name.empty())
9944 qualified_name = name;
9946 qualified_name = qualified_name +
"::" + name;
9948 return qualified_name;
9983 location loc = decl->get_location();
9987 if (c->get_is_declaration_only() && c->get_definition_of_declaration())
9990 loc = c->get_location();
10048has_generic_anonymous_internal_type_name(
const decl_base *d)
10065static interned_string
10066get_generic_anonymous_internal_type_name(
const decl_base *d)
10068 ABG_ASSERT(has_generic_anonymous_internal_type_name(d));
10070 const environment&env = d->get_environment();
10072 interned_string result;
10105get_internal_real_type_name(
const type_base* t)
10113 real_type int_type;
10115 name = int_type.to_string(
true);
10140 return empty_string;
10147 return empty_string;
10164 r += get_generic_anonymous_internal_type_name(d);
10169 return env.
intern(get_internal_real_type_name(t));
10182 internal, qualified);
10187 return env.
intern(repr);
10227 bool qualified,
bool internal)
10230 string tn =
get_type_name(pointed_to_type, qualified, internal);
10249 bool lvalue_reference,
10250 bool qualified,
bool internal)
10254 string name =
get_type_name(pointed_to_type, qualified, internal);
10255 if (lvalue_reference)
10258 name = name +
"&&";
10260 return env.
intern(name);
10280 bool qualified,
bool internal)
10282 const environment& env = underlying_type->get_environment();
10285 string name =
get_type_name(underlying_type, qualified, internal);
10287 if (quals_repr.empty() && internal)
10299 if (!quals_repr.empty())
10305 name += quals_repr;
10308 name = quals_repr +
" " + name;
10311 return env.
intern(name);
10365 std::ostringstream o;
10374 stream_pretty_representation_of_fn_parms(fn_type, o,
10377 return env.
intern(o.str());
10414 c->get_exported_decls_builder();
10415 if (b->fn_id_maps_to_several_fns(fn))
10471 std::ostringstream o;
10490 o <<
" (" << class_type->get_qualified_name(internal) <<
"::*) ";
10491 stream_pretty_representation_of_fn_parms(fn_type, o,
10495 return env.
intern(o.str());
10661 std::ostringstream o;
10679 std::ostringstream o;
10734 const string& indent,
10737 bool qualified_names)
10740 string local_indent =
" ";
10745 if (!internal && clazz->is_struct())
10751 repr = indent +
"union";
10782 string real_indent;
10785 for (class_or_union::data_members::const_iterator dm = dmems.begin();
10789 if (dm != dmems.begin())
10794 real_indent =
"\n" + indent + local_indent;
10801 real_indent, one_line, internal, qualified_names);
10806 if (dm != dmems.begin())
10807 repr += real_indent;
10808 repr += (*dm)->get_pretty_representation(internal,
10813 real_indent+ (*dm)->get_pretty_representation(internal,
10822 repr += indent +
"}";
10850 const string& indent,
10853 bool qualified_names)
10857 internal, qualified_names);
10879 const string& indent,
10882 bool qualified_names)
10911 const string& indent,
bool one_line,
10912 bool qualified_names)
10915 std::ostringstream o;
10916 string local_indent =
" ";
10918 repr = indent +
"enum ";
10921 o << (qualified_names
10933 o <<
"\n" + indent;
10935 o << enumerator.get_name() +
"=" << enumerator.get_value() <<
", ";
10939 o <<
"\n" + indent <<
"}";
10970 const string& indent,
bool one_line,
10971 bool qualified_names)
10977 one_line, qualified_names);
11002 const string& indent,
bool one_line,
11003 bool qualified_names)
11032 const string& indent,
11035 bool qualified_name)
11041 internal, qualified_name);
11070 std::ostringstream o;
11085 o <<
" :" << std::endl;
11089 if (b->get_is_virtual())
11091 o << b->get_base_class()->get_qualified_name()
11095 o << std::hex << *h << std::dec;
11106 <<
" // translation unit: "
11111 <<
" // @: " << std::hex <<
is_type(c)
11117 o << std::hex << *h << std::dec;
11127 << member_type->get_pretty_representation(
false,
11130 if (member_type->get_canonical_type())
11132 o <<
" // uses canonical type: '@"
11133 << std::hex << member_type->get_canonical_type().get() <<
"'";
11136 o << std::hex << *h << std::dec;
11156 if (t && t->get_canonical_type())
11157 o <<
" // uses canonical type '@"
11158 << std::hex << t->get_canonical_type().get() <<
"'";
11163 o << std::hex << *h << std::dec;
11174 o <<
" // virtual member functions\n\n";
11184 o << std::hex << *h << std::dec;
11191 o <<
";" << std::endl;
11195 o <<
"};" << std::endl;
11201 string name = e->get_qualified_name();
11202 std::ostringstream o;
11203 o <<
"enum " << name
11205 << e->get_underlying_type()->get_pretty_representation(
false,
11209 <<
" // size in bits: " << e->get_size_in_bits() <<
"\n"
11210 <<
" // is-declaration-only: " << e->get_is_declaration_only() <<
"\n"
11212 <<
" // translation unit: "
11213 << e->get_translation_unit()->get_absolute_path() <<
"\n"
11214 <<
" // @: " << std::hex <<
is_type(e)
11215 <<
", @canonical: " << e->get_canonical_type().get() << std::dec <<
"\n"
11220 o << std::hex << *h << std::dec;
11226 for (
const auto &enom : e->get_enumerators())
11227 o <<
" " << enom.get_name() <<
" = " << enom.get_value() <<
",\n";
11235 std::ostringstream o;
11236 o << t->get_pretty_representation(
true,
11243 return artifact->get_pretty_representation(
true,
11342 return const_cast<type_base*
>(artifact);
11359 return const_cast<decl_base*
>(artifact);
11415{
return dynamic_cast<const decl_base*
>(t);}
11433{
return dynamic_pointer_cast<decl_base>(t);}
11449#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11450#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11453#ifdef ENSURE_NO_ENDLESS_LOOP
11454#undef ENSURE_NO_ENDLESS_LOOP
11457#define RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(VALUE) \
11460 auto t1 = is_class_or_union_type(f); \
11461 auto t2 = is_class_or_union_type(s); \
11462 t1->priv_->comparing_class_layouts_.erase(t2.get()); \
11463 t2->priv_->comparing_class_layouts_.erase(t1.get()); \
11467#define ENSURE_NO_ENDLESS_LOOP \
11470 auto t1 = is_class_or_union_type(f); \
11471 auto t2 = is_class_or_union_type(s); \
11472 const auto& END = t1->priv_->comparing_class_layouts_.end(); \
11473 if (t1->priv_->comparing_class_layouts_.find(t2.get()) != END \
11474 || t2->priv_->comparing_class_layouts_.find(t1.get()) != END) \
11476 t1->priv_->comparing_class_layouts_.insert(t2.get()); \
11477 t2->priv_->comparing_class_layouts_.insert(t1.get()); \
11485 || (fc->get_qualified_name() != sc->get_qualified_name())
11486 || (fc->get_size_in_bits() != sc->get_size_in_bits())
11487 || (fc->get_data_members().size() != sc->get_data_members().size()))
11491 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
true);
11494 for (
auto f_decl_it = fc->get_data_members().begin(),
11495 s_decl_it = sc->get_data_members().begin();
11496 (f_decl_it != fc->get_data_members().end()
11497 && s_decl_it != sc->get_data_members().end());
11498 ++f_decl_it, ++s_decl_it)
11501 type_base_sptr dm1_type = dm1->get_type(), dm2_type = dm2->get_type();
11503 if (*dm1_type != *dm2_type
11505 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
11509 for (
auto f_bs_it = fc->get_base_specifiers().begin(),
11510 s_bs_it = sc->get_base_specifiers().end();
11511 (f_bs_it != fc->get_base_specifiers().end()
11512 && s_bs_it != sc->get_base_specifiers().end());
11513 ++f_bs_it, ++s_bs_it)
11516 if ((f_bs->get_is_virtual() != s_bs->get_is_virtual())
11517 || (f_bs->get_offset_in_bits() != s_bs->get_offset_in_bits()))
11518 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
11520 class_decl_sptr fb = f_bs->get_base_class(), sb = s_bs->get_base_class();
11522 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
11525 if (fc->has_vtable() != sc->has_vtable())
11526 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
11529 ENSURE_NO_ENDLESS_LOOP;
11530 if (fc->has_vtable())
11532 if (fc->get_virtual_mem_fns().size() > sc->get_virtual_mem_fns().size())
11534 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
11536 for (
auto it1 = fc->get_virtual_mem_fns().begin(),
11537 it2 = sc->get_virtual_mem_fns().begin();
11538 (it1 != fc->get_virtual_mem_fns().end()
11539 && it2 != sc->get_virtual_mem_fns().end());
11542 method_decl_sptr method1 = *it1;
11543 method_decl_sptr method2 = *it2;
11548 method2->get_type()))
11549 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
false);
11553 RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT(
true);
11555#ifdef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11556#undef RETURN_FROM_CLASSES_HAVE_SAME_LAYOUT
11559#ifdef ENSURE_NO_ENDLESS_LOOP
11560#undef ENSURE_NO_ENDLESS_LOOP
11584 if (!type1 || !type2)
11587 if (type1 == type2 || *type1 == *type2)
11593 if (t1 && t2 && *t1 == *t2)
11617 type_base_sptr e1 = a1->get_element_type();
11618 type_base_sptr e2 = a2->get_element_type();
11622 if ((a1->get_size_in_bits() != a2->get_size_in_bits())
11623 || (a1->get_dimension_count() != a2->get_dimension_count())
11635 fn_type2->get_return_type()))
11642 if (fn_type1->get_parameters().size()
11643 != fn_type2->get_parameters().size())
11646 for (
auto p1 = fn_type1->get_first_non_implicit_parm(),
11647 p2 = fn_type2->get_first_non_implicit_parm();
11648 (p1 != fn_type1->get_parameters().end()
11649 && p2 != fn_type2->get_parameters().end());
11652 (*p2)->get_type()))
11678 const decl_base_sptr d2)
11698 auto scope = decl->get_scope();
11701 result = scope->get_translation_unit();
11704 scope = scope->get_scope();
11875 const string& name)
11880 if (!containing_class_or_union)
11897{
return (decl && dynamic_pointer_cast<template_decl>(decl->get_scope()));}
11907 return (decl && (dynamic_pointer_cast<type_tparameter>(decl)
11908 || dynamic_pointer_cast<non_type_tparameter>(decl)
11909 || dynamic_pointer_cast<template_tparameter>(decl)));
11939{
return dynamic_pointer_cast<function_decl>(d);}
11962{
return dynamic_pointer_cast<function_decl::parameter>(tod);}
11973 if (d && (d->
kind() & type_or_decl_base::ABSTRACT_DECL_BASE))
11975 if (!(d->
kind() & type_or_decl_base::ABSTRACT_TYPE_BASE))
12001{
return dynamic_pointer_cast<decl_base>(d);}
12023{
return dynamic_pointer_cast<decl_base>(t);}
12033 if (
dynamic_cast<const type_base*
>(&tod))
12058{
return dynamic_pointer_cast<type_base>(tod);}
12105 type_base_sptr utype = typedf->get_underlying_type();
12108 if (decl_base_sptr d =
is_decl(utype))
12109 for (
auto naming_typedef : d->get_naming_typedefs())
12110 if (naming_typedef.get() == typedf.get())
12140{
return dynamic_cast<const type_decl*
>(t);}
12148{
return dynamic_pointer_cast<type_decl>(t);}
12242{
return dynamic_pointer_cast<typedef_decl>(t);}
12340{
return dynamic_pointer_cast<enum_type_decl>(d);}
12409 if (t->
kind() & type_or_decl_base::CLASS_TYPE)
12423{
return dynamic_pointer_cast<class_decl>(d);}
12445 if (array->is_non_finite())
12515 if (array->get_subranges().size() == 1
12516 && array->get_subranges()[0]->get_length() == 1)
12586 return klass->get_is_declaration_only();
12635shared_ptr<class_or_union>
12637{
return dynamic_pointer_cast<class_or_union>(t);}
12666 const class_or_union_sptr& second)
12696{
return dynamic_pointer_cast<union_decl>(t);}
12710 bool look_through_qualifiers)
12716 if (look_through_qualifiers)
12734 bool look_through_qualifiers)
12736 type_base_sptr type =
is_type(t);
12737 if (look_through_qualifiers)
12739 return dynamic_pointer_cast<pointer_type_def>(type);
12882 bool look_through_qualifiers)
12888 if (look_through_qualifiers)
12905 bool look_through_qualifiers)
12909 if (look_through_qualifiers)
12926 bool look_through_qualifiers)
12928 type_base_sptr type =
is_type(t);
12929 if (look_through_qualifiers)
12931 return dynamic_pointer_cast<reference_type_def>(type);
12942 bool look_through_qualifiers)
12945 if (look_through_qualifiers)
12962 bool look_through_qualifiers)
12964 type_base_sptr type =
is_type(t);
12965 if (look_through_qualifiers)
12967 return dynamic_pointer_cast<ptr_to_mbr_type>(type);
13041const type_base_sptr
13044 type_base_sptr nil;
13048 if (t->get_environment().get_void_pointer_type().get() == t.get())
13077qualified_type_def_sptr
13079{
return dynamic_pointer_cast<qualified_type_def>(t);}
13089{
return dynamic_pointer_cast<function_type>(t);}
13119{
return dynamic_pointer_cast<method_type>(t);}
13199 decl_base_sptr decl;
13206 while (decl->get_is_declaration_only()
13207 && decl->get_definition_of_declaration())
13208 decl = decl->get_definition_of_declaration();
13275 decl_base_sptr d =
is_decl(t);
13300{
return dynamic_pointer_cast<var_decl>(decl);}
13309{
return dynamic_pointer_cast<namespace_decl>(d);}
13343 && dynamic_pointer_cast<function_decl>(decl)
13344 && dynamic_pointer_cast<template_decl>(decl->get_scope()));
13354 bool look_through_qualifiers)
13358 if (look_through_qualifiers)
13370 bool look_through_qualifiers)
13372 type_base_sptr t =
is_type(type);
13374 if (look_through_qualifiers)
13376 return dynamic_pointer_cast<array_type_def>(t);
13385qualified_type_def_sptr
13389 return qualified_type_def_sptr();
13460{
return dynamic_pointer_cast<array_type_def::subrange_type>(type);}
13470{
return decl && dynamic_pointer_cast<template_decl>(decl);}
13476 LOOKUP_ENTITY_TYPE,
13508find_next_delim_in_cplus_type(
const string& fqn,
13512 int angle_count = 0;
13513 bool found =
false;
13515 for (; i < fqn.size(); ++i)
13519 else if (fqn[i] ==
'>')
13521 else if (i + 1 < fqn.size()
13524 && fqn[i+1] ==
':')
13541 list<string>& comps)
13543 string::size_type fqn_size = fqn.size(), comp_begin = 0, comp_end = fqn_size;
13546 if (!find_next_delim_in_cplus_type(fqn, comp_begin, comp_end))
13547 comp_end = fqn_size;
13549 string comp = fqn.substr(comp_begin, comp_end - comp_begin);
13550 comps.push_back(comp);
13552 comp_begin = comp_end + 2;
13553 if (comp_begin >= fqn_size)
13569 for (list<string>::const_iterator c = comps.begin();
13572 if (c == comps.begin())
13575 result +=
"::" + *c;
13590template<
typename T>
13592iterator_is_last(T& container,
13593 typename T::const_iterator i)
13595 typename T::const_iterator next = i;
13597 return (next == container.end());
13614lookup_types_in_map(
const interned_string& type_name,
13617 istring_type_base_wptrs_map_type::const_iterator i = type_map.find(type_name);
13618 if (i != type_map.end())
13638 return lookup_type_in_map<type_decl>(type_name,
13697 return lookup_type_in_map<class_decl>(type_name,
13715 return lookup_type_in_map<union_decl>(type_name,
13750 union_decl_sptr result = lookup_type_in_map<union_decl>(loc, m);
13783 return lookup_type_in_map<enum_type_decl>(type_name,
13822 return lookup_type_in_map<typedef_decl>(type_name,
13858qualified_type_def_sptr
13863 return lookup_type_in_map<qualified_type_def>(type_name,
13882qualified_type_def_sptr
13909 return lookup_type_in_map<pointer_type_def>(type_name,
13971 return lookup_type_in_map<reference_type_def>(type_name,
13990 bool lvalue_reference,
14015 return lookup_type_in_map<array_type_def>(type_name,
14035 return lookup_type_in_map<function_type>(type_name,
14081const type_base_sptr
14085 type_base_sptr result;
14113 return lookup_type(ifqn, tu);
14124const type_base_sptr
14125lookup_type(
const type_base_sptr type,
14129 return lookup_type(type_name, tu);
14148const type_base_sptr
14152 list<string> comps;
14168 list<string> comps;
14184template<
typename NodeKind>
14186get_node_name(shared_ptr<NodeKind> node);
14196{
return node->get_name();}
14205get_node_name(type_base_sptr node)
14216{
return node->get_name();}
14225template<
typename NodeKind>
14226static decl_base_sptr
14227convert_node_to_decl(shared_ptr<NodeKind> node);
14240template<
typename NodeKind>
14242lookup_node_in_scope(
const list<string>& fqn,
14247 shared_ptr<NodeKind> node;
14248 bool it_is_last =
false;
14251 for (list<string>::const_iterator c = fqn.begin(); c != fqn.end(); ++c)
14254 it_is_last = iterator_is_last(fqn, c);
14255 lock_guard<recursive_mutex> lock(cur_scope->get_mutex());
14256 for (scope_decl::declarations::const_iterator m =
14257 cur_scope->get_member_decls().begin();
14264 scope = dynamic_pointer_cast<scope_decl>(*m);
14265 if (scope && scope->get_name() == *c)
14274 node = dynamic_pointer_cast<NodeKind>(*m);
14275 if (node && get_node_name(node) == *c)
14278 dynamic_pointer_cast<class_decl>(node))
14279 if (cl->get_is_declaration_only()
14280 && !cl->get_definition_of_declaration())
14282 resulting_decl = node;
14287 if (!new_scope && !resulting_decl)
14288 return decl_base_sptr();
14289 cur_scope = new_scope;
14292 return resulting_decl;
14313const type_base_sptr
14316{
return is_type(lookup_node_in_scope<type_base>(comps, scope));}
14340static const type_base_sptr
14342 const vector<scope_decl_sptr>& access_path,
14345 vector<scope_decl_sptr> a = access_path;
14346 type_base_sptr result;
14351 first_scope = a.back();
14352 ABG_ASSERT(first_scope->get_name() == scope->get_name());
14359 lock_guard<recursive_mutex> lock(scope->get_mutex());
14360 for (scope_decl::declarations::const_iterator i =
14361 scope->get_member_decls().begin();
14362 i != scope->get_member_decls().end();
14364 if (
is_type(*i) && (*i)->get_name() == n)
14372 first_scope = a.back();
14373 interned_string scope_name, cur_scope_name = first_scope->get_name();
14374 lock_guard<recursive_mutex> lock(scope->get_mutex());
14375 for (scope_decl::scopes::const_iterator i =
14376 scope->get_member_scopes().begin();
14377 i != scope->get_member_scopes().end();
14380 scope_name = (*i)->get_name();
14381 if (scope_name == cur_scope_name)
14407static const type_base_sptr
14412 return type_base_sptr();
14416 vector<scope_decl_sptr> access_path;
14417 for (
auto s = type_decl->get_scope();
14419 s = s->get_scope())
14421 access_path.push_back(s);
14447const type_base_sptr
14464{
return is_var_decl(lookup_node_in_scope<var_decl>(comps, skope));}
14477template<
typename NodeKind>
14479lookup_node_in_translation_unit(
const list<string>& fqn,
14497{
return is_type(lookup_node_in_translation_unit<type_base>(fqn, tu));}
14517{
return is_class_type(lookup_node_in_translation_unit<class_decl>(fqn, tu));}
14530lookup_basic_type_through_translation_units(
const interned_string& type_name,
14531 const corpus& abi_corpus)
14535 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14536 for (translation_units::const_iterator tu =
14556static union_decl_sptr
14557lookup_union_type_through_translation_units(
const interned_string& type_name,
14558 const corpus & abi_corpus)
14560 union_decl_sptr result;
14562 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14563 for (translation_units::const_iterator tu =
14564 abi_corpus.get_translation_units().begin();
14565 tu != abi_corpus.get_translation_units().end();
14584lookup_enum_type_through_translation_units(
const interned_string& type_name,
14585 const corpus & abi_corpus)
14589 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14590 for (translation_units::const_iterator tu =
14591 abi_corpus.get_translation_units().begin();
14592 tu != abi_corpus.get_translation_units().end();
14609lookup_typedef_type_through_translation_units(
const interned_string& type_name,
14610 const corpus & abi_corpus)
14614 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14615 for (translation_units::const_iterator tu =
14616 abi_corpus.get_translation_units().begin();
14617 tu != abi_corpus.get_translation_units().end();
14634static qualified_type_def_sptr
14635lookup_qualified_type_through_translation_units(
const interned_string& t_name,
14636 const corpus & abi_corpus)
14638 qualified_type_def_sptr result;
14640 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14641 for (translation_units::const_iterator tu =
14642 abi_corpus.get_translation_units().begin();
14643 tu != abi_corpus.get_translation_units().end();
14661lookup_pointer_type_through_translation_units(
const interned_string& type_name,
14662 const corpus & abi_corpus)
14666 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14667 for (translation_units::const_iterator tu =
14668 abi_corpus.get_translation_units().begin();
14669 tu != abi_corpus.get_translation_units().end();
14687lookup_reference_type_through_translation_units(
const interned_string& t_name,
14688 const corpus & abi_corpus)
14692 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14693 for (translation_units::const_iterator tu =
14694 abi_corpus.get_translation_units().begin();
14695 tu != abi_corpus.get_translation_units().end();
14713lookup_array_type_through_translation_units(
const interned_string& type_name,
14714 const corpus & abi_corpus)
14718 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14719 for (translation_units::const_iterator tu =
14720 abi_corpus.get_translation_units().begin();
14721 tu != abi_corpus.get_translation_units().end();
14739lookup_function_type_through_translation_units(
const interned_string& type_name,
14740 const corpus & abi_corpus)
14744 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14745 for (translation_units::const_iterator tu =
14746 abi_corpus.get_translation_units().begin();
14747 tu != abi_corpus.get_translation_units().end();
14765 const corpus& abi_corpus)
14767 type_base_sptr result;
14769 lock_guard<recursive_mutex> lock(abi_corpus.priv_->get_mutex());
14770 for (translation_units::const_iterator tu =
14774 if ((result = lookup_type(qn, **tu)))
14791 const string& tu_path,
14794 string_tu_map_type::const_iterator i = corp.priv_->path_tu_map.find(tu_path);
14795 if (i == corp.priv_->path_tu_map.end())
14796 return type_base_sptr();
14801 type_base_sptr t = lookup_type(type_name, *tu);
14822 lock_guard<recursive_mutex> lock(
corpus.priv_->get_mutex());
14826 for (translation_units::const_iterator i =
14872 result = lookup_type_in_map<type_decl>(qualified_name, m);
14874 result = lookup_basic_type_through_translation_units(qualified_name, corp);
14894 result = lookup_type_in_map<type_decl>(loc, m);
14985 class_decl_sptr result = lookup_type_in_map<class_decl>(qualified_name, m);
15003 return lookup_types_in_map(qualified_name, m);
15017 if (!qualified_name)
15047 for (
auto type : *v)
15049 type_base_sptr t(type);
15051 if (c->get_is_declaration_only()
15052 && !c->get_definition_of_declaration())
15053 result.push_back(type);
15056 return !result.empty();
15072 return lookup_types_in_map(qualified_name, m);
15153 union_decl_sptr result = lookup_type_in_map<union_decl>(type_name, m);
15155 result = lookup_union_type_through_translation_units(type_name, corp);
15234 lookup_type_in_map<enum_type_decl>(qualified_name, m);
15236 result = lookup_enum_type_through_translation_units(qualified_name, corp);
15254 return lookup_types_in_map(qualified_name, m);
15283 if (!qualified_name)
15286 string qname(qualified_name);
15377 lookup_type_in_map<typedef_decl>(qualified_name, m);
15379 result = lookup_typedef_type_through_translation_units(qualified_name,
15386lookup_typedef_types(
const string& name,
const corpus& corp)
15390 return lookup_types_in_map(n, m);
15394lookup_typedef_types(
char* name,
const corpus& corp)
15400 return lookup_typedef_types(n, corp);
15450 type_base_sptr result = lookup_type<class_decl>(qualified_name, corp);
15452 result = lookup_type<union_decl>(qualified_name, corp);
15455 result = lookup_type<typedef_decl>(qualified_name, corp);
15492qualified_type_def_sptr
15507qualified_type_def_sptr
15513 qualified_type_def_sptr result =
15514 lookup_type_in_map<qualified_type_def>(qualified_name, m);
15517 result = lookup_qualified_type_through_translation_units(qualified_name,
15559 lookup_type_in_map<pointer_type_def>(qualified_name, m);
15561 result = lookup_pointer_type_through_translation_units(qualified_name,
15609 lookup_type_in_map<reference_type_def>(qualified_name, m);
15611 result = lookup_reference_type_through_translation_units(qualified_name,
15658 lookup_type_in_map<array_type_def>(qualified_name, m);
15660 result = lookup_array_type_through_translation_units(qualified_name, corp);
15729 lookup_type_in_map<function_type>(qualified_name, m);
15731 result = lookup_function_type_through_translation_units(qualified_name,
15754 type_base_sptr result;
15771lookup_type(
const string& name,
const corpus& corp)
15774 return lookup_type(n, corp);
15778lookup_type(
char* name,
const corpus& corp)
15783 interned_string i = corp.get_environment().intern(n);
15784 return lookup_type(i, corp);
15804 type_base_sptr result;
15831 return lookup_type(n, corp);
15848lookup_type(
const type_base_sptr&t,
const corpus& corp)
15851 return lookup_type(*t, corp);
15852 return type_base_sptr();
15855template<
typename TypeKind>
15859 const shared_ptr<TypeKind> type,
15860 recursive_mutex& mutex)
15862 bool result =
false;
15864 lock_guard<recursive_mutex> lock(mutex);
15865 istring_type_base_wptrs_map_type::iterator i = types_map.find(key);
15867 if (i == types_map.end())
15869 types_map[key].push_back(type);
15873 i->second.push_back(type);
15892template<
typename TypeKind>
15896 recursive_mutex& mutex,
15897 bool use_type_name_as_key =
true)
15901 if (use_type_name_as_key)
15905 string str = l.expand();
15906 s = type->get_environment().intern(str);
15910 bool result =
false;
15911 result |= update_type_lookup_map(types_map, s, type, mutex);
15913 s = type->get_environment().intern(repr);
15914 result |= update_type_lookup_map(types_map, s, type, mutex);
15935 recursive_mutex& mutex,
15936 bool use_type_name_as_key)
15940 bool update_qname_map =
true;
15941 if (type->get_is_declaration_only())
15947 is_class_type(class_type->get_definition_of_declaration()))
15951 if (!update_qname_map)
15955 if (use_type_name_as_key)
15957 string qname = type->get_qualified_name();
15958 s = type->get_environment().intern(qname);
15960 else if (
location l = type->get_location())
15962 string str = l.expand();
15963 s = type->get_environment().intern(str);
15966 return update_type_lookup_map(map, s, type, mutex);
15988 recursive_mutex& mutex,
15992 return update_type_lookup_map(types_map, s, type, mutex);
16003template <
typename TypeArtifact>
16008 if (
auto m = tu->
get_types().get_type_map(
typeid(*type.get())))
16009 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16010 tu->priv_->types_mutex_);
16012 if (
corpus *c = type->get_corpus())
16014 if (
auto m = c->priv_->get_types().get_type_map(
typeid(*type.get())))
16015 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16016 c->priv_->get_mutex());
16018 if (
auto m = c->get_type_per_loc_map().get_type_map(
typeid(*type.get())))
16019 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16020 c->priv_->get_mutex(),
16025 if (
auto m = g->priv_->get_types().get_type_map(
typeid(*type.get())))
16026 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16027 c->priv_->get_mutex());
16029 if (
auto m = g->get_type_per_loc_map().get_type_map(
typeid(*type.get())))
16030 maybe_update_types_lookup_map<TypeArtifact>(type, *m,
16031 c->priv_->get_mutex(),
16044 type_base_sptr type =
is_type(decl);
16048 maybe_update_types_lookup_map<type_base>(type);
16072 type_base_sptr result;
16074 result = lookup_type(type, tu);
16080 type_base_sptr underlying_type =
16083 if (underlying_type)
16086 qual->get_cv_quals(),
16087 qual->get_location()));
16092 type_base_sptr pointed_to_type =
16095 if (pointed_to_type)
16098 p->get_size_in_bits(),
16099 p->get_alignment_in_bits(),
16100 p->get_location()));
16105 type_base_sptr pointed_to_type =
16107 if (pointed_to_type)
16111 r->get_size_in_bits(),
16112 r->get_alignment_in_bits(),
16113 r->get_location()));
16127 tu.priv_->synthesized_types_.push_back(result);
16160 type_base_sptr result_return_type;
16165 if (!result_return_type)
16169 type_base_sptr parm_type;
16171 for (function_type::parameters::const_iterator i =
16176 type_base_sptr t = (*i)->get_type();
16183 (*i)->get_location(),
16184 (*i)->get_variadic_marker(),
16185 (*i)->get_is_artificial()));
16186 parms.push_back(parm);
16189 class_or_union_sptr class_type;
16201 result_fn_type.reset(
new method_type(result_return_type,
16213 tu.priv_->synthesized_types_.push_back(result_fn_type);
16218 return result_fn_type;
16229 if (mangled_name.empty())
16234 char * str = abi::__cxa_demangle(mangled_name.c_str(),
16235 NULL, &l, &status);
16236 string demangled_name = mangled_name;
16240 demangled_name = str;
16244 return demangled_name;
16269global_scope::~global_scope()
16283decls_have_naming_typedefs_same_name(decl_base& d1, decl_base& d2)
16285 for (
auto typedef1 : d1.get_naming_typedefs())
16286 for (auto typedef2 : d2.get_naming_typedefs())
16310types_defined_same_linux_kernel_corpus_public(
const type_base& t1,
16311 const type_base& t2)
16313 const corpus *t1_corpus = t1.get_corpus(), *t2_corpus = t2.get_corpus();
16314 string t1_file_path, t2_file_path;
16318 if (!(t1_corpus && t2_corpus
16319 && t1_corpus == t2_corpus
16320 && (t1_corpus->get_origin() & corpus::LINUX_KERNEL_BINARY_ORIGIN)
16325 class_or_union *c1 = 0, *c2 = 0;
16331 if ((c1 && c1->get_is_anonymous() && c1->get_naming_typedefs().empty())
16332 || (c2 && c2->get_is_anonymous() && c2->get_naming_typedefs().empty()))
16339 && c1->get_is_anonymous() && !c1->get_naming_typedefs().empty()
16340 && c2->get_is_anonymous() && !c2->get_naming_typedefs().empty())
16341 if (!decls_have_naming_typedefs_same_name(*c1, *c2))
16347 if (e1->get_is_anonymous() || e2->get_is_anonymous())
16357 if (c1->get_is_declaration_only() != c2->get_is_declaration_only())
16359 if (c1->get_environment().decl_only_class_equals_definition())
16369 if (t1.get_size_in_bits() != t2.get_size_in_bits())
16383 l = c1->get_location();
16385 l =
dynamic_cast<const decl_base&
>(t1).
get_location();
16387 unsigned line = 0, col = 0;
16389 l.
expand(t1_file_path, line, col);
16391 l = c2->get_location();
16393 l =
dynamic_cast<const decl_base&
>(t2).
get_location();
16395 l.
expand(t2_file_path, line, col);
16398 if (t1_file_path.empty() || t2_file_path.empty())
16401 if (t1_file_path == t2_file_path)
16437compare_types_during_canonicalization(
const type_base& canonical_type,
16438 const type_base& candidate_type)
16440#ifdef WITH_DEBUG_TYPE_CANONICALIZATION
16441 const environment& env = canonical_type.get_environment();
16442 if (env.debug_type_canonicalization_is_on())
16444 bool canonical_equality =
false, structural_equality =
false;
16445 env.priv_->allow_type_comparison_results_caching(
false);
16446 env.priv_->use_canonical_type_comparison_ =
false;
16447 structural_equality = canonical_type == candidate_type;
16448 env.priv_->use_canonical_type_comparison_ =
true;
16449 canonical_equality = canonical_type == candidate_type;
16450 env.priv_->allow_type_comparison_results_caching(
true);
16451 if (canonical_equality != structural_equality)
16453 std::cerr <<
"structural & canonical equality different for type: "
16454 << canonical_type.get_pretty_representation(
true,
true)
16458 return structural_equality;
16461 return canonical_type == candidate_type;
16488 bool equal = (types_defined_same_linux_kernel_corpus_public(canonical_type,
16490 || compare_types_during_canonicalization(canonical_type,
16552 const type_base_sptr& candidate_type)
16555 candidate_type.get());
16589 for (
const auto& c : cncls)
16598#ifdef WITH_DEBUG_SELF_COMPARISON
16603 std::cerr <<
"error: wrong canonical type comparison result despite types "
16604 <<
"having the same hash value: "
16605 <<
" type:" << std::hex << &type
16606 <<
", canonical type candidate:" << std::hex << c
16608 <<
"' string repr: " << type.get_pretty_representation()
16616 for (
const auto& c :
reverse(cncls))
16685 const type_base_sptr canonical_type,
16686 int& resulting_index)
16688 if (!canonical_type)
16692 bool found =
false;
16694 if (!reference_hash)
16697 for (
auto ctype : adjacent_canonical_types)
16700 if (*h == *reference_hash)
16709 resulting_index = result;
16739 const type_base_sptr& type)
16741 if (canonical.get() == type.get())
16749 lock_guard<recursive_mutex> lock(cou->get_mutex());
16773 if (canonical_class
16774 && canonical_class.get() != cl.get()
16775 && canonical_class->get_corpus() == cl->get_corpus())
16779 auto mem_fns = cl->get_member_functions_copy();
16780 for (
auto mem_fn : mem_fns)
16781 if (mem_fn->get_symbol())
16783 string n = mem_fn->get_linkage_name();
16785 n = mem_fn->get_name();
16788 lock_guard<recursive_mutex> lock(canonical_class->get_mutex());
16789 method_decl *m = canonical_class->find_member_function(n);
16792 if (!mem_fn->get_linkage_name().empty())
16795 m = canonical_class->find_member_function(n);
16809 && canonical_class->get_corpus()
16810 && cl->get_corpus()
16811 && (cl->get_corpus() == canonical_class->get_corpus()))
16826 auto data_members = cl->get_data_members_copy();
16827 for (
auto data_member : data_members)
16835 auto canonical_data_member =
16836 canonical_class->find_data_member(data_member->get_name());
16837 if (!canonical_data_member)
16840 if (!canonical_data_member->get_symbol())
16841 canonical_data_member->set_symbol(sym);
16857 canonical_class = cl;
16860 if (canonical_class)
16862 lock_guard<recursive_mutex> lock(canonical_class->get_mutex());
16864 if (
auto abi_corpus = canonical_class->get_corpus())
16866 for (
auto fn : canonical_class->get_member_functions())
16872 fn->set_is_in_public_symbol_table(
true);
16873 auto b = abi_corpus->get_exported_decls_builder();
16874 b->maybe_add_fn_to_exported_fns(fn.get(),
16879 lock_guard<recursive_mutex> lock(abi_corpus->priv_->mutex_);
16880 abi_corpus->get_undefined_functions().insert(fn.get());
16893 if (type->get_is_artificial() != canonical->get_is_artificial())
16894 canonical->set_is_artificial(
false);
16896 type->on_canonical_type_set();
16926 bool do_log,
bool show_stats)
16931 if (t->get_canonical_type())
16932 return t->get_canonical_type();
16936 if (do_log && show_stats)
16937 std::cerr <<
"Canonicalization of type '"
16938 << t->get_pretty_representation(
true,
true)
16939 <<
"/@#" << std::hex << t.get() <<
": ";
16943 if (do_log && show_stats)
16946 type_base_sptr canonical = group->get_canonical_type_for(t, group);
16948 if (do_log && show_stats)
16951 if (do_log && show_stats)
16952 std::cerr << tmr <<
"\n";
16955 lock_guard<recursive_mutex> lock(t->priv_->mutex);
16956 t->priv_->canonical_type = canonical;
16961 if (!t->priv_->canonical_type_index)
16962 t->priv_->canonical_type_index = canonical->priv_->canonical_type_index;
16968 lock_guard<recursive_mutex> lock(t->priv_->mutex);
16969 t->priv_->naked_canonical_type = canonical.get();
16973 if (type_base_sptr d =
is_type(cl->get_earlier_declaration()))
16974 if ((canonical = d->get_canonical_type()))
16976 d->priv_->canonical_type = canonical;
16977 d->priv_->naked_canonical_type = canonical.get();
16984 auto scope = d->get_scope();
16994 if (type_base_sptr c =
is_type(scope)->get_canonical_type())
17002 lock_guard<recursive_mutex> lock(scope->get_mutex());
17003 scope->get_canonical_types().insert(canonical);
17004 scope->priv_->sorted_canonical_types_.clear();
17028 auto& env = t->get_environment();
17029 auto group = env.priv_->types_partition_.get_or_create_type_group(t);
17048 bool do_log,
bool show_stats)
17050 if (groups.empty())
17060 std::cerr <<
"Types are broken into " << groups.size() <<
" groups ...\n";
17061 std::cerr <<
"Going to use " << num_workers <<
" threads to canonicalize them ...\n";
17065 queue task_queue(num_workers);
17068 for (
auto type_group : groups)
17077 const vector<task_sptr>& completed_tasks =
17083 std::cerr <<
"Canonicalizing of types DONE in: " << tmr <<
"\n\n";
17087 std::cerr <<
"Details about homonym type groups c14n ...\n";
17088 for (
auto task : completed_tasks)
17092 std::cerr << t->log_message << std::endl;
17094 std::cerr <<
"Details about homonym type groups c14n DONE\n";
17106 priv_->definition_of_declaration_ = d;
17108 if (type_base_sptr canonical_type =
is_type(d)->get_canonical_type())
17109 t->priv_->canonical_type = canonical_type;
17111 priv_->naked_definition_of_declaration_ =
const_cast<decl_base*
>(d.get());
17121 priv_(new
priv(s, a))
17135 return do_hash(
this);
17148 lock_guard<recursive_mutex> lock(priv_->mutex);
17149 return priv_->canonical_type.lock();
17167 lock_guard<recursive_mutex> lock(priv_->mutex);
17168 return priv_->naked_canonical_type;
17199 ABG_RETURN(result);
17207{
return equals(*
this, other, 0);}
17225 lock_guard<recursive_mutex> lock(priv_->mutex);
17226 priv_->size_in_bits = s;
17235 lock_guard<recursive_mutex> lock(priv_->mutex);
17236 return priv_->size_in_bits;
17245 lock_guard<recursive_mutex> lock(priv_->mutex);
17246 priv_->alignment_in_bits = a;
17255 lock_guard<recursive_mutex> lock(priv_->mutex);
17256 return priv_->alignment_in_bits;
17273 v.visit_begin(
this);
17274 bool result = v.visit_end(
this);
17280type_base::~type_base()
17299 static_cast<unsigned>(r));
17314 static_cast<unsigned>(r));
17371parse_real_type_modifier(
const string& word,
17374 if (word ==
"signed")
17376 else if (word ==
"unsigned")
17378 else if (word ==
"short")
17380 else if (word ==
"long")
17382 else if (word ==
"long long")
17400parse_base_real_type(
const string& type_name,
17403 if (type_name ==
"int")
17405 else if (type_name ==
"char")
17407 else if (type_name ==
"bool" || type_name ==
"_Bool")
17409 else if (type_name ==
"double")
17411 else if (type_name ==
"float")
17413 else if (type_name ==
"char16_t")
17415 else if (type_name ==
"char32_t")
17417 else if (type_name ==
"wchar_t")
17419 else if (type_name ==
"__ARRAY_SIZE_TYPE__")
17421 else if (type_name ==
"sizetype")
17422 base = real_type::SIZE_BASE_TYPE;
17423 else if (type_name ==
"ssizetype")
17424 base = real_type::SSIZE_BASE_TYPE;
17425 else if (type_name ==
"bitsizetype")
17426 base = real_type::BIT_SIZE_BASE_TYPE;
17427 else if (type_name ==
"sbitsizetype")
17428 base = real_type::SBIT_SIZE_BASE_TYPE;
17452 string input = type_name;
17453 string::size_type len = input.length();
17454 string::size_type cur_pos = 0, prev_pos = 0;
17455 string cur_word, prev_word;
17458 while (cur_pos < len)
17460 if (cur_pos < len && isspace(input[cur_pos]))
17463 while (cur_pos < len && isspace(input[cur_pos]));
17465 prev_pos = cur_pos;
17466 cur_pos = input.find(
' ', prev_pos);
17467 prev_word = cur_word;
17468 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
17471 && cur_word ==
"long"
17472 && prev_word !=
"long")
17474 if (cur_pos < len && isspace(input[cur_pos]))
17477 while (cur_pos < len && isspace(input[cur_pos]));
17478 prev_pos = cur_pos;
17480 cur_pos = input.find(
' ', prev_pos);
17481 string saved_prev_word = prev_word;
17482 prev_word = cur_word;
17483 cur_word = input.substr(prev_pos, cur_pos - prev_pos);
17484 if (cur_word ==
"long")
17485 cur_word =
"long long";
17488 cur_pos = prev_pos;
17489 cur_word = prev_word;
17490 prev_word = saved_prev_word;
17494 if (!parse_real_type_modifier(cur_word, modifiers))
17496 if (!parse_base_real_type(cur_word, base))
17527 real_type int_type(base_type, modifiers);
17534 : base_(INT_BASE_TYPE),
17535 modifiers_(NO_MODIFIER)
17544 : base_(b), modifiers_(m)
17552 : base_(INT_BASE_TYPE),
17553 modifiers_(NO_MODIFIER)
17571{
return modifiers_;}
17588{
return base_ == other.base_ && modifiers_ == other.modifiers_;}
17606 result +=
"signed ";
17608 result +=
"unsigned ";
17619 result +=
"short ";
17623 result +=
"long long ";
17634 result +=
"double";
17638 result +=
"char16_t";
17640 result +=
"char32_t";
17642 result +=
"wchar_t";
17644 result +=
"__ARRAY_SIZE_TYPE__";
17645 else if (base_ == SIZE_BASE_TYPE)
17646 result +=
"sizetype";
17647 else if (base_ == SSIZE_BASE_TYPE)
17648 result +=
"ssizetype";
17649 else if (base_ == BIT_SIZE_BASE_TYPE)
17650 result +=
"bitsizetype";
17651 else if (base_ == SBIT_SIZE_BASE_TYPE)
17652 result +=
"sbitsizetype";
17661real_type::operator string()
const
17662{
return to_string();}
17685 const string& name,
17686 size_t size_in_bits,
17687 size_t alignment_in_bits,
17689 const string& linkage_name,
17694 | ABSTRACT_TYPE_BASE
17695 | ABSTRACT_DECL_BASE),
17696 decl_base(env, name, locus, linkage_name, vis),
17697 type_base(env, size_in_bits, alignment_in_bits)
17703 real_type int_type(base_type, modifiers);
17708 string real_type_name = int_type;
17756 bool result =
false;
17771 ABG_RETURN(result);
17787 return *
this == *other;
17815 return *
this == other;
17861 if (l.get() == r.get())
17889 bool internal)
const
17913 if (decl_base::priv_->internal_qualified_name_.
empty())
17914 decl_base::priv_->internal_qualified_name_ =
17915 env.
intern(get_internal_real_type_name(
this));
17916 return decl_base::priv_->internal_qualified_name_;
17920 decl_base::priv_->temporary_internal_qualified_name_ =
17921 env.
intern(get_internal_real_type_name(
this));
17922 return decl_base::priv_->temporary_internal_qualified_name_;
17948 bool qualified_name)
const
17952 return get_internal_real_type_name(
this);
17954 if (qualified_name)
17972 v.visit_begin(
this);
17973 bool result = v.visit_end(
this);
17979type_decl::~type_decl()
17999 const string& name,
18000 size_t size_in_bits,
18001 size_t alignment_in_bits,
18005 ABSTRACT_SCOPE_TYPE_DECL
18006 | ABSTRACT_TYPE_BASE
18007 | ABSTRACT_DECL_BASE),
18009 type_base(env, size_in_bits, alignment_in_bits),
18046 ABG_RETURN(result);
18078 return *
this == *other;
18102 if (v.visit_begin(
this))
18108 if (!(*i)->traverse(v))
18113 bool result = v.visit_end(
this);
18119scope_type_decl::~scope_type_decl()
18135 const string& name,
18146 | ABSTRACT_DECL_BASE
18147 | ABSTRACT_SCOPE_DECL),
18173 bool qualified_name)
const
18176 "namespace " + scope_decl::get_pretty_representation(internal,
18215 if (!ns->is_empty_or_has_empty_sub_namespaces())
18236 if (v.visit_begin(
this))
18240 for (
auto m : decls)
18243 dynamic_pointer_cast<ir_traversable_base>(m);
18245 if (!t->traverse (v))
18250 return v.visit_end(
this);
18253namespace_decl::~namespace_decl()
18262class qualified_type_def::priv
18277 : cv_quals_(CV_NONE)
18282 : cv_quals_(quals),
18283 underlying_type_(t)
18335qualified_type_def::qualified_type_def(type_base_sptr type,
18340 | ABSTRACT_TYPE_BASE
18341 | ABSTRACT_DECL_BASE),
18342 type_base(type->get_environment(), type->get_size_in_bits(),
18343 type->get_alignment_in_bits()),
18344 decl_base(type->get_environment(),
"", locus,
"",
18345 dynamic_pointer_cast<
decl_base>(type)->get_visibility()),
18346 priv_(new priv(quals, type))
18365 | ABSTRACT_TYPE_BASE
18366 | ABSTRACT_DECL_BASE),
18370 priv_(new priv(quals))
18407 s = ut->get_size_in_bits();
18436 bool result =
true;
18468 ABG_RETURN(result);
18503 return *
this == *other;
18521 return *
this == *other;
18536 bool internal)
const
18564 priv_->temporary_internal_name_ =
18566 return priv_->temporary_internal_name_;
18582 if (priv_->internal_name_.empty())
18583 priv_->internal_name_ =
18586 return priv_->internal_name_;
18615 if (v.visit_begin(
this))
18622 bool result = v.visit_end(
this);
18627qualified_type_def::~qualified_type_def()
18635 lock_guard<mutex> lock(priv_->mutex_);
18636 return priv_->cv_quals_;
18643 lock_guard<mutex> lock(priv_->mutex_);
18644 priv_->cv_quals_ = cv_quals;
18660 lock_guard<mutex> lock(priv_->mutex_);
18661 return priv_->underlying_type_.lock();
18671 lock_guard<mutex> lock(priv_->mutex_);
18673 priv_->underlying_type_ = t;
18686 scope_decl::declarations::iterator i;
18687 if (s->find_iterator_for_member(
this, i))
18702operator==(
const qualified_type_def_sptr& l,
const qualified_type_def_sptr& r)
18704 if (l.get() == r.get())
18720operator!=(
const qualified_type_def_sptr& l,
const qualified_type_def_sptr& r)
18728 (
static_cast<unsigned>(lhs) |
static_cast<unsigned>(rhs));
18752 (
static_cast<unsigned>(lhs) &
static_cast<unsigned>(rhs));
18774 case qualified_type_def::CV_NONE:
18777 case qualified_type_def::CV_CONST:
18780 case qualified_type_def::CV_VOLATILE:
18783 case qualified_type_def::CV_RESTRICT:
18797struct pointer_type_def::priv
18804 priv(
const type_base_sptr& t)
18806 naked_pointed_to_type_(t.get())
18810 : naked_pointed_to_type_()
18835pointer_type_def::pointer_type_def(
const type_base_sptr& pointed_to,
18836 size_t size_in_bits,
18837 size_t align_in_bits,
18841 | ABSTRACT_TYPE_BASE
18842 | ABSTRACT_DECL_BASE),
18843 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
18844 decl_base(pointed_to->get_environment(),
"", locus,
""),
18845 priv_(new priv(pointed_to))
18851 const environment& env = pointed_to->get_environment();
18852 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
18853 string name = (pto ? pto->get_name() : string(
"void")) +
"*";
18871pointer_type_def::pointer_type_def(
const environment& env,
size_t size_in_bits,
18872 size_t alignment_in_bits,
18876 | ABSTRACT_TYPE_BASE
18877 | ABSTRACT_DECL_BASE),
18878 type_base(env, size_in_bits, alignment_in_bits),
18883 string name = string(
"void") +
"*";
18908 priv_->pointed_to_type_ = t;
18909 priv_->naked_pointed_to_type_ = t.get();
18914 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(t);
18915 string name = (pto ? pto->get_name() : string(
"void")) +
"*";
18947 bool result = p1 == p2;
18960 ABG_RETURN(result);
18990 return *
this == *o;
19011const type_base_sptr
19013{
return priv_->pointed_to_type_.lock();}
19020{
return priv_->naked_pointed_to_type_;}
19058 if (priv_->internal_qualified_name_.empty())
19059 if (pointed_to_type)
19060 priv_->internal_qualified_name_ =
19061 pointer_declaration_name(
this,
19068 return priv_->internal_qualified_name_;
19076 priv_->temp_internal_qualified_name_ =
19077 pointer_declaration_name(
this,
19084 return priv_->temp_internal_qualified_name_;
19093 (pointer_declaration_name(
this,
19105 if (pointed_to_type)
19107 (pointer_declaration_name(
this,
19132 if (v.visit_begin(
this))
19140 bool result = v.visit_end(
this);
19145pointer_type_def::~pointer_type_def()
19162 if (l.get() == r.get())
19190struct reference_type_def::priv
19198 priv(
const type_base_sptr& t,
bool is_lvalue)
19200 is_lvalue_(is_lvalue)
19203 priv(
bool is_lvalue)
19204 : is_lvalue_(is_lvalue)
19233reference_type_def::reference_type_def(
const type_base_sptr pointed_to,
19235 size_t size_in_bits,
19236 size_t align_in_bits,
19240 | ABSTRACT_TYPE_BASE
19241 | ABSTRACT_DECL_BASE),
19242 type_base(pointed_to->get_environment(), size_in_bits, align_in_bits),
19243 decl_base(pointed_to->get_environment(),
"", locus,
""),
19244 priv_(new priv(pointed_to, lvalue))
19250 decl_base_sptr pto = dynamic_pointer_cast<decl_base>(pointed_to);
19255 name = string(pto->get_name()) +
"&";
19263 const environment& env = pointed_to->get_environment();
19287reference_type_def::reference_type_def(
const environment& env,
bool lvalue,
19288 size_t size_in_bits,
19289 size_t alignment_in_bits,
19293 | ABSTRACT_TYPE_BASE
19294 | ABSTRACT_DECL_BASE),
19295 type_base(env, size_in_bits, alignment_in_bits),
19297 priv_(new priv(lvalue))
19300 string name =
"void&";
19329 priv_->pointed_to_type_ = pointed_to_type;
19331 decl_base_sptr pto;
19333 {pto = dynamic_pointer_cast<decl_base>(pointed_to_type);}
19340 string name = string(pto->get_name()) +
"&";
19370 if (l.is_lvalue() != r.is_lvalue())
19376 type_base_sptr p1 = l.get_pointed_to_type(), p2 = r.get_pointed_to_type();
19377 bool result = p1 == p2;
19385 ABG_RETURN(result);
19416 return *
this == *other;
19431 return *
this == *other;
19435reference_type_def::get_pointed_to_type()
const
19436{
return priv_->pointed_to_type_.lock();}
19439reference_type_def::is_lvalue()
const
19440{
return priv_->is_lvalue_;}
19470 type_base_sptr pointed_to_type = get_pointed_to_type();
19477 if (priv_->internal_qualified_name_.empty())
19478 if (pointed_to_type)
19479 priv_->internal_qualified_name_ =
19487 return priv_->internal_qualified_name_;
19495 priv_->temp_internal_qualified_name_ =
19503 return priv_->temp_internal_qualified_name_;
19523 if (pointed_to_type)
19553 bool qualified_name)
const
19557 (get_pointed_to_type()),
19581 if (v.visit_begin(
this))
19584 if (type_base_sptr t = get_pointed_to_type())
19589 bool result = v.visit_end(
this);
19594reference_type_def::~reference_type_def()
19611 if (l.get() == r.get())
19639struct ptr_to_mbr_type::priv
19643 type_base_sptr dm_type_;
19646 type_base_sptr containing_type_;
19653 priv(
const type_base_sptr& dm_type,
const type_base_sptr& containing_type)
19654 : dm_type_(dm_type),
19655 containing_type_(containing_type)
19677 const type_base_sptr& member_type,
19678 const type_base_sptr& containing_type,
19679 size_t size_in_bits,
19680 size_t alignment_in_bits,
19683 POINTER_TO_MEMBER_TYPE
19684 | ABSTRACT_TYPE_BASE
19685 | ABSTRACT_DECL_BASE),
19686 type_base(env, size_in_bits, alignment_in_bits),
19688 priv_(new priv(member_type, containing_type))
19725const type_base_sptr&
19727{
return priv_->dm_type_;}
19734const type_base_sptr&
19736{
return priv_->containing_type_;}
19766 return *
this == *other;
19781 return *
this == *other;
19793 bool internal)
const
19812 if (priv_->internal_qualified_name_.empty())
19813 priv_->internal_qualified_name_ =
19814 ptr_to_mbr_declaration_name(
this,
"",
19817 return priv_->internal_qualified_name_;
19821 priv_->temp_internal_qualified_name_ =
19822 ptr_to_mbr_declaration_name(
this,
"",
true, internal);
19823 return priv_->temp_internal_qualified_name_;
19829 (ptr_to_mbr_declaration_name(
this,
"",
true,
19851 if (v.visit_begin(
this))
19862 bool result = v.visit_end(
this);
19894 bool result =
true;
19896 if (!(l.decl_base::operator==(r)))
19927 ABG_RETURN(result);
19935array_type_def::subrange_type::~subrange_type() =
default;
19944 : s_(UNSIGNED_SIGNEDNESS)
19953 : s_(UNSIGNED_SIGNEDNESS)
19962 : s_(SIGNED_SIGNEDNESS)
19970enum array_type_def::subrange_type::bound_value::signedness
19994{
return v_.unsigned_;}
20002 s_ = UNSIGNED_SIGNEDNESS;
20012 s_ = SIGNED_SIGNEDNESS;
20024 return s_ == v.s_ && v_.unsigned_ == v.v_.unsigned_;
20029struct array_type_def::subrange_type::priv
20039 : upper_bound_(ub), language_(l), infinite_(false)
20042 priv(bound_value lb, bound_value ub,
20044 : lower_bound_(lb), upper_bound_(ub),
20045 language_(l), infinite_(false)
20048 priv(bound_value lb, bound_value ub,
const type_base_sptr &u,
20050 : lower_bound_(lb), upper_bound_(ub), underlying_type_(u),
20051 language_(l), infinite_(false)
20070 const string& name,
20073 const type_base_sptr& utype,
20076 :
type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
20083 priv_(new priv(lower_bound, upper_bound, utype, l))
20103 const string& name,
20108 :
type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
20111 priv_(new priv(lower_bound, upper_bound, l))
20129 const string& name,
20133 :
type_or_decl_base(env, SUBRANGE_TYPE | ABSTRACT_TYPE_BASE | ABSTRACT_DECL_BASE),
20134 type_base(env, upper_bound.get_unsigned_value(), 0),
20136 priv_(new priv(upper_bound, l))
20161{
return priv_->underlying_type_.lock();}
20170 ABG_ASSERT(priv_->underlying_type_.expired());
20171 priv_->underlying_type_ = u;
20181{
return priv_->upper_bound_.get_signed_value();}
20188{
return priv_->lower_bound_.get_signed_value();}
20195{priv_->upper_bound_ = ub;}
20202{priv_->lower_bound_ = lb;}
20219 if (get_upper_bound() >= get_lower_bound())
20220 return get_upper_bound() - get_lower_bound() + 1;
20229{
return priv_->infinite_;}
20237{priv_->infinite_ = f;}
20244{
return priv_->language_;}
20252 std::ostringstream o;
20256 type_base_sptr underlying_type = get_underlying_type();
20257 if (underlying_type)
20259 o <<
"range "<< get_lower_bound() <<
" .. " << get_upper_bound();
20264 o <<
"[" << get_length() <<
"]";
20279 for (vector<subrange_sptr>::const_iterator i = v.begin();
20282 r += (*i)->as_string();
20311 bool result =
true;
20321 ABG_RETURN(result);
20332 ABG_RETURN(result);
20335 ABG_RETURN(result);
20366 return *
this == *other;
20434 repr +=
"<anonymous range>";
20436 repr +=
"<range " +
get_name() +
">";
20437 repr += as_string();
20455 if (v.visit_begin(
this))
20458 if (type_base_sptr u = get_underlying_type())
20463 bool result = v.visit_end(
this);
20470struct array_type_def::priv
20477 priv(type_base_sptr t)
20481 priv(type_base_sptr t, subranges_type subs)
20482 : element_type_(t), subranges_(subs)
20502array_type_def::array_type_def(
const type_base_sptr e_type,
20503 const std::vector<subrange_sptr>& subs,
20507 | ABSTRACT_TYPE_BASE
20508 | ABSTRACT_DECL_BASE),
20511 priv_(new priv(e_type))
20535 const std::vector<subrange_sptr>& subs,
20539 | ABSTRACT_TYPE_BASE
20540 | ABSTRACT_DECL_BASE),
20568array_type_def::update_size()
20573 size_t s = e->get_size_in_bits();
20577 s *= sub->get_length();
20585array_type_def::get_subrange_representation()
const
20611 bool qualified_name)
const
20613 return array_declaration_name(
this,
"",
20614 qualified_name, internal);
20639 std::vector<array_type_def::subrange_sptr > this_subs = l.
get_subranges();
20640 std::vector<array_type_def::subrange_sptr > other_subs = r.
get_subranges();
20642 bool result =
true;
20643 if (this_subs.size() != other_subs.size())
20652 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
20653 for (i = this_subs.begin(), j = other_subs.begin();
20654 i != this_subs.end() && j != other_subs.end();
20678 ABG_RETURN(result);
20701 std::vector<array_type_def::subrange_sptr > this_subs = l->
get_subranges();
20702 std::vector<array_type_def::subrange_sptr > other_subs = r->
get_subranges();
20704 if (this_subs.size() != other_subs.size())
20707 std::vector<array_type_def::subrange_sptr >::const_iterator i,j;
20708 for (i = this_subs.begin(), j = other_subs.begin();
20709 i != this_subs.end() && j != other_subs.end();
20719 if (*first_element_type != *second_element_type)
20775 return *l_ptt == *r_ptt;
20797 const std::vector<subrange_sptr>& subranges =
20800 if (subranges.empty())
20801 return translation_unit::LANG_C11;
20802 return subranges.front()->get_language();
20821 return *
this == *other;
20827const type_base_sptr
20829{
return priv_->element_type_.lock();}
20845 priv_->element_type_ = element_type;
20856 for (
const auto &sub : subs)
20857 priv_->subranges_.push_back(sub);
20869 if (priv_->subranges_.empty())
20872 for (std::vector<shared_ptr<subrange_type> >::const_iterator i =
20873 priv_->subranges_.begin();
20874 i != priv_->subranges_.end();
20876 if ((*i)->is_non_finite())
20883array_type_def::get_dimension_count()
const
20884{
return priv_->subranges_.size();}
20915 if (priv_->internal_qualified_name_.empty())
20916 priv_->internal_qualified_name_ =
20917 array_declaration_name(
this,
"",
20920 return priv_->internal_qualified_name_;
20924 priv_->temp_internal_qualified_name_ =
20925 array_declaration_name(
this,
"",
20927 return priv_->temp_internal_qualified_name_;
20944 (array_declaration_name(
this,
"",
20968 if (v.visit_begin(
this))
20975 subrange->traverse(v);
20980 bool result = v.visit_end(
this);
20986array_type_def::get_location()
const
20990const std::vector<array_type_def::subrange_sptr>&
20992{
return priv_->subranges_;}
20994array_type_def::~array_type_def()
21001class enum_type_decl::priv
21003 recursive_mutex mutex_;
21004 type_base_sptr underlying_type_;
21013 priv(type_base_sptr underlying_type,
21015 : underlying_type_(underlying_type),
21033enum_type_decl::enum_type_decl(
const string& name,
21035 type_base_sptr underlying_type,
21037 const string& linkage_name,
21041 | ABSTRACT_TYPE_BASE
21042 | ABSTRACT_DECL_BASE),
21043 type_base(underlying_type->get_environment(),
21044 underlying_type->get_size_in_bits(),
21045 underlying_type->get_alignment_in_bits()),
21046 decl_base(underlying_type->get_environment(),
21047 name, locus, linkage_name, vis),
21048 priv_(new priv(underlying_type, enums))
21054 e->set_enum_type(
this);
21074{
return priv_->underlying_type_;}
21079{
return priv_->enumerators_;}
21084{
return priv_->enumerators_;}
21092 lock_guard<recursive_mutex> lock(priv_->mutex_);
21093 if (priv_->sorted_enumerators_.empty())
21098 priv_->sorted_enumerators_.push_back(*e);
21100 std::sort(priv_->sorted_enumerators_.begin(),
21101 priv_->sorted_enumerators_.end(),
21105 if (l.get_name() == r.get_name())
21106 return l.get_value() < r.get_value();
21107 return (l.get_name() < r.get_name());
21111 return priv_->sorted_enumerators_;
21126 enum_type_decl:: enumerator& result)
21128 lock_guard<recursive_mutex> lock(priv_->mutex_);
21130 if (e.get_value() == value)
21153 lock_guard<recursive_mutex> lock(priv_->mutex_);
21155 if (e.get_name() == name)
21183 bool qualified_name)
const
21185 string r =
"enum ";
21220 if (v.visit_begin(
this))
21228 bool result = v.visit_end(
this);
21293is_enumerator_value_present_in_enum(
const enum_type_decl::enumerator &enr,
21294 const enum_type_decl &enom,
21295 vector<enum_type_decl::enumerator>& redundant_enrs)
21297 bool found =
false;
21298 for (
const auto &e : enom.get_enumerators())
21299 if (enumerators_values_are_equal(e, enr))
21303 redundant_enrs.push_back(e);
21321is_enumerator_value_redundant(
const enum_type_decl::enumerator &enr,
21322 const enum_type_decl &enom)
21324 vector<enum_type_decl::enumerator> redundant_enrs;
21325 if (is_enumerator_value_present_in_enum(enr, enom, redundant_enrs))
21327 if (!redundant_enrs.empty())
21360 bool result =
true;
21376 if (!!def1 != !!def2)
21408 nullptr, name, name)
21409 && def1->type_base::operator==(*def2)))
21414 if (!def1->decl_base::operator==(*def2))
21416 if (!def1->type_base::operator==(*def2))
21444 ABG_RETURN(result);
21494 && (!is_enumerator_value_redundant(e, *def2)
21495 || !is_enumerator_value_redundant(e, *def1)))
21509 && (!is_enumerator_value_redundant(e, *def1)
21510 || !is_enumerator_value_redundant(e, *def2)))
21522 ABG_RETURN(result);
21543 bool result =
equals(l, r, k,
false);
21575 return *
this == *other;
21590 if (l.get() == r.get())
21592 decl_base_sptr o = r;
21609class enum_type_decl::enumerator::priv
21613 string qualified_name_;
21624 priv(
const string& name,
21626 enum_type_decl* e = 0)
21638enum_type_decl::enumerator::~enumerator() =
default;
21649 : priv_(new priv(name, value))
21656 : priv_(new priv(other.
get_name(),
21658 other.get_enum_type()))
21683 bool names_equal =
true;
21685 return names_equal && (get_value() == other.
get_value());
21704{
return priv_->name_;}
21722 if (priv_->qualified_name_.empty())
21724 priv_->qualified_name_ =
21725 get_enum_type()->get_qualified_name(internal)
21729 return priv_->qualified_name_;
21745{
return priv_->value_;}
21759{
return priv_->enum_type_;}
21766{priv_->enum_type_ = e;}
21772struct typedef_decl::priv
21776 priv(
const type_base_sptr& t)
21777 : underlying_type_(t)
21792typedef_decl::typedef_decl(
const string& name,
21793 const type_base_sptr underlying_type,
21795 const string& linkage_name,
21799 | ABSTRACT_TYPE_BASE
21800 | ABSTRACT_DECL_BASE),
21805 name, locus, linkage_name, vis),
21806 priv_(new priv(underlying_type))
21822typedef_decl::typedef_decl(
const string& name,
21825 const string& mangled_name,
21829 | ABSTRACT_TYPE_BASE
21830 | ABSTRACT_DECL_BASE),
21833 decl_base(env, name, locus, mangled_name, vis),
21834 priv_(new priv(nullptr))
21874 s = t->get_size_in_bits();
21899 a = t->get_alignment_in_bits();
21932 bool result =
true;
21937 if (!(l.decl_base::operator==(r)))
21959 ABG_RETURN(result);
21986 return *
this == *other;
22008 bool qualified_name)
const
22010 string result =
"typedef ";
22011 if (qualified_name)
22024{
return priv_->underlying_type_.lock();}
22032 priv_->underlying_type_ = t;
22046 bool internal)
const
22064 return decl_base::priv_->internal_qualified_name_;
22066 return decl_base::priv_->qualified_name_;
22085 if (v.visit_begin(
this))
22092 if (type_base_sptr t =
is_type(s))
22098 bool result = v.visit_end(
this);
22103typedef_decl::~typedef_decl()
22109struct var_decl::priv
22122 priv(type_base_sptr t,
22125 naked_type_(t.get()),
22133 set_type(type_base_sptr t)
22136 naked_type_ = t.get();
22153var_decl::var_decl(
const string& name,
22154 type_base_sptr type,
22156 const string& linkage_name,
22160 VAR_DECL | ABSTRACT_DECL_BASE),
22161 decl_base(type->get_environment(), name, locus, linkage_name, vis),
22162 priv_(new priv(type, bind))
22170const type_base_sptr
22172{
return priv_->type_.lock();}
22179{priv_->set_type(t);}
22190{
return priv_->naked_type_;}
22197{
return priv_->binding_;}
22204{priv_->binding_ = b;}
22220 priv_->symbol_ = sym;
22235{
return priv_->symbol_;}
22304 bool result =
true;
22317 else if (s0 && !textually_equals(*s0, *s1, k))
22323 bool symbols_are_equal = (s0 && s1 && result);
22325 if (symbols_are_equal)
22330 bool decl_bases_different =
22336 if (decl_bases_different)
22346 if (!l.decl_base::operator==(r))
22370 ABG_RETURN(result);
22395 bool result =
true;
22416 ABG_RETURN(result);
22431 return equals(*
this, *other, 0);
22446 if (priv_->id_.empty())
22451 sym_str = s->get_id_string();
22457 if (!sym_str.empty())
22458 id = env.
intern(
id +
"{" + sym_str +
"}");
22530 result =
"static ";
22534 bool member_of_anonymous_class =
false;
22536 if (scope->get_is_anonymous())
22537 member_of_anonymous_class =
true;
22546 if (member_of_anonymous_class || !qualified_name)
22553 string quals_repr =
22555 if (!quals_repr.empty())
22556 name = quals_repr +
" " + name;
22560 name = string(
" ") + name;
22562 result += array_declaration_name(t, name, qualified_name, internal);
22564 result += pointer_declaration_name(t, name, qualified_name, internal);
22566 result += pointer_declaration_name(t, name, qualified_name, internal);
22568 result += ptr_to_mbr_declaration_name(t, name,
22583 "",
true, internal);
22589 "",
true, internal);
22592 && (member_of_anonymous_class || !qualified_name))
22608 && (member_of_anonymous_class || !qualified_name))
22662 if (v.visit_begin(
this))
22665 if (type_base_sptr t =
get_type())
22669 return v.visit_end(
this);
22672var_decl::~var_decl()
22677thread_local fn_set_type function_type::priv::left_fn_types_being_compared_;
22678thread_local fn_set_type function_type::priv::right_fn_types_being_compared_;
22679thread_local fn_set_type function_type::priv::fn_types_being_printed_;
22691 lock_guard<recursive_mutex> lock(
get_mutex());
22692 priv_->cached_name_.clear();
22693 priv_->internal_cached_name_.clear();
22713function_type::function_type(type_base_sptr return_type,
22715 size_t size_in_bits,
22716 size_t alignment_in_bits)
22718 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22719 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
22720 priv_(new
priv(parms, return_type))
22724 for (parameters::size_type i = 0, j = 1;
22725 i < priv_->parms_.size();
22728 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22735 priv_->parms_[i]->set_index(j);
22746function_type::function_type(type_base_sptr return_type,
22747 size_t size_in_bits,
size_t alignment_in_bits)
22749 FUNCTION_TYPE | ABSTRACT_TYPE_BASE),
22750 type_base(return_type->get_environment(), size_in_bits, alignment_in_bits),
22751 priv_(new
priv(return_type))
22766 size_t size_in_bits,
22767 size_t alignment_in_bits)
22769 type_base(env, size_in_bits, alignment_in_bits),
22796 lock_guard<recursive_mutex> lock(
get_mutex());
22797 return priv_->return_type_.lock();
22807 lock_guard<recursive_mutex> lock(
get_mutex());
22808 priv_->return_type_ = t;
22817 bool is_empty =
false;
22819 lock_guard<recursive_mutex> lock(
get_mutex());
22820 is_empty = priv_->parms_.empty();
22833 lock_guard<recursive_mutex> lock(
get_mutex());
22834 size = priv_->parms_.size();
22845{
return priv_->parms_;}
22866 lock_guard<recursive_mutex> lock(
get_mutex());
22893 lock_guard<recursive_mutex> lock(
get_mutex());
22894 if (i < priv_->parms_.size())
22895 parm = priv_->parms_[i];
22907 lock_guard<recursive_mutex> lock(
get_mutex());
22909 for (parameters::size_type i = 0, j = 1;
22910 i < priv_->parms_.size();
22913 if (i == 0 && priv_->parms_[i]->get_is_artificial())
22920 priv_->parms_[i]->set_index(j);
22931 lock_guard<recursive_mutex> lock(
get_mutex());
22932 parm->set_index(priv_->parms_.size());
22933 priv_->parms_.push_back(parm);
22947 lock_guard<recursive_mutex> lock(
get_mutex());
22948 return (!priv_->parms_.empty()
22949 && priv_->parms_.back()->get_variadic_marker());
22981#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
22990 bool cached_result =
false;
22993 ABG_RETURN(cached_result);
22998 bool result =
true;
23000 if (!l.type_base::operator==(r))
23011 *r_method_type =
dynamic_cast<const method_type*
>(&r);
23013 if (l_method_type && r_method_type)
23014 if (l_method_type->
get_is_static() != r_method_type->get_is_static())
23027 r_class = r_method_type->get_class_type().get();
23031 if (!!l_class != !!r_class
23034 != r_class->get_qualified_name())))
23051 bool compare_result_types =
true;
23052 string l_rt_name = l_return_type_decl
23055 string r_rt_name = r_return_type_decl
23061 (r_class && (r_class->get_qualified_name() == r_rt_name)))
23062 compare_result_types =
false;
23064 if (compare_result_types)
23088 if (l_rt_name != r_rt_name)
23097 vector<shared_ptr<function_decl::parameter> >::const_iterator i,j;
23138function_type::parameters::const_iterator
23144 bool is_method =
dynamic_cast<const method_type*
>(
this);
23148 if (is_method && (*i)->get_is_artificial())
23164function_type::parameters::const_iterator
23170 bool is_method =
dynamic_cast<const method_type*
>(
this);
23175 if (!(*i)->get_is_artificial())
23187function_type::parameters::const_iterator
23214 if (priv_->internal_cached_name_.empty())
23215 priv_->internal_cached_name_ =
23217 return priv_->internal_cached_name_;
23221 priv_->temp_internal_cached_name_ =
23223 return priv_->temp_internal_cached_name_;
23230 if (priv_->cached_name_.empty())
23231 priv_->cached_name_ =
23233 return priv_->cached_name_;
23237 priv_->temp_cached_name_ =
23239 return priv_->temp_cached_name_;
23300 if (v.visit_begin(
this))
23303 bool keep_going =
true;
23307 if (!t->traverse(v))
23308 keep_going =
false;
23315 if (type_base_sptr parm_type = (*i)->get_type())
23316 if (!parm_type->traverse(v))
23321 return v.visit_end(
this);
23324function_type::~function_type()
23330struct method_type::priv
23332 std::recursive_mutex mutex_;
23333 class_or_union_wptr class_type_;
23363method_type::method_type (type_base_sptr return_type,
23364 class_or_union_sptr class_type,
23365 const std::vector<function_decl::parameter_sptr>& p,
23367 size_t size_in_bits,
23368 size_t alignment_in_bits)
23370 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23371 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
23372 function_type(return_type, p, size_in_bits, alignment_in_bits),
23403method_type::method_type(type_base_sptr return_type,
23404 type_base_sptr class_type,
23405 const std::vector<function_decl::parameter_sptr>& p,
23407 size_t size_in_bits,
23408 size_t alignment_in_bits)
23410 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23411 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
23412 function_type(return_type, p, size_in_bits, alignment_in_bits),
23428 size_t size_in_bits,
23429 size_t alignment_in_bits)
23431 type_base(env, size_in_bits, alignment_in_bits),
23451method_type::method_type(class_or_union_sptr class_type,
23453 size_t size_in_bits,
23454 size_t alignment_in_bits)
23456 METHOD_TYPE | ABSTRACT_TYPE_BASE | FUNCTION_TYPE),
23457 type_base(class_type->get_environment(), size_in_bits, alignment_in_bits),
23460 alignment_in_bits),
23488 lock_guard<recursive_mutex> lock(priv_->mutex_);
23489 return class_or_union_sptr(priv_->class_type_);
23503 lock_guard<recursive_mutex> lock(priv_->mutex_);
23504 priv_->class_type_ = t;
23535 lock_guard<recursive_mutex> lock(priv_->mutex_);
23536 priv_->is_const = f;
23545 lock_guard<recursive_mutex> lock(priv_->mutex_);
23546 return priv_->is_const;
23555 lock_guard<recursive_mutex> lock(priv_->mutex_);
23556 priv_->is_static = f;
23565 lock_guard<recursive_mutex> lock(priv_->mutex_);
23566 return priv_->is_static;
23580 lock_guard<recursive_mutex> lock(
get_mutex());
23588 if (!first_parm->get_is_artificial())
23591 type_base_sptr this_ptr_type = first_parm->get_type();
23599 type_base_sptr candidate_class_type =
23633 if (v.visit_begin(
this))
23636 bool keep_going =
true;
23640 if (!t->traverse(v))
23641 keep_going =
false;
23648 if (type_base_sptr parm_type = (*i)->get_type())
23649 if (!parm_type->traverse(v))
23651 keep_going =
false;
23659 keep_going =
false;
23664 return v.visit_end(
this);
23675struct function_decl::priv
23677 recursive_mutex mutex_;
23678 bool declared_inline_;
23685 : declared_inline_(false),
23691 bool declared_inline,
23693 : declared_inline_(declared_inline),
23696 naked_type_(t.get())
23700 bool declared_inline,
23703 : declared_inline_(declared_inline),
23706 naked_type_(t.get()),
23728 bool declared_inline,
23730 const string& mangled_name,
23734 FUNCTION_DECL | ABSTRACT_DECL_BASE),
23766 type_base_sptr fn_type,
23767 bool declared_inline,
23769 const string& linkage_name,
23773 FUNCTION_DECL | ABSTRACT_DECL_BASE),
23774 decl_base(fn_type->get_environment(), name, locus, linkage_name, vis),
23775 scope_decl(fn_type->get_environment(),
"", locus),
23776 priv_(new priv(dynamic_pointer_cast<
function_type>(fn_type),
23798 bool qualified_name)
const
23803 string fn_prefix = mem_fn ?
"method ":
"function ";
23809 fn_prefix +=
"virtual ";
23811 decl_base_sptr return_type;
23818 return_type = mem_fn
23829 internal) +
" " + result;
23832 result = add_outer_pointer_to_fn_type_expr(p, result,
23837 result = add_outer_pointer_to_array_type_expr(p, result,
23844 return fn_prefix + result;
23874 result += mem_fn->
get_type()->get_class_type()->get_qualified_name()
23880 std::ostringstream fn_parms;
23881 stream_pretty_representation_of_fn_parms(*
get_type(),
23885 result += fn_parms.str();
23890 result +=
" const";
23901function_decl::parameters::const_iterator
23904 lock_guard<recursive_mutex> lock(priv_->mutex_);
23909 bool is_method =
dynamic_cast<const method_decl*
>(
this);
23928function_decl::parameters::const_iterator
23931 lock_guard<recursive_mutex> lock(priv_->mutex_);
23936 bool is_method =
dynamic_cast<const method_type*
>(
this);
23941 if (!(*i)->get_is_artificial())
23954 return priv_->type_.lock();
23971 lock_guard<recursive_mutex> lock(priv_->mutex_);
23972 return priv_->naked_type_;
23978 lock_guard<recursive_mutex> lock(priv_->mutex_);
23979 priv_->type_ = fn_type;
23980 priv_->naked_type_ = fn_type.get();
23997 lock_guard<recursive_mutex> lock(priv_->mutex_);
23999 priv_->symbol_ = sym;
24015 lock_guard<recursive_mutex> lock(priv_->mutex_);
24016 return priv_->symbol_;
24025 lock_guard<recursive_mutex> lock(priv_->mutex_);
24026 return priv_->declared_inline_;
24035 lock_guard<recursive_mutex> lock(priv_->mutex_);
24036 priv_->declared_inline_ = value;
24040function_decl::get_binding()
const
24042 lock_guard<recursive_mutex> lock(priv_->mutex_);
24043 return priv_->binding_;
24047const shared_ptr<type_base>
24049{
return get_type()->get_return_type();}
24052const std::vector<shared_ptr<function_decl::parameter> >&
24055 lock_guard<recursive_mutex> lock(priv_->mutex_);
24056 return get_type()->get_parameters();
24065 lock_guard<recursive_mutex> lock(priv_->mutex_);
24066 get_type()->append_parameter(parm);
24075 lock_guard<recursive_mutex> lock(priv_->mutex_);
24076 for (std::vector<shared_ptr<parameter> >::const_iterator i = parms.begin();
24158 bool result =
true;
24162 if (t0 == t1 || *t0 == *t1)
24179 bool symbols_are_equal =
true;
24191 else if (s0 && s0 != s1)
24202 symbols_are_equal = (s0 && s1 && result);
24205 if (symbols_are_equal)
24207 bool decl_bases_different =
false;
24218 if (decl_bases_different)
24230 nullptr,
true, linkage_name))
24242 if (l.get_binding() != r.get_binding())
24283 ABG_RETURN(result);
24299 return equals(*
this, *o, 0);
24327 std::ostringstream id;
24331 string virtual_member_suffix;
24341 virtual_member_suffix +=
"/o";
24346 id <<
"{" << s->get_id_string() <<
"}";
24348 if (!virtual_member_suffix.empty())
24349 id << virtual_member_suffix;
24371 lock_guard<recursive_mutex> lock(priv_->mutex_);
24372 if (type_or_decl_base::priv_->id_.
empty())
24375 return type_or_decl_base::priv_->id_;
24413 if (v.visit_begin(
this))
24417 if (type_base_sptr t =
get_type())
24422 return v.visit_end(
this);
24444 if (l.get() == r.get())
24467struct function_decl::parameter::priv
24469 recursive_mutex mutex_;
24472 bool variadic_marker_;
24479 priv(type_base_sptr type,
24481 bool variadic_marker)
24484 variadic_marker_(variadic_marker)
24488function_decl::parameter::parameter(
const type_base_sptr type,
24490 const string& name,
24491 const location& loc,
24493 : type_or_decl_base(type->get_environment(),
24494 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24495 decl_base(type->get_environment(), name, loc),
24496 priv_(new priv(type, index, is_variadic))
24498 runtime_type_instance(
this);
24501function_decl::parameter::parameter(
const type_base_sptr type,
24503 const string& name,
24504 const location& loc,
24506 bool is_artificial)
24507 : type_or_decl_base(type->get_environment(),
24508 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24509 decl_base(type->get_environment(), name, loc),
24510 priv_(new priv(type, index, is_variadic))
24512 runtime_type_instance(
this);
24513 set_is_artificial(is_artificial);
24516function_decl::parameter::parameter(
const type_base_sptr type,
24517 const string& name,
24518 const location& loc,
24520 bool is_artificial)
24521 : type_or_decl_base(type->get_environment(),
24522 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24523 decl_base(type->get_environment(), name, loc),
24524 priv_(new priv(type, 0, is_variadic))
24526 runtime_type_instance(
this);
24527 set_is_artificial(is_artificial);
24530function_decl::parameter::parameter(
const type_base_sptr type,
24533 : type_or_decl_base(type->get_environment(),
24534 FUNCTION_PARAMETER_DECL | ABSTRACT_DECL_BASE),
24535 decl_base(type->get_environment(),
"", location()),
24536 priv_(new priv(type, index, variad))
24538 runtime_type_instance(
this);
24541function_decl::parameter::~parameter() =
default;
24543const type_base_sptr
24544function_decl::parameter::get_type()
const
24545{
return priv_->type_.lock();}
24572 if (get_variadic_marker()
24592 std::ostringstream o;
24593 o <<
"parameter-" << get_index();
24595 return env.
intern(o.str());
24599function_decl::parameter::get_index()
const
24601 lock_guard<recursive_mutex> lock(priv_->mutex_);
24602 return priv_->index_;
24606function_decl::parameter::set_index(
unsigned i)
24608 lock_guard<recursive_mutex> lock(priv_->mutex_);
24614function_decl::parameter::get_variadic_marker()
const
24616 lock_guard<recursive_mutex> lock(priv_->mutex_);
24617 return priv_->variadic_marker_;
24644 bool result =
true;
24646 if ((l.get_variadic_marker() != r.get_variadic_marker())
24647 || (l.get_index() != r.get_index())
24648 || (!!l.get_type() != !!r.get_type()))
24653 if (l.get_index() != r.get_index())
24655 if (l.get_variadic_marker() != r.get_variadic_marker()
24656 || !!l.get_type() != !!r.get_type())
24663 type_base_sptr l_type = l.get_type();
24664 type_base_sptr r_type = r.get_type();
24666 if (l_type != r_type)
24680 ABG_RETURN(result);
24684function_decl::parameter::operator==(
const parameter& o)
const
24685{
return equals(*
this, o, 0);}
24694 return function_decl::parameter::operator==(*p);
24740 if (v.visit_begin(
this))
24743 if (type_base_sptr t =
get_type())
24747 return v.visit_end(
this);
24780 bool qualified_name)
const
24787 type_repr =
"void";
24793 string result = type_repr;
24794 string parm_name = get_name_id();
24796 if (!parm_name.empty())
24797 result +=
" " + parm_name;
24822 size_t size_in_bits,
size_t align_in_bits,
24826 | ABSTRACT_DECL_BASE
24827 | ABSTRACT_SCOPE_TYPE_DECL
24828 | ABSTRACT_SCOPE_DECL),
24829 decl_base(env, name, locus, name, vis),
24830 type_base(env, size_in_bits, align_in_bits),
24844 bool is_declaration_only)
24847 | ABSTRACT_DECL_BASE
24848 | ABSTRACT_SCOPE_TYPE_DECL
24849 | ABSTRACT_SCOPE_DECL),
24869 hash_t h = do_hash(
this);
24890 if (v.visit_begin(
this))
24899 if (!(*i)->traverse(v))
24909 if (!(*i)->traverse(v))
24918 if (!member_type->traverse(v))
24925 for (member_function_templates::const_iterator i =
24929 if (!(*i)->traverse(v))
24936 for (member_class_templates::const_iterator i =
24940 if (!(*i)->traverse(v))
24949 if (type_base_sptr t =
is_type(s))
24950 if (!t->traverse(v))
24956 bool result = v.visit_end(
this);
24985 type_base_sptr t =
is_type(decl);
24991 return cou->remove_member_type(t);
25015 lock_guard<recursive_mutex> lock(anon_dm_type->
get_mutex());
25016 for (class_or_union::data_members::const_iterator it =
25105 if (t->get_is_anonymous())
25123 if (t->get_is_anonymous())
25141 if (t->get_is_anonymous())
25167 bool is_laid_out,
bool is_static,
25168 size_t offset_in_bits)
25174 lock_guard<recursive_mutex> lock(cou->get_mutex());
25175 cou->priv_->data_members_.push_back(v);
25185 bool is_already_in =
false;
25188 lock_guard<recursive_mutex> lock(cou->get_mutex());
25189 for (
const auto& s_dm: cou->priv_->static_data_members_)
25193 is_already_in =
true;
25197 if (!is_already_in)
25198 cou->priv_->static_data_members_.push_back(v);
25202 lock_guard<recursive_mutex> lock(cou->get_mutex());
25205 for (
auto dm : cou->priv_->non_static_data_members_)
25208 is_already_in =
true;
25212 if (!is_already_in)
25213 cou->priv_->non_static_data_members_.push_back(v);
25221 cou->maybe_fixup_members_of_anon_data_member(v);
25229{
return priv_->data_members_;}
25239 lock_guard<recursive_mutex> lock(
get_mutex());
25240 result.reserve(priv_->data_members_.size());
25241 for (
auto d : priv_->data_members_)
25242 result.push_back(d);
25258 if (m->get_name() == name)
25268 if (
var_decl_sptr data_member = type->find_data_member(name))
25269 return data_member;
25283 if (!v->get_name().empty())
25286 lock_guard<recursive_mutex> lock(
get_mutex());
25289 if (m->get_pretty_representation(
false,
true)
25290 == v->get_pretty_representation(
false,
true))
25316 if (v->get_name().empty())
25330 lock_guard<recursive_mutex> lock(
get_mutex());
25331 return priv_->non_static_data_members_;
25341 lock_guard<recursive_mutex> lock(
get_mutex());
25342 return priv_->static_data_members_;
25347struct member_function_less_than
25366 if (fn != sn)
return fn < sn;
25372 if ((!f_sym) != (!s_sym))
return !f_sym;
25373 if (f_sym && s_sym)
25375 fn = f_sym->get_id_string();
25376 sn = s_sym->get_id_string();
25377 if (fn != sn)
return fn < sn;
25384 if (fn != sn)
return fn < sn;
25388 string fn_filepath, sn_filepath;
25389 unsigned line = 0, column = 0;
25392 fn_loc.
expand(fn_filepath, line, column);
25394 sn_loc.expand(sn_filepath, line, column);
25395 return fn_filepath < sn_filepath;
25410 operator()(
const method_decl_sptr f,
25411 const method_decl_sptr s)
25412 {
return operator()(*f, *s);}
25418 member_function_less_than lt;
25419 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
25437 method_decl_sptr f,
25439 bool is_static,
bool is_ctor,
25440 bool is_dtor,
bool is_const)
25454 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25455 cou->priv_->member_functions_.push_back(f);
25456 cou->priv_->member_functions_sorted_ =
false;
25461 if (!f->get_linkage_name().empty())
25464 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25465 cou->priv_->mem_fns_map_[f->get_linkage_name()] = f;
25467 string demangled_name =
25469 if (demangled_name != f->get_linkage_name())
25471 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25472 cou->priv_->mem_fns_map_[demangled_name] = f;
25477 lock_guard<recursive_mutex> lock(cou->priv_->member_functions_mutex_);
25478 cou->priv_->mem_fns_map_[f->get_name()] = f;
25489 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25490 if (!priv_->member_functions_sorted_)
25492 sort_member_functions(priv_->member_functions_);
25493 priv_->member_functions_sorted_ =
true;
25495 return priv_->member_functions_;
25507 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25508 result.reserve(priv_->member_functions_.size());
25510 result.push_back(f);
25534 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25535 string_mem_fn_sptr_map_type::const_iterator i =
25536 priv_->mem_fns_map_.find(linkage_name);
25537 if (i == priv_->mem_fns_map_.end())
25539 return i->second.get();
25550 lock_guard<recursive_mutex> lock(priv_->member_functions_mutex_);
25551 string_mem_fn_sptr_map_type::const_iterator i =
25552 priv_->mem_fns_map_.find(linkage_name);
25553 if (i == priv_->mem_fns_map_.end())
25587 lock_guard<recursive_mutex> lock(
get_mutex());
25588 string_mem_fn_ptr_map_type::const_iterator i =
25589 priv_->signature_2_mem_fn_map_.find(s);
25590 if (i == priv_->signature_2_mem_fn_map_.end())
25598const member_function_templates&
25600{
return priv_->member_function_templates_;}
25605const member_class_templates&
25607{
return priv_->member_class_templates_;}
25614 member_function_template_sptr m)
25616 decl_base_sptr c = m->as_function_tdecl()->get_scope();
25622 m->as_function_tdecl());
25623 cou->priv_->member_function_templates_.push_back(m);
25633 member_class_template_sptr m)
25641 m->as_class_tdecl());
25642 cou->priv_->member_class_templates_.push_back(m);
25654 && priv_->data_members_.empty()
25655 && priv_->member_functions_.empty()
25656 && priv_->member_function_templates_.empty()
25657 && priv_->member_class_templates_.empty());
25677 else if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
25683 else if (member_function_template_sptr f =
25684 dynamic_pointer_cast<member_function_template>(d))
25686 else if (member_class_template_sptr c =
25687 dynamic_pointer_cast<member_class_template>(d))
25736 return *
this == *o;
25777 if (l_is_decl_only || r_is_decl_only)
25787 if (!def1 || !def2)
25791 && l_is_decl_only && r_is_decl_only
25830 if (!!def1 != !!def2)
25838 if (!(l.decl_base::operator==(r)
25839 && l.type_base::operator==(r)))
25850 bool val = *def1 == *def2;
25859 if (!(l.decl_base::operator==(r)
25860 && l.type_base::operator==(r)
25868 if (types_defined_same_linux_kernel_corpus_public(l, r))
25871#define RETURN(value) return return_comparison_result(l, r, value);
25883 bool result =
true;
25897 for (class_or_union::data_members::const_iterator
25911 || (*d0)->get_type() == (*d1)->get_type())
25938 for (member_function_templates::const_iterator
25943 ++fn_tmpl_it0, ++fn_tmpl_it1)
25944 if (**fn_tmpl_it0 != **fn_tmpl_it1)
25969 for (member_class_templates::const_iterator
25974 ++cl_tmpl_it0, ++cl_tmpl_it1)
25975 if (**cl_tmpl_it0 != **cl_tmpl_it1)
26002 const method_decl_sptr& method)
26025 old_type->get_parameters(),
26026 old_type->get_is_const(),
26027 old_type->get_size_in_bits(),
26028 old_type->get_alignment_in_bits()));
26030 if (
offset_t offset = old_type->get_native_offset())
26031 new_type->set_native_offset(offset);
26040 method->get_binding()));
26041 new_method->set_symbol(method->
get_symbol());
26060 new_method->set_original_artefact(method);
26081 type_base_sptr old_type = variable->
get_type();
26090 size_t offset_in_bits = 0;
26100 new_variable->set_original_artefact(variable);
26102 return new_variable;
26141 decl_base_sptr m = member_type;
26175 size_t size_in_bits,
size_t align_in_bits,
26176 bool is_struct,
const location& locus,
26180 | ABSTRACT_TYPE_BASE
26181 | ABSTRACT_DECL_BASE
26182 | ABSTRACT_SCOPE_TYPE_DECL
26183 | ABSTRACT_SCOPE_DECL),
26184 decl_base(env, name, locus, name, vis),
26185 type_base(env, size_in_bits, align_in_bits),
26188 priv_(new
priv(is_struct))
26212 size_t size_in_bits,
size_t align_in_bits,
26213 bool is_struct,
const location& locus,
26217 | ABSTRACT_TYPE_BASE
26218 | ABSTRACT_DECL_BASE
26219 | ABSTRACT_SCOPE_TYPE_DECL
26220 | ABSTRACT_SCOPE_DECL),
26229 is_anonymous ? string() : name,
26231 type_base(env, size_in_bits, align_in_bits),
26234 priv_(new
priv(is_struct))
26250 bool is_struct,
bool is_declaration_only)
26253 | ABSTRACT_TYPE_BASE
26254 | ABSTRACT_DECL_BASE
26255 | ABSTRACT_SCOPE_TYPE_DECL
26256 | ABSTRACT_SCOPE_DECL),
26260 priv_(new
priv(is_struct))
26273 lock_guard<recursive_mutex> lock(
get_mutex());
26276 for (class_decl::virtual_mem_fn_map_type::iterator i =
26277 priv_->virtual_mem_fns_map_.begin();
26278 i != priv_->virtual_mem_fns_map_.end();
26280 sort_virtual_member_functions(i->second);
26289 priv_->is_struct_ = f;
26297{
return priv_->is_struct_;}
26305 lock_guard<recursive_mutex> lock(
get_mutex());
26306 priv_->bases_.push_back(b);
26307 priv_->bases_map_[b->get_base_class()->get_qualified_name()] = b;
26315{
return priv_->bases_;}
26325 lock_guard<recursive_mutex> lock(
get_mutex());
26326 result.reserve(priv_->bases_.size());
26327 for (
auto b : priv_->bases_)
26328 result.push_back(b);
26342 lock_guard<recursive_mutex> lock(
get_mutex());
26343 unordered_map<string, base_spec_sptr>::iterator i =
26344 priv_->bases_map_.find(qualified_name);
26346 if (i != priv_->bases_map_.end())
26347 return i->second->get_base_class();
26358{
return priv_->virtual_mem_fns_;}
26377{
return priv_->virtual_mem_fns_map_;}
26383 lock_guard<recursive_mutex> lock(
get_mutex());
26384 sort_virtual_member_functions(priv_->virtual_mem_fns_);
26406 bool qualified_name)
const
26408 string cl =
"class ";
26418 if (internal && !
get_name().empty())
26429 string result = cl;
26430 if (qualified_name)
26441 if (method_decl_sptr f = dynamic_pointer_cast<method_decl>(d))
26456struct class_decl::base_spec::priv
26459 long offset_in_bits_;
26463 long offset_in_bits,
26466 offset_in_bits_(offset_in_bits),
26467 is_virtual_(is_virtual)
26485 long offset_in_bits,
26488 ABSTRACT_DECL_BASE),
26490 base->get_linkage_name(), base->get_visibility()),
26492 priv_(new priv(base, offset_in_bits, is_virtual))
26518{
return priv_->base_class_.lock();}
26525{
return priv_->is_virtual_;}
26532{
return priv_->offset_in_bits_;}
26552 if (v.visit_begin(
this))
26555 get_base_class()->traverse(v);
26559 return v.visit_end(
this);
26579class_decl::base_spec::base_spec(
const type_base_sptr& base,
26581 long offset_in_bits,
26584 ABSTRACT_DECL_BASE),
26590 priv_(new priv(dynamic_pointer_cast<
class_decl>(base),
26597class_decl::base_spec::~base_spec() =
default;
26623 if (!l.member_base::operator==(r))
26649 return equals(*
this, *o, 0);
26686method_decl::method_decl(
const string& name,
26688 bool declared_inline,
26690 const string& linkage_name,
26695 | ABSTRACT_DECL_BASE
26700 declared_inline, locus, linkage_name, vis, bind)
26724method_decl::method_decl(
const string& name,
26726 bool declared_inline,
26728 const string& linkage_name,
26733 | ABSTRACT_DECL_BASE
26735 decl_base(type->get_environment(), name, locus, linkage_name, vis),
26736 scope_decl(type->get_environment(),
"", locus),
26738 linkage_name, vis, bind)
26761method_decl::method_decl(
const string& name,
26762 type_base_sptr type,
26763 bool declared_inline,
26765 const string& linkage_name,
26770 | ABSTRACT_DECL_BASE
26772 decl_base(type->get_environment(), name, locus, linkage_name, vis),
26773 scope_decl(type->get_environment(),
"", locus),
26775 linkage_name, vis, bind)
26801 lock_guard<recursive_mutex> lock(cl->priv_->member_functions_mutex_);
26805 cl->priv_->mem_fns_map_[l] = m;
26808 if (!old_lname.empty() && l != old_lname)
26809 if (method_decl_sptr m = cl->find_member_function_sptr(old_lname))
26810 cl->priv_->mem_fns_map_.erase(old_lname);
26813method_decl::~method_decl()
26850 if (l.get() == r.get())
26903{
return dynamic_pointer_cast<method_decl>(d);}
26907struct virtual_member_function_less_than
26931 if (f_offset != s_offset)
return f_offset < s_offset;
26937 if (fn != sn)
return fn < sn;
26943 if ((!f_sym) != (!s_sym))
return !f_sym;
26944 if (f_sym && s_sym)
26946 fn = f_sym->get_id_string();
26947 sn = s_sym->get_id_string();
26948 if (fn != sn)
return fn < sn;
26955 if (fn != sn)
return fn < sn;
26959 string fn_filepath, sn_filepath;
26960 unsigned line = 0, column = 0;
26963 fn_loc.
expand(fn_filepath, line, column);
26965 sn_loc.expand(sn_filepath, line, column);
26966 return fn_filepath < sn_filepath;
26981 operator()(
const method_decl_sptr f,
26982 const method_decl_sptr s)
26983 {
return operator()(*f, *s);}
26992 virtual_member_function_less_than lt;
26993 std::stable_sort(mem_fns.begin(), mem_fns.end(), lt);
27020 method_decl_sptr f,
27023 size_t vtable_offset,
27024 bool is_static,
bool is_ctor,
27025 bool is_dtor,
bool is_const)
27028 is_dtor, is_const);
27035 lock_guard<recursive_mutex> lock(cou->get_mutex());
27036 sort_virtual_member_functions(klass->priv_->virtual_mem_fns_);
27056 class_decl::member_functions::const_iterator m;
27058 lock_guard<recursive_mutex> lock(klass->get_mutex());
27059 for (m = klass->priv_->virtual_mem_fns_.begin();
27060 m != klass->priv_->virtual_mem_fns_.end();
27062 if (m->get() == method.get()
27063 || (*m)->get_linkage_name() == method->get_linkage_name())
27065 if (m == klass->priv_->virtual_mem_fns_.end())
27066 klass->priv_->virtual_mem_fns_.push_back(method);
27076 lock_guard<recursive_mutex> lock(klass->get_mutex());
27077 class_decl::virtual_mem_fn_map_type::iterator i =
27078 klass->priv_->virtual_mem_fns_map_.find(voffset);
27079 if (i == klass->priv_->virtual_mem_fns_map_.end())
27082 virtual_mem_fns_at_voffset.push_back(method);
27083 klass->priv_->virtual_mem_fns_map_[voffset] = virtual_mem_fns_at_voffset;
27087 for (m = i->second.begin() ; m != i->second.end(); ++m)
27088 if (m->get() == method.get()
27089 || (*m)->get_linkage_name() == method->get_linkage_name())
27091 if (m == i->second.end())
27092 i->second.push_back(method);
27122 if ((*b)->get_is_virtual()
27123 || (*b)->get_base_class()->has_virtual_bases())
27152 lock_guard<recursive_mutex> lock(
get_mutex());
27153 ssize_t offset = -1;
27154 for (class_decl::virtual_mem_fn_map_type::const_iterator e =
27158 if (e->first > offset)
27188methods_equal_modulo_elf_symbol(
const method_decl_sptr& f,
27189 const method_decl_sptr& s)
27191 bool equal =
equals(*f, *s,
nullptr,
27213method_matches_at_least_one_in_vector(
const method_decl_sptr& method,
27216 for (class_decl::member_functions::const_iterator i = fns.begin();
27225 if (methods_equal_modulo_elf_symbol(method, *i))
27253l_class_virt_methods_equal_r_modulo_dtors(
const class_decl& l,
27254 const class_decl& r,
27260 for (
auto& l_virt_entry : l_virt_map)
27263 unsigned l_virt_mem_fn_offset = l_virt_entry.first;
27264 auto r_vfns_it = r_virt_map.find(l_virt_mem_fn_offset);
27265 auto& r_vfns = r_vfns_it->second;
27267 if (r_vfns_it == r_virt_map.end())
27277 for (
auto method : l_virt_entry.second)
27278 if (!method_matches_at_least_one_in_vector(method, r_vfns))
27310classes_virt_methods_are_equal_modulo_destructors(
const class_decl& l,
27311 const class_decl& r,
27314 if (l_class_virt_methods_equal_r_modulo_dtors(l, r, k)
27315 && l_class_virt_methods_equal_r_modulo_dtors(r, l, k))
27347 bool result =
false;
27348 if (l.
get_environment().priv_->is_type_comparison_cached(l, r, result))
27349 ABG_RETURN(result);
27362 bool result =
true;
27369 ABG_RETURN(result);
27376#define RETURN(value) CACHE_AND_RETURN_COMPARISON_RESULT(value)
27388 for (class_decl::base_specs::const_iterator
27400 (*b1)->get_base_class().get()))
27432 if (!classes_virt_methods_are_equal_modulo_destructors(l, r, k))
27514 return *
this == *o;
27558 if (l.get() == r.get())
27590operator==(
const class_or_union_sptr& l,
const class_or_union_sptr& r)
27592 if (l.get() == r.get())
27609operator!=(
const class_or_union_sptr& l,
const class_or_union_sptr& r)
27629 if (v.visit_begin(
this))
27635 naming_typedef->traverse(v);
27639 if (!base->traverse(v))
27650 if (!var_sptr->traverse(v))
27662 if (!fn->traverse(v))
27674 if (!t->traverse(v))
27682 for (member_function_templates::const_iterator i =
27686 if (!(*i)->traverse(v))
27693 for (member_class_templates::const_iterator i =
27697 if (!(*i)->traverse(v))
27705 bool result = v.visit_end(
this);
27716struct context_rel::priv
27718 recursive_mutex mutex_;
27721 bool is_static_ =
false;
27724context_rel::context_rel()
27740 priv_->access_ = a;
27741 priv_->is_static_ = f;
27745context_rel::get_scope()
const
27747 lock_guard<recursive_mutex> lock(priv_->mutex_);
27748 return priv_->scope_.lock();
27752context_rel::get_access_specifier()
const
27754 lock_guard<recursive_mutex> lock(priv_->mutex_);
27755 return priv_->access_;
27761 lock_guard<recursive_mutex> lock(priv_->mutex_);
27762 priv_->access_ = a;
27766context_rel::get_is_static()
const
27768 lock_guard<recursive_mutex> lock(priv_->mutex_);
27769 return priv_->is_static_;
27773context_rel::set_is_static(
bool s)
27775 lock_guard<recursive_mutex> lock(priv_->mutex_);
27776 priv_->is_static_ = s;
27782 lock_guard<recursive_mutex> lock(priv_->mutex_);
27787context_rel::operator==(
const context_rel& o)
const
27789 lock_guard<recursive_mutex> lock(priv_->mutex_);
27790 return (priv_->is_static_ == o.priv_->is_static_);
27803 return !operator==(o);
27806context_rel::~context_rel()
27812member_base::operator==(
const member_base& o)
const
27832 if (l.get() == r.get())
27837 return *l ==
static_cast<const decl_base&
>(*r);
27876{
return dynamic_pointer_cast<class_decl::base_spec>(tod);}
27879member_function_template::operator==(
const member_base& other)
const
27886 if (!(is_constructor() == o.is_constructor()
27887 && is_const() == o.is_const()
27888 && member_base::operator==(o)))
27895 return ftdecl->function_tdecl::operator==(*other_ftdecl);
27914 const member_function_template_sptr& r)
27916 if (l.get() == r.get())
27935 const member_function_template_sptr& r)
27952 if (v.visit_begin(
this))
27959 return v.visit_end(
this);
27975 if (!member_base::operator==(o))
27978 return as_class_tdecl()->class_tdecl::operator==(o);
27992 if (!decl_base::operator==(other))
27994 return as_class_tdecl()->class_tdecl::operator==(other);
28008 return *
this == *o;
28021 const member_class_template_sptr& r)
28023 if (l.get() == r.get())
28041 const member_class_template_sptr& r)
28058 if (v.visit_begin(
this))
28065 return v.visit_end(
this);
28085 case private_access:
28088 case protected_access:
28091 case public_access:
28115 c->set_is_static(s);
28125 lock_guard<recursive_mutex> lock(cl->get_mutex());
28127 for (
const auto& dm : cl->get_data_members())
28128 if (dm->get_name() == v->get_name())
28140 lock_guard<recursive_mutex> lock(cl->get_mutex());
28142 for (class_decl::data_members::iterator i =
28143 cl->priv_->non_static_data_members_.begin();
28144 i != cl->priv_->non_static_data_members_.end();
28147 if ((*i)->get_name() == v->get_name())
28149 cl->priv_->non_static_data_members_.erase(i);
28158 lock_guard<recursive_mutex> lock(cl->get_mutex());
28159 bool already_in_static_dms =
false;
28160 for (
const auto& s_dm : cl->priv_->static_data_members_)
28161 if (s_dm->get_name() == v->get_name())
28163 already_in_static_dms =
true;
28166 if (!already_in_static_dms)
28167 cl->priv_->static_data_members_.push_back(var);
28173 lock_guard<recursive_mutex> lock(cl->get_mutex());
28175 for (class_or_union::data_members::iterator i =
28176 cl->priv_->static_data_members_.begin();
28177 i != cl->priv_->static_data_members_.end();
28179 if ((*i)->get_name() == v->get_name())
28181 cl->priv_->static_data_members_.erase(i);
28188 bool is_already_in_non_static_data_members =
false;
28190 lock_guard<recursive_mutex> lock(cl->get_mutex());
28191 for (
const auto& ns_dm : cl->priv_->non_static_data_members_)
28192 if (ns_dm->get_name() == v->get_name())
28194 is_already_in_non_static_data_members =
true;
28197 if (!is_already_in_non_static_data_members)
28198 cl->priv_->non_static_data_members_.push_back(var);
28239 size_t size_in_bits,
const location& locus,
28243 | ABSTRACT_TYPE_BASE
28244 | ABSTRACT_DECL_BASE
28245 | ABSTRACT_SCOPE_TYPE_DECL
28246 | ABSTRACT_SCOPE_DECL),
28247 decl_base(env, name, locus, name, vis),
28270 size_t size_in_bits,
const location& locus,
28274 | ABSTRACT_TYPE_BASE
28275 | ABSTRACT_DECL_BASE
28276 | ABSTRACT_SCOPE_TYPE_DECL
28277 | ABSTRACT_SCOPE_DECL),
28286 is_anonymous ? string() : name,
28305 const string& name,
28306 bool is_declaration_only)
28309 | ABSTRACT_TYPE_BASE
28310 | ABSTRACT_DECL_BASE
28311 | ABSTRACT_SCOPE_TYPE_DECL
28312 | ABSTRACT_SCOPE_DECL),
28353 bool qualified_name)
const
28358 if (internal && !
get_name().empty())
28359 repr = string(
"union ") +
28369 if (qualified_name)
28406 return *
this == *o;
28420 return *
this == *o;
28453 if (v.visit_begin(
this))
28461 for (
auto& d : dmems)
28462 if (!d->traverse(v))
28473 if (!(*i)->traverse(v))
28483 if (!(*i)->traverse(v))
28490 for (member_function_templates::const_iterator i =
28494 if (!(*i)->traverse(v))
28501 for (member_class_templates::const_iterator i =
28505 if (!(*i)->traverse(v))
28513 bool result = v.visit_end(
this);
28552 bool result =
false;
28553 if (l.
get_environment().priv_->is_type_comparison_cached(l, r, result))
28554 ABG_RETURN(result);
28574 const method_decl_sptr& f)
28589 const class_or_union_sptr t = union_type;
28601 const class_or_union_sptr& src_class,
28602 bool copy_virtual_functions)
28604 class_or_union_sptr dest =
28606 class_or_union_sptr src =
28609 if (dest && dest->get_corpus()
28610 && src && src->get_corpus()
28611 && dest->get_corpus() == src->get_corpus())
28613 vector<method_decl_sptr> methods_to_copy;
28615 for (
auto& method : src->get_member_functions())
28617 if (!copy_virtual_functions
28621 string n = method->get_linkage_name();
28623 n = method->get_name();
28624 if (!dest->find_member_function(n))
28625 methods_to_copy.push_back(method);
28628 for (
auto& method : methods_to_copy)
28630 method_decl_sptr copied_method =
28633 ABG_ASSERT(copied_method->get_linkage_name()
28634 == method->get_linkage_name());
28636 == method->get_name());
28638 auto copied_mtype = copied_method->get_type();
28660 const class_or_union_sptr& src_class)
28664 for (
auto& var : src_class->get_data_members())
28665 if (!var->get_name().empty())
28666 if (!dest_class->find_data_member(var->get_name()))
28684 const decl_base_sptr named_type)
28689 || named_type->get_naming_typedefs().empty())
28693 for (
auto n : named_type->get_naming_typedefs())
28694 if (!type->has_naming_typedef(n))
28696 naming_typedef = n;
28700 if (naming_typedef)
28704 naming_typedef->get_location(),
28705 naming_typedef->get_linkage_name(),
28706 naming_typedef->get_visibility()));
28707 result->set_original_artefact(naming_typedef.get());
28709 type->add_naming_typedef(result);
28739 type_base_sptr src_member_type)
28745 corpus *src_abi = src_member_type->get_corpus(),
28746 *dest_abi = dest_class_or_union->get_corpus();
28747 if (src_abi != dest_abi)
28751 decl_base_sptr decl_of_type =
is_decl(src_member_type);
28752 class_or_union_sptr src_scope =
is_class_type(decl_of_type->get_scope());
28757 type_base_sptr result;
28758 bool perform_the_move =
false;
28759 type_base_sptr member_type =
28760 dest_class_or_union->find_member_type(decl_of_type->get_name());
28762 perform_the_move =
true;
28768 perform_the_move =
true;
28771 if (perform_the_move)
28776 ABG_ASSERT(dest_class_or_union.get() == src_scope.get());
28777 result = src_member_type;
28793 class_or_union_sptr src_class_or_union)
28795 if (dest_class_or_union && src_class_or_union)
28796 for (
auto member_type : src_class_or_union->get_member_types())
28811 if (l.get() == r.get())
28834struct mem_fn_context_rel::priv
28836 recursive_mutex mutex_;
28837 bool is_virtual_ =
false;
28838 ssize_t vtable_offset_in_bits_ = -1;
28839 bool is_constructor_ =
false;
28840 bool is_destructor_ =
false;
28841 bool is_const_ =
false;
28844mem_fn_context_rel::mem_fn_context_rel()
28845 : context_rel(), priv_(new priv)
28847 priv_->is_virtual_ =
false;
28848 priv_->vtable_offset_in_bits_ = -1;
28849 priv_->is_constructor_ =
false;
28850 priv_->is_destructor_ =
false;
28851 priv_->is_const_ =
false;
28858 priv_->is_virtual_ =
false;
28859 priv_->vtable_offset_in_bits_ = -1;
28860 priv_->is_constructor_ =
false;
28861 priv_->is_destructor_ =
false;
28862 priv_->is_const_ =
false;
28867 bool is_constructor,
28868 bool is_destructor,
28871 size_t vtable_offset_in_bits,
28874 : context_rel(s, access, is_static),
28877 priv_->is_virtual_ = is_virtual;
28878 priv_->vtable_offset_in_bits_ = vtable_offset_in_bits;
28879 priv_->is_constructor_ = is_constructor;
28880 priv_->is_destructor_ = is_destructor;
28881 priv_->is_const_ = is_const;
28885mem_fn_context_rel::is_virtual()
const
28887 lock_guard<recursive_mutex> lock(priv_->mutex_);
28888 return priv_->is_virtual_;
28892mem_fn_context_rel::is_virtual(
bool is_virtual)
28894 lock_guard<recursive_mutex> lock(priv_->mutex_);
28895 priv_->is_virtual_ = is_virtual;
28907 lock_guard<recursive_mutex> lock(priv_->mutex_);
28908 return priv_->vtable_offset_in_bits_;
28920 lock_guard<recursive_mutex> lock(priv_->mutex_);
28921 priv_->vtable_offset_in_bits_ = s;
28933 lock_guard<recursive_mutex> lock(priv_->mutex_);
28934 return priv_->is_constructor_;
28944 lock_guard<recursive_mutex> lock(priv_->mutex_);
28945 priv_->is_constructor_ = f;
28956 lock_guard<recursive_mutex> lock(priv_->mutex_);
28957 return priv_->is_destructor_;
28967 lock_guard<recursive_mutex> lock(priv_->mutex_);
28968 priv_->is_destructor_ = f;
28980 lock_guard<recursive_mutex> lock(priv_->mutex_);
28981 return priv_->is_const_;
28991 lock_guard<recursive_mutex> lock(priv_->mutex_);
28992 priv_->is_const_ = f;
28995mem_fn_context_rel::~mem_fn_context_rel()
29003class template_decl::priv
29007 std::list<template_parameter_sptr> parms_;
29020{priv_->parms_.push_back(p);}
29026const std::list<template_parameter_sptr>&
29028{
return priv_->parms_;}
29041 const string& name,
29066 return *
this == *other;
29079 list<shared_ptr<template_parameter> >::const_iterator t0, t1;
29105class template_parameter::priv
29111 mutable bool hashing_started_;
29112 mutable bool comparison_started_;
29120 template_decl_(enclosing_template_decl),
29121 hashing_started_(),
29122 comparison_started_()
29126template_parameter::template_parameter(
unsigned index,
29128 : priv_(new priv(index, enclosing_template))
29132template_parameter::get_index()
const
29133{
return priv_->index_;}
29136template_parameter::get_enclosing_template_decl()
const
29137{
return priv_->template_decl_.lock();}
29141template_parameter::operator==(
const template_parameter& o)
const
29143 if (get_index() != o.get_index())
29146 if (priv_->comparison_started_)
29149 bool result =
false;
29154 priv_->comparison_started_ =
true;
29156 if (!!get_enclosing_template_decl() != !!o.get_enclosing_template_decl())
29158 else if (get_enclosing_template_decl()
29159 && (*get_enclosing_template_decl()
29160 != *o.get_enclosing_template_decl()))
29165 priv_->comparison_started_ =
false;
29178{
return !operator==(other);}
29185class type_tparameter::priv
29200type_tparameter::type_tparameter(
unsigned index,
29202 const string& name,
29206 | ABSTRACT_TYPE_BASE
29208 decl_base(enclosing_tdecl->get_environment(), name, locus),
29209 type_base(enclosing_tdecl->get_environment(), 0, 0),
29210 type_decl(enclosing_tdecl->get_environment(), name, 0, 0, locus),
29225 if (!type_decl::operator==(other))
29231 return template_parameter::operator==(o);
29245 if (!type_decl::operator==(other))
29251 return template_parameter::operator==(o);
29265 if (!decl_base::operator==(other))
29271 return template_parameter::operator==(o);
29301{
return *
this ==
static_cast<const type_base&
>(other);}
29303type_tparameter::~type_tparameter()
29307class non_type_tparameter::priv
29317 priv(type_base_sptr type)
29335non_type_tparameter::non_type_tparameter(
unsigned index,
29337 const string& name,
29338 type_base_sptr type,
29341 decl_base(type->get_environment(), name, locus,
""),
29343 priv_(new priv(type))
29351const type_base_sptr
29353{
return priv_->type_.lock();}
29359 if (!decl_base::operator==(other))
29366 return (template_parameter::operator==(o)
29385non_type_tparameter::~non_type_tparameter()
29391class template_tparameter::priv
29405template_tparameter::template_tparameter(
unsigned index,
29407 const string& name,
29411 | ABSTRACT_TYPE_BASE
29413 decl_base(enclosing_tdecl->get_environment(), name, locus),
29414 type_base(enclosing_tdecl->get_environment(), 0, 0),
29415 type_decl(enclosing_tdecl->get_environment(), name,
29416 0, 0, locus, name, VISIBILITY_DEFAULT),
29418 template_decl(enclosing_tdecl->get_environment(), name, locus),
29436 return (type_tparameter::operator==(o)
29455 return (type_tparameter::operator==(o)
29469 return *
this ==
static_cast<const type_base&
>(other);
29488template_tparameter::~template_tparameter()
29496class type_composition::priv
29520type_composition::type_composition(
unsigned index,
29524 ABSTRACT_DECL_BASE),
29535const type_base_sptr
29537{
return priv_->type_.lock();}
29546type_composition::~type_composition()
29555struct function_tdecl::priv
29567 : pattern_(pattern), binding_(bind)
29594 | ABSTRACT_SCOPE_DECL),
29598 priv_(new priv(bind))
29622 | ABSTRACT_SCOPE_DECL),
29627 priv_(new priv(pattern, bind))
29640 ftdecl->priv_->pattern_ = p;
29641 ftdecl->set_name(p->get_name());
29649{
return priv_->pattern_;}
29656{
return priv_->binding_;}
29668 return *
this == *o;
29682 return *
this == *o;
29695 && template_decl::operator==(o)
29696 && scope_decl::operator==(o)
29720 if (!v.visit_begin(
this))
29727 return v.visit_end(
this);
29730function_tdecl::~function_tdecl()
29738struct class_tdecl::priv
29749 : pattern_(pattern)
29768 | ABSTRACT_SCOPE_DECL),
29793 | ABSTRACT_SCOPE_DECL),
29798 priv_(new priv(pattern))
29811 ctdecl->priv_->pattern_ = p;
29812 ctdecl->set_name(p->get_name());
29820{
return priv_->pattern_;}
29829 if (!(template_decl::operator==(o)
29830 && scope_decl::operator==(o)
29849 return *
this ==
static_cast<const decl_base&
>(o);
29857{
return *
this ==
static_cast<const decl_base&
>(o);}
29873 if (v.visit_begin(
this))
29877 pattern->traverse(v);
29880 return v.visit_end(
this);
29883class_tdecl::~class_tdecl()
29894 non_canonicalized_subtype_detector();
29897 non_canonicalized_subtype_detector(
type_base* type)
29899 has_non_canonical_type_()
29908 has_non_canonical_type()
const
29909 {
return has_non_canonical_type_;}
29914 visit_begin(function_decl* f)
29932 visit_begin(type_base* t)
29936 if (!t->get_canonical_type())
29940 has_non_canonical_type_ = t;
29955 visit_end(type_base* )
29957 if (has_non_canonical_type_)
29974 non_canonicalized_subtype_detector v(t.get());
29976 return v.has_non_canonical_type();
29992 const type_base_sptr t_v2)
29999 return (t1 != t2 && repr1 == repr2);
30010 lock_guard<mutex> lock(env.priv_->extra_live_types_mutex_);
30011 env.priv_->extra_live_types_.insert(t);
30046 result =
reinterpret_cast<size_t>(g);
30048 result =
reinterpret_cast<size_t>(s);
30054 string repr = v->get_pretty_representation(
true);
30055 std::hash<string> hash_string;
30063 string repr = f->get_pretty_representation(
true);
30064 std::hash<string> hash_string;
30070 type_base_sptr parm_type = p->get_type();
30072 std::hash<bool> hash_bool;
30073 std::hash<unsigned> hash_unsigned;
30082 std::hash<size_t> hash_size;
30083 std::hash<bool> hash_bool;
30084 type_base_sptr type = bs->get_base_class();
30121{
return hash_as_canonical_type_or_constant(t);}
30148 if (d->type_or_decl_base::priv_->get_hashing_state()
30150 return d->type_or_decl_base::priv_->hash_value_;
30153 return artefact.priv_->hash_value_;
30175 if (mem_fn->get_symbol()
30176 && mem_fn->get_symbol()->is_public()
30177 && mem_fn->get_symbol()->is_defined())
30279 if (
auto decl =
is_decl(type))
30286 type_base_sptr exemplar = type ? type->get_canonical_type():
nullptr;
30311 if (
auto decl =
is_decl(type))
30324 exemplar =
const_cast<type_base*
>(type);
30353hash_as_canonical_type_or_constant(
const type_base *t)
30360 if (!canonical_type)
30378 if (canonical_type)
30379 return reinterpret_cast<size_t>(canonical_type);
30454 const type_base_sptr& second,
30455 bool indirect_type)
30487 bool indirect_type)
30489 if (!!first != !!second)
30501 if (
typeid(*first) !=
typeid(*second))
30517 if (ty1->is_lvalue() != ty2->is_lvalue())
30520 ty2->get_pointed_to_type(),
30539 if (!indirect_type)
30543 return ty1->get_name() == ty2->
get_name();
30549 if (!indirect_type)
30553 return (
get_name(ty1->get_underlying_type())
30561 && ty1->get_name() != ty2->
get_name())
30564 if (!indirect_type)
30567 || (ty1->get_non_static_data_members().size()
30571 for (class_or_union::data_members::const_iterator
30572 i = ty1->get_non_static_data_members().begin(),
30574 (i != ty1->get_non_static_data_members().end()
30581 dm2->get_type().get(),
30594 && ty1->get_name() != ty2->
get_name())
30597 if (!indirect_type)
30606 if (!indirect_type)
30609 || ty1->get_dimension_count() != ty2->get_dimension_count())
30629 for (
auto r1 = ty1->get_subranges().begin(),
30630 r2 = ty1->get_subranges().begin();
30631 (r1 != ty1->get_subranges().end()
30634 if ((*r1)->get_length() != (*r2)->get_length())
30669 if (ty1->get_parameters().size() != ty2->
get_parameters().size())
30672 for (function_type::parameters::const_iterator
30673 i = ty1->get_parameters().begin(),
30675 (i != ty1->get_parameters().end()
30705 const char* dm_name)
30733 return cou->find_data_member(dm);
30748 unsigned parm_index)
30755 if (parms.size() <= parm_index)
30758 return parms[parm_index].get();
30773 std::ostringstream o;
30776 o <<
"unnamed-enum";
30778 o <<
"enum-" << base_name;
30780 o <<
"-underlying-type-" << size;
30800 return data_member;
30820 for (; d != e; ++d)
30841stream_pretty_representation_of_fn_parms(
const function_type& fn_type,
30842 ostream& o,
bool qualified,
30845 bool parms_empty =
false;
30847 lock_guard<recursive_mutex> lock(fn_type.
get_mutex());
30856 type_base_sptr type;
30857 function_decl::parameters::const_iterator first_parm, end;
30859 lock_guard<recursive_mutex> lock(fn_type.
get_mutex());
30865 for (
auto i = first_parm; i != end; ++i)
30867 if (i != first_parm)
30870 type = parm->get_type();
30877 if (env.is_variadic_parameter_type(type))
30933add_outer_pointer_to_fn_type_expr(
const type_base* p,
30934 const string& input,
30935 bool qualified,
bool internal)
30941 string star_or_ref;
30954 if (!pointed_to_fn)
30969 std::ostringstream left, right, inner;
30971 inner <<
"(" << star_or_ref << input <<
")";
30973 type_base_sptr type;
30974 stream_pretty_representation_of_fn_parms(*pointed_to_fn, right,
30975 qualified, internal);
30977 type_base_sptr return_type = pointed_to_fn->get_return_type();
30986 result = left.str() +
" " + inner.str() + right.str();
30990 string inner_string = inner.str() + right.str();
30991 result = add_outer_pointer_to_fn_type_expr(p, inner_string,
30992 qualified, internal);
30996 string inner_string = inner.str() + right.str();
30997 result = add_outer_pointer_to_array_type_expr(p, inner_string,
30998 qualified, internal);
31057add_outer_pointer_to_fn_type_expr(
const type_base_sptr& p,
31058 const string& input,
31059 bool qualified,
bool internal)
31060{
return add_outer_pointer_to_fn_type_expr(p.get(), input, qualified, internal);}
31113add_outer_pointer_to_array_type_expr(
const type_base* p,
31114 const string& input,
bool qualified,
31120 string star_or_ref;
31121 type_base_sptr pointed_to_type;
31125 pointed_to_type = ptr->get_pointed_to_type();
31130 pointed_to_type = ref->get_pointed_to_type();
31138 std::ostringstream left, right, inner;
31139 inner <<
"(" << star_or_ref << input <<
")";
31140 right << array->get_subrange_representation();
31143 type_base_sptr array_element_type = array->get_element_type();
31149 left <<
get_type_name(array_element_type, qualified, internal);
31150 result = left.str() + inner.str() + right.str();
31155 string r = inner.str() + right.str();
31156 result = add_outer_pointer_to_fn_type_expr(p, r, qualified, internal);
31161 string inner_string = inner.str() + right.str();
31162 result = add_outer_pointer_to_array_type_expr(p, inner_string,
31163 qualified, internal);
31222add_outer_pointer_to_array_type_expr(
const type_base_sptr& pointer_to_ar,
31223 const string& input,
bool qualified,
31225{
return add_outer_pointer_to_array_type_expr(pointer_to_ar.get(),
31226 input, qualified, internal);}
31274add_outer_ptr_to_mbr_type_expr(
const ptr_to_mbr_type* p,
31275 const string& input,
bool qualified,
31281 std::ostringstream left, right, inner;
31282 type_base_sptr void_type = p->get_environment().get_void_type();
31283 string containing_type_name =
get_type_name(p->get_containing_type(),
31284 qualified, internal);
31285 type_base_sptr mbr_type = p->get_member_type();
31289 inner <<
"(" << containing_type_name <<
"::*" << input <<
")";
31290 stream_pretty_representation_of_fn_parms(*fn_type, right,
31291 qualified, internal);
31294 return_type = void_type;
31301 left <<
get_type_name(return_type, qualified, internal) <<
" ";;
31302 result = left.str() + inner.str() + right.str();
31306 string inner_str = inner.str() + right.str();
31307 result = pointer_declaration_name(p, inner_str, qualified, internal);
31311 string inner_str = inner.str() + right.str();
31312 result = add_outer_ptr_to_mbr_type_expr(p, inner_str,
31313 qualified, internal);
31320 inner <<
"(" << containing_type_name <<
"::*" << input <<
")";
31321 stream_pretty_representation_of_fn_parms(*fn_type, right,
31322 qualified, internal);
31323 string inner_str = inner.str() + right.str();
31324 result = add_outer_ptr_to_mbr_type_expr(ptr_mbr_type, inner_str,
31325 qualified, internal);
31329 left <<
get_type_name(p->get_member_type(), qualified, internal) <<
" ";
31330 inner << containing_type_name <<
"::*" << input;
31331 result = left.str()+ inner.str();
31351 string d1_name, d2_name;
31368 return d1_name != d2_name;
31391 const type_base_sptr& s)
31403 && (f->get_size_in_bits() == s->get_size_in_bits())
31404 && (f->get_alignment_in_bits() == s->get_alignment_in_bits()))
31418 const decl_base_sptr& s)
31469 const string& input,
bool qualified,
31471{
return add_outer_ptr_to_mbr_type_expr(p.get(), input, qualified, internal);}
31491add_outer_pointer_to_ptr_to_mbr_type_expr(
const type_base* p,
31492 const string& input,
bool qualified,
31498 string star_or_ref;
31499 type_base_sptr pointed_to_type;
31503 pointed_to_type = ptr->get_pointed_to_type();
31508 pointed_to_type= ref->get_pointed_to_type();
31512 if (!pointed_to_type)
31517 if (!pointed_to_ptr_to_mbr)
31520 std::ostringstream inner;
31521 inner << star_or_ref << input;
31522 string result = add_outer_ptr_to_mbr_type_expr(pointed_to_ptr_to_mbr,
31524 qualified, internal);
31541static interned_string
31542pointer_declaration_name(
const type_base* ptr,
31543 const string& idname,
31544 bool qualified,
bool internal)
31547 return interned_string();
31549 type_base_sptr pointed_to_type;
31550 string star_or_ref;
31553 pointed_to_type = p->get_pointed_to_type();
31558 pointed_to_type = p->get_pointed_to_type();
31562 if (!pointed_to_type)
31563 return interned_string();
31576 if (!idname.empty())
31583 result = add_outer_pointer_to_fn_type_expr(ptr, idname,
31584 qualified, internal);
31586 result = add_outer_pointer_to_array_type_expr(ptr, idname,
31587 qualified, internal);
31589 result = add_outer_pointer_to_ptr_to_mbr_type_expr(ptr, idname,
31590 qualified, internal);
31594 return ptr->get_environment().intern(result);
31611static interned_string
31612pointer_declaration_name(
const type_base_sptr& ptr,
31613 const string& variable_name,
31614 bool qualified,
bool internal)
31615{
return pointer_declaration_name(ptr.get(), variable_name,
31616 qualified, internal);}
31631static interned_string
31632array_declaration_name(
const array_type_def* array,
31633 const string& variable_name,
31634 bool qualified,
bool internal)
31637 return interned_string();
31639 type_base_sptr e_type = array->get_element_type();
31640 string e_type_repr =
31648 std::ostringstream o;
31649 if (!variable_name.empty())
31650 o << variable_name <<
" is ";
31652 << array->get_subrange_representation()
31653 <<
") of " << e_type_repr;
31664 result = e_type_repr;
31665 if (!variable_name.empty())
31666 result += variable_name;
31667 result += array->get_subrange_representation();
31671 string s = variable_name + array->get_subrange_representation();
31672 result = pointer_declaration_name(p, s, qualified, internal);
31676 string s = variable_name + array->get_subrange_representation();
31677 result = ptr_to_mbr_declaration_name(p, s, qualified, internal);
31682 return array->get_environment().intern(result);
31698static interned_string
31700 const string& variable_name,
31701 bool qualified,
bool internal)
31702{
return array_declaration_name(array.get(), variable_name,
31703 qualified, internal);}
31718static interned_string
31719ptr_to_mbr_declaration_name(
const ptr_to_mbr_type* ptr,
31720 const string& variable_name,
31721 bool qualified,
bool internal)
31724 return interned_string();
31726 string input = variable_name;
31727 string result = add_outer_ptr_to_mbr_type_expr(ptr, input,
31728 qualified, internal);
31729 return ptr->get_environment().intern(result);
31745static interned_string
31747 const string& variable_name,
31748 bool qualified,
bool internal)
31750 return ptr_to_mbr_declaration_name(ptr.get(), variable_name,
31751 qualified, internal);
31783 class_or_union_sptr canonical_type_of_scope =
31785 if (!canonical_type_of_scope
31793 bool do_move =
true;
31794 if (type_base_sptr t = canonical_type_of_scope->find_member_type(name))
31812 if (!tu || !fn_type)
31818 lock_guard<recursive_mutex> lock(corp->priv_->get_mutex());
31819 corp->priv_->live_fn_types_.insert(fn_type);
31820 fn_type->set_corpus(corp);
31821 fn_type->set_translation_unit(tu);
31826 lock_guard<mutex> lock(tu->priv_->live_fn_types_mutex_);
31827 tu->priv_->live_fn_types_.insert(fn_type);
31860 bool do_log,
bool show_stats)
31870struct ir_node_visitor::priv
31873 bool allow_visiting_already_visited_type_node;
31874 bool allow_visiting_member_type_nodes;
31877 : allow_visiting_already_visited_type_node(true),
31878 allow_visiting_member_type_nodes(true)
31887ir_node_visitor::~ir_node_visitor() =
default;
31896{priv_->allow_visiting_already_visited_type_node = f;}
31905{
return priv_->allow_visiting_already_visited_type_node;}
31914{priv_->allow_visiting_member_type_nodes = f;}
31923{
return priv_->allow_visiting_member_type_nodes;}
31944 canonical_type = p;
31948 size_t canonical_ptr_value =
reinterpret_cast<size_t>(canonical_type);
31949 priv_->visited_ir_nodes.insert(canonical_ptr_value);
31962{priv_->visited_ir_nodes.clear();}
31983 canonical_type = p;
31987 size_t ptr_value =
reinterpret_cast<size_t>(canonical_type);
31988 pointer_set::iterator it = priv_->visited_ir_nodes.find(ptr_value);
31989 if (it == priv_->visited_ir_nodes.end())
31996ir_node_visitor::visit_begin(
decl_base*)
32004ir_node_visitor::visit_begin(type_base*)
32008ir_node_visitor::visit_end(type_base*)
32012ir_node_visitor::visit_begin(scope_decl*)
32016ir_node_visitor::visit_end(scope_decl*)
32020ir_node_visitor::visit_begin(scope_type_decl* t)
32021{
return visit_begin(
static_cast<type_base*
>(t));}
32024ir_node_visitor::visit_end(scope_type_decl* t)
32025{
return visit_end(
static_cast<type_base*
>(t));}
32028ir_node_visitor::visit_begin(type_decl* t)
32029{
return visit_begin(
static_cast<type_base*
>(t));}
32032ir_node_visitor::visit_end(type_decl* t)
32033{
return visit_end(
static_cast<type_base*
>(t));}
32036ir_node_visitor::visit_begin(namespace_decl* d)
32037{
return visit_begin(
static_cast<decl_base*
>(d));}
32040ir_node_visitor::visit_end(namespace_decl* d)
32041{
return visit_end(
static_cast<decl_base*
>(d));}
32044ir_node_visitor::visit_begin(qualified_type_def* t)
32045{
return visit_begin(
static_cast<type_base*
>(t));}
32048ir_node_visitor::visit_end(qualified_type_def* t)
32049{
return visit_end(
static_cast<type_base*
>(t));}
32052ir_node_visitor::visit_begin(pointer_type_def* t)
32053{
return visit_begin(
static_cast<type_base*
>(t));}
32056ir_node_visitor::visit_end(pointer_type_def* t)
32057{
return visit_end(
static_cast<type_base*
>(t));}
32060ir_node_visitor::visit_begin(reference_type_def* t)
32061{
return visit_begin(
static_cast<type_base*
>(t));}
32064ir_node_visitor::visit_end(reference_type_def* t)
32065{
return visit_end(
static_cast<type_base*
>(t));}
32068ir_node_visitor::visit_begin(ptr_to_mbr_type* t)
32069{
return visit_begin(
static_cast<type_base*
>(t));}
32072ir_node_visitor::visit_end(ptr_to_mbr_type* t)
32073{
return visit_end(
static_cast<type_base*
>(t));}
32076ir_node_visitor::visit_begin(array_type_def* t)
32077{
return visit_begin(
static_cast<type_base*
>(t));}
32080ir_node_visitor::visit_end(array_type_def* t)
32081{
return visit_end(
static_cast<type_base*
>(t));}
32084ir_node_visitor::visit_begin(array_type_def::subrange_type* t)
32085{
return visit_begin(
static_cast<type_base*
>(t));}
32088ir_node_visitor::visit_end(array_type_def::subrange_type* t)
32089{
return visit_end(
static_cast<type_base*
>(t));}
32092ir_node_visitor::visit_begin(enum_type_decl* t)
32093{
return visit_begin(
static_cast<type_base*
>(t));}
32096ir_node_visitor::visit_end(enum_type_decl* t)
32097{
return visit_end(
static_cast<type_base*
>(t));}
32100ir_node_visitor::visit_begin(typedef_decl* t)
32101{
return visit_begin(
static_cast<type_base*
>(t));}
32104ir_node_visitor::visit_end(typedef_decl* t)
32105{
return visit_end(
static_cast<type_base*
>(t));}
32108ir_node_visitor::visit_begin(function_type* t)
32109{
return visit_begin(
static_cast<type_base*
>(t));}
32112ir_node_visitor::visit_end(function_type* t)
32113{
return visit_end(
static_cast<type_base*
>(t));}
32116ir_node_visitor::visit_begin(method_type* t)
32117{
return visit_begin(
static_cast<type_base*
>(t));}
32120ir_node_visitor::visit_end(method_type* t)
32121{
return visit_end(
static_cast<type_base*
>(t));}
32125ir_node_visitor::visit_begin(var_decl* d)
32126{
return visit_begin(
static_cast<decl_base*
>(d));}
32129ir_node_visitor::visit_end(var_decl* d)
32130{
return visit_end(
static_cast<decl_base*
>(d));}
32133ir_node_visitor::visit_begin(function_decl* d)
32134{
return visit_begin(
static_cast<decl_base*
>(d));}
32137ir_node_visitor::visit_end(function_decl* d)
32138{
return visit_end(
static_cast<decl_base*
>(d));}
32141ir_node_visitor::visit_begin(function_decl::parameter* d)
32142{
return visit_begin(
static_cast<decl_base*
>(d));}
32145ir_node_visitor::visit_end(function_decl::parameter* d)
32146{
return visit_end(
static_cast<decl_base*
>(d));}
32149ir_node_visitor::visit_begin(function_tdecl* d)
32150{
return visit_begin(
static_cast<decl_base*
>(d));}
32153ir_node_visitor::visit_end(function_tdecl* d)
32154{
return visit_end(
static_cast<decl_base*
>(d));}
32157ir_node_visitor::visit_begin(class_tdecl* d)
32158{
return visit_begin(
static_cast<decl_base*
>(d));}
32161ir_node_visitor::visit_end(class_tdecl* d)
32162{
return visit_end(
static_cast<decl_base*
>(d));}
32165ir_node_visitor::visit_begin(class_or_union* t)
32166{
return visit_begin(
static_cast<type_base*
>(t));}
32169ir_node_visitor::visit_end(class_or_union* t)
32170{
return visit_end(
static_cast<type_base*
>(t));}
32173ir_node_visitor::visit_begin(class_decl* t)
32174{
return visit_begin(
static_cast<type_base*
>(t));}
32177ir_node_visitor::visit_end(class_decl* t)
32178{
return visit_end(
static_cast<type_base*
>(t));}
32181ir_node_visitor::visit_begin(union_decl* t)
32182{
return visit_begin(
static_cast<type_base*
>(t));}
32185ir_node_visitor::visit_end(union_decl* t)
32186{
return visit_end(
static_cast<type_base*
>(t));}
32189ir_node_visitor::visit_begin(class_decl::base_spec* d)
32190{
return visit_begin(
static_cast<decl_base*
>(d));}
32193ir_node_visitor::visit_end(class_decl::base_spec* d)
32194{
return visit_end(
static_cast<decl_base*
>(d));}
32197ir_node_visitor::visit_begin(member_function_template* d)
32198{
return visit_begin(
static_cast<decl_base*
>(d));}
32201ir_node_visitor::visit_end(member_function_template* d)
32202{
return visit_end(
static_cast<decl_base*
>(d));}
32205ir_node_visitor::visit_begin(member_class_template* d)
32206{
return visit_begin(
static_cast<decl_base*
>(d));}
32209ir_node_visitor::visit_end(member_class_template* d)
32210{
return visit_end(
static_cast<decl_base*
>(d));}
32222 static __thread
size_t counter;
32224 std::ostringstream o;
32230struct function_decl_hash
32232 size_t operator()(
const function_decl* f)
const
32233 {
return reinterpret_cast<size_t>(f);}
32236 {
return operator()(f.get());}
32241typedef unordered_map<
const function_decl*, string,
32242 function_decl_hash,
32261static const string&
32265 fns_to_str_map_type::const_iterator i = m.find(fn);
32268 string s = get_next_string();
32289fns_to_str(vector<function_decl*>::const_iterator begin,
32290 vector<function_decl*>::const_iterator end,
32294 vector<function_decl*>::const_iterator i;
32295 for (i = begin; i != end; ++i)
32296 o <<
"'" << fn_to_str(*i, m) <<
"' ";
32322fns_to_str(vector<function_decl*>::const_iterator a_begin,
32323 vector<function_decl*>::const_iterator a_end,
32324 vector<function_decl*>::const_iterator b_begin,
32325 vector<function_decl*>::const_iterator b_end,
32329 fns_to_str(a_begin, a_end, m, o);
32331 fns_to_str(b_begin, b_end, m, o);
32355fns_to_str(vector<function_decl*>::const_iterator a_begin,
32356 vector<function_decl*>::const_iterator a_end,
32357 vector<function_decl*>::const_iterator b_begin,
32358 vector<function_decl*>::const_iterator b_end,
32362 fns_to_str(a_begin, a_end, b_begin, b_end, m, o);
32384 std::string parent_qualified_name;
32386 bool do_update_qualified_name =
false;
32389 d->priv_->qualified_parent_name_ = parent->get_qualified_name();
32390 do_update_qualified_name =
true;
32397 if (do_update_qualified_name && !d->priv_->qualified_parent_name_.empty())
32403 std::string n = d->priv_->qualified_parent_name_ +
"::" + d->
get_name();
32404 d->priv_->qualified_name_ = env.
intern(n);
32405 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
32412 d->priv_->internal_qualified_name_ = d->priv_->qualified_name_;
32414 if (do_update_qualified_name || d->priv_->scoped_name_.empty())
32418 && !parent->get_name().empty())
32419 d->priv_->scoped_name_ =
32422 d->priv_->scoped_name_ =
32426 d->priv_->cached_repr_.clear();
32427 d->priv_->internal_cached_repr_.clear();
32443{
return do_update(d);}
32455 return do_update(d);
This header declares filters for the diff trees resulting from comparing ABI Corpora.
The private data and functions of the abigail::ir::corpus type.
reverse_wrapper< T > reverse(T &iterable)
Return the reverse_wrapper container associated with a given container.
#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.
This type abstracts the configuration information of the library.
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_pool()
Default constructor.
~interned_string_pool()
Destructor.
The abstraction of an interned string.
bool operator<(const interned_string &o) const
"Less than" operator.
const string * raw() const
Return the underlying pointer to std::string that this interned_string wraps.
bool empty() const
Test if the current instance of interned_string is empty.
interned_string & operator=(const interned_string &o)
Assignment operator.
void clear()
Clear the string.
bool operator!=(const interned_string &o) const
Inequality operator.
bool operator==(const interned_string &o) const
Compare the current instance of interned_string against another instance of interned_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 array_type_def::subrange_type::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 class_decl::base_spec, visiting all the sub-types and decls that it might co...
virtual bool operator==(const decl_base &) const
Comparison operator for class_decl::base_spec.
Abstracts a class declaration.
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.
base_specs get_base_specifiers_copy() const
Get a copy of the base specifiers for this class.
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.
friend bool equals(const class_decl &, const class_decl &, change_kind *)
Compares two instances of class_decl.
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.
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.
data_members get_data_members_copy() const
Get a copy of the the data members of this class_or_union.
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.
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.
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.
virtual bool traverse(ir_node_visitor &v)
This implements the ir_traversable_base::traverse pure virtual function.
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.
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.
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.
virtual size_t get_num_anonymous_member_enums() const
Get the number of anonymous member enums contained in this class.
void maybe_fixup_members_of_anon_data_member(var_decl_sptr anon_dm)
Fixup the members of the type of an anonymous data member.
const var_decl_sptr find_data_member(const string &) const
Find a data member of a given name in the current class_or_union.
member_functions get_member_functions_copy() const
Get a copy of the member functions of this class_or_union.
Abstract a class template.
shared_ptr< class_decl > get_pattern() const
Getter 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)....
bool operator!=(const context_rel &o) const
Inequality operator.
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.
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.
std::list< typedef_decl_sptr > & get_naming_typedefs() const
Getter for the naming typedef of the current decl.
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.
virtual const interned_string & get_name() const
Getter for the name 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.
scope_decl_sptr get_scope() const
Return the type containing the current decl, if any.
bool get_is_anonymous() const
Test if the current declaration is anonymous.
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.
bool has_naming_typedef(const typedef_decl_sptr)
Test if the current decl has a given naming typedef.
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.
virtual void set_scope(scope_decl_sptr)
Setter of the scope of the current decl.
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.
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.
void add_naming_typedef(const typedef_decl_sptr)
Set the naming typedef of the current instance of decl_base.
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.
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scpe)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
bool get_is_in_public_symbol_table() const
Test if the decl is defined in a ELF symbol table as a public symbol.
friend bool equals(const decl_base &l, const decl_base &r, change_kind *, bool qualified_name, bool linkage_name)
Compares two instances of decl_base.
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_sptr 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_sptr)
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 enum_type_decl::enumerator type.
bool operator!=(const enumerator &other) const
Inequality operator.
void set_name(const string &n)
Setter for the name of enum_type_decl::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 enum_type_decl::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 enum_type_decl::enumerator.
bool operator==(const enumerator &other) const
Equality operator.
enumerator & operator=(const enumerator &)
Assignment operator of the enum_type_decl::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 "string representation".
const type_base_sptr & get_void_type() const
Get the unique type_decl that represents a "void" type for the current environment....
static size_t get_number_of_threads_to_use()
Getter of the number of threads to use, as set by the user.
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.
type_base * get_canonical_type(const char *name, unsigned index)
Get a given canonical type which has a given "string representation".
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.
const vector< type_base_sptr > & get_sorted_canonical_types() const
Get the sorted list of canonical types.
interned_string intern(const string &) const
Do intern a string.
static size_t process_thread_pool_size_string(const string &)
Process a thread pool size string and convert it to a numeric value.
static void set_number_of_threads_to_use(size_t)
Setter of the number of threads to use, as set by the user.
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 function_decl::parameter.
const function_type_sptr get_type() const
Return the type of the current instance of function_decl.
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.
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 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.
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.
interned_string get_id(const elf_symbol_sptr &s) const
Return an ID that tries to uniquely identify the function inside a program or a library,...
parameters::const_iterator get_first_non_artificial_parm() const
Get the first parameter of the function that is not compiler-generated.
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.
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 function_decl::parameter.
unsigned get_nb_parameters() const
The number of parameters of the function type in a thread-safe manner.
bool has_empty_parameters() const
Test if a the function type has empty parameters in a thread-safe manner.
const parameter_sptr get_parm_at(size_t) const
Get the function parameter at a given index, starting from zero.
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.
parameters::const_iterator get_first_non_artificial_parm() const
Get the first parameter of the function that is not compiler-generated.
This abstracts the global scope of a given translation unit.
global_scope(translation_unit *tu)
Constructor of the global_scope type.
type_base_sptr get_canonical_type_for(type_base_sptr t, homonym_type_group_sptr thiz)
Compute the canonical type for a given instance of type_base.
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.
void allow_visiting_member_type_nodes(bool)
Set if the walker using this visitor is allowed to visit member type nodes.
bool allow_visiting_member_type_nodes() const
Get if the walker using this visitor is allowed to visit member 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.
void set_artificial(size_t v)
Set the artificial-ness of the location.
location()
Default constructor for the location type.
bool get_is_artificial() const
Test if the location is artificial.
bool operator<(const location &other) const
"Less than" operator of the location type.
location & operator=(const location &l)
Assignment operator of the location.
bool operator==(const location &other) const
Equality operator of the location type.
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 location into a tripplet 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.
friend void set_member_function_is_const(function_decl &, bool)
set the const-ness property of a member function.
virtual void set_linkage_name(const string &)
Set the linkage name of the method.
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.
bool get_is_static() const
Fetter of the "is-static" property 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.
virtual bool traverse(ir_node_visitor &)
Traverses an instance of method_type, visiting all the sub-types and decls that it might contain.
bool get_is_for_static_method() const
Test if the current method type is for a static method or not.
void set_is_static(bool)
Setter of the "is-static" property of method_type.
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.
friend decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
virtual size_t get_num_anonymous_member_classes() const
Getter for the number of anonymous classes contained in this scope.
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.
declarations get_member_decls_copy() const
Getter for a copy of the member declarations carried by the current scope_decl.
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.
type_base_sptrs_type get_sorted_member_types_copy() const
Get a copy of the sorted member types.
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.
bool remove_member_type(type_base_sptr t)
Remove a member type from the current class_or_union scope.
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.
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.
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.
Abstracts a template template parameter.
virtual bool operator==(const type_base &) const
Equality operator.
This is the abstraction of the set of relevant artefacts (types, variable declarations,...
const scope_decl_sptr get_global_scope() const
Getter of the the global scope of the translation unit.
void set_address_size(char)
Setter of the address size in this translation unit.
const type_sptr_set_type & get_live_fn_types() const
Get the vector of function types that are used in the current 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...
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 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.
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...
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 vector< type_base_wptr > & get_types_sorted() const
Getter of all types types sorted by their pretty representation.
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 array_ty...
The base class of both types and declarations.
void set_translation_unit(translation_unit *)
Set the translation_unit this ABI artifact belongs to.
const interned_string & get_cached_pretty_representation(bool internal=false) const
Get the pretty representation of the current decl.
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.
std::recursive_mutex & get_mutex() const
Get the recursive mutex associated to the artifact.
const corpus * get_corpus() const
Get the corpus this ABI artifact belongs to.
friend hash_t set_or_get_cached_hash_value(const T &type_or_decl)
Set the hash value of an IR node and return it.
offset_t get_native_offset() const
Get the native offset of a given artifact.
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.
friend class_decl * is_class_type(const type_or_decl_base *)
Test whether a type is a class.
void set_native_offset(const offset_t)
Set the native offset of a given artifact.
void set_original_artefact(const type_or_decl_base *)
Set the original artefact that the current artefact was copied from.
const type_or_decl_base * get_original_artefact() const
Get the original artefact that the current artefact was copied from.
void set_corpus(corpus *) const
Set the ABI corpus associated to the current ABI artifact.
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 elf_symbol_sptr get_symbol() const
Gets the the underlying ELF symbol for the current variable, that was set using var_decl::set_symbol(...
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.
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.
This represents a queue of tasks to be performed.
tasks_type & get_completed_tasks() const
Getter of the vector of tasks that got performed.
void wait_for_workers_to_complete()
Suspends the current thread until all worker threads finish performing the tasks they are executing.
bool schedule_task(const task_sptr &)
Submit a task to the queue of tasks to be performed.
This represents a task to be performed.
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...
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 the given IR node started, is done and a hash value has been stored onto the node....
shared_ptr< homonym_type_group > homonym_type_group_sptr
A typedef for shared pointer of homonym_type_group_sptr.
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.
decl_base_sptr add_decl_to_scope(decl_base_sptr decl, scope_decl_sptr scope)
Appends a declaration to a given scope, if the declaration doesn't already belong to one and if the d...
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.
void add_member_type(scope_decl_sptr scope, type_base_sptr t)
Add a member type to a given scope.
size_t hash_type(const type_base *t)
Hash an ABI artifact that is a type.
const type_base_sptr lookup_type_in_scope(const string &fqn, scope_decl_sptr skope)
Lookup a type in a scope.
void hash_and_canonicalize_types(SequenceType &types, bool do_log=false, bool show_stats=false)
Hash and canonicalize a sequence of types.
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.
scope_decl_sptr get_top_most_scope_under(decl_base_sptr decl, scope_decl_sptr scope)
Return the a scope S containing a given declaration and that is right under a given scope P.
void add_data_member(class_or_union_sptr cou, var_decl_sptr v, access_specifier access, bool is_laid_out, bool is_static, size_t offset_in_bits)
Add a data member to the current instance of class_or_union.
weak_ptr< var_decl > var_decl_wptr
Convenience typedef for a weak pointer on a var_decl.
bool equals(const decl_base &l, const decl_base &r, change_kind *k, bool qualified_name, bool linkage_name)
Compares two instances of decl_base.
bool is_template_parm_composition_type(const shared_ptr< decl_base > decl)
Tests whether a decl is a template parameter composition type.
bool is_function_template_pattern(decl_base_sptr decl)
Test whether a decl is the pattern of a function template.
bool get_member_is_static(const decl_base &d)
Gets a flag saying if a class member is static or not.
unordered_map< uint64_t_pair_type, bool, uint64_t_pair_hash > type_comparison_result_type
A convenience typedef for a map which key is a pair of uint64_t and which value is a boolean....
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.
const global_scope_sptr get_global_scope(decl_base_sptr decl)
Return the global scope as seen by a given declaration.
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.
interned_string get_function_symbol_id(const function_decl *fn)
Get the ID of the symbol of a function or the linkage name of the function if it has no symbol.
bool compare_canonical_type_against_candidate(const type_base_sptr &canonical_type, const type_base_sptr &candidate_type)
Compare a canonical type against a candidate canonical 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.
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.
void copy_missing_member_variables(class_or_union_sptr &dest_class, const class_or_union_sptr &src_class)
Copy missing data members from a source class_decl to a destination one.
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.
void add_member_function_template(class_or_union_sptr cou, member_function_template_sptr m)
Append a member function template to the class_or_union.
vector< type_base_wptr > type_base_wptrs_type
A convenience typedef for a vector of type_base_wptr.
type_base_sptr candidate_matches_a_canonical_type_hash(const list< type_base_sptr > &cncls, type_base &type)
Test if a candidate for type canonicalization coming from ABIXML matches a canonical type by first lo...
bool is_at_template_scope(decl_base_sptr decl)
Tests whether a given decl is at template scope.
weak_ptr< scope_decl > scope_decl_wptr
Convenience typedef for a weak pointer on a scope_decl.
class_or_union_sptr is_at_class_scope(const decl_base_sptr decl)
Tests whether a given decl is at class scope.
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(),...
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.
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.
bool remove_member_decl(scope_decl_sptr scope, decl_base_sptr member)
Remove a declaration from the current scope.
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.
unordered_set< const class_or_union * > class_set_type
A convenience typedef for a set of pointer to class_or_union.
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 get_exemplar_type(type_base_sptr type)
For a given type, return its exemplar type.
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.
namespace_decl_sptr is_namespace(const type_or_decl_base_sptr &d)
Tests if a declaration is a namespace declaration.
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.
typedef_decl_sptr copy_missing_naming_typedef(decl_base_sptr type, const decl_base_sptr named_type)
Copy the naming typedef from a named type to an unnamed one.
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.
void maybe_update_types_lookup_map(const decl_base_sptr decl)
Update the map that associates the fully qualified name of a type declaration with the type itself.
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...
unordered_set< const function_type * > fn_set_type
A convenience typedef for a set of pointer to function_type.
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.
void move_member_type_to_canonicalized_scope(decl_base_sptr member_type)
Move a member type from its current scope to the canonical type of its current scope.
decl_base_sptr lookup_var_decl_in_scope(const string &fqn, scope_decl_sptr skope)
Lookup a var_decl in a scope.
shared_ptr< c14n_task > c14n_task_sptr
A convenience typedef for a shared pointer to c14n_task.
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.
scope_decl_sptr get_scope_of_type(type_base &type)
Getter of the scope of a type.
void unmark_types_as_being_compared(T &l, T &r)
Mark a pair of types as being not compared anymore.
decl_base_sptr add_member_decl(scope_decl_sptr scope, 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_...
vector< type_base_sptr > type_base_sptrs_type
Helper typedef for a vector of shared pointer to a type_base.
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.
shared_ptr< global_scope > global_scope_sptr
Convenience typedef for shared pointer on global_scope.
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.
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.
decl_base_sptr insert_decl_into_scope(decl_base_sptr decl, scope_decl::declarations::iterator before, scope_decl_sptr scope)
Inserts a declaration into a given scope, before a given IR child node of the scope.
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.
void bind_function_type_life_time(const function_type_sptr &fn_type, translation_unit_sptr tu)
Bind the life time of a function type to the file time of a given translation unit.
type_base_sptr peel_const_qualified_type(const qualified_type_def_sptr &q)
If a qualified type is const, then return its underlying type.
bool maybe_update_types_lookup_map< function_type >(const function_type_sptr type, istring_type_base_wptrs_map_type &types_map, recursive_mutex &mutex, bool)
This is the specialization for type function_type of the function template:
bool has_defined_virtual_mem_fn(const class_decl &klass)
Test if a class has at least one member function which has a defined and exported symbol.
const class_or_union_sptr data_member_has_anonymous_type(const var_decl &d)
Test if a data member has annonymous type or not.
void maybe_adjust_canonical_type(const type_base_sptr &canonical, const type_base_sptr &type)
This is a subroutine of the canonicalize() function.
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.
void add_type(type_base_sptr t, homonym_type_group_sptr group)
Add a type to a homonym type group.
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.
function_decl_sptr is_at_function_scope(const decl_base &decl)
Tests whether a given decl is at function scope.
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.
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.
interned_string get_function_symbol_id_if_unique(const function_decl *fn)
Get the ID of the symbol of a function, or, if the ID can designate several different functions,...
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.
bool is_template_parameter(decl_base_sptr decl)
Tests whether a decl is a template parameter.
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.
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.
void perform_type_canonicalization(vector< type_base_sptr > &types, bool do_log, bool show_stats)
Hash and canonicalize a sequence of types.
void copy_missing_member_functions(class_or_union_sptr &dest_class, const class_or_union_sptr &src_class, bool copy_virtual_functions)
Copy missing member functions from a source class_decl to a destination one.
unordered_map< interned_string, bool, hash_interned_string > interned_string_bool_map_type
Convenience typedef for a map of interned_string -> bool.
bool compute_canonical_type_index(const list< type_base_sptr > &adjacent_canonical_types, const type_base_sptr canonical_type, int &resulting_index)
Compute the canonical type index of a recently designated canonical type.
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.
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.
bool enum_equals_modulo_name(const enum_type_decl &l, const enum_type_decl &r, change_kind *k)
Test if two enums are equal modulo their names. That is, the test compares the two enums as if they d...
corpus::origin operator&(corpus::origin l, corpus::origin r)
Bitwise & operator for the corpus::origin type.
void move_member_type(decl_base_sptr member_type, scope_decl_sptr new_scope)
Move a member type of a scope_decl to another scope_decl.
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.
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.
string build_qualified_name(const scope_decl_sptr scope, const string &name)
Build and return a qualified name from a name and its scope.
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 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.
bool maybe_update_types_lookup_map< class_decl >(const class_decl_sptr class_type, istring_type_base_wptrs_map_type &map, recursive_mutex &mutex, bool use_type_name_as_key)
This is the specialization for type class_decl of the function template:
void add_member_function(class_or_union_sptr cou, method_decl_sptr f, access_specifier a, bool is_static, bool is_ctor, bool is_dtor, bool is_const)
Add a member function.
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.
type_base_sptr canonicalize(type_base_sptr type, homonym_type_group_sptr group, bool do_log=false, bool show_stats=false)
Compute the canonical type of a given type.
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.
decl_base_sptr insert_member_decl(scope_decl_sptr scope, decl_base_sptr member, scope_decl::declarations::iterator before)
Insert a member decl to a scope, right before an element pointed to by a given iterator....
void sort_types_for_hash_computing_and_c14n(IteratorType begin, IteratorType end, bool do_log=false)
Sort types before hashing (and then canonicalizing) them.
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.
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 hash_and_canonicalize_type(type_base_sptr t)
Hash and canonicalize a type.
scope_decl_sptr get_type_scope(type_base *t)
Get the scope of a given type.
void set_member_function_virtuality(const function_decl_sptr &fn, bool is_virtual, ssize_t voffset)
Set the virtual-ness of a member fcuntion.
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.
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.
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...
void sort_types(IteratorType begin, IteratorType end, SortingFunctorType comp, bool do_log=false)
Sort types.
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.
void insert_member_type(scope_decl_sptr scope, type_base_sptr t, scope_decl::declarations::iterator before)
Insert a member type to a given scope.
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.
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.
unordered_set< type_base_sptr, shallow_type_hasher, shallow_type_eq > type_sptr_set_type
Convenience typedef for a set of type_base_sptr.
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.
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 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.
void set_pattern(function_tdecl_sptr ftdecl, function_decl_sptr p)
Set a new pattern to the function template.
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.
void move_missing_member_types(class_or_union_sptr dest_class_or_union, class_or_union_sptr src_class_or_union)
Move member types that are present in src_class_or_union but missing from dest_class_or_union into de...
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.
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.
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,...
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.
type_base_sptr maybe_move_missing_member_type(class_or_union_sptr dest_class_or_union, type_base_sptr src_member_type)
Move a member type from its current class or union scope to a destination class or union,...
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.
void add_canonical_type(type_base_sptr t, homonym_type_group_sptr group)
Add a canonical type to a homonym type group.
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.
void add_member_class_template(class_or_union_sptr cou, member_class_template_sptr m)
Append a member class template to the class_or_union.
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.
void canonicalize_homonym_type_groups(const vector< homonym_type_group_sptr > &groups, bool do_log, bool show_stats)
Canonicalize types coming from a vector of homonym_type_group_sptr in //.
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.
bool compare_using_locations(const decl_base *f, const decl_base *s, bool &comp_result)
Compare decls using their locations.
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.
size_t get_number_of_available_threads()
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.
A task that canonicalizes one homonym type group in its own thread.
size_t operator()(const type_base_sptr &l) const
Hash a type by returning the pointer value of its canonical type.
The private data for the class_decl type.
Hasher for the class_or_union type.
static bool is_printing_flat_representation(const class_or_union *cou)
Test if a given instance of class_or_union is being flat-representation-printed.
static void set_printing_flat_representation(const class_or_union *cou)
Mark a given instance of class_or_union as being flat-representation-printed.
static void unset_printing_flat_representation(const class_or_union *cou)
Un-mark a given instance of class_or_union as being flat-representation-printed.
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.
static size_t compute_number_of_threads_to_use()
Compute the number of threads to use by looking at if multithreading is enabled in libabigail at all....
static void clear_type_comparison_results_cache()
Clear the cache type comparison results.
static size_t process_thread_pool_size_string(const string &tps)
Process a thread pool size string and convert it to a numeric value.
static bool allow_type_comparison_results_caching()
Check whether if caching of the sub-types comparison results during the invocation of the equal overl...
Equality functor for instances of function_decl.
The hashing functor for function_type.
The type of the private data of the function_type type.
static void unset_is_pretty_printing(function_type *fn_type)
Unmark a given function pointer as being pretty-printed by add_outer_pointer_to_fn_type_expr.
static void set_is_pretty_printing(function_type *fn_type)
Mark a given function pointer as being pretty-printed by add_outer_pointer_to_fn_type_expr.
static bool is_pretty_printing(function_type *fn_type)
Getter of the 'is_pretty_printing_' boolean.
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.