Representation of objc gc's attribute using ExtQualType.
Note that one test attr-objc-gc.m fails. I will fix this
after removing these attributes from the Decl nodes.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@64889 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 4a3f00f..6b49b85 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -725,7 +725,7 @@
   // Check if we've already instantiated an address space qual'd type of this
   // type.
   llvm::FoldingSetNodeID ID;
-  ExtQualType::Profile(ID, T.getTypePtr(), AddressSpace, ExtQualType::GCNone);      
+  ExtQualType::Profile(ID, T.getTypePtr(), AddressSpace, T.getObjCGCAttr());      
   void *InsertPos = 0;
   if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
     return QualType(EXTQy, 0);
@@ -741,12 +741,47 @@
     assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
   }
   ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical, 
-                                                AddressSpace, ExtQualType::GCNone);
+                                                AddressSpace, 
+                                                QualType::GCNone);
   ExtQualTypes.InsertNode(New, InsertPos);
   Types.push_back(New);
   return QualType(New, T.getCVRQualifiers());
 }
 
+QualType ASTContext::getObjCGCQualType(QualType T, 
+                                       QualType::GCAttrTypes attr) {
+  QualType CanT = getCanonicalType(T);
+  if (CanT.getObjCGCAttr() == attr)
+    return T;
+  
+  // Type's cannot have multiple ExtQuals, therefore we know we only have to deal
+  // with CVR qualifiers from here on out.
+  assert(CanT.getObjCGCAttr() == QualType::GCNone && 
+         "Type is already gc qualified");
+  
+  // Check if we've already instantiated an gc qual'd type of this type.
+  llvm::FoldingSetNodeID ID;
+  ExtQualType::Profile(ID, T.getTypePtr(), T.getAddressSpace(), attr);      
+  void *InsertPos = 0;
+  if (ExtQualType *EXTQy = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos))
+    return QualType(EXTQy, 0);
+  
+  // If the base type isn't canonical, this won't be a canonical type either,
+  // so fill in the canonical type field.
+  QualType Canonical;
+  if (!T->isCanonical()) {
+    Canonical = getObjCGCQualType(CanT, attr);
+    
+    // Get the new insert position for the node we care about.
+    ExtQualType *NewIP = ExtQualTypes.FindNodeOrInsertPos(ID, InsertPos);
+    assert(NewIP == 0 && "Shouldn't be in the map!"); NewIP = NewIP;
+  }
+  ExtQualType *New = new (*this, 8) ExtQualType(T.getTypePtr(), Canonical, 
+                                                0, attr);
+  ExtQualTypes.InsertNode(New, InsertPos);
+  Types.push_back(New);
+  return QualType(New, T.getCVRQualifiers());
+}
 
 /// getComplexType - Return the uniqued reference to the type for a complex
 /// number with the specified element type.