https://github.com/kuilpd updated https://github.com/llvm/llvm-project/pull/120965
>From ab8dcaef120233d0145508aaa4bf45eec22cadf1 Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Mon, 23 Dec 2024 17:49:32 +0500 Subject: [PATCH 1/4] [clang][Sema] Move calculating enum width and type to a separate function --- clang/include/clang/Sema/Sema.h | 7 ++ clang/lib/Sema/SemaDecl.cpp | 158 ++++++++++++++++++-------------- 2 files changed, 94 insertions(+), 71 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 5ee7ea48cc983c..51a1721fb74f01 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3987,6 +3987,13 @@ class Sema final : public SemaBase { SourceLocation IdLoc, IdentifierInfo *Id, const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val); + + bool ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, + bool isCpp, bool isPacked, + unsigned NumNegativeBits, + unsigned NumPositiveBits, unsigned &BestWidth, + QualType &BestType, + QualType &BestPromotionType); void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, const ParsedAttributesView &Attr); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 4001c4d263f1d2..79cbfe3116b26b 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20008,6 +20008,87 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val)); } +bool Sema::ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, + bool is_cpp, bool isPacked, + unsigned NumNegativeBits, + unsigned NumPositiveBits, + unsigned &BestWidth, QualType &BestType, + QualType &BestPromotionType) { + unsigned IntWidth = Context.getTargetInfo().getIntWidth(); + unsigned CharWidth = Context.getTargetInfo().getCharWidth(); + unsigned ShortWidth = Context.getTargetInfo().getShortWidth(); + bool enum_too_large = false; + if (NumNegativeBits) { + // If there is a negative value, figure out the smallest integer type (of + // int/long/longlong) that fits. + // If it's packed, check also if it fits a char or a short. + if (isPacked && NumNegativeBits <= CharWidth && + NumPositiveBits < CharWidth) { + BestType = Context.SignedCharTy; + BestWidth = CharWidth; + } else if (isPacked && NumNegativeBits <= ShortWidth && + NumPositiveBits < ShortWidth) { + BestType = Context.ShortTy; + BestWidth = ShortWidth; + } else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) { + BestType = Context.IntTy; + BestWidth = IntWidth; + } else { + BestWidth = Context.getTargetInfo().getLongWidth(); + + if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) { + BestType = Context.LongTy; + } else { + BestWidth = Context.getTargetInfo().getLongLongWidth(); + + if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth) + enum_too_large = true; + BestType = Context.LongLongTy; + } + } + BestPromotionType = (BestWidth <= IntWidth ? Context.IntTy : BestType); + } else { + // If there is no negative value, figure out the smallest type that fits + // all of the enumerator values. + // If it's packed, check also if it fits a char or a short. + if (isPacked && NumPositiveBits <= CharWidth) { + BestType = Context.UnsignedCharTy; + BestPromotionType = Context.IntTy; + BestWidth = CharWidth; + } else if (isPacked && NumPositiveBits <= ShortWidth) { + BestType = Context.UnsignedShortTy; + BestPromotionType = Context.IntTy; + BestWidth = ShortWidth; + } else if (NumPositiveBits <= IntWidth) { + BestType = Context.UnsignedIntTy; + BestWidth = IntWidth; + BestPromotionType = (NumPositiveBits == BestWidth || !is_cpp) + ? Context.UnsignedIntTy + : Context.IntTy; + } else if (NumPositiveBits <= + (BestWidth = Context.getTargetInfo().getLongWidth())) { + BestType = Context.UnsignedLongTy; + BestPromotionType = (NumPositiveBits == BestWidth || !is_cpp) + ? Context.UnsignedLongTy + : Context.LongTy; + } else { + BestWidth = Context.getTargetInfo().getLongLongWidth(); + if (NumPositiveBits > BestWidth) { + // This can happen with bit-precise integer types, but those are not + // allowed as the type for an enumerator per C23 6.7.2.2p4 and p12. + // FIXME: GCC uses __int128_t and __uint128_t for cases that fit within + // a 128-bit integer, we should consider doing the same. + enum_too_large = true; + } + BestType = Context.UnsignedLongLongTy; + BestPromotionType = (NumPositiveBits == BestWidth || !is_cpp) + ? Context.UnsignedLongLongTy + : Context.LongLongTy; + } + } + return enum_too_large; +} + void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDeclX, ArrayRef<Decl *> Elements, Scope *S, const ParsedAttributesView &Attrs) { @@ -20030,10 +20111,6 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, return; } - unsigned IntWidth = Context.getTargetInfo().getIntWidth(); - unsigned CharWidth = Context.getTargetInfo().getCharWidth(); - unsigned ShortWidth = Context.getTargetInfo().getShortWidth(); - // Verify that all the values are okay, compute the size of the values, and // reverse the list. unsigned NumNegativeBits = 0; @@ -20099,73 +20176,12 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, BestPromotionType = BestType; BestWidth = Context.getIntWidth(BestType); - } - else if (NumNegativeBits) { - // If there is a negative value, figure out the smallest integer type (of - // int/long/longlong) that fits. - // If it's packed, check also if it fits a char or a short. - if (Packed && NumNegativeBits <= CharWidth && NumPositiveBits < CharWidth) { - BestType = Context.SignedCharTy; - BestWidth = CharWidth; - } else if (Packed && NumNegativeBits <= ShortWidth && - NumPositiveBits < ShortWidth) { - BestType = Context.ShortTy; - BestWidth = ShortWidth; - } else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) { - BestType = Context.IntTy; - BestWidth = IntWidth; - } else { - BestWidth = Context.getTargetInfo().getLongWidth(); - - if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) { - BestType = Context.LongTy; - } else { - BestWidth = Context.getTargetInfo().getLongLongWidth(); - - if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth) - Diag(Enum->getLocation(), diag::ext_enum_too_large); - BestType = Context.LongLongTy; - } - } - BestPromotionType = (BestWidth <= IntWidth ? Context.IntTy : BestType); } else { - // If there is no negative value, figure out the smallest type that fits - // all of the enumerator values. - // If it's packed, check also if it fits a char or a short. - if (Packed && NumPositiveBits <= CharWidth) { - BestType = Context.UnsignedCharTy; - BestPromotionType = Context.IntTy; - BestWidth = CharWidth; - } else if (Packed && NumPositiveBits <= ShortWidth) { - BestType = Context.UnsignedShortTy; - BestPromotionType = Context.IntTy; - BestWidth = ShortWidth; - } else if (NumPositiveBits <= IntWidth) { - BestType = Context.UnsignedIntTy; - BestWidth = IntWidth; - BestPromotionType - = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) - ? Context.UnsignedIntTy : Context.IntTy; - } else if (NumPositiveBits <= - (BestWidth = Context.getTargetInfo().getLongWidth())) { - BestType = Context.UnsignedLongTy; - BestPromotionType - = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) - ? Context.UnsignedLongTy : Context.LongTy; - } else { - BestWidth = Context.getTargetInfo().getLongLongWidth(); - if (NumPositiveBits > BestWidth) { - // This can happen with bit-precise integer types, but those are not - // allowed as the type for an enumerator per C23 6.7.2.2p4 and p12. - // FIXME: GCC uses __int128_t and __uint128_t for cases that fit within - // a 128-bit integer, we should consider doing the same. - Diag(Enum->getLocation(), diag::ext_enum_too_large); - } - BestType = Context.UnsignedLongLongTy; - BestPromotionType - = (NumPositiveBits == BestWidth || !getLangOpts().CPlusPlus) - ? Context.UnsignedLongLongTy : Context.LongLongTy; - } + bool enum_too_large = ComputeBestEnumProperties( + Context, Enum, getLangOpts().CPlusPlus, Packed, NumNegativeBits, + NumPositiveBits, BestWidth, BestType, BestPromotionType); + if (enum_too_large) + Diag(Enum->getLocation(), diag::ext_enum_too_large); } // Loop over all of the enumerator constants, changing their types to match @@ -20197,7 +20213,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, // int; or, // - the enumerated type NewTy = Context.IntTy; - NewWidth = IntWidth; + NewWidth = Context.getTargetInfo().getIntWidth(); NewSign = true; } else if (ECD->getType() == BestType) { // Already the right type! >From c41ddb9d9cd5d8d03a541e3a67e8f903af5160c3 Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Mon, 23 Dec 2024 23:48:50 +0500 Subject: [PATCH 2/4] Remove unnecessary arguments and adjust formatting --- clang/include/clang/Sema/Sema.h | 6 ++--- clang/lib/Sema/SemaDecl.cpp | 44 ++++++++++++++++++--------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 51a1721fb74f01..29310a45a521f2 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3988,11 +3988,9 @@ class Sema final : public SemaBase { const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val); - bool ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, - bool isCpp, bool isPacked, + bool ComputeBestEnumProperties(ASTContext &Context, bool isPacked, unsigned NumNegativeBits, - unsigned NumPositiveBits, unsigned &BestWidth, - QualType &BestType, + unsigned NumPositiveBits, QualType &BestType, QualType &BestPromotionType); void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 79cbfe3116b26b..16b074d77b8c78 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20008,16 +20008,16 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val)); } -bool Sema::ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, - bool is_cpp, bool isPacked, +bool Sema::ComputeBestEnumProperties(ASTContext &Context, bool isPacked, unsigned NumNegativeBits, unsigned NumPositiveBits, - unsigned &BestWidth, QualType &BestType, + QualType &BestType, QualType &BestPromotionType) { unsigned IntWidth = Context.getTargetInfo().getIntWidth(); unsigned CharWidth = Context.getTargetInfo().getCharWidth(); unsigned ShortWidth = Context.getTargetInfo().getShortWidth(); - bool enum_too_large = false; + bool EnumTooLarge = false; + unsigned BestWidth; if (NumNegativeBits) { // If there is a negative value, figure out the smallest integer type (of // int/long/longlong) that fits. @@ -20042,7 +20042,7 @@ bool Sema::ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, BestWidth = Context.getTargetInfo().getLongLongWidth(); if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth) - enum_too_large = true; + EnumTooLarge = true; BestType = Context.LongLongTy; } } @@ -20062,15 +20062,17 @@ bool Sema::ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, } else if (NumPositiveBits <= IntWidth) { BestType = Context.UnsignedIntTy; BestWidth = IntWidth; - BestPromotionType = (NumPositiveBits == BestWidth || !is_cpp) - ? Context.UnsignedIntTy - : Context.IntTy; + BestPromotionType = + (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus) + ? Context.UnsignedIntTy + : Context.IntTy; } else if (NumPositiveBits <= (BestWidth = Context.getTargetInfo().getLongWidth())) { BestType = Context.UnsignedLongTy; - BestPromotionType = (NumPositiveBits == BestWidth || !is_cpp) - ? Context.UnsignedLongTy - : Context.LongTy; + BestPromotionType = + (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus) + ? Context.UnsignedLongTy + : Context.LongTy; } else { BestWidth = Context.getTargetInfo().getLongLongWidth(); if (NumPositiveBits > BestWidth) { @@ -20078,15 +20080,16 @@ bool Sema::ComputeBestEnumProperties(ASTContext &Context, EnumDecl *Enum, // allowed as the type for an enumerator per C23 6.7.2.2p4 and p12. // FIXME: GCC uses __int128_t and __uint128_t for cases that fit within // a 128-bit integer, we should consider doing the same. - enum_too_large = true; + EnumTooLarge = true; } BestType = Context.UnsignedLongLongTy; - BestPromotionType = (NumPositiveBits == BestWidth || !is_cpp) - ? Context.UnsignedLongLongTy - : Context.LongLongTy; + BestPromotionType = + (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus) + ? Context.UnsignedLongLongTy + : Context.LongLongTy; } } - return enum_too_large; + return EnumTooLarge; } void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, @@ -20177,10 +20180,11 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, BestWidth = Context.getIntWidth(BestType); } else { - bool enum_too_large = ComputeBestEnumProperties( - Context, Enum, getLangOpts().CPlusPlus, Packed, NumNegativeBits, - NumPositiveBits, BestWidth, BestType, BestPromotionType); - if (enum_too_large) + bool EnumTooLarge = + ComputeBestEnumProperties(Context, Packed, NumNegativeBits, + NumPositiveBits, BestType, BestPromotionType); + BestWidth = Context.getIntWidth(BestType); + if (EnumTooLarge) Diag(Enum->getLocation(), diag::ext_enum_too_large); } >From f6c29bc3a9982c38d11a7b8baeb606d727d7344b Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Tue, 24 Dec 2024 16:49:44 +0500 Subject: [PATCH 3/4] Rename the funtion --- clang/include/clang/Sema/Sema.h | 7 +++---- clang/lib/Sema/SemaDecl.cpp | 13 ++++++------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 29310a45a521f2..ab2da45bcc1e91 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3988,10 +3988,9 @@ class Sema final : public SemaBase { const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val); - bool ComputeBestEnumProperties(ASTContext &Context, bool isPacked, - unsigned NumNegativeBits, - unsigned NumPositiveBits, QualType &BestType, - QualType &BestPromotionType); + bool ComputeBestEnumTypes(ASTContext &Context, bool isPacked, + unsigned NumNegativeBits, unsigned NumPositiveBits, + QualType &BestType, QualType &BestPromotionType); void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, const ParsedAttributesView &Attr); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 16b074d77b8c78..a9721721b257a0 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20008,11 +20008,10 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val)); } -bool Sema::ComputeBestEnumProperties(ASTContext &Context, bool isPacked, - unsigned NumNegativeBits, - unsigned NumPositiveBits, - QualType &BestType, - QualType &BestPromotionType) { +bool Sema::ComputeBestEnumTypes(ASTContext &Context, bool isPacked, + unsigned NumNegativeBits, + unsigned NumPositiveBits, QualType &BestType, + QualType &BestPromotionType) { unsigned IntWidth = Context.getTargetInfo().getIntWidth(); unsigned CharWidth = Context.getTargetInfo().getCharWidth(); unsigned ShortWidth = Context.getTargetInfo().getShortWidth(); @@ -20181,8 +20180,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, BestWidth = Context.getIntWidth(BestType); } else { bool EnumTooLarge = - ComputeBestEnumProperties(Context, Packed, NumNegativeBits, - NumPositiveBits, BestType, BestPromotionType); + ComputeBestEnumTypes(Context, Packed, NumNegativeBits, NumPositiveBits, + BestType, BestPromotionType); BestWidth = Context.getIntWidth(BestType); if (EnumTooLarge) Diag(Enum->getLocation(), diag::ext_enum_too_large); >From c5f1dcf18f9169f8eec06c81c5e8b8b25d3b6e5b Mon Sep 17 00:00:00 2001 From: Ilia Kuklin <ikuk...@accesssoftek.com> Date: Tue, 14 Jan 2025 22:13:47 +0500 Subject: [PATCH 4/4] Move the function to ASTContext --- clang/include/clang/AST/ASTContext.h | 6 ++ clang/include/clang/Sema/Sema.h | 3 - clang/lib/AST/ASTContext.cpp | 79 +++++++++++++++++++++++++ clang/lib/Sema/SemaDecl.cpp | 88 +--------------------------- 4 files changed, 87 insertions(+), 89 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 1e89a6805ce9c6..f6a3c1067bad58 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1726,6 +1726,12 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType getEnumType(const EnumDecl *Decl) const; + /// Compute BestType and BestPromotionType for an enum based on the highest + /// number of negative and positive bits of its elements. + bool computeBestEnumTypes(bool isPacked, unsigned NumNegativeBits, + unsigned NumPositiveBits, QualType &BestType, + QualType &BestPromotionType); + QualType getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const; diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index ab2da45bcc1e91..acacfadeb1f1d6 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -3988,9 +3988,6 @@ class Sema final : public SemaBase { const ParsedAttributesView &Attrs, SourceLocation EqualLoc, Expr *Val); - bool ComputeBestEnumTypes(ASTContext &Context, bool isPacked, - unsigned NumNegativeBits, unsigned NumPositiveBits, - QualType &BestType, QualType &BestPromotionType); void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S, const ParsedAttributesView &Attr); diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 6ec927e13a7552..f8c7317430c4b9 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5209,6 +5209,85 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const { return QualType(newType, 0); } +bool ASTContext::computeBestEnumTypes(bool isPacked, unsigned NumNegativeBits, + unsigned NumPositiveBits, + QualType &BestType, + QualType &BestPromotionType) { + unsigned IntWidth = Target->getIntWidth(); + unsigned CharWidth = Target->getCharWidth(); + unsigned ShortWidth = Target->getShortWidth(); + bool EnumTooLarge = false; + unsigned BestWidth; + if (NumNegativeBits) { + // If there is a negative value, figure out the smallest integer type (of + // int/long/longlong) that fits. + // If it's packed, check also if it fits a char or a short. + if (isPacked && NumNegativeBits <= CharWidth && + NumPositiveBits < CharWidth) { + BestType = SignedCharTy; + BestWidth = CharWidth; + } else if (isPacked && NumNegativeBits <= ShortWidth && + NumPositiveBits < ShortWidth) { + BestType = ShortTy; + BestWidth = ShortWidth; + } else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) { + BestType = IntTy; + BestWidth = IntWidth; + } else { + BestWidth = Target->getLongWidth(); + + if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) { + BestType = LongTy; + } else { + BestWidth = Target->getLongLongWidth(); + + if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth) + EnumTooLarge = true; + BestType = LongLongTy; + } + } + BestPromotionType = (BestWidth <= IntWidth ? IntTy : BestType); + } else { + // If there is no negative value, figure out the smallest type that fits + // all of the enumerator values. + // If it's packed, check also if it fits a char or a short. + if (isPacked && NumPositiveBits <= CharWidth) { + BestType = UnsignedCharTy; + BestPromotionType = IntTy; + BestWidth = CharWidth; + } else if (isPacked && NumPositiveBits <= ShortWidth) { + BestType = UnsignedShortTy; + BestPromotionType = IntTy; + BestWidth = ShortWidth; + } else if (NumPositiveBits <= IntWidth) { + BestType = UnsignedIntTy; + BestWidth = IntWidth; + BestPromotionType = (NumPositiveBits == BestWidth || !LangOpts.CPlusPlus) + ? UnsignedIntTy + : IntTy; + } else if (NumPositiveBits <= (BestWidth = Target->getLongWidth())) { + BestType = UnsignedLongTy; + BestPromotionType = (NumPositiveBits == BestWidth || !LangOpts.CPlusPlus) + ? UnsignedLongTy + : LongTy; + } else { + BestWidth = Target->getLongLongWidth(); + if (NumPositiveBits > BestWidth) { + // This can happen with bit-precise integer types, but those are not + // allowed as the type for an enumerator per C23 6.7.2.2p4 and p12. + // FIXME: GCC uses __int128_t and __uint128_t for cases that fit within + // a 128-bit integer, we should consider doing the same. + EnumTooLarge = true; + } + BestType = UnsignedLongLongTy; + BestPromotionType = (NumPositiveBits == BestWidth || !LangOpts.CPlusPlus) + ? UnsignedLongLongTy + : LongLongTy; + } + } + return EnumTooLarge; +} + QualType ASTContext::getUnresolvedUsingType( const UnresolvedUsingTypenameDecl *Decl) const { if (Decl->TypeForDecl) diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index a9721721b257a0..21ee87be773848 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20008,89 +20008,6 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val)); } -bool Sema::ComputeBestEnumTypes(ASTContext &Context, bool isPacked, - unsigned NumNegativeBits, - unsigned NumPositiveBits, QualType &BestType, - QualType &BestPromotionType) { - unsigned IntWidth = Context.getTargetInfo().getIntWidth(); - unsigned CharWidth = Context.getTargetInfo().getCharWidth(); - unsigned ShortWidth = Context.getTargetInfo().getShortWidth(); - bool EnumTooLarge = false; - unsigned BestWidth; - if (NumNegativeBits) { - // If there is a negative value, figure out the smallest integer type (of - // int/long/longlong) that fits. - // If it's packed, check also if it fits a char or a short. - if (isPacked && NumNegativeBits <= CharWidth && - NumPositiveBits < CharWidth) { - BestType = Context.SignedCharTy; - BestWidth = CharWidth; - } else if (isPacked && NumNegativeBits <= ShortWidth && - NumPositiveBits < ShortWidth) { - BestType = Context.ShortTy; - BestWidth = ShortWidth; - } else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) { - BestType = Context.IntTy; - BestWidth = IntWidth; - } else { - BestWidth = Context.getTargetInfo().getLongWidth(); - - if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) { - BestType = Context.LongTy; - } else { - BestWidth = Context.getTargetInfo().getLongLongWidth(); - - if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth) - EnumTooLarge = true; - BestType = Context.LongLongTy; - } - } - BestPromotionType = (BestWidth <= IntWidth ? Context.IntTy : BestType); - } else { - // If there is no negative value, figure out the smallest type that fits - // all of the enumerator values. - // If it's packed, check also if it fits a char or a short. - if (isPacked && NumPositiveBits <= CharWidth) { - BestType = Context.UnsignedCharTy; - BestPromotionType = Context.IntTy; - BestWidth = CharWidth; - } else if (isPacked && NumPositiveBits <= ShortWidth) { - BestType = Context.UnsignedShortTy; - BestPromotionType = Context.IntTy; - BestWidth = ShortWidth; - } else if (NumPositiveBits <= IntWidth) { - BestType = Context.UnsignedIntTy; - BestWidth = IntWidth; - BestPromotionType = - (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus) - ? Context.UnsignedIntTy - : Context.IntTy; - } else if (NumPositiveBits <= - (BestWidth = Context.getTargetInfo().getLongWidth())) { - BestType = Context.UnsignedLongTy; - BestPromotionType = - (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus) - ? Context.UnsignedLongTy - : Context.LongTy; - } else { - BestWidth = Context.getTargetInfo().getLongLongWidth(); - if (NumPositiveBits > BestWidth) { - // This can happen with bit-precise integer types, but those are not - // allowed as the type for an enumerator per C23 6.7.2.2p4 and p12. - // FIXME: GCC uses __int128_t and __uint128_t for cases that fit within - // a 128-bit integer, we should consider doing the same. - EnumTooLarge = true; - } - BestType = Context.UnsignedLongLongTy; - BestPromotionType = - (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus) - ? Context.UnsignedLongLongTy - : Context.LongLongTy; - } - } - return EnumTooLarge; -} - void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, Decl *EnumDeclX, ArrayRef<Decl *> Elements, Scope *S, const ParsedAttributesView &Attrs) { @@ -20179,9 +20096,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange, BestWidth = Context.getIntWidth(BestType); } else { - bool EnumTooLarge = - ComputeBestEnumTypes(Context, Packed, NumNegativeBits, NumPositiveBits, - BestType, BestPromotionType); + const bool EnumTooLarge = Context.computeBestEnumTypes( + Packed, NumNegativeBits, NumPositiveBits, BestType, BestPromotionType); BestWidth = Context.getIntWidth(BestType); if (EnumTooLarge) Diag(Enum->getLocation(), diag::ext_enum_too_large); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits