[clang] f597d34 - [clang][Sema] Move computing best enum types to a separate function (#120965)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 17 05:23:10 PST 2025
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!
More information about the cfe-commits
mailing list