aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--test/CodeGenCXX/rtti-layout.cpp39
1 files changed, 38 insertions, 1 deletions
diff --git a/test/CodeGenCXX/rtti-layout.cpp b/test/CodeGenCXX/rtti-layout.cpp
index e3b5456f4d..5f9cdab8f5 100644
--- a/test/CodeGenCXX/rtti-layout.cpp
+++ b/test/CodeGenCXX/rtti-layout.cpp
@@ -6,12 +6,14 @@ extern "C" {
const void *_ZTVN10__cxxabiv123__fundamental_type_infoE;
const void *_ZTVN10__cxxabiv117__class_type_infoE;
const void *_ZTVN10__cxxabiv120__si_class_type_infoE;
+ const void *_ZTVN10__cxxabiv121__vmi_class_type_infoE;
const void *_ZTVN10__cxxabiv119__pointer_type_infoE;
const void *_ZTVN10__cxxabiv129__pointer_to_member_type_infoE;
};
#define fundamental_type_info_vtable _ZTVN10__cxxabiv123__fundamental_type_infoE
#define class_type_info_vtable _ZTVN10__cxxabiv117__class_type_infoE
#define si_class_type_info_vtable _ZTVN10__cxxabiv120__si_class_type_infoE
+#define vmi_class_type_info_vtable _ZTVN10__cxxabiv121__vmi_class_type_infoE
#define pointer_type_info_vtable _ZTVN10__cxxabiv119__pointer_type_infoE
#define pointer_to_member_type_info_vtable _ZTVN10__cxxabiv129__pointer_to_member_type_infoE
@@ -34,7 +36,17 @@ return static_cast<const T&>(info);
}
struct Incomplete;
-struct A { };
+struct A { int a; };
+struct Empty { };
+
+struct SI1 : A { };
+struct SI2 : Empty { };
+struct SI3 : Empty { virtual void f() { } };
+
+struct VMI1 : private A { };
+struct VMI2 : virtual A { };
+struct VMI3 : A { virtual void f() { } };
+struct VMI4 : A, Empty { };
#define CHECK(x) if (!(x)) return __LINE__
#define CHECK_VTABLE(type, vtable) if (&vtable##_type_info_vtable + 2 != (((void **)&(typeid(type)))[0])) return __LINE__
@@ -44,6 +56,31 @@ int f() {
// Vectors should be treated as fundamental types.
typedef short __v4hi __attribute__ ((__vector_size__ (8)));
CHECK_VTABLE(__v4hi, fundamental);
+
+ // A does not have any bases.
+ CHECK_VTABLE(A, class);
+
+ // SI1 has a single public base.
+ CHECK_VTABLE(SI1, si_class);
+
+ // SI2 has a single public empty base.
+ CHECK_VTABLE(SI2, si_class);
+
+ // SI3 has a single public empty base. SI3 is dynamic whereas Empty is not, but since Empty is
+ // an empty class, it will still be at offset zero.
+ CHECK_VTABLE(SI3, si_class);
+
+ // VMI1 has a single base, but it is private.
+ CHECK_VTABLE(VMI1, vmi_class);
+
+ // VMI2 has a single base, but it is virtual.
+ CHECK_VTABLE(VMI2, vmi_class);
+
+ // VMI3 has a single base, but VMI3 is dynamic whereas A is not, and A is not empty.
+ CHECK_VTABLE(VMI3, vmi_class);
+
+ // VMI4 has two bases.
+ CHECK_VTABLE(VMI4, vmi_class);
// Pointers to incomplete classes.
CHECK_VTABLE(Incomplete *, pointer);