]> granicus.if.org Git - clang/commitdiff
fix several problems with the protocol qualified id handling where id was implicit.
authorChris Lattner <sabre@nondot.org>
Sat, 26 Jul 2008 00:46:50 +0000 (00:46 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 26 Jul 2008 00:46:50 +0000 (00:46 +0000)
First, fix canonical type handling of these, since protocol qualified id's are always
canonical.  Next, enhance SemaType to actually make these when used (instead of int)
allowing them to actually be used when appropriate.  Finally remove a bunch of logic
relating to the mishandling of canonical types with protocol-qual id's.  This fixes
rdar://5986251

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

include/clang/AST/ASTContext.h
include/clang/AST/Type.h
lib/AST/ASTContext.cpp
lib/AST/Type.cpp
lib/Sema/SemaType.cpp
test/Sema/objc-protocol-1.m

index c981aa4116b4e178f006e548392f27c77f3b05f8..0def9881402ee41d24d17d5ea50a6298406a7555 100644 (file)
@@ -217,8 +217,7 @@ public:
   
   /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for a 
   /// given 'id' and conforming protocol list.
-  QualType getObjCQualifiedIdType(QualType idType,
-                                  ObjCProtocolDecl **ProtocolList, 
+  QualType getObjCQualifiedIdType(ObjCProtocolDecl **ProtocolList, 
                                   unsigned NumProtocols);
                                   
 
index 22f7abaf49be6cc1f86ab12876934189be2c7548..28f6e8cf9328d1838e745b7ecf7414a58101ca69 100644 (file)
@@ -1227,8 +1227,8 @@ class ObjCQualifiedIdType : public Type,
   // List is sorted on protocol name. No protocol is enterred more than once.
   llvm::SmallVector<ObjCProtocolDecl*, 8> Protocols;
     
-  ObjCQualifiedIdType(QualType can, ObjCProtocolDecl **Protos,  unsigned NumP)
-  : Type(ObjCQualifiedId, can), 
+  ObjCQualifiedIdType(ObjCProtocolDecl **Protos, unsigned NumP)
+    : Type(ObjCQualifiedId, QualType()/*these are always canonical*/), 
   Protocols(Protos, Protos+NumP) { }
   friend class ASTContext;  // ASTContext creates these.
 public:
@@ -1250,7 +1250,7 @@ public:
   virtual void getAsStringInternal(std::string &InnerString) const;
     
   void Profile(llvm::FoldingSetNodeID &ID);
-  static void Profile(llvm::FoldingSetNodeID &ID, 
+  static void Profile(llvm::FoldingSetNodeID &ID,
                       ObjCProtocolDecl **protocols, unsigned NumProtocols);
     
   static bool classof(const Type *T) { 
index 54cc8e00683e5e04c0f4bbec4d5ba09b86298026..dedc9b8376a4e376c4a5fb69a1dc6283c0476e38 100644 (file)
@@ -929,8 +929,7 @@ QualType ASTContext::getObjCQualifiedInterfaceType(ObjCInterfaceDecl *Decl,
 
 /// getObjCQualifiedIdType - Return an ObjCQualifiedIdType for the 'id' decl
 /// and the conforming protocol list.
-QualType ASTContext::getObjCQualifiedIdType(QualType idType,
-                                            ObjCProtocolDecl **Protocols, 
+QualType ASTContext::getObjCQualifiedIdType(ObjCProtocolDecl **Protocols, 
                                             unsigned NumProtocols) {
   // Sort the protocol list alphabetically to canonicalize it.
   SortAndUniqueProtocols(Protocols, NumProtocols);
@@ -940,21 +939,11 @@ QualType ASTContext::getObjCQualifiedIdType(QualType idType,
   
   void *InsertPos = 0;
   if (ObjCQualifiedIdType *QT =
-      ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
+        ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(QT, 0);
   
   // No Match;
-  QualType Canonical;
-  if (!idType->isCanonical()) {
-    Canonical = getObjCQualifiedIdType(getCanonicalType(idType), 
-                                       Protocols, NumProtocols);
-    ObjCQualifiedIdType *NewQT = 
-      ObjCQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos);
-    assert(NewQT == 0 && "Shouldn't be in the map!");
-  }
-  
-  ObjCQualifiedIdType *QType = 
-    new ObjCQualifiedIdType(Canonical, Protocols, NumProtocols);
+  ObjCQualifiedIdType *QType = new ObjCQualifiedIdType(Protocols, NumProtocols);
   Types.push_back(QType);
   ObjCQualifiedIdTypes.InsertNode(QType, InsertPos);
   return QualType(QType, 0);
index 275406eabacacca27ae8172632d0e350cda3baf6..08f889a4bf84d827ed1357c00f8b273a2c27e8a0 100644 (file)
@@ -743,8 +743,8 @@ void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID) {
 }
 
 void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID,
-                                         ObjCProtocolDecl **protocols, 
-                                         unsigned NumProtocols) {
+                                  ObjCProtocolDecl **protocols, 
+                                  unsigned NumProtocols) {
   for (unsigned i = 0; i != NumProtocols; i++)
     ID.AddPointer(protocols[i]);
 }
index 4bee2de994884b94e5a0951dfbf7cc6a2e4e67b3..85a457bd562f4cf39bc4b30cc4797a25d0283958 100644 (file)
@@ -43,6 +43,14 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
     }
     break;
   case DeclSpec::TST_unspecified:
+    // "<proto1,proto2>" is an objc qualified ID with a missing id.
+    if (llvm::SmallVector<Action::DeclTy *, 8> *PQ=DS.getProtocolQualifiers()) {
+      Action::DeclTy **PPDecl = &(*PQ)[0];
+      Result = Context.getObjCQualifiedIdType((ObjCProtocolDecl**)(PPDecl),
+                                              DS.getNumProtocolQualifiers());
+      break;
+    }
+      
     // Unspecified typespec defaults to int in C90.  However, the C90 grammar
     // [C90 6.5] only allows a decl-spec if there was *some* type-specifier,
     // type-qualifier, or storage-class-specifier.  If not, emit an extwarn.
@@ -128,13 +136,12 @@ QualType Sema::ConvertDeclSpecToType(const DeclSpec &DS) {
                                    reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
                                                  DS.getNumProtocolQualifiers());
       break;
-    }
-    else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
+    } else if (TypedefDecl *typeDecl = dyn_cast<TypedefDecl>(D)) {
       if (Context.getObjCIdType() == Context.getTypedefType(typeDecl)
           && DS.getProtocolQualifiers()) {
           // id<protocol-list>
         Action::DeclTy **PPDecl = &(*DS.getProtocolQualifiers())[0];
-        Result = Context.getObjCQualifiedIdType(typeDecl->getUnderlyingType(),
+        Result = Context.getObjCQualifiedIdType(
                                  reinterpret_cast<ObjCProtocolDecl**>(PPDecl),
                                             DS.getNumProtocolQualifiers());
         break;
index f0615a32bea92c01944335a43c87c6242a162c21..3ace0ac3de09ce44e5a190962b466d7b9cf035c7 100644 (file)
@@ -1,10 +1,14 @@
 // RUN: clang -fsyntax-only -verify %s
+// rdar://5986251
 
 @protocol SomeProtocol
+- (void) bar;
 @end
 
 void foo(id x) {
   bar((short<SomeProtocol>)x); // expected-error {{expected ')'}} expected-error {{to match this '('}}
   bar((<SomeProtocol>)x);      // expected-warning {{protocol qualifiers without 'id' is archaic}}
+
+  [(<SomeProtocol>)x bar];      // expected-warning {{protocol qualifiers without 'id' is archaic}}
 }