riccibruno updated this revision to Diff 160369.
riccibruno marked 5 inline comments as done.
riccibruno edited the summary of this revision.
riccibruno added a comment.

Bumped the number of bits for parameters from 12 to 14,
stealing from NumExceptions. This means that now (unless
limited by something else in clang) the maximum number
of types in a dynamic exception spec is 127, and the
maximum number of function parameters is 16383.


Repository:
  rC Clang

https://reviews.llvm.org/D50631

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

Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2844,24 +2844,23 @@
 FunctionProtoType::FunctionProtoType(QualType result, ArrayRef<QualType> params,
                                      QualType canonical,
                                      const ExtProtoInfo &epi)
-    : FunctionType(FunctionProto, result, canonical,
-                   result->isDependentType(),
+    : FunctionType(FunctionProto, result, canonical, result->isDependentType(),
                    result->isInstantiationDependentType(),
                    result->isVariablyModifiedType(),
-                   result->containsUnexpandedParameterPack(), epi.ExtInfo),
-      NumParams(params.size()),
-      NumExceptions(epi.ExceptionSpec.Exceptions.size()),
-      ExceptionSpecType(epi.ExceptionSpec.Type),
-      HasExtParameterInfos(epi.ExtParameterInfos != nullptr),
-      Variadic(epi.Variadic), HasTrailingReturn(epi.HasTrailingReturn) {
-  assert(NumParams == params.size() && "function has too many parameters");
-
+                   result->containsUnexpandedParameterPack(), epi.ExtInfo) {
   FunctionTypeBits.TypeQuals = epi.TypeQuals;
   FunctionTypeBits.RefQualifier = epi.RefQualifier;
+  FunctionTypeBits.NumParams = params.size();
+  assert(getNumParams() == params.size() && "function w. too many parameters!");
+  FunctionTypeBits.NumExceptions = epi.ExceptionSpec.Exceptions.size();
+  FunctionTypeBits.ExceptionSpecType = epi.ExceptionSpec.Type;
+  FunctionTypeBits.HasExtParameterInfos = !!epi.ExtParameterInfos;
+  FunctionTypeBits.Variadic = epi.Variadic;
+  FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn;
 
   // Fill in the trailing argument array.
   auto *argSlot = reinterpret_cast<QualType *>(this+1);
-  for (unsigned i = 0; i != NumParams; ++i) {
+  for (unsigned i = 0; i != getNumParams(); ++i) {
     if (params[i]->isDependentType())
       setDependent();
     else if (params[i]->isInstantiationDependentType())
@@ -2875,7 +2874,7 @@
 
   if (getExceptionSpecType() == EST_Dynamic) {
     // Fill in the exception array.
-    QualType *exnSlot = argSlot + NumParams;
+    QualType *exnSlot = argSlot + getNumParams();
     unsigned I = 0;
     for (QualType ExceptionType : epi.ExceptionSpec.Exceptions) {
       // Note that, before C++17, a dependent exception specification does
@@ -2895,7 +2894,7 @@
            epi.ExceptionSpec.NoexceptExpr->isValueDependent());
 
     // Store the noexcept expression and context.
-    auto **noexSlot = reinterpret_cast<Expr **>(argSlot + NumParams);
+    auto **noexSlot = reinterpret_cast<Expr **>(argSlot + getNumParams());
     *noexSlot = epi.ExceptionSpec.NoexceptExpr;
 
     if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() ||
@@ -2907,15 +2906,15 @@
   } else if (getExceptionSpecType() == EST_Uninstantiated) {
     // Store the function decl from which we will resolve our
     // exception specification.
-    auto **slot = reinterpret_cast<FunctionDecl **>(argSlot + NumParams);
+    auto **slot = reinterpret_cast<FunctionDecl **>(argSlot + getNumParams());
     slot[0] = epi.ExceptionSpec.SourceDecl;
     slot[1] = epi.ExceptionSpec.SourceTemplate;
     // This exception specification doesn't make the type dependent, because
     // it's not instantiated as part of instantiating the type.
   } else if (getExceptionSpecType() == EST_Unevaluated) {
     // Store the function decl from which we will resolve our
     // exception specification.
-    auto **slot = reinterpret_cast<FunctionDecl **>(argSlot + NumParams);
+    auto **slot = reinterpret_cast<FunctionDecl **>(argSlot + getNumParams());
     slot[0] = epi.ExceptionSpec.SourceDecl;
   }
 
@@ -2935,7 +2934,7 @@
   if (epi.ExtParameterInfos) {
     auto *extParamInfos =
       const_cast<ExtParameterInfo *>(getExtParameterInfosBuffer());
-    for (unsigned i = 0; i != NumParams; ++i)
+    for (unsigned i = 0; i != getNumParams(); ++i)
       extParamInfos[i] = epi.ExtParameterInfos[i];
   }
 }
@@ -2981,7 +2980,7 @@
   case EST_Dynamic:
     // A dynamic exception specification is throwing unless every exception
     // type is an (unexpanded) pack expansion type.
-    for (unsigned I = 0, N = NumExceptions; I != N; ++I)
+    for (unsigned I = 0; I != getNumExceptions(); ++I)
       if (!getExceptionType(I)->getAs<PackExpansionType>())
         return CT_Can;
     return CT_Dependent;
@@ -3056,7 +3055,8 @@
 
 void FunctionProtoType::Profile(llvm::FoldingSetNodeID &ID,
                                 const ASTContext &Ctx) {
-  Profile(ID, getReturnType(), param_type_begin(), NumParams, getExtProtoInfo(),
+  Profile(ID, getReturnType(), param_type_begin(),
+          getNumParams(), getExtProtoInfo(),
           Ctx, isCanonicalUnqualified());
 }
 
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -1510,18 +1510,36 @@
     /// regparm and the calling convention.
     unsigned ExtInfo : 12;
 
+    /// The ref-qualifier associated with a \c FunctionProtoType.
+    ///
+    /// This is a value of type \c RefQualifierKind.
+    unsigned RefQualifier : 2;
+
     /// Used only by FunctionProtoType, put here to pack with the
     /// other bitfields.
     /// The qualifiers are part of FunctionProtoType because...
     ///
     /// C++ 8.3.5p4: The return type, the parameter type list and the
     /// cv-qualifier-seq, [...], are part of the function type.
     unsigned TypeQuals : 4;
 
-    /// The ref-qualifier associated with a \c FunctionProtoType.
-    ///
-    /// This is a value of type \c RefQualifierKind.
-    unsigned RefQualifier : 2;
+    /// The number of parameters this function has, not counting '...'.
+    unsigned NumParams : 14;
+
+    /// The number of types in the exception spec, if any.
+    unsigned NumExceptions : 7;
+
+    /// The type of exception specification this function has.
+    unsigned ExceptionSpecType : 4;
+
+    /// Whether this function has extended parameter information.
+    unsigned HasExtParameterInfos : 1;
+
+    /// Whether the function is variadic.
+    unsigned Variadic : 1;
+
+    /// Whether this function has a trailing return type.
+    unsigned HasTrailingReturn : 1;
   };
 
   class ObjCObjectTypeBitfields {
@@ -3572,24 +3590,6 @@
   FunctionProtoType(QualType result, ArrayRef<QualType> params,
                     QualType canonical, const ExtProtoInfo &epi);
 
-  /// The number of parameters this function has, not counting '...'.
-  unsigned NumParams : 15;
-
-  /// The number of types in the exception spec, if any.
-  unsigned NumExceptions : 9;
-
-  /// The type of exception specification this function has.
-  unsigned ExceptionSpecType : 4;
-
-  /// Whether this function has extended parameter information.
-  unsigned HasExtParameterInfos : 1;
-
-  /// Whether the function is variadic.
-  unsigned Variadic : 1;
-
-  /// Whether this function has a trailing return type.
-  unsigned HasTrailingReturn : 1;
-
   // ParamInfo - There is an variable size array after the class in memory that
   // holds the parameter types.
 
@@ -3650,10 +3650,10 @@
   }
 
 public:
-  unsigned getNumParams() const { return NumParams; }
+  unsigned getNumParams() const { return FunctionTypeBits.NumParams; }
 
   QualType getParamType(unsigned i) const {
-    assert(i < NumParams && "invalid parameter index");
+    assert(i < getNumParams() && "invalid parameter index");
     return param_type_begin()[i];
   }
 
@@ -3686,7 +3686,8 @@
 
   /// Get the kind of exception specification on this function.
   ExceptionSpecificationType getExceptionSpecType() const {
-    return static_cast<ExceptionSpecificationType>(ExceptionSpecType);
+    return static_cast<ExceptionSpecificationType>(
+        FunctionTypeBits.ExceptionSpecType);
   }
 
   /// Return whether this function has any kind of exception spec.
@@ -3711,9 +3712,9 @@
   /// spec.
   bool hasInstantiationDependentExceptionSpec() const;
 
-  unsigned getNumExceptions() const { return NumExceptions; }
+  unsigned getNumExceptions() const { return FunctionTypeBits.NumExceptions; }
   QualType getExceptionType(unsigned i) const {
-    assert(i < NumExceptions && "Invalid exception number!");
+    assert(i < getNumExceptions() && "Invalid exception number!");
     return exception_begin()[i];
   }
   Expr *getNoexceptExpr() const {
@@ -3756,7 +3757,7 @@
                              : canThrow() == CT_Cannot;
   }
 
-  bool isVariadic() const { return Variadic; }
+  bool isVariadic() const { return FunctionTypeBits.Variadic; }
 
   /// Determines whether this function prototype contains a
   /// parameter pack at the end.
@@ -3766,7 +3767,7 @@
   /// function.
   bool isTemplateVariadic() const;
 
-  bool hasTrailingReturn() const { return HasTrailingReturn; }
+  bool hasTrailingReturn() const { return FunctionTypeBits.HasTrailingReturn; }
 
   unsigned getTypeQuals() const { return FunctionType::getTypeQuals(); }
 
@@ -3787,7 +3788,7 @@
   }
 
   param_type_iterator param_type_end() const {
-    return param_type_begin() + NumParams;
+    return param_type_begin() + getNumParams();
   }
 
   using exception_iterator = const QualType *;
@@ -3804,12 +3805,15 @@
   exception_iterator exception_end() const {
     if (getExceptionSpecType() != EST_Dynamic)
       return exception_begin();
-    return exception_begin() + NumExceptions;
+    return exception_begin() + getNumExceptions();
   }
 
   /// Is there any interesting extra information for any of the parameters
   /// of this function type?
-  bool hasExtParameterInfos() const { return HasExtParameterInfos; }
+  bool hasExtParameterInfos() const {
+    return FunctionTypeBits.HasExtParameterInfos;
+  }
+
   ArrayRef<ExtParameterInfo> getExtParameterInfos() const {
     assert(hasExtParameterInfos());
     return ArrayRef<ExtParameterInfo>(getExtParameterInfosBuffer(),
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to