summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang/include/clang/AST/Type.h35
-rw-r--r--clang/lib/AST/Type.cpp3
2 files changed, 30 insertions, 8 deletions
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 9580f39a5ef..0bf3dc36009 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -1571,6 +1571,8 @@ protected:
unsigned Keyword : 8;
};
+ enum { NumTypeWithKeywordBits = 8 };
+
class VectorTypeBitfields {
friend class VectorType;
friend class DependentVectorType;
@@ -1624,6 +1626,22 @@ protected:
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;
@@ -1655,6 +1673,8 @@ protected:
TypeWithKeywordBitfields TypeWithKeywordBits;
VectorTypeBitfields VectorTypeBits;
TemplateSpecializationTypeBitfields TemplateSpecializationTypeBits;
+ DependentTemplateSpecializationTypeBitfields
+ DependentTemplateSpecializationTypeBits;
PackExpansionTypeBitfields PackExpansionTypeBits;
static_assert(sizeof(TypeBitfields) <= 8,
@@ -1680,6 +1700,9 @@ protected:
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");
};
@@ -5123,10 +5146,6 @@ class alignas(8) DependentTemplateSpecializationType
/// 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,
@@ -5151,12 +5170,14 @@ public:
}
/// 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 *;
@@ -5168,7 +5189,7 @@ public:
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,
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 1dba3e3e4c7..bd1ac3c5aaf 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -2604,7 +2604,8 @@ DependentTemplateSpecializationType::DependentTemplateSpecializationType(
: 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();
OpenPOWER on IntegriCloud