Index: cfe/trunk/include/clang/AST/Type.h =================================================================== --- cfe/trunk/include/clang/AST/Type.h +++ cfe/trunk/include/clang/AST/Type.h @@ -1608,6 +1608,21 @@ unsigned Keyword : 2; }; + class SubstTemplateTypeParmPackTypeBitfields { + friend class SubstTemplateTypeParmPackType; + + unsigned : NumTypeBits; + + /// The number of template arguments in \c Arguments, which is + /// expected to be able to hold at least 1024 according to [implimits]. + /// However as this limit is somewhat easy to hit with template + /// metaprogramming we'd prefer to keep it as large as possible. + /// At the moment it has been left as a non-bitfield since this type + /// safely fits in 64 bits as an unsigned, so there is no reason to + /// introduce the performance impact of a bitfield. + unsigned NumArgs; + }; + class TemplateSpecializationTypeBitfields { friend class TemplateSpecializationType; @@ -1672,6 +1687,7 @@ ReferenceTypeBitfields ReferenceTypeBits; TypeWithKeywordBitfields TypeWithKeywordBits; VectorTypeBitfields VectorTypeBits; + SubstTemplateTypeParmPackTypeBitfields SubstTemplateTypeParmPackTypeBits; TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits; DependentTemplateSpecializationTypeBitfields DependentTemplateSpecializationTypeBits; @@ -1697,6 +1713,9 @@ "TypeWithKeywordBitfields is larger than 8 bytes!"); static_assert(sizeof(VectorTypeBitfields) <= 8, "VectorTypeBitfields is larger than 8 bytes!"); + static_assert(sizeof(SubstTemplateTypeParmPackTypeBitfields) <= 8, + "SubstTemplateTypeParmPackTypeBitfields is larger" + " than 8 bytes!"); static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8, "TemplateSpecializationTypeBitfields is larger" " than 8 bytes!"); @@ -4551,9 +4570,6 @@ /// parameter pack is instantiated with. const TemplateArgument *Arguments; - /// The number of template arguments in \c Arguments. - unsigned NumArguments; - SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, QualType Canon, const TemplateArgument &ArgPack); @@ -4566,6 +4582,10 @@ return Replaced; } + unsigned getNumArgs() const { + return SubstTemplateTypeParmPackTypeBits.NumArgs; + } + bool isSugared() const { return false; } QualType desugar() const { return QualType(this, 0); } Index: cfe/trunk/lib/AST/Type.cpp =================================================================== --- cfe/trunk/lib/AST/Type.cpp +++ cfe/trunk/lib/AST/Type.cpp @@ -3285,11 +3285,12 @@ QualType Canon, const TemplateArgument &ArgPack) : Type(SubstTemplateTypeParmPack, Canon, true, true, false, true), - Replaced(Param), - Arguments(ArgPack.pack_begin()), NumArguments(ArgPack.pack_size()) {} + Replaced(Param), Arguments(ArgPack.pack_begin()) { + SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); +} TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { - return TemplateArgument(llvm::makeArrayRef(Arguments, NumArguments)); + return TemplateArgument(llvm::makeArrayRef(Arguments, getNumArgs())); } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) {