diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1621,8 +1621,8 @@ /// The type of exception specification this function has. unsigned ExceptionSpecType : 4; - /// Whether this function has extended parameter information. - unsigned HasExtParameterInfos : 1; + /// Whether this function has extra bitfields for the prototype. + unsigned HasExtraBitfields : 1; /// Whether the function is variadic. unsigned Variadic : 1; @@ -3805,6 +3805,12 @@ /// A whole unsigned is not needed here and according to /// [implimits] 8 bits would be enough here. unsigned NumExceptionType; + + /// Whether this function has extended parameter information. + bool HasExtParameterInfos : 1; + + FunctionTypeExtraBitfields() + : NumExceptionType(0), HasExtParameterInfos(false) {} }; protected: @@ -3998,6 +4004,10 @@ Result.ExceptionSpec = ESI; return Result; } + + bool requiresFunctionProtoTypeExtraBitfields() const { + return ExtParameterInfos != nullptr || ExceptionSpec.Type == EST_Dynamic; + } }; private: @@ -4088,16 +4098,13 @@ return getExceptionSpecSize(getExceptionSpecType(), getNumExceptions()); } - /// Whether the trailing FunctionTypeExtraBitfields is present. - static bool hasExtraBitfields(ExceptionSpecificationType EST) { - // If the exception spec type is EST_Dynamic then we have > 0 exception - // types and the exact number is stored in FunctionTypeExtraBitfields. - return EST == EST_Dynamic; - } - /// Whether the trailing FunctionTypeExtraBitfields is present. bool hasExtraBitfields() const { - return hasExtraBitfields(getExceptionSpecType()); + assert((getExceptionSpecType() != EST_Dynamic || + FunctionTypeBits.HasExtraBitfields) && + "ExtraBitfields are required for given ExceptionSpecType"); + return FunctionTypeBits.HasExtraBitfields; + } bool hasExtQualifiers() const { @@ -4290,7 +4297,9 @@ /// Is there any interesting extra information for any of the parameters /// of this function type? bool hasExtParameterInfos() const { - return FunctionTypeBits.HasExtParameterInfos; + return hasExtraBitfields() && + getTrailingObjects() + ->HasExtParameterInfos; } ArrayRef getExtParameterInfos() const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4451,8 +4451,7 @@ QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType, Expr *, FunctionDecl *, FunctionProtoType::ExtParameterInfo, Qualifiers>( - NumArgs, EPI.Variadic, - FunctionProtoType::hasExtraBitfields(EPI.ExceptionSpec.Type), + NumArgs, EPI.Variadic, EPI.requiresFunctionProtoTypeExtraBitfields(), ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr, EPI.ExtParameterInfos ? NumArgs : 0, EPI.TypeQuals.hasNonFastQualifiers() ? 1 : 0); diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3209,15 +3209,16 @@ FunctionTypeBits.NumParams = params.size(); assert(getNumParams() == params.size() && "NumParams overflow!"); FunctionTypeBits.ExceptionSpecType = epi.ExceptionSpec.Type; - FunctionTypeBits.HasExtParameterInfos = !!epi.ExtParameterInfos; FunctionTypeBits.Variadic = epi.Variadic; FunctionTypeBits.HasTrailingReturn = epi.HasTrailingReturn; - // Fill in the extra trailing bitfields if present. - if (hasExtraBitfields(epi.ExceptionSpec.Type)) { + if (epi.requiresFunctionProtoTypeExtraBitfields()) { + FunctionTypeBits.HasExtraBitfields = true; auto &ExtraBits = *getTrailingObjects(); - ExtraBits.NumExceptionType = epi.ExceptionSpec.Exceptions.size(); - } + ExtraBits = FunctionTypeExtraBitfields(); + } else + FunctionTypeBits.HasExtraBitfields = false; + // Fill in the trailing argument array. auto *argSlot = getTrailingObjects(); @@ -3229,6 +3230,9 @@ // Fill in the exception type array if present. if (getExceptionSpecType() == EST_Dynamic) { + auto &ExtraBits = *getTrailingObjects(); + ExtraBits.NumExceptionType = epi.ExceptionSpec.Exceptions.size(); + assert(hasExtraBitfields() && "missing trailing extra bitfields!"); auto *exnSlot = reinterpret_cast(getTrailingObjects()); @@ -3288,6 +3292,9 @@ // Fill in the extra parameter info if present. if (epi.ExtParameterInfos) { + auto &ExtraBits = *getTrailingObjects(); + ExtraBits.HasExtParameterInfos = true; + auto *extParamInfos = getTrailingObjects(); for (unsigned i = 0; i != getNumParams(); ++i) extParamInfos[i] = epi.ExtParameterInfos[i];