Improve the representation of template type parameters. We now
canonicalize by template parameter depth, index, and name, and the
unnamed version of a template parameter serves as the canonical.

TemplateTypeParmDecl no longer needs to inherit from
TemplateParmPosition, since depth and index information is present
within the type.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63899 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 7784aed..a87a902 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1144,9 +1144,9 @@
   
   if (TypedefDecl *Typedef = dyn_cast<TypedefDecl>(Decl))
     return getTypedefType(Typedef);
-  else if (TemplateTypeParmDecl *TP = dyn_cast<TemplateTypeParmDecl>(Decl))
-    return getTemplateTypeParmType(TP);
-  else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast<ObjCInterfaceDecl>(Decl))
+  else if (isa<TemplateTypeParmDecl>(Decl)) {
+    assert(false && "Template type parameter types are always available.");
+  } else if (ObjCInterfaceDecl *ObjCInterface = dyn_cast<ObjCInterfaceDecl>(Decl))
     return getObjCInterfaceType(ObjCInterface);
 
   if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Decl)) {
@@ -1185,16 +1185,6 @@
   return QualType(Decl->TypeForDecl, 0);
 }
 
-/// getTemplateTypeParmType - Return the unique reference to the type
-/// for the specified template type parameter declaration. 
-QualType ASTContext::getTemplateTypeParmType(TemplateTypeParmDecl *Decl) {
-  if (!Decl->TypeForDecl) {
-    Decl->TypeForDecl = new (*this,8) TemplateTypeParmType(Decl);
-    Types.push_back(Decl->TypeForDecl);
-  }
-  return QualType(Decl->TypeForDecl, 0);
-}
-
 /// getObjCInterfaceType - Return the unique reference to the type for the
 /// specified ObjC interface decl.
 QualType ASTContext::getObjCInterfaceType(ObjCInterfaceDecl *Decl) {
@@ -1205,6 +1195,31 @@
   return QualType(Decl->TypeForDecl, 0);
 }
 
+/// \brief Retrieve the template type parameter type for a template
+/// parameter with the given depth, index, and (optionally) name.
+QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index, 
+                                             IdentifierInfo *Name) {
+  llvm::FoldingSetNodeID ID;
+  TemplateTypeParmType::Profile(ID, Depth, Index, Name);
+  void *InsertPos = 0;
+  TemplateTypeParmType *TypeParm 
+    = TemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
+
+  if (TypeParm)
+    return QualType(TypeParm, 0);
+  
+  if (Name)
+    TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index, Name,
+                                         getTemplateTypeParmType(Depth, Index));
+  else
+    TypeParm = new (*this, 8) TemplateTypeParmType(Depth, Index);
+
+  Types.push_back(TypeParm);
+  TemplateTypeParmTypes.InsertNode(TypeParm, InsertPos);
+
+  return QualType(TypeParm, 0);
+}
+
 /// CmpProtocolNames - Comparison predicate for sorting protocols
 /// alphabetically.
 static bool CmpProtocolNames(const ObjCProtocolDecl *LHS,