Give Type::isIntegralType() an ASTContext parameter, so that it
provides C "integer type" semantics in C and C++ "integral type"
semantics in C++. 

Note that I still need to update isIntegerType (and possibly other
predicates) using the same approach I've taken for
isIntegralType(). The two should have the same meaning, but currently
don't (!).



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@106074 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
index db2473b..e36ae41 100644
--- a/lib/AST/Expr.cpp
+++ b/lib/AST/Expr.cpp
@@ -1606,8 +1606,10 @@
         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 @@
       // 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 92fffd1..a1d12a3 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -439,14 +439,35 @@
   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;
 }