Create a new InjectedClassNameType to represent bare-word references to the 
injected class name of a class template or class template partial specialization.
This is a non-canonical type;  the canonical type is still a template 
specialization type.  This becomes the TypeForDecl of the pattern declaration,
which cleans up some amount of code (and complicates some other parts, but
whatever).

Fixes PR6326 and probably a few others, primarily by re-establishing a few
invariants about TypeLoc sizes.     



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@98134 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 3a6b4cb..cf8d38c 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -621,7 +621,8 @@
   Inst->setInstantiatedFromMemberTemplate(D);
   
   // Trigger creation of the type for the instantiation.
-  SemaRef.Context.getTypeDeclType(RecordInst);
+  SemaRef.Context.getInjectedClassNameType(RecordInst,
+                  Inst->getInjectedClassNameSpecialization(SemaRef.Context));
   
   // Finish handling of friends.
   if (Inst->getFriendObjectKind()) {
@@ -1462,8 +1463,10 @@
   // actually wrote the specialization, rather than formatting the
   // name based on the "canonical" representation used to store the
   // template arguments in the specialization.
-  QualType WrittenTy
-    = SemaRef.Context.getTemplateSpecializationType(TemplateName(ClassTemplate),
+  TypeSourceInfo *WrittenTy
+    = SemaRef.Context.getTemplateSpecializationTypeInfo(
+                                                    TemplateName(ClassTemplate),
+                                                    PartialSpec->getLocation(),
                                                     InstTemplateArgs,
                                                     CanonType);
   
@@ -1499,6 +1502,7 @@
                                                      ClassTemplate, 
                                                      Converted,
                                                      InstTemplateArgs,
+                                                     CanonType,
                                                      0);
   InstPartialSpec->setInstantiatedFromMember(PartialSpec);
   InstPartialSpec->setTypeAsWritten(WrittenTy);
@@ -2236,12 +2240,18 @@
     ClassTemplateDecl *ClassTemplate = Record->getDescribedClassTemplate();
     
     if (ClassTemplate) {
-      T = ClassTemplate->getInjectedClassNameType(Context);
+      T = ClassTemplate->getInjectedClassNameSpecialization(Context);
     } else if (ClassTemplatePartialSpecializationDecl *PartialSpec
                  = dyn_cast<ClassTemplatePartialSpecializationDecl>(Record)) {
-      T = Context.getTypeDeclType(Record);
       ClassTemplate = PartialSpec->getSpecializedTemplate();
-    } 
+
+      // If we call SubstType with an InjectedClassNameType here we
+      // can end up in an infinite loop.
+      T = Context.getTypeDeclType(Record);
+      assert(isa<InjectedClassNameType>(T) &&
+             "type of partial specialization is not an InjectedClassNameType");
+      T = cast<InjectedClassNameType>(T)->getUnderlyingType();
+    }  
     
     if (!T.isNull()) {
       // Substitute into the injected-class-name to get the type
@@ -2308,16 +2318,16 @@
     // so now we need to look into the instantiated parent context to
     // find the instantiation of the declaration D.
 
-    // If our context is a class template specialization, we may need
-    // to instantiate it before performing lookup into that context.
-    if (ClassTemplateSpecializationDecl *Spec
-                       = dyn_cast<ClassTemplateSpecializationDecl>(ParentDC)) {
+    // If our context used to be dependent, we may need to instantiate
+    // it before performing lookup into that context.
+    if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) {
       if (!Spec->isDependentContext()) {
         QualType T = Context.getTypeDeclType(Spec);
-        if (const TagType *Tag = T->getAs<TagType>())
-          if (!Tag->isBeingDefined() &&
-              RequireCompleteType(Loc, T, diag::err_incomplete_type))
-            return 0;
+        const RecordType *Tag = T->getAs<RecordType>();
+        assert(Tag && "type of non-dependent record is not a RecordType");
+        if (!Tag->isBeingDefined() &&
+            RequireCompleteType(Loc, T, diag::err_incomplete_type))
+          return 0;
       }
     }