unsigned Keyword : 8;
};
+ enum { NumTypeWithKeywordBits = 8 };
+
class VectorTypeBitfields {
friend class VectorType;
friend class DependentVectorType;
unsigned NumArgs;
};
+ class DependentTemplateSpecializationTypeBitfields {
+ friend class DependentTemplateSpecializationType;
+
+ unsigned : NumTypeBits;
+ unsigned : NumTypeWithKeywordBits;
+
+ /// The number of template arguments named in this class template
+ /// specialization, 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 PackExpansionTypeBitfields {
friend class PackExpansionType;
TypeWithKeywordBitfields TypeWithKeywordBits;
VectorTypeBitfields VectorTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+ DependentTemplateSpecializationTypeBitfields
+ DependentTemplateSpecializationTypeBits;
PackExpansionTypeBitfields PackExpansionTypeBits;
static_assert(sizeof(TypeBitfields) <= 8,
static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
"TemplateSpecializationTypeBitfields is larger"
" than 8 bytes!");
+ static_assert(sizeof(DependentTemplateSpecializationTypeBitfields) <= 8,
+ "DependentTemplateSpecializationTypeBitfields is larger"
+ " than 8 bytes!");
static_assert(sizeof(PackExpansionTypeBitfields) <= 8,
"PackExpansionTypeBitfields is larger than 8 bytes");
};
/// The identifier of the template.
const IdentifierInfo *Name;
- /// The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs;
-
DependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
NestedNameSpecifier *NNS,
const IdentifierInfo *Name,
}
/// Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
+ unsigned getNumArgs() const {
+ return DependentTemplateSpecializationTypeBits.NumArgs;
+ }
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), NumArgs};
+ return {getArgs(), getNumArgs()};
}
using iterator = const TemplateArgument *;
QualType desugar() const { return QualType(this, 0); }
void Profile(llvm::FoldingSetNodeID &ID, const ASTContext &Context) {
- Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), NumArgs});
+ Profile(ID, Context, getKeyword(), NNS, Name, {getArgs(), getNumArgs()});
}
static void Profile(llvm::FoldingSetNodeID &ID,
: TypeWithKeyword(Keyword, DependentTemplateSpecialization, Canon, true, true,
/*VariablyModified=*/false,
NNS && NNS->containsUnexpandedParameterPack()),
- NNS(NNS), Name(Name), NumArgs(Args.size()) {
+ NNS(NNS), Name(Name) {
+ DependentTemplateSpecializationTypeBits.NumArgs = Args.size();
assert((!NNS || NNS->isDependent()) &&
"DependentTemplateSpecializatonType requires dependent qualifier");
TemplateArgument *ArgBuffer = getArgBuffer();