forked from OSchip/llvm-project
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: 114921
This commit is contained in:
parent
185051cb8e
commit
1be93f5143
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<CXXRecordDecl>(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<CXXRecordDecl>(Record);
|
||||
CXXRecord->setAggregate(false);
|
||||
CXXRecord->setPOD(false);
|
||||
}
|
||||
|
||||
return NewFD;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in New Issue