From: Fariborz Jahanian Date: Wed, 25 Sep 2013 19:36:32 +0000 (+0000) Subject: ObjectiveC: Handle the case of qualifying protocols X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=a924f847fcc3268ca2ce5c1bc5592a3774aeab80;p=clang ObjectiveC: Handle the case of qualifying protocols declared in a typedef declaraton used as super class of an ObjC class. Curretnly, these protocols are dropped from the class hierarchy. Test shows that it is now included. // rdar://15051465 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191395 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index 9c366190d3..f54561528d 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -6513,6 +6513,10 @@ public: const SourceLocation *ProtoLocs, SourceLocation EndProtoLoc, AttributeList *AttrList); + + void ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, + IdentifierInfo *SuperName, + SourceLocation SuperLoc); Decl *ActOnCompatibilityAlias( SourceLocation AtCompatibilityAliasLoc, diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp index 5e308a6b57..1dc71f1f82 100644 --- a/lib/Parse/ParseObjc.cpp +++ b/lib/Parse/ParseObjc.cpp @@ -289,6 +289,9 @@ Decl *Parser::ParseObjCAtInterfaceDeclaration(SourceLocation AtLoc, LAngleLoc, EndProtoLoc)) return 0; + if (Tok.isNot(tok::less)) + Actions.ActOnTypedefedProtocols(ProtocolRefs, superClassId, superClassLoc); + Decl *ClsType = Actions.ActOnStartClassInterface(AtLoc, nameId, nameLoc, superClassId, superClassLoc, diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp index b938bd6f8b..14f8658fac 100644 --- a/lib/Sema/SemaDeclObjC.cpp +++ b/lib/Sema/SemaDeclObjC.cpp @@ -592,6 +592,29 @@ ActOnStartClassInterface(SourceLocation AtInterfaceLoc, return ActOnObjCContainerStartDefinition(IDecl); } +/// ActOnTypedefedProtocols - this action finds protocol list as part of the +/// typedef'ed use for a qualified super class and adds them to the list +/// of the protocols. +void Sema::ActOnTypedefedProtocols(SmallVectorImpl &ProtocolRefs, + IdentifierInfo *SuperName, + SourceLocation SuperLoc) { + if (!SuperName) + return; + NamedDecl* IDecl = LookupSingleName(TUScope, SuperName, SuperLoc, + LookupOrdinaryName); + if (!IDecl) + return; + + if (const TypedefNameDecl *TDecl = dyn_cast_or_null(IDecl)) { + QualType T = TDecl->getUnderlyingType(); + if (T->isObjCObjectType()) + if (const ObjCObjectType *OPT = T->getAs()) + for (ObjCObjectType::qual_iterator I = OPT->qual_begin(), + E = OPT->qual_end(); I != E; ++I) + ProtocolRefs.push_back(*I); + } +} + /// ActOnCompatibilityAlias - this action is called after complete parsing of /// a \@compatibility_alias declaration. It sets up the alias relationships. Decl *Sema::ActOnCompatibilityAlias(SourceLocation AtLoc, diff --git a/test/SemaObjC/default-synthesize-3.m b/test/SemaObjC/default-synthesize-3.m index f722375ba5..dc18ba7d0a 100644 --- a/test/SemaObjC/default-synthesize-3.m +++ b/test/SemaObjC/default-synthesize-3.m @@ -157,3 +157,27 @@ __attribute ((objc_requires_property_definitions)) // expected-error {{objc_requ __attribute ((objc_requires_property_definitions(1))) // expected-error {{'objc_requires_property_definitions' attribute takes no arguments}} @interface I1 @end + +// rdar://15051465 +@protocol SubFooling + @property(nonatomic, readonly) id hoho; // expected-note 2 {{property declared here}} +@end + +@protocol Fooing + @property(nonatomic, readonly) id muahahaha; // expected-note 2 {{property declared here}} +@end + +typedef NSObject FooObject; + +@interface Okay : NSObject +@end + +@implementation Okay // expected-warning 2 {{auto property synthesis will not synthesize property declared in a protocol}} +@end + +@interface Fail : FooObject +@end + +@implementation Fail // expected-warning 2 {{auto property synthesis will not synthesize property declared in a protocol}} +@end +