Improve the semantic checking for explicit instantiations of
templates. In particular:
  - An explicit instantiation can follow an implicit instantiation (we
  were improperly diagnosing this as an error, previously).
  - In C++0x, an explicit instantiation that follows an explicit
  specialization of the same template specialization is ignored. In
  C++98, we just emit an extension warning.
  - In C++0x, an explicit instantiation must be in a namespace
  enclosing the original template. C++98 has no such requirement.

Also, fixed a longstanding FIXME regarding the integral type that is
used for the size of a constant array type when it is being instantiated.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71689 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index ce8cbe0..3a2f677 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -247,10 +247,26 @@
   // Build a temporary integer literal to specify the size for
   // BuildArrayType. Since we have already checked the size as part of
   // creating the dependent array type in the first place, we know
-  // there aren't any errors.
-  // FIXME: Is IntTy big enough? Maybe not, but LongLongTy causes
-  // problems that I have yet to investigate.
-  IntegerLiteral ArraySize(T->getSize(), SemaRef.Context.IntTy, Loc);
+  // there aren't any errors. However, we do need to determine what
+  // C++ type to give the size expression.
+  llvm::APInt Size = T->getSize();
+  QualType Types[] = { 
+    SemaRef.Context.UnsignedCharTy, SemaRef.Context.UnsignedShortTy, 
+    SemaRef.Context.UnsignedIntTy, SemaRef.Context.UnsignedLongTy, 
+    SemaRef.Context.UnsignedLongLongTy, SemaRef.Context.UnsignedInt128Ty 
+  };
+  const unsigned NumTypes = sizeof(Types) / sizeof(QualType);
+  QualType SizeType;
+  for (unsigned I = 0; I != NumTypes; ++I)
+    if (Size.getBitWidth() == SemaRef.Context.getIntWidth(Types[I])) {
+      SizeType = Types[I];
+      break;
+    }
+
+  if (SizeType.isNull())
+    SizeType = SemaRef.Context.getFixedWidthIntType(Size.getBitWidth(), false);
+
+  IntegerLiteral ArraySize(Size, SizeType, Loc);
   return SemaRef.BuildArrayType(ElementType, T->getSizeModifier(), 
                                 &ArraySize, T->getIndexTypeQualifier(), 
                                 Loc, Entity);