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);