sepavloff updated this revision to Diff 106914.
sepavloff added a comment.
Aligned implementation with https://reviews.llvm.org/D21508.
https://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
@@ -165,6 +165,13 @@
RelativeToPrimary = false;
continue;
}
+
+ if (Pattern && Pattern->getFriendObjectKind() != Decl::FOK_None &&
+ 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
@@ -3249,7 +3249,23 @@
}
llvm_unreachable("All TSK values handled.");
}
-
+
+static FunctionTemplateDecl *getPatternFor(FunctionTemplateDecl *FTD) {
+ for (auto I : FTD->redecls()) {
+ auto D = cast<FunctionTemplateDecl>(I);
+ // If we have hit a point where the user provided a specialization of
+ // this template, we're done looking.
+ if (D->isMemberSpecialization())
+ return D;
+ if (D->isThisDeclarationADefinition())
+ return D;
+ if (FunctionTemplateDecl *Orig = D->getInstantiatedFromMemberTemplate())
+ if (FunctionTemplateDecl *Def = getPatternFor(Orig))
+ return Def;
+ }
+ return nullptr;
+}
+
FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
// Handle class scope explicit specialization special case.
if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
@@ -3274,14 +3290,8 @@
}
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 = getPatternFor(Primary))
+ Primary = Def;
return getDefinitionOrSelf(Primary->getTemplatedDecl());
}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits