Fix for PR32992. Static const classes not exported.

Patch by zahiraam!

Differential Revision: https://reviews.llvm.org/D42968

llvm-svn: 324991
This commit is contained in:
Hans Wennborg 2018-02-13 09:19:43 +00:00
parent 0bb24cd4fa
commit 3bd0a15867
2 changed files with 32 additions and 3 deletions

View File

@ -5476,7 +5476,7 @@ static void CheckAbstractClassUsage(AbstractUsageInfo &Info,
}
}
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(Sema &S, CXXRecordDecl *Class) {
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(Decl *D) {
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);
}
}

View File

@ -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_Object : public ACE_Shared_Object {};
// 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