Skip to content

Commit c5f1dcf

Browse files
committed
Move the function to ASTContext
1 parent f6c29bc commit c5f1dcf

File tree

4 files changed

+87
-89
lines changed

4 files changed

+87
-89
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1726,6 +1726,12 @@ class ASTContext : public RefCountedBase<ASTContext> {
17261726

17271727
QualType getEnumType(const EnumDecl *Decl) const;
17281728

1729+
/// Compute BestType and BestPromotionType for an enum based on the highest
1730+
/// number of negative and positive bits of its elements.
1731+
bool computeBestEnumTypes(bool isPacked, unsigned NumNegativeBits,
1732+
unsigned NumPositiveBits, QualType &BestType,
1733+
QualType &BestPromotionType);
1734+
17291735
QualType
17301736
getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
17311737

clang/include/clang/Sema/Sema.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3988,9 +3988,6 @@ class Sema final : public SemaBase {
39883988
const ParsedAttributesView &Attrs,
39893989
SourceLocation EqualLoc, Expr *Val);
39903990

3991-
bool ComputeBestEnumTypes(ASTContext &Context, bool isPacked,
3992-
unsigned NumNegativeBits, unsigned NumPositiveBits,
3993-
QualType &BestType, QualType &BestPromotionType);
39943991
void ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
39953992
Decl *EnumDecl, ArrayRef<Decl *> Elements, Scope *S,
39963993
const ParsedAttributesView &Attr);

clang/lib/AST/ASTContext.cpp

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5209,6 +5209,85 @@ QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
52095209
return QualType(newType, 0);
52105210
}
52115211

5212+
bool ASTContext::computeBestEnumTypes(bool isPacked, unsigned NumNegativeBits,
5213+
unsigned NumPositiveBits,
5214+
QualType &BestType,
5215+
QualType &BestPromotionType) {
5216+
unsigned IntWidth = Target->getIntWidth();
5217+
unsigned CharWidth = Target->getCharWidth();
5218+
unsigned ShortWidth = Target->getShortWidth();
5219+
bool EnumTooLarge = false;
5220+
unsigned BestWidth;
5221+
if (NumNegativeBits) {
5222+
// If there is a negative value, figure out the smallest integer type (of
5223+
// int/long/longlong) that fits.
5224+
// If it's packed, check also if it fits a char or a short.
5225+
if (isPacked && NumNegativeBits <= CharWidth &&
5226+
NumPositiveBits < CharWidth) {
5227+
BestType = SignedCharTy;
5228+
BestWidth = CharWidth;
5229+
} else if (isPacked && NumNegativeBits <= ShortWidth &&
5230+
NumPositiveBits < ShortWidth) {
5231+
BestType = ShortTy;
5232+
BestWidth = ShortWidth;
5233+
} else if (NumNegativeBits <= IntWidth && NumPositiveBits < IntWidth) {
5234+
BestType = IntTy;
5235+
BestWidth = IntWidth;
5236+
} else {
5237+
BestWidth = Target->getLongWidth();
5238+
5239+
if (NumNegativeBits <= BestWidth && NumPositiveBits < BestWidth) {
5240+
BestType = LongTy;
5241+
} else {
5242+
BestWidth = Target->getLongLongWidth();
5243+
5244+
if (NumNegativeBits > BestWidth || NumPositiveBits >= BestWidth)
5245+
EnumTooLarge = true;
5246+
BestType = LongLongTy;
5247+
}
5248+
}
5249+
BestPromotionType = (BestWidth <= IntWidth ? IntTy : BestType);
5250+
} else {
5251+
// If there is no negative value, figure out the smallest type that fits
5252+
// all of the enumerator values.
5253+
// If it's packed, check also if it fits a char or a short.
5254+
if (isPacked && NumPositiveBits <= CharWidth) {
5255+
BestType = UnsignedCharTy;
5256+
BestPromotionType = IntTy;
5257+
BestWidth = CharWidth;
5258+
} else if (isPacked && NumPositiveBits <= ShortWidth) {
5259+
BestType = UnsignedShortTy;
5260+
BestPromotionType = IntTy;
5261+
BestWidth = ShortWidth;
5262+
} else if (NumPositiveBits <= IntWidth) {
5263+
BestType = UnsignedIntTy;
5264+
BestWidth = IntWidth;
5265+
BestPromotionType = (NumPositiveBits == BestWidth || !LangOpts.CPlusPlus)
5266+
? UnsignedIntTy
5267+
: IntTy;
5268+
} else if (NumPositiveBits <= (BestWidth = Target->getLongWidth())) {
5269+
BestType = UnsignedLongTy;
5270+
BestPromotionType = (NumPositiveBits == BestWidth || !LangOpts.CPlusPlus)
5271+
? UnsignedLongTy
5272+
: LongTy;
5273+
} else {
5274+
BestWidth = Target->getLongLongWidth();
5275+
if (NumPositiveBits > BestWidth) {
5276+
// This can happen with bit-precise integer types, but those are not
5277+
// allowed as the type for an enumerator per C23 6.7.2.2p4 and p12.
5278+
// FIXME: GCC uses __int128_t and __uint128_t for cases that fit within
5279+
// a 128-bit integer, we should consider doing the same.
5280+
EnumTooLarge = true;
5281+
}
5282+
BestType = UnsignedLongLongTy;
5283+
BestPromotionType = (NumPositiveBits == BestWidth || !LangOpts.CPlusPlus)
5284+
? UnsignedLongLongTy
5285+
: LongLongTy;
5286+
}
5287+
}
5288+
return EnumTooLarge;
5289+
}
5290+
52125291
QualType ASTContext::getUnresolvedUsingType(
52135292
const UnresolvedUsingTypenameDecl *Decl) const {
52145293
if (Decl->TypeForDecl)

clang/lib/Sema/SemaDecl.cpp

Lines changed: 2 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -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-
2009420011
void 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

Comments
 (0)