Improve checking for specializations of member classes of class
templates, and keep track of how those member classes were
instantiated or specialized. 

Make sure that we don't try to instantiate an explicitly-specialized
member class of a class template, when that explicit specialization
was a declaration rather than a definition.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83547 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index 7408f2f..2d35117 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -437,6 +437,53 @@
   Conversions.addOverload(ConvDecl);
 }
 
+CXXRecordDecl *CXXRecordDecl::getInstantiatedFromMemberClass() const {
+  if (MemberSpecializationInfo *MSInfo
+        = TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>())
+    return cast<CXXRecordDecl>(MSInfo->getInstantiatedFrom());
+  
+  return 0;
+}
+
+void 
+CXXRecordDecl::setInstantiationOfMemberClass(CXXRecordDecl *RD,
+                                             TemplateSpecializationKind TSK) {
+  assert(TemplateOrInstantiation.isNull() && 
+         "Previous template or instantiation?");
+  assert(!isa<ClassTemplateSpecializationDecl>(this));
+  TemplateOrInstantiation 
+    = new (getASTContext()) MemberSpecializationInfo(RD, TSK);
+}
+
+TemplateSpecializationKind CXXRecordDecl::getTemplateSpecializationKind() {
+  if (ClassTemplateSpecializationDecl *Spec
+        = dyn_cast<ClassTemplateSpecializationDecl>(this))
+    return Spec->getSpecializationKind();
+  
+  if (MemberSpecializationInfo *MSInfo
+      = TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>())
+    return MSInfo->getTemplateSpecializationKind();
+  
+  return TSK_Undeclared;
+}
+
+void 
+CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) {
+  if (ClassTemplateSpecializationDecl *Spec
+      = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
+    Spec->setSpecializationKind(TSK);
+    return;
+  }
+  
+  if (MemberSpecializationInfo *MSInfo
+        = TemplateOrInstantiation.dyn_cast<MemberSpecializationInfo *>()) {
+    MSInfo->setTemplateSpecializationKind(TSK);
+    return;
+  }
+  
+  assert(false && "Not a class template or member class specialization");
+}
+
 CXXConstructorDecl *
 CXXRecordDecl::getDefaultConstructor(ASTContext &Context) {
   QualType ClassType = Context.getTypeDeclType(this);