1// RUN: %clang_cc1 -g -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          };
196  using
197      std::equal_to;
198  using
199      std::allocator;
200  using
201      std::_Select1st;
202  template < class _Key, class _Tp, class _HashFn =
203      hash < _Key >, class _EqualKey = equal_to < _Key >, class _Alloc =
204      allocator < _Tp > >class hash_map {
205        typedef
206            hashtable <
207            pair <
208            _Key,
209        _Tp >,
210        _Key,
211        _HashFn,
212        _Select1st <
213            pair <
214            _Key,
215        _Tp > >,
216        _EqualKey,
217        _Alloc >
218            _Ht;
219       public:
220        typename _Ht::key_type;
221        typedef typename
222            _Ht::key_equal
223            key_equal;
224      };
225}
226using
227__gnu_cxx::hash_map;
228class
229C2;
230template < class > class scoped_ptr {
231};
232namespace {
233class
234    AAA {
235      virtual ~
236          AAA () {
237          }};
238}
239template < typename > class EEE;
240template < typename CCC, typename =
241typename CCC::key_equal, typename =
242EEE < CCC > >class III {
243};
244namespace
245util {
246  class
247      EEE {
248      };
249}
250namespace {
251class
252    C1:
253      util::EEE {
254       public:
255        class
256            C3:
257              AAA {
258                struct FFF;
259                typedef
260                    III <
261                    hash_map <
262                    C2,
263                    FFF > >
264                        GGG;
265                GGG
266                    aaa;
267                friend
268                    C1;
269              };
270        void
271            HHH (C3::GGG &);
272      };
273}
274namespace
275n1 {
276  class
277      Test {
278      };
279  template <
280      typename >
281      class
282      C7 {
283      };
284  class
285      C4:
286        n1::Test {
287          vector <
288              C1::C3 * >
289              a1;
290        };
291  enum C5 { };
292  class
293      C6:
294        C4,
295        n1::C7 <
296        C5 > {
297        };
298  class
299      C8:
300        C6 {
301        };
302  class
303      C9:
304        C8 {
305          void
306              TestBody ();
307        };
308  void
309      C9::TestBody () {
310        scoped_ptr < C1::C3 > context;
311      }
312}
313