From: Douglas Gregor Date: Fri, 30 Jan 2009 17:31:00 +0000 (+0000) Subject: Switch Type::isAggregateType to use the C++ definition of "aggregate X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d7eb846aaf5ee4a8d22c3cd0796d1e7229d46013;p=clang 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/include/clang/AST/Type.h b/include/clang/AST/Type.h index baa2016f55..7697f4a01d 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -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. diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp index 65fd3b4040..5d3478b2ea 100644 --- a/lib/AST/Type.cpp +++ b/lib/AST/Type.cpp @@ -661,12 +661,20 @@ bool Type::isScalarType() const { isa(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(CanonicalType)) { - if (TT->getDecl()->isStruct()) - return true; - return false; - } + if (const CXXRecordType *CXXClassType = dyn_cast(CanonicalType)) + return CXXClassType->getDecl()->isAggregate(); + if (isa(CanonicalType)) + return true; if (const ASQualType *ASQT = dyn_cast(CanonicalType)) return ASQT->getBaseType()->isAggregateType(); return isa(CanonicalType); diff --git a/lib/Analysis/GRExprEngine.cpp b/lib/Analysis/GRExprEngine.cpp index 6a7f86b14b..d9bdd8be0b 100644 --- a/lib/Analysis/GRExprEngine.cpp +++ b/lib/Analysis/GRExprEngine.cpp @@ -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."); diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ad6a719771..3395313f84 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -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(ClassRec->getDecl()); if (!ClassDecl->isAggregate()) diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index 77679ee36f..ed44acff7e 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -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,