Index: include/clang/Basic/DiagnosticSemaKinds.td =================================================================== --- include/clang/Basic/DiagnosticSemaKinds.td +++ include/clang/Basic/DiagnosticSemaKinds.td @@ -2109,6 +2109,8 @@ "definition of dllimport data">; def err_attribute_dllimport_static_field_definition : Error< "definition of dllimport static field not allowed">; +def err_attribute_dll_member_of_dll_class : Error< + "attribute %q0 cannot be applied to member of %q1 class">; def err_attribute_weakref_not_static : Error< "weakref declaration must have internal linkage">; def err_attribute_weakref_not_global_context : Error< @@ -2450,6 +2452,7 @@ InGroup>; def err_mismatched_visibility: Error<"visibility does not match previous declaration">; def note_previous_attribute : Note<"previous attribute is here">; +def note_class_attribute : Note<"class attribute is here">; def note_attribute : Note<"attribute is here">; def err_mismatched_ms_inheritance : Error< "inheritance model does not match %select{definition|previous declaration}0">; Index: lib/Sema/SemaDeclCXX.cpp =================================================================== --- lib/Sema/SemaDeclCXX.cpp +++ lib/Sema/SemaDeclCXX.cpp @@ -4377,16 +4377,24 @@ // specialization bases. for (Decl *Member : Class->decls()) { - if (getDLLAttr(Member)) { - // FIXME: Error about importing/exporting individual members. - } - if (!isa(Member) && !isa(Member)) continue; - auto *NewAttr = cast(ClassAttr->clone(S.getASTContext())); - NewAttr->setInherited(true); - Member->addAttr(NewAttr); + if (InheritableAttr *MemberAttr = getDLLAttr(Member)) { + if (!MemberAttr->isInherited()) { + S.Diag(MemberAttr->getLocation(), + diag::err_attribute_dll_member_of_dll_class) + << MemberAttr << ClassAttr; + S.Diag(ClassAttr->getLocation(), diag::note_class_attribute); + Member->setInvalidDecl(); + continue; + } + } else { + auto *NewAttr = + cast(ClassAttr->clone(S.getASTContext())); + NewAttr->setInherited(true); + Member->addAttr(NewAttr); + } if (CXXMethodDecl *MD = dyn_cast(Member)) { if (ClassExported) { Index: test/SemaCXX/dllimport.cpp =================================================================== --- test/SemaCXX/dllimport.cpp +++ test/SemaCXX/dllimport.cpp @@ -954,3 +954,13 @@ class __declspec(dllimport) ClassDecl; class __declspec(dllimport) ClassDef { }; + +class __declspec(dllimport) ImportClassWithDllMember { // expected-note2{{class attribute is here}} + void __declspec(dllexport) foo(); // expected-error{{attribute 'dllexport' cannot be applied to member of 'dllimport' class}} + void __declspec(dllimport) bar(); // expected-error{{attribute 'dllimport' cannot be applied to member of 'dllimport' class}} +}; + +class __declspec(dllexport) ExportClassWithDllMember { // expected-note2{{class attribute is here}} + void __declspec(dllimport) foo(); // expected-error{{attribute 'dllimport' cannot be applied to member of 'dllexport' class}} + void __declspec(dllexport) bar(); // expected-error{{attribute 'dllexport' cannot be applied to member of 'dllexport' class}} +};