diff options
author | Howard Hinnant <hhinnant@apple.com> | 2012-01-22 01:23:02 +0000 |
---|---|---|
committer | Howard Hinnant <hhinnant@apple.com> | 2012-01-22 01:23:02 +0000 |
commit | facfc46ef3ecde55e675fa19d93d9a25b169c49f (patch) | |
tree | c800cd4558ad93a3024a0d4412458cb957d49f10 /src/private_typeinfo.cpp | |
parent | 321a095c08f0700e8619266518b63d438285d3a1 (diff) | |
download | libcxxabi_35a-facfc46ef3ecde55e675fa19d93d9a25b169c49f.tar.gz |
Add __shim_type_info which fits below std::type_info and above all of the other type_info-derived classes. This is where all of the virtual functions that serve as details of the inner-workings of type_info will live (safely hidden from public view). All type_info objects will be safely down-castable to __shim_type_info, so as to access implementation detail virtual functions. Also temporarily add some print/display statements to each type_info-derived class. This is in support of the continuing development on the personality function.
git-svn-id: https://llvm.org/svn/llvm-project/libcxxabi/trunk@148647 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'src/private_typeinfo.cpp')
-rw-r--r-- | src/private_typeinfo.cpp | 210 |
1 files changed, 187 insertions, 23 deletions
diff --git a/src/private_typeinfo.cpp b/src/private_typeinfo.cpp index 47c1b62..3bf0ea4 100644 --- a/src/private_typeinfo.cpp +++ b/src/private_typeinfo.cpp @@ -7,20 +7,36 @@ // //===----------------------------------------------------------------------===// +#define __name __type_name + #include "private_typeinfo.h" +#include <iostream> + namespace std { +#pragma GCC visibility push(default) + type_info::~type_info() { } +#pragma GCC visibility pop + } // std namespace __cxxabiv1 { +#pragma GCC visibility push(hidden) + +// __shim_type_info + +__shim_type_info::~__shim_type_info() +{ +} + // __fundamental_type_info // This miraculously (compiler magic) emits the type_info's for: @@ -31,42 +47,101 @@ __fundamental_type_info::~__fundamental_type_info() { } +void +__fundamental_type_info::display() const +{ + std::cout << "__fundamental_type_info " << __type_name << '\n'; +} + // __array_type_info __array_type_info::~__array_type_info() { } +void +__array_type_info::display() const +{ + std::cout << "__array_type_info " << __type_name << '\n'; +} + // __function_type_info __function_type_info::~__function_type_info() { } +void +__function_type_info::display() const +{ + std::cout << "__function_type_info " << __type_name << '\n'; +} + // __enum_type_info __enum_type_info::~__enum_type_info() { } +void +__enum_type_info::display() const +{ + std::cout << "__enum_type_info " << __type_name << '\n'; +} + // __class_type_info __class_type_info::~__class_type_info() { } +void +__class_type_info::display() const +{ + std::cout << "__class_type_info " << __type_name << '\n'; +} + // __si_class_type_info __si_class_type_info::~__si_class_type_info() { } +void +__si_class_type_info::display() const +{ + std::cout << "__si_class_type_info " << __type_name << '\n'; + std::cout << "derived from "; + __base_type->display(); +} + // __vmi_class_type_info __vmi_class_type_info::~__vmi_class_type_info() { } +void +__vmi_class_type_info::display() const +{ + std::cout << "__vmi_class_type_info " << __type_name << '\n'; + if (__flags & __non_diamond_repeat_mask) + std::cout << "__non_diamond_repeat_mask\n"; + if (__flags & __diamond_shaped_mask) + std::cout << "__diamond_shaped_mask\n"; + std::cout << "derived from\n"; + for (const __base_class_type_info* p = __base_info; p < __base_info + __base_count; ++p) + p->display(); +} + +void +__base_class_type_info::display() const +{ + if (__offset_flags & __public_mask) + std::cout << "public "; + __base_type->display(); +} + // __pbase_type_info __pbase_type_info::~__pbase_type_info() @@ -79,12 +154,53 @@ __pointer_type_info::~__pointer_type_info() { } +void +__pointer_type_info::display() const +{ + std::cout << "__pointer_type_info " << __type_name << '\n'; + if (__flags & __const_mask) + std::cout << "const "; + if (__flags & __volatile_mask) + std::cout << "volatile "; + if (__flags & __restrict_mask) + std::cout << "restrict "; + if (__flags & __incomplete_mask) + std::cout << "__incomplete_mask "; + if (__flags & __incomplete_class_mask) + std::cout << "__incomplete_class_mask "; + std::cout << "pointer to "; + __pointee->display(); +} + // __pointer_to_member_type_info __pointer_to_member_type_info::~__pointer_to_member_type_info() { } +void +__pointer_to_member_type_info::display() const +{ + std::cout << "__pointer_to_member_type_info " << __type_name << '\n'; + if (__flags & __const_mask) + std::cout << "const "; + if (__flags & __volatile_mask) + std::cout << "volatile "; + if (__flags & __restrict_mask) + std::cout << "restrict "; + if (__flags & __incomplete_mask) + std::cout << "__incomplete_mask "; + if (__flags & __incomplete_class_mask) + std::cout << "__incomplete_class_mask "; + std::cout << "member pointer to class "; + __context->display(); + std::cout << "and type "; + __pointee->display(); +} + +#pragma GCC visibility pop +#pragma GCC visibility push(default) + // __dynamic_cast // static_ptr: pointer to an object of type static_type; nonnull, and since the @@ -137,6 +253,7 @@ __pointer_to_member_type_info::~__pointer_to_member_type_info() // static_type in the DAG. // // dst_type != static_type: The compiler computes the dynamic_cast in this case too. +// dynamic_type != static_type: The compiler computes the dynamic_cast in this case too. // // Returns: // @@ -147,7 +264,7 @@ __pointer_to_member_type_info::~__pointer_to_member_type_info() // path from (dynamic_ptr, dynamic_type) to the one dst_type, then return // a pointer to that dst_type. // Else if there are 0 dst_types of flavor 1 and exactly 1 dst_type of flavor 2, and -// if there is a public path (dynamic_ptr, dynamic_type) to +// if there is a public path from (dynamic_ptr, dynamic_type) to // (static_ptr, static_type) and a public path from (dynamic_ptr, dynamic_type) // to the one dst_type, then return a pointer to that one dst_type. // Else return nullptr. @@ -219,6 +336,9 @@ __dynamic_cast(const void* static_ptr, return const_cast<void*>(dst_ptr); } +#pragma GCC visibility pop +#pragma GCC visibility push(hidden) + // Call this function when you hit a static_type which is a base (above) a dst_type. // Let caller know you hit a static_type. But only start recording details if // this is (static_ptr, static_type) -- the node we are casting from. @@ -272,8 +392,6 @@ __class_type_info::process_static_type_above_dst(__dynamic_cast_info* info, } // Call this function when you hit a static_type which is not a base (above) a dst_type. -// Let caller know you hit a static_type (this may not be necessary). -// But only start recording details if this is (static_ptr, static_type) -- the node we are casting from. // If this is (static_ptr, static_type) // Record the path (public or not) from (dynamic_ptr, dynamic_type) to here. There may be // multiple paths from (dynamic_ptr, dynamic_type) to here, record the "most public" one. @@ -302,18 +420,48 @@ __class_type_info::process_static_type_below_dst(__dynamic_cast_info* info, // If this is neither a static_type nor a dst_type node, continue searching // base classes above. // All the hoopla surrounding the search code is doing nothing but looking for -// excuses to stop the search prematurely (break out of the for-loop): -// -// const Iter e = __base_info + __base_count; -// for (Iter p = __base_info; p < e; ++p) -// p->search_above_dst(info, current_ptr, current_ptr, path_below); -// -// or: -// -// const Iter e = __base_info + __base_count; -// for (Iter p = __base_info; p < e; ++p) -// p->search_below_dst(info, current_ptr, path_below); -// +// excuses to stop the search prematurely (break out of the for-loop). That is, +// the algorithm below is simply an optimization of this: +// void +// __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, +// const void* current_ptr, +// int path_below) const +// { +// typedef const __base_class_type_info* Iter; +// if (this == info->static_type) +// process_static_type_below_dst(info, current_ptr, path_below); +// else if (this == info->dst_type) +// { +// // Record the most public access path that got us here +// if (info->path_dynamic_ptr_to_dst_ptr != public_path) +// info->path_dynamic_ptr_to_dst_ptr = path_below; +// bool does_dst_type_point_to_our_static_type = false; +// for (Iter p = __base_info, e= __base_info + __base_count; p < e; ++p) +// { +// p->search_above_dst(info, current_ptr, current_ptr, public_path); +// if (info->found_our_static_ptr) +// does_dst_type_point_to_our_static_type = true; +// // break out early here if you can detect it doesn't matter if you do +// } +// if (!does_dst_type_point_to_our_static_type) +// { +// // We found a dst_type that doesn't point to (static_ptr, static_type) +// // So record the address of this dst_ptr and increment the +// // count of the number of such dst_types found in the tree. +// info->dst_ptr_not_leading_to_static_ptr = current_ptr; +// info->number_to_dst_ptr += 1; +// } +// } +// else +// { +// // This is not a static_type and not a dst_type. +// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) +// { +// p->search_below_dst(info, current_ptr, public_path); +// // break out early here if you can detect it doesn't matter if you do +// } +// } +// } void __vmi_class_type_info::search_below_dst(__dynamic_cast_info* info, const void* current_ptr, @@ -608,14 +756,28 @@ __class_type_info::search_below_dst(__dynamic_cast_info* info, // for a public path to (static_ptr, static_type). // This function is guaranteed not to find a node of type dst_type. // Theoretically this is a very simple function which just stops if it finds a -// static_type node, else keeps searching with: -// -// const Iter e = __base_info + __base_count; -// for (Iter p = __base_info; p < e; ++p) -// p->search_above_dst(info, dst_ptr, current_ptr, path_below); -// -// All the hoopla surrounding the search code is doing nothing but looking for -// excuses to stop the search prematurely (break out of the for-loop). +// static_type node: All the hoopla surrounding the search code is doing +// nothing but looking for excuses to stop the search prematurely (break out of +// the for-loop). That is, the algorithm below is simply an optimization of this: +// void +// __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, +// const void* dst_ptr, +// const void* current_ptr, +// int path_below) const +// { +// if (this == info->static_type) +// process_static_type_above_dst(info, dst_ptr, current_ptr, path_below); +// else +// { +// typedef const __base_class_type_info* Iter; +// // This is not a static_type and not a dst_type +// for (Iter p = __base_info, e = __base_info + __base_count; p < e; ++p) +// { +// p->search_above_dst(info, dst_ptr, current_ptr, public_path); +// // break out early here if you can detect it doesn't matter if you do +// } +// } +// } void __vmi_class_type_info::search_above_dst(__dynamic_cast_info* info, const void* dst_ptr, @@ -750,4 +912,6 @@ __base_class_type_info::search_below_dst(__dynamic_cast_info* info, not_public_path); } +#pragma GCC visibility pop + } // __cxxabiv1 |