diff options
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 15 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/dllexport.cpp | 10 |
2 files changed, 25 insertions, 0 deletions
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 51ba96fb1e8..9e3647548be 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -5685,6 +5685,21 @@ void Sema::checkClassLevelDLLAttribute(CXXRecordDecl *Class) { cast<InheritableAttr>(ClassAttr->clone(getASTContext())); NewAttr->setInherited(true); Member->addAttr(NewAttr); + + if (MD) { + // Propagate DLLAttr to friend re-declarations of MD that have already + // been constructed. + for (FunctionDecl *FD = MD->getMostRecentDecl(); FD; + FD = FD->getPreviousDecl()) { + if (FD->getFriendObjectKind() == Decl::FOK_None) + continue; + assert(!getDLLAttr(FD) && + "friend re-decl should not already have a DLLAttr"); + NewAttr = cast<InheritableAttr>(ClassAttr->clone(getASTContext())); + NewAttr->setInherited(true); + FD->addAttr(NewAttr); + } + } } } diff --git a/clang/test/CodeGenCXX/dllexport.cpp b/clang/test/CodeGenCXX/dllexport.cpp index 4155940f77e..82360557ee6 100644 --- a/clang/test/CodeGenCXX/dllexport.cpp +++ b/clang/test/CodeGenCXX/dllexport.cpp @@ -290,6 +290,16 @@ struct FuncFriend { __declspec(dllexport) void friend1() {} void friend2() {} +// MSC-DAG: define dso_local dllexport void @"\01?func@Befriended@@SAXXZ"() +// GNU-DAG: define dso_local dllexport void @_ZN10Befriended4funcEv() +struct __declspec(dllexport) Befriended { + static void func(); + struct Befriending { + friend void Befriended::func(); + }; +}; +void Befriended::func() {} + // Implicit declarations can be redeclared with dllexport. // MSC-DAG: define dso_local dllexport noalias i8* @"\01??2@{{YAPAXI|YAPEAX_K}}@Z"( // GNU-DAG: define dso_local dllexport noalias i8* @_Znw{{[yj]}}( |