]> granicus.if.org Git - clang/commitdiff
Fix <rdar://problem/6770276> Support Class<Proto> syntax.
authorSteve Naroff <snaroff@apple.com>
Wed, 22 Jul 2009 16:07:01 +0000 (16:07 +0000)
committerSteve Naroff <snaroff@apple.com>
Wed, 22 Jul 2009 16:07:01 +0000 (16:07 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@76741 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/Type.h
include/clang/Basic/DiagnosticSemaKinds.td
lib/AST/ASTContext.cpp
lib/AST/Type.cpp
lib/Sema/SemaExprObjC.cpp
lib/Sema/SemaType.cpp
test/SemaObjC/call-super-2.m
test/SemaObjC/protocol-archane.m
test/SemaObjC/protocol-attribute.m
test/SemaObjC/protocol-qualified-class-unsupported.m

index 82efb0a23b9231e80353dd4dcd4612c80811c03c..8500676d78c0289d2ba1226728c26c07a6b30937 100644 (file)
@@ -402,6 +402,7 @@ public:
   bool isObjCInterfaceType() const;             // NSString or NSString<foo>
   bool isObjCQualifiedInterfaceType() const;    // NSString<foo>
   bool isObjCQualifiedIdType() const;           // id<foo>
+  bool isObjCQualifiedClassType() const;        // Class<foo>
   bool isObjCIdType() const;                    // id
   bool isObjCClassType() const;                 // Class
   bool isObjCBuiltinType() const;               // 'id' or 'Class'
@@ -1950,7 +1951,7 @@ public:
            Protocols.size(); 
   }
   /// isObjCQualifiedClassType - true for "Class <p>".
-  bool isQualifiedClassType() const {
+  bool isObjCQualifiedClassType() const {
     return getPointeeType()->isSpecificBuiltinType(BuiltinType::ObjCClass) && 
            Protocols.size();
   }
@@ -2137,6 +2138,11 @@ inline bool Type::isObjCQualifiedIdType() const {
     return OPT->isObjCQualifiedIdType();
   return false;
 }
+inline bool Type::isObjCQualifiedClassType() const {
+  if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
+    return OPT->isObjCQualifiedClassType();
+  return false;
+}
 inline bool Type::isObjCIdType() const {
   if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType())
     return OPT->isObjCIdType();
index 5a8ffb1bb7c9ac7affdf4ea72661f568c6f4e399..3553a0386b521b0ff334149e9980b90880d2d984 100644 (file)
@@ -1961,8 +1961,6 @@ def ext_c99_array_usage : Extension<
   "use of C99-specific array features, accepted as an extension">;
 def err_invalid_protocol_qualifiers : Error<
   "invalid protocol qualifiers on non-ObjC type">;
-def err_qualified_class_unsupported : Error<
-  "protocol qualified 'Class' is unsupported">;
 def warn_ivar_use_hidden : Warning<
   "local declaration of %0 hides instance variable">;
 def error_ivar_use_in_class_method : Error<
index 304799cf91b9ff478e7ba74852128e8868c77019..174e183d530efb7ef0bc03aafc9feae1d864d739 100644 (file)
@@ -1742,9 +1742,6 @@ static void SortAndUniqueProtocols(ObjCProtocolDecl **&Protocols,
 QualType ASTContext::getObjCObjectPointerType(QualType InterfaceT,
                                               ObjCProtocolDecl **Protocols, 
                                               unsigned NumProtocols) {
-  if (InterfaceT.isNull()) 
-    InterfaceT = ObjCBuiltinIdTy;
-    
   // Sort the protocol list alphabetically to canonicalize it.
   if (NumProtocols)
     SortAndUniqueProtocols(Protocols, NumProtocols);
index ffcaf42ef9278e8c516239d739964f84841effdc..4d57680da2b947e4a2fcb0a6a31975514e2a9c8f 100644 (file)
@@ -1603,7 +1603,7 @@ void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString,
   
   if (isObjCIdType() || isObjCQualifiedIdType())
     ObjCQIString = "id";
-  else if (isObjCClassType())
+  else if (isObjCClassType() || isObjCQualifiedClassType())
     ObjCQIString = "Class";
   else
     ObjCQIString = getInterfaceDecl()->getNameAsString();
index 068b386980e4f33d89b07bb6e7a7ec310fce4fad..2d144100e5d0186111061562b76eee22b759a04a 100644 (file)
@@ -512,8 +512,7 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
   }
 
   // Handle messages to id.  
-  if (ReceiverCType == Context.getCanonicalType(Context.getObjCIdType()) ||
-      ReceiverCType->isBlockPointerType() ||
+  if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() ||
       Context.isObjCNSObjectType(RExpr->getType())) {
     ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
                                Sel, SourceRange(lbrac,rbrac));
@@ -528,7 +527,8 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
   }
   
   // Handle messages to Class.
-  if (ReceiverCType == Context.getCanonicalType(Context.getObjCClassType())) {
+  if (ReceiverCType->isObjCClassType() || 
+      ReceiverCType->isObjCQualifiedClassType()) {
     ObjCMethodDecl *Method = 0;
     
     if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
@@ -538,6 +538,9 @@ Sema::ExprResult Sema::ActOnInstanceMessage(ExprTy *receiver, Selector Sel,
         
         if (!Method)
           Method = LookupPrivateClassMethod(Sel, ClassDecl);
+          
+        // FIXME: if we still haven't found a method, we need to look in 
+        // protocols (if we have qualifiers).
       }
       if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
         return true;
index 3964f767ebf90b2d86a823a1a2362fd2ecacd952..a686e1db5963a6a380a620f80475f5db835b019f 100644 (file)
@@ -101,7 +101,7 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
   case DeclSpec::TST_unspecified:
     // "<proto1,proto2>" is an objc qualified ID with a missing id.
     if (DeclSpec::ProtocolQualifierListTy PQ = DS.getProtocolQualifiers()) {
-      Result = Context.getObjCObjectPointerType(QualType()
+      Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy
                                                 (ObjCProtocolDecl**)PQ,
                                                 DS.getNumProtocolQualifiers());
       break;
@@ -220,14 +220,14 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS,
                                               DS.getNumProtocolQualifiers());
       else if (Result->isObjCIdType())
         // id<protocol-list>
-        Result = Context.getObjCObjectPointerType(QualType()
+        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinIdTy
                         (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
       else if (Result->isObjCClassType()) {
         if (DeclLoc.isInvalid())
           DeclLoc = DS.getSourceRange().getBegin();
         // Class<protocol-list>
-        Diag(DeclLoc, diag::err_qualified_class_unsupported)
-          << DS.getSourceRange();
+        Result = Context.getObjCObjectPointerType(Context.ObjCBuiltinClassTy, 
+                        (ObjCProtocolDecl**)PQ, DS.getNumProtocolQualifiers());
       } else {
         if (DeclLoc.isInvalid())
           DeclLoc = DS.getSourceRange().getBegin();
index 92bec27c6783588f0de32c9d17c6dabc99d872b4..a481cffd2886defb5693074b9361ff597d122d75 100644 (file)
@@ -40,8 +40,8 @@ id objc_getClass(const char *s);
 {
    int i = [(id <Func>)self class_func0];
    i += [(id <Func>)super class_func0];    // expected-error {{cannot cast 'super' (it isn't an expression)}}
-   i += [(Class <Func>)self class_func0];  // expected-error {{protocol qualified 'Class' is unsupported}}
-   return i + [(Class <Func>)super class_func0]; // expected-error {{protocol qualified 'Class' is unsupported}} // expected-error {{cannot cast 'super' (it isn't an expression)}}
+   i += [(Class <Func>)self class_func0];  // 
+   return i + [(Class <Func>)super class_func0]; // // expected-error {{cannot cast 'super' (it isn't an expression)}}
 }
 + (int) class_func3
 {
index 3e70c05096524f6300ad8fc86e9bcf6ab2fb312d..05f5103178f2b099ab291c1bc436014fca27a143 100644 (file)
@@ -28,8 +28,7 @@ typedef int NotAnObjCObjectType;
 // GCC doesn't diagnose this.
 NotAnObjCObjectType <SomeProtocol> *obj; // expected-error {{invalid protocol qualifiers on non-ObjC type}}
 
-// Decided not to support the following GCC extension. Found while researching rdar://6497631
 typedef struct objc_class *Class;
 
-Class <SomeProtocol> UnfortunateGCCExtension; // expected-error {{protocol qualified 'Class' is unsupported}}
+Class <SomeProtocol> UnfortunateGCCExtension;
 
index ae8441132c7783218615bc4f4dc9edd1a73918a8..6bd58dd9a03ad0dcb096412a75fbf45f430b281f 100644 (file)
@@ -3,7 +3,7 @@
 __attribute ((unavailable))
 @protocol FwProto; // expected-note{{marked unavailable}}
 
-Class <FwProto> cFw = 0;  // expected-warning {{'FwProto' is unavailable}} expected-error{{protocol qualified 'Class' is unsupported}}
+Class <FwProto> cFw = 0;  // expected-warning {{'FwProto' is unavailable}}
 
 
 __attribute ((deprecated)) @protocol MyProto1
@@ -31,7 +31,7 @@ __attribute ((deprecated)) @protocol MyProto1
 
 
 
-Class <MyProto1> clsP1 = 0;  // expected-warning {{'MyProto1' is deprecated}} expected-error{{protocol qualified 'Class' is unsupported}}
+Class <MyProto1> clsP1 = 0;  // expected-warning {{'MyProto1' is deprecated}}
 
 @protocol FwProto @end // expected-note{{marked unavailable}}
 
index ad1ed5dc9411a9728a60393c4ff3b317fd0ea5ab..6e344c1f44143379a2f4ea8b419767deea5fbc09 100644 (file)
@@ -23,7 +23,7 @@ id objc_getClass(const char *s);
 @interface Derived2: Object <Func>
 @end
 
-static void doSomething(Class <Func> unsupportedObjectType) { // expected-error {{protocol qualified 'Class' is unsupported}}
+static void doSomething(Class <Func> unsupportedObjectType) {
   [unsupportedObjectType class_func0];
 }