bool hasNonInstance = false;
bool isField = false;
BaseSet Classes;
- for (const NamedDecl *const D : R) {
+ for (NamedDecl *D : R) {
+ // Look through any using decls.
+ D = D->getUnderlyingDecl();
+
if (D->isCXXInstanceMember()) {
- // Look through any using decls.
- const NamedDecl *const UnderlyingDecl = D->getUnderlyingDecl();
- isField |= isa<FieldDecl>(UnderlyingDecl) ||
- isa<MSPropertyDecl>(UnderlyingDecl) ||
- isa<IndirectFieldDecl>(UnderlyingDecl);
+ isField |= isa<FieldDecl>(D) || isa<MSPropertyDecl>(D) ||
+ isa<IndirectFieldDecl>(D);
- const CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
+ CXXRecordDecl *R = cast<CXXRecordDecl>(D->getDeclContext());
Classes.insert(R->getCanonicalDecl());
} else
hasNonInstance = true;
template <class T> struct A {
void foo();
- void foo2();
- static void static_foo();
- static void static_foo2();
-
+
void test0() {
Unrelated::foo(); // expected-error {{call to non-static member function without an object argument}}
}
void test1() {
B<T>::foo();
- B<T>::foo2(); // expected-error {{call to non-static member function without an object argument}}
- B<T>::static_foo();
- B<T>::static_foo2();
}
static void test2() {
B<T>::foo(); // expected-error {{call to non-static member function without an object argument}}
- B<T>::foo2(); // expected-error {{call to non-static member function without an object argument}}
- B<T>::static_foo();
- B<T>::static_foo2();
}
void test3() {
};
template <class T> struct B : A<T> {
- using A<T>::foo2;
- using A<T>::static_foo2;
};
-
+
template <class T> struct C {
};
int test() {
A<int> a;
a.test0(); // no instantiation note here, decl is ill-formed
- a.test1(); // expected-note {{in instantiation}}
+ a.test1();
a.test2(); // expected-note {{in instantiation}}
a.test3(); // expected-note {{in instantiation}}
}