summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp9
-rw-r--r--clang/test/SemaCXX/friend.cpp4
2 files changed, 10 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index fd0dc6fca73..59e984dd93e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -7035,6 +7035,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
assert(!isa<TemplateDecl>(Member) && "Only for non-template members");
// Try to find the member we are instantiating.
+ NamedDecl *FoundInstantiation = nullptr;
NamedDecl *Instantiation = nullptr;
NamedDecl *InstantiatedFrom = nullptr;
MemberSpecializationInfo *MSInfo = nullptr;
@@ -7050,6 +7051,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
if (!hasExplicitCallingConv(Adjusted))
Adjusted = adjustCCAndNoReturn(Adjusted, Method->getType());
if (Context.hasSameType(Adjusted, Method->getType())) {
+ FoundInstantiation = *I;
Instantiation = Method;
InstantiatedFrom = Method->getInstantiatedFromMemberFunction();
MSInfo = Method->getMemberSpecializationInfo();
@@ -7062,6 +7064,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
if (Previous.isSingleResult() &&
(PrevVar = dyn_cast<VarDecl>(Previous.getFoundDecl())))
if (PrevVar->isStaticDataMember()) {
+ FoundInstantiation = Previous.getRepresentativeDecl();
Instantiation = PrevVar;
InstantiatedFrom = PrevVar->getInstantiatedFromStaticDataMember();
MSInfo = PrevVar->getMemberSpecializationInfo();
@@ -7070,6 +7073,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
CXXRecordDecl *PrevRecord;
if (Previous.isSingleResult() &&
(PrevRecord = dyn_cast<CXXRecordDecl>(Previous.getFoundDecl()))) {
+ FoundInstantiation = Previous.getRepresentativeDecl();
Instantiation = PrevRecord;
InstantiatedFrom = PrevRecord->getInstantiatedFromMemberClass();
MSInfo = PrevRecord->getMemberSpecializationInfo();
@@ -7078,6 +7082,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
EnumDecl *PrevEnum;
if (Previous.isSingleResult() &&
(PrevEnum = dyn_cast<EnumDecl>(Previous.getFoundDecl()))) {
+ FoundInstantiation = Previous.getRepresentativeDecl();
Instantiation = PrevEnum;
InstantiatedFrom = PrevEnum->getInstantiatedFromMemberEnum();
MSInfo = PrevEnum->getMemberSpecializationInfo();
@@ -7106,7 +7111,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
}
Previous.clear();
- Previous.addDecl(Instantiation);
+ Previous.addDecl(FoundInstantiation);
return false;
}
@@ -7207,7 +7212,7 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
// Save the caller the trouble of having to figure out which declaration
// this specialization matches.
Previous.clear();
- Previous.addDecl(Instantiation);
+ Previous.addDecl(FoundInstantiation);
return false;
}
diff --git a/clang/test/SemaCXX/friend.cpp b/clang/test/SemaCXX/friend.cpp
index c90ce74616d..4f27f4df6c9 100644
--- a/clang/test/SemaCXX/friend.cpp
+++ b/clang/test/SemaCXX/friend.cpp
@@ -147,11 +147,13 @@ namespace test8 {
}
using ns2::f; // expected-note {{using declaration}}
}
- struct A { void f(); }; // expected-note {{target of using declaration}}
+ struct A { void f(); }; // expected-note 2{{target of using declaration}}
struct B : public A { using A::f; }; // expected-note {{using declaration}}
+ template<typename T> struct C : A { using A::f; }; // expected-note {{using declaration}}
struct X {
template<class T> friend void ns1::f(T t); // expected-error {{cannot befriend target of using declaration}}
friend void B::f(); // expected-error {{cannot befriend target of using declaration}}
+ friend void C<int>::f(); // expected-error {{cannot befriend target of using declaration}}
};
}
OpenPOWER on IntegriCloud