1c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused
2c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// RUN: %clang_cc1 -fsyntax-only -verify %s -Wno-unused -fms-compatibility -DMSVC
3a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -Wno-unused
4a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s -Wno-unused -fms-compatibility -DMSVC
5a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-unused
6a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s -Wno-unused -fms-compatibility -DMSVC
7d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregornamespace N {
8d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  struct A {
9d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    typedef int type;
10d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  };
11d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
12d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  struct B {
13d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  };
14d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
15d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  struct C {
16d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    struct type { };
17d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    int type; // expected-note 2{{referenced member 'type' is declared here}}
18d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  };
19d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor}
20d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
21d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorint i;
22d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
23a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainartypename N::A::type *ip1 = &i;
24a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if __cplusplus <= 199711L // C++03 or earlier modes
25a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// expected-warning@-2 {{'typename' occurs outside of a template}}
26a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif
27a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainartypename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}}
28a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if __cplusplus <= 199711L
29a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// expected-warning@-2 {{'typename' occurs outside of a template}}
30a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif
31a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainartypename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}}
32a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if __cplusplus <= 199711L
33a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// expected-warning@-2 {{'typename' occurs outside of a template}}
34a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif
35d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
36d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorvoid test(double d) {
37a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  typename N::A::type f(typename N::A::type(a)); // expected-warning{{disambiguated as a function declaration}}
38a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // expected-note@-1 {{add a pair of parentheses}}
39a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if __cplusplus <= 199711L
40a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  // expected-warning@-3 2{{'typename' occurs outside of a template}}
41a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif
42d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  int five = f(5);
43d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
44d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  using namespace N;
45a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  for (typename A::type i = 0; i < 10; ++i)
46a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if __cplusplus <= 199711L
47a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// expected-warning@-2 {{'typename' occurs outside of a template}}
48a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif
49d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    five += 1;
50d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
51a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar  const typename N::A::type f2(d);
52a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#if __cplusplus <= 199711L
53a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar// expected-warning@-2 {{'typename' occurs outside of a template}}
54a4de17562d13d7a8188108243c4cfbd52f33229aPirama Arumuga Nainar#endif
55d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor}
56d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
57d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregornamespace N {
58d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  template<typename T>
59d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  struct X {
607c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall    typedef typename T::type type; // expected-error {{no type named 'type' in 'N::B'}} \
617c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall    // expected-error {{no type named 'type' in 'B'}} \
62d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    // FIXME: location info for error above isn't very good \
63d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    // expected-error 2{{typename specifier refers to non-type member 'type'}} \
64d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor    // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
65d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  };
66d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor}
67d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
68d57959af02b4af695276f4204443afe6e5d86bd8Douglas GregorN::X<N::A>::type *ip4 = &i;
699ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey YasskinN::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'N::X<N::B>' requested here}}
709ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey YasskinN::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'N::X<N::C>' requested here}}
71d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
729ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey YasskinN::X<int>::type fail1; // expected-note{{in instantiation of template class 'N::X<int>' requested here}}
73d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
74d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregortemplate<typename T>
75d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorstruct Y {
767c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  typedef typename N::X<T>::type *type; // expected-note{{in instantiation of template class 'N::X<B>' requested here}} \
777c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  // expected-note{{in instantiation of template class 'N::X<C>' requested here}}
78d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor};
79d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
80d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorstruct A {
81d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  typedef int type;
82d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor};
83d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
84d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorstruct B {
85d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor};
86d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
87d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregorstruct C {
88d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  struct type { };
89d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor  int type; // expected-note{{referenced member 'type' is declared here}}
90d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor};
91d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor
92d57959af02b4af695276f4204443afe6e5d86bd8Douglas Gregor::Y<A>::type ip7 = &i;
939ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey Yasskin::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'Y<B>' requested here}}
949ab14541716928894821cf5d53d6b4c95ffdf3a3Jeffrey Yasskin::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'Y<C>' requested here}}
9500c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
9600c93a10c3504b77dad4467766bfca3248defbfbRichard Trieutemplate<typename T> struct D {
9700c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef typename T::foo foo;  // expected-error {{type 'long' cannot be used prior to '::' because it has no members}}
9800c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef typename foo::bar bar;
9900c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu};
10000c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
10100c93a10c3504b77dad4467766bfca3248defbfbRichard TrieuD<long> struct_D;  // expected-note {{in instantiation of template class 'D<long>' requested here}}
10200c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
10300c93a10c3504b77dad4467766bfca3248defbfbRichard Trieutemplate<typename T> struct E {
10400c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef typename T::foo foo;
10500c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef typename foo::bar bar;  // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}}
10600c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu};
10700c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
10800c93a10c3504b77dad4467766bfca3248defbfbRichard Trieustruct F {
10900c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef double foo;
11000c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu};
11100c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
11200c93a10c3504b77dad4467766bfca3248defbfbRichard TrieuE<F> struct_E; // expected-note {{in instantiation of template class 'E<F>' requested here}}
11300c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
11400c93a10c3504b77dad4467766bfca3248defbfbRichard Trieutemplate<typename T> struct G {
11500c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef typename T::foo foo;
11600c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  typedef typename foo::bar bar;
11700c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu};
11800c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
11900c93a10c3504b77dad4467766bfca3248defbfbRichard Trieustruct H {
12000c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  struct foo {
12100c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu    typedef double bar;
12200c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu  };
12300c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu};
12400c93a10c3504b77dad4467766bfca3248defbfbRichard Trieu
12500c93a10c3504b77dad4467766bfca3248defbfbRichard TrieuG<H> struct_G;
126480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor
127480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregornamespace PR10925 {
128480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  template< int mydim, typename Traits >
129480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  class BasicGeometry
130480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  {
131480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    typedef int some_type_t;
132480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  };
133480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor
134480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  template<class ctype, int mydim, int coorddim>
135480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  class MockGeometry : BasicGeometry<mydim, int>{
136480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor    using typename BasicGeometry<mydim, int>::operator[]; // expected-error {{typename is allowed for identifiers only}}
137480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor  };
138480b53cfff18c40d10fcb09b0185a9b75dfd491eDouglas Gregor}
139ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
140ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
141ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrainnamespace missing_typename {
1428c14de83188640bab9cae658e92a655e6d4fd484Kaelyn Uhraintemplate <class T1, class T2> struct pair {}; // expected-note 7 {{template parameter is declared here}}
143ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
144ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhraintemplate <class T1, class T2>
145ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrainstruct map {
146ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  typedef T1* iterator;
147ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain};
148ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
149ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhraintemplate <class T>
150ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrainclass ExampleClass1 {
151ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  struct ExampleItem;
152ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
153ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
154ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  struct ExampleItemSet {
155ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain    typedef ExampleItem* iterator;
1568c14de83188640bab9cae658e92a655e6d4fd484Kaelyn Uhrain    ExampleItem* operator[](unsigned);
157ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  };
158ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
159ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  void foo() {
160c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#ifdef MSVC
161c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
162c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#else
163c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
164c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#endif
165c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    pair<ExampleItemSet::iterator, int> i;
166651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    pair<this->ExampleItemSet::iterator, int> i; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
167651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines    pair<ExampleItemSet::operator[], int> i; // expected-error-re {{template argument for template type parameter must be a type{{$}}}}
168ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  }
169c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#ifdef MSVC
170c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
171c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#else
172c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
173c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#endif
174c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  pair<ExampleItemSet::iterator, int> elt;
175ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
176ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
177ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  typedef map<int, ExampleItem*> ExampleItemMap;
178ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain
179ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  static void bar() {
180c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#ifdef MSVC
181c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
182c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#else
183c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
184c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#endif
185c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    pair<ExampleItemMap::iterator, int> i;
186ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  }
187c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#ifdef MSVC
188c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
189c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#else
190c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // expected-error@+2 {{template argument for template type parameter must be a type; did you forget 'typename'?}}
191c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#endif
192c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  pair<ExampleItemMap::iterator, int> entry;
193ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain  pair<bar, int> foobar; // expected-error {{template argument for template type parameter must be a type}}
194ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain};
195ab7ad72f432810011041c5628b377f77cb1c81e6Kaelyn Uhrain} // namespace missing_typename
196c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
197c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace missing_typename_and_base {
198c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <class T> struct Bar {}; // expected-note 1+ {{template parameter is declared here}}
199c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T>
200c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstruct Foo : T {
201c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
202c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // FIXME: MSVC accepts this code.
203c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  Bar<TypeInBase> x; // expected-error {{use of undeclared identifier 'TypeInBase'}}
204c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
205c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#ifdef MSVC
206c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
207c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#else
208c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // expected-error@+2 {{must be a type; did you forget 'typename'?}}
209c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#endif
210c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  Bar<T::TypeInBase> y;
211c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
212c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#ifdef MSVC
213c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // expected-warning@+4 {{omitted 'typename' is a Microsoft extension}}
214c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#else
215c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  // expected-error@+2 {{must be a type; did you forget 'typename'?}}
216c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines#endif
217c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  Bar<T::NestedRD::TypeInNestedRD> z;
218c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
219c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines};
220c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstruct Base {
221c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  typedef int TypeInBase;
222c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  struct NestedRD {
223c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines    typedef int TypeInNestedRD;
224c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  };
225c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines};
226c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen HinesFoo<Base> x;
227c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} // namespace missing_typename_and_base
228c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
229c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace func_type_vs_construct_tmp {
230c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename> struct S { typedef int type; };
231c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T> void f();
232c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <int N> void f();
233c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
234c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// expected-error@+1 {{missing 'typename' prior to dependent type name 'S<int>::type'}}
235c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T> void g() { f</*typename*/ S<T>::type(int())>(); }
236c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
237c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// Adding typename does fix the diagnostic.
238c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T> void h() { f<typename S<T>::type(int())>(); }
239c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
240c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid j() {
241c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  g<int>(); // expected-note-re {{in instantiation {{.*}} requested here}}
242c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  h<int>();
243c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
244c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} // namespace func_type_vs_construct_tmp
245c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
246c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesnamespace pointer_vs_multiply {
247c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesint x;
248c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// expected-error@+1 {{missing 'typename' prior to dependent type name 'B::type_or_int'}}
249c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T> void g() { T::type_or_int * x; }
250c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines// expected-error@+1 {{typename specifier refers to non-type member 'type_or_int' in 'pointer_vs_multiply::A'}}
251c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinestemplate <typename T> void h() { typename T::type_or_int * x; }
252c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
253c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstruct A { static const int type_or_int = 5; }; // expected-note {{referenced member 'type_or_int' is declared here}}
254c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesstruct B { typedef int type_or_int; };
255c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines
256c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hinesvoid j() {
257c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  g<A>();
258c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  g<B>(); // expected-note-re {{in instantiation {{.*}} requested here}}
259c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  h<A>(); // expected-note-re {{in instantiation {{.*}} requested here}}
260c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines  h<B>();
261c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines}
262c568f1e98938584c0ef0b12ae5018ff7d90a4072Stephen Hines} // namespace pointer_vs_multiply
263