summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShoaib Meenai <smeenai@fb.com>2017-04-20 01:11:42 +0000
committerShoaib Meenai <smeenai@fb.com>2017-04-20 01:11:42 +0000
commita90474544e47bd0d4452cfe4d9073ce48bacf150 (patch)
treeb63282d0bb870679b25cf717592ba832eb5ceedb
parent2b0d6134c768e36d9c1d3c2a8485e8e245b3b6f4 (diff)
downloadbcm5719-llvm-a90474544e47bd0d4452cfe4d9073ce48bacf150.tar.gz
bcm5719-llvm-a90474544e47bd0d4452cfe4d9073ce48bacf150.zip
[Sema] Use MSVC inner class behavior on Itanium
Windows Itanium aims to use MSVC export and import semantics. Inner class members shouldn't be exported on a dllexport explicit instantiation definition of the outer class, and they shouldn't be imported on a dllimport explicit instantiation declaration of the outer class (instead a local copy should be emitted). We were doing the first but not the second, and this mismatch can lead to link errors. Fix the behavior and add tests for both. Differential Revision: https://reviews.llvm.org/D32213 llvm-svn: 300804
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp7
-rw-r--r--clang/test/CodeGenCXX/windows-itanium-dllexport.cpp25
2 files changed, 29 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index edd6edfce9d..2d44489023e 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -2605,10 +2605,11 @@ Sema::InstantiateClassMembers(SourceLocation PointOfInstantiation,
== TSK_ExplicitSpecialization)
continue;
- if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ if ((Context.getTargetInfo().getCXXABI().isMicrosoft() ||
+ Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) &&
TSK == TSK_ExplicitInstantiationDeclaration) {
- // In MSVC mode, explicit instantiation decl of the outer class doesn't
- // affect the inner class.
+ // In MSVC and Windows Itanium mode, explicit instantiation decl of the
+ // outer class doesn't affect the inner class.
continue;
}
diff --git a/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp b/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp
index 92cca244428..ff780c77782 100644
--- a/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp
+++ b/clang/test/CodeGenCXX/windows-itanium-dllexport.cpp
@@ -1,5 +1,10 @@
// RUN: %clang_cc1 -emit-llvm -triple i686-windows-itanium -fdeclspec %s -o - | FileCheck %s
+#define JOIN2(x, y) x##y
+#define JOIN(x, y) JOIN2(x, y)
+#define UNIQ(name) JOIN(name, __LINE__)
+#define USEMEMFUNC(class, func) void (class::*UNIQ(use)())() { return &class::func; }
+
struct __declspec(dllexport) s {
void f() {}
};
@@ -28,3 +33,23 @@ template class __declspec(dllexport) c<double>;
// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdEaSERKS0_
// CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv
+
+template <class T>
+struct outer {
+ void f() {}
+ struct inner {
+ void f() {}
+ };
+};
+
+template class __declspec(dllexport) outer<int>;
+
+// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv
+// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv
+
+extern template class __declspec(dllimport) outer<char>;
+USEMEMFUNC(outer<char>, f)
+USEMEMFUNC(outer<char>::inner, f)
+
+// CHECK: declare dllimport {{.*}} @_ZN5outerIcE1fEv
+// CHECK: define {{.*}} @_ZN5outerIcE5inner1fEv
OpenPOWER on IntegriCloud