diff options
-rw-r--r-- | include/clang/AST/DeclObjC.h | 2 | ||||
-rw-r--r-- | lib/AST/DeclObjC.cpp | 22 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 23 | ||||
-rw-r--r-- | test/Sema/objc-props-on-prots.m | 65 |
4 files changed, 106 insertions, 6 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index 1e82b5c56d..b62027e893 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -543,6 +543,8 @@ public: unsigned getNumInstanceMethods() const { return NumInstanceMethods; } unsigned getNumClassMethods() const { return NumClassMethods; } + + ObjCPropertyDecl *FindPropertyDeclaration(IdentifierInfo *PropertyId) const; unsigned getNumPropertyDecl() const { return NumPropertyDecl; } diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp index e493d27ac3..6536df6e1e 100644 --- a/lib/AST/DeclObjC.cpp +++ b/lib/AST/DeclObjC.cpp @@ -157,6 +157,14 @@ ObjCPropertyDecl * if (property) return property; } + // Look through protocols. + for (ObjCInterfaceDecl::protocol_iterator I = protocol_begin(), + E = protocol_end(); I != E; ++I) { + ObjCProtocolDecl *Protocol = *I; + ObjCPropertyDecl *property = Protocol->FindPropertyDeclaration(PropertyId); + if (property) + return property; + } if (getSuperClass()) return getSuperClass()->FindPropertyDeclaration(PropertyId); return 0; @@ -397,6 +405,20 @@ ObjCCategoryDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { return 0; } +/// FindPropertyDeclaration - Finds declaration of the property given its name +/// in 'PropertyId' and returns it. It returns 0, if not found. +/// +ObjCPropertyDecl * +ObjCProtocolDecl::FindPropertyDeclaration(IdentifierInfo *PropertyId) const { + for (ObjCProtocolDecl::classprop_iterator I = classprop_begin(), + E = classprop_end(); I != E; ++I) { + ObjCPropertyDecl *property = *I; + if (property->getIdentifier() == PropertyId) + return property; + } + return 0; +} + ObjCIvarDecl *ObjCInterfaceDecl::lookupInstanceVariable( IdentifierInfo *ID, ObjCInterfaceDecl *&clsDeclared) { ObjCInterfaceDecl* ClassDecl = this; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8d382485b1..89609501ff 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -602,10 +602,11 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, return new ExtVectorElementExpr(ret, BaseExpr, Member, MemberLoc); } else if (BaseType->isObjCInterfaceType()) { ObjCInterfaceDecl *IFace; - if (isa<ObjCInterfaceType>(BaseType.getCanonicalType())) - IFace = dyn_cast<ObjCInterfaceType>(BaseType)->getDecl(); + QualType CanonType = BaseType.getCanonicalType(); + if (isa<ObjCInterfaceType>(CanonType)) + IFace = dyn_cast<ObjCInterfaceType>(CanonType)->getDecl(); else - IFace = dyn_cast<ObjCQualifiedInterfaceType>(BaseType)->getDecl(); + IFace = dyn_cast<ObjCQualifiedInterfaceType>(CanonType)->getDecl(); ObjCInterfaceDecl *clsDeclared; if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member, clsDeclared)) return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, @@ -614,10 +615,11 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, PointerType *pointerType = static_cast<PointerType*>(BaseType.getTypePtr()); BaseType = pointerType->getPointeeType(); ObjCInterfaceDecl *IFace; - if (isa<ObjCInterfaceType>(BaseType.getCanonicalType())) - IFace = dyn_cast<ObjCInterfaceType>(BaseType)->getDecl(); + QualType CanonType = BaseType.getCanonicalType(); + if (isa<ObjCInterfaceType>(CanonType)) + IFace = dyn_cast<ObjCInterfaceType>(CanonType)->getDecl(); else - IFace = dyn_cast<ObjCQualifiedInterfaceType>(BaseType)->getDecl(); + IFace = dyn_cast<ObjCQualifiedInterfaceType>(CanonType)->getDecl(); ObjCInterfaceDecl *clsDeclared; if (ObjCIvarDecl *IV = IFace->lookupInstanceVariable(&Member, clsDeclared)) return new ObjCIvarRefExpr(IV, IV->getType(), MemberLoc, BaseExpr, @@ -639,6 +641,15 @@ ActOnMemberReferenceExpr(ExprTy *Base, SourceLocation OpLoc, // void someMethod() { frameworkBundle.bundlePath = 0; } // ObjCPropertyDecl *PD = IFace->FindPropertyDeclaration(&Member); + + if (!PD) { // Lastly, check protocols on qualified interfaces. + if (ObjCQualifiedInterfaceType *QIT = + dyn_cast<ObjCQualifiedInterfaceType>(CanonType)) { + for (unsigned i = 0; i < QIT->getNumProtocols(); i++) + if ((PD = QIT->getProtocols(i)->FindPropertyDeclaration(&Member))) + break; + } + } if (PD) return new ObjCPropertyRefExpr(PD, PD->getType(), MemberLoc, BaseExpr); } diff --git a/test/Sema/objc-props-on-prots.m b/test/Sema/objc-props-on-prots.m new file mode 100644 index 0000000000..aa5be25795 --- /dev/null +++ b/test/Sema/objc-props-on-prots.m @@ -0,0 +1,65 @@ +// RUN: clang -fsyntax-only -verify %s +typedef signed char BOOL; +@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator; + +@protocol NSObject +- (BOOL) isEqual:(id) object; +@end + +@protocol NSCoding +- (void) encodeWithCoder:(NSCoder *) aCoder; +@end + +@interface NSObject < NSObject > {} @end + +typedef float CGFloat; + +@interface NSResponder:NSObject < NSCoding > {} @end + +@class XCElementView; + +typedef struct _XCElementInset {} XCElementInset; + +@protocol XCElementP < NSObject > +-(BOOL) vertical; +@end + +@protocol XCElementDisplayDelegateP; +@protocol XCElementTabMarkerP; + +typedef NSObject < XCElementTabMarkerP > XCElementTabMarker; + +@protocol XCElementTabberP < XCElementP > +-(void) setMarker:(XCElementTabMarker *) marker; +@end + +typedef NSObject < XCElementTabberP > XCElementTabber; + +@protocol XCElementTabMarkerP < NSObject > +@property(nonatomic) +BOOL variableSized; +@end + +@protocol XCElementJustifierP < XCElementP > +-(void) setHJustification:(CGFloat) hJust; +@end + +typedef NSObject < XCElementJustifierP > XCElementJustifier; +@interface XCElementImp:NSObject < XCElementP > {} +@end + +@class XCElementImp; + +@interface XCElementTabberImp:XCElementImp < XCElementTabberP > { + XCElementTabMarker *_marker; +} +@end + +@implementation XCElementTabberImp +- (void) setMarker:(XCElementTabMarker *) marker { + if (_marker && _marker.variableSized) { + } +} +- vertical { return self; } +- (BOOL)isEqual:x { return 1; } +@end |