diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index a7efe7859163..259e920acf9f 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -4029,6 +4029,22 @@ class FunctionType : public Type { /// because TrailingObjects cannot handle repeated types. struct ExceptionType { QualType Type; }; + /// A simple holder for various uncommon bits which do not fit in + /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the + /// alignment of subsequent objects in TrailingObjects. + struct alignas(void *) FunctionTypeExtraBitfields { + /// The number of types in the exception specification. + /// A whole unsigned is not needed here and according to + /// [implimits] 8 bits would be enough here. + unsigned NumExceptionType : 10; + + LLVM_PREFERRED_TYPE(bool) + unsigned HasArmTypeAttributes : 1; + + FunctionTypeExtraBitfields() + : NumExceptionType(0), HasArmTypeAttributes(false) {} + }; + /// The AArch64 SME ACLE (Arm C/C++ Language Extensions) define a number /// of function type attributes that can be set on function types, including /// function pointers. @@ -4042,7 +4058,8 @@ class FunctionType : public Type { SME_ZAMask = 0b111 << SME_ZAShift, SME_AttributeMask = 0b111'111 // We only support maximum 6 bits because of - // the bitmask in FunctionTypeExtraBitfields. + // the bitmask in FunctionTypeArmAttributes + // and ExtProtoInfo. }; enum ArmStateValue : unsigned { @@ -4057,20 +4074,15 @@ class FunctionType : public Type { return (ArmStateValue)((AttrBits & SME_ZAMask) >> SME_ZAShift); } - /// A simple holder for various uncommon bits which do not fit in - /// FunctionTypeBitfields. Aligned to alignof(void *) to maintain the - /// alignment of subsequent objects in TrailingObjects. - struct alignas(void *) FunctionTypeExtraBitfields { - /// The number of types in the exception specification. - /// A whole unsigned is not needed here and according to - /// [implimits] 8 bits would be enough here. - unsigned NumExceptionType : 10; - + /// A holder for Arm type attributes as described in the Arm C/C++ + /// Language extensions which are not particularly common to all + /// types and therefore accounted separately from FunctionTypeBitfields. + struct alignas(void *) FunctionTypeArmAttributes { /// Any AArch64 SME ACLE type attributes that need to be propagated /// on declarations and function pointers. unsigned AArch64SMEAttributes : 6; - FunctionTypeExtraBitfields() - : NumExceptionType(0), AArch64SMEAttributes(SME_NormalFunction) {} + + FunctionTypeArmAttributes() : AArch64SMEAttributes(SME_NormalFunction) {} }; protected: @@ -4169,7 +4181,8 @@ class FunctionProtoType final public llvm::FoldingSetNode, private llvm::TrailingObjects< FunctionProtoType, QualType, SourceLocation, - FunctionType::FunctionTypeExtraBitfields, FunctionType::ExceptionType, + FunctionType::FunctionTypeExtraBitfields, + FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType, Expr *, FunctionDecl *, FunctionType::ExtParameterInfo, Qualifiers> { friend class ASTContext; // ASTContext creates these. friend TrailingObjects; @@ -4276,7 +4289,11 @@ class FunctionProtoType final bool requiresFunctionProtoTypeExtraBitfields() const { return ExceptionSpec.Type == EST_Dynamic || - AArch64SMEAttributes != SME_NormalFunction; + requiresFunctionProtoTypeArmAttributes(); + } + + bool requiresFunctionProtoTypeArmAttributes() const { + return AArch64SMEAttributes != SME_NormalFunction; } void setArmSMEAttribute(AArch64SMETypeAttributes Kind, bool Enable = true) { @@ -4296,6 +4313,10 @@ class FunctionProtoType final return isVariadic(); } + unsigned numTrailingObjects(OverloadToken) const { + return hasArmTypeAttributes(); + } + unsigned numTrailingObjects(OverloadToken) const { return hasExtraBitfields(); } @@ -4384,6 +4405,12 @@ class FunctionProtoType final } + bool hasArmTypeAttributes() const { + return FunctionTypeBits.HasExtraBitfields && + getTrailingObjects() + ->HasArmTypeAttributes; + } + bool hasExtQualifiers() const { return FunctionTypeBits.HasExtQuals; } @@ -4595,9 +4622,9 @@ class FunctionProtoType final /// Return a bitmask describing the SME attributes on the function type, see /// AArch64SMETypeAttributes for their values. unsigned getAArch64SMEAttributes() const { - if (!hasExtraBitfields()) + if (!hasArmTypeAttributes()) return SME_NormalFunction; - return getTrailingObjects() + return getTrailingObjects() ->AArch64SMEAttributes; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d9cefcaa84d7..0fc0831b221a 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4484,10 +4484,11 @@ QualType ASTContext::getFunctionTypeInternal( EPI.ExceptionSpec.Type, EPI.ExceptionSpec.Exceptions.size()); size_t Size = FunctionProtoType::totalSizeToAlloc< QualType, SourceLocation, FunctionType::FunctionTypeExtraBitfields, - FunctionType::ExceptionType, Expr *, FunctionDecl *, - FunctionProtoType::ExtParameterInfo, Qualifiers>( + FunctionType::FunctionTypeArmAttributes, FunctionType::ExceptionType, + Expr *, FunctionDecl *, FunctionProtoType::ExtParameterInfo, Qualifiers>( NumArgs, EPI.Variadic, EPI.requiresFunctionProtoTypeExtraBitfields(), - ESH.NumExceptionType, ESH.NumExprPtr, ESH.NumFunctionDeclPtr, + EPI.requiresFunctionProtoTypeArmAttributes(), 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 index b419fc8836b0..3db5ae182f32 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -3459,6 +3459,14 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef params, FunctionTypeBits.HasExtraBitfields = false; } + if (epi.requiresFunctionProtoTypeArmAttributes()) { + auto &ArmTypeAttrs = *getTrailingObjects(); + ArmTypeAttrs = FunctionTypeArmAttributes(); + + // Also set the bit in FunctionTypeExtraBitfields + auto &ExtraBits = *getTrailingObjects(); + ExtraBits.HasArmTypeAttributes = true; + } // Fill in the trailing argument array. auto *argSlot = getTrailingObjects(); @@ -3470,10 +3478,10 @@ FunctionProtoType::FunctionProtoType(QualType result, ArrayRef params, // Propagate the SME ACLE attributes. if (epi.AArch64SMEAttributes != SME_NormalFunction) { - auto &ExtraBits = *getTrailingObjects(); + auto &ArmTypeAttrs = *getTrailingObjects(); assert(epi.AArch64SMEAttributes <= SME_AttributeMask && "Not enough bits to encode SME attributes"); - ExtraBits.AArch64SMEAttributes = epi.AArch64SMEAttributes; + ArmTypeAttrs.AArch64SMEAttributes = epi.AArch64SMEAttributes; } // Fill in the exception type array if present.