[Modules][ObjC] ASTReader should add protocols for class extensions

During deserialization clang is currently missing the merging of
protocols into the canonical interface for the class extension.

This merging only currently happens during parsing and should also
be considered during deserialization.

rdar://problem/38724303

llvm-svn: 331063
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 7a5d22c..046c699 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -1205,6 +1205,12 @@
     ProtoLocs.push_back(ReadSourceLocation());
   CD->setProtocolList(ProtoRefs.data(), NumProtoRefs, ProtoLocs.data(),
                       Reader.getContext());
+
+  // Protocols in the class extension belong to the class.
+  if (NumProtoRefs > 0 && CD->ClassInterface && CD->IsClassExtension())
+    CD->ClassInterface->mergeClassExtensionProtocolList(
+        (ObjCProtocolDecl *const *)ProtoRefs.data(), NumProtoRefs,
+        Reader.getContext());
 }
 
 void ASTDeclReader::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *CAD) {
diff --git a/clang/test/Modules/Inputs/class-extension/a-private.h b/clang/test/Modules/Inputs/class-extension/a-private.h
new file mode 100644
index 0000000..e35402a
--- /dev/null
+++ b/clang/test/Modules/Inputs/class-extension/a-private.h
@@ -0,0 +1,5 @@
+#import "a.h"
+#import "a-proto.h"
+
+@interface A () <AProto>
+@end
diff --git a/clang/test/Modules/Inputs/class-extension/a-proto.h b/clang/test/Modules/Inputs/class-extension/a-proto.h
new file mode 100644
index 0000000..32043ec
--- /dev/null
+++ b/clang/test/Modules/Inputs/class-extension/a-proto.h
@@ -0,0 +1,7 @@
+@protocol NSObject
+@end
+
+@protocol AProto <NSObject>
+@property (nonatomic, readwrite, assign) int p0;
+@property (nonatomic, readwrite, assign) int p1;
+@end
diff --git a/clang/test/Modules/Inputs/class-extension/a.h b/clang/test/Modules/Inputs/class-extension/a.h
new file mode 100644
index 0000000..28c409c
--- /dev/null
+++ b/clang/test/Modules/Inputs/class-extension/a.h
@@ -0,0 +1,5 @@
+@interface NSObject
+@end
+
+@interface A : NSObject
+@end
diff --git a/clang/test/Modules/Inputs/class-extension/module.modulemap b/clang/test/Modules/Inputs/class-extension/module.modulemap
new file mode 100644
index 0000000..5c30bc5
--- /dev/null
+++ b/clang/test/Modules/Inputs/class-extension/module.modulemap
@@ -0,0 +1,11 @@
+
+module A {
+  header "a.h"
+  header "a-proto.h"
+  export *
+}
+
+module AP {
+  header "a-private.h"
+  export *
+}
diff --git a/clang/test/Modules/class-extension-protocol.m b/clang/test/Modules/class-extension-protocol.m
new file mode 100644
index 0000000..752e4e1
--- /dev/null
+++ b/clang/test/Modules/class-extension-protocol.m
@@ -0,0 +1,9 @@
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 %s -fsyntax-only -fmodules -fimplicit-module-maps -fmodules-cache-path=%t.cache -I%S/Inputs/class-extension -verify
+// expected-no-diagnostics
+
+#import "a-private.h"
+
+int foo(A *X) {
+  return X.p0 + X.p1;
+}