Reduced repro: $ clang -cc1 -triple i386-pc-windows-msvc19.11.0 -emit-pch -fms-extensions -fms-compatibility -fms-compatibility-version=19.11 -std=c++14 -fdelayed-template-parsing -x c++-header a.ii -o /dev/null
a.ii: namespace a { enum b { c }; } template <typename> class d { static constexpr a::b e = a::c; }; namespace f { template <typename g = int> class h : d<g> {}; } using f::h; class __declspec(dllexport) i : h<> {}; On Wed, Feb 14, 2018 at 4:22 PM, Hans Wennborg <h...@chromium.org> wrote: > I ended up having to revert this in r325133 as it broke the Chromium > build. Please see > https://bugs.chromium.org/p/chromium/issues/detail?id=812231#c1 for a > reproducer. > > On Tue, Feb 13, 2018 at 10:19 AM, Hans Wennborg via cfe-commits > <cfe-commits@lists.llvm.org> wrote: >> Author: hans >> Date: Tue Feb 13 01:19:43 2018 >> New Revision: 324991 >> >> URL: http://llvm.org/viewvc/llvm-project?rev=324991&view=rev >> Log: >> Fix for PR32992. Static const classes not exported. >> >> Patch by zahiraam! >> >> Differential Revision: https://reviews.llvm.org/D42968 >> >> Modified: >> cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> cfe/trunk/test/CodeGenCXX/dllexport.cpp >> >> Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=324991&r1=324990&r2=324991&view=diff >> ============================================================================== >> --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) >> +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Tue Feb 13 01:19:43 2018 >> @@ -5476,7 +5476,7 @@ static void CheckAbstractClassUsage(Abst >> } >> } >> >> -static void ReferenceDllExportedMethods(Sema &S, CXXRecordDecl *Class) { >> +static void ReferenceDllExportedMembers(Sema &S, CXXRecordDecl *Class) { >> Attr *ClassAttr = getDLLAttr(Class); >> if (!ClassAttr) >> return; >> @@ -5491,6 +5491,16 @@ static void ReferenceDllExportedMethods( >> return; >> >> for (Decl *Member : Class->decls()) { >> + // Defined static variables that are members of an exported base >> + // class must be marked export too. Push them to implicit instantiation >> + // queue. >> + auto *VD = dyn_cast<VarDecl>(Member); >> + if (VD && Member->getAttr<DLLExportAttr>() && >> + VD->getStorageClass() == SC_Static && >> + TSK == TSK_ImplicitInstantiation) >> + S.PendingLocalImplicitInstantiations.push_back( >> + std::make_pair(VD, VD->getLocation())); >> + >> auto *MD = dyn_cast<CXXMethodDecl>(Member); >> if (!MD) >> continue; >> @@ -10902,12 +10912,12 @@ void Sema::ActOnFinishCXXNonNestedClass( >> >> void Sema::referenceDLLExportedClassMethods() { >> if (!DelayedDllExportClasses.empty()) { >> - // Calling ReferenceDllExportedMethods might cause the current function >> to >> + // Calling ReferenceDllExportedMembers might cause the current function >> to >> // be called again, so use a local copy of DelayedDllExportClasses. >> SmallVector<CXXRecordDecl *, 4> WorkList; >> std::swap(DelayedDllExportClasses, WorkList); >> for (CXXRecordDecl *Class : WorkList) >> - ReferenceDllExportedMethods(*this, Class); >> + ReferenceDllExportedMembers(*this, Class); >> } >> } >> >> >> Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp >> URL: >> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=324991&r1=324990&r2=324991&view=diff >> ============================================================================== >> --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original) >> +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Tue Feb 13 01:19:43 2018 >> @@ -28,6 +28,7 @@ struct External { int v; }; >> >> // The vftable for struct W is comdat largest because we have RTTI. >> // M32-DAG: $"\01??_7W@@6B@" = comdat largest >> +// M32-DAG: $"\01?smember@?$Base@H@PR32992@@0HA" = comdat any >> >> >> >> //===----------------------------------------------------------------------===// >> @@ -977,3 +978,21 @@ class __declspec(dllexport) ACE_Service_ >> // MSVC2015-DAG: define weak_odr dllexport >> {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q >> // The declarations should not be exported. >> // MSVC2013-NOT: define weak_odr dllexport >> {{.+}}ACE_Service_Object@@Q{{.+}}@$$Q >> + >> +namespace PR32992 { >> +// Static data members of a instantiated base class should be exported. >> +template <class T> >> +class Base { >> + virtual void myfunc() {} >> + static int smember; >> +}; >> +// MS-DAG: @"\01?smember@?$Base@H@PR32992@@0HA" = weak_odr dllexport >> global i32 77, comdat, align 4 >> +template <class T> int Base<T>::smember = 77; >> +template <class T> >> +class __declspec(dllexport) Derived2 : Base<T> { >> + void myfunc() {} >> +}; >> +class Derived : public Derived2<int> { >> + void myfunc() {} >> +}; >> +} // namespace PR32992 >> >> >> _______________________________________________ >> cfe-commits mailing list >> cfe-commits@lists.llvm.org >> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits