From 98641f22328f8541a90a380ee2cfe6d61e106254 Mon Sep 17 00:00:00 2001 From: Shoaib Meenai Date: Thu, 20 Apr 2017 01:11:42 +0000 Subject: [PATCH] [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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@300804 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaTemplateInstantiate.cpp | 7 +++--- test/CodeGenCXX/windows-itanium-dllexport.cpp | 25 +++++++++++++++++++ 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index edd6edfce9..2d44489023 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/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/test/CodeGenCXX/windows-itanium-dllexport.cpp b/test/CodeGenCXX/windows-itanium-dllexport.cpp index 92cca24442..ff780c7778 100644 --- a/test/CodeGenCXX/windows-itanium-dllexport.cpp +++ b/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; // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdEaSERKS0_ // CHECK: define {{.*}} dllexport {{.*}} @_ZN1cIdE1fEv + +template +struct outer { + void f() {} + struct inner { + void f() {} + }; +}; + +template class __declspec(dllexport) outer; + +// CHECK: define {{.*}} dllexport {{.*}} @_ZN5outerIiE1fEv +// CHECK-NOT: define {{.*}} dllexport {{.*}} @_ZN5outerIiE5inner1fEv + +extern template class __declspec(dllimport) outer; +USEMEMFUNC(outer, f) +USEMEMFUNC(outer::inner, f) + +// CHECK: declare dllimport {{.*}} @_ZN5outerIcE1fEv +// CHECK: define {{.*}} @_ZN5outerIcE5inner1fEv -- 2.40.0