diff options
author | Douglas Gregor <dgregor@apple.com> | 2009-05-13 18:28:20 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2009-05-13 18:28:20 +0000 |
commit | ff66803b43f2ea9206637dceb793e9505f3b9c48 (patch) | |
tree | 401d9f5eee2178816667fd2139457347bee01a9a /lib/Sema/SemaTemplateInstantiate.cpp | |
parent | 70b6a83b833c40f320d0ed2310cbcdf2be4cece0 (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.cpp | 24 |
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); |