diff options
| author | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2018-04-27 18:01:23 +0000 |
|---|---|---|
| committer | Bruno Cardoso Lopes <bruno.cardoso@gmail.com> | 2018-04-27 18:01:23 +0000 |
| commit | fbff2fafb3b169acba47de6c6154d5890c16a709 (patch) | |
| tree | d79dfe2b65a2beaf6caa3d6cb3c230d45d653f21 | |
| parent | a6322924e69838d1cda04b3d6a87c1b475d1e218 (diff) | |
| download | bcm5719-llvm-fbff2fafb3b169acba47de6c6154d5890c16a709.tar.gz bcm5719-llvm-fbff2fafb3b169acba47de6c6154d5890c16a709.zip | |
[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
6 files changed, 43 insertions, 0 deletions
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp index 7a5d22c00f8..046c699a224 100644 --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -1205,6 +1205,12 @@ void ASTDeclReader::VisitObjCCategoryDecl(ObjCCategoryDecl *CD) { 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 00000000000..e35402ac18a --- /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 00000000000..32043ec2498 --- /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 00000000000..28c409c3377 --- /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 00000000000..5c30bc57e46 --- /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 00000000000..752e4e129d2 --- /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; +} |

