sepavloff created this revision.
sepavloff added a reviewer: rsmith.
sepavloff added a subscriber: cfe-commits.
If a function template was defined in a friend declaration in a
template class, it was not instantiated because template definition
was not found.
http://reviews.llvm.org/D21767
Files:
lib/AST/Decl.cpp
lib/Sema/SemaTemplateInstantiate.cpp
test/SemaTemplate/instantiate-friend-function.cpp
Index: test/SemaTemplate/instantiate-friend-function.cpp
===================================================================
--- /dev/null
+++ test/SemaTemplate/instantiate-friend-function.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+// RUN: %clang_cc1 -S -triple i686-pc-linux-gnu -std=c++11 %s -o - | FileCheck %s
+// expected-no-diagnostics
+
+template<typename T> void func_01(T *x);
+template<typename T1>
+struct C1 {
+ template<typename T> friend void func_01(T *x) {}
+};
+
+C1<int> v1a;
+
+void use_01(int *x) {
+ func_01(x);
+}
+// CHECK: _Z7func_01IiEvPT_:
+
+
+template<typename T1>
+struct C2 {
+ template<typename T> friend void func_02(T *x) {}
+};
+
+C2<int> v2a;
+template<typename T> void func_02(T *x);
+
+void use_02(int *x) {
+ func_02(x);
+}
+// CHECK: _Z7func_02IiEvPT_:
+
+
+template<typename T1>
+struct C3a {
+ template<typename T> friend void func_03(T *x) {}
+};
+template<typename T1>
+struct C3b {
+ template<typename T> friend void func_03(T *x) {}
+};
+
+template<typename T> void func_03(T *x) {}
+
+void use_03(int *x) {
+ func_03(x);
+}
+// CHECK: _Z7func_03IiEvPT_:
+
+
+template<typename T> constexpr int func_04(const T x);
+template<typename T1>
+struct C4 {
+ template<typename T> friend constexpr int func_04(const T x) { return sizeof(T); }
+};
+
+C4<int> v4;
+
+void use_04(int *x) {
+ static_assert(func_04(short(122)) == sizeof(short), "Invalid calculation");
+ static_assert(func_04(122) == sizeof(int), "Invalid calculation");
+ static_assert(func_04(122L) == sizeof(long), "Invalid calculation");
+ static_assert(func_04(122LL) == sizeof(long long), "Invalid calculation");
+}
Index: lib/Sema/SemaTemplateInstantiate.cpp
===================================================================
--- lib/Sema/SemaTemplateInstantiate.cpp
+++ lib/Sema/SemaTemplateInstantiate.cpp
@@ -164,6 +164,13 @@
RelativeToPrimary = false;
continue;
}
+
+ if (Pattern && Pattern->getFriendObjectKind() &&
+ Function->getDeclContext()->isFileContext()) {
+ Ctx = const_cast<DeclContext*>(Pattern->getLexicalDeclContext());
+ RelativeToPrimary = false;
+ continue;
+ }
} else if (CXXRecordDecl *Rec = dyn_cast<CXXRecordDecl>(Ctx)) {
if (ClassTemplateDecl *ClassTemplate = Rec->getDescribedClassTemplate()) {
QualType T = ClassTemplate->getInjectedClassNameSpecialization();
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -3152,19 +3152,13 @@
"template");
return getPrimaryTemplate()->getTemplatedDecl();
}
-
+
if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
- while (Primary->getInstantiatedFromMemberTemplate()) {
- // If we have hit a point where the user provided a specialization of
- // this template, we're done looking.
- if (Primary->isMemberSpecialization())
- break;
- Primary = Primary->getInstantiatedFromMemberTemplate();
- }
-
+ if (FunctionTemplateDecl *Def = Primary->getDefinition())
+ Primary = Def;
return Primary->getTemplatedDecl();
- }
-
+ }
+
return getInstantiatedFromMemberFunction();
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits