summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-07-12 20:38:49 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-07-12 20:38:49 +0000
commit141942fcca5e7da4a582192c8bc81c9ccbd84784 (patch)
tree07b6d1b5494188f232716e0c9f680a475cc48130 /clang/lib
parent023e65611deff2b536fe6a0801b5dbcd11907e8d (diff)
downloadbcm5719-llvm-141942fcca5e7da4a582192c8bc81c9ccbd84784.tar.gz
bcm5719-llvm-141942fcca5e7da4a582192c8bc81c9ccbd84784.zip
Unrevert r186040, reverted in r186185, with fix for PR16597.
Original commit log: If we friend a declaration twice, that should not make it visible to name lookup in the surrounding context. Slightly rework how we handle friend declarations to inherit the visibility of the prior declaration, rather than setting a friend declaration to be visible whenever there was a prior declaration. llvm-svn: 186199
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaDecl.cpp12
-rw-r--r--clang/lib/Sema/SemaLookup.cpp11
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp3
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp20
4 files changed, 21 insertions, 25 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 5e535da19a1..fd4ddcf55e6 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6328,12 +6328,11 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
if (isFriend) {
- // For now, claim that the objects have no previous declaration.
if (FunctionTemplate) {
- FunctionTemplate->setObjectOfFriendDecl(false);
+ FunctionTemplate->setObjectOfFriendDecl();
FunctionTemplate->setAccess(AS_public);
}
- NewFD->setObjectOfFriendDecl(false);
+ NewFD->setObjectOfFriendDecl();
NewFD->setAccess(AS_public);
}
@@ -6652,8 +6651,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
NewFD->setAccess(Access);
if (FunctionTemplate) FunctionTemplate->setAccess(Access);
-
- PrincipalDecl->setObjectOfFriendDecl(true);
}
if (NewFD->isOverloadedOperator() && !DC->isRecord() &&
@@ -10384,9 +10381,8 @@ CreateNewDecl:
// declaration so we always pass true to setObjectOfFriendDecl to make
// the tag name visible.
if (TUK == TUK_Friend)
- New->setObjectOfFriendDecl(/* PreviouslyDeclared = */ !Previous.empty() ||
- (!FriendSawTagOutsideEnclosingNamespace &&
- getLangOpts().MicrosoftExt));
+ New->setObjectOfFriendDecl(!FriendSawTagOutsideEnclosingNamespace &&
+ getLangOpts().MicrosoftExt);
// Set the access specifier.
if (!Invalid && SearchDC->isRecord())
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 8d954ca994c..be336277b4a 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -2757,8 +2757,15 @@ void Sema::ArgumentDependentLookup(DeclarationName Name, bool Operator,
// If the only declaration here is an ordinary friend, consider
// it only if it was declared in an associated classes.
if (D->getIdentifierNamespace() == Decl::IDNS_OrdinaryFriend) {
- DeclContext *LexDC = D->getLexicalDeclContext();
- if (!AssociatedClasses.count(cast<CXXRecordDecl>(LexDC)))
+ bool DeclaredInAssociatedClass = false;
+ for (Decl *DI = D; DI; DI = DI->getPreviousDecl()) {
+ DeclContext *LexDC = DI->getLexicalDeclContext();
+ if (AssociatedClasses.count(cast<CXXRecordDecl>(LexDC))) {
+ DeclaredInAssociatedClass = true;
+ break;
+ }
+ }
+ if (!DeclaredInAssociatedClass)
continue;
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index e6006b6bf97..6f1ab19f10e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -1120,8 +1120,7 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
NewClass->setAccess(PrevClassTemplate->getAccess());
}
- NewTemplate->setObjectOfFriendDecl(/* PreviouslyDeclared = */
- PrevClassTemplate != NULL);
+ NewTemplate->setObjectOfFriendDecl();
// Friend templates are visible in fairly strange ways.
if (!CurContext->isDependentContext()) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b5a80d3f6a0..14185c37ad1 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -960,7 +960,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
else
Inst->setAccess(D->getAccess());
- Inst->setObjectOfFriendDecl(PrevClassTemplate != 0);
+ Inst->setObjectOfFriendDecl();
// TODO: do we want to track the instantiation progeny of this
// friend target decl?
} else {
@@ -1110,8 +1110,8 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
// If the original function was part of a friend declaration,
// inherit its namespace state.
- if (Decl::FriendObjectKind FOK = D->getFriendObjectKind())
- Record->setObjectOfFriendDecl(FOK == Decl::FOK_Declared);
+ if (D->getFriendObjectKind())
+ Record->setObjectOfFriendDecl();
// Make sure that anonymous structs and unions are recorded.
if (D->isAnonymousStructOrUnion()) {
@@ -1315,7 +1315,7 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
assert(isFriend && "non-friend has dependent specialization info?");
// This needs to be set now for future sanity.
- Function->setObjectOfFriendDecl(/*HasPrevious*/ true);
+ Function->setObjectOfFriendDecl();
// Instantiate the explicit template arguments.
TemplateArgumentListInfo ExplicitArgs(Info->getLAngleLoc(),
@@ -1365,13 +1365,7 @@ 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 *PrevDecl;
- if (TemplateParams)
- PrevDecl = FunctionTemplate->getPreviousDecl();
- else
- PrevDecl = Function->getPreviousDecl();
-
- PrincipalDecl->setObjectOfFriendDecl(PrevDecl != 0);
+ PrincipalDecl->setObjectOfFriendDecl();
DC->makeDeclVisibleInContext(PrincipalDecl);
bool queuedInstantiation = false;
@@ -1639,7 +1633,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
TemplateParams, Method);
if (isFriend) {
FunctionTemplate->setLexicalDeclContext(Owner);
- FunctionTemplate->setObjectOfFriendDecl(true);
+ FunctionTemplate->setObjectOfFriendDecl();
} else if (D->isOutOfLine())
FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
Method->setDescribedFunctionTemplate(FunctionTemplate);
@@ -1666,7 +1660,7 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D,
TempParamLists.data());
Method->setLexicalDeclContext(Owner);
- Method->setObjectOfFriendDecl(true);
+ Method->setObjectOfFriendDecl();
} else if (D->isOutOfLine())
Method->setLexicalDeclContext(D->getLexicalDeclContext());
OpenPOWER on IntegriCloud