summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Bergmann <sbergman@redhat.com>2018-03-08 07:34:40 +0000
committerStephan Bergmann <sbergman@redhat.com>2018-03-08 07:34:40 +0000
commit0feb0b9059792596e8386d030fa3d0aed9527798 (patch)
tree320adaa17876e2c69cec839e128cb7937e4c3010
parent5bbcca6967acfdfd845cddeec4123ea0be3388e0 (diff)
downloadbcm5719-llvm-0feb0b9059792596e8386d030fa3d0aed9527798.tar.gz
bcm5719-llvm-0feb0b9059792596e8386d030fa3d0aed9527798.zip
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 llvm-svn: 326990
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp15
-rw-r--r--clang/test/CodeGenCXX/dllexport.cpp10
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]}}(
OpenPOWER on IntegriCloud