diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index 975659b1e50e..aa2ff3c43df6 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -688,10 +688,6 @@ public: /// no base classes, and no virtual functions (C++ [dcl.init.aggr]p1). bool isAggregate() const { return data().Aggregate; } - /// setAggregate - Set whether this class is an aggregate (C++ - /// [dcl.init.aggr]). - void setAggregate(bool Agg) { data().Aggregate = Agg; } - /// setMethodAsVirtual - Make input method virtual and set the necesssary /// special function bits and other bits accordingly. void setMethodAsVirtual(FunctionDecl *Method); @@ -702,9 +698,6 @@ public: /// user-defined destructor. bool isPOD() const { return data().PlainOldData; } - /// setPOD - Set whether this class is a POD-type (C++ [class]p4). - void setPOD(bool POD) { data().PlainOldData = POD; } - /// isEmpty - Whether this class is empty (C++0x [meta.unary.prop]), which /// means it has a virtual function, virtual base, data member (other than /// 0-width bit-field) or inherits from a non-empty class. Does NOT include diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index 5d9a09da7020..440eaddb7c16 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -97,6 +97,14 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases, CXXRecordDecl *BaseClassDecl = cast(BaseType->getAs()->getDecl()); + // C++ [dcl.init.aggr]p1: + // An aggregate is [...] a class with [...] no base classes [...]. + data().Aggregate = false; + + // C++ [class]p4: + // A POD-struct is an aggregate class... + data().PlainOldData = false; + // Now go through all virtual bases of this base and add them. for (CXXRecordDecl::base_class_iterator VBase = BaseClassDecl->vbases_begin(), @@ -268,6 +276,18 @@ CXXRecordDecl::addedMember(Decl *D) { if (FunTmpl) D = FunTmpl->getTemplatedDecl(); + if (CXXMethodDecl *Method = dyn_cast(D)) { + if (Method->isVirtual()) { + // C++ [dcl.init.aggr]p1: + // An aggregate is an array or a class with [...] no virtual functions. + data().Aggregate = false; + + // C++ [class]p4: + // A POD-struct is an aggregate class... + data().PlainOldData = false; + } + } + if (D->isImplicit()) { if (CXXConstructorDecl *Constructor = dyn_cast(D)) { // If this is the implicit default constructor, note that we have now @@ -334,6 +354,12 @@ CXXRecordDecl::addedMember(Decl *D) { if (isa(D)) { data().DeclaredDestructor = true; data().UserDeclaredDestructor = true; + + // C++ [class]p4: + // A POD-struct is an aggregate class that has [...] no user-defined + // destructor. + data().PlainOldData = false; + return; } @@ -382,6 +408,28 @@ CXXRecordDecl::addedMember(Decl *D) { return; } + + // Handle non-static data members. + if (FieldDecl *Field = dyn_cast(D)) { + // C++ [dcl.init.aggr]p1: + // An aggregate is an array or a class (clause 9) with [...] no + // private or protected non-static data members (clause 11). + // + // A POD must be an aggregate. + if (D->getAccess() == AS_private || D->getAccess() == AS_protected) { + data().Aggregate = false; + data().PlainOldData = false; + } + + // C++ [class]p9: + // A POD struct is a class that is both a trivial class and a + // standard-layout class, and has no non-static data members of type + // non-POD struct, non-POD union (or array of such types). + ASTContext &Context = getASTContext(); + QualType T = Context.getBaseElementType(Field->getType()); + if (!T->isPODType()) + data().PlainOldData = false; + } } static CanQualType GetConversionType(ASTContext &Context, NamedDecl *Conv) { @@ -566,8 +614,6 @@ void CXXRecordDecl::removeConversion(const NamedDecl *ConvDecl) { void CXXRecordDecl::setMethodAsVirtual(FunctionDecl *Method) { Method->setVirtualAsWritten(true); - setAggregate(false); - setPOD(false); setEmpty(false); setPolymorphic(true); setHasTrivialConstructor(false); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 68cdc556e8d5..5ac6f618d302 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -3931,10 +3931,6 @@ void Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD, } } - // C++ [class]p4: A POD-struct is an aggregate class that has [...] no - // user-defined destructor. - Record->setPOD(false); - // C++ [class.dtor]p3: A destructor is trivial if it is an implicitly- // declared destructor. // FIXME: C++0x: don't do this for "= default" destructors @@ -6194,8 +6190,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, if (!InvalidDecl && getLangOptions().CPlusPlus) { CXXRecordDecl* CXXRecord = cast(Record); - if (!T->isPODType()) - CXXRecord->setPOD(false); if (!ZeroWidth) CXXRecord->setEmpty(false); if (T->isReferenceType()) @@ -6235,18 +6229,6 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T, Diag(Loc, diag::warn_attribute_weak_on_field); NewFD->setAccess(AS); - - // C++ [dcl.init.aggr]p1: - // An aggregate is an array or a class (clause 9) with [...] no - // private or protected non-static data members (clause 11). - // A POD must be an aggregate. - if (getLangOptions().CPlusPlus && - (AS == AS_private || AS == AS_protected)) { - CXXRecordDecl *CXXRecord = cast(Record); - CXXRecord->setAggregate(false); - CXXRecord->setPOD(false); - } - return NewFD; } diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 473247139e65..8ecf047a670d 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -527,14 +527,6 @@ void Sema::SetClassDeclAttributesFromBase(CXXRecordDecl *Class, if (BaseClass->isPolymorphic()) Class->setPolymorphic(true); - // C++ [dcl.init.aggr]p1: - // An aggregate is [...] a class with [...] no base classes [...]. - Class->setAggregate(false); - - // C++ [class]p4: - // A POD-struct is an aggregate class... - Class->setPOD(false); - if (BaseIsVirtual) { // C++ [class.ctor]p5: // A constructor is trivial if its class has no virtual base classes.