Switch Type::isAggregateType to use the C++ definition of "aggregate
type" rather than the C definition. We do this because both C99 and
Clang always use "aggregate type" as "aggregate or union type", and
the C++ definition includes union types.



git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@63395 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 65fd3b4..5d3478b 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -661,12 +661,20 @@
          isa<ObjCQualifiedIdType>(CanonicalType);
 }
 
+/// \brief Determines whether the type is a C++ aggregate type or C
+/// aggregate or union type.
+///
+/// An aggregate type is an array or a class type (struct, union, or
+/// class) that has no user-declared constructors, no private or
+/// protected non-static data members, no base classes, and no virtual
+/// functions (C++ [dcl.init.aggr]p1). The notion of an aggregate type
+/// subsumes the notion of C aggregates (C99 6.2.5p21) because it also
+/// includes union types.
 bool Type::isAggregateType() const {
-  if (const TagType *TT = dyn_cast<TagType>(CanonicalType)) {
-    if (TT->getDecl()->isStruct())
-      return true;
-    return false;
-  }
+  if (const CXXRecordType *CXXClassType = dyn_cast<CXXRecordType>(CanonicalType))
+    return CXXClassType->getDecl()->isAggregate();
+  if (isa<RecordType>(CanonicalType))
+    return true;
   if (const ASQualType *ASQT = dyn_cast<ASQualType>(CanonicalType))
     return ASQT->getBaseType()->isAggregateType();
   return isa<ArrayType>(CanonicalType);