summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2017-10-05 21:45:27 +0000
committerHans Wennborg <hans@hanshq.net>2017-10-05 21:45:27 +0000
commit9da3c75a1356cb0a67cc329f246a4a40bbb450db (patch)
tree591e52a50e7e519fd860c2addf99f1786b365c6e
parent44f9376347d7fd4e1ef85dfd284e1549c42ecb81 (diff)
downloadbcm5719-llvm-9da3c75a1356cb0a67cc329f246a4a40bbb450db.tar.gz
bcm5719-llvm-9da3c75a1356cb0a67cc329f246a4a40bbb450db.zip
For dllexport class templates, export specializations of member functions (PR34849)
llvm-svn: 315025
-rw-r--r--clang/lib/Sema/SemaDecl.cpp15
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp8
2 files changed, 23 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 48fb2318e61..5b90557e799 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6041,6 +6041,21 @@ static void checkDLLAttributeRedeclaration(Sema &S, NamedDecl *OldDecl,
diag::warn_dllimport_dropped_from_inline_function)
<< NewDecl << OldImportAttr;
}
+
+ // A specialization of a class template member function is processed here
+ // since it's a redeclaration. If the parent class is dllexport, the
+ // specialization inherits that attribute. This doesn't happen automatically
+ // since the parent class isn't instantiated until later.
+ if (IsSpecialization && isa<CXXMethodDecl>(NewDecl) && !NewImportAttr &&
+ !NewExportAttr) {
+ if (const DLLExportAttr *ParentExportAttr = cast<CXXMethodDecl>(NewDecl)
+ ->getParent()
+ ->getAttr<DLLExportAttr>()) {
+ DLLExportAttr *NewAttr = ParentExportAttr->clone(S.Context);
+ NewAttr->setInherited(true);
+ NewDecl->addAttr(NewAttr);
+ }
+ }
}
/// Given that we are within the definition of the given function,
diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp
index bdef2eb06e6..a984b6d7ef1 100644
--- a/clang/test/CodeGenCXX/dllexport.cpp
+++ b/clang/test/CodeGenCXX/dllexport.cpp
@@ -831,6 +831,14 @@ template <typename T> struct ExplicitInstantiationTwoAttributes { void f() {} };
template struct __declspec(dllexport) __declspec(dllimport) ExplicitInstantiationTwoAttributes<int>;
// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationTwoAttributes@H@@QAEXXZ"
+// Specializations of exported class template functions get exported.
+namespace pr34849 {
+template <typename T> struct __declspec(dllexport) ExportedClass { void foo(); };
+template<> void ExportedClass<int>::foo() {}
+template struct ExportedClass<int>;
+// M32-DAG: define dllexport x86_thiscallcc void @"\01?foo@?$ExportedClass@H@pr34849@@QAEXXZ"
+}
+
//===----------------------------------------------------------------------===//
// Classes with template base classes
OpenPOWER on IntegriCloud