2010-08-21 04:54:15 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify %s
|
2016-04-15 07:47:07 +08:00
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
|
|
|
|
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
|
2010-08-21 04:54:15 +08:00
|
|
|
|
2012-06-23 00:39:39 +08:00
|
|
|
// Clang used to crash trying to recover while adding 'this->' before Work(x);
|
2010-08-21 04:54:15 +08:00
|
|
|
|
|
|
|
template <typename> struct A {
|
|
|
|
static void Work(int); // expected-note{{must qualify identifier}}
|
|
|
|
};
|
|
|
|
|
|
|
|
template <typename T> struct B : public A<T> {
|
|
|
|
template <typename T2> B(T2 x) {
|
|
|
|
Work(x); // expected-error{{use of undeclared identifier}}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
void Test() {
|
|
|
|
B<int> b(0); // expected-note{{in instantiation of function template}}
|
|
|
|
}
|
|
|
|
|
2013-07-23 02:09:32 +08:00
|
|
|
|
|
|
|
// Don't crash here.
|
|
|
|
namespace PR16134 {
|
|
|
|
template <class P> struct S // expected-error {{expected ';'}}
|
|
|
|
template <> static S<Q>::f() // expected-error +{{}}
|
|
|
|
}
|
2013-08-10 20:00:21 +08:00
|
|
|
|
|
|
|
namespace PR16225 {
|
|
|
|
template <typename T> void f();
|
2016-04-15 07:47:07 +08:00
|
|
|
template <typename C> void g(C*) {
|
2013-08-10 20:00:21 +08:00
|
|
|
struct LocalStruct : UnknownBase<Mumble, C> { }; // expected-error {{unknown template name 'UnknownBase'}} \
|
|
|
|
// expected-error {{use of undeclared identifier 'Mumble'}}
|
2016-04-15 07:47:07 +08:00
|
|
|
f<LocalStruct>();
|
|
|
|
#if __cplusplus <= 199711L
|
|
|
|
// expected-warning@-2 {{template argument uses local type 'LocalStruct'}}
|
|
|
|
#endif
|
2013-08-10 20:00:21 +08:00
|
|
|
}
|
|
|
|
struct S;
|
|
|
|
void h() {
|
2016-04-15 07:47:07 +08:00
|
|
|
g<S>(0);
|
|
|
|
#if __cplusplus <= 199711L
|
|
|
|
// expected-note@-2 {{in instantiation of function template specialization}}
|
|
|
|
#endif
|
2013-08-10 20:00:21 +08:00
|
|
|
}
|
|
|
|
}
|
2015-10-01 01:30:48 +08:00
|
|
|
|
|
|
|
namespace test1 {
|
|
|
|
template <typename> class ArraySlice {};
|
|
|
|
class Foo;
|
|
|
|
class NonTemplateClass {
|
|
|
|
void MemberFunction(ArraySlice<Foo>, int);
|
|
|
|
template <class T> void MemberFuncTemplate(ArraySlice<T>, int);
|
|
|
|
};
|
|
|
|
void NonTemplateClass::MemberFunction(ArraySlice<Foo> resource_data,
|
|
|
|
int now) {
|
|
|
|
// expected-note@+1 {{in instantiation of function template specialization 'test1::NonTemplateClass::MemberFuncTemplate<test1::Foo>'}}
|
|
|
|
MemberFuncTemplate(resource_data, now);
|
|
|
|
}
|
|
|
|
template <class T>
|
|
|
|
void NonTemplateClass::MemberFuncTemplate(ArraySlice<T> resource_data, int) {
|
|
|
|
// expected-error@+1 {{use of undeclared identifier 'UndeclaredMethod'}}
|
|
|
|
UndeclaredMethod(resource_data);
|
|
|
|
}
|
|
|
|
// expected-error@+2 {{out-of-line definition of 'UndeclaredMethod' does not match any declaration}}
|
|
|
|
// expected-note@+1 {{must qualify identifier to find this declaration in dependent base class}}
|
|
|
|
void NonTemplateClass::UndeclaredMethod() {}
|
|
|
|
}
|