aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-26 02:38:45 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-26 02:38:45 +0000
commita7bc8559b40a78d664d6c7faf4b42ff21184c146 (patch)
tree5a7c61bc9b67fb5c491b3b905138a215b9051a6c
parent1a6e03457ebafd6ac523cdcf5d6b6f411ea08772 (diff)
Apparently that didn't work. Reverting for now.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99601 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/Sema/SemaAccess.cpp2
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp43
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p1.cpp13
3 files changed, 15 insertions, 43 deletions
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp
index 4cfd99d5c5..a92989696e 100644
--- a/lib/Sema/SemaAccess.cpp
+++ b/lib/Sema/SemaAccess.cpp
@@ -319,7 +319,7 @@ static Sema::AccessResult MatchesFriend(Sema &S,
if (Friend == FTD->getCanonicalDecl())
return Sema::AR_accessible;
- if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
+ if (MightInstantiateTo(S, FTD, Friend))
return Sema::AR_dependent;
return Sema::AR_inaccessible;
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index d929b5a370..cbd9086dfb 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -904,15 +904,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
// Check whether there is already a function template specialization for
// this declaration.
FunctionTemplateDecl *FunctionTemplate = D->getDescribedFunctionTemplate();
-
- bool isFriend;
- if (FunctionTemplate)
- isFriend = (FunctionTemplate->getFriendObjectKind() != Decl::FOK_None);
- else
- isFriend = (D->getFriendObjectKind() != Decl::FOK_None);
-
void *InsertPos = 0;
- if (!isFriend && FunctionTemplate && !TemplateParams) {
+ if (FunctionTemplate && !TemplateParams) {
llvm::FoldingSetNodeID ID;
FunctionTemplateSpecializationInfo::Profile(ID,
TemplateArgs.getInnermost().getFlatArgumentList(),
@@ -940,29 +933,14 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
return 0;
QualType T = TInfo->getType();
- NestedNameSpecifier *Qualifier = D->getQualifier();
- if (Qualifier) {
- Qualifier = SemaRef.SubstNestedNameSpecifier(Qualifier,
- D->getQualifierRange(),
- TemplateArgs);
- if (!Qualifier) return 0;
- }
-
// If we're instantiating a local function declaration, put the result
// in the owner; otherwise we need to find the instantiated context.
DeclContext *DC;
if (D->getDeclContext()->isFunctionOrMethod())
DC = Owner;
- else if (isFriend && Qualifier) {
- CXXScopeSpec SS;
- SS.setScopeRep(Qualifier);
- SS.setRange(D->getQualifierRange());
- DC = SemaRef.computeDeclContext(SS);
- if (!DC) return 0;
- } else {
+ else
DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(),
TemplateArgs);
- }
FunctionDecl *Function =
FunctionDecl::Create(SemaRef.Context, DC, D->getLocation(),
@@ -970,8 +948,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
D->getStorageClass(),
D->isInlineSpecified(), D->hasWrittenPrototype());
- if (Qualifier)
- Function->setQualifierInfo(Qualifier, D->getQualifierRange());
+ // Substitute the nested name specifier, if any.
+ if (SubstQualifier(D, Function))
+ return 0;
Function->setLexicalDeclContext(Owner);
@@ -995,7 +974,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
// which means substituting int for T, but leaving "f" as a friend function
// template.
// Build the function template itself.
- FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, DC,
+ FunctionTemplate = FunctionTemplateDecl::Create(SemaRef.Context, Owner,
Function->getLocation(),
Function->getDeclName(),
TemplateParams, Function);
@@ -1037,7 +1016,9 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
// If the original function was part of a friend declaration,
// inherit its namespace state and add it to the owner.
- if (isFriend) {
+ NamedDecl *FromFriendD
+ = TemplateParams? cast<NamedDecl>(D->getDescribedFunctionTemplate()) : D;
+ if (FromFriendD->getFriendObjectKind()) {
NamedDecl *ToFriendD = 0;
NamedDecl *PrevDecl;
if (TemplateParams) {
@@ -1048,7 +1029,11 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
PrevDecl = Function->getPreviousDeclaration();
}
ToFriendD->setObjectOfFriendDecl(PrevDecl != NULL);
- DC->makeDeclVisibleInContext(ToFriendD, /*Recoverable=*/ false);
+ if (!Owner->isDependentContext() && !PrevDecl)
+ DC->makeDeclVisibleInContext(ToFriendD, /* Recoverable = */ false);
+
+ if (!TemplateParams)
+ Function->setInstantiationOfMemberFunction(D, TSK_ImplicitInstantiation);
}
return Function;
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 0e41e5f832..39818028bb 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -178,16 +178,3 @@ namespace test7 {
};
template class D<int>;
}
-
-namespace test8 {
- template <class N> class A {
- static int x;
- template <class T> friend void foo();
- };
- template class A<int>;
-
- template <class T> void foo() {
- A<int>::x = 0;
- }
- template void foo<int>();
-}