diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-09-28 19:45:33 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-09-28 19:45:33 +0000 | 
| commit | a832d3e2ccdecaf8f081b183f823f4627c0fbea3 (patch) | |
| tree | 82a81670fe4713666b13c8693b94656926940498 /clang/lib/AST | |
| parent | a349ed0693fc2d63b3229714ae8264c91e5dbf17 (diff) | |
| download | bcm5719-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')
| -rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 50 | 
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); | 

