Author: hans Date: Mon Feb 26 07:03:59 2018 New Revision: 326089 URL: http://llvm.org/viewvc/llvm-project?rev=326089&view=rev Log: Re-commit r324991 "Fix for PR32992. Static const classes not exported."
Fix for PR32992. Static const classes not exported. Patch by zahiraam! (This re-lands the commit, but using S.MarkVariableReferenced instead of S.PendingInstantiations.push_back, and with an additional test.) 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=326089&r1=326088&r2=326089&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Feb 26 07:03:59 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,14 @@ 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. + auto *VD = dyn_cast<VarDecl>(Member); + if (VD && Member->getAttr<DLLExportAttr>() && + VD->getStorageClass() == SC_Static && + TSK == TSK_ImplicitInstantiation) + S.MarkVariableReferenced(VD->getLocation(), VD); + auto *MD = dyn_cast<CXXMethodDecl>(Member); if (!MD) continue; @@ -10902,12 +10910,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=326089&r1=326088&r2=326089&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original) +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Mon Feb 26 07:03:59 2018 @@ -29,6 +29,8 @@ 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 + //===----------------------------------------------------------------------===// // Globals @@ -94,7 +96,35 @@ inline int __declspec(dllexport) inlineS return x++; } +namespace PR32992 { +// Static data members of a instantiated base class should be exported. +template <class T> +class Base { + virtual void myfunc() {} + static int smember; +}; +// MSC-DAG: @"\01?smember@?$Base@H@PR32992@@0HA" = weak_odr dso_local 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 +namespace PR32992_1 { +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<> {}; +} //===----------------------------------------------------------------------===// // Variable templates _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits