]> granicus.if.org Git - clang/commitdiff
5 cleanups to ObjCObjectPointerType work:
authorSteve Naroff <snaroff@apple.com>
Mon, 20 Jul 2009 17:56:53 +0000 (17:56 +0000)
committerSteve Naroff <snaroff@apple.com>
Mon, 20 Jul 2009 17:56:53 +0000 (17:56 +0000)
- Remove Sema::CheckPointeeTypesForAssignment(), a temporary API I added to ease migration to ObjCObjectPointerType. Convert Sema::CheckAssignmentConstraints() to no longer depend on the temporary API.
- Sema::ConvertDeclSpecToType(): Replace a couple FIXME's with an important comment/example.
- Sema::GetTypeForDeclarator(): Get the protocol's from the interface, NOT the declspec (to support the following C typedef idiom: "typedef C<P> T; T *obj").
- Sema::ObjCQualifiedIdTypesAreCompatible(): Removed some dead code.
- ASTContext::getObjCEncodingForTypeImpl(): Some minor cleanups.

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

lib/AST/ASTContext.cpp
lib/Sema/Sema.h
lib/Sema/SemaExpr.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaType.cpp

index 680ec24eff601e6e2505f07753b56d915403f245..05627b47ebe706a514e9b356bb8db538d2345a6a 100644 (file)
@@ -2758,10 +2758,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
       if (FD || EncodingProperty) {
         // Note that we do extended encoding of protocol qualifer list
         // Only when doing ivar or property encoding.
-        const ObjCObjectPointerType *QIDT = T->getAsObjCQualifiedIdType();
         S += '"';
-        for (ObjCObjectPointerType::qual_iterator I = QIDT->qual_begin(),
-             E = QIDT->qual_end(); I != E; ++I) {
+        for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+             E = OPT->qual_end(); I != E; ++I) {
           S += '<';
           S += (*I)->getNameAsString();
           S += '>';
@@ -2786,12 +2785,10 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
 
     S += '@';
     if (FD || EncodingProperty) {
-      const ObjCInterfaceType *OIT = OPT->getInterfaceType();
-      ObjCInterfaceDecl *OI = OIT->getDecl();
       S += '"';
-      S += OI->getNameAsCString();
-      for (ObjCInterfaceType::qual_iterator I = OIT->qual_begin(),
-           E = OIT->qual_end(); I != E; ++I) {
+      S += OPT->getInterfaceDecl()->getNameAsCString();
+      for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+           E = OPT->qual_end(); I != E; ++I) {
         S += '<';
         S += (*I)->getNameAsString();
         S += '>';
index 82a8a087d9f2e7fbea5172579fa178f346df0969..837b2c8fecb97f633c5deb0f89a39459d9f83605 100644 (file)
@@ -3033,8 +3033,6 @@ public:
   // Helper function for CheckAssignmentConstraints (C99 6.5.16.1p1)
   AssignConvertType CheckPointerTypesForAssignment(QualType lhsType, 
                                                    QualType rhsType);
-  AssignConvertType CheckPointeeTypesForAssignment(QualType lhsType, 
-                                                   QualType rhsType);
                                                    
   // Helper function for CheckAssignmentConstraints involving two
   // block pointer types.
index 35c0ddb06dd65d2a265ef125b9a623c28515e206..7aa66f9b627777289f33c4bfbda84458e84cebdd 100644 (file)
@@ -2398,8 +2398,8 @@ Sema::ActOnMemberReferenceExpr(Scope *S, ExprArg Base, SourceLocation OpLoc,
                                                      MemberLoc, BaseExpr));
     }
     // Check protocols on qualified interfaces.
-    for (ObjCObjectPointerType::qual_iterator I = IFaceT->qual_begin(),
-         E = IFaceT->qual_end(); I != E; ++I)
+    for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(),
+         E = OPT->qual_end(); I != E; ++I)
       if (ObjCPropertyDecl *PD = (*I)->FindPropertyDeclaration(&Member)) {
         // Check whether we can reference this property.
         if (DiagnoseUseOfDecl(PD, MemberLoc))
@@ -3303,7 +3303,6 @@ Action::OwningExprResult Sema::ActOnConditionalOp(SourceLocation QuestionLoc,
                                                  RHSExpr, result));
 }
 
-
 // CheckPointerTypesForAssignment - This is a very tricky routine (despite
 // being closely modeled after the C99 spec:-). The odd characteristic of this
 // routine is it effectively iqnores the qualifiers on the top level pointee.
@@ -3317,11 +3316,6 @@ Sema::CheckPointerTypesForAssignment(QualType lhsType, QualType rhsType) {
   lhptee = lhsType->getAsPointerType()->getPointeeType();
   rhptee = rhsType->getAsPointerType()->getPointeeType();
 
-  return CheckPointeeTypesForAssignment(lhptee, rhptee);
-}
-
-Sema::AssignConvertType
-Sema::CheckPointeeTypesForAssignment(QualType lhptee, QualType rhptee) {
   // make sure we operate on the canonical type
   lhptee = Context.getCanonicalType(lhptee);
   rhptee = Context.getCanonicalType(rhptee);
@@ -3495,12 +3489,12 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
     if (isa<PointerType>(rhsType))
       return CheckPointerTypesForAssignment(lhsType, rhsType);
 
+    // In general, C pointers are not compatible with ObjC object pointers.
     if (isa<ObjCObjectPointerType>(rhsType)) {
-      QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType();
-      QualType lhptee = lhsType->getAsPointerType()->getPointeeType();
-      return CheckPointeeTypesForAssignment(lhptee, rhptee);
+      if (lhsType->isVoidPointerType()) // an exception to the rule.
+        return Compatible;
+      return IncompatiblePointer;
     }
-
     if (rhsType->getAsBlockPointerType()) {
       if (lhsType->getAsPointerType()->getPointeeType()->isVoidType())
         return Compatible;
@@ -3533,18 +3527,19 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
   if (isa<ObjCObjectPointerType>(lhsType)) {
     if (rhsType->isIntegerType())
       return IntToPointer;
-
+      
+    // In general, C pointers are not compatible with ObjC object pointers.
     if (isa<PointerType>(rhsType)) {
-      QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
-      QualType rhptee = rhsType->getAsPointerType()->getPointeeType();
-      return CheckPointeeTypesForAssignment(lhptee, rhptee);
+      if (rhsType->isVoidPointerType()) // an exception to the rule.
+        return Compatible;
+      return IncompatiblePointer;
     }
     if (rhsType->isObjCObjectPointerType()) {
       if (lhsType->isObjCBuiltinType() || rhsType->isObjCBuiltinType())
         return Compatible;
-      QualType lhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
-      QualType rhptee = rhsType->getAsObjCObjectPointerType()->getPointeeType();
-      return CheckPointeeTypesForAssignment(lhptee, rhptee);
+      if (Context.typesAreCompatible(lhsType, rhsType))
+        return Compatible;
+      return IncompatiblePointer;
     }
     if (const PointerType *RHSPT = rhsType->getAsPointerType()) {
       if (RHSPT->getPointeeType()->isVoidType())
@@ -3579,10 +3574,11 @@ Sema::CheckAssignmentConstraints(QualType lhsType, QualType rhsType) {
     if (lhsType->isIntegerType())
       return PointerToInt;
 
+    // In general, C pointers are not compatible with ObjC object pointers.
     if (isa<PointerType>(lhsType)) {
-      QualType rhptee = lhsType->getAsObjCObjectPointerType()->getPointeeType();
-      QualType lhptee = rhsType->getAsPointerType()->getPointeeType();
-      return CheckPointeeTypesForAssignment(lhptee, rhptee);
+      if (lhsType->isVoidPointerType()) // an exception to the rule.
+        return Compatible;
+      return IncompatiblePointer;
     }
     if (isa<BlockPointerType>(lhsType) &&
         rhsType->getAsPointerType()->getPointeeType()->isVoidType())
index 1d995b53e63b8f25ec2db0877dca48f68e5f7604..66e1beb9838096d5f7054814db4338307315d7c9 100644 (file)
@@ -854,34 +854,6 @@ bool Sema::ObjCQualifiedIdTypesAreCompatible(QualType lhs, QualType rhs,
     }
     return true;
   }
-  // FIXME: The code below will be removed when ObjCQualifiedInterfaceType is
-  // removed.
-  if (!lhs->isPointerType())
-    return false;
-  
-  QualType ltype = lhs->getAsPointerType()->getPointeeType();
-  if (const ObjCInterfaceType *lhsQI =
-         ltype->getAsObjCQualifiedInterfaceType()) {
-    ObjCObjectPointerType::qual_iterator LHSProtoI = lhsQI->qual_begin();
-    ObjCObjectPointerType::qual_iterator LHSProtoE = lhsQI->qual_end();
-    for (; LHSProtoI != LHSProtoE; ++LHSProtoI) {
-      bool match = false;
-      ObjCProtocolDecl *lhsProto = *LHSProtoI;
-      for (ObjCObjectPointerType::qual_iterator I = rhsQID->qual_begin(),
-           E = rhsQID->qual_end(); I != E; ++I) {
-        ObjCProtocolDecl *rhsProto = *I;
-        if (ProtocolCompatibleWithProtocol(lhsProto, rhsProto) ||
-            (compare && ProtocolCompatibleWithProtocol(rhsProto, lhsProto))) {
-          match = true;
-          break;
-        }
-      }
-      if (!match)
-        return false;
-    }
-    return true;
-  }
-  
   return false;
 }
 
index 57989a021b5aad30095cc1c5559536f4ee5a68c3..5fbc8e813b63bda34a2b2500f79947e101770b52 100644 (file)
@@ -205,12 +205,16 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
     Result = QualType::getFromOpaquePtr(DS.getTypeRep());
 
     if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
-      // FIXME: Adding a TST_objcInterface clause doesn't seem ideal, so we have
-      // this "hack" for now...
       if (const ObjCInterfaceType *Interface = Result->getAsObjCInterfaceType())
-        // FIXME: Investigate removing the protocol list in ObjCInterfaceType.
-        // To simply this, Sema::GetTypeForDeclarator() uses the declspec 
-        // protocol list, not the list we are storing here.
+        // It would be nice if protocol qualifiers were only stored with the
+        // ObjCObjectPointerType. Unfortunately, this isn't possible due
+        // to the following typedef idiom (which is uncommon, but allowed):
+        // 
+        // typedef Foo<P> T;
+        // static void func() {
+        //   Foo<P> *yy;
+        //   T *zz;
+        // }
         Result = Context.getObjCInterfaceType(Interface->getDecl(),
                                               (ObjCProtocolDecl**)PQ,
                                               DS.getNumProtocolQualifiers());
@@ -901,10 +905,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip,
         // Build the type anyway.
       }
       if (getLangOptions().ObjC1 && T->isObjCInterfaceType()) {
-        const DeclSpec &DS = D.getDeclSpec();
+        const ObjCInterfaceType *OIT = T->getAsObjCInterfaceType();
         T = Context.getObjCObjectPointerType(T,
-                                (ObjCProtocolDecl **)DS.getProtocolQualifiers(),
-                                DS.getNumProtocolQualifiers());
+                                         (ObjCProtocolDecl **)OIT->qual_begin(),
+                                         OIT->getNumProtocols());
         break;
       }
       T = BuildPointerType(T, DeclType.Ptr.TypeQuals, DeclType.Loc, Name);