Author: sberg Date: Wed Mar 7 23:34:40 2018 New Revision: 326990 URL: http://llvm.org/viewvc/llvm-project?rev=326990&view=rev Log: Propagate DLLAttr to friend re-declarations of member functions
...that have already been constructed (e.g., in inner classes) while parsing the class definition. They would otherwise lack any DLLAttr inherited from the class, which are only set here (called from Sema::CheckCompletedClass) after the class definition has been parsed completely. Differential revision: https://reviews.llvm.org/D16632 Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp cfe/trunk/test/CodeGenCXX/dllexport.cpp Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=326990&r1=326989&r2=326990&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original) +++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Wed Mar 7 23:34:40 2018 @@ -5685,6 +5685,21 @@ void Sema::checkClassLevelDLLAttribute(C 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); + } + } } } Modified: cfe/trunk/test/CodeGenCXX/dllexport.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/dllexport.cpp?rev=326990&r1=326989&r2=326990&view=diff ============================================================================== --- cfe/trunk/test/CodeGenCXX/dllexport.cpp (original) +++ cfe/trunk/test/CodeGenCXX/dllexport.cpp Wed Mar 7 23:34:40 2018 @@ -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]}}( _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits