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 llvm-svn: 326089
This commit is contained in:
parent
832f90fa0c
commit
83665e6d36
|
@ -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);
|
Attr *ClassAttr = getDLLAttr(Class);
|
||||||
if (!ClassAttr)
|
if (!ClassAttr)
|
||||||
return;
|
return;
|
||||||
|
@ -5491,6 +5491,14 @@ static void ReferenceDllExportedMethods(Sema &S, CXXRecordDecl *Class) {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (Decl *Member : Class->decls()) {
|
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);
|
auto *MD = dyn_cast<CXXMethodDecl>(Member);
|
||||||
if (!MD)
|
if (!MD)
|
||||||
continue;
|
continue;
|
||||||
|
@ -10902,12 +10910,12 @@ void Sema::ActOnFinishCXXNonNestedClass(Decl *D) {
|
||||||
|
|
||||||
void Sema::referenceDLLExportedClassMethods() {
|
void Sema::referenceDLLExportedClassMethods() {
|
||||||
if (!DelayedDllExportClasses.empty()) {
|
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.
|
// be called again, so use a local copy of DelayedDllExportClasses.
|
||||||
SmallVector<CXXRecordDecl *, 4> WorkList;
|
SmallVector<CXXRecordDecl *, 4> WorkList;
|
||||||
std::swap(DelayedDllExportClasses, WorkList);
|
std::swap(DelayedDllExportClasses, WorkList);
|
||||||
for (CXXRecordDecl *Class : WorkList)
|
for (CXXRecordDecl *Class : WorkList)
|
||||||
ReferenceDllExportedMethods(*this, Class);
|
ReferenceDllExportedMembers(*this, Class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,8 @@ struct External { int v; };
|
||||||
// The vftable for struct W is comdat largest because we have RTTI.
|
// The vftable for struct W is comdat largest because we have RTTI.
|
||||||
// M32-DAG: $"\01??_7W@@6B@" = comdat largest
|
// M32-DAG: $"\01??_7W@@6B@" = comdat largest
|
||||||
|
|
||||||
|
// M32-DAG: $"\01?smember@?$Base@H@PR32992@@0HA" = comdat any
|
||||||
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Globals
|
// Globals
|
||||||
|
@ -94,7 +96,35 @@ inline int __declspec(dllexport) inlineStaticLocalsFunc() {
|
||||||
return x++;
|
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
|
// Variable templates
|
||||||
|
|
Loading…
Reference in New Issue