summaryrefslogtreecommitdiff
path: root/clang/test/CodeGenCXX/class-layout.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CodeGenCXX/class-layout.cpp')
-rw-r--r--clang/test/CodeGenCXX/class-layout.cpp79
1 files changed, 79 insertions, 0 deletions
diff --git a/clang/test/CodeGenCXX/class-layout.cpp b/clang/test/CodeGenCXX/class-layout.cpp
new file mode 100644
index 0000000..dac0a0a
--- /dev/null
+++ b/clang/test/CodeGenCXX/class-layout.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 %s -triple x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+// An extra byte should be allocated for an empty class.
+namespace Test1 {
+ // CHECK: %"struct.Test1::A" = type { i8 }
+ struct A { } *a;
+}
+
+namespace Test2 {
+ // No need to add tail padding here.
+ // CHECK: %"struct.Test2::A" = type { i8*, i32 }
+ struct A { void *a; int b; } *a;
+}
+
+namespace Test3 {
+ // C should have a vtable pointer.
+ // CHECK: %"struct.Test3::A" = type { i32 (...)**, i32 }
+ struct A { virtual void f(); int a; } *a;
+}
+
+namespace Test4 {
+ // Test from PR5589.
+ // CHECK: %"struct.Test4::B" = type { %"struct.Test4::A", i16, double }
+ // CHECK: %"struct.Test4::A" = type { i32, i8, float }
+ struct A {
+ int a;
+ char c;
+ float b;
+ };
+ struct B : public A {
+ short d;
+ double e;
+ } *b;
+}
+
+namespace Test5 {
+ struct A {
+ virtual void f();
+ char a;
+ };
+
+ // CHECK: %"struct.Test5::B" = type { [9 x i8], i8, i8, [5 x i8] }
+ struct B : A {
+ char b : 1;
+ char c;
+ } *b;
+}
+
+// PR10912: don't crash
+namespace Test6 {
+ template <typename T> class A {
+ // If T is complete, IR-gen will want to translate it recursively
+ // when translating T*.
+ T *foo;
+ };
+
+ class B;
+
+ // This causes IR-gen to have an incomplete translation of A<B>
+ // sitting around.
+ A<B> *a;
+
+ class C {};
+ class B : public C {
+ // This forces Sema to instantiate A<B>, which triggers a callback
+ // to IR-gen. Because of the previous, incomplete translation,
+ // IR-gen actually cares, and it immediately tries to complete
+ // A<B>'s IR type. That, in turn, causes the translation of B*.
+ // B isn't complete yet, but it has a definition, and if we try to
+ // compute a record layout for that definition then we'll really
+ // regret it later.
+ A<B> a;
+ };
+
+ // The derived class E and empty base class C are required to
+ // provoke the original assertion.
+ class E : public B {};
+ E *e;
+}