@@ -20008,89 +20008,6 @@ bool Sema::IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val,
2000820008 return !(FlagMask & Val) || (AllowMask && !(FlagMask & ~Val));
2000920009}
2001020010
20011- bool Sema::ComputeBestEnumTypes(ASTContext &Context, bool isPacked,
20012- unsigned NumNegativeBits,
20013- unsigned NumPositiveBits, QualType &BestType,
20014- QualType &BestPromotionType) {
20015- unsigned IntWidth = Context.getTargetInfo().getIntWidth();
20016- unsigned CharWidth = Context.getTargetInfo().getCharWidth();
20017- unsigned ShortWidth = Context.getTargetInfo().getShortWidth();
20018- bool EnumTooLarge = false;
20019- unsigned BestWidth;
20020- if (NumNegativeBits) {
20021- // If there is a negative value, figure out the smallest integer type (of
20022- // int/long/longlong) that fits.
20023- // If it's packed, check also if it fits a char or a short.
20024- if (isPacked && NumNegativeBits <= CharWidth &&
20025- NumPositiveBits < CharWidth) {
20026- BestType = Context.SignedCharTy;
20027- BestWidth = CharWidth;
20028- } else if (isPacked && NumNegativeBits <= ShortWidth &&
20029- NumPositiveBits < ShortWidth) {
20030- BestType = Context.ShortTy;
20031- BestWidth = ShortWidth;
20032- } else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) {
20033- BestType = Context.IntTy;
20034- BestWidth = IntWidth;
20035- } else {
20036- BestWidth = Context.getTargetInfo().getLongWidth();
20037-
20038- if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) {
20039- BestType = Context.LongTy;
20040- } else {
20041- BestWidth = Context.getTargetInfo().getLongLongWidth();
20042-
20043- if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
20044- EnumTooLarge = true;
20045- BestType = Context.LongLongTy;
20046- }
20047- }
20048- BestPromotionType = (BestWidth <= IntWidth ? Context.IntTy : BestType);
20049- } else {
20050- // If there is no negative value, figure out the smallest type that fits
20051- // all of the enumerator values.
20052- // If it's packed, check also if it fits a char or a short.
20053- if (isPacked && NumPositiveBits <= CharWidth) {
20054- BestType = Context.UnsignedCharTy;
20055- BestPromotionType = Context.IntTy;
20056- BestWidth = CharWidth;
20057- } else if (isPacked && NumPositiveBits <= ShortWidth) {
20058- BestType = Context.UnsignedShortTy;
20059- BestPromotionType = Context.IntTy;
20060- BestWidth = ShortWidth;
20061- } else if (NumPositiveBits <= IntWidth) {
20062- BestType = Context.UnsignedIntTy;
20063- BestWidth = IntWidth;
20064- BestPromotionType =
20065- (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus)
20066- ? Context.UnsignedIntTy
20067- : Context.IntTy;
20068- } else if (NumPositiveBits <=
20069- (BestWidth = Context.getTargetInfo().getLongWidth())) {
20070- BestType = Context.UnsignedLongTy;
20071- BestPromotionType =
20072- (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus)
20073- ? Context.UnsignedLongTy
20074- : Context.LongTy;
20075- } else {
20076- BestWidth = Context.getTargetInfo().getLongLongWidth();
20077- if (NumPositiveBits > BestWidth) {
20078- // This can happen with bit-precise integer types, but those are not
20079- // allowed as the type for an enumerator per C23 6.7.2.2p4 and p12.
20080- // FIXME: GCC uses __int128_t and __uint128_t for cases that fit within
20081- // a 128-bit integer, we should consider doing the same.
20082- EnumTooLarge = true;
20083- }
20084- BestType = Context.UnsignedLongLongTy;
20085- BestPromotionType =
20086- (NumPositiveBits == BestWidth || !Context.getLangOpts().CPlusPlus)
20087- ? Context.UnsignedLongLongTy
20088- : Context.LongLongTy;
20089- }
20090- }
20091- return EnumTooLarge;
20092- }
20093-
2009420011void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
2009520012 Decl *EnumDeclX, ArrayRef<Decl *> Elements, Scope *S,
2009620013 const ParsedAttributesView &Attrs) {
@@ -20179,9 +20096,8 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
2017920096
2018020097 BestWidth = Context.getIntWidth(BestType);
2018120098 } else {
20182- bool EnumTooLarge =
20183- ComputeBestEnumTypes(Context, Packed, NumNegativeBits, NumPositiveBits,
20184- BestType, BestPromotionType);
20099+ const bool EnumTooLarge = Context.computeBestEnumTypes(
20100+ Packed, NumNegativeBits, NumPositiveBits, BestType, BestPromotionType);
2018520101 BestWidth = Context.getIntWidth(BestType);
2018620102 if (EnumTooLarge)
2018720103 Diag(Enum->getLocation(), diag::ext_enum_too_large);
0 commit comments