1 // { dg-do compile }
2 // { dg-additional-options "-Wno-psabi -Wno-return-type" }
3 // Ignore warning on some powerpc-linux configurations.
4 // { dg-prune-output "non-standard ABI extension" }
5 
6 typedef float __m128 __attribute__ ((__vector_size__ (16)));
7 const int a = 0;
8 enum
9 {
10   ReadOnlyAccessors
11 };
12 template <typename> struct traits;
13 struct A
14 {
15   enum
16   {
17     value = 1
18   };
19 };
20 template <typename> struct EigenBase;
21 template <typename> class J;
22 template <typename, int = A::value> class DenseCoeffsBase;
23 template <typename, int, int, int = 0, int = 0, int = 0> class K;
24 template <typename> class N;
25 template <typename, typename> class CwiseUnaryOp;
26 template <typename> class L;
27 template <typename> class P;
28 template <typename> struct B;
29 template <typename> struct C;
30 template <typename Derived> struct dense_xpr_base
31 {
32   typedef N<Derived> type;
33 };
34 template <typename Packet> void padd (Packet);
35 template <> struct C<float>
36 {
37   typedef __m128 type;
38 };
39 struct D
40 {
41   void
42   packetOp (C<float>::type)
43   {
44     __m128 b = { m_other };
45     padd (b);
46   }
47   float m_other;
48 };
49 template <typename Derived>
50 class DenseCoeffsBase<Derived, ReadOnlyAccessors> : public EigenBase<Derived>
51 {
52 public:
53   typedef typename C<typename traits<Derived>::Scalar>::type PacketScalar;
54 };
55 template <typename Derived>
56 class DenseCoeffsBase<Derived>
57     : public DenseCoeffsBase<Derived, ReadOnlyAccessors>
58 {
59 public:
60   template <typename OtherDerived, int, int LoadMode>
61   void
62   copyPacket (typename traits<Derived>::Index, J<OtherDerived> p2)
63   {
64     p2.derived ().template packet<LoadMode> (0);
65   }
66 };
67 template <typename Derived> class J : public DenseCoeffsBase<Derived>
68 {
69 public:
70   using DenseCoeffsBase<Derived>::derived;
71   template <typename OtherDerived>
72   Derived &lazyAssign (const J<OtherDerived> &);
73 };
74 template <typename Derived> class N : public J<Derived>
75 {
76 public:
77   template <typename OtherDerived>
78   typename B<OtherDerived>::Type operator*(N<OtherDerived>);
79   L<Derived> array ();
80 };
81 template <typename Derived> struct EigenBase
82 {
83   Derived
84   derived () const
85   {
86     return *static_cast<const Derived *> (this);
87   }
88 };
89 template <typename Derived1, typename Derived2> struct F
90 {
91   static void
92   run (Derived1 p1, Derived2 p2)
93   {
94     enum
95     {
96       srcAlignment
97     };
98     for (;;)
99       p1.template copyPacket<Derived2, 0, srcAlignment> (0, p2);
100   }
101 };
102 template <typename Derived>
103 template <typename OtherDerived>
104 Derived &
105 J<Derived>::lazyAssign (const J<OtherDerived> &p1)
106 {
107   F<Derived, OtherDerived>::run (derived (), p1.derived ());
108 }
109 template <typename Derived, typename OtherDerived> struct G
110 {
111   static Derived
112   run (Derived p1, OtherDerived p2)
113   {
114     p1.lazyAssign (p2);
115   }
116 };
117 class H
118 {
119 public:
120   H (int, int, int);
121 };
122 template <typename Derived> class M : public dense_xpr_base<Derived>::type
123 {
124 public:
125   typedef typename traits<Derived>::Index Index;
126   H m_storage;
127   M (Index, Index, Index) : m_storage (0, 0, 0) {}
128   template <typename OtherDerived>
129   void
130   _set_noalias (J<OtherDerived> p1)
131   {
132     G<Derived, OtherDerived>::run (this->derived (), p1.derived ());
133   }
134 };
135 template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows,
136           int _MaxCols>
137 struct traits<K<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
138 {
139   typedef _Scalar Scalar;
140   typedef int StorageKind;
141   typedef int Index;
142 };
143 template <typename, int _Rows, int _Cols, int, int, int>
144 class K : public M<K<float, _Rows, _Cols> >
145 {
146 public:
147   typedef M<K> Base;
148   typedef K Nested;
149   template <typename T0, typename T1> K (T0, T1);
150   template <typename OtherDerived> K (N<OtherDerived> p1) : Base (0, 0, 0)
151   {
152     Base::_set_noalias (p1);
153   }
154 };
155 template <typename UnaryOp, typename XprType>
156 struct traits<CwiseUnaryOp<UnaryOp, XprType> > : traits<XprType>
157 {
158 };
159 template <typename, typename, typename> class I;
160 template <typename, typename XprType>
161 class CwiseUnaryOp
162     : public I<D, XprType, typename traits<XprType>::StorageKind>
163 {
164 public:
165   D
166   functor ()
167   {
168     return m_functor;
169   }
170   typename XprType::Nested nestedExpression ();
171   D m_functor;
172 };
173 template <typename UnaryOp, typename XprType>
174 class I<UnaryOp, XprType, int>
175     : public dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
176 {
177 public:
178   typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
179   typedef typename dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
180   typedef Derived Nested;
181   using Base::derived;
182   template <int LoadMode> void packet (typename traits<Derived>::Index)
183   {
184     derived ().functor ().packetOp (
185         derived ().nestedExpression ().template packet<LoadMode> (0));
186   }
187 };
188 template <typename> struct B
189 {
190   typedef P<CwiseUnaryOp<D, L<K<float, 0, 1> > > > Type;
191 };
192 template <typename Derived> class O : public J<Derived>
193 {
194 public:
195   P<Derived> matrix ();
196 };
197 template <typename ExpressionType>
198 struct traits<L<ExpressionType> > : traits<typename ExpressionType::Nested>
199 {
200 };
201 template <typename ExpressionType> class L : public O<L<ExpressionType> >
202 {
203 public:
204   typedef L Nested;
205   template <int>
206   typename O<L>::PacketScalar packet (typename traits<L>::Index);
207 };
208 template <typename ExpressionType>
209 struct traits<P<ExpressionType> > : traits<typename ExpressionType::Nested>
210 {
211 };
212 template <typename ExpressionType> class P : public N<P<ExpressionType> >
213 {
214 public:
215   N<P> Base;
216   template <int LoadMode> void packet (typename traits<P>::Index)
217   {
218     m_expression.template packet<LoadMode> (0);
219   }
220   ExpressionType m_expression;
221 };
222 int
223 main ()
224 {
225   K<float, 0, a> m (0, 0);
226   K<float, 0, 1> c (0, 0);
227   c = m.array ().matrix () * m;
228 }
229