1*67e74705SXin Li // RUN: %clang_cc1 -triple i686-linux-gnu %s -emit-llvm -o - | FileCheck %s 2*67e74705SXin Li 3*67e74705SXin Li class A { 4*67e74705SXin Li // append has to have the same prototype as fn1 to tickle the bug. 5*67e74705SXin Li void (*append)(A *); 6*67e74705SXin Li }; 7*67e74705SXin Li 8*67e74705SXin Li class B {}; 9*67e74705SXin Li class D; 10*67e74705SXin Li 11*67e74705SXin Li // C has to be non-C++98 POD with available tail padding, making the LLVM base 12*67e74705SXin Li // type differ from the complete LLVM type. 13*67e74705SXin Li class C { 14*67e74705SXin Li // This member creates a circular LLVM type reference to %class.D. 15*67e74705SXin Li D *m_group; 16*67e74705SXin Li B changeListeners; 17*67e74705SXin Li }; 18*67e74705SXin Li class D : C {}; 19*67e74705SXin Li fn1(A * p1)20*67e74705SXin Livoid fn1(A *p1) { 21*67e74705SXin Li } 22*67e74705SXin Li 23*67e74705SXin Li void fn2(C *)24*67e74705SXin Lifn2(C *) { 25*67e74705SXin Li } 26*67e74705SXin Li 27*67e74705SXin Li // We end up using an opaque type for 'append' to avoid circular references. 28*67e74705SXin Li // CHECK: %class.A = type { {}* } 29*67e74705SXin Li // CHECK: %class.C = type <{ %class.D*, %class.B, [3 x i8] }> 30*67e74705SXin Li // CHECK: %class.D = type { %class.C.base, [3 x i8] } 31*67e74705SXin Li // CHECK: %class.C.base = type <{ %class.D*, %class.B }> 32*67e74705SXin Li // CHECK: %class.B = type { i8 } 33