]> granicus.if.org Git - clang/commitdiff
Switch Type::isAggregateType to use the C++ definition of "aggregate
authorDouglas Gregor <dgregor@apple.com>
Fri, 30 Jan 2009 17:31:00 +0000 (17:31 +0000)
committerDouglas Gregor <dgregor@apple.com>
Fri, 30 Jan 2009 17:31:00 +0000 (17:31 +0000)
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

include/clang/AST/Type.h
lib/AST/Type.cpp
lib/Analysis/GRExprEngine.cpp
lib/Sema/SemaDecl.cpp
lib/Sema/SemaInit.cpp

index baa2016f553b3c66e3069fdd2ad737402024109b..7697f4a01da69d86bc3a5cc094484524383f05e8 100644 (file)
@@ -328,7 +328,7 @@ public:
   bool isVoidType() const;         // C99 6.2.5p19
   bool isDerivedType() const;      // C99 6.2.5p20
   bool isScalarType() const;       // C99 6.2.5p21 (arithmetic + pointers)
-  bool isAggregateType() const;    // C99 6.2.5p21 (arrays, structures)
+  bool isAggregateType() const;
   
   // Type Predicates: Check to see if this type is structurally the specified
   // type, ignoring typedefs and qualifiers.
index 65fd3b40408ca81339615004b55aa8fde3738476..5d3478b2eabaf98b879e261ff569d1ac4ad47644 100644 (file)
@@ -661,12 +661,20 @@ bool Type::isScalarType() const {
          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);
index 6a7f86b14bf00d7484a7e3931a4435e19badd115..d9bdd8be0b69d50a8fcf6d805aeb74d76f209882 100644 (file)
@@ -493,8 +493,7 @@ void GRExprEngine::VisitLValue(Expr* Ex, NodeTy* Pred, NodeSet& Dst) {
       // can be used in a lvalue context.  We need to enhance our support
       // of such temporaries in both the environment and the store, so right
       // now we just do a regular visit.
-      assert ((Ex->getType()->isAggregateType() || 
-              Ex->getType()->isUnionType()) &&
+      assert ((Ex->getType()->isAggregateType()) &&
               "Other kinds of expressions with non-aggregate/union types do"
               " not have lvalues.");
       
index ad6a7197718d0eb4ad70c1dc802bb2ec18cf5d11..3395313f84cd82d7ef50c6e783eb6c8af1a8946e 100644 (file)
@@ -1083,6 +1083,7 @@ bool Sema::CheckInitializerTypes(Expr *&Init, QualType &DeclType,
     // we have an initializer list and a destination type that is not
     // an aggregate.
     // FIXME: In C++0x, this is yet another form of initialization.
+    // FIXME: Move this checking into CheckInitList!
     if (const RecordType *ClassRec = DeclType->getAsRecordType()) {
       const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassRec->getDecl());
       if (!ClassDecl->isAggregate())
index 77679ee36f981e297499dbb6903bb65bd9c828b9..ed44acff7ee99b0bf42d6812c5d7551b39cbe1b8 100644 (file)
@@ -287,8 +287,8 @@ void InitListChecker::CheckListElementTypes(InitListExpr *IList,
     CheckScalarType(IList, DeclType, Index, StructuredList, StructuredIndex);
   } else if (DeclType->isVectorType()) {
     CheckVectorType(IList, DeclType, Index, StructuredList, StructuredIndex);
-  } else if (DeclType->isAggregateType() || DeclType->isUnionType()) {
-    if (DeclType->isStructureType() || DeclType->isUnionType()) {
+  } else if (DeclType->isAggregateType()) {
+    if (DeclType->isRecordType()) {
       RecordDecl *RD = DeclType->getAsRecordType()->getDecl();
       CheckStructUnionTypes(IList, DeclType, RD->field_begin(), 
                             SubobjectIsDesignatorContext, Index,