loladiro updated this revision to Diff 36565.
loladiro added a comment.
Address review comment re loop structure. Reword comment that had a typo to
both fix the typo and make the intent of the code more clear.
Repository:
rL LLVM
http://reviews.llvm.org/D13419
Files:
lib/AST/Decl.cpp
lib/AST/DeclCXX.cpp
test/CodeGenCXX/visibility.cpp
Index: test/CodeGenCXX/visibility.cpp
===================================================================
--- test/CodeGenCXX/visibility.cpp
+++ test/CodeGenCXX/visibility.cpp
@@ -1314,3 +1314,57 @@
// CHECK-LABEL: define void @_ZN6test693foo1fEv
// CHECK-HIDDEN-LABEL: define hidden void @_ZN6test693foo1fEv
}
+
+namespace test70 {
+ template < typename T > class foo {
+ public:
+ T x;
+ template < typename S >
+ HIDDEN S AddS(S);
+ template < typename S > class HIDDEN barS {
+ public:
+ static S AddS2(foo<T> x, S);
+ };
+ template < typename S > class HIDDEN barZ {
+ public:
+ template < typename Z >
+ static S AddSZ(foo<T> x, S, Z);
+ };
+ };
+
+ // CHECK: define linkonce_odr hidden i64 @_ZN6test703fooIiE4AddSIxEET_S3_
+ // CHECK-NOT: define linkonce_odr i64 @_ZN6test703fooIiE4AddSIxEET_S3_
+ template < typename T >
+ template < typename S >
+ HIDDEN S foo<T>::AddS(S y) {
+ return ((S) x) + y;
+ }
+
+ // CHECK: define linkonce_odr hidden i64 @_ZN6test703fooIiE4barSIxE5AddS2ES1_x
+ // CHECK-NOT: define linkonce_odr i64 @_ZN6test703fooIiE4barSIxE5AddS2ES1_x
+ template < typename T >
+ template < typename S >
+ HIDDEN S foo<T>::barS<S>::AddS2(foo<T> x, S y) {
+ return ((S) x.x) + y;
+ }
+
+ // CHECK: define linkonce_odr hidden i64 @_ZN6test703fooIiE4barZIxE5AddSZIcEExS1_xT_
+ // CHECK-NOT: define linkonce_odr i64 @_ZN6test703fooIiE4barZIxE5AddSZIcEExS1_xT_
+ template < typename T >
+ template < typename S >
+ template < typename Z >
+ HIDDEN S foo<T>::barZ<S>::AddSZ(foo<T> x, S y, Z z) {
+ return ((S) x.x) + y + ((S) z);
+ }
+
+ extern template struct foo<int>;
+ template struct foo<int>;
+
+ void f() {
+ auto var = foo<int>{5};
+ auto bar = var.AddS((long long)3);
+ auto bar2 = decltype(var)::barS<long long>::AddS2(var,3);
+ auto bar3 = decltype(var)::barZ<long long>::AddSZ(var,3,(char)0);
+ }
+}
+
Index: lib/AST/DeclCXX.cpp
===================================================================
--- lib/AST/DeclCXX.cpp
+++ lib/AST/DeclCXX.cpp
@@ -1261,17 +1261,19 @@
if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
auto From = TD->getInstantiatedFrom();
if (auto *CTD = From.dyn_cast<ClassTemplateDecl *>()) {
- while (auto *NewCTD = CTD->getInstantiatedFromMemberTemplate()) {
- if (NewCTD->isMemberSpecialization())
+ while (!CTD->isMemberSpecialization()) {
+ auto *NewCTD = CTD->getInstantiatedFromMemberTemplate();
+ if (!NewCTD)
break;
CTD = NewCTD;
}
return CTD->getTemplatedDecl()->getDefinition();
}
if (auto *CTPSD =
From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
- while (auto *NewCTPSD = CTPSD->getInstantiatedFromMember()) {
- if (NewCTPSD->isMemberSpecialization())
+ while (!CTPSD->isMemberSpecialization()) {
+ auto *NewCTPSD = CTPSD->getInstantiatedFromMember();
+ if (!NewCTPSD)
break;
CTPSD = NewCTPSD;
}
Index: lib/AST/Decl.cpp
===================================================================
--- lib/AST/Decl.cpp
+++ lib/AST/Decl.cpp
@@ -1049,7 +1049,9 @@
// If this is a member class of a specialization of a class template
// and the corresponding decl has explicit visibility, use that.
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(ND)) {
- CXXRecordDecl *InstantiatedFrom = RD->getInstantiatedFromMemberClass();
+ const CXXRecordDecl *InstantiatedFrom = RD->getTemplateInstantiationPattern();
+ if (!InstantiatedFrom)
+ InstantiatedFrom = RD->getInstantiatedFromMemberClass();
if (InstantiatedFrom)
return getVisibilityOf(InstantiatedFrom, kind);
}
@@ -1084,16 +1086,12 @@
}
// Also handle function template specializations.
if (const FunctionDecl *fn = dyn_cast<FunctionDecl>(ND)) {
- // If the function is a specialization of a template with an
- // explicit visibility attribute, use that.
- if (FunctionTemplateSpecializationInfo *templateInfo
- = fn->getTemplateSpecializationInfo())
- return getVisibilityOf(templateInfo->getTemplate()->getTemplatedDecl(),
- kind);
-
- // If the function is a member of a specialization of a class template
- // and the corresponding decl has explicit visibility, use that.
- FunctionDecl *InstantiatedFrom = fn->getInstantiatedFromMemberFunction();
+ // If the function is a template specialization or a member of
+ // a specialized class template and the corresponding decl has
+ // explicit visibility, use that.
+ FunctionDecl *InstantiatedFrom = fn->getTemplateInstantiationPattern();
+ if (!InstantiatedFrom)
+ InstantiatedFrom = fn->getInstantiatedFromMemberFunction();
if (InstantiatedFrom)
return getVisibilityOf(InstantiatedFrom, kind);
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits