diff options
author | John McCall <rjmccall@apple.com> | 2009-08-29 03:16:09 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2009-08-29 03:16:09 +0000 |
commit | f181d8a44f5837213eeaee6d71f584b1ab2849cd (patch) | |
tree | 15fe88e4f2e1cf77deb0e325d36751286ecf5409 | |
parent | 9a5bca34ca09d3a88c2ccb4f53b27cf99de4f182 (diff) |
Ensure code generation for friend declarations in class templates.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80418 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 18 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiateDecl.cpp | 2 | ||||
-rw-r--r-- | test/CXX/temp/temp.decls/temp.friend/p1.cpp | 4 |
3 files changed, 17 insertions, 7 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 4cb5a276e6..521394b978 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -37,7 +37,7 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D) { if (!Ctx) Ctx = D->getDeclContext(); - for (; !Ctx->isFileContext(); Ctx = Ctx->getParent()) { + while (!Ctx->isFileContext()) { // Add template arguments from a class template instantiation. if (ClassTemplateSpecializationDecl *Spec = dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) { @@ -46,18 +46,26 @@ Sema::getTemplateInstantiationArgs(NamedDecl *D) { break; Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs()); - continue; } // Add template arguments from a function template specialization. - if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) { + else if (FunctionDecl *Function = dyn_cast<FunctionDecl>(Ctx)) { // FIXME: Check whether this is an explicit specialization. if (const TemplateArgumentList *TemplateArgs = Function->getTemplateSpecializationArgs()) Result.addOuterTemplateArguments(TemplateArgs); - - continue; + + // If this is a friend declaration and it declares an entity at + // namespace scope, take arguments from its lexical parent + // instead of its semantic parent. + if (Function->getFriendObjectKind() && + Function->getDeclContext()->isFileContext()) { + Ctx = Function->getLexicalDeclContext(); + continue; + } } + + Ctx = Ctx->getParent(); } return Result; diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp index 8370bd17ef..df4ebfaa93 100644 --- a/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -498,6 +498,8 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D) { Function->setObjectOfFriendDecl(WasDeclared); if (!Owner->isDependentContext()) DC->makeDeclVisibleInContext(Function); + + Function->setInstantiationOfMemberFunction(D); } if (InitFunctionInstantiation(Function, D)) diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp index b834257889..fe92f4d759 100644 --- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp +++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp @@ -1,4 +1,4 @@ -// RUN: clang-cc -fsyntax-only -verify %s +// RUN: clang-cc %s template <typename T> struct Num { T value_; @@ -38,7 +38,7 @@ int calc1() { int calc2() { Num<int> x = 3; - Num<int>::Rep<char> n = 10; + Num<int>::Rep<char> n = (cast) 10; Num<int> result = x * n; return result.get(); } |