Skip to content

Commit 31777c1

Browse files
[clang] Rework hasBooleanRepresentation.
This is a follow-up of 13aac46. This commit adjusts the implementation of `hasBooleanRepresentation` to have a similar behavior as the one of `hasIntegerRepresentation`. In particular vector of booleans should be handled in `hasBooleanRepresentation`, while `_Atomic(bool)` should not.
1 parent 123b0e2 commit 31777c1

File tree

5 files changed

+34
-19
lines changed

5 files changed

+34
-19
lines changed

clang/include/clang/AST/Decl.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5238,6 +5238,14 @@ inline bool IsEnumDeclScoped(EnumDecl *ED) {
52385238
return ED->isScoped();
52395239
}
52405240

5241+
/// Return the integer type corresponding to the given decl.
5242+
///
5243+
/// We use this function to break a cycle between the inline definitions in
5244+
/// Type.h and Decl.h.
5245+
inline QualType GetEnumDeclIntegerType(EnumDecl *ED) {
5246+
return ED->getIntegerType();
5247+
}
5248+
52415249
/// OpenMP variants are mangled early based on their OpenMP context selector.
52425250
/// The new name looks likes this:
52435251
/// <name> + OpenMPVariantManglingSeparatorStr + <mangled OpenMP context>

clang/include/clang/AST/Type.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2774,7 +2774,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
27742774
bool hasFloatingRepresentation() const;
27752775

27762776
/// Determine whether this type has a boolean representation
2777-
/// of some sort.
2777+
/// of some sort, e.g., it is a boolean type or a vector thereof.
27782778
bool hasBooleanRepresentation() const;
27792779

27802780
// Type Checking Functions: Check to see if this type is structurally the
@@ -8531,6 +8531,7 @@ inline bool Type::isNullPtrType() const {
85318531

85328532
bool IsEnumDeclComplete(EnumDecl *);
85338533
bool IsEnumDeclScoped(EnumDecl *);
8534+
QualType GetEnumDeclIntegerType(EnumDecl *);
85348535

85358536
inline bool Type::isIntegerType() const {
85368537
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
@@ -8623,6 +8624,13 @@ inline bool Type::isIntegralOrEnumerationType() const {
86238624
inline bool Type::isBooleanType() const {
86248625
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
86258626
return BT->getKind() == BuiltinType::Bool;
8627+
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
8628+
// Incomplete enum types are not treated as integer types.
8629+
// FIXME: In C++, enum types are never integer types.
8630+
return IsEnumDeclComplete(ET->getDecl()) &&
8631+
!IsEnumDeclScoped(ET->getDecl()) &&
8632+
GetEnumDeclIntegerType(ET->getDecl())->isBooleanType();
8633+
}
86268634
return false;
86278635
}
86288636

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2336,16 +2336,9 @@ bool Type::isArithmeticType() const {
23362336
}
23372337

23382338
bool Type::hasBooleanRepresentation() const {
2339-
if (isBooleanType())
2340-
return true;
2341-
2342-
if (const EnumType *ET = getAs<EnumType>())
2343-
return ET->getDecl()->getIntegerType()->isBooleanType();
2344-
2345-
if (const AtomicType *AT = getAs<AtomicType>())
2346-
return AT->getValueType()->hasBooleanRepresentation();
2347-
2348-
return false;
2339+
if (const auto *VT = dyn_cast<VectorType>(CanonicalType))
2340+
return VT->getElementType()->isBooleanType();
2341+
return isBooleanType();
23492342
}
23502343

23512344
Type::ScalarTypeKind Type::getScalarTypeKind() const {

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1920,7 +1920,7 @@ static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
19201920
llvm::MDNode *CodeGenFunction::getRangeForLoadFromType(QualType Ty) {
19211921
llvm::APInt Min, End;
19221922
if (!getRangeForType(*this, Ty, Min, End, CGM.getCodeGenOpts().StrictEnums,
1923-
Ty->hasBooleanRepresentation()))
1923+
Ty->hasBooleanRepresentation() && !Ty->isVectorType()))
19241924
return nullptr;
19251925

19261926
llvm::MDBuilder MDHelper(getLLVMContext());
@@ -1948,7 +1948,7 @@ bool CodeGenFunction::EmitScalarRangeCheck(llvm::Value *Value, QualType Ty,
19481948
if (!HasBoolCheck && !HasEnumCheck)
19491949
return false;
19501950

1951-
bool IsBool = Ty->hasBooleanRepresentation() ||
1951+
bool IsBool = (Ty->hasBooleanRepresentation() && !Ty->isVectorType()) ||
19521952
NSAPI(CGM.getContext()).isObjCBOOLType(Ty);
19531953
bool NeedsBoolCheck = HasBoolCheck && IsBool;
19541954
bool NeedsEnumCheck = HasEnumCheck && Ty->getAs<EnumType>();
@@ -2068,11 +2068,8 @@ llvm::Value *CodeGenFunction::EmitLoadOfScalar(Address Addr, bool Volatile,
20682068
/// by ConvertType) to its load/store type (as returned by
20692069
/// convertTypeForLoadStore).
20702070
llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
2071-
if (Ty->hasBooleanRepresentation() || Ty->isBitIntType()) {
2072-
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
2073-
bool Signed = Ty->isSignedIntegerOrEnumerationType();
2074-
return Builder.CreateIntCast(Value, StoreTy, Signed, "storedv");
2075-
}
2071+
if (auto *AtomicTy = Ty->getAs<AtomicType>())
2072+
Ty = AtomicTy->getValueType();
20762073

20772074
if (Ty->isExtVectorBoolType()) {
20782075
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
@@ -2088,13 +2085,22 @@ llvm::Value *CodeGenFunction::EmitToMemory(llvm::Value *Value, QualType Ty) {
20882085
Value = Builder.CreateBitCast(Value, StoreTy);
20892086
}
20902087

2088+
if (Ty->hasBooleanRepresentation() || Ty->isBitIntType()) {
2089+
llvm::Type *StoreTy = convertTypeForLoadStore(Ty, Value->getType());
2090+
bool Signed = Ty->isSignedIntegerOrEnumerationType();
2091+
return Builder.CreateIntCast(Value, StoreTy, Signed, "storedv");
2092+
}
2093+
20912094
return Value;
20922095
}
20932096

20942097
/// Converts a scalar value from its load/store type (as returned
20952098
/// by convertTypeForLoadStore) to its primary IR type (as returned
20962099
/// by ConvertType).
20972100
llvm::Value *CodeGenFunction::EmitFromMemory(llvm::Value *Value, QualType Ty) {
2101+
if (auto *AtomicTy = Ty->getAs<AtomicType>())
2102+
Ty = AtomicTy->getValueType();
2103+
20982104
if (Ty->isPackedVectorBoolType(getContext())) {
20992105
const auto *RawIntTy = Value->getType();
21002106

clang/lib/Sema/SemaType.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9955,7 +9955,7 @@ QualType Sema::BuiltinChangeSignedness(QualType BaseType, UTTKind UKind,
99559955
SourceLocation Loc) {
99569956
bool IsMakeSigned = UKind == UnaryTransformType::MakeSigned;
99579957
if ((!BaseType->isIntegerType() && !BaseType->isEnumeralType()) ||
9958-
BaseType->isBooleanType() ||
9958+
(BaseType->isBooleanType() && !BaseType->isEnumeralType()) ||
99599959
(BaseType->isBitIntType() &&
99609960
BaseType->getAs<BitIntType>()->getNumBits() < 2)) {
99619961
Diag(Loc, diag::err_make_signed_integral_only)

0 commit comments

Comments
 (0)