]> granicus.if.org Git - clang/commitdiff
More work to integrate newly added ObjCQualifiedClassType into the type system.
authorSteve Naroff <snaroff@apple.com>
Sat, 21 Feb 2009 21:17:01 +0000 (21:17 +0000)
committerSteve Naroff <snaroff@apple.com>
Sat, 21 Feb 2009 21:17:01 +0000 (21:17 +0000)
This is necessary 'plumbing' to fix <rdar://problem/6497631> Message lookup is sometimes different than gcc's.

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

include/clang/AST/Type.h
lib/AST/ASTContext.cpp
lib/AST/Type.cpp
lib/CodeGen/CodeGenTypes.cpp
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp

index 5dc2c31107444237f3658978867e081fd56a09e0..cb34c77f1ac7d46e06903fade09208625c112cc4 100644 (file)
@@ -270,7 +270,7 @@ public:
     TypeName, Tagged, ExtQual,
     TemplateTypeParm, ClassTemplateSpecialization,
     ObjCInterface, ObjCQualifiedInterface,
-    ObjCQualifiedId,
+    ObjCQualifiedId, ObjCQualifiedClass,
     TypeOfExp, TypeOfTyp, // GNU typeof extension.
     BlockPointer,          // C extension
     FixedWidthInt
@@ -1758,7 +1758,7 @@ class ObjCQualifiedClassType : public Type,
   llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
     
   ObjCQualifiedClassType(ObjCProtocolDecl **Protos, unsigned NumP)
-    : Type(ObjCQualifiedId, QualType()/*these are always canonical*/,
+    : Type(ObjCQualifiedClass, QualType()/*these are always canonical*/,
            /*Dependent=*/false), 
   Protocols(Protos, Protos+NumP) { }
   friend class ASTContext;  // ASTContext creates these.
@@ -1785,7 +1785,7 @@ public:
                       ObjCProtocolDecl **protocols, unsigned NumProtocols);
     
   static bool classof(const Type *T) { 
-    return T->getTypeClass() == ObjCQualifiedId
+    return T->getTypeClass() == ObjCQualifiedClass
   }
   static bool classof(const ObjCQualifiedClassType *) { return true; }
     
index cdd61cd3f4a4b3adc4baacd72ccd66b2a82f8520..605f46b44bffdcf3d90ad95a418f1928717e9123 100644 (file)
@@ -2408,7 +2408,7 @@ bool ASTContext::isObjCNSObjectType(QualType Ty) const {
 /// to struct), Interface* (pointer to ObjCInterfaceType) and id<P> (qualified
 /// ID type).
 bool ASTContext::isObjCObjectPointerType(QualType Ty) const {
-  if (Ty->isObjCQualifiedIdType())
+  if (Ty->isObjCQualifiedIdType() || Ty->isObjCQualifiedClassType())
     return true;
   
   // Blocks are objects.
index ba8b463c27739d99cbd786eb6f694eab7abb5018..065b626930bc53ba140f2e165540b15327830633 100644 (file)
@@ -693,7 +693,8 @@ bool Type::isScalarType() const {
          isa<BlockPointerType>(CanonicalType) ||
          isa<MemberPointerType>(CanonicalType) ||
          isa<ComplexType>(CanonicalType) ||
-         isa<ObjCQualifiedIdType>(CanonicalType);
+         isa<ObjCQualifiedIdType>(CanonicalType) ||
+         isa<ObjCQualifiedClassType>(CanonicalType);
 }
 
 /// \brief Determines whether the type is a C++ aggregate type or C
index a385d8c9d295c1da82d681c264f92b5d7865f59d..47ac79f70b54828587c2b1b381f064c3fd7f6cfb 100644 (file)
@@ -290,6 +290,7 @@ const llvm::Type *CodeGenTypes::ConvertNewType(QualType T) {
   }
 
   case Type::ObjCQualifiedId:
+  case Type::ObjCQualifiedClass:
     // Protocols don't influence the LLVM type.
     return ConvertTypeRecursive(Context.getObjCIdType());
 
index c390f769f59313870bbbb8158cec8dc2a4f556a2..b17f7bc1ca8e8fd35796de1ecbab33d04181d8b6 100644 (file)
@@ -2734,7 +2734,9 @@ Sema::CheckSingleAssignmentConstraints(QualType lhsType, Expr *&rExpr) {
 
   // C99 6.5.16.1p1: the left operand is a pointer and the right is
   // a null pointer constant.
-  if ((lhsType->isPointerType() || lhsType->isObjCQualifiedIdType() ||
+  if ((lhsType->isPointerType() || 
+       lhsType->isObjCQualifiedIdType() || 
+       lhsType->isObjCQualifiedClassType() ||
        lhsType->isBlockPointerType())
       && rExpr->isNullPointerConstant(Context)) {
     ImpCastExprToType(rExpr, lhsType);
index 19dc3821c763ce167955ef676222db4f9c109e1b..afa025552adcc21ad76c5125e2aa6ad057b5adbd 100644 (file)
@@ -391,7 +391,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
   // We allow sending a message to a qualified ID ("id<foo>"), which is ok as 
   // long as one of the protocols implements the selector (if not, warn).
   if (ObjCQualifiedIdType *QIT = dyn_cast<ObjCQualifiedIdType>(ReceiverCType)) {
-    // Search protocols
+    // Search protocols for instance methods.
+    ReceiverCType.dump();
     for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
       ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
       if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
@@ -400,6 +401,18 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
     if (!Method)
       Diag(lbrac, diag::warn_method_not_found_in_protocol)
         << Sel << RExpr->getSourceRange();
+  // Check for GCC extension "Class<foo>".
+  } else if (ObjCQualifiedClassType *QIT = 
+               dyn_cast<ObjCQualifiedClassType>(ReceiverCType)) {
+    // Search protocols for class methods.
+    for (unsigned i = 0; i < QIT->getNumProtocols(); i++) {
+      ObjCProtocolDecl *PDecl = QIT->getProtocols(i);
+      if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
+        break;
+    }
+    if (!Method)
+      Diag(lbrac, diag::warn_method_not_found_in_protocol)
+        << Sel << RExpr->getSourceRange();
   } else if (const ObjCInterfaceType *OCIReceiver = 
                 ReceiverCType->getAsPointerToObjCInterfaceType()) {
     // We allow sending a message to a pointer to an interface (an object).