aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema/SemaTemplateInstantiate.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2009-05-13 18:28:20 +0000
committerDouglas Gregor <dgregor@apple.com>2009-05-13 18:28:20 +0000
commitff66803b43f2ea9206637dceb793e9505f3b9c48 (patch)
tree401d9f5eee2178816667fd2139457347bee01a9a /lib/Sema/SemaTemplateInstantiate.cpp
parent70b6a83b833c40f320d0ed2310cbcdf2be4cece0 (diff)
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
Diffstat (limited to 'lib/Sema/SemaTemplateInstantiate.cpp')
-rw-r--r--lib/Sema/SemaTemplateInstantiate.cpp24
1 files changed, 20 insertions, 4 deletions
diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp
index ce8cbe0f43..3a2f677755 100644
--- a/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/lib/Sema/SemaTemplateInstantiate.cpp
@@ -247,10 +247,26 @@ InstantiateConstantArrayType(const ConstantArrayType *T,
// 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);