Patch to implemented objective-c's dynamic object pointer qualified with
the protocol list (id<P,...> types).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@45121 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
index 4351b89..92b691e 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -49,6 +49,7 @@
   
   unsigned NumTagStruct = 0, NumTagUnion = 0, NumTagEnum = 0, NumTagClass = 0;
   unsigned NumObjcInterfaces = 0, NumObjcQualifiedInterfaces = 0;
+  unsigned NumObjcQualifiedIds = 0;
   
   for (unsigned i = 0, e = Types.size(); i != e; ++i) {
     Type *T = Types[i];
@@ -83,6 +84,8 @@
       ++NumObjcInterfaces;
     else if (isa<ObjcQualifiedInterfaceType>(T))
       ++NumObjcQualifiedInterfaces;
+    else if (isa<ObjcQualifiedIdType>(T))
+      ++NumObjcQualifiedIds;
     else {
       QualType(T, 0).dump();
       assert(0 && "Unknown type!");
@@ -106,6 +109,8 @@
   fprintf(stderr, "    %d interface types\n", NumObjcInterfaces);
   fprintf(stderr, "    %d protocol qualified interface types\n",
           NumObjcQualifiedInterfaces);
+  fprintf(stderr, "    %d protocol qualified id types\n",
+          NumObjcQualifiedIds);
   fprintf(stderr, "Total bytes = %d\n", int(NumBuiltin*sizeof(BuiltinType)+
     NumPointer*sizeof(PointerType)+NumArray*sizeof(ArrayType)+
     NumComplex*sizeof(ComplexType)+NumVector*sizeof(VectorType)+
@@ -677,7 +682,7 @@
   if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
   
   QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
-  Decl->TypeForDecl = new TypedefType(Decl, Canonical);
+  Decl->TypeForDecl = new TypedefType(Type::TypeName, Decl, Canonical);
   Types.push_back(Decl->TypeForDecl);
   return QualType(Decl->TypeForDecl, 0);
 }
@@ -713,6 +718,29 @@
   return QualType(QType, 0);
 }
 
+/// getObjcQualifiedIdType - Return a 
+/// getObjcQualifiedIdType type for the given interface decl and
+/// the conforming protocol list.
+QualType ASTContext::getObjcQualifiedIdType(TypedefDecl *Decl,
+                                            ObjcProtocolDecl **Protocols, 
+                                            unsigned NumProtocols) {
+  llvm::FoldingSetNodeID ID;
+  ObjcQualifiedIdType::Profile(ID, Protocols, NumProtocols);
+  
+  void *InsertPos = 0;
+  if (ObjcQualifiedIdType *QT =
+      ObjcQualifiedIdTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(QT, 0);
+  
+  // No Match;
+  QualType Canonical = Decl->getUnderlyingType().getCanonicalType();
+  ObjcQualifiedIdType *QType =
+  new ObjcQualifiedIdType(Decl, Canonical, Protocols, NumProtocols);
+  Types.push_back(QType);
+  ObjcQualifiedIdTypes.InsertNode(QType, InsertPos);
+  return QualType(QType, 0);
+}
+
 /// getTypeOfExpr - Unlike many "get<Type>" functions, we can't unique
 /// TypeOfExpr AST's (since expression's are never shared). For example,
 /// multiple declarations that refer to "typeof(x)" all contain different
@@ -1043,7 +1071,13 @@
     }
     
     S += encoding;
-  } else if (const PointerType *PT = T->getAsPointerType()) {
+  }
+  else if (const ObjcQualifiedIdType *QIT = dyn_cast<ObjcQualifiedIdType>(T)) {
+    // Treat id<P...> same as 'id' for encoding purposes.
+    return getObjcEncodingForType(QIT->getDecl()->getUnderlyingType(), S);
+    
+  }
+  else if (const PointerType *PT = T->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
     if (isObjcIdType(PointeeTy) || PointeeTy->isObjcInterfaceType()) {
       S += '@';
@@ -1221,6 +1255,13 @@
   return true;
 }
 
+// TODO: id<P1,...> vs. id<P,...>
+#if 0
+bool ASTContext::QualifiedIdTypesAreCompatible(QualType lhs, 
+                                                      QualType rhs) {
+}
+#endif
+
 bool ASTContext::vectorTypesAreCompatible(QualType lhs, QualType rhs) {
   const VectorType *lVector = lhs->getAsVectorType();
   const VectorType *rVector = rhs->getAsVectorType();