diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 93bf9a39917ee647995617b9b73c5238eb8070c5..336166dd723462130ced5dfd49d97acc194ee3cf 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -849,7 +849,7 @@ public: bool isCharType() const; bool isWideCharType() const; bool isAnyCharacterType() const; - bool isIntegralType() const; + bool isIntegralType(ASTContext &Ctx) const; /// \brief Determine whether this type is an integral or enumeration type. bool isIntegralOrEnumerationType() const; diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index db2473bb558a2ea5329acb9dd98211db77c10c41..e36ae41ce46ec872defee3135a021a84c734c148 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1606,8 +1606,10 @@ Expr *Expr::IgnoreParenNoopCasts(ASTContext &Ctx) { continue; } - if ((E->getType()->isPointerType() || E->getType()->isIntegralType()) && - (SE->getType()->isPointerType() || SE->getType()->isIntegralType()) && + if ((E->getType()->isPointerType() || + E->getType()->isIntegralType(Ctx)) && + (SE->getType()->isPointerType() || + SE->getType()->isIntegralType(Ctx)) && Ctx.getTypeSize(E->getType()) == Ctx.getTypeSize(SE->getType())) { E = SE; continue; @@ -1797,8 +1799,7 @@ bool Expr::isNullPointerConstant(ASTContext &Ctx, // If the unthinkable happens, fall through to the safest alternative. case NPC_ValueDependentIsNull: - return isTypeDependent() || - (getType()->isIntegralType() && !getType()->isEnumeralType()); + return isTypeDependent() || getType()->isIntegralType(Ctx); case NPC_ValueDependentIsNotNull: return false; diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 92fffd18812c59c3a973f917551eada6a2e341a5..a1d12a38cad96e8479cb0afcd34f3b7b8fbf7eee 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -439,14 +439,35 @@ bool Type::isIntegerType() const { return false; } -bool Type::isIntegralType() const { +/// \brief Determine whether this type is an integral type. +/// +/// This routine determines whether the given type is an integral type per +/// C++ [basic.fundamental]p7. Although the C standard does not define the +/// term "integral type", it has a similar term "integer type", and in C++ +/// the two terms are equivalent. However, C's "integer type" includes +/// enumeration types, while C++'s "integer type" does not. The \c ASTContext +/// parameter is used to determine whether we should be following the C or +/// C++ rules when determining whether this type is an integral/integer type. +/// +/// For cases where C permits "an integer type" and C++ permits "an integral +/// type", use this routine. +/// +/// For cases where C permits "an integer type" and C++ permits "an integral +/// or enumeration type", use \c isIntegralOrEnumerationType() instead. +/// +/// \param Ctx The context in which this type occurs. +/// +/// \returns true if the type is considered an integral type, false otherwise. +bool Type::isIntegralType(ASTContext &Ctx) const { if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType)) return BT->getKind() >= BuiltinType::Bool && BT->getKind() <= BuiltinType::Int128; - if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) - if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) - return true; // Complete enum types are integral. - // FIXME: In C++, enum types are never integral. + + if (!Ctx.getLangOptions().CPlusPlus) + if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) + if (TT->getDecl()->isEnum() && TT->getDecl()->isDefinition()) + return true; // Complete enum types are integral in C. + return false; } diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 8af4b506c7131423664282fea97e6ca8017286fb..81b038bdf1fc1adaa3236057404e5aee03c7adbc 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -624,8 +624,8 @@ CGObjCGNU::GenerateMessageSend(CodeGen::CodeGenFunction &CGF, // to be on the stack / in those registers at the time) on most platforms, // and generates a SegV on SPARC. With LLVM it corrupts the stack. bool isPointerSizedReturn = false; - if (ResultType->isAnyPointerType() || ResultType->isIntegralType() || - ResultType->isVoidType()) + if (ResultType->isAnyPointerType() || + ResultType->isIntegralOrEnumerationType() || ResultType->isVoidType()) isPointerSizedReturn = true; llvm::BasicBlock *startBB = 0; diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index a4f192bc90f730dae624951323fc6a7ded5586d6..74f9a51f0aeb1404090c37399228fe6dcab01df0 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -1084,7 +1084,7 @@ ABIArgInfo X86_64ABIInfo::getCoerceResult(QualType Ty, if (const EnumType *EnumTy = Ty->getAs<EnumType>()) Ty = EnumTy->getDecl()->getIntegerType(); - if (Ty->isIntegralType() || Ty->hasPointerRepresentation()) + if (Ty->isIntegralOrEnumerationType() || Ty->hasPointerRepresentation()) return (Ty->isPromotableIntegerType() ? ABIArgInfo::getExtend() : ABIArgInfo::getDirect()); } else if (CoerceTo == llvm::Type::getDoubleTy(CoerceTo->getContext())) { diff --git a/lib/Sema/SemaCXXCast.cpp b/lib/Sema/SemaCXXCast.cpp index 98270866a25166a422d2606af90788d9191130b2..d87ad6ef1c97695a7ea284330cac406ebd72d6c3 100644 --- a/lib/Sema/SemaCXXCast.cpp +++ b/lib/Sema/SemaCXXCast.cpp @@ -1085,8 +1085,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, } // See below for the enumeral issue. - if (SrcType->isNullPtrType() && DestType->isIntegralType() && - !DestType->isEnumeralType()) { + if (SrcType->isNullPtrType() && DestType->isIntegralType(Self.Context)) { // C++0x 5.2.10p4: A pointer can be explicitly converted to any integral // type large enough to hold it. A value of std::nullptr_t can be // converted to an integral type; the conversion has the same meaning @@ -1103,9 +1102,9 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, bool destIsVector = DestType->isVectorType(); bool srcIsVector = SrcType->isVectorType(); if (srcIsVector || destIsVector) { - bool srcIsScalar = SrcType->isIntegralType() && !SrcType->isEnumeralType(); - bool destIsScalar = - DestType->isIntegralType() && !DestType->isEnumeralType(); + // FIXME: Should this also apply to floating point types? + bool srcIsScalar = SrcType->isIntegralType(Self.Context); + bool destIsScalar = DestType->isIntegralType(Self.Context); // Check if this is a cast between a vector and something else. if (!(srcIsScalar && destIsVector) && !(srcIsVector && destIsScalar) && @@ -1148,9 +1147,7 @@ static TryCastResult TryReinterpretCast(Sema &Self, Expr *SrcExpr, return TC_Success; } - // Note: Clang treats enumeration types as integral types. If this is ever - // changed for C++, the additional check here will be redundant. - if (DestType->isIntegralType() && !DestType->isEnumeralType()) { + if (DestType->isIntegralType(Self.Context)) { assert(srcIsPtr && "One type must be a pointer"); // C++ 5.2.10p4: A pointer can be explicitly converted to any integral // type large enough to hold it. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 39fbc6a684d52702c0822c42f550e002566cc835..813fc6cd3c218c634745b88f5125084fc9fa82b0 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -6291,7 +6291,7 @@ void Sema::ActOnFields(Scope* S, static bool isRepresentableIntegerValue(ASTContext &Context, llvm::APSInt &Value, QualType T) { - assert(T->isIntegralType() && "Integral type required!"); + assert(T->isIntegralType(Context) && "Integral type required!"); unsigned BitWidth = Context.getIntWidth(T); if (Value.isUnsigned() || Value.isNonNegative()) @@ -6305,7 +6305,7 @@ static bool isRepresentableIntegerValue(ASTContext &Context, static QualType getNextLargerIntegralType(ASTContext &Context, QualType T) { // FIXME: Int128/UInt128 support, which also needs to be introduced into // enum checking below. - assert(T->isIntegralType() && "Integral type required!"); + assert(T->isIntegralType(Context) && "Integral type required!"); const unsigned NumTypes = 4; QualType SignedIntegralTypes[NumTypes] = { Context.ShortTy, Context.IntTy, Context.LongTy, Context.LongLongTy diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 347b597f28858420dc8a25552d91a88eeb2e3efd..deb9e058c05e998eba84567b918c623859f015b9 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -3913,13 +3913,13 @@ bool Sema::CheckCastTypes(SourceRange TyR, QualType castType, Expr *&castExpr, if (!castType->isArithmeticType()) { QualType castExprType = castExpr->getType(); - if (!castExprType->isIntegralType() && + if (!castExprType->isIntegralType(Context) && castExprType->isArithmeticType()) return Diag(castExpr->getLocStart(), diag::err_cast_pointer_from_non_pointer_int) << castExprType << castExpr->getSourceRange(); } else if (!castExpr->getType()->isArithmeticType()) { - if (!castType->isIntegralType() && castType->isArithmeticType()) + if (!castType->isIntegralType(Context) && castType->isArithmeticType()) return Diag(castExpr->getLocStart(), diag::err_cast_pointer_to_non_pointer_int) << castType << castExpr->getSourceRange(); @@ -4953,7 +4953,7 @@ QualType Sema::CheckVectorOperands(SourceLocation Loc, Expr *&lex, Expr *&rex) { // Handle the case of an ext vector and scalar. if (const ExtVectorType *LV = lhsType->getAs<ExtVectorType>()) { QualType EltTy = LV->getElementType(); - if (EltTy->isIntegralType() && rhsType->isIntegralType()) { + if (EltTy->isIntegralType(Context) && rhsType->isIntegralType(Context)) { if (Context.getIntegerTypeOrder(EltTy, rhsType) >= 0) { ImpCastExprToType(rex, lhsType, CastExpr::CK_IntegralCast); if (swapped) std::swap(rex, lex); diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 3de8e730c60ee7fec77f3b11896051e7e3067a41..24fdff375721df26a183b4aad2e08de5ea4d59f7 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -963,7 +963,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, SCS.Second = ICK_Complex_Promotion; FromType = ToType.getUnqualifiedType(); } else if (FromType->isIntegralOrEnumerationType() && - (ToType->isIntegralType() && !ToType->isEnumeralType())) { + ToType->isIntegralType(Context)) { // Integral conversions (C++ 4.7). SCS.Second = ICK_Integral_Conversion; FromType = ToType.getUnqualifiedType(); @@ -981,8 +981,7 @@ Sema::IsStandardConversion(Expr* From, QualType ToType, SCS.Second = ICK_Floating_Conversion; FromType = ToType.getUnqualifiedType(); } else if ((FromType->isFloatingType() && - ToType->isIntegralType() && (!ToType->isBooleanType() && - !ToType->isEnumeralType())) || + ToType->isIntegralType(Context) && !ToType->isBooleanType()) || (FromType->isIntegralOrEnumerationType() && ToType->isFloatingType())) { // Floating-integral conversions (C++ 4.9). @@ -1143,7 +1142,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) { if (From) if (FieldDecl *MemberDecl = From->getBitField()) { APSInt BitWidth; - if (FromType->isIntegralType() && !FromType->isEnumeralType() && + if (FromType->isIntegralType(Context) && MemberDecl->getBitWidth()->isIntegerConstantExpr(BitWidth, Context)) { APSInt ToSize(BitWidth.getBitWidth(), BitWidth.isUnsigned()); ToSize = Context.getTypeSize(ToType);