aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/DeclObjC.h2
-rw-r--r--lib/AST/DeclObjC.cpp22
-rw-r--r--lib/Sema/SemaExpr.cpp23
-rw-r--r--test/Sema/objc-props-on-prots.m65
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