]> granicus.if.org Git - clang/commitdiff
When looking for property name (or getter method) in a
authorFariborz Jahanian <fjahanian@apple.com>
Thu, 19 Mar 2009 18:15:34 +0000 (18:15 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Thu, 19 Mar 2009 18:15:34 +0000 (18:15 +0000)
dot-syntax expression after earching the list of protocols
in the qualified-id, must keep searching the protocol list
of each of the protocols in the list.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67314 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaExpr.cpp
test/SemaObjC/access-property-getter.m [new file with mode: 0644]

index e43d4b8027ff49ceb8b99090daad9d2ff824dd29..c06f1cfad788979fafbb9985a748c3ee558a5e9f 100644 (file)
@@ -1697,6 +1697,51 @@ CheckExtVectorComponent(QualType baseType, SourceLocation OpLoc,
   return VT; // should never get here (a typedef type should always be found).
 }
 
+static Decl *FindGetterNameDeclFromProtocolList(const ObjCProtocolDecl*PDecl,
+                                                IdentifierInfo &Member,
+                                                const Selector &Sel) {
+  
+  if (ObjCPropertyDecl *PD = PDecl->FindPropertyDeclaration(&Member))
+    return PD;
+  if (ObjCMethodDecl *OMD = PDecl->getInstanceMethod(Sel))
+    return OMD;
+  
+  for (ObjCProtocolDecl::protocol_iterator I = PDecl->protocol_begin(),
+       E = PDecl->protocol_end(); I != E; ++I) {
+    if (Decl *D = FindGetterNameDeclFromProtocolList(*I, Member, Sel))
+      return D;
+  }
+  return 0;
+}
+
+static Decl *FindGetterNameDecl(const ObjCQualifiedIdType *QIdTy,
+                                IdentifierInfo &Member,
+                                const Selector &Sel) {
+  // Check protocols on qualified interfaces.
+  Decl *GDecl = 0;
+  for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
+       E = QIdTy->qual_end(); I != E; ++I) {
+    if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
+      GDecl = PD;
+      break;
+    }
+    // Also must look for a getter name which uses property syntax.
+    if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
+      GDecl = OMD;
+      break;
+    }
+  }
+  if (!GDecl) {
+    for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
+         E = QIdTy->qual_end(); I != E; ++I) {
+      // Search in the protocol-qualifier list of current protocol.
+      GDecl = FindGetterNameDeclFromProtocolList(*I, Member, Sel);
+      if (GDecl)
+        return GDecl;
+    }
+  }
+  return GDecl;
+}
 
 Action::OwningExprResult
 Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
@@ -1968,25 +2013,25 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
   const ObjCQualifiedIdType *QIdTy;
   if (OpKind == tok::period && (QIdTy = BaseType->getAsObjCQualifiedIdType())) {
     // Check protocols on qualified interfaces.
-    for (ObjCQualifiedIdType::qual_iterator I = QIdTy->qual_begin(),
-         E = QIdTy->qual_end(); I != E; ++I) {
-      if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
+    Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
+    if (Decl *PMDecl = FindGetterNameDecl(QIdTy, Member, Sel)) {
+      if (ObjCPropertyDecl *PD = dyn_cast<ObjCPropertyDecl>(PMDecl)) {
         // Check the use of this declaration
         if (DiagnoseUseOfDecl(PD, MemberLoc))
           return ExprError();
-
+        
         return Owned(new (Context) ObjCPropertyRefExpr(PD, PD->getType(),
                                                        MemberLoc, BaseExpr));
       }
-      // Also must look for a getter name which uses property syntax.
-      Selector Sel = PP.getSelectorTable().getNullarySelector(&Member);
-      if (ObjCMethodDecl *OMD = (*I)->getInstanceMethod(Sel)) {
+      if (ObjCMethodDecl *OMD = dyn_cast<ObjCMethodDecl>(PMDecl)) {
         // Check the use of this method.
         if (DiagnoseUseOfDecl(OMD, MemberLoc))
           return ExprError();
-
+        
         return Owned(new (Context) ObjCMessageExpr(BaseExpr, Sel,
-                        OMD->getResultType(), OMD, OpLoc, MemberLoc, NULL, 0));
+                                                   OMD->getResultType(), 
+                                                   OMD, OpLoc, MemberLoc, 
+                                                   NULL, 0));
       }
     }
 
diff --git a/test/SemaObjC/access-property-getter.m b/test/SemaObjC/access-property-getter.m
new file mode 100644 (file)
index 0000000..903f53c
--- /dev/null
@@ -0,0 +1,35 @@
+// RUN: clang -verify %s
+
+@protocol NSObject
+- (oneway void)release;
+@end
+
+@protocol XCOutputStreams <NSObject>
+@end
+
+
+@interface XCWorkQueueCommandInvocation 
+{
+    id <XCOutputStreams> _outputStream;
+}
+@end
+
+@interface XCWorkQueueCommandSubprocessInvocation : XCWorkQueueCommandInvocation
+@end
+
+@interface XCWorkQueueCommandLocalSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation
+@end
+
+@interface XCWorkQueueCommandDistributedSubprocessInvocation : XCWorkQueueCommandSubprocessInvocation
+@end
+
+@interface XCWorkQueueCommandCacheFetchInvocation : XCWorkQueueCommandSubprocessInvocation
+
+@end
+
+@implementation XCWorkQueueCommandCacheFetchInvocation
+- (id)harvestPredictivelyProcessedOutputFiles
+{
+     _outputStream.release;
+}
+@end