[AST] Pack the unsigned of DependentTemplateSpecializationType into Type
authorBruno Ricci <riccibrun@gmail.com>
Thu, 16 Aug 2018 10:28:18 +0000 (10:28 +0000)
committerBruno Ricci <riccibrun@gmail.com>
Thu, 16 Aug 2018 10:28:18 +0000 (10:28 +0000)
The bit-fields of `Type` have enough space for the member
`unsigned NumArgs` of `DependentTemplateSpecializationType`.

Reviewed By: erichkeane

Differential Revision: https://reviews.llvm.org/D50712

llvm-svn: 339860

clang/include/clang/AST/Type.h
clang/lib/AST/Type.cpp

index 9580f39..0bf3dc3 100644 (file)
@@ -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,
index 1dba3e3..bd1ac3c 100644 (file)
@@ -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();