Index: include/clang/AST/Type.h =================================================================== --- include/clang/AST/Type.h +++ include/clang/AST/Type.h @@ -1510,6 +1510,11 @@ /// 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... @@ -1518,10 +1523,23 @@ /// 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 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(ExceptionSpecType); + return static_cast( + 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 getExtParameterInfos() const { assert(hasExtParameterInfos()); return ArrayRef(getExtParameterInfosBuffer(), Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -2844,24 +2844,23 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef 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(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(argSlot + NumParams); + auto **noexSlot = reinterpret_cast(argSlot + getNumParams()); *noexSlot = epi.ExceptionSpec.NoexceptExpr; if (epi.ExceptionSpec.NoexceptExpr->isValueDependent() || @@ -2907,7 +2906,7 @@ } else if (getExceptionSpecType() == EST_Uninstantiated) { // Store the function decl from which we will resolve our // exception specification. - auto **slot = reinterpret_cast(argSlot + NumParams); + auto **slot = reinterpret_cast(argSlot + getNumParams()); slot[0] = epi.ExceptionSpec.SourceDecl; slot[1] = epi.ExceptionSpec.SourceTemplate; // This exception specification doesn't make the type dependent, because @@ -2915,7 +2914,7 @@ } else if (getExceptionSpecType() == EST_Unevaluated) { // Store the function decl from which we will resolve our // exception specification. - auto **slot = reinterpret_cast(argSlot + NumParams); + auto **slot = reinterpret_cast(argSlot + getNumParams()); slot[0] = epi.ExceptionSpec.SourceDecl; } @@ -2935,7 +2934,7 @@ if (epi.ExtParameterInfos) { auto *extParamInfos = const_cast(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()) 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()); }