Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -2685,10 +2685,14 @@ continue; if ((Context.getTargetInfo().getCXXABI().isMicrosoft() || - Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment()) && + Context.getTargetInfo().getTriple().isWindowsItaniumEnvironment() || + Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) && TSK == TSK_ExplicitInstantiationDeclaration) { // In MSVC and Windows Itanium mode, explicit instantiation decl of the // outer class doesn't affect the inner class. + // In GNU mode, inner classes aren't dllexported. Don't let the + // instantiation cover the inner class, to avoid undefined references + // to inner classes that weren't exported. continue; } Index: test/CodeGenCXX/mingw-template-dllexport.cpp =================================================================== --- test/CodeGenCXX/mingw-template-dllexport.cpp +++ test/CodeGenCXX/mingw-template-dllexport.cpp @@ -1,5 +1,10 @@ // RUN: %clang_cc1 -emit-llvm -triple i686-mingw32 %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; } + template class c { void f(); @@ -36,3 +41,10 @@ // 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