First step toward fixing <rdar://problem/6613046> refactor clang objc type representation.

Add a type (ObjCObjectPointerType) and remove a type (ObjCQualifiedIdType).

This large/tedious patch is just a first step. Next step is to remove ObjCQualifiedInterfaceType. After that, I will remove the magic TypedefType for 'id' (installed by Sema). This work will enable various simplifications throughout clang (when dealing with ObjC types). 

No functionality change.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@73649 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 55a0952..1db666f 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -562,6 +562,12 @@
   return dyn_cast<ObjCInterfaceType>(CanonicalType.getUnqualifiedType());
 }
 
+const ObjCObjectPointerType *Type::getAsObjCObjectPointerType() const {
+  // There is no sugar for ObjCObjectPointerType's, just return the
+  // canonical type pointer if it is the right class.
+  return dyn_cast<ObjCObjectPointerType>(CanonicalType.getUnqualifiedType());
+}
+
 const ObjCQualifiedInterfaceType *
 Type::getAsObjCQualifiedInterfaceType() const {
   // There is no sugar for ObjCQualifiedInterfaceType's, just return the
@@ -569,10 +575,14 @@
   return dyn_cast<ObjCQualifiedInterfaceType>(CanonicalType.getUnqualifiedType());
 }
 
-const ObjCQualifiedIdType *Type::getAsObjCQualifiedIdType() const {
+const ObjCObjectPointerType *Type::getAsObjCQualifiedIdType() const {
   // There is no sugar for ObjCQualifiedIdType's, just return the canonical
   // type pointer if it is the right class.
-  return dyn_cast<ObjCQualifiedIdType>(CanonicalType.getUnqualifiedType());
+  if (const ObjCObjectPointerType *OPT = getAsObjCObjectPointerType()) {
+    if (OPT->isObjCQualifiedIdType())
+      return OPT;
+  }
+  return 0;
 }
 
 const TemplateTypeParmType *Type::getAsTemplateTypeParmType() const {
@@ -777,7 +787,7 @@
          isa<BlockPointerType>(CanonicalType) ||
          isa<MemberPointerType>(CanonicalType) ||
          isa<ComplexType>(CanonicalType) ||
-         isa<ObjCQualifiedIdType>(CanonicalType);
+         isa<ObjCObjectPointerType>(CanonicalType);
 }
 
 /// \brief Determines whether the type is a C++ aggregate type or C
@@ -864,7 +874,7 @@
   case MemberPointer:
   case Vector:
   case ExtVector:
-  case ObjCQualifiedId:
+  case ObjCObjectPointer:
     return true;
 
   case Enum:
@@ -919,7 +929,7 @@
   case Typename:
   case ObjCInterface:
   case ObjCQualifiedInterface:
-  case ObjCQualifiedId:
+  case ObjCObjectPointer:
     return true;
   default:
     return false;
@@ -980,6 +990,19 @@
           getNumExceptions(), exception_begin());
 }
 
+void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID,
+                                    const ObjCInterfaceDecl *Decl,
+                                    ObjCProtocolDecl **protocols,
+                                    unsigned NumProtocols) {
+  ID.AddPointer(Decl);
+  for (unsigned i = 0; i != NumProtocols; i++)
+    ID.AddPointer(protocols[i]);
+}
+
+void ObjCObjectPointerType::Profile(llvm::FoldingSetNodeID &ID) {
+  Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
+}
+
 void ObjCQualifiedInterfaceType::Profile(llvm::FoldingSetNodeID &ID,
                                          const ObjCInterfaceDecl *Decl,
                                          ObjCProtocolDecl **protocols, 
@@ -993,17 +1016,6 @@
   Profile(ID, getDecl(), &Protocols[0], getNumProtocols());
 }
 
-void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID,
-                                  ObjCProtocolDecl **protocols, 
-                                  unsigned NumProtocols) {
-  for (unsigned i = 0; i != NumProtocols; i++)
-    ID.AddPointer(protocols[i]);
-}
-
-void ObjCQualifiedIdType::Profile(llvm::FoldingSetNodeID &ID) {
-  Profile(ID, &Protocols[0], getNumProtocols());
-}
-
 /// LookThroughTypedefs - Return the ultimate type this typedef corresponds to
 /// potentially looking through *all* consequtive typedefs.  This returns the
 /// sum of the type qualifiers, so if you have:
@@ -1593,6 +1605,30 @@
   InnerString = getDecl()->getIdentifier()->getName() + InnerString;
 }
 
+void ObjCObjectPointerType::getAsStringInternal(std::string &InnerString, 
+                                                const PrintingPolicy &Policy) const {
+  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
+    InnerString = ' ' + InnerString;
+
+  std::string ObjCQIString;
+  
+  if (getDecl())
+    ObjCQIString = getDecl()->getNameAsString();
+  else
+    ObjCQIString = "id";
+
+  if (!qual_empty()) {
+    ObjCQIString += '<';
+    for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
+      ObjCQIString += (*I)->getNameAsString();
+      if (I+1 != E)
+        ObjCQIString += ',';
+    }
+    ObjCQIString += '>';
+  }
+  InnerString = ObjCQIString + InnerString;
+}
+
 void 
 ObjCQualifiedInterfaceType::getAsStringInternal(std::string &InnerString,
                                            const PrintingPolicy &Policy) const {
@@ -1612,20 +1648,6 @@
   InnerString = ObjCQIString + InnerString;
 }
 
-void ObjCQualifiedIdType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
-  if (!InnerString.empty())    // Prefix the basic type, e.g. 'typedefname X'.
-    InnerString = ' ' + InnerString;
-  std::string ObjCQIString = "id";
-  ObjCQIString += '<';
-  for (qual_iterator I = qual_begin(), E = qual_end(); I != E; ++I) {
-    ObjCQIString += (*I)->getNameAsString();
-    if (I+1 != E)
-      ObjCQIString += ',';
-  }
-  ObjCQIString += '>';
-  InnerString = ObjCQIString + InnerString;
-}
-
 void TagType::getAsStringInternal(std::string &InnerString, const PrintingPolicy &Policy) const {
   if (Policy.SuppressTag)
     return;