diff options
author | Hans Wennborg <hans@hanshq.net> | 2017-10-05 21:45:27 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2017-10-05 21:45:27 +0000 |
commit | 9da3c75a1356cb0a67cc329f246a4a40bbb450db (patch) | |
tree | 591e52a50e7e519fd860c2addf99f1786b365c6e | |
parent | 44f9376347d7fd4e1ef85dfd284e1549c42ecb81 (diff) | |
download | bcm5719-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.cpp | 15 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/dllexport.cpp | 8 |
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 |