1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
22bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregornamespace N {
32bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor  struct Outer {
42bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor    struct Inner {
52bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor      template<typename T>
62bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor      struct InnerTemplate {
72bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor        struct VeryInner {
82bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor          typedef T type;
92bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor
102bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor          static enum K1 { K1Val = sizeof(T) } Kind1;
118dbc3c64965f99e48830885835b7d2fc26ec3cf5Douglas Gregor          static enum { K2Val = sizeof(T)*2 } Kind2;
12d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor          enum { K3Val = sizeof(T)*2 } Kind3;
132bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor
142bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor          void foo() {
152bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor            K1 k1 = K1Val;
162bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor            Kind1 = K1Val;
172bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor            Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
18d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor            Kind3 = K3Val;
192bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor          }
20d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor
21d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor          struct UeberInner {
22d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor            void bar() {
23d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor              K1 k1 = K1Val;
24d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor              Kind1 = K1Val;
25d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor              Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
26ed961e7fffc268eeace169869f5a059bcbd5fcbdDouglas Gregor
27ed961e7fffc268eeace169869f5a059bcbd5fcbdDouglas Gregor              InnerTemplate t;
28ed961e7fffc268eeace169869f5a059bcbd5fcbdDouglas Gregor              InnerTemplate<type> t2;
29d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor            }
30d0c873799614d32c9c11280878ac1a856f92f707Douglas Gregor          };
312bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor        };
322bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor      };
332bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor    };
342bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor  };
352bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor}
362bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregor
372bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregortypedef int INT;
382bba76b0ec4c2f2134eebb1a2bbfe102f36c2f6eDouglas Gregortemplate struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
391eabb7d0c30f6a876b0fd03ad4656c096c26b8d0Douglas Gregortemplate struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
406569d68745c8213709740337d2be52b031384f58Douglas Gregor
416569d68745c8213709740337d2be52b031384f58Douglas Gregornamespace N2 {
426569d68745c8213709740337d2be52b031384f58Douglas Gregor  struct Outer2 {
438e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor    template<typename T, typename U = T>
446569d68745c8213709740337d2be52b031384f58Douglas Gregor    struct Inner {
456569d68745c8213709740337d2be52b031384f58Douglas Gregor      void foo() {
466569d68745c8213709740337d2be52b031384f58Douglas Gregor        enum { K1Val = sizeof(T) } k1;
478e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        enum K2 { K2Val = sizeof(T)*2 } k2a;
486569d68745c8213709740337d2be52b031384f58Douglas Gregor
498e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        K2 k2b = K2Val;
508e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor
518e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        struct S { T x, y; } s1;
528e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        struct { U x, y; } s2;
538e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        s1.x = s2.x; // expected-error{{incompatible}}
548e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor
558e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        typedef T type;
568e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregor        type t2 = s1.x;
576569d68745c8213709740337d2be52b031384f58Douglas Gregor
587b0a5723d6851a6f0365536508c2e4db678812b3Douglas Gregor        typedef struct { T z; } type2;
597b0a5723d6851a6f0365536508c2e4db678812b3Douglas Gregor        type2 t3 = { s1.x };
607b0a5723d6851a6f0365536508c2e4db678812b3Douglas Gregor
616569d68745c8213709740337d2be52b031384f58Douglas Gregor        Inner i1;
626569d68745c8213709740337d2be52b031384f58Douglas Gregor        i1.foo();
636569d68745c8213709740337d2be52b031384f58Douglas Gregor        Inner<T> i2;
646569d68745c8213709740337d2be52b031384f58Douglas Gregor        i2.foo();
656569d68745c8213709740337d2be52b031384f58Douglas Gregor      }
666569d68745c8213709740337d2be52b031384f58Douglas Gregor    };
676569d68745c8213709740337d2be52b031384f58Douglas Gregor  };
686569d68745c8213709740337d2be52b031384f58Douglas Gregor}
696569d68745c8213709740337d2be52b031384f58Douglas Gregor
708e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregortemplate struct N2::Outer2::Inner<float>;
718e92bf33baa91a8d97cbd4859648af149d5b5e74Douglas Gregortemplate struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
72c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor
73c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor// Test dependent pointer-to-member expressions.
74c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregortemplate<typename T>
75c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregorstruct smart_ptr {
76c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor  struct safe_bool {
77c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor    int member;
78c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor  };
79c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor
80c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor  operator int safe_bool::*() const {
81c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor    return ptr? &safe_bool::member : 0;
82c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor  }
83c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor
84c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor  T* ptr;
85c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor};
86c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor
87c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregorvoid test_smart_ptr(smart_ptr<int> p) {
88c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor  if (p) { }
89c86a6e988184867b09aa17a619402d0e81d0fda0Douglas Gregor}
9068b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall
9168b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall// PR5517
9268b6b87b6beb7922fc2c8ab923ba2ce125490363John McCallnamespace test0 {
9368b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall  template <int K> struct X {
9468b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall    X() { extern void x(); }
9568b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall  };
9668b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall  void g() { X<2>(); }
9768b6b87b6beb7922fc2c8ab923ba2ce125490363John McCall}
98ec8045d3f0375302eadaa63deb373bacaf25a569John McCall
99ec8045d3f0375302eadaa63deb373bacaf25a569John McCall// <rdar://problem/8302161>
100ec8045d3f0375302eadaa63deb373bacaf25a569John McCallnamespace test1 {
101ec8045d3f0375302eadaa63deb373bacaf25a569John McCall  template <typename T> void f(T const &t) {
102ec8045d3f0375302eadaa63deb373bacaf25a569John McCall    union { char c; T t_; };
103ec8045d3f0375302eadaa63deb373bacaf25a569John McCall    c = 'a'; // <- this shouldn't silently fail to instantiate
104ec8045d3f0375302eadaa63deb373bacaf25a569John McCall    T::foo(); // expected-error {{has no members}}
105ec8045d3f0375302eadaa63deb373bacaf25a569John McCall  }
106ec8045d3f0375302eadaa63deb373bacaf25a569John McCall  template void f(int const &); // expected-note {{requested here}}
107ec8045d3f0375302eadaa63deb373bacaf25a569John McCall}
108e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith
109e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smithnamespace test2 {
110e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith  template<typename T> void f() {
111e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith    T::error; // expected-error {{no member}}
112e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith  }
113e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith  void g() {
114e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith    // This counts as an odr-use, so should trigger the instantiation of f<int>.
115e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith    (void)&f<int>; // expected-note {{here}}
116e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith  }
117e6975e9b0985ad7f7ff9187e38d95bfe9ac4181bRichard Smith}
118