[cfe-commits] r45203 - in /cfe/trunk: AST/ASTContext.cpp Sema/SemaExpr.cpp include/clang/AST/ASTContext.h include/clang/AST/Type.h test/Sema/protocol-id-test-3.m

Fariborz Jahanian fjahanian at apple.com
Wed Dec 19 09:45:59 PST 2007


Author: fjahanian
Date: Wed Dec 19 11:45:58 2007
New Revision: 45203

URL: http://llvm.org/viewvc/llvm-project?rev=45203&view=rev
Log:
This patch concludes implementation of dynamic objective-c type qualified by
protocol list.

Added:
    cfe/trunk/test/Sema/protocol-id-test-3.m
Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Type.h

Modified: cfe/trunk/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/AST/ASTContext.cpp?rev=45203&r1=45202&r2=45203&view=diff

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Wed Dec 19 11:45:58 2007
@@ -1265,12 +1265,100 @@
   return true;
 }
 
-// TODO: id<P1,...> vs. id<P,...>
-#if 0
-bool ASTContext::QualifiedIdTypesAreCompatible(QualType lhs, 
-                                                      QualType rhs) {
+/// ObjcQualifiedIdTypesAreCompatible - Compares two types, at least
+/// one of which is a protocol qualified 'id' type.
+bool ASTContext::ObjcQualifiedIdTypesAreCompatible(QualType lhs, 
+                                                   QualType rhs) {
+  // match id<P..> with an 'id' type in all cases.
+  if (const PointerType *PT = lhs->getAsPointerType()) {
+    QualType PointeeTy = PT->getPointeeType();
+    if (isObjcIdType(PointeeTy))
+      return true;
+        
+  }
+  else if (const PointerType *PT = rhs->getAsPointerType()) {
+    QualType PointeeTy = PT->getPointeeType();
+    if (isObjcIdType(PointeeTy))
+      return true;
+    
+  }
+  
+  ObjcQualifiedInterfaceType *lhsQI = 0;
+  ObjcQualifiedInterfaceType *rhsQI = 0;
+  ObjcQualifiedIdType *lhsQID = dyn_cast<ObjcQualifiedIdType>(lhs);
+  ObjcQualifiedIdType *rhsQID = dyn_cast<ObjcQualifiedIdType>(rhs);
+  
+  if (lhsQID) {
+    if (!rhsQID && rhs->getTypeClass() == Type::Pointer) {
+      QualType rtype = 
+        cast<PointerType>(rhs.getCanonicalType())->getPointeeType();
+      rhsQI = 
+        dyn_cast<ObjcQualifiedInterfaceType>(
+          rtype.getCanonicalType().getTypePtr());
+    }
+    if (!rhsQI && !rhsQID)
+      return false;
+    
+    for (unsigned i =0; i < lhsQID->getNumProtocols(); i++) {
+      bool match = false;
+      ObjcProtocolDecl *lhsProto = lhsQID->getProtocols(i);
+      unsigned numRhsProtocols;
+      ObjcProtocolDecl **rhsProtoList;
+      if (rhsQI) {
+        numRhsProtocols = rhsQI->getNumProtocols();
+        rhsProtoList = rhsQI->getReferencedProtocols();
+      }
+      else {
+        numRhsProtocols = rhsQID->getNumProtocols();
+        rhsProtoList = rhsQID->getReferencedProtocols();
+      }
+      for (unsigned j = 0; j < numRhsProtocols; j++) {
+        ObjcProtocolDecl *rhsProto = rhsProtoList[j];
+        if (lhsProto == rhsProto) {
+          match = true;
+          break;
+        }
+      }
+      if (!match)
+        return false;
+    }    
+  }
+  else if (rhsQID) {
+    if (!lhsQID && lhs->getTypeClass() == Type::Pointer) {
+      QualType ltype = 
+      cast<PointerType>(lhs.getCanonicalType())->getPointeeType();
+      lhsQI = 
+      dyn_cast<ObjcQualifiedInterfaceType>(
+        ltype.getCanonicalType().getTypePtr());
+    }
+    if (!lhsQI && !lhsQID)
+      return false;
+    unsigned numLhsProtocols;
+    ObjcProtocolDecl **lhsProtoList;
+    if (lhsQI) {
+      numLhsProtocols = lhsQI->getNumProtocols();
+      lhsProtoList = lhsQI->getReferencedProtocols();
+    }
+    else {
+      numLhsProtocols = lhsQID->getNumProtocols();
+      lhsProtoList = lhsQID->getReferencedProtocols();
+    }
+    for (unsigned i =0; i < numLhsProtocols; i++) {
+      bool match = false;
+      ObjcProtocolDecl *lhsProto = lhsProtoList[i];
+      for (unsigned j = 0; j < rhsQID->getNumProtocols(); j++) {
+        ObjcProtocolDecl *rhsProto = rhsQID->getProtocols(j);
+        if (lhsProto == rhsProto) {
+          match = true;
+          break;
+        }
+      }
+      if (!match)
+        return false;
+    }    
+  }
+  return true;
 }
-#endif
 
 bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
   const VectorType *lVector = lhs->getAsVectorType();

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=45203&r1=45202&r2=45203&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Wed Dec 19 11:45:58 2007
@@ -1103,6 +1103,8 @@
 ///
 Sema::AssignmentCheckResult
 Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
+
+  
   if (lhsType.getCanonicalType().getUnqualifiedType() == 
       rhsType.getCanonicalType().getUnqualifiedType())
     return Compatible; // common case, fast path...
@@ -1110,7 +1112,13 @@
   if (lhsType->isReferenceType() || rhsType->isReferenceType()) {
     if (Context.referenceTypesAreCompatible(lhsType, rhsType))
       return Compatible;
-  } else if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
+  }
+  else if (lhsType->isObjcQualifiedIdType() 
+           || rhsType->isObjcQualifiedIdType()) {
+    if (Context.ObjcQualifiedIdTypesAreCompatible(lhsType, rhsType))
+      return Compatible;
+  }
+  else if (lhsType->isArithmeticType() && rhsType->isArithmeticType()) {
     if (lhsType->isVectorType() || rhsType->isVectorType()) {
       if (!getLangOptions().LaxVectorConversions) {
         if (lhsType.getCanonicalType() != rhsType.getCanonicalType())

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=45203&r1=45202&r2=45203&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Wed Dec 19 11:45:58 2007
@@ -297,6 +297,7 @@
   /// Objective-C specific type checking.
   bool interfaceTypesAreCompatible(QualType, QualType);
   bool QualifiedInterfaceTypesAreCompatible(QualType, QualType);
+  bool ObjcQualifiedIdTypesAreCompatible(QualType, QualType);
   bool objcTypesAreCompatible(QualType, QualType);
   bool isObjcIdType(QualType T) const {
     if (!IdStructType) // ObjC isn't enabled

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=45203&r1=45202&r2=45203&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Wed Dec 19 11:45:58 2007
@@ -943,7 +943,9 @@
   unsigned getNumProtocols() const {
     return Protocols.size();
   }
-    
+  ObjcProtocolDecl **getReferencedProtocols() {
+    return &Protocols[0];
+  }  
   virtual void getAsStringInternal(std::string &InnerString) const;
   
   void Profile(llvm::FoldingSetNodeID &ID);
@@ -975,6 +977,9 @@
   unsigned getNumProtocols() const {
     return Protocols.size();
   }
+  ObjcProtocolDecl **getReferencedProtocols() {
+    return &Protocols[0];
+  } 
     
   virtual void getAsStringInternal(std::string &InnerString) const;
     
@@ -1024,7 +1029,8 @@
   return isa<FunctionType>(CanonicalType);
 }
 inline bool Type::isPointerType() const {
-  return isa<PointerType>(CanonicalType);
+  return isa<PointerType>(CanonicalType) || 
+	 isa<ObjcQualifiedIdType>(CanonicalType);
 }
 inline bool Type::isFunctionPointerType() const {
   if (const PointerType* T = getAsPointerType())

Added: cfe/trunk/test/Sema/protocol-id-test-3.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/protocol-id-test-3.m?rev=45203&view=auto

==============================================================================
--- cfe/trunk/test/Sema/protocol-id-test-3.m (added)
+++ cfe/trunk/test/Sema/protocol-id-test-3.m Wed Dec 19 11:45:58 2007
@@ -0,0 +1,94 @@
+// RUN: clang -pedantic -fsyntax-only -verify %s
+
+ at protocol MyProto1 
+ at end
+
+ at protocol MyProto2 
+ at end
+
+ at interface INTF @end
+
+id<MyProto1> Func(INTF <MyProto1, MyProto2> *p2)
+{
+	return p2;
+}
+
+
+
+
+ id<MyProto1> Gunc(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+
+ id<MyProto1> Gunc1(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+id<MyProto1, MyProto2> Gunc2(id <MyProto1>p2)
+{
+	Func(p2);	// expected-error {{incompatible types passing 'id<MyProto1>' to function expecting 'INTF<MyProto1,MyProto2> *'}}
+	return p2;	// expected-error {{incompatible type returning 'id<MyProto1>', expected 'id<MyProto1,MyProto2>'}}
+}
+
+
+
+id<MyProto1> Gunc3(id <MyProto2>p2)
+{
+	return p2;	 // expected-error {{incompatible type returning 'id<MyProto2>', expected 'id<MyProto1>'}}
+}
+
+
+id<MyProto1, MyProto2> Gunc4(id <MyProto2, MyProto1>p2)
+{
+	return p2;
+}
+
+
+
+INTF<MyProto1> * Hunc(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+
+INTF<MyProto1> * Hunc1(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+INTF<MyProto1, MyProto2> * Hunc2(id <MyProto1>p2)
+{
+	Func(p2);	// expected-error {{incompatible types passing 'id<MyProto1>' to function expecting 'INTF<MyProto1,MyProto2> *'}}
+	return p2;	// expected-error {{incompatible type returning 'id<MyProto1>', expected 'INTF<MyProto1,MyProto2> *'}}
+}
+
+INTF<MyProto1> * Hunc3(id <MyProto2>p2)
+{
+	return p2;	 // expected-error {{incompatible type returning 'id<MyProto2>', expected 'INTF<MyProto1> *'}}
+}
+
+
+INTF<MyProto1, MyProto2> * Hunc4(id <MyProto2, MyProto1>p2)
+{
+	return p2;
+}
+
+id Iunc(id <MyProto1, MyProto2>p2)
+{
+	return p2;
+}
+
+
+id<MyProto1> Iunc1(id p2)
+{
+	return p2;
+}
+
+id<MyProto1, MyProto2> Iunc2(id p2)
+{
+	Iunc(p2);	
+	return p2;
+}





More information about the cfe-commits mailing list