[cfe-commits] [libcxxabi] r148647 - in /libcxxabi/trunk/src: private_typeinfo.cpp private_typeinfo.h
Howard Hinnant
hhinnant at apple.com
Sat Jan 21 17:23:03 PST 2012
Author: hhinnant
Date: Sat Jan 21 19:23:02 2012
New Revision: 148647
URL: http://llvm.org/viewvc/llvm-project?rev=148647&view=rev
Log:
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.
Modified:
libcxxabi/trunk/src/private_typeinfo.cpp
libcxxabi/trunk/src/private_typeinfo.h
Modified: libcxxabi/trunk/src/private_typeinfo.cpp
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.cpp?rev=148647&r1=148646&r2=148647&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.cpp (original)
+++ libcxxabi/trunk/src/private_typeinfo.cpp Sat Jan 21 19:23:02 2012
@@ -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 @@
{
}
+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 @@
{
}
+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 @@
// 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 @@
// 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 @@
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 @@
}
// 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 @@
// 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 @@
// 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 @@
not_public_path);
}
+#pragma GCC visibility pop
+
} // __cxxabiv1
Modified: libcxxabi/trunk/src/private_typeinfo.h
URL: http://llvm.org/viewvc/llvm-project/libcxxabi/trunk/src/private_typeinfo.h?rev=148647&r1=148646&r2=148647&view=diff
==============================================================================
--- libcxxabi/trunk/src/private_typeinfo.h (original)
+++ libcxxabi/trunk/src/private_typeinfo.h Sat Jan 21 19:23:02 2012
@@ -16,32 +16,47 @@
namespace __cxxabiv1
{
-class __fundamental_type_info
+#pragma GCC visibility push(hidden)
+
+class __shim_type_info
: public std::type_info
{
public:
+ virtual ~__shim_type_info();
+
+ virtual void display() const = 0;
+};
+
+class __fundamental_type_info
+ : public __shim_type_info
+{
+public:
virtual ~__fundamental_type_info();
+ virtual void display() const;
};
class __array_type_info
- : public std::type_info
+ : public __shim_type_info
{
public:
virtual ~__array_type_info();
+ virtual void display() const;
};
class __function_type_info
- : public std::type_info
+ : public __shim_type_info
{
public:
virtual ~__function_type_info();
+ virtual void display() const;
};
class __enum_type_info
- : public std::type_info
+ : public __shim_type_info
{
public:
virtual ~__enum_type_info();
+ virtual void display() const;
};
enum
@@ -104,7 +119,7 @@
// Has no base class
class __class_type_info
- : public std::type_info
+ : public __shim_type_info
{
public:
virtual ~__class_type_info();
@@ -113,6 +128,7 @@
void process_static_type_below_dst(__dynamic_cast_info*, const void*, int) const;
virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const;
virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const;
+ virtual void display() const;
};
// Has one non-virtual public base class at offset zero
@@ -126,6 +142,7 @@
virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const;
virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const;
+ virtual void display() const;
};
struct __base_class_type_info
@@ -143,6 +160,7 @@
void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const;
void search_below_dst(__dynamic_cast_info*, const void*, int) const;
+ void display() const;
};
// Has one or more base classes
@@ -166,14 +184,15 @@
virtual void search_above_dst(__dynamic_cast_info*, const void*, const void*, int) const;
virtual void search_below_dst(__dynamic_cast_info*, const void*, int) const;
+ virtual void display() const;
};
class __pbase_type_info
- : public std::type_info
+ : public __shim_type_info
{
public:
unsigned int __flags;
- const std::type_info* __pointee;
+ const __shim_type_info* __pointee;
enum __masks
{
@@ -192,6 +211,7 @@
{
public:
virtual ~__pointer_type_info();
+ virtual void display() const;
};
class __pointer_to_member_type_info
@@ -201,8 +221,11 @@
const __class_type_info* __context;
virtual ~__pointer_to_member_type_info();
+ virtual void display() const;
};
+#pragma GCC visibility pop
+
} // __cxxabiv1
#endif // __PRIVATE_TYPEINFO_H_
More information about the cfe-commits
mailing list