diff options
author | John McCall <rjmccall@apple.com> | 2010-10-19 02:26:41 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2010-10-19 02:26:41 +0000 |
commit | 4eab39f0745fb1949dbb40c4145771b927888242 (patch) | |
tree | 7e2ebff0e4d3af9a1e26a4479f6ed7e722d3fb2c | |
parent | 613ef3d4c144f8c35224daf28a187426d2044aee (diff) |
Instantiate enclosing template parameter lists when instantiating friends.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@116789 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 19 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.friend/p5.cpp | 11 |
2 files changed, 29 insertions, 1 deletions
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 57ea18809d..5636647cda 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -1276,6 +1276,20 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, cast<Decl>(Owner)->isDefinedOutsideFunctionOrMethod()); LocalInstantiationScope Scope(SemaRef, MergeWithParentScope); + // Instantiate enclosing template arguments for friends. + llvm::SmallVector<TemplateParameterList *, 4> TempParamLists; + unsigned NumTempParamLists = 0; + if (isFriend && (NumTempParamLists = D->getNumTemplateParameterLists())) { + TempParamLists.set_size(NumTempParamLists); + for (unsigned I = 0; I != NumTempParamLists; ++I) { + TemplateParameterList *TempParams = D->getTemplateParameterList(I); + TemplateParameterList *InstParams = SubstTemplateParams(TempParams); + if (!InstParams) + return NULL; + TempParamLists[I] = InstParams; + } + } + llvm::SmallVector<ParmVarDecl *, 4> Params; TypeSourceInfo *TInfo = D->getTypeSourceInfo(); TInfo = SubstFunctionType(D, Params); @@ -1402,6 +1416,11 @@ TemplateDeclInstantiator::VisitCXXMethodDecl(CXXMethodDecl *D, // out-of-line, the instantiation will have the same lexical // context (which will be a namespace scope) as the template. if (isFriend) { + if (NumTempParamLists) + Method->setTemplateParameterListsInfo(SemaRef.Context, + NumTempParamLists, + TempParamLists.data()); + Method->setLexicalDeclContext(Owner); Method->setObjectOfFriendDecl(true); } else if (D->isOutOfLine()) diff --git a/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/test/CXX/temp/temp.decls/temp.friend/p5.cpp index 7d1ef7b2d3..63fd3df269 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p5.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p5.cpp @@ -57,7 +57,7 @@ namespace test2 { }; } -// rdar://problem/8540527 +// Tests 3, 4 and 5 were all noted in <rdar://problem/8540527>. namespace test3 { template <class T> struct A { struct Inner { @@ -92,3 +92,12 @@ namespace test4 { X<int>() += 1.0; } } + +namespace test5 { + template<template <class> class T> struct A { + template<template <class> class T> friend void A<T>::foo(); + }; + + template <class> struct B {}; + template class A<B>; +} |