1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
3e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor// Tests various places where requiring a complete type involves
4e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor// instantiation of that type.
5e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
6e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregortemplate<typename T>
7e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregorstruct X {
8e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  X(T);
9e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
10e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
11e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor       // expected-error{{data member instantiated with function type 'int (int)'}} \
12e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor       // expected-error{{data member instantiated with function type 'char (char)'}} \
13e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor       // expected-error{{data member instantiated with function type 'short (short)'}} \
147d520baec9b762633a09d31ee0db12e41fe2758aDouglas Gregor       // expected-error{{data member instantiated with function type 'float (float)'}}
15e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor};
16e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
17e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas GregorX<int> f() { return 0; }
18e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
19e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregorstruct XField {
207c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
21e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor};
22e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
23e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregorvoid test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
24e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)ptr1[i];
257c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
26e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor}
27e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
28e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregorvoid test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
29e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor                X<char(char)> *ptr3, X<short(short)> *ptr4) {
30e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)(ptr1 + 5);
31e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)(5 + ptr2);
327c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
337c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
34e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor}
35e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
36e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregorvoid test_new() {
37e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)new X<float>(0);
387c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
39e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor}
40e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor
41e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregorvoid test_memptr(X<long> *p1, long X<long>::*pm1,
423f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor                 X<long(long)> *p2,
433f5b61c394f4f205bcb4d316eb2a7a0a68b8af86Douglas Gregor                 long (X<long(long)>::*pm2)(long)) {
44e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor  (void)(p1->*pm1);
45e7450f5dbd5bed63b8ef9db86350a8fc3db011e8Douglas Gregor}
46393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor
47393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor// Reference binding to a base
48393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregortemplate<typename T>
49393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregorstruct X1 { };
50393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor
51393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregortemplate<typename T>
52393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregorstruct X2 : public T { };
53393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor
54393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregorvoid refbind_base(X2<X1<int> > &x2) {
55393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor  X1<int> &x1 = x2;
56393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor}
57393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor
58393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor// Enumerate constructors for user-defined conversion.
59393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregortemplate<typename T>
60393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregorstruct X3 {
61393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor  X3(T);
62393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor};
63393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor
64393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregorvoid enum_constructors(X1<float> &x1) {
65393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor  X3<X1<float> > x3 = x1;
66393896f49d5248435cf203cf1de60a86dc507c44Douglas Gregor}
677c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor
687c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregornamespace PR6376 {
697c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  template<typename T, typename U> struct W { };
707c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor
717c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  template<typename T>
727c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  struct X {
737c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor    template<typename U>
747c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor    struct apply {
757c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor      typedef W<T, U> type;
767c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor    };
777c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  };
787c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor
797c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  template<typename T, typename U>
807c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  struct Y : public X<T>::template apply<U>::type { };
817c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor
827c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor  template struct Y<int, float>;
837c1e98f1cb37b40e619a0c8aee8b337f037b432bDouglas Gregor}
84f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor
85f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregornamespace TemporaryObjectCopy {
86f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  // Make sure we instantiate classes when we create a temporary copy.
87f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  template<typename T>
88f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  struct X {
89f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor    X(T);
90f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  };
91f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor
92f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  template<typename T>
93f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  void f(T t) {
94f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor    const X<int> &x = X<int>(t);
95f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  }
96f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor
97f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor  template void f(int);
98f86fcb341116e72c5497e6b57695f46eca5f29e9Douglas Gregor}
996b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor
1006b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregornamespace PR7080 {
1016b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  template <class T, class U>
1026b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  class X
1036b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  {
1046b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor    typedef char true_t;
1056b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor    class false_t { char dummy[2]; };
1066b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor    static true_t dispatch(U);
1076b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor    static false_t dispatch(...);
1086b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor    static T trigger();
1096b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  public:
1106b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor    enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
1116b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  };
1126b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor
1136b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  template <class T>
1146b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  class rv : public T
1156b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  { };
1166b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor
1176b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor  bool x = X<int, rv<int>&>::value;
1186b6d01fbc297d703f7ad1e605aa97afc6289a64fDouglas Gregor}
1195613876991c80a684595fe8de1f039296a0657ffJohn McCall
1205613876991c80a684595fe8de1f039296a0657ffJohn McCallnamespace pr7199 {
1215613876991c80a684595fe8de1f039296a0657ffJohn McCall  template <class T> class A; // expected-note {{template is declared here}}
1225613876991c80a684595fe8de1f039296a0657ffJohn McCall  template <class T> class B {
1235613876991c80a684595fe8de1f039296a0657ffJohn McCall    class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
1245613876991c80a684595fe8de1f039296a0657ffJohn McCall  };
1255613876991c80a684595fe8de1f039296a0657ffJohn McCall
1265613876991c80a684595fe8de1f039296a0657ffJohn McCall  template class B<int>; // expected-note {{in instantiation}}
1275613876991c80a684595fe8de1f039296a0657ffJohn McCall}
1287d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor
1297d14d389f0539545715e756629127c1fe5a4773aDouglas Gregornamespace PR8425 {
1307d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  template <typename T>
1317d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  class BaseT {};
1327d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor
1337d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  template <typename T>
1347d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  class DerivedT : public BaseT<T> {};
1357d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor
1367d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  template <typename T>
1377d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  class FromT {
1387d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  public:
1397d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor    operator DerivedT<T>() const { return DerivedT<T>(); }
1407d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  };
1417d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor
1427d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  void test() {
1437d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor    FromT<int> ft;
1447d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor    BaseT<int> bt(ft);
1457d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor  }
1467d14d389f0539545715e756629127c1fe5a4773aDouglas Gregor}
147