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);