summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/DeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2010-09-28 19:45:33 +0000
committerDouglas Gregor <dgregor@apple.com>2010-09-28 19:45:33 +0000
commita832d3e2ccdecaf8f081b183f823f4627c0fbea3 (patch)
tree82a81670fe4713666b13c8693b94656926940498 /clang/lib/AST/DeclCXX.cpp
parenta349ed0693fc2d63b3229714ae8264c91e5dbf17 (diff)
downloadbcm5719-llvm-a832d3e2ccdecaf8f081b183f823f4627c0fbea3.tar.gz
bcm5719-llvm-a832d3e2ccdecaf8f081b183f823f4627c0fbea3.zip
Reinstate r114921, which I've exonerated via a self-host build.
Centralize the management of CXXRecordDecl::DefinitionData's Aggregate and PlainOldData bits in CXXRecordDecl itself. Another milepost on the road toward <rdar://problem/8459981>. llvm-svn: 114977
Diffstat (limited to 'clang/lib/AST/DeclCXX.cpp')
-rw-r--r--clang/lib/AST/DeclCXX.cpp50
1 files changed, 48 insertions, 2 deletions
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 5d9a09da702..440eaddb7c1 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<CXXRecordDecl>(BaseType->getAs<RecordType>()->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<CXXMethodDecl>(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<CXXConstructorDecl>(D)) {
// If this is the implicit default constructor, note that we have now
@@ -334,6 +354,12 @@ CXXRecordDecl::addedMember(Decl *D) {
if (isa<CXXDestructorDecl>(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<FieldDecl>(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);
OpenPOWER on IntegriCloud