1// RUN: %clang_cc1 -g -triple %itanium_abi_triple -emit-llvm-only %s
2// Check that we don't crash.
3// PR12305, PR12315
4
5# 1 "a.h"  3
6template < typename T1 > struct Types1
7{
8  typedef T1 Head;
9};
10template < typename > struct Types;
11template < template < typename > class Tmpl > struct TemplateSel
12{
13  template < typename T > struct Bind
14  {
15    typedef Tmpl < T > type;
16  };
17};
18template < typename > struct NoneT;
19template < template < typename > class T1, template < typename > class > struct Templates2
20{
21  typedef TemplateSel < T1 > Head;
22};
23template < template < typename > class, template < typename > class =
24  NoneT, template < typename > class = NoneT, template < typename > class =
25  NoneT > struct Templates;
26template < template < typename > class T1,
27  template < typename > class T2 > struct Templates <T1, T2 >
28{
29  typedef Templates2 < T1, T2 > type;
30};
31template < typename T > struct TypeList
32{
33  typedef Types1 < T > type;
34};
35template < template < typename > class, class TestSel,
36  typename Types > class TypeParameterizedTest
37{
38public:static bool Register ()
39  {
40    typedef typename Types::Head Type;
41    typename TestSel::template Bind < Type >::type TestClass;
42}};
43
44template < template < typename > class Fixture, typename Tests,
45  typename Types > class TypeParameterizedTestCase
46{
47public:static bool Register (char *, char *, int *)
48  {
49    typedef typename Tests::Head Head;
50    TypeParameterizedTest < Fixture, Head, Types >::Register;
51}};
52
53template < typename > class TypedTestP1
54{
55};
56
57namespace gtest_case_TypedTestP1_
58{
59  template < typename gtest_TypeParam_ > class A:TypedTestP1 <
60    gtest_TypeParam_ >
61  {
62  };
63template < typename gtest_TypeParam_ > class B:TypedTestP1 <
64    gtest_TypeParam_ >
65  {
66  };
67  typedef Templates < A >::type gtest_AllTests_;
68}
69
70template < typename > class TypedTestP2
71{
72};
73
74namespace gtest_case_TypedTestP2_
75{
76  template < typename gtest_TypeParam_ > class A:TypedTestP2 <
77    gtest_TypeParam_ >
78  {
79  };
80  typedef Templates < A >::type gtest_AllTests_;
81}
82
83bool gtest_Int_TypedTestP1 =
84  TypeParameterizedTestCase < TypedTestP1,
85  gtest_case_TypedTestP1_::gtest_AllTests_,
86  TypeList < int >::type >::Register ("Int", "TypedTestP1", 0);
87bool gtest_Int_TypedTestP2 =
88  TypeParameterizedTestCase < TypedTestP2,
89  gtest_case_TypedTestP2_::gtest_AllTests_,
90  TypeList < Types < int > >::type >::Register ("Int", "TypedTestP2", 0);
91
92template < typename _Tp > struct new_allocator
93{
94  typedef _Tp *pointer;
95  template < typename > struct rebind {
96    typedef new_allocator other;
97  };
98};
99template < typename _Tp > struct allocator:new_allocator < _Tp > {
100};
101template < typename _Tp, typename _Alloc > struct _Vector_base {
102  typedef typename _Alloc::template rebind < _Tp >::other _Tp_alloc_type;
103  struct _Vector_impl {
104    typename _Tp_alloc_type::pointer _M_end_of_storage;
105  };
106  _Vector_base () {
107    foo((int *) this->_M_impl._M_end_of_storage);
108  }
109  void foo(int *);
110  _Vector_impl _M_impl;
111};
112template < typename _Tp, typename _Alloc =
113allocator < _Tp > >struct vector:_Vector_base < _Tp, _Alloc > { };
114
115
116template < class T> struct HHH {};
117struct DDD { int x_;};
118struct Data;
119struct X1;
120struct CCC:DDD {   virtual void xxx (HHH < X1 >); };
121template < class SSS > struct EEE:vector < HHH < SSS > > { };
122template < class SSS, class = EEE < SSS > >class FFF { };
123template < class SSS, class GGG = EEE < SSS > >class AAA:FFF <GGG> { };
124class BBB:virtual CCC {
125  void xxx (HHH < X1 >);
126  vector < HHH < X1 > >aaa;
127};
128class ZZZ:AAA < Data >, BBB { virtual ZZZ *ppp () ; };
129ZZZ * ZZZ::ppp () { return new ZZZ; }
130
131namespace std
132{
133  template < class, class > struct pair;
134}
135namespace __gnu_cxx {
136template < typename > class new_allocator;
137}
138namespace std {
139template < typename _Tp > class allocator:__gnu_cxx::new_allocator < _Tp > {
140};
141template < typename, typename > struct _Vector_base {
142};
143template < typename _Tp, typename _Alloc = std::allocator < _Tp > >class vector:_Vector_base < _Tp,
144  _Alloc
145        > {
146        };
147}
148
149namespace
150std {
151  template <
152      typename,
153      typename > struct unary_function;
154  template <
155      typename,
156      typename,
157      typename > struct binary_function;
158  template <
159      typename
160      _Tp > struct equal_to:
161        binary_function <
162        _Tp,
163        _Tp,
164        bool > {
165        };
166  template <
167      typename
168      _Pair > struct _Select1st:
169        unary_function <
170        _Pair,
171        typename
172        _Pair::first_type > {
173        };
174}
175# 1 "f.h"  3
176using
177std::pair;
178namespace
179__gnu_cxx {
180  template <
181      class > struct hash;
182  template <
183      class,
184      class,
185      class,
186      class,
187      class
188          _EqualKey,
189      class >
190          class
191          hashtable {
192           public:
193            typedef _EqualKey
194                key_equal;
195            typedef void key_type;
196          };
197  using
198      std::equal_to;
199  using
200      std::allocator;
201  using
202      std::_Select1st;
203  template < class _Key, class _Tp, class _HashFn =
204      hash < _Key >, class _EqualKey = equal_to < _Key >, class _Alloc =
205      allocator < _Tp > >class hash_map {
206        typedef
207            hashtable <
208            pair <
209            _Key,
210        _Tp >,
211        _Key,
212        _HashFn,
213        _Select1st <
214            pair <
215            _Key,
216        _Tp > >,
217        _EqualKey,
218        _Alloc >
219            _Ht;
220       public:
221        typedef typename _Ht::key_type key_type;
222        typedef typename
223            _Ht::key_equal
224            key_equal;
225      };
226}
227using
228__gnu_cxx::hash_map;
229class
230C2;
231template < class > class scoped_ptr {
232};
233namespace {
234class
235    AAA {
236      virtual ~
237          AAA () {
238          }};
239}
240template < typename > class EEE;
241template < typename CCC, typename =
242typename CCC::key_equal, typename =
243EEE < CCC > >class III {
244};
245namespace
246util {
247  class
248      EEE {
249      };
250}
251namespace {
252class
253    C1:
254      util::EEE {
255       public:
256        class
257            C3:
258              AAA {
259                struct FFF;
260                typedef
261                    III <
262                    hash_map <
263                    C2,
264                    FFF > >
265                        GGG;
266                GGG
267                    aaa;
268                friend
269                    C1;
270              };
271        void
272            HHH (C3::GGG &);
273      };
274}
275namespace
276n1 {
277  class
278      Test {
279      };
280  template <
281      typename >
282      class
283      C7 {
284      };
285  class
286      C4:
287        n1::Test {
288          vector <
289              C1::C3 * >
290              a1;
291        };
292  enum C5 { };
293  class
294      C6:
295        C4,
296        n1::C7 <
297        C5 > {
298        };
299  class
300      C8:
301        C6 {
302        };
303  class
304      C9:
305        C8 {
306          void
307              TestBody ();
308        };
309  void
310      C9::TestBody () {
311        scoped_ptr < C1::C3 > context;
312      }
313}
314