Author: Ilia Kuklin Date: 2025-01-17T18:23:07+05:00 New Revision: f597d346ab6e42cbfe421b153abf7ece6b592f1d
URL: https://github.com/llvm/llvm-project/commit/f597d346ab6e42cbfe421b153abf7ece6b592f1d DIFF: https://github.com/llvm/llvm-project/commit/f597d346ab6e42cbfe421b153abf7ece6b592f1d.diff LOG: [clang][Sema] Move computing best enum types to a separate function (#120965) Move the code that computes BestType and BestPromotionType for an enum to a separate function which can be called from outside of Sema. Added: Modified: clang/include/clang/AST/ASTContext.h clang/lib/AST/ASTContext.cpp clang/lib/Sema/SemaDecl.cpp Removed: ################################################################################ diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index 0e07c5d6ce8fba..4e9b961688d559 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1726,6 +1726,13 @@ 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. + /// Returns true if enum width is too large. + bool computeBestEnumTypes(bool IsPacked, unsigned NumNegativeBits, + unsigned NumPositiveBits, QualType &BestType, + QualType &BestPromotionType); + QualType getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const; diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index d0ce4c511aedd0..155dbcfcaeed31 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 e0dd6039810cbc..4b56a4dea05e5c 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -20043,10 +20043,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; @@ -20112,73 +20108,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 EnumTooLarge = Context.computeBestEnumTypes( + Packed, NumNegativeBits, NumPositiveBits, BestType, BestPromotionType); + BestWidth = Context.getIntWidth(BestType); + if (EnumTooLarge) + Diag(Enum->getLocation(), diag::ext_enum_too_large); } // Loop over all of the enumerator constants, changing their types to match @@ -20210,7 +20145,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! _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits