[llvm-branch-commits] [cfe-branch] r311357 - Mention some warning-related additions and changes for LLVM 5

2017-08-21 Thread Alex Lorenz via llvm-branch-commits
Author: arphaman
Date: Mon Aug 21 10:47:51 2017
New Revision: 311357

URL: http://llvm.org/viewvc/llvm-project?rev=311357&view=rev
Log:
Mention some warning-related additions and changes for LLVM 5
release notes

Modified:
cfe/branches/release_50/docs/ReleaseNotes.rst

Modified: cfe/branches/release_50/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/branches/release_50/docs/ReleaseNotes.rst?rev=311357&r1=311356&r2=311357&view=diff
==
--- cfe/branches/release_50/docs/ReleaseNotes.rst (original)
+++ cfe/branches/release_50/docs/ReleaseNotes.rst Mon Aug 21 10:47:51 2017
@@ -58,6 +58,25 @@ Improvements to Clang's diagnostics
 -  -Wunused-lambda-capture warns when a variable explicitly captured
by a lambda is not used in the body of the lambda.
 
+-  -Wstrict-prototypes is a new warning that warns about non-prototype
+   function and block declarations and types in C and Objective-C.
+
+-  -Wunguarded-availability is a new warning that warns about uses of new
+   APIs that were introduced in a system whose version is newer than the
+   deployment target version. A new Objective-C expression ``@available`` has
+   been introduced to perform system version checking at runtime. This warning
+   is off by default to prevent unexpected warnings in existing projects.
+   However, its less strict sibling -Wunguarded-availability-new is on by
+   default. It warns about unguarded uses of APIs only when they were 
introduced
+   in or after macOS 10.13, iOS 11, tvOS 11 or watchOS 4.
+
+-  The -Wdocumentation warning now allows the use of ``\param`` and
+   ``\returns`` documentation directives in the documentation comments for
+   declarations with a function or a block pointer type.
+
+-  The compiler no longer warns about unreachable ``__builtin_unreachable``
+   statements.
+
 New Compiler Flags
 --
 


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [cfe-branch] r311453 - Mention #pragma pack PCH serialization change in release notes

2017-08-22 Thread Alex Lorenz via llvm-branch-commits
Author: arphaman
Date: Tue Aug 22 06:23:54 2017
New Revision: 311453

URL: http://llvm.org/viewvc/llvm-project?rev=311453&view=rev
Log:
Mention #pragma pack PCH serialization change in release notes

Modified:
cfe/branches/release_50/docs/ReleaseNotes.rst

Modified: cfe/branches/release_50/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/branches/release_50/docs/ReleaseNotes.rst?rev=311453&r1=311452&r2=311453&view=diff
==
--- cfe/branches/release_50/docs/ReleaseNotes.rst (original)
+++ cfe/branches/release_50/docs/ReleaseNotes.rst Tue Aug 22 06:23:54 2017
@@ -98,6 +98,10 @@ New Pragmas in Clang
 - Clang now supports the ``clang attribute`` pragma that allows users to apply
   an attribute to multiple declarations.
 
+- ``pragma pack`` directives that are included in a precompiled header are now
+  applied correctly to the declarations in the compilation unit that includes
+  that precompiled header.
+
 Attribute Changes in Clang
 --
 


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [cfe-branch] r311452 - Mention #pragma clang attribute in the release notes

2017-08-22 Thread Alex Lorenz via llvm-branch-commits
Author: arphaman
Date: Tue Aug 22 06:15:19 2017
New Revision: 311452

URL: http://llvm.org/viewvc/llvm-project?rev=311452&view=rev
Log:
Mention #pragma clang attribute in the release notes

Modified:
cfe/branches/release_50/docs/ReleaseNotes.rst

Modified: cfe/branches/release_50/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/branches/release_50/docs/ReleaseNotes.rst?rev=311452&r1=311451&r2=311452&view=diff
==
--- cfe/branches/release_50/docs/ReleaseNotes.rst (original)
+++ cfe/branches/release_50/docs/ReleaseNotes.rst Tue Aug 22 06:15:19 2017
@@ -95,8 +95,8 @@ future versions of Clang.
 New Pragmas in Clang
 ---
 
-Clang now supports the ...
-
+- Clang now supports the ``clang attribute`` pragma that allows users to apply
+  an attribute to multiple declarations.
 
 Attribute Changes in Clang
 --


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [cfe-branch] r311451 - Mention the ObjC property synthesis changes in release notes

2017-08-22 Thread Alex Lorenz via llvm-branch-commits
Author: arphaman
Date: Tue Aug 22 06:11:19 2017
New Revision: 311451

URL: http://llvm.org/viewvc/llvm-project?rev=311451&view=rev
Log:
Mention the ObjC property synthesis changes in release notes

Modified:
cfe/branches/release_50/docs/ReleaseNotes.rst

Modified: cfe/branches/release_50/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/branches/release_50/docs/ReleaseNotes.rst?rev=311451&r1=311450&r2=311451&view=diff
==
--- cfe/branches/release_50/docs/ReleaseNotes.rst (original)
+++ cfe/branches/release_50/docs/ReleaseNotes.rst Tue Aug 22 06:11:19 2017
@@ -176,7 +176,16 @@ C++1z Feature Support
 Objective-C Language Changes in Clang
 -
 
-...
+- Clang now guarantees that a ``readwrite`` property is synthesized when an
+  ambiguous property (i.e. a property that's declared in multiple protocols)
+  is synthesized. The ``-Wprotocol-property-synthesis-ambiguity`` warning that
+  warns about incompatible property types is now promoted to an error when
+  there's an ambiguity between ``readwrite`` and ``readonly`` properties.
+
+- Clang now prohibits synthesis of ambiguous properties with incompatible
+  explicit property attributes. The following property attributes are
+  checked for differences: ``copy``, ``retain``/``strong``, ``atomic``,
+  ``getter`` and ``setter``.
 
 OpenCL C Language Changes in Clang
 --


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [cfe-branch] r311455 - Mention libclang code-completion changes in release notes

2017-08-22 Thread Alex Lorenz via llvm-branch-commits
Author: arphaman
Date: Tue Aug 22 06:36:03 2017
New Revision: 311455

URL: http://llvm.org/viewvc/llvm-project?rev=311455&view=rev
Log:
Mention libclang code-completion changes in release notes

Modified:
cfe/branches/release_50/docs/ReleaseNotes.rst

Modified: cfe/branches/release_50/docs/ReleaseNotes.rst
URL: 
http://llvm.org/viewvc/llvm-project/cfe/branches/release_50/docs/ReleaseNotes.rst?rev=311455&r1=311454&r2=311455&view=diff
==
--- cfe/branches/release_50/docs/ReleaseNotes.rst (original)
+++ cfe/branches/release_50/docs/ReleaseNotes.rst Tue Aug 22 06:36:03 2017
@@ -266,8 +266,30 @@ clang-format
 libclang
 
 
-...
+- Libclang now provides code-completion results for more C++ constructs
+  and keywords. The following keywords/identifiers are now included in the
+  code-completion results: ``static_assert``, ``alignas``, ``constexpr``,
+  ``final``, ``noexcept``, ``override`` and ``thread_local``.
 
+- Libclang now provides code-completion results for members from dependent
+  classes. For example:
+
+  .. code-block:: c++
+
+template
+void appendValue(std::vector &dest, const T &value) {
+dest. // Relevant completion results are now shown after '.'
+}
+
+  Note that code-completion results are still not provided when the member
+  expression includes a dependent base expression. For example:
+
+  .. code-block:: c++
+
+template
+void appendValue(std::vector> &dest, const T &value) {
+dest.at(0). // Libclang fails to provide completion results after '.'
+}
 
 Static Analyzer
 ---


___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] 03dcd57 - [clang] add a new `swift_attr` attribute

2020-12-04 Thread Alex Lorenz via llvm-branch-commits

Author: Alex Lorenz
Date: 2020-12-04T15:53:24-08:00
New Revision: 03dcd57ecf99b31021644b868cae422897d520f8

URL: 
https://github.com/llvm/llvm-project/commit/03dcd57ecf99b31021644b868cae422897d520f8
DIFF: 
https://github.com/llvm/llvm-project/commit/03dcd57ecf99b31021644b868cae422897d520f8.diff

LOG: [clang] add a new `swift_attr` attribute

The swift_attr attribute is a generic annotation attribute that's not used by 
clang,
but is used by the Swift compiler. The Swift compiler can use these annotations 
to provide
various syntactic and semantic sugars for the imported Objective-C API 
declarations.

Differential Revision: https://reviews.llvm.org/D92354

Added: 
clang/test/AST/attr-swift_attr.m
clang/test/SemaObjC/validate-attr-swift_attr.m

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/lib/Sema/SemaDeclAttr.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 8555bd351747..3beef7b89243 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2149,6 +2149,12 @@ def Regparm : TypeAttr {
   let ASTNode = 0;
 }
 
+def SwiftAttr : InheritableAttr {
+  let Spellings = [GNU<"swift_attr">];
+  let Args = [StringArgument<"Attribute">];
+  let Documentation = [SwiftAttrDocs];
+}
+
 def SwiftBridge : InheritableAttr {
   let Spellings = [GNU<"swift_bridge">];
   let Args = [StringArgument<"SwiftType">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 1781543cc4f3..673c9553c83d 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3628,6 +3628,19 @@ Swift.
   }];
 }
 
+def SwiftAttrDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_attr";
+  let Content = [{
+The ``swift_attr`` provides a Swift-specific annotation for the declaration
+to which the attribute appertains to. It can be used on any declaration
+in Clang. This kind of annotation is ignored by Clang as it doesn't have any
+semantic meaning in languages supported by Clang. The Swift compiler can
+interpret these annotations according to its own rules when importing C or
+Objective-C declarations.
+}];
+}
+
 def SwiftBridgeDocs : Documentation {
   let Category = SwiftDocs;
   let Heading = "swift_bridge";

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index d31d18eac474..e0aa6d1f119c 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5607,6 +5607,16 @@ static void handleObjCPreciseLifetimeAttr(Sema &S, Decl 
*D,
   D->addAttr(::new (S.Context) ObjCPreciseLifetimeAttr(S.Context, AL));
 }
 
+static void handleSwiftAttrAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
+  // Make sure that there is a string literal as the annotation's single
+  // argument.
+  StringRef Str;
+  if (!S.checkStringLiteralArgumentAttr(AL, 0, Str))
+return;
+
+  D->addAttr(::new (S.Context) SwiftAttrAttr(S.Context, AL, Str));
+}
+
 static void handleSwiftBridge(Sema &S, Decl *D, const ParsedAttr &AL) {
   // Make sure that there is a string literal as the annotation's single
   // argument.
@@ -7941,6 +7951,9 @@ static void ProcessDeclAttribute(Sema &S, Scope *scope, 
Decl *D,
 break;
 
   // Swift attributes.
+  case ParsedAttr::AT_SwiftAttr:
+handleSwiftAttrAttr(S, D, AL);
+break;
   case ParsedAttr::AT_SwiftBridge:
 handleSwiftBridge(S, D, AL);
 break;

diff  --git a/clang/test/AST/attr-swift_attr.m 
b/clang/test/AST/attr-swift_attr.m
new file mode 100644
index ..3cd51b81e349
--- /dev/null
+++ b/clang/test/AST/attr-swift_attr.m
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -ast-dump %s | FileCheck %s
+
+__attribute__((swift_attr("@actor")))
+@interface View
+@end
+
+// CHECK: InterfaceDecl {{.*}} View
+// CHECK-NEXT: SwiftAttrAttr {{.*}} "@actor"

diff  --git a/clang/test/SemaObjC/validate-attr-swift_attr.m 
b/clang/test/SemaObjC/validate-attr-swift_attr.m
new file mode 100644
index ..4ff434d17972
--- /dev/null
+++ b/clang/test/SemaObjC/validate-attr-swift_attr.m
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -verify -fsyntax-only %s
+
+// expected-error@+1 {{'swift_attr' attribute takes one argument}}
+__attribute__((swift_attr))
+@interface I
+@end
+
+// expected-error@+1 {{'swift_attr' attribute requires a string}}
+__attribute__((swift_attr(1)))
+@interface J
+@end



___
llvm-branch-commits mailing list
llvm-branch-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits


[llvm-branch-commits] [clang] eddd1d1 - [clang] add a `swift_async_name` attribute

2020-12-04 Thread Alex Lorenz via llvm-branch-commits

Author: Alex Lorenz
Date: 2020-12-04T15:55:29-08:00
New Revision: eddd1d192bcaf11e449b34a3a569b85eb390e4f2

URL: 
https://github.com/llvm/llvm-project/commit/eddd1d192bcaf11e449b34a3a569b85eb390e4f2
DIFF: 
https://github.com/llvm/llvm-project/commit/eddd1d192bcaf11e449b34a3a569b85eb390e4f2.diff

LOG: [clang] add a `swift_async_name` attribute

The swift_async_name attribute provides a name for a function/method that can 
be used
to call the async overload of this method from Swift. This name specified in 
this attribute
assumes that the last parameter in the function/method its applied to is 
removed when
Swift invokes it, as the the Swift's await/async transformation implicitly 
constructs the callback.

Differential Revision: https://reviews.llvm.org/D92355

Added: 
clang/test/SemaObjCXX/attr-swift_name-cxx.mm

Modified: 
clang/include/clang/Basic/Attr.td
clang/include/clang/Basic/AttrDocs.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/include/clang/Sema/Sema.h
clang/lib/Sema/SemaDeclAttr.cpp
clang/test/Misc/pragma-attribute-supported-attributes-list.test
clang/test/SemaObjC/attr-swift_name.m

Removed: 




diff  --git a/clang/include/clang/Basic/Attr.td 
b/clang/include/clang/Basic/Attr.td
index 3beef7b89243..0212b60a2afe 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -2149,6 +2149,13 @@ def Regparm : TypeAttr {
   let ASTNode = 0;
 }
 
+def SwiftAsyncName : InheritableAttr {
+  let Spellings = [GNU<"swift_async_name">];
+  let Args = [StringArgument<"Name">];
+  let Subjects = SubjectList<[ObjCMethod, Function], ErrorDiag>;
+  let Documentation = [SwiftAsyncNameDocs];
+}
+
 def SwiftAttr : InheritableAttr {
   let Spellings = [GNU<"swift_attr">];
   let Args = [StringArgument<"Attribute">];

diff  --git a/clang/include/clang/Basic/AttrDocs.td 
b/clang/include/clang/Basic/AttrDocs.td
index 673c9553c83d..bf985986e21b 100644
--- a/clang/include/clang/Basic/AttrDocs.td
+++ b/clang/include/clang/Basic/AttrDocs.td
@@ -3628,6 +3628,27 @@ Swift.
   }];
 }
 
+def SwiftAsyncNameDocs : Documentation {
+  let Category = SwiftDocs;
+  let Heading = "swift_async_name";
+  let Content = [{
+The ``swift_async_name`` attribute provides the name of the ``async`` overload 
for
+the given declaration in Swift. If this attribute is absent, the name is
+transformed according to the algorithm built into the Swift compiler.
+
+The argument is a string literal that contains the Swift name of the function 
or
+method. The name may be a compound Swift name. The function or method with such
+an attribute must have more than zero parameters, as its last parameter is
+assumed to be a callback that's eliminated in the Swift ``async`` name.
+
+  .. code-block:: objc
+
+@interface URL
++ (void) loadContentsFrom:(URL *)url callback:(void (^)(NSData *))data 
__attribute__((__swift_async_name__("URL.loadContentsFrom(_:)")))
+@end
+  }];
+}
+
 def SwiftAttrDocs : Documentation {
   let Category = SwiftDocs;
   let Heading = "swift_attr";

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index f51ef849b932..21660965abf7 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -4028,7 +4028,12 @@ def warn_attr_swift_name_subscript_getter_newValue
   : Warning<"%0 attribute for 'subscript' getter cannot have a 'newValue:' 
parameter">,
 InGroup;
 def warn_attr_swift_name_num_params
-  : Warning<"too %select{few|many}0 parameters in %1 attribute (expected %2; 
got %3)">,
+  : Warning<"too %select{few|many}0 parameters in the signature specified by "
+"the %1 attribute (expected %2; got %3)">,
+InGroup;
+def warn_attr_swift_name_decl_missing_params
+  : Warning<"%0 attribute cannot be applied to a %select{function|method}1 "
+"with no parameters">,
 InGroup;
 
 def err_attr_swift_error_no_error_parameter : Error<

diff  --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b3ede504542f..980be69cb1a5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -1977,7 +1977,7 @@ class Sema final {
   ///
   /// \returns true if the name is a valid swift name for \p D, false 
otherwise.
   bool DiagnoseSwiftName(Decl *D, StringRef Name, SourceLocation Loc,
- const ParsedAttr &AL);
+ const ParsedAttr &AL, bool IsAsync);
 
   /// A derivative of BoundTypeDiagnoser for which the diagnostic's type
   /// parameter is preceded by a 0/1 enum that is 1 if the type is sizeless.

diff  --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index e0aa6d1f119c..a3153979deff 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5922,7 +5922,7 @@ validateSwiftFunctionN

[llvm-branch-commits] [clang] db226cd - [objc] diagnose protocol conformance in categories with direct members

2020-12-04 Thread Alex Lorenz via llvm-branch-commits

Author: Alex Lorenz
Date: 2020-12-04T15:55:34-08:00
New Revision: db226cdf4cf91f350267da1a5b95dda42dd23413

URL: 
https://github.com/llvm/llvm-project/commit/db226cdf4cf91f350267da1a5b95dda42dd23413
DIFF: 
https://github.com/llvm/llvm-project/commit/db226cdf4cf91f350267da1a5b95dda42dd23413.diff

LOG: [objc] diagnose protocol conformance in categories with direct members
in their corresponding class interfaces

Categories that add protocol conformances to classes with direct members should 
prohibit protocol
conformances when the methods/properties that the protocol expects are actually 
declared as 'direct' in the class.

Differential Revision: https://reviews.llvm.org/D92602

Added: 
clang/test/SemaObjC/category-direct-members-protocol-conformance.m

Modified: 
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaDeclObjC.cpp

Removed: 




diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 21660965abf7..01a521fc603e 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -1062,6 +1062,10 @@ def warn_objc_direct_property_ignored : Warning<
   InGroup;
 def err_objc_direct_dynamic_property : Error<
   "direct property cannot be @dynamic">;
+def err_objc_direct_protocol_conformance : Error<
+  "%select{category %1|class extension}0 cannot conform to protocol %2 because 
"
+  "of direct members declared in interface %3">;
+def note_direct_member_here : Note<"direct member declared here">;
 
 def warn_conflicting_overriding_ret_types : Warning<
   "conflicting return type in "

diff  --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index a48919685ba2..60253a82e93a 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -3912,6 +3912,55 @@ static void DiagnoseVariableSizedIvars(Sema &S, 
ObjCContainerDecl *OCD) {
   }
 }
 
+static void DiagnoseCategoryDirectMembersProtocolConformance(
+Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl);
+
+static void DiagnoseCategoryDirectMembersProtocolConformance(
+Sema &S, ObjCCategoryDecl *CDecl,
+const llvm::iterator_range &Protocols) {
+  for (auto *PI : Protocols)
+DiagnoseCategoryDirectMembersProtocolConformance(S, PI, CDecl);
+}
+
+static void DiagnoseCategoryDirectMembersProtocolConformance(
+Sema &S, ObjCProtocolDecl *PDecl, ObjCCategoryDecl *CDecl) {
+  if (!PDecl->isThisDeclarationADefinition() && PDecl->getDefinition())
+PDecl = PDecl->getDefinition();
+
+  llvm::SmallVector DirectMembers;
+  const auto *IDecl = CDecl->getClassInterface();
+  for (auto *MD : PDecl->methods()) {
+if (!MD->isPropertyAccessor()) {
+  if (const auto *CMD =
+  IDecl->getMethod(MD->getSelector(), MD->isInstanceMethod())) {
+if (CMD->isDirectMethod())
+  DirectMembers.push_back(CMD);
+  }
+}
+  }
+  for (auto *PD : PDecl->properties()) {
+if (const auto *CPD = IDecl->FindPropertyVisibleInPrimaryClass(
+PD->getIdentifier(),
+PD->isClassProperty()
+? ObjCPropertyQueryKind::OBJC_PR_query_class
+: ObjCPropertyQueryKind::OBJC_PR_query_instance)) {
+  if (CPD->isDirectProperty())
+DirectMembers.push_back(CPD);
+}
+  }
+  if (!DirectMembers.empty()) {
+S.Diag(CDecl->getLocation(), diag::err_objc_direct_protocol_conformance)
+<< CDecl->IsClassExtension() << CDecl << PDecl << IDecl;
+for (const auto *MD : DirectMembers)
+  S.Diag(MD->getLocation(), diag::note_direct_member_here);
+return;
+  }
+
+  // Check on this protocols's referenced protocols, recursively.
+  DiagnoseCategoryDirectMembersProtocolConformance(S, CDecl,
+   PDecl->protocols());
+}
+
 // Note: For class/category implementations, allMethods is always null.
 Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, ArrayRef 
allMethods,
ArrayRef allTUVars) {
@@ -4012,6 +4061,8 @@ Decl *Sema::ActOnAtEnd(Scope *S, SourceRange AtEnd, 
ArrayRef allMethods,
   ObjCInterfaceDecl *CCPrimary = C->getClassInterface();
   DiagnoseClassExtensionDupMethods(C, CCPrimary);
 }
+
+DiagnoseCategoryDirectMembersProtocolConformance(*this, C, C->protocols());
   }
   if (ObjCContainerDecl *CDecl = dyn_cast(ClassDecl)) {
 if (CDecl->getIdentifier())

diff  --git 
a/clang/test/SemaObjC/category-direct-members-protocol-conformance.m 
b/clang/test/SemaObjC/category-direct-members-protocol-conformance.m
new file mode 100644
index ..dfee42f58869
--- /dev/null
+++ b/clang/test/SemaObjC/category-direct-members-protocol-conformance.m
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+__attribute__((objc_root_class))
+@interface RootClass
+
+- (void)baseMethod;
+
+@end
+
+__attrib