summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2018-02-26 15:03:59 +0000
committerHans Wennborg <hans@hanshq.net>2018-02-26 15:03:59 +0000
commit83665e6d36bc383e89d3c65a3d701688a84406e3 (patch)
tree450f1a891b7e058d7d27d78f89ac70799c2f0503
parent832f90fa0c6618aa8c11f2f3fd45094f7c4272e5 (diff)
downloadbcm5719-llvm-83665e6d36bc383e89d3c65a3d701688a84406e3.tar.gz
bcm5719-llvm-83665e6d36bc383e89d3c65a3d701688a84406e3.zip
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
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp14
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp30
2 files changed, 41 insertions, 3 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 45adbe3a16e..76ef9af73ff 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -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,14 @@ 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.
+ 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(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);
}
}
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index 5c8a60b67da..4ab84c14f1b 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -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) inlineStaticLocalsFunc() {
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
OpenPOWER on IntegriCloud