summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2010-03-26 23:10:15 +0000
committerJohn McCall <rjmccall@apple.com>2010-03-26 23:10:15 +0000
commit30837102a2ef32218c5d95d372b9ab3561733b6c (patch)
tree79c89310337a2a9ad971687a95432db2be69f154 /clang/lib/Sema
parent4667effa8bdd9df81e51e1e3219c7cd0f525af58 (diff)
downloadbcm5719-llvm-30837102a2ef32218c5d95d372b9ab3561733b6c.tar.gz
bcm5719-llvm-30837102a2ef32218c5d95d372b9ab3561733b6c.zip
Put function templates instantiated from friend declarations in the correct
lexical context. This is required for ADL to work properly; fixes PR6716. llvm-svn: 99665
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiateDecl.cpp21
1 files changed, 15 insertions, 6 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e795f0ad1bc..59c9819751c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -840,16 +840,18 @@ TemplateDeclInstantiator::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
assert(InstTemplate &&
"VisitFunctionDecl/CXXMethodDecl didn't create a template!");
+ bool isFriend = (InstTemplate->getFriendObjectKind() != Decl::FOK_None);
+
// Link the instantiation back to the pattern *unless* this is a
// non-definition friend declaration.
if (!InstTemplate->getInstantiatedFromMemberTemplate() &&
- !(InstTemplate->getFriendObjectKind() &&
- !D->getTemplatedDecl()->isThisDeclarationADefinition()))
+ !(isFriend && !D->getTemplatedDecl()->isThisDeclarationADefinition()))
InstTemplate->setInstantiatedFromMemberTemplate(D);
- // Add non-friends into the owner.
- if (!InstTemplate->getFriendObjectKind())
+ // Make declarations visible in the appropriate context.
+ if (!isFriend)
Owner->addDecl(InstTemplate);
+
return InstTemplate;
}
@@ -973,7 +975,13 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
if (Qualifier)
Function->setQualifierInfo(Qualifier, D->getQualifierRange());
- Function->setLexicalDeclContext(Owner);
+ DeclContext *LexicalDC = Owner;
+ if (!isFriend && D->isOutOfLine()) {
+ assert(D->getDeclContext()->isFileContext());
+ LexicalDC = D->getDeclContext();
+ }
+
+ Function->setLexicalDeclContext(LexicalDC);
// Attach the parameters
for (unsigned P = 0; P < Params.size(); ++P)
@@ -1000,7 +1008,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
Function->getDeclName(),
TemplateParams, Function);
Function->setDescribedFunctionTemplate(FunctionTemplate);
- FunctionTemplate->setLexicalDeclContext(D->getLexicalDeclContext());
+
+ FunctionTemplate->setLexicalDeclContext(LexicalDC);
if (isFriend && D->isThisDeclarationADefinition()) {
// TODO: should we remember this connection regardless of whether
OpenPOWER on IntegriCloud