unsigned Keyword : 2;
};
+ class TemplateSpecializationTypeBitfields {
+ friend class TemplateSpecializationType;
+
+ unsigned : NumTypeBits;
+
+ /// Whether this template specialization type is a substituted type alias.
+ unsigned TypeAlias : 1;
+
+ /// 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;
+ };
+
union {
TypeBitfields TypeBits;
ArrayTypeBitfields ArrayTypeBits;
ReferenceTypeBitfields ReferenceTypeBits;
TypeWithKeywordBitfields TypeWithKeywordBits;
VectorTypeBitfields VectorTypeBits;
+ TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
static_assert(sizeof(TypeBitfields) <= 8,
"TypeBitfields is larger than 8 bytes!");
"TypeWithKeywordBitfields is larger than 8 bytes!");
static_assert(sizeof(VectorTypeBitfields) <= 8,
"VectorTypeBitfields is larger than 8 bytes!");
+ static_assert(sizeof(TemplateSpecializationTypeBitfields) <= 8,
+ "TemplateSpecializationTypeBitfields is larger"
+ " than 8 bytes!");
};
private:
/// replacement must, recursively, be one of these).
TemplateName Template;
- /// The number of template arguments named in this class template
- /// specialization.
- unsigned NumArgs : 31;
-
- /// Whether this template specialization type is a substituted type alias.
- unsigned TypeAlias : 1;
-
TemplateSpecializationType(TemplateName T,
ArrayRef<TemplateArgument> Args,
QualType Canon,
/// typedef A<Ts...> type; // not a type alias
/// };
/// \endcode
- bool isTypeAlias() const { return TypeAlias; }
+ bool isTypeAlias() const { return TemplateSpecializationTypeBits.TypeAlias; }
/// Get the aliased type, if this is a specialization of a type alias
/// template.
}
/// Retrieve the number of template arguments.
- unsigned getNumArgs() const { return NumArgs; }
+ unsigned getNumArgs() const {
+ return TemplateSpecializationTypeBits.NumArgs;
+ }
/// Retrieve a specific template argument as a type.
/// \pre \c isArgType(Arg)
const TemplateArgument &getArg(unsigned Idx) const; // in TemplateBase.h
ArrayRef<TemplateArgument> template_arguments() const {
- return {getArgs(), NumArgs};
+ return {getArgs(), getNumArgs()};
}
bool isSugared() const {
Canon.isNull()? true : Canon->isDependentType(),
Canon.isNull()? true : Canon->isInstantiationDependentType(),
false,
- T.containsUnexpandedParameterPack()),
- Template(T), NumArgs(Args.size()), TypeAlias(!AliasedType.isNull()) {
+ T.containsUnexpandedParameterPack()), Template(T) {
+ TemplateSpecializationTypeBits.NumArgs = Args.size();
+ TemplateSpecializationTypeBits.TypeAlias = !AliasedType.isNull();
+
assert(!T.getAsDependentTemplateName() &&
"Use DependentTemplateSpecializationType for dependent template-name");
assert((T.getKind() == TemplateName::Template ||
}
// Store the aliased type if this is a type alias template specialization.
- if (TypeAlias) {
+ if (isTypeAlias()) {
auto *Begin = reinterpret_cast<TemplateArgument *>(this + 1);
*reinterpret_cast<QualType*>(Begin + getNumArgs()) = AliasedType;
}